Skip to content

Commit

Permalink
{cli} changes for create and update FLowLog with User ManagedIdentity (
Browse files Browse the repository at this point in the history
…Azure#29855)

* Azcli changes for create n update FL with MI

* build fix

* build fix

* build fix

* build fix

* fixing linter issues

* fixing linter issues
  • Loading branch information
jmegha123 authored Sep 13, 2024
1 parent 4879bda commit 8f2d5e5
Show file tree
Hide file tree
Showing 5 changed files with 326 additions and 8 deletions.
19 changes: 19 additions & 0 deletions src/azure-cli/azure/cli/command_modules/network/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,25 @@ def validate_dns_record_type(namespace):
return


def validate_managed_identity_resource_id(resource_id):
if resource_id.lower() == 'none':
return True
parts = resource_id.split('/')
if len(parts) != 9:
raise ValueError(
'Invalid resource ID format for a managed identity. It should be in the format:'
'/subscriptions/{subscription}/resourceGroups/{resource_group}/providers/'
'Microsoft.ManagedIdentity/userAssignedIdentities/{identity_name}')

if (parts[1] != 'subscriptions' or parts[3] != 'resourceGroups' or parts[5] != 'providers' or
parts[6] != 'Microsoft.ManagedIdentity' or parts[7] != 'userAssignedIdentities'):
raise ValueError(
'Invalid resource ID format for a managed identity. It should contain subscriptions,'
'resourceGroups, providers/Microsoft.ManagedIdentity/userAssignedIdentities'
'in the correct order.')
return True


def validate_user_assigned_identity(cmd, namespace):
from msrestazure.tools import is_valid_resource_id, resource_id

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class Create(AAZCommand):
"""

_aaz_info = {
"version": "2022-01-01",
"version": "2023-11-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2022-01-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2023-11-01"],
]
}

Expand Down Expand Up @@ -119,6 +119,29 @@ def _build_arguments_schema(cls, *args, **kwargs):

# define Arg Group "Parameters"

_args_schema = cls._args_schema
_args_schema.identity = AAZObjectArg(
options=["--identity"],
arg_group="Parameters",
help="FlowLog resource Managed Identity",
)

identity = cls._args_schema.identity
identity.type = AAZStrArg(
options=["type"],
help="The type of identity used for the resource. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the virtual machine.",
enum={"None": "None", "SystemAssigned": "SystemAssigned", "SystemAssigned, UserAssigned": "SystemAssigned, UserAssigned", "UserAssigned": "UserAssigned"},
)
identity.user_assigned_identities = AAZDictArg(
options=["user-assigned-identities"],
help="The list of user identities associated with resource. The user identity dictionary key references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.",
)

user_assigned_identities = cls._args_schema.identity.user_assigned_identities
user_assigned_identities.Element = AAZObjectArg(
blank={},
)

# define Arg Group "Properties"

_args_schema = cls._args_schema
Expand Down Expand Up @@ -258,7 +281,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2022-01-01",
"api-version", "2023-11-01",
required=True,
),
}
Expand All @@ -283,10 +306,20 @@ def content(self):
typ=AAZObjectType,
typ_kwargs={"flags": {"required": True, "client_flatten": True}}
)
_builder.set_prop("identity", AAZObjectType, ".identity")
_builder.set_prop("location", AAZStrType, ".location")
_builder.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}})
_builder.set_prop("tags", AAZDictType, ".tags")

identity = _builder.get(".identity")
if identity is not None:
identity.set_prop("type", AAZStrType, ".type")
identity.set_prop("userAssignedIdentities", AAZDictType, ".user_assigned_identities")

user_assigned_identities = _builder.get(".identity.userAssignedIdentities")
if user_assigned_identities is not None:
user_assigned_identities.set_elements(AAZObjectType, ".")

properties = _builder.get(".properties")
if properties is not None:
properties.set_prop("enabled", AAZBoolType, ".enabled")
Expand Down Expand Up @@ -346,6 +379,7 @@ def _build_schema_on_200_201(cls):
flags={"read_only": True},
)
_schema_on_200_201.id = AAZStrType()
_schema_on_200_201.identity = AAZObjectType()
_schema_on_200_201.location = AAZStrType()
_schema_on_200_201.name = AAZStrType(
flags={"read_only": True},
Expand All @@ -358,6 +392,33 @@ def _build_schema_on_200_201(cls):
flags={"read_only": True},
)

identity = cls._schema_on_200_201.identity
identity.principal_id = AAZStrType(
serialized_name="principalId",
flags={"read_only": True},
)
identity.tenant_id = AAZStrType(
serialized_name="tenantId",
flags={"read_only": True},
)
identity.type = AAZStrType()
identity.user_assigned_identities = AAZDictType(
serialized_name="userAssignedIdentities",
)

user_assigned_identities = cls._schema_on_200_201.identity.user_assigned_identities
user_assigned_identities.Element = AAZObjectType()

_element = cls._schema_on_200_201.identity.user_assigned_identities.Element
_element.client_id = AAZStrType(
serialized_name="clientId",
flags={"read_only": True},
)
_element.principal_id = AAZStrType(
serialized_name="principalId",
flags={"read_only": True},
)

properties = cls._schema_on_200_201.properties
properties.enabled = AAZBoolType()
properties.flow_analytics_configuration = AAZObjectType(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ class Update(AAZCommand):
"""

_aaz_info = {
"version": "2022-01-01",
"version": "2023-11-01",
"resources": [
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2022-01-01"],
["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/networkwatchers/{}/flowlogs/{}", "2023-11-01"],
]
}

Expand Down Expand Up @@ -126,6 +126,33 @@ def _build_arguments_schema(cls, *args, **kwargs):

# define Arg Group "Parameters"

_args_schema = cls._args_schema
_args_schema.identity = AAZObjectArg(
options=["--identity"],
arg_group="Parameters",
help="FlowLog resource Managed Identity",
nullable=True,
)

identity = cls._args_schema.identity
identity.type = AAZStrArg(
options=["type"],
help="The type of identity used for the resource. The type 'SystemAssigned, UserAssigned' includes both an implicitly created identity and a set of user assigned identities. The type 'None' will remove any identities from the virtual machine.",
nullable=True,
enum={"None": "None", "SystemAssigned": "SystemAssigned", "SystemAssigned, UserAssigned": "SystemAssigned, UserAssigned", "UserAssigned": "UserAssigned"},
)
identity.user_assigned_identities = AAZDictArg(
options=["user-assigned-identities"],
help="The list of user identities associated with resource. The user identity dictionary key references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.",
nullable=True,
)

user_assigned_identities = cls._args_schema.identity.user_assigned_identities
user_assigned_identities.Element = AAZObjectArg(
nullable=True,
blank={},
)

# define Arg Group "Properties"

_args_schema = cls._args_schema
Expand Down Expand Up @@ -269,7 +296,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2022-01-01",
"api-version", "2023-11-01",
required=True,
),
}
Expand Down Expand Up @@ -372,7 +399,7 @@ def url_parameters(self):
def query_parameters(self):
parameters = {
**self.serialize_query_param(
"api-version", "2022-01-01",
"api-version", "2023-11-01",
required=True,
),
}
Expand Down Expand Up @@ -430,10 +457,20 @@ def _update_instance(self, instance):
value=instance,
typ=AAZObjectType
)
_builder.set_prop("identity", AAZObjectType, ".identity")
_builder.set_prop("location", AAZStrType, ".location")
_builder.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}})
_builder.set_prop("tags", AAZDictType, ".tags")

