aly 0.1.2 → 0.2.1

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: add2aa880577ff73d3a010623270ad00ebd51f3997378d040725eb239dd0b043
4
- data.tar.gz: 8af5de2402336f2655b33ddaaa0bea2a9e0144176e8da9d230237b090fbf9d31
3
+ metadata.gz: 31c380fbca73a1136b7c8dea73e13ddd28f03a8e6e3a9a395bd55d225215ee56
4
+ data.tar.gz: b320bcbb2b06fadd45f1ba005526fba07657287dbdf81e7ba48c50c3e4d24723
5
5
  SHA512:
6
- metadata.gz: 9808a86bbaffb9470c73b74a1789ca05bd205886a919b0d2c11fe91ced18f55c3550ca8855e8c69f7d73fdfcc2fe87c75796cfd1677cf7afd0daef5d9200ab64
7
- data.tar.gz: 04ab0a3be23ac8b4caa7a5d537bdb26270e04b731224a059c283354806801f6369175f18ce4ea96ad9afee8f9493a8c112685855f1f458528155fbba696aaaa4
6
+ metadata.gz: 3ea21f6de6ea31ded361e64a40b97f7f48fe1e8652994effebbd99d1b380c1b8a08d11519cdb4dd2d58196f66fd24adde2cc5d4d2069367809c8e7766cab4906
7
+ data.tar.gz: 1a5f4e03792bded3c18cb798d03c574a35f96bda022c36265f0ff281cd7d52f8fe3edd987dbc36826768272f824b20dd42b320da63e30fa576b4a7032b4f8034
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ /.idea/
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- aly (0.1.1)
4
+ aly (0.2.1)
5
5
  terminal-table (~> 1.8.0)
6
6
  thor (~> 0.20.0)
7
7
 
@@ -39,6 +39,7 @@ GEM
39
39
 
40
40
  PLATFORMS
41
41
  x86_64-darwin-20
42
+ x86_64-darwin-21
42
43
 
43
44
  DEPENDENCIES
44
45
  aly!
data/lib/aly/app.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'json'
2
2
  require 'terminal-table'
3
+ require 'socket'
4
+
3
5
 
4
6
  class Array
5
7
  def table
@@ -20,11 +22,11 @@ module Aly
20
22
  end
21
23
 
22
24
  def ecs(*args, **options)
23
- raw_out = exec('ecs', 'DescribeInstances', '--pager')
25
+ raw_out = exec('ecs', 'DescribeInstances', '--pager', **options)
24
26
  selected = raw_out['Instances']['Instance'].each do |item|
25
- item['PrivateIP'] = (item['NetworkInterfaces']['NetworkInterface'] || []).map { |ni| ni['PrimaryIpAddress'] }.join(', ')
27
+ item['PrivateIP'] = (item['NetworkInterfaces']['NetworkInterface'] || []).map { |ni| ni['PrimaryIpAddress'] }.join(',')
26
28
  item['PublicIP'] = item['EipAddress']['IpAddress'] || ''
27
- item['PublicIP'] = item['PublicIpAddress']['IpAddress'].join(', ') if item['PublicIP'] == ''
29
+ item['PublicIP'] = item['PublicIpAddress']['IpAddress'].join(',') if item['PublicIP'] == ''
28
30
  end
29
31
 
30
32
  if query = args.first&.split(',')
@@ -41,7 +43,9 @@ module Aly
41
43
  Id: row['InstanceId'],
42
44
  Name: row['InstanceName'],
43
45
  PrivateIP: row['PrivateIP'],
44
- PublicIP: row['PublicIP']
46
+ PublicIP: row['PublicIP'],
47
+ CPU: row['Cpu'],
48
+ RAM: "#{row['Memory'] / 1024.0} GB"
45
49
  }
46
50
  end
47
51
  puts selected.table&.to_s
@@ -49,7 +53,8 @@ module Aly
49
53
  end
50
54
 
51
55
  def eip(*args, **options)
52
- raw_out = exec('vpc', 'DescribeEipAddresses', '--PageSize=100')
56
+ puts 'EIPs:'
57
+ raw_out = exec('vpc', 'DescribeEipAddresses', '--PageSize=100', **options)
53
58
  selected = raw_out['EipAddresses']['EipAddress']
54
59
 
55
60
  if query = args.first&.split(',')
@@ -61,7 +66,7 @@ module Aly
61
66
  if options['detail']
62
67
  puts JSON.pretty_generate(selected)
63
68
  else
