aly 0.2.3 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f26b851dc09f00694624a45426546e11bc72c63de0a991ceb1e6b1e8989a3f1
4
- data.tar.gz: e4f1e81074036af2e6565f0f98a30ffd7a81dc82a1c42bb878f6357c5a93cf55
3
+ metadata.gz: a8ccc78283759268e2374660bf543b44bee7b49e715c8e78da7584897e54c3a9
4
+ data.tar.gz: 27df10c05d066cf96d34b4d6c7e67701a4d9a53a5662535215e0489861d3a4b9
5
5
  SHA512:
6
- metadata.gz: c762fdf73886adb7229a88510e613ec7d58966dc42cb1fe98bf3d84b7082274551e2201f08439953c467743561e90a4229d777294963d765a68987f0c3916c2d
7
- data.tar.gz: 97f110b453a54434943d380ad960536dc26934ceff82b6f8fac8782011c38f2e8aba9692ff56cd8d5714c2df78926f0a947e965d78169e55f8d9fcf1f35d9796
6
+ metadata.gz: b7265019730f3b3b5620a0502f416cf74705f711df7fb49228b699d98a59efe9666293cccb314f41afe3a3a79d72e9ea2758465ba37a4af5bcc384f4291d0191
7
+ data.tar.gz: f1498dc9304a8c8f88bf10540142708cf1b094aa58865a0755d47894d2ec9fc0d9adb16c4cc5d8b5797cc7dc3b258388b0a6954865472fafee6df8b95b18a825
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- aly (0.2.3)
4
+ aly (0.3.2)
5
5
  terminal-table (~> 1.8.0)
6
6
  thor (~> 0.20.0)
7
7
 
data/aly.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = "A simple wrapper for aliyun cli"
13
13
  spec.homepage = "https://github.com/lululau/aly"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
15
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
16
16
 
17
17
  # Specify which files should be added to the gem when it is released.
18
18
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
data/lib/aly/app.rb CHANGED
@@ -10,7 +10,7 @@ class Array
10
10
  Terminal::Table.new { |t|
11
11
  t << header
12
12
  t << :separator
13
- each { |row| t << row.values }
13
+ each { |row| t << (row.nil? ? :separator : row.values) }
14
14
  }
15
15
  end
16
16
  end
@@ -91,6 +91,128 @@ module Aly
91
91
  end
92
92
  end
93
93
 
