diff --git a/google/cloud/asset/__init__.py b/google/cloud/asset/__init__.py index b4309178..ae1a5cd6 100644 --- a/google/cloud/asset/__init__.py +++ b/google/cloud/asset/__init__.py @@ -67,6 +67,9 @@ from google.cloud.asset_v1.types.assets import IamPolicyAnalysisResult from google.cloud.asset_v1.types.assets import IamPolicyAnalysisState from google.cloud.asset_v1.types.assets import IamPolicySearchResult +from google.cloud.asset_v1.types.assets import RelatedAsset +from google.cloud.asset_v1.types.assets import RelatedAssets +from google.cloud.asset_v1.types.assets import RelationshipAttributes from google.cloud.asset_v1.types.assets import Resource from google.cloud.asset_v1.types.assets import ResourceSearchResult from google.cloud.asset_v1.types.assets import TemporalAsset @@ -120,6 +123,9 @@ "IamPolicyAnalysisResult", "IamPolicyAnalysisState", "IamPolicySearchResult", + "RelatedAsset", + "RelatedAssets", + "RelationshipAttributes", "Resource", "ResourceSearchResult", "TemporalAsset", diff --git a/google/cloud/asset_v1/__init__.py b/google/cloud/asset_v1/__init__.py index ada8ad1c..5628bd25 100644 --- a/google/cloud/asset_v1/__init__.py +++ b/google/cloud/asset_v1/__init__.py @@ -61,6 +61,9 @@ from .types.assets import IamPolicyAnalysisResult from .types.assets import IamPolicyAnalysisState from .types.assets import IamPolicySearchResult +from .types.assets import RelatedAsset +from .types.assets import RelatedAssets +from .types.assets import RelationshipAttributes from .types.assets import Resource from .types.assets import ResourceSearchResult from .types.assets import TemporalAsset @@ -109,6 +112,9 @@ "OutputResult", "PartitionSpec", "PubsubDestination", + "RelatedAsset", + "RelatedAssets", + "RelationshipAttributes", "Resource", "ResourceSearchResult", "SearchAllIamPoliciesRequest", diff --git a/google/cloud/asset_v1/types/__init__.py b/google/cloud/asset_v1/types/__init__.py index 4a220650..6fd16f4b 100644 --- a/google/cloud/asset_v1/types/__init__.py +++ b/google/cloud/asset_v1/types/__init__.py @@ -60,6 +60,9 @@ IamPolicyAnalysisResult, IamPolicyAnalysisState, IamPolicySearchResult, + RelatedAsset, + RelatedAssets, + RelationshipAttributes, Resource, ResourceSearchResult, TemporalAsset, @@ -112,6 +115,9 @@ "IamPolicyAnalysisResult", "IamPolicyAnalysisState", "IamPolicySearchResult", + "RelatedAsset", + "RelatedAssets", + "RelationshipAttributes", "Resource", "ResourceSearchResult", "TemporalAsset", diff --git a/google/cloud/asset_v1/types/asset_service.py b/google/cloud/asset_v1/types/asset_service.py index 6794d437..ff66dd71 100644 --- a/google/cloud/asset_v1/types/asset_service.py +++ b/google/cloud/asset_v1/types/asset_service.py @@ -76,6 +76,7 @@ class ContentType(proto.Enum): ORG_POLICY = 4 ACCESS_POLICY = 5 OS_INVENTORY = 6 + RELATIONSHIP = 7 class AnalyzeIamPolicyLongrunningMetadata(proto.Message): @@ -84,7 +85,8 @@ class AnalyzeIamPolicyLongrunningMetadata(proto.Message): Attributes: create_time (google.protobuf.timestamp_pb2.Timestamp): - The time the operation was created. + Output only. The time the operation was + created. """ create_time = proto.Field(proto.MESSAGE, number=1, message=timestamp_pb2.Timestamp,) @@ -138,6 +140,23 @@ class ExportAssetsRequest(proto.Message): output_config (google.cloud.asset_v1.types.OutputConfig): Required. Output configuration indicating where the results will be output to. + relationship_types (Sequence[str]): + A list of relationship types to export, for example: + ``INSTANCE_TO_INSTANCEGROUP``. This field should only be + specified if content_type=RELATIONSHIP. + + - If specified: it snapshots specified relationships. It + returns an error if any of the [relationship_types] + doesn't belong to the supported relationship types of the + [asset_types] or if any of the [asset_types] doesn't + belong to the source types of the [relationship_types]. + - Otherwise: it snapshots the supported relationships for + all [asset_types] or returns an error if any of the + [asset_types] has no relationship support. An unspecified + asset types field means all supported asset_types. See + `Introduction to Cloud Asset + Inventory `__ + for all supported asset types and relationship types. """ parent = proto.Field(proto.STRING, number=1,) @@ -145,6 +164,7 @@ class ExportAssetsRequest(proto.Message): asset_types = proto.RepeatedField(proto.STRING, number=3,) content_type = proto.Field(proto.ENUM, number=4, enum="ContentType",) output_config = proto.Field(proto.MESSAGE, number=5, message="OutputConfig",) + relationship_types = proto.RepeatedField(proto.STRING, number=6,) class ExportAssetsResponse(proto.Message): @@ -228,6 +248,23 @@ class ListAssetsRequest(proto.Message): ``ListAssetsRequest``. It is a continuation of a prior ``ListAssets`` call, and the API should return the next page of assets. + relationship_types (Sequence[str]): + A list of relationship types to output, for example: + ``INSTANCE_TO_INSTANCEGROUP``. This field should only be + specified if content_type=RELATIONSHIP. + + - If specified: it snapshots specified relationships. It + returns an error if any of the [relationship_types] + doesn't belong to the supported relationship types of the + [asset_types] or if any of the [asset_types] doesn't + belong to the source types of the [relationship_types]. + - Otherwise: it snapshots the supported relationships for + all [asset_types] or returns an error if any of the + [asset_types] has no relationship support. An unspecified + asset types field means all supported asset_types. See + `Introduction to Cloud Asset + Inventory `__ + for all supported asset types and relationship types. """ parent = proto.Field(proto.STRING, number=1,) @@ -236,6 +273,7 @@ class ListAssetsRequest(proto.Message): content_type = proto.Field(proto.ENUM, number=4, enum="ContentType",) page_size = proto.Field(proto.INT32, number=5,) page_token = proto.Field(proto.STRING, number=6,) + relationship_types = proto.RepeatedField(proto.STRING, number=7,) class ListAssetsResponse(proto.Message): @@ -290,6 +328,23 @@ class BatchGetAssetsHistoryRequest(proto.Message): not set, the snapshot of the assets at end_time will be returned. The returned results contain all temporal assets whose time window overlap with read_time_window. + relationship_types (Sequence[str]): + Optional. A list of relationship types to output, for + example: ``INSTANCE_TO_INSTANCEGROUP``. This field should + only be specified if content_type=RELATIONSHIP. + + - If specified: it outputs specified relationships' history + on the [asset_names]. It returns an error if any of the + [relationship_types] doesn't belong to the supported + relationship types of the [asset_names] or if any of the + [asset_names]'s types doesn't belong to the source types + of the [relationship_types]. + - Otherwise: it outputs the supported relationships' + history on the [asset_names] or returns an error if any + of the [asset_names]'s types has no relationship support. + See `Introduction to Cloud Asset + Inventory `__ + for all supported asset types and relationship types. """ parent = proto.Field(proto.STRING, number=1,) @@ -298,6 +353,7 @@ class BatchGetAssetsHistoryRequest(proto.Message): read_time_window = proto.Field( proto.MESSAGE, number=4, message=gca_assets.TimeWindow, ) + relationship_types = proto.RepeatedField(proto.STRING, number=5,) class BatchGetAssetsHistoryResponse(proto.Message): @@ -675,6 +731,25 @@ class Feed(proto.Message): See our `user guide `__ for detailed instructions. + relationship_types (Sequence[str]): + A list of relationship types to output, for example: + ``INSTANCE_TO_INSTANCEGROUP``. This field should only be + specified if content_type=RELATIONSHIP. + + - If specified: it outputs specified relationship updates + on the [asset_names] or the [asset_types]. It returns an + error if any of the [relationship_types] doesn't belong + to the supported relationship types of the [asset_names] + or [asset_types], or any of the [asset_names] or the + [asset_types] doesn't belong to the source types of the + [relationship_types]. + - Otherwise: it outputs the supported relationships of the + types of [asset_names] and [asset_types] or returns an + error if any of the [asset_names] or the [asset_types] + has no replationship support. See `Introduction to Cloud + Asset + Inventory `__ + for all supported asset types and relationship types. """ name = proto.Field(proto.STRING, number=1,) @@ -685,6 +760,7 @@ class Feed(proto.Message): proto.MESSAGE, number=5, message="FeedOutputConfig", ) condition = proto.Field(proto.MESSAGE, number=6, message=expr_pb2.Expr,) + relationship_types = proto.RepeatedField(proto.STRING, number=7,) class SearchAllResourcesRequest(proto.Message): diff --git a/google/cloud/asset_v1/types/assets.py b/google/cloud/asset_v1/types/assets.py index a55efe1e..a09daeeb 100644 --- a/google/cloud/asset_v1/types/assets.py +++ b/google/cloud/asset_v1/types/assets.py @@ -33,6 +33,9 @@ "TimeWindow", "Asset", "Resource", + "RelatedAssets", + "RelationshipAttributes", + "RelatedAsset", "ResourceSearchResult", "VersionedResource", "AttachedResource", @@ -157,6 +160,10 @@ class Asset(proto.Message): `this topic `__ for more information. + related_assets (google.cloud.asset_v1.types.RelatedAssets): + The related assets of the asset of one + relationship type. One asset only represents one + type of relationship. ancestors (Sequence[str]): The ancestry path of an asset in Google Cloud `resource hierarchy `__, @@ -199,6 +206,7 @@ class Asset(proto.Message): message=service_perimeter_pb2.ServicePerimeter, ) os_inventory = proto.Field(proto.MESSAGE, number=12, message=Inventory,) + related_assets = proto.Field(proto.MESSAGE, number=13, message="RelatedAssets",) ancestors = proto.RepeatedField(proto.STRING, number=10,) @@ -259,6 +267,88 @@ class Resource(proto.Message): location = proto.Field(proto.STRING, number=8,) +class RelatedAssets(proto.Message): + r"""The detailed related assets with the ``relationship_type``. + Attributes: + relationship_attributes (google.cloud.asset_v1.types.RelationshipAttributes): + The detailed relationship attributes. + assets (Sequence[google.cloud.asset_v1.types.RelatedAsset]): + The peer resources of the relationship. + """ + + relationship_attributes = proto.Field( + proto.MESSAGE, number=1, message="RelationshipAttributes", + ) + assets = proto.RepeatedField(proto.MESSAGE, number=2, message="RelatedAsset",) + + +class RelationshipAttributes(proto.Message): + r"""The relationship attributes which include ``type``, + ``source_resource_type``, ``target_resource_type`` and ``action``. + + Attributes: + type_ (str): + The unique identifier of the relationship type. Example: + ``INSTANCE_TO_INSTANCEGROUP`` + source_resource_type (str): + The source asset type. Example: + ``compute.googleapis.com/Instance`` + target_resource_type (str): + The target asset type. Example: + ``compute.googleapis.com/Disk`` + action (str): + The detail of the relationship, e.g. ``contains``, + ``attaches`` + """ + + type_ = proto.Field(proto.STRING, number=4,) + source_resource_type = proto.Field(proto.STRING, number=1,) + target_resource_type = proto.Field(proto.STRING, number=2,) + action = proto.Field(proto.STRING, number=3,) + + +class RelatedAsset(proto.Message): + r"""An asset identify in Google Cloud which contains its name, type and + ancestors. An asset can be any resource in the Google Cloud + `resource + hierarchy `__, + a resource outside the Google Cloud resource hierarchy (such as + Google Kubernetes Engine clusters and objects), or a policy (e.g. + Cloud IAM policy). See `Supported asset + types `__ + for more information. + + Attributes: + asset (str): + The full name of the asset. Example: + ``//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`` + + See `Resource + names `__ + for more information. + asset_type (str): + The type of the asset. Example: + ``compute.googleapis.com/Disk`` + + See `Supported asset + types `__ + for more information. + ancestors (Sequence[str]): + The ancestors of an asset in Google Cloud `resource + hierarchy `__, + represented as a list of relative resource names. An + ancestry path starts with the closest ancestor in the + hierarchy and ends at root. + + Example: + ``["projects/123456789", "folders/5432", "organizations/1234"]`` + """ + + asset = proto.Field(proto.STRING, number=1,) + asset_type = proto.Field(proto.STRING, number=2,) + ancestors = proto.RepeatedField(proto.STRING, number=3,) + + class ResourceSearchResult(proto.Message): r"""A result of Resource Search, containing information of a cloud resource. diff --git a/scripts/fixup_asset_v1_keywords.py b/scripts/fixup_asset_v1_keywords.py index 5d5abef3..3e376ccd 100644 --- a/scripts/fixup_asset_v1_keywords.py +++ b/scripts/fixup_asset_v1_keywords.py @@ -42,12 +42,12 @@ class assetCallTransformer(cst.CSTTransformer): 'analyze_iam_policy': ('analysis_query', 'execution_timeout', ), 'analyze_iam_policy_longrunning': ('analysis_query', 'output_config', ), 'analyze_move': ('resource', 'destination_parent', 'view', ), - 'batch_get_assets_history': ('parent', 'asset_names', 'content_type', 'read_time_window', ), + 'batch_get_assets_history': ('parent', 'asset_names', 'content_type', 'read_time_window', 'relationship_types', ), 'create_feed': ('parent', 'feed_id', 'feed', ), 'delete_feed': ('name', ), - 'export_assets': ('parent', 'output_config', 'read_time', 'asset_types', 'content_type', ), + 'export_assets': ('parent', 'output_config', 'read_time', 'asset_types', 'content_type', 'relationship_types', ), 'get_feed': ('name', ), - 'list_assets': ('parent', 'read_time', 'asset_types', 'content_type', 'page_size', 'page_token', ), + 'list_assets': ('parent', 'read_time', 'asset_types', 'content_type', 'page_size', 'page_token', 'relationship_types', ), 'list_feeds': ('parent', ), 'search_all_iam_policies': ('scope', 'query', 'page_size', 'page_token', 'asset_types', 'order_by', ), 'search_all_resources': ('scope', 'query', 'asset_types', 'page_size', 'page_token', 'order_by', 'read_mask', ), diff --git a/tests/unit/gapic/asset_v1/test_asset_service.py b/tests/unit/gapic/asset_v1/test_asset_service.py index 20e2ee23..8eb6e5fe 100644 --- a/tests/unit/gapic/asset_v1/test_asset_service.py +++ b/tests/unit/gapic/asset_v1/test_asset_service.py @@ -1092,6 +1092,7 @@ def test_create_feed( asset_names=["asset_names_value"], asset_types=["asset_types_value"], content_type=asset_service.ContentType.RESOURCE, + relationship_types=["relationship_types_value"], ) response = client.create_feed(request) @@ -1106,6 +1107,7 @@ def test_create_feed( assert response.asset_names == ["asset_names_value"] assert response.asset_types == ["asset_types_value"] assert response.content_type == asset_service.ContentType.RESOURCE + assert response.relationship_types == ["relationship_types_value"] def test_create_feed_from_dict(): @@ -1148,6 +1150,7 @@ async def test_create_feed_async( asset_names=["asset_names_value"], asset_types=["asset_types_value"], content_type=asset_service.ContentType.RESOURCE, + relationship_types=["relationship_types_value"], ) ) response = await client.create_feed(request) @@ -1163,6 +1166,7 @@ async def test_create_feed_async( assert response.asset_names == ["asset_names_value"] assert response.asset_types == ["asset_types_value"] assert response.content_type == asset_service.ContentType.RESOURCE + assert response.relationship_types == ["relationship_types_value"] @pytest.mark.asyncio @@ -1298,6 +1302,7 @@ def test_get_feed(transport: str = "grpc", request_type=asset_service.GetFeedReq asset_names=["asset_names_value"], asset_types=["asset_types_value"], content_type=asset_service.ContentType.RESOURCE, + relationship_types=["relationship_types_value"], ) response = client.get_feed(request) @@ -1312,6 +1317,7 @@ def test_get_feed(transport: str = "grpc", request_type=asset_service.GetFeedReq assert response.asset_names == ["asset_names_value"] assert response.asset_types == ["asset_types_value"] assert response.content_type == asset_service.ContentType.RESOURCE + assert response.relationship_types == ["relationship_types_value"] def test_get_feed_from_dict(): @@ -1354,6 +1360,7 @@ async def test_get_feed_async( asset_names=["asset_names_value"], asset_types=["asset_types_value"], content_type=asset_service.ContentType.RESOURCE, + relationship_types=["relationship_types_value"], ) ) response = await client.get_feed(request) @@ -1369,6 +1376,7 @@ async def test_get_feed_async( assert response.asset_names == ["asset_names_value"] assert response.asset_types == ["asset_types_value"] assert response.content_type == asset_service.ContentType.RESOURCE + assert response.relationship_types == ["relationship_types_value"] @pytest.mark.asyncio @@ -1700,6 +1708,7 @@ def test_update_feed( asset_names=["asset_names_value"], asset_types=["asset_types_value"], content_type=asset_service.ContentType.RESOURCE, + relationship_types=["relationship_types_value"], ) response = client.update_feed(request) @@ -1714,6 +1723,7 @@ def test_update_feed( assert response.asset_names == ["asset_names_value"] assert response.asset_types == ["asset_types_value"] assert response.content_type == asset_service.ContentType.RESOURCE + assert response.relationship_types == ["relationship_types_value"] def test_update_feed_from_dict(): @@ -1756,6 +1766,7 @@ async def test_update_feed_async( asset_names=["asset_names_value"], asset_types=["asset_types_value"], content_type=asset_service.ContentType.RESOURCE, + relationship_types=["relationship_types_value"], ) ) response = await client.update_feed(request) @@ -1771,6 +1782,7 @@ async def test_update_feed_async( assert response.asset_names == ["asset_names_value"] assert response.asset_types == ["asset_types_value"] assert response.content_type == asset_service.ContentType.RESOURCE + assert response.relationship_types == ["relationship_types_value"] @pytest.mark.asyncio