aly 0.1.1 → 0.2.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: 34fd1e28efaddb6086f9733f1d9ba642899d7b8401b75b91c3a3ec8328e6d4d7
4
- data.tar.gz: 43c4a862eb3068239a508dc08ad79e6842c315cbe6ea104a958cc7063fed7964
3
+ metadata.gz: a67b93ee1a1850b5f9af5afaffbd14d0d989f2394571f09c7a5d22382a128535
4
+ data.tar.gz: 837c13099835afd7b34f2e7db2143fb96ad1c208083ba84ee2bda0fd15eb1ed7
5
5
  SHA512:
6
- metadata.gz: 8217b6478e6291f5608be558d9356dad8baa71faea68b75f670c0e2b6e3f2a4cac5a378d81ea79b12259c6e46deceffdf16c11ffa053f4dc3f72013b5a5a60f3
7
- data.tar.gz: e3a63a7c64d1a923e74e26f188a2b7f5729472125c6a9f3d1d5378ce9179429a0bd3406187c339e3b8c55dcfac4f3c0691dd2d6bc50c96ef14bde70e01b2a873
6
+ metadata.gz: 480f9262bdc049a8b6028fd3cbaca0b3ca7e6be60506464be6a51e65cb227add6e74447d43ded3bccb8870294c8874f0736522c2ed0ae9bae243c50e09d417c5
7
+ data.tar.gz: 93bd2d071c76d4eb30552e7512e061e583906470debe1cd1b59d9a4ee70f1bc3a1397099b33bf19a9fc443fe297624771c405492ad6981fee56847f0d398875a
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.0)
4
+ aly (0.2.0)
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
@@ -27,9 +29,9 @@ module Aly
27
29
  item['PublicIP'] = item['PublicIpAddress']['IpAddress'].join(', ') if item['PublicIP'] == ''
28
30
  end
29
31
 
30
- if query = args.first
32
+ if query = args.first&.split(',')
31
33
  selected = selected.select do |item|
32
- item.values_at('InstanceId', 'InstanceName', 'PrivateIP', 'PublicIP').compact.any? { |e| e.include?(query) }
34
+ item.values_at('InstanceId', 'InstanceName', 'PrivateIP', 'PublicIP').compact.any? { |e| query.any? { |q| e.include?(q) } }
33
35
  end
34
36
  end
35
37
 
@@ -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,12 +53,13 @@ module Aly
49
53
  end
50
54
 
51
55
  def eip(*args, **options)
56
+ puts 'EIPs:'
52
57
  raw_out = exec('vpc', 'DescribeEipAddresses', '--PageSize=100')
53
58
  selected = raw_out['EipAddresses']['EipAddress']
54
59
 
55
- if query = args.first
60
+ if query = args.first&.split(',')
56
61
  selected = selected.select do |item|
57
- item.values_at('AllocationId', 'InstanceId', 'InstanceType', 'IpAddress').compact.any? { |e| e.include?(query) }
62
+ item.values_at('AllocationId', 'InstanceId', 'InstanceType', 'IpAddress').compact.any? { |e| query.any? { |q| e.include?(q) } }
58
63
  end
59
64
  end
60
65
 
@@ -99,9 +104,9 @@ module Aly
99
104
  lb['Listeners'] = listeners[lb['LoadBalancerId']] || []
100
105
  end
101
106
 
102
- if query = args.first
107
+ if query = args.first&.split(',')
103
108
  selected = selected.select do |lb|
104
- lb.values_at('LoadBalancerId', 'LoadBalancerName', 'Address').compact.any? { |e| e.include?(query) }
109
+ lb.values_at('LoadBalancerId', 'LoadBalancerName', 'Address').compact.any? { |e| query.any? { |q| e.include?(q) } }
105
110
  end
106
111
  end
107
112
 
@@ -142,6 +147,142 @@ module Aly
142
147
  end
143
148
  end
