diff --git a/src/relationship/HISTORY.rst b/src/relationship/HISTORY.rst index bfa2397441e..cabde49fcfb 100644 --- a/src/relationship/HISTORY.rst +++ b/src/relationship/HISTORY.rst @@ -3,6 +3,11 @@ Release History =============== +1.0.0b2 ++++++++ +* Update relationship commands to use stable API version 2026-08-01. +* Update serviceGroupMember creation to use a Service Group source with ``--source-id``. + 1.0.0b1 +++++++ * Initial release. diff --git a/src/relationship/README.md b/src/relationship/README.md index 6842606907f..1c81025f23d 100644 --- a/src/relationship/README.md +++ b/src/relationship/README.md @@ -5,7 +5,7 @@ Relationships are ARM extension resources that create semantic associations between a source resource and a target resource. Two relationship types are supported: - **dependencyOf** — creates dependency links between ARM resources -- **serviceGroupMember** — associates resources with Service Groups +- **serviceGroupMember** — associates Azure resources with Service Groups, with the Service Group as the relationship source ## How to use ## Install this extension using the below CLI command @@ -50,7 +50,7 @@ az relationship dependency-of delete \ az relationship service-group-member create \ --resource-uri "/subscriptions/{sub}/resourceGroups/{rg}" \ --name myMembership \ - --target-id "/providers/Microsoft.Management/serviceGroups/mySG" + --source-id "/providers/Microsoft.Management/serviceGroups/mySG" ``` #### Show a serviceGroupMember relationship diff --git a/src/relationship/azext_relationship/_help.py b/src/relationship/azext_relationship/_help.py index 130446b7d6b..69c25528733 100644 --- a/src/relationship/azext_relationship/_help.py +++ b/src/relationship/azext_relationship/_help.py @@ -75,9 +75,8 @@ type: group short-summary: Manage serviceGroupMember relationships. long-summary: | - ServiceGroupMember relationships associate resources with Service Groups. - Valid sources: Service Groups, Subscriptions, Resource Groups, Resources. - Valid targets: Service Groups ONLY. + ServiceGroupMember relationships associate Azure resources with Service Groups. + The source must be a Service Group. The target is the resource identified by --resource-uri. """ helps['relationship service-group-member create'] = """ @@ -85,18 +84,18 @@ short-summary: Create a serviceGroupMember relationship. long-summary: Create or update a serviceGroupMember relationship. This is a long-running operation. examples: - - name: Create a service group membership from a resource group + - name: Add a resource group to a service group text: > az relationship service-group-member create --resource-uri "/subscriptions/{sub}/resourceGroups/{rg}" --name myMembership - --target-id "/providers/Microsoft.Management/serviceGroups/mySG" - - name: Create a service group membership from a subscription + --source-id "/providers/Microsoft.Management/serviceGroups/mySG" + - name: Add a subscription to a service group text: > az relationship service-group-member create --resource-uri "/subscriptions/{sub}" --name subMembership - --target-id "/providers/Microsoft.Management/serviceGroups/mySG" + --source-id "/providers/Microsoft.Management/serviceGroups/mySG" """ helps['relationship service-group-member show'] = """ diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/__init__.py b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/__init__.py index 45df27f97a0..1965d86a763 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/__init__.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/__init__.py @@ -12,3 +12,4 @@ from ._create import * from ._delete import * from ._show import * +from ._wait import * diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_create.py b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_create.py index ead4dcd06e9..00f0b42d07f 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_create.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_create.py @@ -19,9 +19,9 @@ class Create(AAZCommand): """ _aaz_info = { - "version": "2023-09-01-preview", + "version": "2026-08-01", "resources": [ - ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/dependencyof/{}", "2023-09-01-preview"], + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/dependencyof/{}", "2026-08-01"], ] } @@ -46,9 +46,6 @@ def _build_arguments_schema(cls, *args, **kwargs): options=["--name"], help="Name of dependencyOf relationship.", required=True, - fmt=AAZStrArgFormat( - pattern="^[a-zA-Z0-9]{3,64}$", - ), ) _args_schema.resource_uri = AAZStrArg( options=["--resource-uri"], @@ -150,7 +147,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01-preview", + "api-version", "2026-08-01", required=True, ), } diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_delete.py b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_delete.py index 1aca244efd1..ad73d410fe9 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_delete.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_delete.py @@ -13,16 +13,16 @@ @register_command( "relationship dependency-of delete", - confirmation="Are you sure you want to delete this relationship?", + confirmation="Are you sure you want to perform this operation?", ) class Delete(AAZCommand): """Delete a DependencyOfRelationship """ _aaz_info = { - "version": "2023-09-01-preview", + "version": "2026-08-01", "resources": [ - ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/dependencyof/{}", "2023-09-01-preview"], + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/dependencyof/{}", "2026-08-01"], ] } @@ -47,9 +47,6 @@ def _build_arguments_schema(cls, *args, **kwargs): options=["--name"], help="Name of dependencyOf relationship.", required=True, - fmt=AAZStrArgFormat( - pattern="^[a-zA-Z0-9]{3,64}$", - ), ) _args_schema.resource_uri = AAZStrArg( options=["--resource-uri"], @@ -141,7 +138,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01-preview", + "api-version", "2026-08-01", required=True, ), } diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_show.py b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_show.py index 8bd0e33971c..cfc8d861fa9 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_show.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_show.py @@ -19,9 +19,9 @@ class Show(AAZCommand): """ _aaz_info = { - "version": "2023-09-01-preview", + "version": "2026-08-01", "resources": [ - ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/dependencyof/{}", "2023-09-01-preview"], + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/dependencyof/{}", "2026-08-01"], ] } @@ -45,9 +45,6 @@ def _build_arguments_schema(cls, *args, **kwargs): options=["--name"], help="Name of dependencyOf relationship.", required=True, - fmt=AAZStrArgFormat( - pattern="^[a-zA-Z0-9]{3,64}$", - ), ) _args_schema.resource_uri = AAZStrArg( options=["--resource-uri"], @@ -118,7 +115,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01-preview", + "api-version", "2026-08-01", required=True, ), } diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_wait.py b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_wait.py new file mode 100644 index 00000000000..d0de939eee2 --- /dev/null +++ b/src/relationship/azext_relationship/aaz/latest/relationship/dependency_of/_wait.py @@ -0,0 +1,236 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "relationship dependency-of wait", +) +class Wait(AAZWaitCommand): + """Place the CLI in a waiting state until a condition is met. + """ + + _aaz_info = { + "resources": [ + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/dependencyof/{}", "2026-08-01"], + ] + } + + def _handler(self, command_args): + super()._handler(command_args) + self._execute_operations() + return self._output() + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.name = AAZStrArg( + options=["--name"], + help="Name of dependencyOf relationship.", + required=True, + ) + _args_schema.resource_uri = AAZStrArg( + options=["--resource-uri"], + help="The fully qualified Azure Resource manager identifier of the resource.", + required=True, + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.DependencyOfRelationshipsGet(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance, client_flatten=False) + return result + + class DependencyOfRelationshipsGet(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( + "/{resourceUri}/providers/Microsoft.Relationships/dependencyOf/{name}", + **self.url_parameters + ) + + @property + def method(self): + return "GET" + + @property + def error_format(self): + return "MgmtErrorFormat" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "name", self.ctx.args.name, + required=True, + ), + **self.serialize_url_param( + "resourceUri", self.ctx.args.resource_uri, + skip_quote=True, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2026-08-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.id = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.name = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.properties = AAZObjectType() + _schema_on_200.system_data = AAZObjectType( + serialized_name="systemData", + flags={"read_only": True}, + ) + _schema_on_200.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties + properties.metadata = AAZObjectType( + flags={"read_only": True}, + ) + properties.origin_information = AAZObjectType( + serialized_name="originInformation", + flags={"read_only": True}, + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_id = AAZStrType( + serialized_name="sourceId", + flags={"read_only": True}, + ) + properties.target_id = AAZStrType( + serialized_name="targetId", + flags={"required": True}, + ) + properties.target_tenant = AAZStrType( + serialized_name="targetTenant", + ) + + metadata = cls._schema_on_200.properties.metadata + metadata.source_type = AAZStrType( + serialized_name="sourceType", + flags={"read_only": True}, + ) + metadata.target_type = AAZStrType( + serialized_name="targetType", + flags={"read_only": True}, + ) + + origin_information = cls._schema_on_200.properties.origin_information + origin_information.discovery_engine = AAZStrType( + serialized_name="discoveryEngine", + flags={"read_only": True}, + ) + origin_information.relationship_origin_type = AAZStrType( + serialized_name="relationshipOriginType", + flags={"read_only": True}, + ) + + system_data = cls._schema_on_200.system_data + system_data.created_at = AAZStrType( + serialized_name="createdAt", + ) + system_data.created_by = AAZStrType( + serialized_name="createdBy", + ) + system_data.created_by_type = AAZStrType( + serialized_name="createdByType", + ) + system_data.last_modified_at = AAZStrType( + serialized_name="lastModifiedAt", + ) + system_data.last_modified_by = AAZStrType( + serialized_name="lastModifiedBy", + ) + system_data.last_modified_by_type = AAZStrType( + serialized_name="lastModifiedByType", + ) + + return cls._schema_on_200 + + +class _WaitHelper: + """Helper class for Wait""" + + +__all__ = ["Wait"] diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/__init__.py b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/__init__.py index 45df27f97a0..1965d86a763 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/__init__.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/__init__.py @@ -12,3 +12,4 @@ from ._create import * from ._delete import * from ._show import * +from ._wait import * diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_create.py b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_create.py index 5c839d37dca..c80f6e394cd 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_create.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_create.py @@ -19,9 +19,9 @@ class Create(AAZCommand): """ _aaz_info = { - "version": "2023-09-01-preview", + "version": "2026-08-01", "resources": [ - ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/servicegroupmember/{}", "2023-09-01-preview"], + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/servicegroupmember/{}", "2026-08-01"], ] } @@ -46,9 +46,6 @@ def _build_arguments_schema(cls, *args, **kwargs): options=["--name"], help="Name of ServiceGroupMember relationship.", required=True, - fmt=AAZStrArgFormat( - pattern="^[a-zA-Z0-9]{3,64}$", - ), ) _args_schema.resource_uri = AAZStrArg( options=["--resource-uri"], @@ -59,16 +56,16 @@ def _build_arguments_schema(cls, *args, **kwargs): # define Arg Group "Properties" _args_schema = cls._args_schema - _args_schema.target_id = AAZResourceIdArg( - options=["--target-id"], + _args_schema.source_id = AAZResourceIdArg( + options=["--source-id"], arg_group="Properties", - help="The relationship target resource id.", + help="The relationship source resource id. Must be a service group.", required=True, ) - _args_schema.target_tenant = AAZStrArg( - options=["--target-tenant"], + _args_schema.source_tenant = AAZStrArg( + options=["--source-tenant"], arg_group="Properties", - help="The relationship target tenant id.", + help="The relationship source tenant id.", ) return cls._args_schema @@ -150,7 +147,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01-preview", + "api-version", "2026-08-01", required=True, ), } @@ -179,8 +176,8 @@ def content(self): properties = _builder.get(".properties") if properties is not None: - properties.set_prop("targetId", AAZStrType, ".target_id", typ_kwargs={"flags": {"required": True}}) - properties.set_prop("targetTenant", AAZStrType, ".target_tenant") + properties.set_prop("sourceId", AAZStrType, ".source_id", typ_kwargs={"flags": {"required": True}}) + properties.set_prop("sourceTenant", AAZStrType, ".source_tenant") return self.serialize_content(_content_value) @@ -231,14 +228,14 @@ def _build_schema_on_200_201(cls): ) properties.source_id = AAZStrType( serialized_name="sourceId", - flags={"read_only": True}, + flags={"required": True}, + ) + properties.source_tenant = AAZStrType( + serialized_name="sourceTenant", ) properties.target_id = AAZStrType( serialized_name="targetId", - flags={"required": True}, - ) - properties.target_tenant = AAZStrType( - serialized_name="targetTenant", + flags={"read_only": True}, ) metadata = cls._schema_on_200_201.properties.metadata diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_delete.py b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_delete.py index 87cbf9a723f..e94093b0258 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_delete.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_delete.py @@ -13,16 +13,16 @@ @register_command( "relationship service-group-member delete", - confirmation="Are you sure you want to delete this relationship?", + confirmation="Are you sure you want to perform this operation?", ) class Delete(AAZCommand): """Delete a ServiceGroupMemberRelationship """ _aaz_info = { - "version": "2023-09-01-preview", + "version": "2026-08-01", "resources": [ - ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/servicegroupmember/{}", "2023-09-01-preview"], + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/servicegroupmember/{}", "2026-08-01"], ] } @@ -47,9 +47,6 @@ def _build_arguments_schema(cls, *args, **kwargs): options=["--name"], help="Name of ServiceGroupMember relationship.", required=True, - fmt=AAZStrArgFormat( - pattern="^[a-zA-Z0-9]{3,64}$", - ), ) _args_schema.resource_uri = AAZStrArg( options=["--resource-uri"], @@ -141,7 +138,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01-preview", + "api-version", "2026-08-01", required=True, ), } diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_show.py b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_show.py index d6d3ed3a8ed..5688a0a0b8f 100644 --- a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_show.py +++ b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_show.py @@ -19,9 +19,9 @@ class Show(AAZCommand): """ _aaz_info = { - "version": "2023-09-01-preview", + "version": "2026-08-01", "resources": [ - ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/servicegroupmember/{}", "2023-09-01-preview"], + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/servicegroupmember/{}", "2026-08-01"], ] } @@ -45,9 +45,6 @@ def _build_arguments_schema(cls, *args, **kwargs): options=["--name"], help="Name of ServiceGroupMember relationship.", required=True, - fmt=AAZStrArgFormat( - pattern="^[a-zA-Z0-9]{3,64}$", - ), ) _args_schema.resource_uri = AAZStrArg( options=["--resource-uri"], @@ -118,7 +115,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01-preview", + "api-version", "2026-08-01", required=True, ), } @@ -180,14 +177,14 @@ def _build_schema_on_200(cls): ) properties.source_id = AAZStrType( serialized_name="sourceId", - flags={"read_only": True}, + flags={"required": True}, + ) + properties.source_tenant = AAZStrType( + serialized_name="sourceTenant", ) properties.target_id = AAZStrType( serialized_name="targetId", - flags={"required": True}, - ) - properties.target_tenant = AAZStrType( - serialized_name="targetTenant", + flags={"read_only": True}, ) metadata = cls._schema_on_200.properties.metadata diff --git a/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_wait.py b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_wait.py new file mode 100644 index 00000000000..cc8d6299327 --- /dev/null +++ b/src/relationship/azext_relationship/aaz/latest/relationship/service_group_member/_wait.py @@ -0,0 +1,236 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "relationship service-group-member wait", +) +class Wait(AAZWaitCommand): + """Place the CLI in a waiting state until a condition is met. + """ + + _aaz_info = { + "resources": [ + ["mgmt-plane", "/{resourceuri}/providers/microsoft.relationships/servicegroupmember/{}", "2026-08-01"], + ] + } + + def _handler(self, command_args): + super()._handler(command_args) + self._execute_operations() + return self._output() + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.name = AAZStrArg( + options=["--name"], + help="Name of ServiceGroupMember relationship.", + required=True, + ) + _args_schema.resource_uri = AAZStrArg( + options=["--resource-uri"], + help="The fully qualified Azure Resource manager identifier of the resource.", + required=True, + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.ServiceGroupMemberRelationshipsGet(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance, client_flatten=False) + return result + + class ServiceGroupMemberRelationshipsGet(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( + "/{resourceUri}/providers/Microsoft.Relationships/serviceGroupMember/{name}", + **self.url_parameters + ) + + @property + def method(self): + return "GET" + + @property + def error_format(self): + return "MgmtErrorFormat" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "name", self.ctx.args.name, + required=True, + ), + **self.serialize_url_param( + "resourceUri", self.ctx.args.resource_uri, + skip_quote=True, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2026-08-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.id = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.name = AAZStrType( + flags={"read_only": True}, + ) + _schema_on_200.properties = AAZObjectType() + _schema_on_200.system_data = AAZObjectType( + serialized_name="systemData", + flags={"read_only": True}, + ) + _schema_on_200.type = AAZStrType( + flags={"read_only": True}, + ) + + properties = cls._schema_on_200.properties + properties.metadata = AAZObjectType( + flags={"read_only": True}, + ) + properties.origin_information = AAZObjectType( + serialized_name="originInformation", + flags={"read_only": True}, + ) + properties.provisioning_state = AAZStrType( + serialized_name="provisioningState", + flags={"read_only": True}, + ) + properties.source_id = AAZStrType( + serialized_name="sourceId", + flags={"required": True}, + ) + properties.source_tenant = AAZStrType( + serialized_name="sourceTenant", + ) + properties.target_id = AAZStrType( + serialized_name="targetId", + flags={"read_only": True}, + ) + + metadata = cls._schema_on_200.properties.metadata + metadata.source_type = AAZStrType( + serialized_name="sourceType", + flags={"read_only": True}, + ) + metadata.target_type = AAZStrType( + serialized_name="targetType", + flags={"read_only": True}, + ) + + origin_information = cls._schema_on_200.properties.origin_information + origin_information.discovery_engine = AAZStrType( + serialized_name="discoveryEngine", + flags={"read_only": True}, + ) + origin_information.relationship_origin_type = AAZStrType( + serialized_name="relationshipOriginType", + flags={"read_only": True}, + ) + + system_data = cls._schema_on_200.system_data + system_data.created_at = AAZStrType( + serialized_name="createdAt", + ) + system_data.created_by = AAZStrType( + serialized_name="createdBy", + ) + system_data.created_by_type = AAZStrType( + serialized_name="createdByType", + ) + system_data.last_modified_at = AAZStrType( + serialized_name="lastModifiedAt", + ) + system_data.last_modified_by = AAZStrType( + serialized_name="lastModifiedBy", + ) + system_data.last_modified_by_type = AAZStrType( + serialized_name="lastModifiedByType", + ) + + return cls._schema_on_200 + + +class _WaitHelper: + """Helper class for Wait""" + + +__all__ = ["Wait"] diff --git a/src/relationship/azext_relationship/tests/latest/test_relationship_scenario.py b/src/relationship/azext_relationship/tests/latest/test_relationship_scenario.py index 807f5b64e5c..f73d7990e8f 100644 --- a/src/relationship/azext_relationship/tests/latest/test_relationship_scenario.py +++ b/src/relationship/azext_relationship/tests/latest/test_relationship_scenario.py @@ -11,8 +11,9 @@ live_only, ) -# Tests that target a real Service Group require AZURE_RELATIONSHIP_TEST_TARGET_SG -# to be explicitly configured in the live environment. +# Tests that use a real Service Group require AZURE_RELATIONSHIP_TEST_TARGET_SG +# to be explicitly configured in the live environment. It is the target for +# dependencyOf relationships and the source for serviceGroupMember relationships. SDK_TESTS_SG = os.environ.get('AZURE_RELATIONSHIP_TEST_TARGET_SG') @@ -22,7 +23,7 @@ def setUp(self): super().setUp() tests_not_requiring_target_sg = { 'test_dependency_of_same_source_target', - 'test_sgm_invalid_target', + 'test_sgm_invalid_source', 'test_sgm_nonexistent_sg', } if ( @@ -32,7 +33,7 @@ def setUp(self): ): self.skipTest( 'Set AZURE_RELATIONSHIP_TEST_TARGET_SG to run live tests ' - 'that require a pre-existing Service Group target.' + 'that require a pre-existing Service Group.' ) @live_only() @@ -46,17 +47,19 @@ def test_dependency_of_crud(self): self.cmd(f'az group create --name {rg_name} --location eastus') try: - # CREATE + # CREATE ASYNCHRONOUSLY AND WAIT self.cmd( f'az relationship dependency-of create ' f'--resource-uri "{rg_uri}" ' f'--name {rel_name} ' - f'--target-id "{SDK_TESTS_SG}"', - checks=[ - self.check('name', rel_name), - self.check('type', 'Microsoft.Relationships/dependencyOf'), - self.exists('properties.provisioningState'), - ] + f'--target-id "{SDK_TESTS_SG}" ' + f'--no-wait' + ) + self.cmd( + f'az relationship dependency-of wait ' + f'--resource-uri "{rg_uri}" ' + f'--name {rel_name} ' + f'--created' ) # SHOW @@ -66,18 +69,26 @@ def test_dependency_of_crud(self): f'--name {rel_name}', checks=[ self.check('name', rel_name), + self.check('type', 'Microsoft.Relationships/dependencyOf'), + self.check('properties.provisioningState', 'Succeeded'), + self.check('properties.sourceId', rg_uri), self.check('properties.targetId', SDK_TESTS_SG), - self.exists('properties.sourceId'), self.exists('properties.metadata.sourceType'), self.exists('properties.metadata.targetType'), ] ) - # DELETE + # DELETE ASYNCHRONOUSLY AND WAIT self.cmd( f'az relationship dependency-of delete ' f'--resource-uri "{rg_uri}" ' - f'--name {rel_name} --yes' + f'--name {rel_name} --yes --no-wait' + ) + self.cmd( + f'az relationship dependency-of wait ' + f'--resource-uri "{rg_uri}" ' + f'--name {rel_name} ' + f'--deleted' ) # VERIFY DELETE (should 404) @@ -130,7 +141,7 @@ def test_dependency_of_subscription_scope(self): @live_only() def test_service_group_member_crud(self): - """Full CRUD lifecycle for a serviceGroupMember relationship (RG → ServiceGroup).""" + """Full CRUD lifecycle for a serviceGroupMember relationship (ServiceGroup → RG).""" rg_name = self.create_random_name('rg-sgm-', 20) rel_name = 'sgmrel' + self.create_random_name('', 6).replace('-', '') sub_id = self.get_subscription_id() @@ -139,17 +150,19 @@ def test_service_group_member_crud(self): self.cmd(f'az group create --name {rg_name} --location eastus') try: - # CREATE + # CREATE ASYNCHRONOUSLY AND WAIT self.cmd( f'az relationship service-group-member create ' f'--resource-uri "{rg_uri}" ' f'--name {rel_name} ' - f'--target-id "{SDK_TESTS_SG}"', - checks=[ - self.check('name', rel_name), - self.check('type', 'Microsoft.Relationships/serviceGroupMember'), - self.exists('properties.provisioningState'), - ] + f'--source-id "{SDK_TESTS_SG}" ' + f'--no-wait' + ) + self.cmd( + f'az relationship service-group-member wait ' + f'--resource-uri "{rg_uri}" ' + f'--name {rel_name} ' + f'--created' ) # SHOW @@ -159,16 +172,26 @@ def test_service_group_member_crud(self): f'--name {rel_name}', checks=[ self.check('name', rel_name), - self.check('properties.targetId', SDK_TESTS_SG), + self.check('type', 'Microsoft.Relationships/serviceGroupMember'), + self.check('properties.provisioningState', 'Succeeded'), + self.check('properties.sourceId', SDK_TESTS_SG), + self.check('properties.targetId', rg_uri), + self.exists('properties.metadata.sourceType'), self.exists('properties.metadata.targetType'), ] ) - # DELETE + # DELETE ASYNCHRONOUSLY AND WAIT self.cmd( f'az relationship service-group-member delete ' f'--resource-uri "{rg_uri}" ' - f'--name {rel_name} --yes' + f'--name {rel_name} --yes --no-wait' + ) + self.cmd( + f'az relationship service-group-member wait ' + f'--resource-uri "{rg_uri}" ' + f'--name {rel_name} ' + f'--deleted' ) # VERIFY DELETE (should 404) @@ -183,7 +206,7 @@ def test_service_group_member_crud(self): @live_only() def test_sgm_subscription_scope(self): - """ServiceGroupMember with subscription as the source scope.""" + """ServiceGroupMember with subscription as the target scope.""" rel_name = 'sgmsub' + self.create_random_name('', 6).replace('-', '') sub_id = self.get_subscription_id() sub_uri = f'/subscriptions/{sub_id}' @@ -194,8 +217,10 @@ def test_sgm_subscription_scope(self): f'az relationship service-group-member create ' f'--resource-uri "{sub_uri}" ' f'--name {rel_name} ' - f'--target-id "{SDK_TESTS_SG}"', + f'--source-id "{SDK_TESTS_SG}"', checks=[ + self.check('properties.sourceId', SDK_TESTS_SG), + self.check('properties.targetId', sub_uri), self.exists('properties.provisioningState'), self.check('type', 'Microsoft.Relationships/serviceGroupMember'), ] @@ -208,7 +233,8 @@ def test_sgm_subscription_scope(self): f'--name {rel_name}', checks=[ self.check('name', rel_name), - self.check('properties.targetId', SDK_TESTS_SG), + self.check('properties.sourceId', SDK_TESTS_SG), + self.check('properties.targetId', sub_uri), ] ) finally: @@ -243,8 +269,8 @@ def test_dependency_of_same_source_target(self): self.cmd(f'az group delete --name {rg_name} --yes --no-wait') @live_only() - def test_sgm_invalid_target(self): - """ServiceGroupMember should fail when target is not a Service Group.""" + def test_sgm_invalid_source(self): + """ServiceGroupMember should fail when source is not a Service Group.""" rg_name = self.create_random_name('rg-err-tgt-', 20) rel_name = 'badsgm' + self.create_random_name('', 6).replace('-', '') sub_id = self.get_subscription_id() @@ -253,12 +279,12 @@ def test_sgm_invalid_target(self): self.cmd(f'az group create --name {rg_name} --location eastus') try: - # CREATE SGM targeting a resource group (not a SG) should fail + # CREATE SGM sourced from a resource group (not a SG) should fail self.cmd( f'az relationship service-group-member create ' f'--resource-uri "{rg_uri}" ' f'--name {rel_name} ' - f'--target-id "{rg_uri}"', + f'--source-id "{rg_uri}"', expect_failure=True ) finally: @@ -266,7 +292,7 @@ def test_sgm_invalid_target(self): @live_only() def test_sgm_nonexistent_sg(self): - """ServiceGroupMember should fail when target SG does not exist.""" + """ServiceGroupMember should fail when source SG does not exist.""" rg_name = self.create_random_name('rg-err-nosg-', 20) rel_name = 'badnosg' + self.create_random_name('', 6).replace('-', '') sub_id = self.get_subscription_id() @@ -276,12 +302,12 @@ def test_sgm_nonexistent_sg(self): self.cmd(f'az group create --name {rg_name} --location eastus') try: - # CREATE SGM targeting non-existent SG should fail + # CREATE SGM sourced from a non-existent SG should fail self.cmd( f'az relationship service-group-member create ' f'--resource-uri "{rg_uri}" ' f'--name {rel_name} ' - f'--target-id "{fake_sg}"', + f'--source-id "{fake_sg}"', expect_failure=True ) finally: diff --git a/src/relationship/setup.py b/src/relationship/setup.py index 2b7f1a96d64..5e593928220 100644 --- a/src/relationship/setup.py +++ b/src/relationship/setup.py @@ -8,7 +8,7 @@ # HISTORY.rst entry. -VERSION = '1.0.0b1' +VERSION = '1.0.0b2' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers