def service_client(self, region=None, method_names=None): """ Returns a client for the service using the session/role/region of the service class instance :param region: :param method_names: names of function to create wrapper methods for with retry logic :return: client for making the call to describe the resources """ if region is None: region = boto3.client(self.service_name).meta.config.region_name if self._service_client is None or self._service_client.meta.config.region_name != region: args = {"service_name": self.service_name, "region_name": region} self._service_client = self.session.client(**args) if self._service_retry_strategy is not None and method_names is not None: for method in method_names: boto_retry.make_method_with_retries( boto_client_or_resource=self._service_client, name=method, service_retry_strategy=self._service_retry_strategy) return self._service_client
def _get_tags_for_resource(self, client, resource): """ Returns the tags for specific resources that require additional boto calls to retrieve their tags. Tags are not supported for this service. :param client: Client that can be used to make the boto call to retrieve the tags :param resource: The resource for which to retrieve the tags :return: Tags """ if self._resource_name not in RESOURCES_WITH_TAGS: raise ValueError("Resource type {] does not support tags".format( self._resource_name)) if self._service_retry_strategy is not None: if getattr(self._service_client, "list_tags_for_resource" + boto_retry.DEFAULT_SUFFIX, None) is None: boto_retry.make_method_with_retries( boto_client_or_resource=self._service_client, name="describe_tags", service_retry_strategy=self._service_retry_strategy) tag_list = client.describe_tags_with_retries( LoadBalancerNames=[resource["LoadBalancerName"]]).get( "TagDescriptions") else: tag_list = client.describe_tags( LoadBalancerNames=[resource["LoadBalancerName"]]).get( "TagDescriptions") if len(tag_list) > 0: return [{ "Key": t["Key"], "Value": t["Value"] } for t in tag_list[0].get("Tags", [])] else: return {}
def _get_tags_for_resource(self, client, resource): """ Returns the tags for specific resources that require additional boto calls to retrieve their tags. :param client: Client that can be used to make the boto call to retrieve the tags :param resource: The resource for which to retrieve the tags :return: Tags """ arn_property_name = "{}ARN".format(self._resource_name[0:-1]) arn = resource[arn_property_name] if self._use_cached_tags: return self.cached_tags(self._resource_name, resource['Region']).get(arn, {}) if self._service_retry_strategy is not None: if getattr(self._service_client, "list_tags_for_resource" + boto_retry.DEFAULT_SUFFIX, None) is None: boto_retry.make_method_with_retries( boto_client_or_resource=self._service_client, name="list_tags_for_resource", service_retry_strategy=self._service_retry_strategy) resp = client.list_tags_for_resource_with_retries( ResourceARN=arn) return resp.get("Tags", []) return client.list_tags_for_resource(ResourceARN=arn).get("Tags", [])
def _get_tags_for_resource(self, client, resource): """ Returns the tags for specific resources that require additional boto calls to retrieve their tags. Tags are not supported for this service. :param client: Client that can be used to make the boto call to retrieve the tags :param resource: The resource for which to retrieve the tags :return: Tags """ if self._resource_name not in RESOURCES_WITH_TAGS: raise ValueError("Resource type {] does not support tags".format( self._resource_name)) if self._resource_name == CACHE_CLUSTERS: if resource["CacheClusterStatus"] not in ["available"]: return [] arn_name = resource["CacheClusterId"] arn_resource = "cluster" else: if resource["SnapshotStatus"] in ["creating"]: return [] arn_name = resource["SnapshotName"] arn_resource = "snapshot" arn = ARN.format(client.meta.region_name, self.aws_account, arn_resource, arn_name) if self._service_retry_strategy is not None: if getattr(self._service_client, "list_tags_for_resource" + boto_retry.DEFAULT_SUFFIX, None) is None: boto_retry.make_method_with_retries( boto_client_or_resource=self._service_client, name="list_tags_for_resource", service_retry_strategy=self._service_retry_strategy) return client.list_tags_for_resource_with_retries( ResourceName=arn).get("TagList", []) return client.list_tags_for_resource(ResourceName=arn).get( "TagList", [])
def _get_tags_for_resource(self, client, resource): """ Returns the tags for specific resources that require additional boto calls to retrieve their tags. :param client: Client that can be used to make the boto call to retrieve the tags :param resource: The resource for which to retrieve the tags :return: Tags """ arn = "arn:aws:dynamodb:{}:{}:table/{}".format(client.meta.region_name, self.aws_account, resource["TableName"]) if self._service_retry_strategy is not None: if getattr(self._service_client, "list_tags_of_resource" + boto_retry.DEFAULT_SUFFIX, None) is None: boto_retry.make_method_with_retries( boto_client_or_resource=self._service_client, name="list_tags_of_resource", service_retry_strategy=self._service_retry_strategy) return client.list_tags_of_resource_with_retries( ResourceArn=arn).get("Tags", []) return client.list_tags_of_resource(ResourceArn=arn).get("Tags", [])
def _get_tags_for_resource(self, client, resource): """ Returns the tags for specific resources that require additional boto calls to retrieve their tags. :param client: Client that can be used to make the boto call to retrieve the tags :param resource: The resource for which to retrieve the tags :return: Tags """ # get the name of the proprty that holds the arn of the resource arn_property_name = "{}Arn".format(self._resource_name[0:-1]) if arn_property_name[0:2].lower() == "db": arn_property_name = "DB{}".format(arn_property_name[2:]) # get the arn of the resource resource_arn = resource[arn_property_name] # owner of the resource (could be other account for shared sbapshots) resource_owner_account = resource_arn.split(":")[4] resource_region = resource_arn.split(":")[3] if resource_owner_account == self.aws_account: # sane account, can use same session as used to retrieve the resource if self._use_cached_tags: self._tag_session = self.session # make sure the client has retries if getattr(self._service_client, "list_tags_for_resource" + boto_retry.DEFAULT_SUFFIX, None) is None: boto_retry.make_method_with_retries(boto_client_or_resource=client, name="list_tags_for_resource", service_retry_strategy=self._service_retry_strategy) self._tag_rds_client = client else: # resource is from other account, get a session to get the tags from that account as these are not # visible for shared rds resources if self._tag_account != resource_owner_account or self._tag_session is None: self._tag_account = resource_owner_account used_tag_role = None if self._tag_roles is not None: # see if there is a role for the owner account for role in self._tag_roles: if role is not None and services.account_from_role_arn(role) == resource_owner_account: used_tag_role = role break else: # if there is no role and the account is the ops automator account use the default role # in other cases it is not possible to retrieve the tags if resource_owner_account != os.getenv(handlers.ENV_OPS_AUTOMATOR_ACCOUNT): return {} self._tag_session = services.get_session(role_arn=used_tag_role) if not self._use_cached_tags: self._tag_rds_client = boto_retry.get_client_with_retries("rds", methods=["list_tags_for_resource"], context=self._context, region=resource_region) if self._use_cached_tags: return self.cached_tags(session=self._tag_session, resource_name=RESOURCES_WITH_TAGS[resource["ResourceTypeName"]], region=resource_region).get(resource_arn, {}) try: resp = self._tag_rds_client.list_tags_for_resource_with_retries(ResourceName=resource_arn) return resp.get("TagList", []) except botocore.exceptions.ClientError as ex: if getattr(ex, "response", {}).get("Error", {}).get("Code", "") == "InvalidParameterValue": return [] raise_exception("Can not list rds tags for resource {}, {}", resource_arn, ex)