94
+ def full_slb(lbs, eips, **options)
95
+ lbs.each do |lb|
96
+ puts "\nLoanBalancer Id: %s, Name: %s" % [lb['LoadBalancerId'], lb['LoadBalancerName']]
97
+ puts "==============================================================\n\n"
98
+ listeners = lb['Listeners']
99
+ background_servers = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{lb['LoadBalancerId']}", **options)['BackendServers']['BackendServer'] || []
100
+
101
+ puts ' LoadBalancer Basic Information:'
102
+ puts([{
103
+ Id: lb['LoadBalancerId'],
104
+ Name: lb['LoadBalancerName'],
105
+ Address: lb['Address'],
106
+ Eip: lb['Eip'],
107
+ Listeners: listeners.size
108
+ }].table.to_s.gsub(/^/, ' '))
109
+ puts
110
+
111
+ if background_servers && background_servers.size > 0
112
+ puts ' Default Backend Servers:'
113
+ puts
114
+
115
+ ecss = @ecs.select { |e| background_servers.map{|ee| ee['ServerId']}.include?(e['InstanceId']) }
116
+
117
+ puts ecss.map { |row|
118
+ {
119
+ Id: row['InstanceId'],
120
+ Name: row['InstanceName'],
121
+ PrivateIP: row['PrivateIP'].join(','),
122
+ PublicIP: row['PublicIP'].join(','),
123
+ CPU: row['Cpu'],
124
+ RAM: "#{row['Memory'] / 1024.0} GB"
125
+ }
126
+ }.table.to_s.gsub(/^/, ' ')
127
+ puts
128
+ end
129
+
130
+ vserver_groups = exec('slb', 'DescribeVServerGroups', '--pager', "--LoadBalancerId=#{lb['LoadBalancerId']}", **options)["VServerGroups"]["VServerGroup"] || []
131
+ vserver_group_servers = vserver_groups.flat_map do |vg|
132
+ vg_attr = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{vg['VServerGroupId']}", **options)["BackendServers"]["BackendServer"]
133
+ vg_attr.each_with_index.map do |attr, idx|
134
+ ecs = @ecs.find {|e| e['InstanceId'] == attr['ServerId'] }
135
+ {
136
+ VGroupId: (idx.zero? ? vg['VServerGroupId'] : ''),
137
+ VGroupName: (idx.zero? ? vg['VServerGroupName'] : ''),
138
+ Weight: attr['Weight'],
139
+ Port: attr['Port'],
140
+ Type: attr['Type'],
141
+ EcsId: attr['ServerId'],
142
+ EcsName: ecs['InstanceName'],
143
+ PrivateIP: ecs['PrivateIP'].join(','),
144
+ PublicIP: ecs['PublicIP'].join(','),
145
+ CPU: ecs['Cpu'],
146
+ RAM: "#{ecs['Memory'] / 1024.0} GB"
147
+ }
148
+ end + [nil]
149
+ end
150
+ puts ' VServer Groups:'
151
+ puts vserver_group_servers[0..-2].table.to_s.gsub(/^/, ' ')
152
+ puts
153
+
154
+ listeners.each do |listener|
155
+ listener_type = ['HTTP', 'HTTPS', 'TCP', 'TCPS', 'UDP'].find { |e| !listener["#{e}ListenerConfig"].empty? }
156
+ listener['ListenerType'] = listener_type
157
+ end
158
+
159
+ listeners_info = listeners.map do |listener|
160
+ {
161
+ Description: listener['Description'],
162
+ Port: listener['ListenerPort'],
163
+ Protocol: listener['ListenerProtocol'],
164
+ Status: listener['Status'],
165
+ HeathCheck: (listener["#{listener['ListenerType']}ListenerConfig"] || {}).dig("HealthCheck") || 'off',
166
+ BackendServerPort: listener['BackendServerPort'],
167
+ ForwardPort: listener.dig('HTTPListenerConfig', 'ForwardPort'),
168
+ VServerGroup: listener['VServerGroupId'],
169
+ AclStatus: listener['AclStatus'] || 'off',
170
+ AclType: listener['AclType'],
171
+ AclIds: (listener['AclIds'] || []).join(','),
172
+ }
173
+ end
174
+
175
+ puts ' Configured Listeners:'
176
+ puts listeners_info.table.to_s.gsub(/^/, ' ')
177
+ puts
178
+
179
+ listener_rules = listeners.flat_map do |listener|
180
+ listener_type = listener['ListenerType']
181
+ next [] unless listener_type
182
+ rules = exec('slb', "DescribeLoadBalancer#{listener_type}ListenerAttribute", "--LoadBalancerId=#{lb['LoadBalancerId']}", "--ListenerPort=#{listener['ListenerPort']}", **options).dig('Rules', 'Rule') || []
183
+ rules.map do |rule|
184
+ {'Listener' => listener['Description']}.merge(rule)
185
+ end
186
+ end
187
+
188
+ puts ' Listener Rules:'
189
+ puts listener_rules.table.to_s.gsub(/^/, ' ')
190
+ puts
191
+
192
+ if options['acl']
193
+ acl_ids = listeners.flat_map { |listener| listener['AclIds'] || [] }.uniq
194
+ unless acl_ids.empty?
195
+ alc_entries = acl_ids.flat_map do |acl_id|
196
+ attr = exec('slb', 'DescribeAccessControlListAttribute', "--AclId=#{acl_id}", **options)
197
+ (attr.dig('AclEntrys', 'AclEntry') || []).each_with_index.map do |e, idx|
198
+ {
199
+ AclId: (idx.zero? ? attr['AclId'] : ''),
200
+ AclName: (idx.zero? ? attr['AclName'] : ''),
201
+ AclEntryIP: e['AclEntryIP'],
202
+ AclEntryComment: e['AclEntryComment']
203
+ }
204
+ end + [nil]
205
+ end
206
+ puts ' Access Control Lists:'
207
+ puts alc_entries[0..-2].table.to_s.gsub(/^/, ' ')
208
+ puts
209
+ end
210
+
211
+ end
212
+
213
+ end
214
+ end
215
+
94
216
  def slb(*args, **options)
