32
32
according to their schema.
33
33
"""
34
34
35
+ _IMAGE_REPO_PREFIX_PROPERTY_NAME = '__image_repo_prefix__'
36
+
35
37
36
38
class InvalidProperty (Exception ):
37
39
pass
@@ -41,6 +43,10 @@ class MissingRequiredProperty(Exception):
41
43
pass
42
44
43
45
46
+ class MissingRequiredValue (Exception ):
47
+ pass
48
+
49
+
44
50
def main ():
45
51
parser = ArgumentParser (description = _PROG_HELP )
46
52
schema_values_common .add_to_argument_parser (parser )
@@ -64,25 +70,32 @@ def expand(values_dict, schema, app_uid=''):
64
70
"""Returns the expanded values according to schema."""
65
71
schema .validate ()
66
72
73
+ valid_property_names = set (schema .properties .keys () +
74
+ [_IMAGE_REPO_PREFIX_PROPERTY_NAME ])
67
75
for k in values_dict :
68
- if k not in schema . properties :
76
+ if k not in valid_property_names :
69
77
raise InvalidProperty ('No such property defined in schema: {}' .format (k ))
70
78
71
79
# Captures the final property name-value mappings.
72
80
# This has both properties directly specified under schema's `properties` and
73
81
# generated properties. See below for details about generated properties.
74
82
result = {}
75
- # Captures only the generated properties. These are not directly specified in the schema
76
- # under `properties`. Rather, their name are specified in special `generatedProperties` fields
77
- # under individual property `x-google-marketplace`.
83
+ # Captures only the generated properties. These are not directly specified in
84
+ # the schema under `properties`. Rather, their name are specified in special
85
+ # `generatedProperties` fields under each property's `x-google-marketplace`.
78
86
# Note that properties with generated values are NOT generated properties.
79
87
generated = {}
80
88
89
+ if schema .is_v2 ():
90
+ # Handles the images section of the schema.
91
+ generate_v2_image_properties (schema , values_dict , generated )
92
+
81
93
# Copy explicitly specified values and generate values into result.
82
94
for k , prop in schema .properties .iteritems ():
83
95
v = values_dict .get (k , None )
84
96
85
- # The value is not explicitly specified and thus is eligible for auto-generation.
97
+ # The value is not explicitly specified and
98
+ # thus is eligible for auto-generation.
86
99
if v is None :
87
100
if prop .password :
88
101
v = generate_password (prop .password )
@@ -106,7 +119,7 @@ def expand(values_dict, schema, app_uid=''):
106
119
if not isinstance (v , str ):
107
120
raise InvalidProperty (
108
121
'Invalid value for IMAGE property {}: {}' .format (k , v ))
109
- generate_properties_for_image (prop , v , generated )
122
+ generate_v1_properties_for_image (prop , v , generated )
110
123
elif prop .string :
111
124
if not isinstance (v , str ):
112
125
raise InvalidProperty (
@@ -118,13 +131,13 @@ def expand(values_dict, schema, app_uid=''):
118
131
'Invalid value for TLS_CERTIFICATE property {}: {}' .format (k , v ))
119
132
generate_properties_for_tls_certificate (prop , v , generated )
120
133
121
- # Copy generated properties into result, validating that there are no collisions.
122
134
if v is not None :
123
135
result [k ] = v
124
136
125
137
validate_value_types (result , schema )
126
138
validate_required_props (result , schema )
127
139
140
+ # Copy generated properties into result, validating no collisions.
128
141
for k , v in generated .iteritems ():
129
142
if k in result :
130
143
raise InvalidProperty (
@@ -155,7 +168,7 @@ def generate_properties_for_appuid(prop, value, result):
155
168
result [prop .application_uid .application_create ] = False if value else True
156
169
157
170
158
- def generate_properties_for_image (prop , value , result ):
171
+ def generate_v1_properties_for_image (prop , value , result ):
159
172
if prop .image .split_by_colon :
160
173
before_name , after_name = prop .image .split_by_colon
161
174
parts = value .split (':' , 1 )
@@ -185,6 +198,37 @@ def generate_properties_for_image(prop, value, result):
185
198
result [tag_name ] = tag_value
186
199
187
200
201
+ def generate_v2_image_properties (schema , values_dict , result ):
202
+ repo_prefix = values_dict .get (_IMAGE_REPO_PREFIX_PROPERTY_NAME , None )
203
+ if not repo_prefix :
204
+ raise MissingRequiredValue ('A valid value for __image_repo_prefix__ '
205
+ 'must be specified in values.yaml' )
206
+ tag = schema .x_google_marketplace .published_version
207
+ for img in schema .x_google_marketplace .images .values ():
208
+ if img .name :
209
+ # Allows an empty image name for legacy reason.
210
+ registry_repo = '{}/{}' .format (repo_prefix , img .name )
211
+ else :
212
+ registry_repo = repo_prefix
213
+ registry , repo = registry_repo .split ('/' , 1 )
214
+ full = '{}:{}' .format (registry_repo , tag )
215
+ for prop in img .properties .values ():
216
+ if prop .part_type == config_helper .IMAGE_PROJECTION_TYPE_FULL :
217
+ result [prop .name ] = full
218
+ elif prop .part_type == config_helper .IMAGE_PROJECTION_TYPE_REGISTRY :
219
+ result [prop .name ] = registry
220
+ elif prop .part_type == config_helper .IMAGE_PROJECTION_TYPE_REGISTRY_REPO :
221
+ result [prop .name ] = registry_repo
222
+ elif prop .part_type == config_helper .IMAGE_PROJECTION_TYPE_REPO :
223
+ result [prop .name ] = repo
224
+ elif prop .part_type == config_helper .IMAGE_PROJECTION_TYPE_TAG :
225
+ result [prop .name ] = tag
226
+ else :
227
+ raise InvalidProperty (
228
+ 'Invalid type for images.properties.type: {}' .format (
229
+ prop .part_type ))
230
+
231
+
188
232
def generate_properties_for_string (prop , value , result ):
189
233
if prop .string .base64_encoded :
190
234
result [prop .string .base64_encoded ] = base64 .b64encode (value )
0 commit comments