@@ -117,7 +117,7 @@ def _get_storage_unique_name(self, disk_props):
117
117
access_mode = self ._get_storage_access_mode (disk_props )
118
118
storage_unique_name = f"{ storage_name } |{ account_name } |{ share_name } |{ mount_path } |{ access_mode } "
119
119
hash_value = hashlib .md5 (storage_unique_name .encode ()).hexdigest ()[:16 ] # Take first 16 chars of hash
120
- result = f"{ storage_name } { hash_value } "
120
+ result = f"{ storage_name } { hash_value } " . replace ( "-" , "" ). replace ( "_" , "" )
121
121
return result [:32 ] # Ensure total length is no more than 32
122
122
123
123
def _get_mount_options (self , disk_props ):
@@ -134,6 +134,39 @@ def _get_storage_enable_subpath(self, disk_props):
134
134
enableSubPath = disk_props .get ('customPersistentDiskProperties' , False ).get ('enableSubPath' , False )
135
135
return enableSubPath
136
136
137
+ def _get_app_storage_configs (self ):
138
+ storage_configs = []
139
+ apps = self .wrapper_data .get_apps ()
140
+ for app in apps :
141
+ # Check if app has properties and customPersistentDiskProperties
142
+ if 'properties' in app and 'customPersistentDisks' in app ['properties' ]:
143
+ disks = app ['properties' ].get ('customPersistentDisks' , [])
144
+ for disk_props in disks :
145
+ if self ._get_storage_enable_subpath (disk_props ) is True :
146
+ logger .warning ("Mismatch: enableSubPath of custom persistent disks is not supported in Azure Container Apps." )
147
+ # print("storage_name + account_name + share_name + mount_path + access_mode:", storage_name + account_name + share_name + mountPath + access_mode)
148
+ storage_config = {
149
+ 'paramContainerAppEnvStorageAccountKey' : self ._get_param_name_of_storage_account_key (disk_props ),
150
+ 'storageName' : self ._get_storage_unique_name (disk_props ),
151
+ 'shareName' : self ._get_storage_share_name (disk_props ),
152
+ 'accessMode' : self ._get_storage_access_mode (disk_props ),
153
+ 'accountName' : self ._get_storage_account_name (disk_props ),
154
+ }
155
+ if storage_config not in storage_configs :
156
+ storage_configs .append (storage_config )
157
+ return storage_configs
158
+
159
+ # app
160
+ def _get_container_image (self , app ):
161
+ blueDeployment = self .wrapper_data .get_blue_deployment_by_app (app )
162
+ if blueDeployment is not None :
163
+ if self .wrapper_data .is_support_custom_container_image_for_app (app ):
164
+ server = blueDeployment ['properties' ]['source' ].get ('customContainer' ).get ('server' , '' )
165
+ containerImage = blueDeployment ['properties' ]['source' ].get ('customContainer' ).get ('containerImage' , '' )
166
+ return f"{ server } /{ containerImage } "
167
+ else :
168
+ return None
169
+
137
170
# module name
138
171
def _get_app_module_name (self , app ):
139
172
appName = self ._get_resource_name (app )
@@ -159,6 +192,11 @@ def _get_param_name_of_storage_account_key(self, disk_props):
159
192
storage_unique_name = self ._get_storage_unique_name (disk_props )
160
193
return "containerAppEnvStorageAccountKeyOf_" + storage_unique_name
161
194
195
+ # get param name of paramContainerAppImagePassword
196
+ def _get_param_name_of_container_image_password (self , app ):
197
+ appName = self ._get_resource_name (app )
198
+ return "containerImagePasswordOf_" + appName .replace ("-" , "_" )
199
+
162
200
163
201
class SourceDataWrapper :
164
202
def __init__ (self , source ):
@@ -210,7 +248,7 @@ def is_support_sba(self):
210
248
return self .is_support_feature ('Microsoft.AppPlatform/Spring/applicationLiveViews' )
211
249
212
250
def is_support_gateway (self ):
213
- return self .is_support_feature ('Microsoft.AppPlatform/Spring/gateways/routeConfigs ' )
251
+ return self .is_support_feature ('Microsoft.AppPlatform/Spring/gateways' )
214
252
215
253
def get_asa_service (self ):
216
254
return self .get_resources_by_type ('Microsoft.AppPlatform/Spring' )[0 ]
@@ -228,12 +266,12 @@ def get_deployments_by_app(self, app):
228
266
def get_blue_deployment_by_app (self , app ):
229
267
deployments = self .get_deployments_by_app (app )
230
268
deployments = [deployment for deployment in deployments if deployment ['properties' ]['active' ] is True ]
231
- return deployments [0 ] if deployments else {}
269
+ return deployments [0 ] if deployments else None
232
270
233
271
def get_green_deployment_by_app (self , app ):
234
272
deployments = self .get_deployments_by_app (app )
235
273
deployments = [deployment for deployment in deployments if deployment ['properties' ]['active' ] is False ]
236
- return deployments [0 ] if deployments else {}
274
+ return deployments [0 ] if deployments else None
237
275
238
276
def get_green_deployments (self ):
239
277
deployments = self .get_deployments ()
@@ -295,3 +333,24 @@ def is_enabled_system_assigned_identity_for_app(self, app):
295
333
if identity is None :
296
334
return False
297
335
return identity .get ('type' ) == 'SystemAssigned'
336
+
337
+ def is_support_custom_container_image_for_deployment (self , deployment ):
338
+ if deployment is None :
339
+ return False
340
+ return deployment ['properties' ].get ('source' ) is not None and \
341
+ deployment ['properties' ]['source' ].get ('customContainer' ) is not None and \
342
+ deployment ['properties' ]['source' ].get ('type' ) == 'Container' and \
343
+ deployment ['properties' ]['source' ]['customContainer' ].get ('containerImage' ) is not None
344
+
345
+ def is_support_custom_container_image_for_app (self , app ):
346
+ blueDeployment = self .get_blue_deployment_by_app (app )
347
+ if blueDeployment is None :
348
+ return False
349
+ return self .is_support_custom_container_image_for_deployment (blueDeployment )
350
+
351
+ def is_private_custom_container_image (self , app ):
352
+ blueDeployment = self .get_blue_deployment_by_app (app )
353
+ if blueDeployment is None :
354
+ return False
355
+ if self .is_support_custom_container_image_for_app (app ):
356
+ return blueDeployment ['properties' ]['source' ].get ('customContainer' ).get ('imageRegistryCredential' , {}).get ('username' , None ) is not None
0 commit comments