aly 0.1.2 → 0.2.1

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: 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