95
217
  raw_out = exec('slb', 'DescribeLoadBalancers', '--pager', **options)
96
218
  selected = raw_out['LoadBalancers']['LoadBalancer'] || []
@@ -115,7 +237,29 @@ module Aly
115
237
  end
116
238
  end
117
239
 
118
- if options['detail']
240
+ @eip ||= exec('vpc', 'DescribeEipAddresses', '--PageSize=100', **options)['EipAddresses']['EipAddress'] || []
241
+
242
+ eip_map = @eip.each_with_object({}) { |eip, h| h[eip['InstanceId']] = eip['IpAddress'] }
243
+ selected.each do |slb|
244
+ slb['Eip'] = eip_map[slb['LoadBalancerId']]
245
+ end
246
+
247
+ @ecs = exec('ecs', 'DescribeInstances', '--pager', **options)['Instances']['Instance'] || []
248
+ @ecs.each do |item|
249
+ item['PrivateIP'] = (item['NetworkInterfaces']['NetworkInterface'] || []).map { |ni| ni['PrimaryIpAddress'] }
250
+ item['PublicIP'] = []
251
+ if ip = item['EipAddress']['IpAddress']
252
+ item['PublicIP'] << ip
253
+ end
254
+ if ips = item['PublicIpAddress']['IpAddress']
255
+ item['PublicIP'] += ips
256
+ end
257
+ item['AllIPs'] = item['PrivateIP'] + item['PublicIP']
258
+ end
259
+
260
+ if options['full']
261
+ full_slb(selected, eips, **options)
262
+ elsif options['detail']
119
263
  selected.each do |row|
120
264
  described_load_balancer_attributes = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{row['LoadBalancerId']}", **options)
121
265
  row['BackendServers'] = described_load_balancer_attributes['BackendServers']['BackendServer']
@@ -165,80 +309,119 @@ module Aly
165
309
  @listeners ||= exec('slb', 'DescribeLoadBalancerListeners', '--pager', 'path=Listeners', **options)['Listeners'] || []
166
310
  lb = @slb.find { |e| e['Address'] == host || e['Eip'] == host }
167
311
  listeners = @listeners.select { |e| e['LoadBalancerId'] == lb['LoadBalancerId'] }
168
- background_servers = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{lb['LoadBalancerId']}", **options)['BackendServers']['BackendServer']
169
312
 
170
- puts 'LoadBalancers:'
313
+ puts "\nLoanBalancer Id: %s, Name: %s" % [lb['LoadBalancerId'], lb['LoadBalancerName']]
314
+ puts "==============================================================\n\n"
315
+ background_servers = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{lb['LoadBalancerId']}", **options)['BackendServers']['BackendServer'] || []
316
+
317
+ puts ' LoadBalancer Basic Information:'
171
318
  puts([{
172
- Id: lb['LoadBalancerId'],
173
- Name: lb['LoadBalancerName'],
174
- Address: lb['Address'],
175
- Eip: lb['Eip'],
176
- Listeners: listeners.size
177
- }].table.to_s)
319
+ Id: lb['LoadBalancerId'],
320
+ Name: lb['LoadBalancerName'],
321
+ Address: lb['Address'],
322
+ Eip: lb['Eip'],
323
+ Listeners: listeners.size
324
+ }].table.to_s.gsub(/^/, ' '))
178
325
  puts
179
326
 
180
327
  if background_servers && background_servers.size > 0
181
- puts 'Default Backend Servers:'
182
- puts background_servers.table.to_s
328
+ puts ' Default Backend Servers:'
183
329
  puts
