forked from GoogleCloudPlatform/magic-modules
-
Notifications
You must be signed in to change notification settings - Fork 0
/
product.rb
216 lines (173 loc) · 6.21 KB
/
product.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# Copyright 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
require 'api/object'
require 'google/logger'
require 'compile/core'
require 'json'
module Api
# Repesents a product to be managed
class Product < Api::Object::Named
# Inherited:
# The name of the product's API capitalised in the appropriate places.
# This isn't just the API name because it doesn't meaningfully separate
# words in the api name - "accesscontextmanager" vs "AccessContextManager"
# Example inputs: "Compute", "AccessContextManager"
# attr_reader :name
# The full name of the GCP product; eg "Cloud Bigtable"
attr_reader :display_name
# The name of the product's API; "compute", "accesscontextmanager"
def api_name
name.downcase
end
def to_s
# relies on the custom to_json definitions
JSON.pretty_generate(self)
end
# Prints a dot notation path to where the field is nested within the parent
# object when called on a property. eg: parent.meta.label.foo
# Redefined on Product to terminate the calls up the parent chain.
def lineage
name
end
def to_json(opts = nil)
json_out = {}
instance_variables.each do |v|
if v == :@objects
json_out['@resources'] = objects.map { |o| [o.name, o] }.to_h
elsif instance_variable_get(v) == false || instance_variable_get(v).nil?
# ignore false or missing because omitting them cleans up result
# and both are the effective defaults of their types
else
json_out[v] = instance_variable_get(v)
end
end
JSON.generate(json_out, opts)
end
# The product full name is the "display name" in string form intended for
# users to read in documentation; "Google Compute Engine", "Cloud Bigtable"
def product_full_name
if !display_name.nil?
display_name
else
name.underscore.humanize
end
end
attr_reader :objects
# The list of permission scopes available for the service
# For example: `https://www.googleapis.com/auth/compute`
attr_reader :scopes
# The API versions of this product
attr_reader :versions
# The base URL for the service API endpoint
# For example: `https://www.googleapis.com/compute/v1/`
attr_reader :base_url
# The APIs required to be enabled for this product.
# Usually just the product's API
attr_reader :apis_required
attr_reader :async
include Compile::Core
def validate
super
set_variables @objects, :__product
check :display_name, type: String
check :objects, type: Array, item_type: Api::Resource, required: true
check :scopes, type: Array, item_type: String, required: true
check :apis_required, type: Array, item_type: Api::Product::ApiReference
check :async, type: Api::Async
check_versions
end
# Represents a version of the API for this product
class Version < Api::Object
include Comparable
attr_reader :base_url
attr_reader :default
attr_reader :name
ORDER = %w[ga beta alpha].freeze
def validate
super
check :default, type: :boolean, default: false
check :base_url, type: String, required: true
check :name, type: String, allowed: ORDER, required: true
end
def to_s
str = "#{name}: #{base_url}"
str += ' (default)' if default
str
end
def <=>(other)
ORDER.index(name) <=> ORDER.index(other.name) if other.is_a?(Version)
end
end
def default_version
@versions.each do |v|
return v if v.default
end
return @versions.last if @versions.length == 1
end
def version_obj(name)
@versions.each do |v|
return v if v.name == name
end
raise "API version '#{name}' does not exist for product '#{@name}'"
end
def version_obj_or_default(name)
exists_at_version(name) ? version_obj(name) : default_version
end
# Not a conventional setter, so ignore rubocop's warning
# rubocop:disable Naming/AccessorMethodName
def set_properties_based_on_version(version)
@base_url = version.base_url
end
# rubocop:enable Naming/AccessorMethodName
def exists_at_version_or_lower(name)
# Versions aren't normally going to be empty since products need a
# base_url. This nil check exists for atypical products, like _bundle.
return true if @versions.nil?
name ||= Version::ORDER[0]
return false unless Version::ORDER.include?(name)
(0..Version::ORDER.index(name)).each do |i|
return true if exists_at_version(Version::ORDER[i])
end
false
end
def exists_at_version(name)
# Versions aren't normally going to be empty since products need a
# base_url. This nil check exists for atypical products, like _bundle.
return true if @versions.nil?
@versions.any? { |v| v.name == name }
end
private
def check_versions
check :versions, type: Array, item_type: Api::Product::Version, required: true
# Confirm that at most one version is the default
defaults = 0
@versions.each do |v|
defaults += 1 if v.default
end
raise "Product '#{@name}' must specify at most one default API version" \
if defaults > 1
raise "Product '#{@name}' must specify a default API version" \
if defaults.zero? && @versions.length > 1
end
# Represents any APIs that are required to be enabled to use this product
class ApiReference < Api::Object
attr_reader :name
attr_reader :url
def validate
super
check :name, type: String, required: true
check :url, type: String, required: true
end
end
end
end