identity = _builder.get(".identity")
if identity is not None:
identity.set_prop("type", AAZStrType, ".type")
identity.set_prop("userAssignedIdentities", AAZDictType, ".user_assigned_identities")

user_assigned_identities = _builder.get(".identity.userAssignedIdentities")
if user_assigned_identities is not None:
user_assigned_identities.set_elements(AAZObjectType, ".")

properties = _builder.get(".properties")
if properties is not None:
properties.set_prop("enabled", AAZBoolType, ".enabled")
Expand Down Expand Up @@ -490,6 +527,7 @@ def _build_schema_flow_log_read(cls, _schema):
if cls._schema_flow_log_read is not None:
_schema.etag = cls._schema_flow_log_read.etag
_schema.id = cls._schema_flow_log_read.id
_schema.identity = cls._schema_flow_log_read.identity
_schema.location = cls._schema_flow_log_read.location
_schema.name = cls._schema_flow_log_read.name
_schema.properties = cls._schema_flow_log_read.properties
Expand All @@ -504,6 +542,7 @@ def _build_schema_flow_log_read(cls, _schema):
flags={"read_only": True},
)
flow_log_read.id = AAZStrType()
flow_log_read.identity = AAZObjectType()
flow_log_read.location = AAZStrType()
flow_log_read.name = AAZStrType(
flags={"read_only": True},
Expand All @@ -516,6 +555,33 @@ def _build_schema_flow_log_read(cls, _schema):
flags={"read_only": True},
)

