gclouder_undefined_resources 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|