gclouder_undefined_resources 0.2.4 → 0.2.5
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 +4 -4
- data/lib/gclouder_undefined_resources.rb +5 -0
- data/lib/gclouder_undefined_resources/cli_args.rb +14 -7
- data/lib/gclouder_undefined_resources/remote_resources.rb +32 -36
- data/lib/gclouder_undefined_resources/remote_resources/remote.rb +21 -4
- data/lib/gclouder_undefined_resources/remote_resources/resource.rb +76 -23
- data/lib/gclouder_undefined_resources/remote_resources/resource/symbols.rb +25 -0
- data/lib/gclouder_undefined_resources/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 20430b49eb8ba80923b7f889e8ea10e4231a69fd
|
|
4
|
+
data.tar.gz: 526c81e66012a0d5638deb36cd7f3e062ca52759
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b5c005bda0d49fd5ae55b65aab68262a45da0eaa89d170b7634ae59bfb141a8381c70b53dbb7c5fc0ae990075f70406f7d8f5cbb0534451cea1bacfab1d53644
|
|
7
|
+
data.tar.gz: d9ee105a14940609a5850ebfe1f918aeb428b8c43a04f1899ab9f32048c4f8f7d5f86479b4245d16d70873d12b37da827234b4af284ff00727221cada9aea1bb
|
|
@@ -13,6 +13,7 @@ require "gclouder_undefined_resources/local_resources"
|
|
|
13
13
|
require "gclouder_undefined_resources/remote_resources"
|
|
14
14
|
require "gclouder_undefined_resources/remote_resources/remote"
|
|
15
15
|
require "gclouder_undefined_resources/remote_resources/resource"
|
|
16
|
+
require "gclouder_undefined_resources/remote_resources/resource/symbols"
|
|
16
17
|
|
|
17
18
|
module GClouderUndefinedResources
|
|
18
19
|
def self.run
|
|
@@ -50,5 +51,9 @@ module GClouderUndefinedResources
|
|
|
50
51
|
else
|
|
51
52
|
puts "unknown group-by type"
|
|
52
53
|
end
|
|
54
|
+
|
|
55
|
+
remote_resources.display_report unless CLIArgs.cli_args[:hide_report]
|
|
56
|
+
|
|
57
|
+
exit 1 if remote_resources.any_undefined_and_unfiltered?
|
|
53
58
|
end
|
|
54
59
|
end
|
|
@@ -18,13 +18,20 @@ module GClouderUndefinedResources
|
|
|
18
18
|
option_parser = Trollop::Parser.new do
|
|
19
19
|
banner "\n undefined gcp resources\n "
|
|
20
20
|
|
|
21
|
-
opt :local_resources,
|
|
22
|
-
|
|
23
|
-
opt :
|
|
24
|
-
|
|
25
|
-
opt :
|
|
26
|
-
|
|
27
|
-
opt :
|
|
21
|
+
opt :local_resources, "file containing local resource definitions", type: :string, required: true
|
|
22
|
+
opt :filter_config, "file containing filter config", type: :string
|
|
23
|
+
opt :key_file, "specify key file for gcloud(1) authentication\n ", type: :string
|
|
24
|
+
|
|
25
|
+
opt :group_by, "how to format output. valid values include: location, type\n ", type: :string, default: "location"
|
|
26
|
+
|
|
27
|
+
opt :show_filter_rule, "show filter matching output", type: :bool
|
|
28
|
+
opt :show_filter_name, "include filter rule name in output\n ", type: :bool
|
|
29
|
+
|
|
30
|
+
opt :hide_filtered, "hide filtered results from output", type: :bool, default: false
|
|
31
|
+
opt :hide_defined, "hide defined results from output", type: :bool, default: false
|
|
32
|
+
opt :hide_report, "display statistics for each resource status type\n ", type: :bool
|
|
33
|
+
|
|
34
|
+
opt :verbose, "verbose\n ", type: :bool
|
|
28
35
|
end
|
|
29
36
|
|
|
30
37
|
@cli_args = Trollop.with_standard_exception_handling(option_parser) do
|
|
@@ -2,24 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module GClouderUndefinedResources
|
|
4
4
|
class RemoteResources
|
|
5
|
-
module Symbols
|
|
6
|
-
def self.tick
|
|
7
|
-
"✓".green
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.x
|
|
11
|
-
"✗".red
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.tick_filtered
|
|
15
|
-
"✓".yellow
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def self.x_filtered
|
|
19
|
-
"✗".yellow
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
5
|
def initialize(project_id)
|
|
24
6
|
@project_id = project_id
|
|
25
7
|
@resources = []
|
|
@@ -27,6 +9,14 @@ module GClouderUndefinedResources
|
|
|
27
9
|
|
|
28
10
|
def collect
|
|
29
11
|
add Remote::GCloud.fetch(@project_id)
|
|
12
|
+
|
|
13
|
+
@resources = @resources.reject do |resource|
|
|
14
|
+
CLIArgs.cli_args[:hide_filtered] && resource.filtered?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@resources = @resources.reject do |resource|
|
|
18
|
+
CLIArgs.cli_args[:hide_defined] && resource.defined?
|
|
19
|
+
end
|
|
30
20
|
end
|
|
31
21
|
|
|
32
22
|
def add(resources)
|
|
@@ -66,15 +56,7 @@ module GClouderUndefinedResources
|
|
|
66
56
|
puts
|
|
67
57
|
|
|
68
58
|
resources_by_region.each do |resource|
|
|
69
|
-
|
|
70
|
-
status = resource.defined? ? Symbols.tick_filtered : Symbols.x_filtered
|
|
71
|
-
else
|
|
72
|
-
status = resource.defined? ? Symbols.tick : Symbols.x
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# FIXME: do the skipping stuff here, or display status of the resource name..
|
|
76
|
-
# FIXME: to_s in resource could include x or tick or whatever
|
|
77
|
-
puts " #{status} #{resource.name}"
|
|
59
|
+
puts " #{resource}"
|
|
78
60
|
end
|
|
79
61
|
end
|
|
80
62
|
end
|
|
@@ -108,19 +90,33 @@ module GClouderUndefinedResources
|
|
|
108
90
|
puts
|
|
109
91
|
|
|
110
92
|
resources_by_type.each do |resource|
|
|
111
|
-
|
|
112
|
-
status = resource.defined? ? Symbols.tick_filtered : Symbols.x_filtered
|
|
113
|
-
else
|
|
114
|
-
status = resource.defined? ? Symbols.tick : Symbols.x
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# FIXME: do the skipping stuff here, or display status of the resource name..
|
|
118
|
-
# FIXME: to_s in resource could include x or tick or whatever
|
|
119
|
-
puts " #{status} #{resource.name}"
|
|
93
|
+
puts " #{resource}"
|
|
120
94
|
end
|
|
121
95
|
end
|
|
122
96
|
end
|
|
123
97
|
end
|
|
124
98
|
end
|
|
99
|
+
|
|
100
|
+
def display_report
|
|
101
|
+
status_types = @resources.group_by { |resource| resource.status }
|
|
102
|
+
|
|
103
|
+
return if status_types.empty?
|
|
104
|
+
|
|
105
|
+
puts
|
|
106
|
+
puts " report"
|
|
107
|
+
puts
|
|
108
|
+
status_types.each do |status_type, resources|
|
|
109
|
+
puts " #{status_type} - #{resources.length}"
|
|
110
|
+
end
|
|
111
|
+
puts
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def any_undefined_and_unfiltered?
|
|
115
|
+
status_types = @resources.group_by { |resource| resource.status }
|
|
116
|
+
|
|
117
|
+
return if status_types.empty?
|
|
118
|
+
|
|
119
|
+
status_types.key?("✗".red)
|
|
120
|
+
end
|
|
125
121
|
end
|
|
126
122
|
end
|
|
@@ -26,6 +26,7 @@ module GClouderUndefinedResources
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
# FIXME: refactor
|
|
29
30
|
module ResourcesList
|
|
30
31
|
def self.fetch(project_id)
|
|
31
32
|
json = JSON.parse(Shell.run("gcloud alpha resources list --format json"))
|
|
@@ -33,15 +34,31 @@ module GClouderUndefinedResources
|
|
|
33
34
|
json.select do |resource|
|
|
34
35
|
result = true
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
if resource.key?("projectId")
|
|
38
|
+
result = nil if resource["projectId"] != project_id
|
|
39
|
+
#puts "skipping resource because project id does not match: #{resource['projectId']}"
|
|
40
|
+
elsif resource.key?("selfLink")
|
|
41
|
+
result = nil if resource["selfLink"] !~ /projects\/#{project_id}\//
|
|
42
|
+
#puts "skipping resource because project id does not match: #{resource['selfLink']}"
|
|
43
|
+
else
|
|
44
|
+
ap resource
|
|
45
|
+
puts "error: resource has no selfLink or projectId property, unable to determine project id"
|
|
46
|
+
exit 1
|
|
47
|
+
end
|
|
37
48
|
|
|
38
|
-
if resource
|
|
39
|
-
puts "
|
|
40
|
-
|
|
49
|
+
if !resource.key?("name")
|
|
50
|
+
puts "resource has no name key:"
|
|
51
|
+
ap resource
|
|
41
52
|
end
|
|
42
53
|
|
|
43
54
|
result
|
|
44
55
|
end.map do |resource|
|
|
56
|
+
if !resource.key?("name")
|
|
57
|
+
ap resource
|
|
58
|
+
puts "error: resource has no name key"
|
|
59
|
+
exit 1
|
|
60
|
+
end
|
|
61
|
+
|
|
45
62
|
Resource.new(resource["name"], resource)
|
|
46
63
|
end
|
|
47
64
|
end
|
|
@@ -22,6 +22,8 @@ module GClouderUndefinedResources
|
|
|
22
22
|
def region
|
|
23
23
|
return unless @data.key?("selfLink")
|
|
24
24
|
match = @data["selfLink"].match(/.*\/regions\/([^\/]+)/)
|
|
25
|
+
match = @data["location"].downcase if @data.key?("location") && !match[1]
|
|
26
|
+
return unless @data.key?("location") && @data["location"] == "global"
|
|
25
27
|
return match[1] if match
|
|
26
28
|
zone[0..-3] if zone
|
|
27
29
|
end
|
|
@@ -34,6 +36,7 @@ module GClouderUndefinedResources
|
|
|
34
36
|
|
|
35
37
|
def global?
|
|
36
38
|
return true if zone.nil? && region.nil?
|
|
39
|
+
return true if @data.key?("location") && @data["location"] == "global"
|
|
37
40
|
return unless @data.key?("selfLink")
|
|
38
41
|
!@data["selfLink"].match(/.*\/projects\/[^\/]+\/global/).nil?
|
|
39
42
|
end
|
|
@@ -84,20 +87,7 @@ module GClouderUndefinedResources
|
|
|
84
87
|
next
|
|
85
88
|
end
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
puts "filter: "
|
|
89
|
-
puts " description: #{filter['description']}"
|
|
90
|
-
puts " region: #{filter['region']}"
|
|
91
|
-
puts " zone: #{filter['zone']}"
|
|
92
|
-
puts " type: #{filter['type']}"
|
|
93
|
-
puts " name: #{filter['name']}"
|
|
94
|
-
puts "match: "
|
|
95
|
-
puts " region: #{region}"
|
|
96
|
-
puts " zone: #{zone}"
|
|
97
|
-
puts " type: #{original_type}"
|
|
98
|
-
puts " name: #{name}"
|
|
99
|
-
puts
|
|
100
|
-
end
|
|
90
|
+
@filter_rule = filter
|
|
101
91
|
|
|
102
92
|
return true
|
|
103
93
|
end
|
|
@@ -105,6 +95,54 @@ module GClouderUndefinedResources
|
|
|
105
95
|
false
|
|
106
96
|
end
|
|
107
97
|
|
|
98
|
+
# FIXME: refactor
|
|
99
|
+
def status
|
|
100
|
+
if self.filtered?
|
|
101
|
+
if self.defined?
|
|
102
|
+
if filter.dig("mark", "filtered")
|
|
103
|
+
filter["mark"]["filtered"]["symbol"].send(filter["mark"]["filtered"]["colour"])
|
|
104
|
+
else
|
|
105
|
+
Symbols.tick_filtered
|
|
106
|
+
end
|
|
107
|
+
else
|
|
108
|
+
if filter.dig("mark", "unfiltered")
|
|
109
|
+
filter["mark"]["unfiltered"]["symbol"].send(filter["mark"]["unfiltered"]["colour"])
|
|
110
|
+
else
|
|
111
|
+
Symbols.x_filtered
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
else
|
|
115
|
+
if self.defined?
|
|
116
|
+
Symbols.tick
|
|
117
|
+
else
|
|
118
|
+
Symbols.x
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def filter
|
|
124
|
+
@filter_rule
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def filter_description
|
|
128
|
+
if filter.key?("description")
|
|
129
|
+
"# #{filter["description"]}".gray
|
|
130
|
+
else
|
|
131
|
+
"# filter has no description".gray
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def to_s
|
|
136
|
+
s = "#{status} #{name}"
|
|
137
|
+
s += " #{filter_description}" if CLIArgs.cli_args[:show_filter_name] and filtered?
|
|
138
|
+
s += "\n#{formatted_filter_rule}" if CLIArgs.cli_args[:show_filter_rule] and filtered?
|
|
139
|
+
s
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def formatted_filter_rule
|
|
143
|
+
filter.ai.gsub("\n", "\n ").gsub(/^{/, " {")
|
|
144
|
+
end
|
|
145
|
+
|
|
108
146
|
private
|
|
109
147
|
|
|
110
148
|
def filters
|
|
@@ -120,13 +158,16 @@ module GClouderUndefinedResources
|
|
|
120
158
|
when "serviceAccount"
|
|
121
159
|
["service_accounts"]
|
|
122
160
|
|
|
161
|
+
# TODO: not yet implemented in gclouder
|
|
123
162
|
when "type.googleapis.com/cloud.bigstore.api.Bucket"
|
|
124
|
-
[]
|
|
163
|
+
["buckets"]
|
|
125
164
|
|
|
126
165
|
when "type.googleapis.com/cloud.dns.api.ManagedZone"
|
|
127
166
|
["dns", "zones"]
|
|
128
167
|
|
|
168
|
+
# TODO: not yet implemented in gclouder
|
|
129
169
|
when "type.googleapis.com/cloud.resourcemanager.Organization"
|
|
170
|
+
["resource_manager", "organization"]
|
|
130
171
|
|
|
131
172
|
when "type.googleapis.com/compute.BackendBucket"
|
|
132
173
|
["compute", "backend-buckets"]
|
|
@@ -161,8 +202,9 @@ module GClouderUndefinedResources
|
|
|
161
202
|
when "type.googleapis.com/compute.Router"
|
|
162
203
|
["compute", "router"]
|
|
163
204
|
|
|
205
|
+
# TODO: not yet implemented in gclouder
|
|
164
206
|
when "type.googleapis.com/compute.SslCertificate"
|
|
165
|
-
[]
|
|
207
|
+
["compute", "ssl_certificate"]
|
|
166
208
|
|
|
167
209
|
when "type.googleapis.com/compute.Subnetwork"
|
|
168
210
|
["subnets"]
|
|
@@ -176,26 +218,37 @@ module GClouderUndefinedResources
|
|
|
176
218
|
when "type.googleapis.com/compute.UrlMap"
|
|
177
219
|
["compute", "url_maps"]
|
|
178
220
|
|
|
221
|
+
# TODO: not yet implemented in gclouder
|
|
179
222
|
when "type.googleapis.com/google.api.servicemanagement.v1.ManagedService"
|
|
180
|
-
[]
|
|
223
|
+
["service_management", "service"]
|
|
181
224
|
|
|
225
|
+
# TODO: not yet implemented in gclouder
|
|
182
226
|
when "type.googleapis.com/google.appengine.v1.Application"
|
|
183
|
-
[]
|
|
227
|
+
["app", "app"]
|
|
184
228
|
|
|
229
|
+
# TODO: not yet implemented in gclouder
|
|
185
230
|
when "type.googleapis.com/google.appengine.v1.Service"
|
|
186
|
-
[]
|
|
231
|
+
["app", "service"]
|
|
187
232
|
|
|
233
|
+
# TODO: not yet implemented in gclouder
|
|
188
234
|
when "type.googleapis.com/google.appengine.v1.Version"
|
|
189
|
-
[]
|
|
235
|
+
["app", "version"]
|
|
190
236
|
|
|
237
|
+
# TODO: not yet implemented in gclouder
|
|
191
238
|
when "type.googleapis.com/google.cloud.billing.v1.BillingAccount"
|
|
192
|
-
[]
|
|
239
|
+
["billing", "account"]
|
|
193
240
|
|
|
241
|
+
# TODO: not yet implemented in gclouder
|
|
194
242
|
when "type.googleapis.com/google.cloud.dataproc.v1.Cluster"
|
|
195
|
-
[]
|
|
243
|
+
["dataproc", "cluster"]
|
|
196
244
|
|
|
245
|
+
# TODO: not yet implemented in gclouder
|
|
197
246
|
when "type.googleapis.com/google.cloudresourcemanager.projects.v1beta1.Project"
|
|
198
|
-
[]
|
|
247
|
+
["project"]
|
|
248
|
+
|
|
249
|
+
# TODO: not yet implemented in gclouder
|
|
250
|
+
when "type.googleapis.com/google.cloud.dataproc.v1.Job"
|
|
251
|
+
["dataproc", "job"]
|
|
199
252
|
|
|
200
253
|
else
|
|
201
254
|
puts "error: unknown or no '@type' property found for data:"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
module GClouderUndefinedResources
|
|
4
|
+
class RemoteResources
|
|
5
|
+
class Resource
|
|
6
|
+
module Symbols
|
|
7
|
+
def self.tick
|
|
8
|
+
"✓".green
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.x
|
|
12
|
+
"✗".red
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.tick_filtered
|
|
16
|
+
"✓".yellow
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.x_filtered
|
|
20
|
+
"✗".yellow
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gclouder_undefined_resources
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rob Wilson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-02-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: trollop
|
|
@@ -68,6 +68,7 @@ files:
|
|
|
68
68
|
- lib/gclouder_undefined_resources/remote_resources.rb
|
|
69
69
|
- lib/gclouder_undefined_resources/remote_resources/remote.rb
|
|
70
70
|
- lib/gclouder_undefined_resources/remote_resources/resource.rb
|
|
71
|
+
- lib/gclouder_undefined_resources/remote_resources/resource/symbols.rb
|
|
71
72
|
- lib/gclouder_undefined_resources/resource.rb
|
|
72
73
|
- lib/gclouder_undefined_resources/self_link.rb
|
|
73
74
|
- lib/gclouder_undefined_resources/shell.rb
|