/
opt
/
imh-python
/
lib
/
python3.9
/
site-packages
/
libcloud
/
common
/
/opt/imh-python/lib/python3.9/site-packages/libcloud/common
mkdir
upload
Name
Size
Mode
Actions
__pycache__/
-
0755
rm
abiquo.py
10315
0644
edit
dl
rm
aliyun.py
8800
0644
edit
dl
rm
aws.py
17632
0644
edit
dl
rm
azure.py
10362
0644
edit
dl
rm
azure_arm.py
10058
0644
edit
dl
rm
base.py
33185
0644
edit
dl
rm
brightbox.py
3484
0644
edit
dl
rm
buddyns.py
2489
0644
edit
dl
rm
cloudsigma.py
4389
0644
edit
dl
rm
cloudstack.py
7572
0644
edit
dl
rm
digitalocean.py
7037
0644
edit
dl
rm
dimensiondata.py
58274
0644
edit
dl
rm
dnsimple.py
2030
0644
edit
dl
rm
dnspod.py
2549
0644
edit
dl
rm
durabledns.py
10669
0644
edit
dl
rm
exceptions.py
3425
0644
edit
dl
rm
gandi.py
6225
0644
edit
dl
rm
gandi_live.py
7380
0644
edit
dl
rm
gig_g8.py
2946
0644
edit
dl
rm
gogrid.py
6395
0644
edit
dl
rm
google.py
30831
0644
edit
dl
rm
gridscale.py
4296
0644
edit
dl
rm
hostvirtual.py
2524
0644
edit
dl
rm
kubernetes.py
9061
0644
edit
dl
rm
linode.py
5598
0644
edit
dl
rm
liquidweb.py
6582
0644
edit
dl
rm
luadns.py
2675
0644
edit
dl
rm
maxihost.py
2152
0644
edit
dl
rm
nfsn.py
4137
0644
edit
dl
rm
nsone.py
2443
0644
edit
dl
rm
nttcis.py
74125
0644
edit
dl
rm
onapp.py
2132
0644
edit
dl
rm
openstack.py
18747
0644
edit
dl
rm
openstack_identity.py
61740
0644
edit
dl
rm
ovh.py
5963
0644
edit
dl
rm
pointdns.py
2044
0644
edit
dl
rm
providers.py
4071
0644
edit
dl
rm
rackspace.py
934
0644
edit
dl
rm
softlayer.py
2938
0644
edit
dl
rm
types.py
6914
0644
edit
dl
rm
upcloud.py
8956
0644
edit
dl
rm
vultr.py
4161
0644
edit
dl
rm
worldwidedns.py
7244
0644
edit
dl
rm
xmlrpc.py
3939
0644
edit
dl
rm
zonomi.py
4422
0644
edit
dl
rm
__init__.py
0
0644
edit
dl
rm
Edit:
/opt/imh-python/lib/python3.9/site-packages/libcloud/common/aws.py
(17632B)
# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You 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. from typing import Dict from typing import Optional from typing import Type import base64 from datetime import datetime import hashlib import hmac import time from hashlib import sha256 try: import simplejson as json except ImportError: import json # type: ignore from libcloud.utils.py3 import ET from libcloud.utils.py3 import _real_unicode from libcloud.utils.py3 import basestring from libcloud.common.base import ConnectionUserAndKey, XmlResponse, BaseDriver from libcloud.common.base import JsonResponse from libcloud.common.types import InvalidCredsError, MalformedResponseError from libcloud.utils.py3 import b, httplib, urlquote from libcloud.utils.xml import findtext, findall __all__ = [ 'AWSBaseResponse', 'AWSGenericResponse', 'AWSTokenConnection', 'SignedAWSConnection', 'AWSRequestSignerAlgorithmV2', 'AWSRequestSignerAlgorithmV4', 'AWSDriver' ] DEFAULT_SIGNATURE_VERSION = '2' UNSIGNED_PAYLOAD = 'UNSIGNED-PAYLOAD' PARAMS_NOT_STRING_ERROR_MSG = """ "params" dictionary contains an attribute "%s" which value (%s, %s) is not a string. Parameters are sent via query parameters and not via request body and as such, all the values need to be of a simple type (string, int, bool). For arrays and other complex types, you should use notation similar to this one: params['TagSpecification.1.Tag.Value'] = 'foo' params['TagSpecification.2.Tag.Value'] = 'bar' See https://docs.aws.amazon.com/AWSEC2/latest/APIReference/Query-Requests.html for details. """.strip() class AWSBaseResponse(XmlResponse): namespace = None def _parse_error_details(self, element): """ Parse code and message from the provided error element. :return: ``tuple`` with two elements: (code, message) :rtype: ``tuple`` """ code = findtext(element=element, xpath='Code', namespace=self.namespace) message = findtext(element=element, xpath='Message', namespace=self.namespace) return code, message class AWSGenericResponse(AWSBaseResponse): # There are multiple error messages in AWS, but they all have an Error node # with Code and Message child nodes. Xpath to select them # None if the root node *is* the Error node xpath = None # This dict maps <Error><Code>CodeName</Code></Error> to a specific # exception class that is raised immediately. # If a custom exception class is not defined, errors are accumulated and # returned from the parse_error method. exceptions = {} # type: Dict[str, Type[Exception]] def success(self): return self.status in [httplib.OK, httplib.CREATED, httplib.ACCEPTED] def parse_error(self): context = self.connection.context status = int(self.status) # FIXME: Probably ditch this as the forbidden message will have # corresponding XML. if status == httplib.FORBIDDEN: if not self.body: raise InvalidCredsError(str(self.status) + ': ' + self.error) else: raise InvalidCredsError(self.body) try: body = ET.XML(self.body) except Exception: raise MalformedResponseError('Failed to parse XML', body=self.body, driver=self.connection.driver) if self.xpath: errs = findall(element=body, xpath=self.xpath, namespace=self.namespace) else: errs = [body] msgs = [] for err in errs: code, message = self._parse_error_details(element=err) exceptionCls = self.exceptions.get(code, None) if exceptionCls is None: msgs.append('%s: %s' % (code, message)) continue # Custom exception class is defined, immediately throw an exception params = {} if hasattr(exceptionCls, 'kwargs'): for key in exceptionCls.kwargs: if key in context: params[key] = context[key] raise exceptionCls(value=message, driver=self.connection.driver, **params) return "\n".join(msgs) class AWSTokenConnection(ConnectionUserAndKey): def __init__(self, user_id, key, secure=True, host=None, port=None, url=None, timeout=None, proxy_url=None, token=None, retry_delay=None, backoff=None): self.token = token super(AWSTokenConnection, self).__init__(user_id, key, secure=secure, host=host, port=port, url=url, timeout=timeout, retry_delay=retry_delay, backoff=backoff, proxy_url=proxy_url) def add_default_params(self, params): # Even though we are adding it to the headers, we need it here too # so that the token is added to the signature. if self.token: params['x-amz-security-token'] = self.token return super(AWSTokenConnection, self).add_default_params(params) def add_default_headers(self, headers): if self.token: headers['x-amz-security-token'] = self.token return super(AWSTokenConnection, self).add_default_headers(headers) class AWSRequestSigner(object): """ Class which handles signing the outgoing AWS requests. """ def __init__(self, access_key, access_secret, version, connection): """ :param access_key: Access key. :type access_key: ``str`` :param access_secret: Access secret. :type access_secret: ``str`` :param version: API version. :type version: ``str`` :param connection: Connection instance. :type connection: :class:`Connection` """ self.access_key = access_key self.access_secret = access_secret self.version = version # TODO: Remove cycling dependency between connection and signer self.connection = connection def get_request_params(self, params, method='GET', path='/'): return params def get_request_headers(self, params, headers, method='GET', path='/', data=None): return params, headers class AWSRequestSignerAlgorithmV2(AWSRequestSigner): def get_request_params(self, params, method='GET', path='/'): params['SignatureVersion'] = '2' params['SignatureMethod'] = 'HmacSHA256' params['AWSAccessKeyId'] = self.access_key params['Version'] = self.version params['Timestamp'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) params['Signature'] = self._get_aws_auth_param( params=params, secret_key=self.access_secret, path=path) return params def _get_aws_auth_param(self, params, secret_key, path='/'): """ Creates the signature required for AWS, per http://bit.ly/aR7GaQ [docs.amazonwebservices.com]: StringToSign = HTTPVerb + "\n" + ValueOfHostHeaderInLowercase + "\n" + HTTPRequestURI + "\n" + CanonicalizedQueryString <from the preceding step> """ connection = self.connection keys = list(params.keys()) keys.sort() pairs = [] for key in keys: value = str(params[key]) pairs.append(urlquote(key, safe='') + '=' + urlquote(value, safe='-_~')) qs = '&'.join(pairs) hostname = connection.host if (connection.secure and connection.port != 443) or \ (not connection.secure and connection.port != 80): hostname += ':' + str(connection.port) string_to_sign = '\n'.join(('GET', hostname, path, qs)) b64_hmac = base64.b64encode( hmac.new(b(secret_key), b(string_to_sign), digestmod=sha256).digest() ) return b64_hmac.decode('utf-8') class AWSRequestSignerAlgorithmV4(AWSRequestSigner): def get_request_params(self, params, method='GET', path='/'): if method == 'GET': params['Version'] = self.version return params def get_request_headers(self, params, headers, method='GET', path='/', data=None): now = datetime.utcnow() headers['X-AMZ-Date'] = now.strftime('%Y%m%dT%H%M%SZ') headers['X-AMZ-Content-SHA256'] = self._get_payload_hash(method, data) headers['Authorization'] = \ self._get_authorization_v4_header(params=params, headers=headers, dt=now, method=method, path=path, data=data) return params, headers def _get_authorization_v4_header(self, params, headers, dt, method='GET', path='/', data=None): credentials_scope = self._get_credential_scope(dt=dt) signed_headers = self._get_signed_headers(headers=headers) signature = self._get_signature(params=params, headers=headers, dt=dt, method=method, path=path, data=data) return 'AWS4-HMAC-SHA256 Credential=%(u)s/%(c)s, ' \ 'SignedHeaders=%(sh)s, Signature=%(s)s' % { 'u': self.access_key, 'c': credentials_scope, 'sh': signed_headers, 's': signature } def _get_signature(self, params, headers, dt, method, path, data): key = self._get_key_to_sign_with(dt) string_to_sign = self._get_string_to_sign(params=params, headers=headers, dt=dt, method=method, path=path, data=data) return _sign(key=key, msg=string_to_sign, hex=True) def _get_key_to_sign_with(self, dt): return _sign( _sign( _sign( _sign(('AWS4' + self.access_secret), dt.strftime('%Y%m%d')), self.connection.driver.region_name), self.connection.service_name), 'aws4_request') def _get_string_to_sign(self, params, headers, dt, method, path, data): canonical_request = self._get_canonical_request(params=params, headers=headers, method=method, path=path, data=data) return '\n'.join(['AWS4-HMAC-SHA256', dt.strftime('%Y%m%dT%H%M%SZ'), self._get_credential_scope(dt), _hash(canonical_request)]) def _get_credential_scope(self, dt): return '/'.join([dt.strftime('%Y%m%d'), self.connection.driver.region_name, self.connection.service_name, 'aws4_request']) def _get_signed_headers(self, headers): return ';'.join([k.lower() for k in sorted(headers.keys())]) def _get_canonical_headers(self, headers): return '\n'.join([':'.join([k.lower(), str(v).strip()]) for k, v in sorted(headers.items())]) + '\n' def _get_payload_hash(self, method, data=None): if data is UnsignedPayloadSentinel: return UNSIGNED_PAYLOAD if method in ('POST', 'PUT'): if data: if hasattr(data, 'next') or hasattr(data, '__next__'): # File upload; don't try to read the entire payload return UNSIGNED_PAYLOAD return _hash(data) else: return UNSIGNED_PAYLOAD else: return _hash('') def _get_request_params(self, params): # For self.method == GET return '&'.join(["%s=%s" % (urlquote(k, safe=''), urlquote(str(v), safe='~')) for k, v in sorted(params.items())]) def _get_canonical_request(self, params, headers, method, path, data): return '\n'.join([ method, path, self._get_request_params(params), self._get_canonical_headers(headers), self._get_signed_headers(headers), self._get_payload_hash(method, data) ]) class UnsignedPayloadSentinel: pass class SignedAWSConnection(AWSTokenConnection): version = None # type: Optional[str] def __init__(self, user_id, key, secure=True, host=None, port=None, url=None, timeout=None, proxy_url=None, token=None, retry_delay=None, backoff=None, signature_version=DEFAULT_SIGNATURE_VERSION): super(SignedAWSConnection, self).__init__(user_id=user_id, key=key, secure=secure, host=host, port=port, url=url, timeout=timeout, token=token, retry_delay=retry_delay, backoff=backoff, proxy_url=proxy_url) self.signature_version = str(signature_version) if self.signature_version == '2': signer_cls = AWSRequestSignerAlgorithmV2 elif self.signature_version == '4': signer_cls = AWSRequestSignerAlgorithmV4 else: raise ValueError('Unsupported signature_version: %s' % (signature_version)) self.signer = signer_cls(access_key=self.user_id, access_secret=self.key, version=self.version, connection=self) def add_default_params(self, params): params = self.signer.get_request_params(params=params, method=self.method, path=self.action) # Verify that params only contain simple types and no nested # dictionaries. # params are sent via query params so only strings are supported for key, value in params.items(): if not isinstance(value, (_real_unicode, basestring, int, bool)): msg = PARAMS_NOT_STRING_ERROR_MSG % (key, value, type(value)) raise ValueError(msg) return params def pre_connect_hook(self, params, headers): params, headers = self.signer.get_request_headers(params=params, headers=headers, method=self.method, path=self.action, data=self.data) return params, headers class AWSJsonResponse(JsonResponse): """ Amazon ECS response class. ECS API uses JSON unlike the s3, elb drivers """ def parse_error(self): response = json.loads(self.body) code = response['__type'] message = response.get('Message', response['message']) return ('%s: %s' % (code, message)) def _sign(key, msg, hex=False): if hex: return hmac.new(b(key), b(msg), hashlib.sha256).hexdigest() else: return hmac.new(b(key), b(msg), hashlib.sha256).digest() def _hash(msg): return hashlib.sha256(b(msg)).hexdigest() class AWSDriver(BaseDriver): def __init__(self, key, secret=None, secure=True, host=None, port=None, api_version=None, region=None, token=None, **kwargs): self.token = token super(AWSDriver, self).__init__(key, secret=secret, secure=secure, host=host, port=port, api_version=api_version, region=region, token=token, **kwargs) def _ex_connection_class_kwargs(self): kwargs = super(AWSDriver, self)._ex_connection_class_kwargs() kwargs['token'] = self.token return kwargs
Save
cmd:
run