Skip to content

Commit f138192

Browse files
committed
feat: migrate vm nic commands to aaz
dev dev dev
1 parent ad78421 commit f138192

File tree

4 files changed

+3234
-58
lines changed

4 files changed

+3234
-58
lines changed

src/azure-cli/azure/cli/command_modules/vm/custom.py

Lines changed: 113 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,13 +2878,42 @@ def show_vm_nic(cmd, resource_group_name, vm_name, nic):
28782878

28792879
NicShow = import_aaz_by_profile(cmd.cli_ctx.cloud.profile, "network.nic").Show
28802880

2881-
vm = get_vm(cmd, resource_group_name, vm_name)
2882-
found = next(
2883-
(n for n in vm.network_profile.network_interfaces if nic.lower() == n.id.lower()), None
2884-
# pylint: disable=no-member
2885-
)
2881+
vm = get_vm_to_update_by_aaz(cmd, resource_group_name, vm_name) or {}
2882+
nics = (vm.get('networkProfile') or {}).get('networkInterfaces') or []
2883+
2884+
nic_in = (nic or "").strip()
2885+
nic_in_lower = nic_in.lower()
2886+
2887+
def _safe_id(n):
2888+
_id = (n or {}).get('id')
2889+
return _id.strip() if isinstance(_id, str) else None
2890+
2891+
found = None
2892+
if "/subscriptions/" in nic_in_lower and "/networkinterfaces/" in nic_in_lower:
2893+
found = next(
2894+
(n for n in nics if (_safe_id(n) or "").lower() == nic_in_lower),
2895+
None
2896+
)
2897+
2898+
if not found:
2899+
for n in nics:
2900+
_id = _safe_id(n)
2901+
if not _id:
2902+
continue
2903+
try:
2904+
if parse_resource_id(_id).get('name', '').lower() == nic_in_lower:
2905+
found = n
2906+
break
2907+
except Exception:
2908+
continue
2909+
28862910
if found:
2887-
nic_name = parse_resource_id(found.id)['name']
2911+
found_id = _safe_id(found)
2912+
if not found_id:
2913+
raise ResourceNotFoundError(
2914+
f"NIC '{nic}' is attached to VM '{vm_name}' but NIC id is missing in VM network profile."
2915+
)
2916+
nic_name = parse_resource_id(found_id)['name']
28882917
return NicShow(cli_ctx=cmd.cli_ctx)(command_args={
28892918
'name': nic_name,
28902919
'resource_group': resource_group_name
@@ -2893,88 +2922,125 @@ def show_vm_nic(cmd, resource_group_name, vm_name, nic):
28932922

28942923

28952924
def list_vm_nics(cmd, resource_group_name, vm_name):
2896-
vm = get_vm(cmd, resource_group_name, vm_name)
2897-
return vm.network_profile.network_interfaces # pylint: disable=no-member
2925+
vm = get_vm_to_update_by_aaz(cmd, resource_group_name, vm_name) or {}
2926+
nics = (vm.get('networkProfile') or {}).get('networkInterfaces') or []
2927+
2928+
normalized = []
2929+
for nic in nics:
2930+
nic = nic or {}
2931+
normalized.append({
2932+
"id": nic.get("id"),
2933+
"resourceGroup": nic.get("resourceGroup") or resource_group_name,
2934+
"primary": nic.get("primary"),
2935+
"deleteOption": nic.get("deleteOption"),
2936+
})
2937+
return normalized
28982938

28992939

29002940
def add_vm_nic(cmd, resource_group_name, vm_name, nics, primary_nic=None):
2901-
vm = get_vm_to_update(cmd, resource_group_name, vm_name)
2941+
from .operations.vm import convert_show_result_to_snake_case as to_snake_case
2942+
2943+
vm = to_snake_case(get_vm_to_update_by_aaz(cmd, resource_group_name, vm_name) or {}) or {}
29022944
new_nics = _build_nic_list(cmd, nics)
29032945
existing_nics = _get_existing_nics(vm)
2904-
return _update_vm_nics(cmd, vm, existing_nics + new_nics, primary_nic)
2946+
2947+
return _update_vm_nics(
2948+
cmd, vm, existing_nics + new_nics, primary_nic,
2949+
resource_group_name=resource_group_name,
2950+
vm_name=vm_name)
29052951

29062952

29072953
def remove_vm_nic(cmd, resource_group_name, vm_name, nics, primary_nic=None):
2954+
from .operations.vm import convert_show_result_to_snake_case as to_snake_case
29082955

2909-
def to_delete(nic_id):
2910-
return [n for n in nics_to_delete if n.id.lower() == nic_id.lower()]
2956+
vm = to_snake_case(get_vm_to_update_by_aaz(cmd, resource_group_name, vm_name) or {}) or {}
29112957

2912-
vm = get_vm_to_update(cmd, resource_group_name, vm_name)
29132958
nics_to_delete = _build_nic_list(cmd, nics)
29142959
existing_nics = _get_existing_nics(vm)
2915-
survived = [x for x in existing_nics if not to_delete(x.id)]
2916-
return _update_vm_nics(cmd, vm, survived, primary_nic)
2960+
2961+
delete_ids = {n["id"].lower() for n in nics_to_delete if n.get("id")}
2962+
2963+
survived = [x for x in existing_nics if (x.get("id") or "").lower() not in delete_ids]
2964+
if not survived:
2965+
# aligns with platform behavior
2966+
# (https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-network-interface-vm)
2967+
raise ValidationError("A virtual machine must have at least one network interface. "
2968+
"You cannot detach the only NIC from a VM.")
2969+
2970+
return _update_vm_nics(
2971+
cmd, vm, survived, primary_nic,
2972+
resource_group_name=resource_group_name,
2973+
vm_name=vm_name)
29172974

29182975

29192976
def set_vm_nic(cmd, resource_group_name, vm_name, nics, primary_nic=None):
2920-
vm = get_vm_to_update(cmd, resource_group_name, vm_name)
2921-
nics = _build_nic_list(cmd, nics)
2922-
return _update_vm_nics(cmd, vm, nics, primary_nic)
2977+
from .operations.vm import convert_show_result_to_snake_case as to_snake_case
2978+
2979+
vm = to_snake_case(get_vm_to_update_by_aaz(cmd, resource_group_name, vm_name) or {}) or {}
2980+
nic_list = _build_nic_list(cmd, nics)
2981+
2982+
# VM must have at least one NIC
2983+
if not nic_list:
2984+
raise ValidationError(
2985+
"A virtual machine must have at least one network interface. "
2986+
"The '--nics' parameter cannot be empty."
2987+
)
2988+
2989+
return _update_vm_nics(
2990+
cmd, vm, nic_list, primary_nic,
2991+
resource_group_name=resource_group_name,
2992+
vm_name=vm_name,
2993+
)
29232994

29242995

29252996
def _build_nic_list(cmd, nic_ids):
29262997
NicShow = import_aaz_by_profile(cmd.cli_ctx.cloud.profile, "network.nic").Show
2927-
2928-
NetworkInterfaceReference = cmd.get_models('NetworkInterfaceReference')
29292998
nic_list = []
29302999
if nic_ids:
2931-
# pylint: disable=no-member
29323000
for nic_id in nic_ids:
29333001
rg, name = _parse_rg_name(nic_id)
2934-
nic = NicShow(cli_ctx=cmd.cli_ctx)(command_args={
2935-
'name': name,
2936-
'resource_group': rg
2937-
})
2938-
nic_list.append(NetworkInterfaceReference(id=nic['id'], primary=False))
3002+
nic = NicShow(cli_ctx=cmd.cli_ctx)(command_args={'name': name, 'resource_group': rg})
3003+
nic_list.append({"id": nic["id"], "primary": False})
29393004
return nic_list
29403005

29413006

29423007
def _get_existing_nics(vm):
2943-
network_profile = getattr(vm, 'network_profile', None)
2944-
nics = []
2945-
if network_profile is not None:
2946-
nics = network_profile.network_interfaces or []
2947-
return nics
3008+
return (vm.get("network_profile") or {}).get("network_interfaces") or []
29483009

29493010

2950-
def _update_vm_nics(cmd, vm, nics, primary_nic):
2951-
NetworkProfile = cmd.get_models('NetworkProfile')
2952-
3011+
def _update_vm_nics(cmd, vm, nics, primary_nic, resource_group_name, vm_name):
29533012
if primary_nic:
29543013
try:
29553014
_, primary_nic_name = _parse_rg_name(primary_nic)
29563015
except IndexError:
29573016
primary_nic_name = primary_nic
29583017

2959-
matched = [n for n in nics if _parse_rg_name(n.id)[1].lower() == primary_nic_name.lower()]
3018+
matched = [n for n in nics if _parse_rg_name(n["id"])[1].lower() == primary_nic_name.lower()]
29603019
if not matched:
2961-
raise CLIError('Primary Nic {} is not found'.format(primary_nic))
3020+
raise CLIError(f'Primary Nic {primary_nic} is not found')
29623021
if len(matched) > 1:
2963-
raise CLIError('Duplicate Nic entries with name {}'.format(primary_nic))
3022+
raise CLIError(f'Duplicate Nic entries with name {primary_nic}')
29643023
for n in nics:
2965-
n.primary = False
2966-
matched[0].primary = True
3024+
n["primary"] = False
3025+
matched[0]["primary"] = True
29673026
elif nics:
2968-
if not [n for n in nics if n.primary]:
2969-
nics[0].primary = True
3027+
if not any(n.get("primary") for n in nics):
3028+
nics[0]["primary"] = True
29703029

2971-
network_profile = getattr(vm, 'network_profile', None)
2972-
if network_profile is None:
2973-
vm.network_profile = NetworkProfile(network_interfaces=nics)
2974-
else:
2975-
network_profile.network_interfaces = nics
3030+
vm.setdefault("network_profile", {})
3031+
vm["network_profile"]["network_interfaces"] = nics
3032+
3033+
vm.pop("resources", None)
3034+
3035+
vm["resource_group"] = resource_group_name
3036+
vm["vm_name"] = vm_name
3037+
3038+
from .operations.vm import VMCreate
3039+
3040+
poller = VMCreate(cli_ctx=cmd.cli_ctx)(command_args=vm)
3041+
result = LongRunningOperation(cmd.cli_ctx)(poller)
29763042

2977-
return set_vm(cmd, vm).network_profile.network_interfaces
3043+
return (result.get("networkProfile") or {}).get("networkInterfaces") or []
29783044
# endregion
29793045

29803046

src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vm_create_multi_nics.yaml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3053,7 +3053,7 @@ interactions:
30533053
User-Agent:
30543054
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
30553055
method: GET
3056-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3056+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
30573057
response:
30583058
body:
30593059
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -3129,7 +3129,7 @@ interactions:
31293129
User-Agent:
31303130
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
31313131
method: GET
3132-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3132+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
31333133
response:
31343134
body:
31353135
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -3255,7 +3255,7 @@ interactions:
32553255
User-Agent:
32563256
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
32573257
method: GET
3258-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3258+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
32593259
response:
32603260
body:
32613261
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -3398,7 +3398,7 @@ interactions:
33983398
User-Agent:
33993399
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
34003400
method: PUT
3401-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3401+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
34023402
response:
34033403
body:
34043404
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -3536,7 +3536,7 @@ interactions:
35363536
User-Agent:
35373537
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
35383538
method: GET
3539-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3539+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
35403540
response:
35413541
body:
35423542
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -3612,7 +3612,7 @@ interactions:
36123612
User-Agent:
36133613
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
36143614
method: GET
3615-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3615+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
36163616
response:
36173617
body:
36183618
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -3756,7 +3756,7 @@ interactions:
37563756
User-Agent:
37573757
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
37583758
method: PUT
3759-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3759+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
37603760
response:
37613761
body:
37623762
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -3947,7 +3947,7 @@ interactions:
39473947
User-Agent:
39483948
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
39493949
method: GET
3950-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
3950+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
39513951
response:
39523952
body:
39533953
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -4023,7 +4023,7 @@ interactions:
40234023
User-Agent:
40244024
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
40254025
method: GET
4026-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
4026+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
40274027
response:
40284028
body:
40294029
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -4215,7 +4215,7 @@ interactions:
42154215
User-Agent:
42164216
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
42174217
method: PUT
4218-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
4218+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
42194219
response:
42204220
body:
42214221
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n
@@ -4406,7 +4406,7 @@ interactions:
44064406
User-Agent:
44074407
- AZURECLI/2.71.0 azsdk-python-core/1.31.0 Python/3.10.11 (Windows-10-10.0.26100-SP0)
44084408
method: GET
4409-
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2024-11-01
4409+
uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1?api-version=2025-04-01
44104410
response:
44114411
body:
44124412
string: "{\r\n \"name\": \"multinicvm1\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_multi_nic_vm000001/providers/Microsoft.Compute/virtualMachines/multinicvm1\",\r\n

0 commit comments

Comments
 (0)