330
+
331
+ ecss = @ecs.select { |e| background_servers.map{|ee| ee['ServerId']}.include?(e['InstanceId']) }
332
+
333
+ puts ecss.map { |row|
334
+ {
335
+ Id: row['InstanceId'],
336
+ Name: row['InstanceName'],
337
+ PrivateIP: row['PrivateIP'].join(','),
338
+ PublicIP: row['PublicIP'].join(','),
339
+ CPU: row['Cpu'],
340
+ RAM: "#{row['Memory'] / 1024.0} GB"
341
+ }
342
+ }.table.to_s.gsub(/^/, ' ')
343
+ puts
344
+ end
345
+
346
+ vserver_groups = exec('slb', 'DescribeVServerGroups', '--pager', "--LoadBalancerId=#{lb['LoadBalancerId']}", **options)["VServerGroups"]["VServerGroup"] || []
347
+ vserver_group_servers = vserver_groups.flat_map do |vg|
348
+ vg_attr = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{vg['VServerGroupId']}", **options)["BackendServers"]["BackendServer"]
349
+ vg_attr.each_with_index.map do |attr, idx|
350
+ ecs = @ecs.find {|e| e['InstanceId'] == attr['ServerId'] }
351
+ {
352
+ VGroupId: (idx.zero? ? vg['VServerGroupId'] : ''),
353
+ VGroupName: (idx.zero? ? vg['VServerGroupName'] : ''),
354
+ Weight: attr['Weight'],
355
+ Port: attr['Port'],
356
+ Type: attr['Type'],
357
+ EcsId: attr['ServerId'],
358
+ EcsName: ecs['InstanceName'],
359
+ PrivateIP: ecs['PrivateIP'].join(','),
360
+ PublicIP: ecs['PublicIP'].join(','),
361
+ CPU: ecs['Cpu'],
362
+ RAM: "#{ecs['Memory'] / 1024.0} GB"
363
+ }
364
+ end + [nil]
365
+ end
366
+ puts ' VServer Groups:'
367
+ puts vserver_group_servers[0..-2].table.to_s.gsub(/^/, ' ')
368
+ puts
369
+
370
+ listeners.each do |listener|
371
+ listener_type = ['HTTP', 'HTTPS', 'TCP', 'TCPS', 'UDP'].find { |e| !listener["#{e}ListenerConfig"].empty? }
372
+ listener['ListenerType'] = listener_type
184
373
  end
185
374
 
186
375
  listeners_info = listeners.map do |listener|
187
376
  {
377
+ Description: listener['Description'],
188
378
  Port: listener['ListenerPort'],
189
379
  Protocol: listener['ListenerProtocol'],
190
380
  Status: listener['Status'],
381
+ HeathCheck: (listener["#{listener['ListenerType']}ListenerConfig"] || {}).dig("HealthCheck") || 'off',
191
382
  BackendServerPort: listener['BackendServerPort'],
192
383
  ForwardPort: listener.dig('HTTPListenerConfig', 'ForwardPort'),
193
- VServerGroup: listener['VServerGroupId']
384
+ VServerGroup: listener['VServerGroupId'],
385
+ AclStatus: listener['AclStatus'] || 'off',
386
+ AclType: listener['AclType'],
387
+ AclIds: (listener['AclIds'] || []).join(','),
194
388
  }
195
389
  end
196
390
 
197
- puts 'Configured Listeners:'
198
- puts listeners_info.table.to_s
391
+ puts ' Configured Listeners:'
392
+ puts listeners_info.table.to_s.gsub(/^/, ' ')
199
393
  puts
200
394
 
