diff --git a/rpe/resources/gcp.py b/rpe/resources/gcp.py index ceb124f..a988fd5 100644 --- a/rpe/resources/gcp.py +++ b/rpe/resources/gcp.py @@ -97,6 +97,9 @@ def _extract_cai_name_data(name): # NodePools 'cluster': r'/clusters/([^\/]+)/', + + # ServiceAccounts + 'service_account': r'serviceAccounts/([^\/]+)/', } resource_data = {} @@ -171,7 +174,6 @@ def full_resource_name(self): return self._full_resource_name - # Google's documentation describes what it calls a 'full resource name' for # resources. None of the API's seem to implement it (except Cloud Asset # Inventory). This attempts to generate it from the discovery-based api @@ -252,12 +254,11 @@ def _get_component(self, component): req_arg_method = getattr(self, f'_get_{component}_request_args') else: req_arg_method = getattr(self, '_get_request_args') - + method = getattr(self.service, method_name) - + component_metadata = method(**req_arg_method()).execute() return component_metadata - def get(self, refresh=True): @@ -422,14 +423,12 @@ def _get_request_args(self): } - class GcpBigqueryDataset(GoogleAPIResource): service_name = "bigquery" resource_path = "datasets" version = "v2" - required_resource_data = ['name', 'project_id'] resource_type = "bigquery.googleapis.com/Dataset" @@ -526,7 +525,7 @@ def _get_request_args(self): } -class GcpComputeDisks(GoogleAPIResource): +class GcpComputeDisk(GoogleAPIResource): service_name = "compute" resource_path = "disks" @@ -544,6 +543,24 @@ def _get_request_args(self): } +class GcpComputeRegionDisk(GoogleAPIResource): + + service_name = "compute" + resource_path = "regionDisks" + version = "v1" + + required_resource_data = ['name', 'location', 'project_id'] + + resource_type = "compute.googleapis.com/RegionDisk" + + def _get_request_args(self): + return { + 'project': self._resource_data['project_id'], + 'region': self._resource_data['location'], + 'disk': self._resource_data['name'] + } + + class GcpComputeSubnetwork(GoogleAPIResource): service_name = "compute" @@ -579,7 +596,6 @@ def _get_request_args(self): } - class GcpDataprocCluster(GoogleAPIResource): service_name = "dataproc" resource_path = "projects.regions.clusters" @@ -654,7 +670,6 @@ def _get_request_args(self): } - class GcpGkeClusterNodepool(GoogleAPIResource): service_name = "container" @@ -678,6 +693,43 @@ def _get_request_args(self): } +class GcpIamServiceAccount(GoogleAPIResource): + + service_name = "iam" + resource_path = "projects.serviceAccounts" + version = "v1" + + required_resource_data = ['name', 'project_id'] + + resource_type = 'iam.googleapis.com/ServiceAccount' + + def _get_request_args(self): + return { + 'name': 'projects/{}/serviceAccounts/{}'.format( + self._resource_data['project_id'], + self._resource_data['name'] + ) + } + + +class GcpIamServiceAccountKey(GoogleAPIResource): + + service_name = "iam" + resource_path = "projects.serviceAccounts.keys" + version = "v1" + + required_resource_data = ['name', 'service_account', 'project_id'] + + resource_type = 'iam.googleapis.com/ServiceAccountKey' + + def _get_request_args(self): + return { + 'name': 'projects/{}/serviceAccounts/{}/keys/{}'.format( + self._resource_data['project_id'], + self._resource_data['service_account'], + self._resource_data['name'] + ) + } class GcpPubsubSubscription(GoogleAPIResource): @@ -710,7 +762,6 @@ def _get_iam_request_args(self): } - class GcpPubsubTopic(GoogleAPIResource): service_name = "pubsub" @@ -742,7 +793,6 @@ def _get_iam_request_args(self): } - class GcpStorageBucket(GoogleAPIResource): service_name = "storage" @@ -782,6 +832,7 @@ def _get_request_args(self): 'project': self._resource_data['project_id'] } + class GcpOrganization(GoogleAPIResource): service_name = "cloudresourcemanager" diff --git a/tests/test_resources.py b/tests/test_resources.py index c5f443b..8fd9d10 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -25,7 +25,7 @@ from rpe.resources.gcp import GcpBigtableInstance from rpe.resources.gcp import GcpCloudFunction from rpe.resources.gcp import GcpComputeInstance -from rpe.resources.gcp import GcpComputeDisks +from rpe.resources.gcp import GcpComputeDisk from rpe.resources.gcp import GcpDatafusionInstance from rpe.resources.gcp import GcpDataprocCluster from rpe.resources.gcp import GcpGkeCluster @@ -95,7 +95,7 @@ 'location': 'us-central1-a', 'project_id': test_project }, - cls=GcpComputeDisks, + cls=GcpComputeDisk, resource_type='compute.googleapis.com/Disk', name='//compute.googleapis.com/projects/my_project/zones/us-central1-a/disks/my_resource' ), diff --git a/tests/test_resources_cai.py b/tests/test_resources_cai.py index 72337d4..6ec468b 100644 --- a/tests/test_resources_cai.py +++ b/tests/test_resources_cai.py @@ -25,7 +25,8 @@ from rpe.resources.gcp import GcpBigtableInstance from rpe.resources.gcp import GcpCloudFunction from rpe.resources.gcp import GcpComputeInstance -from rpe.resources.gcp import GcpComputeDisks +from rpe.resources.gcp import GcpComputeDisk +from rpe.resources.gcp import GcpComputeRegionDisk from rpe.resources.gcp import GcpDatafusionInstance from rpe.resources.gcp import GcpDataprocCluster from rpe.resources.gcp import GcpGkeCluster @@ -39,6 +40,8 @@ from rpe.resources.gcp import GcpStorageBucket from rpe.resources.gcp import GcpComputeFirewall from rpe.resources.gcp import GcpComputeSubnetwork +from rpe.resources.gcp import GcpIamServiceAccount +from rpe.resources.gcp import GcpIamServiceAccountKey client_kwargs = { 'credentials': Credentials(token='') @@ -87,7 +90,14 @@ "name": "//compute.googleapis.com/projects/test-project/zones/us-central1-a/disks/test-resource", "asset_type": "compute.googleapis.com/Disk", }, - resource_cls=GcpComputeDisks + resource_cls=GcpComputeDisk + ), + CaiTestCase( + data={ + "name": "//compute.googleapis.com/projects/test-project/regions/us-central1/disks/test-resource", + "asset_type": "compute.googleapis.com/RegionDisk", + }, + resource_cls=GcpComputeRegionDisk ), CaiTestCase( data={ @@ -131,6 +141,20 @@ }, resource_cls=GcpGkeClusterNodepool ), + CaiTestCase( + data={ + "name": "//iam.googleapis.com/projects/test-project/serviceAccounts/foo", + "asset_type": "iam.googleapis.com/ServiceAccount", + }, + resource_cls=GcpIamServiceAccount + ), + CaiTestCase( + data={ + "name": "//iam.googleapis.com/projects/test-project/serviceAccounts/foo/keys/bar", + "asset_type": "iam.googleapis.com/ServiceAccountKey", + }, + resource_cls=GcpIamServiceAccountKey + ), CaiTestCase( data={ "name": "//pubsub.googleapis.com/projects/test-project/subscriptions/test-resource",