aly 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f26b851dc09f00694624a45426546e11bc72c63de0a991ceb1e6b1e8989a3f1
4
- data.tar.gz: e4f1e81074036af2e6565f0f98a30ffd7a81dc82a1c42bb878f6357c5a93cf55
3
+ metadata.gz: 9db212d7233b62974d4d2b74909f00090561d6dbe874950e580d92d84be67b5f
4
+ data.tar.gz: de5bdb35a47c607db653a5befb8f55a82f53dbaca1c28646c00b54be263dd52d
5
5
  SHA512:
6
- metadata.gz: c762fdf73886adb7229a88510e613ec7d58966dc42cb1fe98bf3d84b7082274551e2201f08439953c467743561e90a4229d777294963d765a68987f0c3916c2d
7
- data.tar.gz: 97f110b453a54434943d380ad960536dc26934ceff82b6f8fac8782011c38f2e8aba9692ff56cd8d5714c2df78926f0a947e965d78169e55f8d9fcf1f35d9796
6
+ metadata.gz: b95c2203787b28ff2abeb5cfe2b54015619c6289a21ef631b8dc8c6c6dbb599600fa9a1113afb99300d6262c8452d41b81e82d117c9a88f98b4fe80ccd67cfd1
7
+ data.tar.gz: 3d2178da37d57a8c90a585640e6ed60aa9cafff01c449165c10929fc8c0c362a00b06fbb5c2708c02ef931e565a3368955fc3c3bcaa900f66bc15b21e50dbd20
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.0)
5
5
  terminal-table (~> 1.8.0)
6
6
  thor (~> 0.20.0)
7
7
 
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,122 @@ 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:"
404
+ puts ' Listener Rules:'
405
+ puts listener_rules.table.to_s.gsub(/^/, ' ')
406
+ puts
230
407
 
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
408
+ if options['acl']
409
+ acl_ids = listeners.flat_map { |listener| listener['AclIds'] || [] }.uniq
410
+ unless acl_ids.empty?
411
+ alc_entries = acl_ids.flat_map do |acl_id|
412
+ attr = exec('slb', 'DescribeAccessControlListAttribute', "--AclId=#{acl_id}", **options)
413
+ (attr.dig('AclEntrys', 'AclEntry') || []).each_with_index.map do |e, idx|
414
+ {
415
+ AclId: (idx.zero? ? attr['AclId'] : ''),
416
+ AclName: (idx.zero? ? attr['AclName'] : ''),
417
+ AclEntryIP: e['AclEntryIP'],
418
+ AclEntryComment: e['AclEntryComment']
419
+ }
420
+ end + [nil]
421
+ end
422
+ puts ' Access Control Lists:'
423
+ puts alc_entries[0..-2].table.to_s.gsub(/^/, ' ')
424
+ puts
425
+ end
241
426
 
427
+ end
242
428
  end
243
429
 
244
430
  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.0"
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.0
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