144
149
 
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)
159
+ @listeners ||= exec('slb', 'DescribeLoadBalancerListeners', '--pager', 'path=Listeners')['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']}")['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
+ BackendServers: background_servers.map { |e| e['ServerId'] }.join(', ')
171
+ }].table.to_s)
172
+ puts
173
+
174
+ listeners_info = listeners.map do |listener|
175
+ {
176
+ Port: listener['ListenerPort'],
177
+ Protocol: listener['ListenerProtocol'],
178
+ Status: listener['ListenerStatus'],
179
+ BackendServerPort: listener['BackendServerPort'],
180
+ ForwardPort: listener.dig('HTTPListenerConfig', 'ForwardPort'),
181
+ VServerGroup: listener['VServerGroupId']
182
+ }
183
+ end
184
+
185
+ puts 'Configured Listeners:'
186
+ puts listeners_info.table.to_s
187
+ puts
188
+
189
+ listeners_info.each do |listener|
190
+ if listener[:VServerGroup]
191
+ vserver_group = exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{listener[:VServerGroup]}")["BackendServers"]["BackendServer"]
192
+ puts "VServerGroup #{listener[:VServerGroup]}:"
193
+ puts(vserver_group.map { |e|
194
+ {
195
+ EcInstanceId: e['ServerId'],
196
+ Port: e['Port'],
197
+ Weight: e['Weight'],
198
+ Type: e['Type']
199
+ }
200
+ }.table.to_s)
201
+ puts
202
+ end
203
+ end
204
+
205
+ ecs_ids = background_servers.map { |e| e['ServerId'] }
206
+ ecs_ids += listeners_info.flat_map { |e|
207
+ if e[:VServerGroup]
208
+ exec('slb', 'DescribeVServerGroupAttribute', "--VServerGroupId=#{e[:VServerGroup]}")["BackendServers"]["BackendServer"].map { |e| e['ServerId'] }
209
+ else
210
+ []
211
+ end
212
+ }
213
+ ecs_ids.uniq!
214
+
215
+ ecss = @ecs.select { |e| ecs_ids.include?(e['InstanceId']) }
216
+
217
+ puts "Referenced ECS Instances:"
218
+
219
+ puts ecss.map { |row|
220
+ {
221
+ Id: row['InstanceId'],
222
+ Name: row['InstanceName'],
223
+ PrivateIP: row['PrivateIP'].join(', '),
224
+ PublicIP: row['PublicIP'].join(', '),
225
+ CPU: row['Cpu'],
226
+ RAM: "#{row['Memory'] / 1024.0} GB"
227
+ }
228
+ }.table.to_s
229
+
230
+ end
231
+
232
+ def show_ecs(host)
233
+ selected = @ecs.select { |e| e['AllIPs'].include?(host) }.map do |row|
234
+ {
235
+ Id: row['InstanceId'],
236
+ Name: row['InstanceName'],
237
+ PrivateIP: row['PrivateIP'].join(', '),
238
+ PublicIP: row['PublicIP'].join(', '),
239
+ CPU: row['Cpu'],
240
+ RAM: "#{row['Memory'] / 1024.0} GB"
241
+ }
242
+ end
243
+ puts 'ECS Instances:'
244
+ puts selected.table&.to_s
245
+ end
246
+
247
+ def eip_contains_host?(host)
248
+ @eip.any? { |eip| eip['IpAddress'] == host }
249
+ end
250
+
251
+ def show(*args, **options)
252
+ @slb ||= exec('slb', 'DescribeLoadBalancers', '--pager')['LoadBalancers']['LoadBalancer']
253
+
254
+ @eip ||= exec('vpc', 'DescribeEipAddresses', '--PageSize=100')['EipAddresses']['EipAddress']
255
+ unless @ecs
256
+ @ecs = exec('ecs', 'DescribeInstances', '--pager')['Instances']['Instance']
257
+ @ecs.each do |item|
258
+ item['PrivateIP'] = (item['NetworkInterfaces']['NetworkInterface'] || []).map { |ni| ni['PrimaryIpAddress'] }
259
+ item['PublicIP'] = []
260
+ if ip = item['EipAddress']['IpAddress']
261
+ item['PublicIP'] << ip
262
+ end
263
+ if ips = item['PublicIpAddress']['IpAddress']
264
+ item['PublicIP'] += ips
265
+ end
266
+ item['AllIPs'] = item['PrivateIP'] + item['PublicIP']
267
+ end
268
+ end
269
+
270
+ host = IPSocket::getaddress(args.first)
271
+
272
+ puts "Host: #{args.first} resolves to #{host}" if host != args.first
273
+ puts
274
+
275
+ if slb_contains_host?(host)
276
+ show_slb(host)
277
+ elsif ecs_contains_host?(host)
278
+ show_ecs(host)
279
+ elsif eip_contains_host?(host)
280
+ eip(host)
281
+ else
282
+ puts "Not found: #{host}"
283
+ end
284
+ end
285
+
145
286
  def exec(command, sub_command, *args)
146
287
  JSON.parse(`aliyun #{command} #{sub_command} #{args.join(' ')}`)
147
288
  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.1"
4
+ VERSION = "0.2.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.1.1
4
+ version: 0.2.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: 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