@@ -1419,12 +1419,12 @@ def get_vm_to_update_by_aaz(cmd, resource_group_name, vm_name):
14191419 from .operations .vm import VMShow
14201420
14211421 vm = VMShow (cli_ctx = cmd .cli_ctx )(command_args = {
1422- ' resource_group' : resource_group_name ,
1422+ " resource_group" : resource_group_name ,
14231423 "vm_name" : vm_name
14241424 })
14251425
14261426 # To avoid unnecessary permission check of image
1427- storage_profile = vm .get (' storageProfile' , {})
1427+ storage_profile = vm .get (" storageProfile" , {})
14281428 storage_profile ["imageReference" ] = None
14291429
14301430 return vm
@@ -1739,6 +1739,40 @@ def set_vm(cmd, instance, lro_operation=None, no_wait=False):
17391739 return LongRunningOperation (cmd .cli_ctx )(poller )
17401740
17411741
1742+ # Notes: vm format is in snake_case
1743+ def set_vm_by_aaz (cmd , vm , no_wait = False ):
1744+ from .aaz .latest .vm import Create as _VMCreate
1745+
1746+ parsed_id = _parse_rg_name (vm ["id" ])
1747+ vm ["resource_group" ] = parsed_id [0 ]
1748+ vm ["vm_name" ] = parsed_id [1 ]
1749+ vm ["no_wait" ] = no_wait
1750+
1751+ class SetVM (_VMCreate ):
1752+ def _output (self , * args , ** kwargs ):
1753+ from azure .cli .core .aaz import AAZUndefined , has_value
1754+
1755+ # Resolve flatten conflict
1756+ # When the type field conflicts, the type in inner layer is ignored and the outer layer is applied
1757+ if has_value (self .ctx .vars .instance .resources ):
1758+ for resource in self .ctx .vars .instance .resources :
1759+ if has_value (resource .type ):
1760+ resource .type = AAZUndefined
1761+
1762+ result = self .deserialize_output (self .ctx .vars .instance , client_flatten = True )
1763+ if result .get ('osProfile' , {}).get ('secrets' , []):
1764+ for secret in result ['osProfile' ]['secrets' ]:
1765+ for cert in secret .get ('vaultCertificates' , []):
1766+ if not cert .get ('certificateStore' ):
1767+ cert ['certificateStore' ] = None
1768+ return result
1769+
1770+ vm = LongRunningOperation (cmd .cli_ctx )(
1771+ SetVM (cli_ctx = cmd .cli_ctx )(command_args = vm ))
1772+
1773+ return vm
1774+
1775+
17421776def patch_vm (cmd , resource_group_name , vm_name , vm ):
17431777 client = _compute_client_factory (cmd .cli_ctx )
17441778 poller = client .virtual_machines .begin_update (resource_group_name , vm_name , vm )
@@ -3288,51 +3322,75 @@ def get_vm_format_secret(cmd, secrets, certificate_store=None, keyvault=None, re
32883322def add_vm_secret (cmd , resource_group_name , vm_name , keyvault , certificate , certificate_store = None ):
32893323 from azure .mgmt .core .tools import parse_resource_id
32903324 from ._vm_utils import create_data_plane_keyvault_certificate_client , get_key_vault_base_url
3291- VaultSecretGroup , SubResource , VaultCertificate = cmd . get_models (
3292- 'VaultSecretGroup' , 'SubResource' , 'VaultCertificate' )
3293- vm = get_vm_to_update ( cmd , resource_group_name , vm_name )
3325+ from . operations . vm import convert_show_result_to_snake_case
3326+ vm = get_vm_to_update_by_aaz ( cmd , resource_group_name , vm_name )
3327+ vm = convert_show_result_to_snake_case ( vm )
32943328
32953329 if '://' not in certificate : # has a cert name rather a full url?
32963330 keyvault_client = create_data_plane_keyvault_certificate_client (
32973331 cmd .cli_ctx , get_key_vault_base_url (cmd .cli_ctx , parse_resource_id (keyvault )['name' ]))
32983332 cert_info = keyvault_client .get_certificate (certificate )
32993333 certificate = cert_info .secret_id
33003334
3301- if not _is_linux_os (vm ):
3335+ if not _is_linux_os_by_aaz (vm ):
33023336 certificate_store = certificate_store or 'My'
33033337 elif certificate_store :
33043338 raise CLIError ('Usage error: --certificate-store is only applicable on Windows VM' )
3305- vault_cert = VaultCertificate (certificate_url = certificate , certificate_store = certificate_store )
3306- vault_secret_group = next ((x for x in vm .os_profile .secrets
3307- if x .source_vault and x .source_vault .id .lower () == keyvault .lower ()), None )
3339+ vault_cert = {
3340+ 'certificate_store' : certificate_store ,
3341+ 'certificate_url' : certificate
3342+ }
3343+ vault_secret_group = next ((x for x in vm .get ('os_profile' , {}).get ('secrets' , [])
3344+ if x .get ('source_vault' , {}).get ('id' , '' ).lower () == keyvault .lower ()), None )
33083345 if vault_secret_group :
3309- vault_secret_group .vault_certificates .append (vault_cert )
3346+ certs = vault_secret_group .get ('vault_certificates' , [])
3347+ certs .append (vault_cert )
3348+ vault_secret_group ['vault_certificates' ] = certs
33103349 else :
3311- vault_secret_group = VaultSecretGroup (source_vault = SubResource (id = keyvault ), vault_certificates = [vault_cert ])
3312- vm .os_profile .secrets .append (vault_secret_group )
3313- vm = set_vm (cmd , vm )
3314- return vm .os_profile .secrets
3350+ vault_secret_group = {
3351+ 'source_vault' : {
3352+ 'id' : keyvault
3353+ },
3354+ 'vault_certificates' : [vault_cert ]
3355+ }
3356+
3357+ if not vm .get ('os_profile' ):
3358+ vm ['os_profile' ] = {'secret' : []}
3359+
3360+ if not vm .get ('os_profile' ).get ('secrets' ):
3361+ vm ['os_profile' ]['secrets' ] = []
3362+
3363+ vm ['os_profile' ]['secrets' ].append (vault_secret_group )
3364+
3365+ vm = set_vm_by_aaz (cmd , vm )
3366+ return vm .get ('osProfile' , {}).get ('secrets' , [])
33153367
33163368
33173369def list_vm_secrets (cmd , resource_group_name , vm_name ):
3318- vm = get_vm (cmd , resource_group_name , vm_name )
3319- if vm .os_profile :
3320- return vm .os_profile .secrets
3321- return []
3370+ vm = get_vm_by_aaz (cmd , resource_group_name , vm_name )
3371+
3372+ if vm .get ('osProfile' , {}).get ('secrets' , []):
3373+ for secret in vm ['osProfile' ]['secrets' ]:
3374+ for cert in secret .get ('vaultCertificates' , []):
3375+ if not cert .get ('certificateStore' ):
3376+ cert ['certificateStore' ] = None
3377+
3378+ return vm .get ('osProfile' , {}).get ('secrets' , [])
33223379
33233380
33243381def remove_vm_secret (cmd , resource_group_name , vm_name , keyvault , certificate = None ):
3325- vm = get_vm_to_update (cmd , resource_group_name , vm_name )
3382+ from .operations .vm import convert_show_result_to_snake_case
3383+ vm = get_vm_to_update_by_aaz (cmd , resource_group_name , vm_name )
33263384
33273385 # support 2 kinds of filter:
33283386 # a. if only keyvault is supplied, we delete its whole vault group.
33293387 # b. if both keyvault and certificate are supplied, we only delete the specific cert entry.
33303388
3331- to_keep = vm .os_profile . secrets
3389+ to_keep = vm .get ( 'osProfile' , {}). get ( ' secrets' , [])
33323390 keyvault_matched = []
33333391 if keyvault :
33343392 keyvault = keyvault .lower ()
3335- keyvault_matched = [x for x in to_keep if x .source_vault and x . source_vault . id .lower () == keyvault ]
3393+ keyvault_matched = [x for x in to_keep if x .get ( 'sourceVault' , {}). get ( 'id' , '' ) .lower () == keyvault ]
33363394
33373395 if keyvault and not certificate :
33383396 to_keep = [x for x in to_keep if x not in keyvault_matched ]
@@ -3342,13 +3400,15 @@ def remove_vm_secret(cmd, resource_group_name, vm_name, keyvault, certificate=No
33423400 if '://' not in cert_url_pattern : # just a cert name?
33433401 cert_url_pattern = '/' + cert_url_pattern + '/'
33443402 for x in temp :
3345- x .vault_certificates = ([v for v in x .vault_certificates
3346- if not (v .certificate_url and cert_url_pattern in v .certificate_url .lower ())])
3347- to_keep = [x for x in to_keep if x .vault_certificates ] # purge all groups w/o any cert entries
3348-
3349- vm .os_profile .secrets = to_keep
3350- vm = set_vm (cmd , vm )
3351- return vm .os_profile .secrets
3403+ x ['vaultCertificates' ] = [v for v in x .get ('vaultCertificates' )
3404+ if not (v .get ('certificateUrl' ) and
3405+ cert_url_pattern in v .get ('certificateUrl' , '' ).lower ())]
3406+ to_keep = [x for x in to_keep if x .get ('vaultCertificates' )] # purge all groups w/o any cert entries
3407+
3408+ vm ['osProfile' ]['secrets' ] = to_keep
3409+ vm = convert_show_result_to_snake_case (vm )
3410+ vm = set_vm_by_aaz (cmd , vm )
3411+ return vm .get ('osProfile' , {}).get ('secrets' , [])
33523412# endregion
33533413
33543414
0 commit comments