From 17ad41aaff8b8332383ffc8e49e72ac30f9cee26 Mon Sep 17 00:00:00 2001 From: Jian Hui Date: Tue, 13 Oct 2026 10:29:51 +0800 Subject: [PATCH] faet: Add DDoS Custom Policy mitigation-rule support to Azure CLI --- .../cli/command_modules/network/_help.py | 4 + .../cli/command_modules/network/_params.py | 5 + .../network/_template_builder.py | 8 +- .../network/ddos_custom_policy/_create.py | 319 ++- .../network/ddos_custom_policy/_delete.py | 6 +- .../network/ddos_custom_policy/_list.py | 411 ++- .../network/ddos_custom_policy/_show.py | 117 +- .../network/ddos_custom_policy/_update.py | 729 ++++- .../network/ddos_custom_policy/_wait.py | 115 +- .../cli/command_modules/network/custom.py | 10 +- .../network/operations/ddos_custom_policy.py | 45 +- .../recordings/test_ddos_custom_policy.yaml | 30 +- ...t_ddos_custom_policy_attach_to_lb_fip.yaml | 8 +- ...dos_custom_policy_attach_to_public_ip.yaml | 16 +- ...t_ddos_custom_policy_mitigation_rules.yaml | 2530 +++++++++++++++++ .../tests/latest/test_network_commands.py | 112 +- 16 files changed, 4280 insertions(+), 185 deletions(-) create mode 100644 src/azure-cli/azure/cli/command_modules/network/tests/latest/recordings/test_ddos_custom_policy_mitigation_rules.yaml diff --git a/src/azure-cli/azure/cli/command_modules/network/_help.py b/src/azure-cli/azure/cli/command_modules/network/_help.py index 70415b4cd9e..3222478ff8d 100644 --- a/src/azure-cli/azure/cli/command_modules/network/_help.py +++ b/src/azure-cli/azure/cli/command_modules/network/_help.py @@ -6258,4 +6258,8 @@ az network ddos-custom-policy create --resource-group rg1 --ddos-custom-policy-name test-ddos-custom-policy \\ --location centraluseuap --detection-rule-name detectionRuleTcp \\ --detection-mode TrafficThreshold --traffic-type Tcp --packets-per-second 1000000 + - name: Create DDoS custom policy with a TCP mitigation rule that denies traffic from a prefix or country + text: | + az network ddos-custom-policy create --resource-group rg1 --ddos-custom-policy-name test-ddos-custom-policy \\ + --location centraluseuap --mitigation-rules "[{name:mitigationRuleTcp,traffic-scope:Tcp,tcp-default-mitigations:{per-source-rate-limiting:{packets-per-second:100000},per-source-connection-rate-limiting:{connections-per-second:1000}},source-policy-overrides:[{policy-action:{action-type:Deny},conditions:{ip-prefixes:[198.51.100.0/24],geo-matches:[{country-code:CA}]}}]}]" """ diff --git a/src/azure-cli/azure/cli/command_modules/network/_params.py b/src/azure-cli/azure/cli/command_modules/network/_params.py index 168f3b28d69..2d8376f393d 100644 --- a/src/azure-cli/azure/cli/command_modules/network/_params.py +++ b/src/azure-cli/azure/cli/command_modules/network/_params.py @@ -856,4 +856,9 @@ def load_arguments(self, _): c.argument('detection_mode', arg_group='Detection Rules', help='The detection mode for the DDoS detection rule.') c.argument('traffic_type', arg_group='Detection Rules', help='The traffic type (one of Tcp, Udp, TcpSyn) that the detection rule will be applied upon.') c.argument('packets_per_second', arg_group='Detection Rules', help='The customized packets per second threshold.') + from .aaz.latest.network.ddos_custom_policy import Create as _DdosCustomPolicyCreate + # reuse the generated AAZ arg so shorthand/JSON parsing, `??` help and validation stay in sync with the API + mitigation_rules = _DdosCustomPolicyCreate._build_arguments_schema().mitigation_rules.to_cmd_arg('mitigation_rules').type.settings # pylint: disable=protected-access + c.argument('mitigation_rules', options_list=['--mitigation-rules'], arg_group='Mitigation Rules', + action=mitigation_rules['action'], nargs=mitigation_rules['nargs'], help=mitigation_rules['help']) # endregion diff --git a/src/azure-cli/azure/cli/command_modules/network/_template_builder.py b/src/azure-cli/azure/cli/command_modules/network/_template_builder.py index 70e4e967b56..6734adbd8af 100644 --- a/src/azure-cli/azure/cli/command_modules/network/_template_builder.py +++ b/src/azure-cli/azure/cli/command_modules/network/_template_builder.py @@ -520,7 +520,7 @@ def build_vpn_connection_resource(cmd, name, location, tags, gateway1, gateway2, def build_ddos_custom_policy(cmd, ddos_custom_policy_name, location=None, tags=None, detection_rule_name=None, - detection_mode=None, packets_per_second=None, traffic_type=None): + detection_mode=None, packets_per_second=None, traffic_type=None, mitigation_rules=None): policy = {'ddos_custom_policy_name': ddos_custom_policy_name} if location: @@ -529,6 +529,12 @@ def build_ddos_custom_policy(cmd, ddos_custom_policy_name, location=None, tags=N if tags: policy['tags'] = tags + if mitigation_rules: + policy['mitigation_rules'] = mitigation_rules + + if not (detection_rule_name or detection_mode or packets_per_second or traffic_type): + return policy + detection_rules = {} traffic_detection_rule = {} diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_create.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_create.py index 06524684fba..732479fe2c6 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_create.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_create.py @@ -22,9 +22,9 @@ class Create(AAZCommand): """ _aaz_info = { - "version": "2025-07-01", + "version": "2026-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2025-07-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2026-03-01"], ] } @@ -81,11 +81,20 @@ def _build_arguments_schema(cls, *args, **kwargs): arg_group="Properties", help="The list of DDoS detection rules associated with the custom policy.", ) + _args_schema.mitigation_rules = AAZListArg( + options=["--mitigation-rules"], + arg_group="Properties", + help="The list of DDoS mitigation rules associated with the custom policy.", + ) detection_rules = cls._args_schema.detection_rules detection_rules.Element = AAZObjectArg() _element = cls._args_schema.detection_rules.Element + _element.id = AAZStrArg( + options=["id"], + help="Resource ID.", + ) _element.name = AAZStrArg( options=["name"], help="The name of the DDoS detection rule.", @@ -110,6 +119,128 @@ def _build_arguments_schema(cls, *args, **kwargs): help="The traffic type (one of Tcp, Udp, TcpSyn) that the detection rule will be applied upon.", enum={"Tcp": "Tcp", "TcpSyn": "TcpSyn", "Udp": "Udp"}, ) + + mitigation_rules = cls._args_schema.mitigation_rules + mitigation_rules.Element = AAZObjectArg() + + _element = cls._args_schema.mitigation_rules.Element + _element.id = AAZStrArg( + options=["id"], + help="Resource ID.", + ) + _element.name = AAZStrArg( + options=["name"], + help="The name of the DDoS mitigation rule.", + required=True, + ) + _element.source_policy_overrides = AAZListArg( + options=["source-policy-overrides"], + help="Source-specific actions that override the default mitigations. A rule supports at most one Deny override and one Permit override.", + ) + _element.tcp_default_mitigations = AAZObjectArg( + options=["tcp-default-mitigations"], + help="The default TCP mitigations. This property is valid only when trafficScope is Tcp.", + ) + _element.traffic_scope = AAZStrArg( + options=["traffic-scope"], + help="The traffic protocol to which the mitigation rule applies.", + required=True, + enum={"Tcp": "Tcp", "Udp": "Udp"}, + ) + _element.udp_default_mitigations = AAZObjectArg( + options=["udp-default-mitigations"], + help="The default UDP mitigations. This property is valid only when trafficScope is Udp.", + ) + + source_policy_overrides = cls._args_schema.mitigation_rules.Element.source_policy_overrides + source_policy_overrides.Element = AAZObjectArg() + + _element = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element + _element.conditions = AAZObjectArg( + options=["conditions"], + help="The source conditions that select traffic for the action.", + required=True, + ) + _element.policy_action = AAZObjectArg( + options=["policy-action"], + help="The action to apply to matching traffic.", + required=True, + ) + + conditions = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListArg( + options=["geo-matches"], + help="The geographic matches. Entries are evaluated with OR semantics.", + ) + conditions.ip_prefixes = AAZListArg( + options=["ip-prefixes"], + help="The IPv4 or IPv6 CIDR prefixes in `
/` format. Entries are evaluated with OR semantics.", + ) + + geo_matches = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectArg() + + _element = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrArg( + options=["continent"], + help="The continent to match. Country membership follows the service-defined mapping documented on DdosGeoMatch.", + enum={"Africa": "Africa", "Antarctica": "Antarctica", "Asia": "Asia", "Europe": "Europe", "NorthAmerica": "NorthAmerica", "Oceania": "Oceania", "SouthAmerica": "SouthAmerica"}, + ) + _element.country_code = AAZStrArg( + options=["country-code"], + help="The uppercase two-letter ISO 3166-1 alpha-2 code for the country or territory to match.", + fmt=AAZStrArgFormat( + pattern="^[A-Z]{2}$", + ), + ) + + ip_prefixes = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrArg() + + policy_action = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrArg( + options=["action-type"], + help="The source policy action type.", + required=True, + enum={"Deny": "Deny", "Permit": "Permit"}, + ) + + tcp_default_mitigations = cls._args_schema.mitigation_rules.Element.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectArg( + options=["per-source-connection-rate-limiting"], + help="The per-source rate limit for new TCP connection establishments.", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectArg( + options=["per-source-rate-limiting"], + help="The per-source TCP packet rate limit.", + ) + + per_source_connection_rate_limiting = cls._args_schema.mitigation_rules.Element.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntArg( + options=["connections-per-second"], + help="The maximum number of new TCP connections established per second from a source IP.", + required=True, + ) + + per_source_rate_limiting = cls._args_schema.mitigation_rules.Element.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntArg( + options=["packets-per-second"], + help="The maximum number of TCP packets allowed per second from a source IP.", + required=True, + ) + + udp_default_mitigations = cls._args_schema.mitigation_rules.Element.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectArg( + options=["per-source-rate-limiting"], + help="The per-source UDP packet rate limit.", + ) + + per_source_rate_limiting = cls._args_schema.mitigation_rules.Element.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntArg( + options=["packets-per-second"], + help="The maximum number of UDP packets allowed per second from a source IP.", + required=True, + ) return cls._args_schema def _execute_operations(self): @@ -193,7 +324,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2025-07-01", + "api-version", "2026-03-01", required=True, ), } @@ -225,6 +356,7 @@ def content(self): properties = _builder.get(".properties") if properties is not None: properties.set_prop("detectionRules", AAZListType, ".detection_rules") + properties.set_prop("mitigationRules", AAZListType, ".mitigation_rules") detection_rules = _builder.get(".properties.detectionRules") if detection_rules is not None: @@ -232,6 +364,7 @@ def content(self): _elements = _builder.get(".properties.detectionRules[]") if _elements is not None: + _elements.set_prop("id", AAZStrType, ".id") _elements.set_prop("name", AAZStrType, ".name") _elements.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}}) @@ -245,6 +378,75 @@ def content(self): traffic_detection_rule.set_prop("packetsPerSecond", AAZIntType, ".packets_per_second") traffic_detection_rule.set_prop("trafficType", AAZStrType, ".traffic_type") + mitigation_rules = _builder.get(".properties.mitigationRules") + if mitigation_rules is not None: + mitigation_rules.set_elements(AAZObjectType, ".") + + _elements = _builder.get(".properties.mitigationRules[]") + if _elements is not None: + _elements.set_prop("id", AAZStrType, ".id") + _elements.set_prop("name", AAZStrType, ".name", typ_kwargs={"flags": {"required": True}}) + _elements.set_prop("properties", AAZObjectType, ".", typ_kwargs={"flags": {"required": True}}) + + properties = _builder.get(".properties.mitigationRules[].properties") + if properties is not None: + properties.set_prop("sourcePolicyOverrides", AAZListType, ".source_policy_overrides") + properties.set_prop("tcpDefaultMitigations", AAZObjectType, ".tcp_default_mitigations") + properties.set_prop("trafficScope", AAZStrType, ".traffic_scope", typ_kwargs={"flags": {"required": True}}) + properties.set_prop("udpDefaultMitigations", AAZObjectType, ".udp_default_mitigations") + + source_policy_overrides = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides") + if source_policy_overrides is not None: + source_policy_overrides.set_elements(AAZObjectType, ".") + + _elements = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[]") + if _elements is not None: + _elements.set_prop("conditions", AAZObjectType, ".conditions", typ_kwargs={"flags": {"required": True}}) + _elements.set_prop("policyAction", AAZObjectType, ".policy_action", typ_kwargs={"flags": {"required": True}}) + + conditions = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions") + if conditions is not None: + conditions.set_prop("geoMatches", AAZListType, ".geo_matches") + conditions.set_prop("ipPrefixes", AAZListType, ".ip_prefixes") + + geo_matches = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions.geoMatches") + if geo_matches is not None: + geo_matches.set_elements(AAZObjectType, ".") + + _elements = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions.geoMatches[]") + if _elements is not None: + _elements.set_prop("continent", AAZStrType, ".continent") + _elements.set_prop("countryCode", AAZStrType, ".country_code") + + ip_prefixes = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions.ipPrefixes") + if ip_prefixes is not None: + ip_prefixes.set_elements(AAZStrType, ".") + + policy_action = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].policyAction") + if policy_action is not None: + policy_action.set_prop("actionType", AAZStrType, ".action_type", typ_kwargs={"flags": {"required": True}}) + + tcp_default_mitigations = _builder.get(".properties.mitigationRules[].properties.tcpDefaultMitigations") + if tcp_default_mitigations is not None: + tcp_default_mitigations.set_prop("perSourceConnectionRateLimiting", AAZObjectType, ".per_source_connection_rate_limiting") + tcp_default_mitigations.set_prop("perSourceRateLimiting", AAZObjectType, ".per_source_rate_limiting") + + per_source_connection_rate_limiting = _builder.get(".properties.mitigationRules[].properties.tcpDefaultMitigations.perSourceConnectionRateLimiting") + if per_source_connection_rate_limiting is not None: + per_source_connection_rate_limiting.set_prop("connectionsPerSecond", AAZIntType, ".connections_per_second", typ_kwargs={"flags": {"required": True}}) + + per_source_rate_limiting = _builder.get(".properties.mitigationRules[].properties.tcpDefaultMitigations.perSourceRateLimiting") + if per_source_rate_limiting is not None: + per_source_rate_limiting.set_prop("packetsPerSecond", AAZIntType, ".packets_per_second", typ_kwargs={"flags": {"required": True}}) + + udp_default_mitigations = _builder.get(".properties.mitigationRules[].properties.udpDefaultMitigations") + if udp_default_mitigations is not None: + udp_default_mitigations.set_prop("perSourceRateLimiting", AAZObjectType, ".per_source_rate_limiting") + + per_source_rate_limiting = _builder.get(".properties.mitigationRules[].properties.udpDefaultMitigations.perSourceRateLimiting") + if per_source_rate_limiting is not None: + per_source_rate_limiting.set_prop("packetsPerSecond", AAZIntType, ".packets_per_second", typ_kwargs={"flags": {"required": True}}) + tags = _builder.get(".tags") if tags is not None: tags.set_elements(AAZStrType, ".") @@ -292,6 +494,9 @@ def _build_schema_on_200_201(cls): properties.front_end_ip_configuration = AAZListType( serialized_name="frontEndIpConfiguration", ) + properties.mitigation_rules = AAZListType( + serialized_name="mitigationRules", + ) properties.provisioning_state = AAZStrType( serialized_name="provisioningState", flags={"read_only": True}, @@ -347,6 +552,114 @@ def _build_schema_on_200_201(cls): front_end_ip_configuration.Element = AAZObjectType() _CreateHelper._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) + mitigation_rules = cls._schema_on_200_201.properties.mitigation_rules + mitigation_rules.Element = AAZObjectType() + + _element = cls._schema_on_200_201.properties.mitigation_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"required": True}, + ) + _element.properties = AAZObjectType( + flags={"required": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200_201.properties.mitigation_rules.Element.properties + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_policy_overrides = AAZListType( + serialized_name="sourcePolicyOverrides", + ) + properties.tcp_default_mitigations = AAZObjectType( + serialized_name="tcpDefaultMitigations", + ) + properties.traffic_scope = AAZStrType( + serialized_name="trafficScope", + flags={"required": True}, + ) + properties.udp_default_mitigations = AAZObjectType( + serialized_name="udpDefaultMitigations", + ) + + source_policy_overrides = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides + source_policy_overrides.Element = AAZObjectType() + + _element = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element + _element.conditions = AAZObjectType( + flags={"required": True}, + ) + _element.policy_action = AAZObjectType( + serialized_name="policyAction", + flags={"required": True}, + ) + + conditions = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListType( + serialized_name="geoMatches", + ) + conditions.ip_prefixes = AAZListType( + serialized_name="ipPrefixes", + ) + + geo_matches = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectType() + + _element = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrType() + _element.country_code = AAZStrType( + serialized_name="countryCode", + ) + + ip_prefixes = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrType() + + policy_action = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrType( + serialized_name="actionType", + flags={"required": True}, + ) + + tcp_default_mitigations = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectType( + serialized_name="perSourceConnectionRateLimiting", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_connection_rate_limiting = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntType( + serialized_name="connectionsPerSecond", + flags={"required": True}, + ) + + per_source_rate_limiting = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + udp_default_mitigations = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_rate_limiting = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + public_ip_addresses = cls._schema_on_200_201.properties.public_ip_addresses public_ip_addresses.Element = AAZObjectType() _CreateHelper._build_schema_common_sub_resource_read(public_ip_addresses.Element) diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_delete.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_delete.py index 0f10da89566..8ab24844798 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_delete.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_delete.py @@ -23,9 +23,9 @@ class Delete(AAZCommand): """ _aaz_info = { - "version": "2025-07-01", + "version": "2026-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2025-07-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2026-03-01"], ] } @@ -143,7 +143,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2025-07-01", + "api-version", "2026-03-01", required=True, ), } diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_list.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_list.py index 3797fe2a34a..d1a3cbb3c36 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_list.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_list.py @@ -19,9 +19,10 @@ class List(AAZCommand): """ _aaz_info = { - "version": "2025-07-01", + "version": "2026-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies", "2025-07-01"], + ["mgmt-plane", "/subscriptions/{}/providers/microsoft.network/ddoscustompolicies", "2026-03-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies", "2026-03-01"], ] } @@ -42,14 +43,17 @@ def _build_arguments_schema(cls, *args, **kwargs): # define Arg Group "" _args_schema = cls._args_schema - _args_schema.resource_group = AAZResourceGroupNameArg( - required=True, - ) + _args_schema.resource_group = AAZResourceGroupNameArg() return cls._args_schema def _execute_operations(self): self.pre_operations() - self.DdosCustomPoliciesList(ctx=self.ctx)() + condition_0 = has_value(self.ctx.subscription_id) and has_value(self.ctx.args.resource_group) is not True + condition_1 = has_value(self.ctx.args.resource_group) and has_value(self.ctx.subscription_id) + if condition_0: + self.DdosCustomPoliciesListAll(ctx=self.ctx)() + if condition_1: + self.DdosCustomPoliciesList(ctx=self.ctx)() self.post_operations() @register_callback @@ -65,6 +69,288 @@ def _output(self, *args, **kwargs): next_link = self.deserialize_output(self.ctx.vars.instance.next_link) return result, next_link + class DdosCustomPoliciesListAll(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200]: + return self.on_200(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/providers/Microsoft.Network/ddosCustomPolicies", + **self.url_parameters + ) + + @property + def method(self): + return "GET" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2026-03-01", + required=True, + ), + } + return parameters + + @property + def header_parameters(self): + parameters = { + **self.serialize_header_param( + "Accept", "application/json", + ), + } + return parameters + + def on_200(self, session): + data = self.deserialize_http_content(session) + self.ctx.set_var( + "instance", + data, + schema_builder=self._build_schema_on_200 + ) + + _schema_on_200 = None + + @classmethod + def _build_schema_on_200(cls): + if cls._schema_on_200 is not None: + return cls._schema_on_200 + + cls._schema_on_200 = AAZObjectType() + + _schema_on_200 = cls._schema_on_200 + _schema_on_200.next_link = AAZStrType( + serialized_name="nextLink", + ) + _schema_on_200.value = AAZListType( + flags={"required": True}, + ) + + value = cls._schema_on_200.value + value.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType() + _element.location = AAZStrType() + _element.name = AAZStrType( + flags={"read_only": True}, + ) + _element.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _element.tags = AAZDictType() + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.value.Element.properties + properties.detection_rules = AAZListType( + serialized_name="detectionRules", + ) + properties.front_end_ip_configuration = AAZListType( + serialized_name="frontEndIpConfiguration", + ) + properties.mitigation_rules = AAZListType( + serialized_name="mitigationRules", + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.public_ip_addresses = AAZListType( + serialized_name="publicIPAddresses", + flags={"read_only": True}, + ) + properties.resource_guid = AAZStrType( + serialized_name="resourceGuid", + flags={"read_only": True}, + ) + + detection_rules = cls._schema_on_200.value.Element.properties.detection_rules + detection_rules.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.detection_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType() + _element.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.value.Element.properties.detection_rules.Element.properties + properties.detection_mode = AAZStrType( + serialized_name="detectionMode", + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.traffic_detection_rule = AAZObjectType( + serialized_name="trafficDetectionRule", + ) + + traffic_detection_rule = cls._schema_on_200.value.Element.properties.detection_rules.Element.properties.traffic_detection_rule + traffic_detection_rule.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + ) + traffic_detection_rule.traffic_type = AAZStrType( + serialized_name="trafficType", + ) + + front_end_ip_configuration = cls._schema_on_200.value.Element.properties.front_end_ip_configuration + front_end_ip_configuration.Element = AAZObjectType() + _ListHelper._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) + + mitigation_rules = cls._schema_on_200.value.Element.properties.mitigation_rules + mitigation_rules.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.mitigation_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"required": True}, + ) + _element.properties = AAZObjectType( + flags={"required": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_policy_overrides = AAZListType( + serialized_name="sourcePolicyOverrides", + ) + properties.tcp_default_mitigations = AAZObjectType( + serialized_name="tcpDefaultMitigations", + ) + properties.traffic_scope = AAZStrType( + serialized_name="trafficScope", + flags={"required": True}, + ) + properties.udp_default_mitigations = AAZObjectType( + serialized_name="udpDefaultMitigations", + ) + + source_policy_overrides = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides + source_policy_overrides.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element + _element.conditions = AAZObjectType( + flags={"required": True}, + ) + _element.policy_action = AAZObjectType( + serialized_name="policyAction", + flags={"required": True}, + ) + + conditions = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListType( + serialized_name="geoMatches", + ) + conditions.ip_prefixes = AAZListType( + serialized_name="ipPrefixes", + ) + + geo_matches = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrType() + _element.country_code = AAZStrType( + serialized_name="countryCode", + ) + + ip_prefixes = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrType() + + policy_action = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrType( + serialized_name="actionType", + flags={"required": True}, + ) + + tcp_default_mitigations = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectType( + serialized_name="perSourceConnectionRateLimiting", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_connection_rate_limiting = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntType( + serialized_name="connectionsPerSecond", + flags={"required": True}, + ) + + per_source_rate_limiting = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + udp_default_mitigations = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_rate_limiting = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + public_ip_addresses = cls._schema_on_200.value.Element.properties.public_ip_addresses + public_ip_addresses.Element = AAZObjectType() + _ListHelper._build_schema_common_sub_resource_read(public_ip_addresses.Element) + + tags = cls._schema_on_200.value.Element.tags + tags.Element = AAZStrType() + + return cls._schema_on_200 + class DdosCustomPoliciesList(AAZHttpOperation): CLIENT_TYPE = "MgmtClient" @@ -109,7 +395,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2025-07-01", + "api-version", "2026-03-01", required=True, ), } @@ -176,6 +462,9 @@ def _build_schema_on_200(cls): properties.front_end_ip_configuration = AAZListType( serialized_name="frontEndIpConfiguration", ) + properties.mitigation_rules = AAZListType( + serialized_name="mitigationRules", + ) properties.provisioning_state = AAZStrType( serialized_name="provisioningState", flags={"read_only": True}, @@ -231,6 +520,114 @@ def _build_schema_on_200(cls): front_end_ip_configuration.Element = AAZObjectType() _ListHelper._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) + mitigation_rules = cls._schema_on_200.value.Element.properties.mitigation_rules + mitigation_rules.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.mitigation_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"required": True}, + ) + _element.properties = AAZObjectType( + flags={"required": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_policy_overrides = AAZListType( + serialized_name="sourcePolicyOverrides", + ) + properties.tcp_default_mitigations = AAZObjectType( + serialized_name="tcpDefaultMitigations", + ) + properties.traffic_scope = AAZStrType( + serialized_name="trafficScope", + flags={"required": True}, + ) + properties.udp_default_mitigations = AAZObjectType( + serialized_name="udpDefaultMitigations", + ) + + source_policy_overrides = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides + source_policy_overrides.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element + _element.conditions = AAZObjectType( + flags={"required": True}, + ) + _element.policy_action = AAZObjectType( + serialized_name="policyAction", + flags={"required": True}, + ) + + conditions = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListType( + serialized_name="geoMatches", + ) + conditions.ip_prefixes = AAZListType( + serialized_name="ipPrefixes", + ) + + geo_matches = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrType() + _element.country_code = AAZStrType( + serialized_name="countryCode", + ) + + ip_prefixes = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrType() + + policy_action = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrType( + serialized_name="actionType", + flags={"required": True}, + ) + + tcp_default_mitigations = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectType( + serialized_name="perSourceConnectionRateLimiting", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_connection_rate_limiting = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntType( + serialized_name="connectionsPerSecond", + flags={"required": True}, + ) + + per_source_rate_limiting = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + udp_default_mitigations = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_rate_limiting = cls._schema_on_200.value.Element.properties.mitigation_rules.Element.properties.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + public_ip_addresses = cls._schema_on_200.value.Element.properties.public_ip_addresses public_ip_addresses.Element = AAZObjectType() _ListHelper._build_schema_common_sub_resource_read(public_ip_addresses.Element) diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_show.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_show.py index ec96d3f4940..a0e6bc8a7bc 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_show.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_show.py @@ -22,9 +22,9 @@ class Show(AAZCommand): """ _aaz_info = { - "version": "2025-07-01", + "version": "2026-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2025-07-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2026-03-01"], ] } @@ -120,7 +120,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2025-07-01", + "api-version", "2026-03-01", required=True, ), } @@ -176,6 +176,9 @@ def _build_schema_on_200(cls): properties.front_end_ip_configuration = AAZListType( serialized_name="frontEndIpConfiguration", ) + properties.mitigation_rules = AAZListType( + serialized_name="mitigationRules", + ) properties.provisioning_state = AAZStrType( serialized_name="provisioningState", flags={"read_only": True}, @@ -231,6 +234,114 @@ def _build_schema_on_200(cls): front_end_ip_configuration.Element = AAZObjectType() _ShowHelper._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) + mitigation_rules = cls._schema_on_200.properties.mitigation_rules + mitigation_rules.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"required": True}, + ) + _element.properties = AAZObjectType( + flags={"required": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties.mitigation_rules.Element.properties + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_policy_overrides = AAZListType( + serialized_name="sourcePolicyOverrides", + ) + properties.tcp_default_mitigations = AAZObjectType( + serialized_name="tcpDefaultMitigations", + ) + properties.traffic_scope = AAZStrType( + serialized_name="trafficScope", + flags={"required": True}, + ) + properties.udp_default_mitigations = AAZObjectType( + serialized_name="udpDefaultMitigations", + ) + + source_policy_overrides = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides + source_policy_overrides.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element + _element.conditions = AAZObjectType( + flags={"required": True}, + ) + _element.policy_action = AAZObjectType( + serialized_name="policyAction", + flags={"required": True}, + ) + + conditions = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListType( + serialized_name="geoMatches", + ) + conditions.ip_prefixes = AAZListType( + serialized_name="ipPrefixes", + ) + + geo_matches = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrType() + _element.country_code = AAZStrType( + serialized_name="countryCode", + ) + + ip_prefixes = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrType() + + policy_action = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrType( + serialized_name="actionType", + flags={"required": True}, + ) + + tcp_default_mitigations = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectType( + serialized_name="perSourceConnectionRateLimiting", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_connection_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntType( + serialized_name="connectionsPerSecond", + flags={"required": True}, + ) + + per_source_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + udp_default_mitigations = cls._schema_on_200.properties.mitigation_rules.Element.properties.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + public_ip_addresses = cls._schema_on_200.properties.public_ip_addresses public_ip_addresses.Element = AAZObjectType() _ShowHelper._build_schema_common_sub_resource_read(public_ip_addresses.Element) diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_update.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_update.py index 0acf5d61415..d8d378da415 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_update.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_update.py @@ -22,9 +22,9 @@ class Update(AAZCommand): """ _aaz_info = { - "version": "2025-07-01", + "version": "2026-03-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2025-07-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2026-03-01"], ] } @@ -86,6 +86,12 @@ def _build_arguments_schema(cls, *args, **kwargs): help="The list of DDoS detection rules associated with the custom policy.", nullable=True, ) + _args_schema.mitigation_rules = AAZListArg( + options=["--mitigation-rules"], + arg_group="Properties", + help="The list of DDoS mitigation rules associated with the custom policy.", + nullable=True, + ) detection_rules = cls._args_schema.detection_rules detection_rules.Element = AAZObjectArg( @@ -93,6 +99,11 @@ def _build_arguments_schema(cls, *args, **kwargs): ) _element = cls._args_schema.detection_rules.Element + _element.id = AAZStrArg( + options=["id"], + help="Resource ID.", + nullable=True, + ) _element.name = AAZStrArg( options=["name"], help="The name of the DDoS detection rule.", @@ -122,6 +133,139 @@ def _build_arguments_schema(cls, *args, **kwargs): nullable=True, enum={"Tcp": "Tcp", "TcpSyn": "TcpSyn", "Udp": "Udp"}, ) + + mitigation_rules = cls._args_schema.mitigation_rules + mitigation_rules.Element = AAZObjectArg( + nullable=True, + ) + + _element = cls._args_schema.mitigation_rules.Element + _element.id = AAZStrArg( + options=["id"], + help="Resource ID.", + nullable=True, + ) + _element.name = AAZStrArg( + options=["name"], + help="The name of the DDoS mitigation rule.", + ) + _element.source_policy_overrides = AAZListArg( + options=["source-policy-overrides"], + help="Source-specific actions that override the default mitigations. A rule supports at most one Deny override and one Permit override.", + nullable=True, + ) + _element.tcp_default_mitigations = AAZObjectArg( + options=["tcp-default-mitigations"], + help="The default TCP mitigations. This property is valid only when trafficScope is Tcp.", + nullable=True, + ) + _element.traffic_scope = AAZStrArg( + options=["traffic-scope"], + help="The traffic protocol to which the mitigation rule applies.", + enum={"Tcp": "Tcp", "Udp": "Udp"}, + ) + _element.udp_default_mitigations = AAZObjectArg( + options=["udp-default-mitigations"], + help="The default UDP mitigations. This property is valid only when trafficScope is Udp.", + nullable=True, + ) + + source_policy_overrides = cls._args_schema.mitigation_rules.Element.source_policy_overrides + source_policy_overrides.Element = AAZObjectArg( + nullable=True, + ) + + _element = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element + _element.conditions = AAZObjectArg( + options=["conditions"], + help="The source conditions that select traffic for the action.", + ) + _element.policy_action = AAZObjectArg( + options=["policy-action"], + help="The action to apply to matching traffic.", + ) + + conditions = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListArg( + options=["geo-matches"], + help="The geographic matches. Entries are evaluated with OR semantics.", + nullable=True, + ) + conditions.ip_prefixes = AAZListArg( + options=["ip-prefixes"], + help="The IPv4 or IPv6 CIDR prefixes in `
/` format. Entries are evaluated with OR semantics.", + nullable=True, + ) + + geo_matches = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectArg( + nullable=True, + ) + + _element = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrArg( + options=["continent"], + help="The continent to match. Country membership follows the service-defined mapping documented on DdosGeoMatch.", + nullable=True, + enum={"Africa": "Africa", "Antarctica": "Antarctica", "Asia": "Asia", "Europe": "Europe", "NorthAmerica": "NorthAmerica", "Oceania": "Oceania", "SouthAmerica": "SouthAmerica"}, + ) + _element.country_code = AAZStrArg( + options=["country-code"], + help="The uppercase two-letter ISO 3166-1 alpha-2 code for the country or territory to match.", + nullable=True, + fmt=AAZStrArgFormat( + pattern="^[A-Z]{2}$", + ), + ) + + ip_prefixes = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrArg( + nullable=True, + ) + + policy_action = cls._args_schema.mitigation_rules.Element.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrArg( + options=["action-type"], + help="The source policy action type.", + enum={"Deny": "Deny", "Permit": "Permit"}, + ) + + tcp_default_mitigations = cls._args_schema.mitigation_rules.Element.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectArg( + options=["per-source-connection-rate-limiting"], + help="The per-source rate limit for new TCP connection establishments.", + nullable=True, + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectArg( + options=["per-source-rate-limiting"], + help="The per-source TCP packet rate limit.", + nullable=True, + ) + + per_source_connection_rate_limiting = cls._args_schema.mitigation_rules.Element.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntArg( + options=["connections-per-second"], + help="The maximum number of new TCP connections established per second from a source IP.", + ) + + per_source_rate_limiting = cls._args_schema.mitigation_rules.Element.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntArg( + options=["packets-per-second"], + help="The maximum number of TCP packets allowed per second from a source IP.", + ) + + udp_default_mitigations = cls._args_schema.mitigation_rules.Element.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectArg( + options=["per-source-rate-limiting"], + help="The per-source UDP packet rate limit.", + nullable=True, + ) + + per_source_rate_limiting = cls._args_schema.mitigation_rules.Element.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntArg( + options=["packets-per-second"], + help="The maximum number of UDP packets allowed per second from a source IP.", + ) return cls._args_schema def _execute_operations(self): @@ -202,7 +346,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2025-07-01", + "api-version", "2026-03-01", required=True, ), } @@ -233,7 +377,203 @@ def _build_schema_on_200(cls): return cls._schema_on_200 cls._schema_on_200 = AAZObjectType() - _UpdateHelper._build_schema_ddos_custom_policy_read(cls._schema_on_200) + + _schema_on_200 = cls._schema_on_200 + _schema_on_200.etag = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.id = AAZStrType() + _schema_on_200.location = AAZStrType() + _schema_on_200.name = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _schema_on_200.tags = AAZDictType() + _schema_on_200.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties + properties.detection_rules = AAZListType( + serialized_name="detectionRules", + ) + properties.front_end_ip_configuration = AAZListType( + serialized_name="frontEndIpConfiguration", + ) + properties.mitigation_rules = AAZListType( + serialized_name="mitigationRules", + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.public_ip_addresses = AAZListType( + serialized_name="publicIPAddresses", + flags={"read_only": True}, + ) + properties.resource_guid = AAZStrType( + serialized_name="resourceGuid", + flags={"read_only": True}, + ) + + detection_rules = cls._schema_on_200.properties.detection_rules + detection_rules.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.detection_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType() + _element.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties.detection_rules.Element.properties + properties.detection_mode = AAZStrType( + serialized_name="detectionMode", + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.traffic_detection_rule = AAZObjectType( + serialized_name="trafficDetectionRule", + ) + + traffic_detection_rule = cls._schema_on_200.properties.detection_rules.Element.properties.traffic_detection_rule + traffic_detection_rule.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + ) + traffic_detection_rule.traffic_type = AAZStrType( + serialized_name="trafficType", + ) + + front_end_ip_configuration = cls._schema_on_200.properties.front_end_ip_configuration + front_end_ip_configuration.Element = AAZObjectType() + _UpdateHelper._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) + + mitigation_rules = cls._schema_on_200.properties.mitigation_rules + mitigation_rules.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"required": True}, + ) + _element.properties = AAZObjectType( + flags={"required": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties.mitigation_rules.Element.properties + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_policy_overrides = AAZListType( + serialized_name="sourcePolicyOverrides", + ) + properties.tcp_default_mitigations = AAZObjectType( + serialized_name="tcpDefaultMitigations", + ) + properties.traffic_scope = AAZStrType( + serialized_name="trafficScope", + flags={"required": True}, + ) + properties.udp_default_mitigations = AAZObjectType( + serialized_name="udpDefaultMitigations", + ) + + source_policy_overrides = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides + source_policy_overrides.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element + _element.conditions = AAZObjectType( + flags={"required": True}, + ) + _element.policy_action = AAZObjectType( + serialized_name="policyAction", + flags={"required": True}, + ) + + conditions = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListType( + serialized_name="geoMatches", + ) + conditions.ip_prefixes = AAZListType( + serialized_name="ipPrefixes", + ) + + geo_matches = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrType() + _element.country_code = AAZStrType( + serialized_name="countryCode", + ) + + ip_prefixes = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrType() + + policy_action = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrType( + serialized_name="actionType", + flags={"required": True}, + ) + + tcp_default_mitigations = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectType( + serialized_name="perSourceConnectionRateLimiting", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_connection_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntType( + serialized_name="connectionsPerSecond", + flags={"required": True}, + ) + + per_source_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + udp_default_mitigations = cls._schema_on_200.properties.mitigation_rules.Element.properties.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + public_ip_addresses = cls._schema_on_200.properties.public_ip_addresses + public_ip_addresses.Element = AAZObjectType() + _UpdateHelper._build_schema_common_sub_resource_read(public_ip_addresses.Element) + + tags = cls._schema_on_200.tags + tags.Element = AAZStrType() return cls._schema_on_200 @@ -301,7 +641,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2025-07-01", + "api-version", "2026-03-01", required=True, ), } @@ -344,7 +684,203 @@ def _build_schema_on_200_201(cls): return cls._schema_on_200_201 cls._schema_on_200_201 = AAZObjectType() - _UpdateHelper._build_schema_ddos_custom_policy_read(cls._schema_on_200_201) + + _schema_on_200_201 = cls._schema_on_200_201 + _schema_on_200_201.etag = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200_201.id = AAZStrType() + _schema_on_200_201.location = AAZStrType() + _schema_on_200_201.name = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200_201.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _schema_on_200_201.tags = AAZDictType() + _schema_on_200_201.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200_201.properties + properties.detection_rules = AAZListType( + serialized_name="detectionRules", + ) + properties.front_end_ip_configuration = AAZListType( + serialized_name="frontEndIpConfiguration", + ) + properties.mitigation_rules = AAZListType( + serialized_name="mitigationRules", + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.public_ip_addresses = AAZListType( + serialized_name="publicIPAddresses", + flags={"read_only": True}, + ) + properties.resource_guid = AAZStrType( + serialized_name="resourceGuid", + flags={"read_only": True}, + ) + + detection_rules = cls._schema_on_200_201.properties.detection_rules + detection_rules.Element = AAZObjectType() + + _element = cls._schema_on_200_201.properties.detection_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType() + _element.properties = AAZObjectType( + flags={"client_flatten": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200_201.properties.detection_rules.Element.properties + properties.detection_mode = AAZStrType( + serialized_name="detectionMode", + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.traffic_detection_rule = AAZObjectType( + serialized_name="trafficDetectionRule", + ) + + traffic_detection_rule = cls._schema_on_200_201.properties.detection_rules.Element.properties.traffic_detection_rule + traffic_detection_rule.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + ) + traffic_detection_rule.traffic_type = AAZStrType( + serialized_name="trafficType", + ) + + front_end_ip_configuration = cls._schema_on_200_201.properties.front_end_ip_configuration + front_end_ip_configuration.Element = AAZObjectType() + _UpdateHelper._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) + + mitigation_rules = cls._schema_on_200_201.properties.mitigation_rules + mitigation_rules.Element = AAZObjectType() + + _element = cls._schema_on_200_201.properties.mitigation_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"required": True}, + ) + _element.properties = AAZObjectType( + flags={"required": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200_201.properties.mitigation_rules.Element.properties + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_policy_overrides = AAZListType( + serialized_name="sourcePolicyOverrides", + ) + properties.tcp_default_mitigations = AAZObjectType( + serialized_name="tcpDefaultMitigations", + ) + properties.traffic_scope = AAZStrType( + serialized_name="trafficScope", + flags={"required": True}, + ) + properties.udp_default_mitigations = AAZObjectType( + serialized_name="udpDefaultMitigations", + ) + + source_policy_overrides = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides + source_policy_overrides.Element = AAZObjectType() + + _element = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element + _element.conditions = AAZObjectType( + flags={"required": True}, + ) + _element.policy_action = AAZObjectType( + serialized_name="policyAction", + flags={"required": True}, + ) + + conditions = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListType( + serialized_name="geoMatches", + ) + conditions.ip_prefixes = AAZListType( + serialized_name="ipPrefixes", + ) + + geo_matches = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectType() + + _element = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrType() + _element.country_code = AAZStrType( + serialized_name="countryCode", + ) + + ip_prefixes = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrType() + + policy_action = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrType( + serialized_name="actionType", + flags={"required": True}, + ) + + tcp_default_mitigations = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectType( + serialized_name="perSourceConnectionRateLimiting", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_connection_rate_limiting = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntType( + serialized_name="connectionsPerSecond", + flags={"required": True}, + ) + + per_source_rate_limiting = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + udp_default_mitigations = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_rate_limiting = cls._schema_on_200_201.properties.mitigation_rules.Element.properties.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + public_ip_addresses = cls._schema_on_200_201.properties.public_ip_addresses + public_ip_addresses.Element = AAZObjectType() + _UpdateHelper._build_schema_common_sub_resource_read(public_ip_addresses.Element) + + tags = cls._schema_on_200_201.tags + tags.Element = AAZStrType() return cls._schema_on_200_201 @@ -366,6 +902,7 @@ def _update_instance(self, instance): properties = _builder.get(".properties") if properties is not None: properties.set_prop("detectionRules", AAZListType, ".detection_rules") + properties.set_prop("mitigationRules", AAZListType, ".mitigation_rules") detection_rules = _builder.get(".properties.detectionRules") if detection_rules is not None: @@ -373,6 +910,7 @@ def _update_instance(self, instance): _elements = _builder.get(".properties.detectionRules[]") if _elements is not None: + _elements.set_prop("id", AAZStrType, ".id") _elements.set_prop("name", AAZStrType, ".name") _elements.set_prop("properties", AAZObjectType, typ_kwargs={"flags": {"client_flatten": True}}) @@ -386,6 +924,75 @@ def _update_instance(self, instance): traffic_detection_rule.set_prop("packetsPerSecond", AAZIntType, ".packets_per_second") traffic_detection_rule.set_prop("trafficType", AAZStrType, ".traffic_type") + mitigation_rules = _builder.get(".properties.mitigationRules") + if mitigation_rules is not None: + mitigation_rules.set_elements(AAZObjectType, ".") + + _elements = _builder.get(".properties.mitigationRules[]") + if _elements is not None: + _elements.set_prop("id", AAZStrType, ".id") + _elements.set_prop("name", AAZStrType, ".name", typ_kwargs={"flags": {"required": True}}) + _elements.set_prop("properties", AAZObjectType, ".", typ_kwargs={"flags": {"required": True}}) + + properties = _builder.get(".properties.mitigationRules[].properties") + if properties is not None: + properties.set_prop("sourcePolicyOverrides", AAZListType, ".source_policy_overrides") + properties.set_prop("tcpDefaultMitigations", AAZObjectType, ".tcp_default_mitigations") + properties.set_prop("trafficScope", AAZStrType, ".traffic_scope", typ_kwargs={"flags": {"required": True}}) + properties.set_prop("udpDefaultMitigations", AAZObjectType, ".udp_default_mitigations") + + source_policy_overrides = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides") + if source_policy_overrides is not None: + source_policy_overrides.set_elements(AAZObjectType, ".") + + _elements = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[]") + if _elements is not None: + _elements.set_prop("conditions", AAZObjectType, ".conditions", typ_kwargs={"flags": {"required": True}}) + _elements.set_prop("policyAction", AAZObjectType, ".policy_action", typ_kwargs={"flags": {"required": True}}) + + conditions = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions") + if conditions is not None: + conditions.set_prop("geoMatches", AAZListType, ".geo_matches") + conditions.set_prop("ipPrefixes", AAZListType, ".ip_prefixes") + + geo_matches = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions.geoMatches") + if geo_matches is not None: + geo_matches.set_elements(AAZObjectType, ".") + + _elements = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions.geoMatches[]") + if _elements is not None: + _elements.set_prop("continent", AAZStrType, ".continent") + _elements.set_prop("countryCode", AAZStrType, ".country_code") + + ip_prefixes = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].conditions.ipPrefixes") + if ip_prefixes is not None: + ip_prefixes.set_elements(AAZStrType, ".") + + policy_action = _builder.get(".properties.mitigationRules[].properties.sourcePolicyOverrides[].policyAction") + if policy_action is not None: + policy_action.set_prop("actionType", AAZStrType, ".action_type", typ_kwargs={"flags": {"required": True}}) + + tcp_default_mitigations = _builder.get(".properties.mitigationRules[].properties.tcpDefaultMitigations") + if tcp_default_mitigations is not None: + tcp_default_mitigations.set_prop("perSourceConnectionRateLimiting", AAZObjectType, ".per_source_connection_rate_limiting") + tcp_default_mitigations.set_prop("perSourceRateLimiting", AAZObjectType, ".per_source_rate_limiting") + + per_source_connection_rate_limiting = _builder.get(".properties.mitigationRules[].properties.tcpDefaultMitigations.perSourceConnectionRateLimiting") + if per_source_connection_rate_limiting is not None: + per_source_connection_rate_limiting.set_prop("connectionsPerSecond", AAZIntType, ".connections_per_second", typ_kwargs={"flags": {"required": True}}) + + per_source_rate_limiting = _builder.get(".properties.mitigationRules[].properties.tcpDefaultMitigations.perSourceRateLimiting") + if per_source_rate_limiting is not None: + per_source_rate_limiting.set_prop("packetsPerSecond", AAZIntType, ".packets_per_second", typ_kwargs={"flags": {"required": True}}) + + udp_default_mitigations = _builder.get(".properties.mitigationRules[].properties.udpDefaultMitigations") + if udp_default_mitigations is not None: + udp_default_mitigations.set_prop("perSourceRateLimiting", AAZObjectType, ".per_source_rate_limiting") + + per_source_rate_limiting = _builder.get(".properties.mitigationRules[].properties.udpDefaultMitigations.perSourceRateLimiting") + if per_source_rate_limiting is not None: + per_source_rate_limiting.set_prop("packetsPerSecond", AAZIntType, ".packets_per_second", typ_kwargs={"flags": {"required": True}}) + tags = _builder.get(".tags") if tags is not None: tags.set_elements(AAZStrType, ".") @@ -419,115 +1026,5 @@ def _build_schema_common_sub_resource_read(cls, _schema): _schema.id = cls._schema_common_sub_resource_read.id - _schema_ddos_custom_policy_read = None - - @classmethod - def _build_schema_ddos_custom_policy_read(cls, _schema): - if cls._schema_ddos_custom_policy_read is not None: - _schema.etag = cls._schema_ddos_custom_policy_read.etag - _schema.id = cls._schema_ddos_custom_policy_read.id - _schema.location = cls._schema_ddos_custom_policy_read.location - _schema.name = cls._schema_ddos_custom_policy_read.name - _schema.properties = cls._schema_ddos_custom_policy_read.properties - _schema.tags = cls._schema_ddos_custom_policy_read.tags - _schema.type = cls._schema_ddos_custom_policy_read.type - return - - cls._schema_ddos_custom_policy_read = _schema_ddos_custom_policy_read = AAZObjectType() - - ddos_custom_policy_read = _schema_ddos_custom_policy_read - ddos_custom_policy_read.etag = AAZStrType( - flags={"read_only": True}, - ) - ddos_custom_policy_read.id = AAZStrType() - ddos_custom_policy_read.location = AAZStrType() - ddos_custom_policy_read.name = AAZStrType( - flags={"read_only": True}, - ) - ddos_custom_policy_read.properties = AAZObjectType( - flags={"client_flatten": True}, - ) - ddos_custom_policy_read.tags = AAZDictType() - ddos_custom_policy_read.type = AAZStrType( - flags={"read_only": True}, - ) - - properties = _schema_ddos_custom_policy_read.properties - properties.detection_rules = AAZListType( - serialized_name="detectionRules", - ) - properties.front_end_ip_configuration = AAZListType( - serialized_name="frontEndIpConfiguration", - ) - properties.provisioning_state = AAZStrType( - serialized_name="provisioningState", - flags={"read_only": True}, - ) - properties.public_ip_addresses = AAZListType( - serialized_name="publicIPAddresses", - flags={"read_only": True}, - ) - properties.resource_guid = AAZStrType( - serialized_name="resourceGuid", - flags={"read_only": True}, - ) - - detection_rules = _schema_ddos_custom_policy_read.properties.detection_rules - detection_rules.Element = AAZObjectType() - - _element = _schema_ddos_custom_policy_read.properties.detection_rules.Element - _element.etag = AAZStrType( - flags={"read_only": True}, - ) - _element.id = AAZStrType( - flags={"read_only": True}, - ) - _element.name = AAZStrType() - _element.properties = AAZObjectType( - flags={"client_flatten": True}, - ) - _element.type = AAZStrType( - flags={"read_only": True}, - ) - - properties = _schema_ddos_custom_policy_read.properties.detection_rules.Element.properties - properties.detection_mode = AAZStrType( - serialized_name="detectionMode", - ) - properties.provisioning_state = AAZStrType( - serialized_name="provisioningState", - flags={"read_only": True}, - ) - properties.traffic_detection_rule = AAZObjectType( - serialized_name="trafficDetectionRule", - ) - - traffic_detection_rule = _schema_ddos_custom_policy_read.properties.detection_rules.Element.properties.traffic_detection_rule - traffic_detection_rule.packets_per_second = AAZIntType( - serialized_name="packetsPerSecond", - ) - traffic_detection_rule.traffic_type = AAZStrType( - serialized_name="trafficType", - ) - - front_end_ip_configuration = _schema_ddos_custom_policy_read.properties.front_end_ip_configuration - front_end_ip_configuration.Element = AAZObjectType() - cls._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) - - public_ip_addresses = _schema_ddos_custom_policy_read.properties.public_ip_addresses - public_ip_addresses.Element = AAZObjectType() - cls._build_schema_common_sub_resource_read(public_ip_addresses.Element) - - tags = _schema_ddos_custom_policy_read.tags - tags.Element = AAZStrType() - - _schema.etag = cls._schema_ddos_custom_policy_read.etag - _schema.id = cls._schema_ddos_custom_policy_read.id - _schema.location = cls._schema_ddos_custom_policy_read.location - _schema.name = cls._schema_ddos_custom_policy_read.name - _schema.properties = cls._schema_ddos_custom_policy_read.properties - _schema.tags = cls._schema_ddos_custom_policy_read.tags - _schema.type = cls._schema_ddos_custom_policy_read.type - __all__ = ["Update"] diff --git a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_wait.py b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_wait.py index ef1f8bbf9d1..e5825749806 100644 --- a/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_wait.py +++ b/src/azure-cli/azure/cli/command_modules/network/aaz/latest/network/ddos_custom_policy/_wait.py @@ -20,7 +20,7 @@ class Wait(AAZWaitCommand): _aaz_info = { "resources": [ - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2025-07-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.network/ddoscustompolicies/{}", "2026-03-01"], ] } @@ -116,7 +116,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2025-07-01", + "api-version", "2026-03-01", required=True, ), } @@ -172,6 +172,9 @@ def _build_schema_on_200(cls): properties.front_end_ip_configuration = AAZListType( serialized_name="frontEndIpConfiguration", ) + properties.mitigation_rules = AAZListType( + serialized_name="mitigationRules", + ) properties.provisioning_state = AAZStrType( serialized_name="provisioningState", flags={"read_only": True}, @@ -227,6 +230,114 @@ def _build_schema_on_200(cls): front_end_ip_configuration.Element = AAZObjectType() _WaitHelper._build_schema_common_sub_resource_read(front_end_ip_configuration.Element) + mitigation_rules = cls._schema_on_200.properties.mitigation_rules + mitigation_rules.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element + _element.etag = AAZStrType( + flags={"read_only": True}, + ) + _element.id = AAZStrType( + flags={"read_only": True}, + ) + _element.name = AAZStrType( + flags={"required": True}, + ) + _element.properties = AAZObjectType( + flags={"required": True}, + ) + _element.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties.mitigation_rules.Element.properties + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_policy_overrides = AAZListType( + serialized_name="sourcePolicyOverrides", + ) + properties.tcp_default_mitigations = AAZObjectType( + serialized_name="tcpDefaultMitigations", + ) + properties.traffic_scope = AAZStrType( + serialized_name="trafficScope", + flags={"required": True}, + ) + properties.udp_default_mitigations = AAZObjectType( + serialized_name="udpDefaultMitigations", + ) + + source_policy_overrides = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides + source_policy_overrides.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element + _element.conditions = AAZObjectType( + flags={"required": True}, + ) + _element.policy_action = AAZObjectType( + serialized_name="policyAction", + flags={"required": True}, + ) + + conditions = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions + conditions.geo_matches = AAZListType( + serialized_name="geoMatches", + ) + conditions.ip_prefixes = AAZListType( + serialized_name="ipPrefixes", + ) + + geo_matches = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches + geo_matches.Element = AAZObjectType() + + _element = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.geo_matches.Element + _element.continent = AAZStrType() + _element.country_code = AAZStrType( + serialized_name="countryCode", + ) + + ip_prefixes = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.conditions.ip_prefixes + ip_prefixes.Element = AAZStrType() + + policy_action = cls._schema_on_200.properties.mitigation_rules.Element.properties.source_policy_overrides.Element.policy_action + policy_action.action_type = AAZStrType( + serialized_name="actionType", + flags={"required": True}, + ) + + tcp_default_mitigations = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations + tcp_default_mitigations.per_source_connection_rate_limiting = AAZObjectType( + serialized_name="perSourceConnectionRateLimiting", + ) + tcp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_connection_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_connection_rate_limiting + per_source_connection_rate_limiting.connections_per_second = AAZIntType( + serialized_name="connectionsPerSecond", + flags={"required": True}, + ) + + per_source_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.tcp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + + udp_default_mitigations = cls._schema_on_200.properties.mitigation_rules.Element.properties.udp_default_mitigations + udp_default_mitigations.per_source_rate_limiting = AAZObjectType( + serialized_name="perSourceRateLimiting", + ) + + per_source_rate_limiting = cls._schema_on_200.properties.mitigation_rules.Element.properties.udp_default_mitigations.per_source_rate_limiting + per_source_rate_limiting.packets_per_second = AAZIntType( + serialized_name="packetsPerSecond", + flags={"required": True}, + ) + public_ip_addresses = cls._schema_on_200.properties.public_ip_addresses public_ip_addresses.Element = AAZObjectType() _WaitHelper._build_schema_common_sub_resource_read(public_ip_addresses.Element) diff --git a/src/azure-cli/azure/cli/command_modules/network/custom.py b/src/azure-cli/azure/cli/command_modules/network/custom.py index 43ced27457a..06dca295fe9 100644 --- a/src/azure-cli/azure/cli/command_modules/network/custom.py +++ b/src/azure-cli/azure/cli/command_modules/network/custom.py @@ -6906,11 +6906,17 @@ def _build_arguments_schema(cls, *args, **kwargs): def create_ddos_custom_policy(cmd, ddos_custom_policy_name, resource_group_name, location=None, tags=None, detection_rule_name=None, detection_mode=None, traffic_type=None, - packets_per_second=None, no_wait=None): + packets_per_second=None, mitigation_rules=None, no_wait=None): from .aaz.latest.network.ddos_custom_policy import Create as DdosCustomPolicyCreate, Show as DdosCustomPolicyShow from .operations.ddos_custom_policy import convert_ddos_custom_policy_to_snake_case, combine_old_and_new_custom_policy from ._template_builder import build_ddos_custom_policy + if mitigation_rules: + # `--mitigation-rules` is parsed by the AAZ action; materialize it into plain dicts so it can be merged. + args = DdosCustomPolicyCreate._build_arguments_schema()() + mitigation_rules.apply(args, 'mitigation_rules') + mitigation_rules = args.mitigation_rules.to_serialized_data() + existing_policy = None try: @@ -6930,7 +6936,7 @@ def create_ddos_custom_policy(cmd, ddos_custom_policy_name, resource_group_name, ddos_custom_policy_name, resource_group_name, err) policy = build_ddos_custom_policy(cmd, ddos_custom_policy_name, location, tags, detection_rule_name, detection_mode, - packets_per_second, traffic_type) + packets_per_second, traffic_type, mitigation_rules) if existing_policy: policy = combine_old_and_new_custom_policy(existing_policy, policy) diff --git a/src/azure-cli/azure/cli/command_modules/network/operations/ddos_custom_policy.py b/src/azure-cli/azure/cli/command_modules/network/operations/ddos_custom_policy.py index 57c0be06493..0f7961315b3 100644 --- a/src/azure-cli/azure/cli/command_modules/network/operations/ddos_custom_policy.py +++ b/src/azure-cli/azure/cli/command_modules/network/operations/ddos_custom_policy.py @@ -4,32 +4,29 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long, protected-access, too-few-public-methods +import re -def combine_old_and_new_custom_policy(old_policy, new_policy): - old_rules = old_policy.get('detection_rules', []) - new_rules = new_policy.get('detection_rules', []) - - new_rule_name = {rule['name']: rule for rule in new_rules} - combined_rule = [] - used = [] +def _merge_rules_by_name(old_rules, new_rules): + new_by_name = {rule.get('name'): rule for rule in new_rules} + merged = [new_by_name.pop(rule.get('name'), rule) for rule in old_rules] + return merged + list(new_by_name.values()) - for rule in old_rules: - name = rule.get('name') - if name in new_rule_name: - combined_rule.append(new_rule_name[name]) - used.append(name) - continue - combined_rule.append(rule) +def combine_old_and_new_custom_policy(old_policy, new_policy): + for key in ('detection_rules', 'mitigation_rules'): + rules = _merge_rules_by_name(old_policy.get(key, []), new_policy.get(key, [])) + if rules: + new_policy[key] = rules + return new_policy - for rule in new_rules: - name = rule.get('name') - if name not in used: - combined_rule.append(rule) - new_policy['detection_rules'] = combined_rule - return new_policy +def _camel_to_snake(data): + if isinstance(data, dict): + return {re.sub(r'(?