def create_resolver_endpoint( self, region, creator_request_id, name, security_group_ids, direction, ip_addresses, tags, ): # pylint: disable=too-many-arguments """Return description for a newly created resolver endpoint. NOTE: IPv6 IPs are currently not being filtered when calculating the create_resolver_endpoint() IpAddresses. """ validate_args([ ("creatorRequestId", creator_request_id), ("direction", direction), ("ipAddresses", ip_addresses), ("name", name), ("securityGroupIds", security_group_ids), ("ipAddresses.subnetId", ip_addresses), ]) errmsg = self.tagger.validate_tags( tags or [], limit=ResolverEndpoint.MAX_TAGS_PER_RESOLVER_ENDPOINT) if errmsg: raise TagValidationException(errmsg) endpoints = [ x for x in self.resolver_endpoints.values() if x.region == region ] if len(endpoints) > ResolverEndpoint.MAX_ENDPOINTS_PER_REGION: raise LimitExceededException( f"Account '{get_account_id()}' has exceeded 'max-endpoints'") self._verify_subnet_ips(region, ip_addresses) self._verify_security_group_ids(region, security_group_ids) if creator_request_id in [ x.creator_request_id for x in self.resolver_endpoints.values() ]: raise ResourceExistsException( f"Resolver endpoint with creator request ID " f"'{creator_request_id}' already exists") endpoint_id = ( f"rslvr-{'in' if direction == 'INBOUND' else 'out'}-{get_random_hex(17)}" ) resolver_endpoint = ResolverEndpoint( region, endpoint_id, creator_request_id, security_group_ids, direction, ip_addresses, name, ) self.resolver_endpoints[endpoint_id] = resolver_endpoint self.tagger.tag_resource(resolver_endpoint.arn, tags or []) return resolver_endpoint
def tag_resource(self, resource_arn, tags): self._matched_arn(resource_arn) errmsg = self.tagger.validate_tags( tags, limit=ResolverEndpoint.MAX_TAGS_PER_RESOLVER_ENDPOINT ) if errmsg: raise TagValidationException(errmsg) self.tagger.tag_resource(resource_arn, tags)
def tag_resource(self, resource_arn, tags): """Add or overwrite one or more tags for specified resource.""" self._matched_arn(resource_arn) errmsg = self.tagger.validate_tags( tags, limit=ResolverEndpoint.MAX_TAGS_PER_RESOLVER_ENDPOINT) if errmsg: raise TagValidationException(errmsg) self.tagger.tag_resource(resource_arn, tags)
def create_resolver_rule( self, region, creator_request_id, name, rule_type, domain_name, target_ips, resolver_endpoint_id, tags, ): # pylint: disable=too-many-arguments """Return description for a newly created resolver rule.""" validate_args( [ ("creatorRequestId", creator_request_id), ("ruleType", rule_type), ("domainName", domain_name), ("name", name), *[("targetIps.port", x) for x in target_ips], ("resolverEndpointId", resolver_endpoint_id), ] ) errmsg = self.tagger.validate_tags( tags or [], limit=ResolverRule.MAX_TAGS_PER_RESOLVER_RULE ) if errmsg: raise TagValidationException(errmsg) rules = [x for x in self.resolver_rules.values() if x.region == region] if len(rules) > ResolverRule.MAX_RULES_PER_REGION: # Did not verify that this is the actual error message. raise LimitExceededException( f"Account '{get_account_id()}' has exceeded 'max-rules'" ) # Per the AWS documentation and as seen with the AWS console, target # ips are only relevant when the value of Rule is FORWARD. However, # boto3 ignores this condition and so shall we. for ip_addr in [x["Ip"] for x in target_ips]: try: # boto3 fails with an InternalServiceException if IPv6 # addresses are used, which isn't helpful. if not isinstance(ip_address(ip_addr), IPv4Address): raise InvalidParameterException( f"Only IPv4 addresses may be used: '{ip_addr}'" ) except ValueError as exc: raise InvalidParameterException( f"Invalid IP address: '{ip_addr}'" ) from exc # The boto3 documentation indicates that ResolverEndpoint is # optional, as does the AWS documention. But if resolver_endpoint_id # is set to None or an empty string, it results in boto3 raising # a ParamValidationError either regarding the type or len of string. if resolver_endpoint_id: if resolver_endpoint_id not in [ x.id for x in self.resolver_endpoints.values() ]: raise ResourceNotFoundException( f"Resolver endpoint with ID '{resolver_endpoint_id}' does not exist." ) if rule_type == "SYSTEM": raise InvalidRequestException( "Cannot specify resolver endpoint ID and target IP " "for SYSTEM type resolver rule" ) if creator_request_id in [ x.creator_request_id for x in self.resolver_rules.values() ]: raise ResourceExistsException( f"Resolver rule with creator request ID " f"'{creator_request_id}' already exists" ) rule_id = f"rslvr-rr-{get_random_hex(17)}" resolver_rule = ResolverRule( region, rule_id, creator_request_id, rule_type, domain_name, target_ips, resolver_endpoint_id, name, ) self.resolver_rules[rule_id] = resolver_rule self.tagger.tag_resource(resolver_rule.arn, tags or []) return resolver_rule