Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/boto/endpoints.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler |
|---|---|
| date | Fri, 31 Jul 2020 00:18:57 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d30785e31577 |
|---|---|
| 1 # Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. | |
| 2 # | |
| 3 # Licensed under the Apache License, Version 2.0 (the "License"). You | |
| 4 # may not use this file except in compliance with the License. A copy of | |
| 5 # the License is located at | |
| 6 # | |
| 7 # http://aws.amazon.com/apache2.0/ | |
| 8 # | |
| 9 # or in the "license" file accompanying this file. This file is | |
| 10 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF | |
| 11 # ANY KIND, either express or implied. See the License for the specific | |
| 12 # language governing permissions and limitations under the License. | |
| 13 import boto.vendored.regions.regions as _regions | |
| 14 | |
| 15 | |
| 16 class _CompatEndpointResolver(_regions.EndpointResolver): | |
| 17 """Endpoint resolver which handles boto2 compatibility concerns. | |
| 18 | |
| 19 This is NOT intended for external use whatsoever. | |
| 20 """ | |
| 21 | |
| 22 _DEFAULT_SERVICE_RENAMES = { | |
| 23 # The botocore resolver is based on endpoint prefix. | |
| 24 # These don't always sync up to the name that boto2 uses. | |
| 25 # A mapping can be provided that handles the mapping between | |
| 26 # "service names" and endpoint prefixes. | |
| 27 'awslambda': 'lambda', | |
| 28 'cloudwatch': 'monitoring', | |
| 29 'ses': 'email', | |
| 30 'ec2containerservice': 'ecs', | |
| 31 'configservice': 'config', | |
| 32 } | |
| 33 | |
| 34 def __init__(self, endpoint_data, service_rename_map=None): | |
| 35 """ | |
| 36 :type endpoint_data: dict | |
| 37 :param endpoint_data: Regions and endpoints data in the same format | |
| 38 as is used by botocore / boto3. | |
| 39 | |
| 40 :type service_rename_map: dict | |
| 41 :param service_rename_map: A mapping of boto2 service name to | |
| 42 endpoint prefix. | |
| 43 """ | |
| 44 super(_CompatEndpointResolver, self).__init__(endpoint_data) | |
| 45 if service_rename_map is None: | |
| 46 service_rename_map = self._DEFAULT_SERVICE_RENAMES | |
| 47 # Mapping of boto2 service name to endpoint prefix | |
| 48 self._endpoint_prefix_map = service_rename_map | |
| 49 # Mapping of endpoint prefix to boto2 service name | |
| 50 self._service_name_map = dict( | |
| 51 (v, k) for k, v in service_rename_map.items()) | |
| 52 | |
| 53 def get_available_endpoints(self, service_name, partition_name='aws', | |
| 54 allow_non_regional=False): | |
| 55 endpoint_prefix = self._endpoint_prefix(service_name) | |
| 56 return super(_CompatEndpointResolver, self).get_available_endpoints( | |
| 57 endpoint_prefix, partition_name, allow_non_regional) | |
| 58 | |
| 59 def get_all_available_regions(self, service_name): | |
| 60 """Retrieve every region across partitions for a service.""" | |
| 61 regions = set() | |
| 62 endpoint_prefix = self._endpoint_prefix(service_name) | |
| 63 | |
| 64 # Get every region for every partition in the new endpoint format | |
| 65 for partition_name in self.get_available_partitions(): | |
| 66 if self._is_global_service(service_name, partition_name): | |
| 67 # Global services are available in every region in the | |
| 68 # partition in which they are considered global. | |
| 69 partition = self._get_partition_data(partition_name) | |
| 70 regions.update(partition['regions'].keys()) | |
| 71 continue | |
| 72 else: | |
| 73 regions.update( | |
| 74 self.get_available_endpoints( | |
| 75 endpoint_prefix, partition_name) | |
| 76 ) | |
| 77 | |
| 78 return list(regions) | |
| 79 | |
| 80 def construct_endpoint(self, service_name, region_name=None): | |
| 81 endpoint_prefix = self._endpoint_prefix(service_name) | |
| 82 return super(_CompatEndpointResolver, self).construct_endpoint( | |
| 83 endpoint_prefix, region_name) | |
| 84 | |
| 85 def get_available_services(self): | |
| 86 """Get a list of all the available services in the endpoints file(s)""" | |
| 87 services = set() | |
| 88 | |
| 89 for partition in self._endpoint_data['partitions']: | |
| 90 services.update(partition['services'].keys()) | |
| 91 | |
| 92 return [self._service_name(s) for s in services] | |
| 93 | |
| 94 def _is_global_service(self, service_name, partition_name='aws'): | |
| 95 """Determines whether a service uses a global endpoint. | |
| 96 | |
| 97 In theory a service can be 'global' in one partition but regional in | |
| 98 another. In practice, each service is all global or all regional. | |
| 99 """ | |
| 100 endpoint_prefix = self._endpoint_prefix(service_name) | |
| 101 partition = self._get_partition_data(partition_name) | |
| 102 service = partition['services'].get(endpoint_prefix, {}) | |
| 103 return 'partitionEndpoint' in service | |
| 104 | |
| 105 def _get_partition_data(self, partition_name): | |
| 106 """Get partition information for a particular partition. | |
| 107 | |
| 108 This should NOT be used to get service endpoint data because it only | |
| 109 loads from the new endpoint format. It should only be used for | |
| 110 partition metadata and partition specific service metadata. | |
| 111 | |
| 112 :type partition_name: str | |
| 113 :param partition_name: The name of the partition to search for. | |
| 114 | |
| 115 :returns: Partition info from the new endpoints format. | |
| 116 :rtype: dict or None | |
| 117 """ | |
| 118 for partition in self._endpoint_data['partitions']: | |
| 119 if partition['partition'] == partition_name: | |
| 120 return partition | |
| 121 raise ValueError( | |
| 122 "Could not find partition data for: %s" % partition_name) | |
| 123 | |
| 124 def _endpoint_prefix(self, service_name): | |
| 125 """Given a boto2 service name, get the endpoint prefix.""" | |
| 126 return self._endpoint_prefix_map.get(service_name, service_name) | |
| 127 | |
| 128 def _service_name(self, endpoint_prefix): | |
| 129 """Given an endpoint prefix, get the boto2 service name.""" | |
| 130 return self._service_name_map.get(endpoint_prefix, endpoint_prefix) | |
| 131 | |
| 132 | |
| 133 class BotoEndpointResolver(object): | |
| 134 """Resolves endpoint hostnames for AWS services. | |
| 135 | |
| 136 This is NOT intended for external use. | |
| 137 """ | |
| 138 | |
| 139 def __init__(self, endpoint_data, service_rename_map=None): | |
| 140 """ | |
| 141 :type endpoint_data: dict | |
| 142 :param endpoint_data: Regions and endpoints data in the same format | |
| 143 as is used by botocore / boto3. | |
| 144 | |
| 145 :type service_rename_map: dict | |
| 146 :param service_rename_map: A mapping of boto2 service name to | |
| 147 endpoint prefix. | |
| 148 """ | |
| 149 self._resolver = _CompatEndpointResolver( | |
| 150 endpoint_data, service_rename_map) | |
| 151 | |
| 152 def resolve_hostname(self, service_name, region_name): | |
| 153 """Resolve the hostname for a service in a particular region. | |
| 154 | |
| 155 :type service_name: str | |
| 156 :param service_name: The service to look up. | |
| 157 | |
| 158 :type region_name: str | |
| 159 :param region_name: The region to find the endpoint for. | |
| 160 | |
| 161 :return: The hostname for the given service in the given region. | |
| 162 """ | |
| 163 endpoint = self._resolver.construct_endpoint(service_name, region_name) | |
| 164 if endpoint is None: | |
| 165 return None | |
| 166 return endpoint.get('sslCommonName', endpoint['hostname']) | |
| 167 | |
| 168 def get_all_available_regions(self, service_name): | |
| 169 """Get all the regions a service is available in. | |
| 170 | |
| 171 :type service_name: str | |
| 172 :param service_name: The service to look up. | |
| 173 | |
| 174 :rtype: list of str | |
| 175 :return: A list of all the regions the given service is available in. | |
| 176 """ | |
| 177 return self._resolver.get_all_available_regions(service_name) | |
| 178 | |
| 179 def get_available_services(self): | |
| 180 """Get all the services supported by the endpoint data. | |
| 181 | |
| 182 :rtype: list of str | |
| 183 :return: A list of all the services explicitly contained within the | |
| 184 endpoint data provided during instantiation. | |
| 185 """ | |
| 186 return self._resolver.get_available_services() | |
| 187 | |
| 188 | |
| 189 class StaticEndpointBuilder(object): | |
| 190 """Builds a static mapping of endpoints in the legacy format.""" | |
| 191 | |
| 192 def __init__(self, resolver): | |
| 193 """ | |
| 194 :type resolver: BotoEndpointResolver | |
| 195 :param resolver: An endpoint resolver. | |
| 196 """ | |
| 197 self._resolver = resolver | |
| 198 | |
| 199 def build_static_endpoints(self, service_names=None): | |
| 200 """Build a set of static endpoints in the legacy boto2 format. | |
| 201 | |
| 202 :param service_names: The names of the services to build. They must | |
| 203 use the names that boto2 uses, not boto3, e.g "ec2containerservice" | |
| 204 and not "ecs". If no service names are provided, all available | |
| 205 services will be built. | |
| 206 | |
| 207 :return: A dict consisting of:: | |
| 208 {"service": {"region": "full.host.name"}} | |
| 209 """ | |
| 210 if service_names is None: | |
| 211 service_names = self._resolver.get_available_services() | |
| 212 | |
| 213 static_endpoints = {} | |
| 214 for name in service_names: | |
| 215 endpoints_for_service = self._build_endpoints_for_service(name) | |
| 216 if endpoints_for_service: | |
| 217 # It's possible that when we try to build endpoints for | |
| 218 # services we get an empty hash. In that case we don't | |
| 219 # bother adding it to the final list of static endpoints. | |
| 220 static_endpoints[name] = endpoints_for_service | |
| 221 self._handle_special_cases(static_endpoints) | |
| 222 return static_endpoints | |
| 223 | |
| 224 def _build_endpoints_for_service(self, service_name): | |
| 225 # Given a service name, 'ec2', build a dict of | |
| 226 # 'region' -> 'hostname' | |
| 227 endpoints = {} | |
| 228 regions = self._resolver.get_all_available_regions(service_name) | |
| 229 for region_name in regions: | |
| 230 endpoints[region_name] = self._resolver.resolve_hostname( | |
| 231 service_name, region_name) | |
| 232 return endpoints | |
| 233 | |
| 234 def _handle_special_cases(self, static_endpoints): | |
| 235 # cloudsearchdomain endpoints use the exact same set of endpoints as | |
| 236 # cloudsearch. | |
| 237 if 'cloudsearch' in static_endpoints: | |
| 238 cloudsearch_endpoints = static_endpoints['cloudsearch'] | |
| 239 static_endpoints['cloudsearchdomain'] = cloudsearch_endpoints |