201
- listeners_info.each do |listener|
202
- if listener[:VServerGroup]
203
- vserver_group = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{listener[:VServerGroup]}", **options)["BackendServers"]["BackendServer"]
204
- puts "VServerGroup #{listener[:VServerGroup]}:"
205
- puts(vserver_group.map { |e|
206
- {
207
- EcsInstanceId: e['ServerId'],
208
- Port: e['Port'],
209
- Weight: e['Weight'],
210
- Type: e['Type']
211
- }
212
- }.table.to_s)
213
- puts
395
+ listener_rules = listeners.flat_map do |listener|
396
+ listener_type = listener['ListenerType']
397
+ next [] unless listener_type
398
+ rules = exec('slb', "DescribeLoadBalancer#{listener_type}ListenerAttribute", "--LoadBalancerId=#{lb['LoadBalancerId']}", "--ListenerPort=#{listener['ListenerPort']}", **options).dig('Rules', 'Rule') || []
399
+ rules.map do |rule|
400
+ {'Listener' => listener['Description']}.merge(rule)
214
401
  end
215
402
  end
216
403
 
217
- ecs_ids = background_servers.map { |e| e['ServerId'] }
218
- ecs_ids += listeners_info.flat_map { |e|
219
- if e[:VServerGroup]
220
- exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{e[:VServerGroup]}", **options)["BackendServers"]["BackendServer"].map { |e| e['ServerId'] }
221
- else
222
- []
223
- end
224
- }
225
- ecs_ids.uniq!
226
-
227
- ecss = @ecs.select { |e| ecs_ids.include?(e['InstanceId']) }
228
-
229
- puts "Referenced ECS Instances:"
230
-
231
- puts ecss.map { |row|
232
- {
233
- Id: row['InstanceId'],
234
- Name: row['InstanceName'],
235
- PrivateIP: row['PrivateIP'].join(','),
236
- PublicIP: row['PublicIP'].join(','),
237
- CPU: row['Cpu'],
238
- RAM: "#{row['Memory'] / 1024.0} GB"
239
- }
240
- }.table.to_s
404
+ puts ' Listener Rules:'
405
+ puts listener_rules.table.to_s.gsub(/^/, ' ')
406
+ puts
241
407
 
408
+ acl_ids = listeners.flat_map { |listener| listener['AclIds'] || [] }.uniq
409
+ unless acl_ids.empty?
410
+ alc_entries = acl_ids.flat_map do |acl_id|
411
+ attr = exec('slb', 'DescribeAccessControlListAttribute', "--AclId=#{acl_id}", **options)
412
+ (attr.dig('AclEntrys', 'AclEntry') || []).each_with_index.map do |e, idx|
413
+ {
414
+ AclId: (idx.zero? ? attr['AclId'] : ''),
415
+ AclName: (idx.zero? ? attr['AclName'] : ''),
416
+ AclEntryIP: e['AclEntryIP'],
417
+ AclEntryComment: e['AclEntryComment']
418
+ }
419
+ end + [nil]
420
+ end
421
+ puts ' Access Control Lists:'
422
+ puts alc_entries[0..-2].table.to_s.gsub(/^/, ' ')
423
+ puts
424
+ end
242
425
  end
243
426
 
244
427
  def show_ecs(host)
data/lib/aly/cli.rb CHANGED
@@ -4,6 +4,8 @@ module Aly
4
4
  class CLI < ::Thor
5
5
  class_option :profile, type: :string, optional: true, aliases: ['-p'], desc: 'select profile'
6
6
  class_option :detail, type: :boolean, optional: true, default: false, aliases: ['-d'], desc: 'show detail infomation in JSON format'
7
+ class_option :full, type: :boolean, optional: true, default: false, aliases: ['-f'], desc: 'print tables with more infomation'
8
+ class_option :acl, type: :boolean, optional: true, default: false, aliases: ['-a'], desc: 'show ACL entries'
7
9
 
8
10
  desc 'ecs', 'get ECS information'
9
11
  def ecs(query = nil)
data/lib/aly/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Aly
4
- VERSION = "0.2.3"
4
+ VERSION = "0.3.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liu Xiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-18 00:00:00.000000000 Z
11
+ date: 2022-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -88,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
88
  requirements:
89
89
  - - ">="
90
90
  - !ruby/object:Gem::Version
91
- version: 2.7.0
91
+ version: 2.5.0
92
92
  required_rubygems_version: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="