64
- net_intefraces = exec('ecs', 'DescribeNetworkInterfaces', '--pager')['NetworkInterfaceSets']['NetworkInterfaceSet'].each_with_object({}) do |item, result|
69
+ net_intefraces = exec('ecs', 'DescribeNetworkInterfaces', '--pager', **options)['NetworkInterfaceSets']['NetworkInterfaceSet'].each_with_object({}) do |item, result|
65
70
  result[item['NetworkInterfaceId']] = item
66
71
  end
67
72
  selected = selected.map do |row|
@@ -86,10 +91,10 @@ module Aly
86
91
  end
87
92
 
88
93
  def slb(*args, **options)
89
- raw_out = exec('slb', 'DescribeLoadBalancers', '--pager')
94
+ raw_out = exec('slb', 'DescribeLoadBalancers', '--pager', **options)
90
95
  selected = raw_out['LoadBalancers']['LoadBalancer']
91
96
 
92
- listeners = exec('slb', 'DescribeLoadBalancerListeners', '--pager', 'path=Listeners')['Listeners'].each_with_object({}) do |listener, result|
97
+ listeners = exec('slb', 'DescribeLoadBalancerListeners', '--pager', 'path=Listeners', **options)['Listeners'].each_with_object({}) do |listener, result|
93
98
  instance_id = listener['LoadBalancerId']
94
99
  result[instance_id] ||= []
95
100
  result[instance_id] << listener
@@ -107,11 +112,11 @@ module Aly
107
112
 
108
113
  if options['detail']
109
114
  selected.each do |row|
110
- described_load_balancer_attributes = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{row['LoadBalancerId']}")
115
+ described_load_balancer_attributes = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{row['LoadBalancerId']}", **options)
111
116
  row['BackendServers'] = described_load_balancer_attributes['BackendServers']['BackendServer']
112
117
 
113
118
  row['Listeners'].select { |e| e['VServerGroupId'] }.each do |listener|
114
- vserver_group = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{listener['VServerGroupId']}")
119
+ vserver_group = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{listener['VServerGroupId']}", **options)
115
120
  listener['VServerGroup'] = vserver_group
116
121
  end
117
122
  end
@@ -142,8 +147,151 @@ module Aly
142
147
  end
143
148
  end
144
149
 
