aly 0.1.3 → 0.2.2

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: 9259e511caf4ff304c7f0e3abb279ee2a72bdededc55f289a52b9e85b65d7d7c
4
- data.tar.gz: e4ba5cd7522b8bf53c02cca5eead898451fefdb344f56d31d09fc91e838be185
3
+ metadata.gz: 929950a91790b6ca3522f18cb114d29d58ccc1d4c61e4de6b649198d5624ecf3
4
+ data.tar.gz: 0c55d48418ec5a8661f8ef912dc7fc647514c99be0c14964a2f2d7fb4ed78198
5
5
  SHA512:
6
- metadata.gz: 63289e66578eaca5b6c8be92e6416e939370fd7b2b6c2d0e1603fa6455740683db5320bc45a69309a36d1cf7e747ef48e41b42337f60d8267c2be8f8ebd483a6
7
- data.tar.gz: aca415bbc279e4e08069eb791b776487f5ac72680fa57989a3bdcb438e5172948f4e624a9080c3c4bc489b8e9141adc18cc28c498276b1ba061f94b4215be197
6
+ metadata.gz: e3e21c88c0dc447b9ca035786bbe4f1c4504f148a7731cb9cc8b9d1205152392e5e83d7fb702aaefd6f20ffb5acea3fc22677f3bccd20332c0914391ceae2e30
7
+ data.tar.gz: da9a871f358fa988084dc84f5498c3800bd6eefc8467dcae6faf81fc7f4a2aab60cc6128cf84d387103ff92b658611dda502c4a9f1beb2162100749a6dc0b3e8
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.2)
4
+ aly (0.2.2)
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')
24
- selected = raw_out['Instances']['Instance'].each do |item|
25
- item['PrivateIP'] = (item['NetworkInterfaces']['NetworkInterface'] || []).map { |ni| ni['PrimaryIpAddress'] }.join(', ')
25
+ raw_out = exec('ecs', 'DescribeInstances', '--pager', **options)
26
+ selected = (raw_out['Instances']['Instance'] || []).each do |item|
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(',')
@@ -51,7 +53,8 @@ module Aly
51
53
  end
52
54
 
53
55
  def eip(*args, **options)
54
- raw_out = exec('vpc', 'DescribeEipAddresses', '--PageSize=100')
56
+ puts 'EIPs:'
57
+ raw_out = exec('vpc', 'DescribeEipAddresses', '--PageSize=100', **options)
55
58
  selected = raw_out['EipAddresses']['EipAddress']
56
59
 
57
60
  if query = args.first&.split(',')
@@ -63,7 +66,7 @@ module Aly
63
66
  if options['detail']
64
67
  puts JSON.pretty_generate(selected)
65
68
  else
66
- 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|
67
70
  result[item['NetworkInterfaceId']] = item
68
71
  end
69
72
  selected = selected.map do |row|
@@ -88,10 +91,10 @@ module Aly
88
91
  end
89
92
 
90
93
  def slb(*args, **options)
91
- raw_out = exec('slb', 'DescribeLoadBalancers', '--pager')
92
- selected = raw_out['LoadBalancers']['LoadBalancer']
94
+ raw_out = exec('slb', 'DescribeLoadBalancers', '--pager', **options)
95
+ selected = raw_out['LoadBalancers']['LoadBalancer'] || []
93
96
 
94
- 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|
95
98
  instance_id = listener['LoadBalancerId']
96
99
  result[instance_id] ||= []
97
100
  result[instance_id] << listener
@@ -109,11 +112,11 @@ module Aly
109
112
 
110
113
  if options['detail']
111
114
  selected.each do |row|
112
- described_load_balancer_attributes = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{row['LoadBalancerId']}")
115
+ described_load_balancer_attributes = exec('slb', 'DescribeLoadBalancerAttribute', "--LoadBalancerId=#{row['LoadBalancerId']}", **options)
113
116
  row['BackendServers'] = described_load_balancer_attributes['BackendServers']['BackendServer']
114
117
 
115
118
  row['Listeners'].select { |e| e['VServerGroupId'] }.each do |listener|
116
- vserver_group = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{listener['VServerGroupId']}")
119
+ vserver_group = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{listener['VServerGroupId']}", **options)
117
120
  listener['VServerGroup'] = vserver_group
118
121
  end
119
122
  end
@@ -144,8 +147,151 @@ module Aly
144
147
  end
145
148
  end
146
149
 
147
- def exec(command, sub_command, *args)
148
- 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}`)
149
295
  end
150
296
  end
151
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.3"
4
+ VERSION = "0.2.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.1.3
4
+ version: 0.2.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: 2021-10-22 00:00:00.000000000 Z
11
+ date: 2022-03-18 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