identity = _schema_flow_log_read.identity
identity.principal_id = AAZStrType(
serialized_name="principalId",
flags={"read_only": True},
)
identity.tenant_id = AAZStrType(
serialized_name="tenantId",
flags={"read_only": True},
)
identity.type = AAZStrType()
identity.user_assigned_identities = AAZDictType(
serialized_name="userAssignedIdentities",
)

user_assigned_identities = _schema_flow_log_read.identity.user_assigned_identities
user_assigned_identities.Element = AAZObjectType()

_element = _schema_flow_log_read.identity.user_assigned_identities.Element
_element.client_id = AAZStrType(
serialized_name="clientId",
flags={"read_only": True},
)
_element.principal_id = AAZStrType(
serialized_name="principalId",
flags={"read_only": True},
)

properties = _schema_flow_log_read.properties
properties.enabled = AAZBoolType()
properties.flow_analytics_configuration = AAZObjectType(
Expand Down Expand Up @@ -575,6 +641,7 @@ def _build_schema_flow_log_read(cls, _schema):

_schema.etag = cls._schema_flow_log_read.etag
_schema.id = cls._schema_flow_log_read.id
_schema.identity = cls._schema_flow_log_read.identity
_schema.location = cls._schema_flow_log_read.location
_schema.name = cls._schema_flow_log_read.name
_schema.properties = cls._schema_flow_log_read.properties
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azure.cli.core.profiles import ResourceType
from azure.cli.core.commands.validators import validate_tags
from azure.cli.command_modules.network._validators import validate_managed_identity_resource_id
from .._validators import _resolve_api_version

from ..aaz.latest.network.watcher import RunConfigurationDiagnostic as _RunConfigurationDiagnostic
Expand Down Expand Up @@ -1062,6 +1063,11 @@ def _build_arguments_schema(cls, *args, **kwargs):
minimum=10,
)
)
args_schema.user_assigned_identity = AAZResourceIdArg(
options=["--user-assigned-identity"],
help="Name or ID of the ManagedIdentity Resource.",
required=False,
)
args_schema.retention = AAZIntArg(
options=['--retention'],
help="Number of days to retain logs.",
Expand Down Expand Up @@ -1134,6 +1140,21 @@ def pre_operations(self):
elif has_value(args.nsg):
args.target_resource_id = args.nsg

if has_value(args.user_assigned_identity):
user_assigned_identity = args.user_assigned_identity.to_serialized_data()
is_valid_miresource_id = validate_managed_identity_resource_id(user_assigned_identity)
if not is_valid_miresource_id:
raise CLIError('Managed Identity resource id is invalid')
if user_assigned_identity.lower() != 'none':
args.identity = {
"type": "UserAssigned",
"user_assigned_identities": {user_assigned_identity: {}}
}
else:
args.identity = {
"type": "None"
}

if has_value(args.retention):
if args.retention > 0:
args.retention_policy = {"days": args.retention, "enabled": True}
Expand Down Expand Up @@ -1179,6 +1200,11 @@ def _build_arguments_schema(cls, *args, **kwargs):
minimum=10,
)
)
args_schema.user_assigned_identity = AAZResourceIdArg(
options=["--user-assigned-identity"],
help="Name or ID of the ManagedIdentity Resource.",
required=False,
)
args_schema.traffic_analytics_enabled = AAZBoolArg(
options=['--traffic-analytics'], arg_group="Traffic Analytics", nullable=True,
help="Enable traffic analytics. Defaults to true if `--workspace` is provided."
Expand Down Expand Up @@ -1245,10 +1271,24 @@ def pre_operations(self):
args.target_resource_id = args.nic
elif has_value(args.nsg):
args.target_resource_id = args.nsg

if has_value(args.retention) and args.retention > 0:
args.retention_policy = {"days": args.retention, "enabled": True}

if has_value(args.user_assigned_identity):
user_assigned_identity = args.user_assigned_identity.to_serialized_data()
is_valid_miresource_id = validate_managed_identity_resource_id(user_assigned_identity)
if not is_valid_miresource_id:
raise CLIError('Managed Identity resource id is invalid')
if user_assigned_identity.lower() != 'none':
args.identity = {
"type": "UserAssigned",
"user_assigned_identities": {user_assigned_identity: {}}
}
else:
args.identity = {
"type": "None"
}

if has_value(args.traffic_analytics_workspace):
workspace = get_arm_resource_by_id(self.cli_ctx, args.traffic_analytics_workspace.to_serialized_data())
if not workspace:
Expand Down
Loading

0 comments on commit 8f2d5e5

Please sign in to comment.