145
- def exec(command, sub_command, *args)
146
- JSON.parse(`aliyun #{command} #{sub_command} #{args.join(' ')}`)
150
+ def slb_contains_host?(host)
151
+ @slb.any? { |lb| lb['Address'] == host }
152
+ end
153
+
154
+ def ecs_contains_host?(host)
155
+ @ecs.any? { |item| item['AllIPs'].include?(host) }
156
+ end
157
+
158
+ def show_slb(host, **options)
159
+ @listeners ||= exec('slb', 'DescribeLoadBalancerListeners', '--pager', 'path=Listeners', **options)['Listeners']
160
+ lb = @slb.find { |e| e['Address'] == host }
161
+ listeners = @listeners.select { |e| e['LoadBalancerId'] == lb['LoadBalancerId'] }
162
+ background_servers = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{lb['LoadBalancerId']}", **options)['BackendServers']['BackendServer']
163
+
164
+ puts 'LoadBalancers:'
165
+ puts([{
166
+ Id: lb['LoadBalancerId'],
167
+ Name: lb['LoadBalancerName'],
168
+ Address: lb['Address'],
169
+ Listeners: listeners.size
170
+ }].table.to_s)
171
+ puts
172
+
173
+ if background_servers && background_servers.size > 0
174
+ puts 'Default Backend Servers:'
175
+ puts background_servers.table.to_s
176
+ puts
177
+ end
178
+
179
+ listeners_info = listeners.map do |listener|
180
+ {
181
+ Port: listener['ListenerPort'],
182
+ Protocol: listener['ListenerProtocol'],
183
+ Status: listener['Status'],
184
+ BackendServerPort: listener['BackendServerPort'],
185
+ ForwardPort: listener.dig('HTTPListenerConfig', 'ForwardPort'),
186
+ VServerGroup: listener['VServerGroupId']
187
+ }
188
+ end
189
+
190
+ puts 'Configured Listeners:'
191
+ puts listeners_info.table.to_s
192
+ puts
193
+
194
+ listeners_info.each do |listener|
195
+ if listener[:VServerGroup]
196
+ vserver_group = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{listener[:VServerGroup]}", **options)["BackendServers"]["BackendServer"]
197
+ puts "VServerGroup #{listener[:VServerGroup]}:"
198
+ puts(vserver_group.map { |e|
199
+ {
200
+ EcsInstanceId: e['ServerId'],
201
+ Port: e['Port'],
202
+ Weight: e['Weight'],
203
+ Type: e['Type']
204
+ }
205
+ }.table.to_s)
206
+ puts
207
+ end
208
+ end
209
+
210
+ ecs_ids = background_servers.map { |e| e['ServerId'] }
211
+ ecs_ids += listeners_info.flat_map { |e|
212
+ if e[:VServerGroup]
213
+ exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{e[:VServerGroup]}", **options)["BackendServers"]["BackendServer"].map { |e| e['ServerId'] }
214
+ else
215
+ []
216
+ end
217
+ }
218
+ ecs_ids.uniq!
219
+
220
+ ecss = @ecs.select { |e| ecs_ids.include?(e['InstanceId']) }
221
+
222
+ puts "Referenced ECS Instances:"
223
+
224
+ puts ecss.map { |row|
225
+ {
226
+ Id: row['InstanceId'],
227
+ Name: row['InstanceName'],
228
+ PrivateIP: row['PrivateIP'].join(','),
229
+ PublicIP: row['PublicIP'].join(','),
230
+ CPU: row['Cpu'],
231
+ RAM: "#{row['Memory'] / 1024.0} GB"
232
+ }
233
+ }.table.to_s
234
+
235
+ end
236
+
237
+ def show_ecs(host)
238
+ selected = @ecs.select { |e| e['AllIPs'].include?(host) }.map do |row|
239
+ {
240
+ Id: row['InstanceId'],
241
+ Name: row['InstanceName'],
242
+ PrivateIP: row['PrivateIP'].join(','),
243
+ PublicIP: row['PublicIP'].join(','),
244
+ CPU: row['Cpu'],
245
+ RAM: "#{row['Memory'] / 1024.0} GB"
246
+ }
247
+ end
248
+ puts 'ECS Instances:'
249
+ puts selected.table&.to_s
250
+ end
251
+
252
+ def eip_contains_host?(host)
253
+ @eip.any? { |eip| eip['IpAddress'] == host }
254
+ end
255
+
256
+ def show(*args, **options)
257
+ @slb ||= exec('slb', 'DescribeLoadBalancers', '--pager', **options)['LoadBalancers']['LoadBalancer']
258
+
259
+ @eip ||= exec('vpc', 'DescribeEipAddresses', '--PageSize=100', **options)['EipAddresses']['EipAddress']
260
+ unless @ecs
261
+ @ecs = exec('ecs', 'DescribeInstances', '--pager', **options)['Instances']['Instance']
262
+ @ecs.each do |item|
263
+ item['PrivateIP'] = (item['NetworkInterfaces']['NetworkInterface'] || []).map { |ni| ni['PrimaryIpAddress'] }
264
+ item['PublicIP'] = []
265
+ if ip = item['EipAddress']['IpAddress']
266
+ item['PublicIP'] << ip
267
+ end
268
+ if ips = item['PublicIpAddress']['IpAddress']
269
+ item['PublicIP'] += ips
270
+ end
271
+ item['AllIPs'] = item['PrivateIP'] + item['PublicIP']
272
+ end
273
+ end
274
+
275
+ host = IPSocket::getaddress(args.first)
276
+
277
+ puts "Host: #{args.first} resolves to #{host}" if host != args.first
278
+ puts
279
+
280
+ if slb_contains_host?(host)
281
+ show_slb(host, **options)
282
+ elsif ecs_contains_host?(host)
283
+ show_ecs(host)
284
+ elsif eip_contains_host?(host)
285
+ eip(host)
286
+ else
287
+ puts "Not found: #{host}"
288
+ end
289
+ end
290
+
291
+ def exec(command, sub_command, *args, **options)
292
+ command = "aliyun #{command} #{sub_command} #{args.join(' ')}"
293
+ command += " -p #{options['profile']}" if options['profile']
294
+ JSON.parse(`#{command}`)
147
295
  end
148
296
  end
149
297
  end
data/lib/aly/cli.rb CHANGED
@@ -20,6 +20,11 @@ module Aly
20
20
  App.new.start(options: options, command: :slb, args: [query])
21
21
  end
22
22
 
23
+ desc 'show', 'show resource information of host'
24
+ def show(host = nil)
25
+ App.new.start(options: options, command: :show, args: [host])
26
+ end
27
+
23
28
  class << self
24
29
  def main(args)
25
30
  start(args)
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.1.2"
4
+ VERSION = "0.2.1"
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.1.2
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Liu Xiang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-19 00:00:00.000000000 Z
11
+ date: 2022-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -95,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  requirements: []
98
- rubygems_version: 3.2.3
98
+ rubygems_version: 3.3.3
99
99
  signing_key:
100
100
  specification_version: 4
101
101
  summary: A simple wrapper for aliyun cli