Source code for google.cloud.forseti.common.gcp_type.resource_util

# Copyright 2017 The Forseti Security Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Util for generic operations for Resources."""

from google.cloud.forseti.common.gcp_type import backend_service
from google.cloud.forseti.common.gcp_type import billing_account
from google.cloud.forseti.common.gcp_type import bucket
from google.cloud.forseti.common.gcp_type import cloudsql_instance
from google.cloud.forseti.common.gcp_type import ke_cluster
from google.cloud.forseti.common.gcp_type import dataset
from google.cloud.forseti.common.gcp_type import folder
from google.cloud.forseti.common.gcp_type import groups_settings
from google.cloud.forseti.common.gcp_type import instance
from google.cloud.forseti.common.gcp_type import organization as org
from google.cloud.forseti.common.gcp_type import project
from google.cloud.forseti.common.gcp_type import resource
from google.cloud.forseti.common.gcp_type import role
from google.cloud.forseti.common.gcp_type import table
from google.cloud.forseti.services import utils

_RESOURCE_TYPE_MAP = {
    resource.ResourceType.ORGANIZATION: {
        'class': org.Organization,
        'plural': 'Organizations',
        'can_create_resource': True,
    },
    resource.ResourceType.BILLING_ACCOUNT: {
        'class': billing_account.BillingAccount,
        'plural': 'Billing Accounts',
        'can_create_resource': True,
    },
    resource.ResourceType.FOLDER: {
        'class': folder.Folder,
        'plural': 'Folders',
        'can_create_resource': True,
    },
    resource.ResourceType.PROJECT: {
        'class': project.Project,
        'plural': 'Projects',
        'can_create_resource': True,
    },
    resource.ResourceType.BACKEND_SERVICE: {
        'class': backend_service.BackendService,
        'plural': 'Backend Services',
        'can_create_resource': False,
    },
    resource.ResourceType.BUCKET: {
        'class': bucket.Bucket,
        'plural': 'Buckets',
        'can_create_resource': True,
    },
    resource.ResourceType.CLOUD_SQL_INSTANCE: {
        'class': cloudsql_instance.CloudSQLInstance,
        'plural': 'Cloud SQL Instances',
        'can_create_resource': True,
    },
    resource.ResourceType.DATASET: {
        'class': dataset.Dataset,
        'plural': 'Datasets',
        'can_create_resource': True,
    },
    resource.ResourceType.INSTANCE: {
        'class': instance.Instance,
        'plural': 'GCE Instances',
        'can_create_resource': True,
    },
    resource.ResourceType.KE_CLUSTER: {
        'class': ke_cluster.KeCluster,
        'plural': 'GKE Clusters',
        'can_create_resource': True,
    },
    resource.ResourceType.ROLE: {
        'class': role.Role,
        'plural': 'Roles',
        'can_create_resource': True,
    },
    resource.ResourceType.TABLE: {
        'class': table.Table,
        'plural': 'Tables',
        'can_create_resource': True,
    },
    resource.ResourceType.GROUPS_SETTINGS: {
        'class': groups_settings.GroupsSettings,
        'plural': 'Groups Settings',
        'can_create_resource': True,
    },
}


[docs]def create_resource(resource_id, resource_type, **kwargs): """Factory to create a certain kind of Resource. Args: resource_id (str): The resource id. resource_type (str): The resource type. **kwargs (dict): Extra args. Returns: Resource: The new Resource based on the type, if supported, otherwise None. """ if resource_type not in _RESOURCE_TYPE_MAP: return None resource_type = _RESOURCE_TYPE_MAP[resource_type] if not resource_type.get('can_create_resource'): return None return resource_type.get('class')( resource_id, **kwargs)
[docs]def create_resource_from_db_row(row): """Create a resource type from a database resource row. Args: row (Resource): the database resource row. Returns: Resource: the concrete resource type. """ parent = ( create_resource_from_db_row(row.parent) if row.parent else None) return create_resource_from_json(row.type, parent, row.data)
[docs]def create_resource_from_json(resource_type, parent, json_string): """Factory to create a certain kind of Resource from JSON data. Args: resource_type (str): The resource type. parent (Resource): parent resource of this type. json_string (str): resource's JSON data. Returns: Resource: The new Resource based on the type, if supported, otherwise None. """ if resource_type not in _RESOURCE_TYPE_MAP: return None resource_type = _RESOURCE_TYPE_MAP[resource_type] if not resource_type.get('can_create_resource'): return None return resource_type.get('class').from_json(parent, json_string)
[docs]def get_ancestors_from_full_name(full_name): """Creates a Resource for each resource in the full ancestory path. Args: full_name (str): The full resource name from the model, includes all parent resources in the hierarchy to the root organization. Returns: list: A list of Resource objects, from parent to base ancestor. """ resource_ancestors = [] for (resource_type, resource_id) in utils.get_resources_from_full_name( full_name): resource_ancestors.append(create_resource(resource_id, resource_type)) return resource_ancestors
[docs]def pluralize(resource_type): """Determine the pluralized form of the resource type. Args: resource_type (str): The resource type for which to get its plural form. Returns: str: The pluralized version of the resource type, if supported, otherwise None. """ if resource_type not in _RESOURCE_TYPE_MAP: return None return _RESOURCE_TYPE_MAP.get(resource_type).get('plural')
[docs]def type_from_name(resource_name): """Determine resource type from resource name. Args: resource_name (str): The unique resoure name, with the format "{resource_type}/{resource_id}". Returns: str: The resource type, if it exists, otherwise None. """ if not resource_name: return None for (resource_type, metadata) in _RESOURCE_TYPE_MAP.items(): if resource_name.startswith(metadata['plural'].lower()): return resource_type return None
[docs]def cast_to_gcp_resources(resources_to_cast): """Get a list Resource objects from a list of dict resource descriptors Args: resources_to_cast (list): A list of resource descriptors as dictionaries. [{'resourceId': {'id': '3456', 'type': 'Project'}} {'resourceId': {'id': '1234', 'type': 'Organization'}}] Returns: list: A list of cast Resource objects """ cast_resources = [] for resource_to_cast in resources_to_cast: resource_id = resource_to_cast['resourceId']['id'] resource_type = resource_to_cast['resourceId']['type'] cast_resource = create_resource(resource_id, resource_type) cast_resources.append(cast_resource) return cast_resources