http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py deleted file mode 100644 index 03ca6be..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/slb.py +++ /dev/null @@ -1,831 +0,0 @@ -# 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. - -__all__ = [ - 'SLB_API_VERSION', - 'SLBDriver' -] - -import sys - -try: - import simplejson as json -except ImportError: - import json - -from libcloud.common.aliyun import AliyunXmlResponse, SignedAliyunConnection -from libcloud.common.types import LibcloudError -from libcloud.loadbalancer.types import State -from libcloud.loadbalancer.base import Algorithm, Driver, LoadBalancer, Member -from libcloud.utils.misc import ReprMixin -from libcloud.utils.py3 import u -from libcloud.utils.xml import findattr, findtext, findall - - -SLB_API_VERSION = '2014-05-15' -SLB_API_HOST = 'slb.aliyuncs.com' -DEFAULT_SIGNATURE_VERSION = '1.0' - - -STATE_MAPPINGS = { - 'inactive': State.UNKNOWN, - 'active': State.RUNNING, - 'locked': State.PENDING -} - - -RESOURCE_EXTRA_ATTRIBUTES_MAP = { - 'balancer': { - 'create_timestamp': { - 'xpath': 'CreateTimeStamp', - 'transform_func': int - }, - 'address_type': { - 'xpath': 'AddressType', - 'transform_func': u - }, - 'region_id': { - 'xpath': 'RegionId', - 'transform_func': u - }, - 'region_id_alias': { - 'xpath': 'RegionIdAlias', - 'transform_func': u - }, - 'create_time': { - 'xpath': 'CreateTime', - 'transform_func': u - }, - 'master_zone_id': { - 'xpath': 'MasterZoneId', - 'transform_func': u - }, - 'slave_zone_id': { - 'xpath': 'SlaveZoneId', - 'transform_func': u - }, - 'network_type': { - 'xpath': 'NetworkType', - 'transform_func': u - } - } -} - - -SLB_SCHEDULER_TO_ALGORITHM = { - 'wrr': Algorithm.WEIGHTED_ROUND_ROBIN, - 'wlc': Algorithm.WEIGHTED_LEAST_CONNECTIONS -} - - -ALGORITHM_TO_SLB_SCHEDULER = { - Algorithm.WEIGHTED_ROUND_ROBIN: 'wrr', - Algorithm.WEIGHTED_LEAST_CONNECTIONS: 'wlc' -} - - -class SLBConnection(SignedAliyunConnection): - version = SLB_API_VERSION - host = SLB_API_HOST - responseCls = AliyunXmlResponse - service_name = 'slb' - - -class SLBLoadBalancerAttribute(object): - """ - This class used to get listeners and backend servers related to a balancer - listeners is a ``list`` of ``dict``, each element contains - 'ListenerPort' and 'ListenerProtocol' keys. - backend_servers is a ``list`` of ``dict``, each element contains - 'ServerId' and 'Weight' keys. - """ - def __init__(self, balancer, listeners, backend_servers, extra=None): - self.balancer = balancer - self.listeners = listeners or [] - self.backend_servers = backend_servers or [] - self.extra = extra or {} - - def is_listening(self, port): - for listener in self.listeners: - if listener.get('ListenerPort') == port: - return True - return False - - def is_attached(self, member): - for server in self.backend_servers: - if server.get('Serverid') == member.id: - return True - return False - - def __repr__(self): - return ('<SLBLoadBalancerAttribute id=%s, ports=%s, servers=%s ...>' % - (self.balancer.id, self.listeners, self.backend_servers)) - - -class SLBLoadBalancerListener(ReprMixin, object): - """ - Base SLB load balancer listener class - """ - _repr_attributes = ['port', 'backend_port', 'scheduler', 'bandwidth'] - action = None - option_keys = [] - - def __init__(self, port, backend_port, algorithm, bandwidth, extra=None): - self.port = port - self.backend_port = backend_port - self.scheduler = ALGORITHM_TO_SLB_SCHEDULER.get(algorithm, 'wrr') - self.bandwidth = bandwidth - self.extra = extra or {} - - @classmethod - def create(cls, port, backend_port, algorithm, bandwidth, extra=None): - return cls(port, backend_port, algorithm, bandwidth, extra=extra) - - def get_create_params(self): - params = self.get_required_params() - options = self.get_optional_params() - options.update(params) - return options - - def get_required_params(self): - params = {'Action': self.action, - 'ListenerPort': self.port, - 'BackendServerPort': self.backend_port, - 'Scheduler': self.scheduler, - 'Bandwidth': self.bandwidth} - return params - - def get_optional_params(self): - options = {} - for option in self.option_keys: - if self.extra and option in self.extra: - options[option] = self.extra[option] - return options - - -class SLBLoadBalancerHttpListener(SLBLoadBalancerListener): - """ - This class represents a rule to route http request to the backends. - """ - action = 'CreateLoadBalancerHTTPListener' - option_keys = ['XForwardedFor', 'StickySessionType', 'CookieTimeout', - 'Cookie', 'HealthCheckDomain', 'HealthCheckURI', - 'HealthCheckConnectPort', 'HealthyThreshold', - 'UnhealthyThreshold', 'HealthCheckTimeout', - 'HealthCheckInterval', 'HealthCheckHttpCode'] - - def __init__(self, port, backend_port, algorithm, bandwidth, - sticky_session, health_check, extra=None): - super(SLBLoadBalancerHttpListener, self).__init__( - port, backend_port, algorithm, bandwidth, extra=extra) - self.sticky_session = sticky_session - self.health_check = health_check - - def get_required_params(self): - params = super(SLBLoadBalancerHttpListener, - self).get_required_params() - params['StickySession'] = self.sticky_session - params['HealthCheck'] = self.health_check - return params - - @classmethod - def create(cls, port, backend_port, algorithm, bandwidth, extra={}): - if 'StickySession' not in extra: - raise AttributeError('StickySession is required') - if 'HealthCheck' not in extra: - raise AttributeError('HealthCheck is required') - sticky_session = extra['StickySession'] - health_check = extra['HealthCheck'] - return cls(port, backend_port, algorithm, bandwidth, sticky_session, - health_check, extra=extra) - - -class SLBLoadBalancerHttpsListener(SLBLoadBalancerListener): - """ - This class represents a rule to route https request to the backends. - """ - action = 'CreateLoadBalancerHTTPSListener' - option_keys = ['XForwardedFor', 'StickySessionType', 'CookieTimeout', - 'Cookie', 'HealthCheckDomain', 'HealthCheckURI', - 'HealthCheckConnectPort', 'HealthyThreshold', - 'UnhealthyThreshold', 'HealthCheckTimeout', - 'HealthCheckInterval', 'HealthCheckHttpCode'] - - def __init__(self, port, backend_port, algorithm, bandwidth, - sticky_session, health_check, certificate_id, extra=None): - super(SLBLoadBalancerHttpsListener, self).__init__( - port, backend_port, algorithm, bandwidth, extra=extra) - self.sticky_session = sticky_session - self.health_check = health_check - self.certificate_id = certificate_id - - def get_required_params(self): - params = super(SLBLoadBalancerHttpsListener, - self).get_required_params() - params['StickySession'] = self.sticky_session - params['HealthCheck'] = self.health_check - params['ServerCertificateId'] = self.certificate_id - return params - - @classmethod - def create(cls, port, backend_port, algorithm, bandwidth, extra={}): - if 'StickySession' not in extra: - raise AttributeError('StickySession is required') - if 'HealthCheck' not in extra: - raise AttributeError('HealthCheck is required') - if 'ServerCertificateId' not in extra: - raise AttributeError('ServerCertificateId is required') - sticky_session = extra['StickySession'] - health_check = extra['HealthCheck'] - certificate_id = extra['ServerCertificateId'] - return cls(port, backend_port, algorithm, bandwidth, sticky_session, - health_check, certificate_id, extra=extra) - - -class SLBLoadBalancerTcpListener(SLBLoadBalancerListener): - """ - This class represents a rule to route tcp request to the backends. - """ - action = 'CreateLoadBalancerTCPListener' - option_keys = ['PersistenceTimeout', 'HealthCheckType', - 'HealthCheckDomain', 'HealthCheckURI', - 'HealthCheckConnectPort', 'HealthyThreshold', - 'UnhealthyThreshold', 'HealthCheckConnectTimeout', - 'HealthCheckInterval', 'HealthCheckHttpCode'] - - -class SLBLoadBalancerUdpListener(SLBLoadBalancerTcpListener): - """ - This class represents a rule to route udp request to the backends. - """ - action = 'CreateLoadBalancerUDPListener' - option_keys = ['PersistenceTimeout', 'HealthCheckConnectPort', - 'HealthyThreshold', 'UnhealthyThreshold', - 'HealthCheckConnectTimeout', 'HealthCheckInterval'] - - -class SLBServerCertificate(ReprMixin, object): - _repr_attributes = ['id', 'name', 'fingerprint'] - - def __init__(self, id, name, fingerprint): - self.id = id - self.name = name - self.fingerprint = fingerprint - - -PROTOCOL_TO_LISTENER_MAP = { - 'http': SLBLoadBalancerHttpListener, - 'https': SLBLoadBalancerHttpsListener, - 'tcp': SLBLoadBalancerTcpListener, - 'udp': SLBLoadBalancerUdpListener -} - - -class SLBDriver(Driver): - """ - Aliyun SLB load balancer driver. - """ - name = 'Aliyun Server Load Balancer' - website = 'https://www.aliyun.com/product/slb' - connectionCls = SLBConnection - path = '/' - namespace = None - - _VALUE_TO_ALGORITHM_MAP = SLB_SCHEDULER_TO_ALGORITHM - - _ALGORITHM_TO_VALUE_MAP = ALGORITHM_TO_SLB_SCHEDULER - - def __init__(self, access_id, secret, region): - super(SLBDriver, self).__init__(access_id, secret) - self.region = region - - def list_protocols(self): - return list(PROTOCOL_TO_LISTENER_MAP.keys()) - - def list_balancers(self, ex_balancer_ids=None, ex_filters=None): - """ - List all loadbalancers - - @inherits :class:`Driver.list_balancers` - - :keyword ex_balancer_ids: a list of balancer ids to filter results - Only balancers which's id in this list - will be returned - :type ex_balancer_ids: ``list`` of ``str`` - - :keyword ex_filters: attributes to filter results. Only balancers - which have all the desired attributes - and values will be returned - :type ex_filters: ``dict`` - """ - - params = {'Action': 'DescribeLoadBalancers', - 'RegionId': self.region} - if ex_balancer_ids and isinstance(ex_balancer_ids, list): - params['LoadBalancerId'] = ','.join(ex_balancer_ids) - - if ex_filters and isinstance(ex_filters, dict): - ex_filters.update(params) - params = ex_filters - resp_body = self.connection.request(self.path, params=params).object - return self._to_balancers(resp_body) - - def create_balancer(self, name, port, protocol, algorithm, members, - ex_bandwidth=None, ex_internet_charge_type=None, - ex_address_type=None, ex_vswitch_id=None, - ex_master_zone_id=None, ex_slave_zone_id=None, - ex_client_token=None, - **kwargs): - """ - Create a new load balancer instance - - @inherits: :class:`Driver.create_balancer` - - :keyword ex_bandwidth: The max bandwidth limit for `paybybandwidth` - internet charge type, in Mbps unit - :type ex_bandwidth: ``int`` in range [1, 1000] - - :keyword ex_internet_charge_type: The internet charge type - :type ex_internet_charge_type: a ``str`` of `paybybandwidth` - or `paybytraffic` - - :keyword ex_address_type: The listening IP address type - :type ex_address_type: a ``str`` of `internet` or `intranet` - - :keyword ex_vswitch_id: The vswitch id in a VPC network - :type ex_vswitch_id: ``str`` - - :keyword ex_master_zone_id: The id of the master availability zone - :type ex_master_zone_id: ``str`` - - :keyword ex_slave_zone_id: The id of the slave availability zone - :type ex_slave_zone_id: ``str`` - - :keyword ex_client_token: The token generated by client to - identify requests - :type ex_client_token: ``str`` - """ - - # 1.Create load balancer - params = {'Action': 'CreateLoadBalancer', - 'RegionId': self.region} - if name: - params['LoadBalancerName'] = name - if not port: - raise AttributeError('port is required') - if not protocol: - # NOTE(samsong8610): Use http listener as default - protocol = 'http' - if protocol not in PROTOCOL_TO_LISTENER_MAP: - raise AttributeError('unsupport protocol %s' % protocol) - - # Bandwidth in range [1, 1000] Mbps - bandwidth = -1 - if ex_bandwidth: - try: - bandwidth = int(ex_bandwidth) - except ValueError: - raise AttributeError('ex_bandwidth should be a integer in ' - 'range [1, 1000].') - params['Bandwidth'] = bandwidth - - if ex_internet_charge_type: - if ex_internet_charge_type.lower() == 'paybybandwidth': - if bandwidth == -1: - raise AttributeError('PayByBandwidth internet charge type' - ' need ex_bandwidth be set') - params['InternetChargeType'] = ex_internet_charge_type - - if ex_address_type: - if ex_address_type.lower() not in ('internet', 'intranet'): - raise AttributeError('ex_address_type should be "internet" ' - 'or "intranet"') - params['AddressType'] = ex_address_type - - if ex_vswitch_id: - params['VSwitchId'] = ex_vswitch_id - - if ex_master_zone_id: - params['MasterZoneId'] = ex_master_zone_id - if ex_slave_zone_id: - params['SlaveZoneId'] = ex_slave_zone_id - - if ex_client_token: - params['ClientToken'] = ex_client_token - - if members and isinstance(members, list): - backend_ports = [member.port for member in members] - if len(set(backend_ports)) != 1: - raise AttributeError('the ports of members should be unique') - # NOTE(samsong8610): If members do not provide backend port, - # default to listening port - backend_port = backend_ports[0] or port - else: - backend_port = port - - balancer = None - try: - resp_body = self.connection.request(self.path, params).object - balancer = self._to_balancer(resp_body) - balancer.port = port - - # 2.Add backend servers - if members is None: - members = [] - for member in members: - self.balancer_attach_member(balancer, member) - # 3.Create listener - # NOTE(samsong8610): Assume only create a listener which uses all - # the bandwidth. - self.ex_create_listener(balancer, backend_port, protocol, - algorithm, bandwidth, **kwargs) - self.ex_start_listener(balancer, port) - return balancer - except Exception: - e = sys.exc_info()[1] - if balancer is not None: - try: - self.destroy_balancer(balancer) - except Exception: - pass - raise e - - def destroy_balancer(self, balancer): - params = {'Action': 'DeleteLoadBalancer', - 'LoadBalancerId': balancer.id} - resp = self.connection.request(self.path, params) - return resp.success() - - def get_balancer(self, balancer_id): - balancers = self.list_balancers(ex_balancer_ids=[balancer_id]) - if len(balancers) != 1: - raise LibcloudError('could not find load balancer with id %s' % - balancer_id) - return balancers[0] - - def balancer_attach_compute_node(self, balancer, node): - if len(node.public_ips) > 0: - ip = node.public_ips[0] - else: - ip = node.private_ips[0] - member = Member(id=node.id, ip=ip, port=balancer.port) - return self.balancer_attach_member(balancer, member) - - def balancer_attach_member(self, balancer, member): - params = {'Action': 'AddBackendServers', - 'LoadBalancerId': balancer.id} - if member and isinstance(member, Member): - params['BackendServers'] = self._to_servers_json([member]) - self.connection.request(self.path, params) - return member - - def balancer_detach_member(self, balancer, member): - params = {'Action': 'RemoveBackendServers', - 'LoadBalancerId': balancer.id} - if member and isinstance(member, Member): - params['BackendServers'] = self._list_to_json([member.id]) - self.connection.request(self.path, params) - return member - - def balancer_list_members(self, balancer): - attribute = self.ex_get_balancer_attribute(balancer) - members = [Member(server['ServerId'], None, None, balancer=balancer, - extra={'Weight': server['Weight']}) - for server in attribute.backend_servers] - return members - - def ex_get_balancer_attribute(self, balancer): - """ - Get balancer attribute - - :param balancer: the balancer to get attribute - :type balancer: ``LoadBalancer`` - - :return: the balancer attribute - :rtype: ``SLBLoadBalancerAttribute`` - """ - - params = {'Action': 'DescribeLoadBalancerAttribute', - 'LoadBalancerId': balancer.id} - resp_body = self.connection.request(self.path, params).object - attribute = self._to_balancer_attribute(resp_body) - return attribute - - def ex_list_listeners(self, balancer): - """ - Get all listener related to the given balancer - - :param balancer: the balancer to list listeners - :type balancer: ``LoadBalancer`` - - :return: a list of listeners - :rtype: ``list`` of ``SLBLoadBalancerListener`` - """ - - attribute = self.ex_get_balancer_attribute(balancer) - listeners = [SLBLoadBalancerListener(each['ListenerPort'], None, - None, None) - for each in attribute.listeners] - return listeners - - def ex_create_listener(self, balancer, backend_port, protocol, algorithm, - bandwidth, **kwargs): - """ - Create load balancer listening rule. - - :param balancer: the balancer which the rule belongs to. - The listener created will listen on the port of the - the balancer as default. 'ListenerPort' in kwargs - will *OVERRIDE* it. - :type balancer: ``LoadBalancer`` - - :param backend_port: the backend server port - :type backend_port: ``int`` - - :param protocol: the balancer protocol, default to http - :type protocol: ``str`` - - :param algorithm: the balancer routing algorithm - :type algorithm: ``Algorithm`` - - :param bandwidth: the listener bandwidth limits - :type bandwidth: ``str`` - - :return: the created listener - :rtype: ``SLBLoadBalancerListener`` - """ - - cls = PROTOCOL_TO_LISTENER_MAP.get(protocol, - SLBLoadBalancerHttpListener) - if 'ListenerPort' in kwargs: - port = kwargs['ListenerPort'] - else: - port = balancer.port - listener = cls.create(port, backend_port, algorithm, - bandwidth, extra=kwargs) - params = listener.get_create_params() - params['LoadBalancerId'] = balancer.id - params['RegionId'] = self.region - resp = self.connection.request(self.path, params) - return resp.success() - - def ex_start_listener(self, balancer, port): - """ - Start balancer's listener listening the given port. - - :param balancer: a load balancer - :type balancer: ``LoadBalancer`` - - :param port: listening port - :type port: ``int`` - - :return: whether operation is success - :rtype: ``bool`` - """ - - params = {'Action': 'StartLoadBalancerListener', - 'LoadBalancerId': balancer.id, - 'ListenerPort': port} - resp = self.connection.request(self.path, params) - return resp.success() - - def ex_stop_listener(self, balancer, port): - """ - Stop balancer's listener listening the given port. - - :param balancer: a load balancer - :type balancer: ``LoadBalancer`` - - :param port: listening port - :type port: ``int`` - - :return: whether operation is success - :rtype: ``bool`` - """ - - params = {'Action': 'StopLoadBalancerListener', - 'LoadBalancerId': balancer.id, - 'ListenerPort': port} - resp = self.connection.request(self.path, params) - return resp.success() - - def ex_upload_certificate(self, name, server_certificate, - private_key): - """ - Upload certificate and private key for https load balancer listener - - :param name: the certificate name - :type name: ``str`` - - :param server_certificate: the content of the certificate to upload - in PEM format - :type server_certificate: ``str`` - - :param private_key: the content of the private key to upload - in PEM format - :type private_key: ``str`` - - :return: new created certificate info - :rtype: ``SLBServerCertificate`` - """ - - params = {'Action': 'UploadServerCertificate', - 'RegionId': self.region, - 'ServerCertificate': server_certificate, - 'PrivateKey': private_key} - if name: - params['ServerCertificateName'] = name - resp_body = self.connection.request(self.path, params).object - return self._to_server_certificate(resp_body) - - def ex_list_certificates(self, certificate_ids=[]): - """ - List all server certificates - - :param certificate_ids: certificate ids to filter results - :type certificate_ids: ``str`` - - :return: certificates - :rtype: ``SLBServerCertificate`` - """ - - params = {'Action': 'DescribeServerCertificates', - 'RegionId': self.region} - if certificate_ids and isinstance(certificate_ids, list): - params['ServerCertificateId'] = ','.join(certificate_ids) - - resp_body = self.connection.request(self.path, params).object - cert_elements = findall(resp_body, - 'ServerCertificates/ServerCertificate', - namespace=self.namespace) - certificates = [self._to_server_certificate(el) - for el in cert_elements] - return certificates - - def ex_delete_certificate(self, certificate_id): - """ - Delete the given server certificate - - :param certificate_id: the id of the certificate to delete - :type certificate_id: ``str`` - - :return: whether process is success - :rtype: ``bool`` - """ - - params = {'Action': 'DeleteServerCertificate', - 'RegionId': self.region, - 'ServerCertificateId': certificate_id} - resp = self.connection.request(self.path, params) - return resp.success() - - def ex_set_certificate_name(self, certificate_id, name): - """ - Set server certificate name. - - :param certificate_id: the id of the server certificate to update - :type certificate_id: ``str`` - - :param name: the new name - :type name: ``str`` - - :return: whether updating is success - :rtype: ``bool`` - """ - - params = {'Action': 'SetServerCertificateName', - 'RegionId': self.region, - 'ServerCertificateId': certificate_id, - 'ServerCertificateName': name} - resp = self.connection.request(self.path, params) - return resp.success() - - def _to_balancers(self, element): - xpath = 'LoadBalancers/LoadBalancer' - return [self._to_balancer(el) - for el in findall(element=element, xpath=xpath, - namespace=self.namespace)] - - def _to_balancer(self, el): - _id = findtext(element=el, xpath='LoadBalancerId', - namespace=self.namespace) - name = findtext(element=el, xpath='LoadBalancerName', - namespace=self.namespace) - status = findtext(element=el, xpath='LoadBalancerStatus', - namespace=self.namespace) - state = STATE_MAPPINGS.get(status, State.UNKNOWN) - address = findtext(element=el, xpath='Address', - namespace=self.namespace) - extra = self._get_extra_dict( - el, RESOURCE_EXTRA_ATTRIBUTES_MAP['balancer']) - - balancer = LoadBalancer(id=_id, name=name, state=state, ip=address, - port=None, driver=self, extra=extra) - return balancer - - def _create_list_params(self, params, items, label): - """ - return parameter list - """ - if isinstance(items, str): - items = [items] - for index, item in enumerate(items): - params[label % (index + 1)] = item - return params - - def _get_extra_dict(self, element, mapping): - """ - Extract attributes from the element based on rules provided in the - mapping dictionary. - - :param element: Element to parse the values from. - :type element: xml.etree.ElementTree.Element. - - :param mapping: Dictionary with the extra layout - :type node: :class:`Node` - - :rtype: ``dict`` - """ - extra = {} - for attribute, values in mapping.items(): - transform_func = values['transform_func'] - value = findattr(element=element, - xpath=values['xpath'], - namespace=self.namespace) - if value: - try: - extra[attribute] = transform_func(value) - except Exception: - extra[attribute] = None - else: - extra[attribute] = value - - return extra - - def _to_servers_json(self, members): - servers = [] - for each in members: - server = {'ServerId': each.id, - 'Weight': '100'} - if 'Weight' in each.extra: - server['Weight'] = each.extra['Weight'] - servers.append(server) - try: - return json.dumps(servers) - except Exception: - raise AttributeError('could not convert member to backend server') - - def _to_balancer_attribute(self, element): - balancer = self._to_balancer(element) - port_proto_elements = findall( - element, 'ListenerPortsAndProtocol/ListenerPortAndProtocol', - namespace=self.namespace) - if len(port_proto_elements) > 0: - listeners = [self._to_port_and_protocol(el) - for el in port_proto_elements] - else: - port_elements = findall(element, 'ListenerPorts/ListenerPort', - namespace=self.namespace) - listeners = [{'ListenerPort': el.text, 'ListenerProtocol': 'http'} - for el in port_elements] - server_elements = findall(element, - 'BackendServers/BackendServer', - namespace=self.namespace) - backend_servers = [self._to_server_and_weight(el) - for el in server_elements] - return SLBLoadBalancerAttribute(balancer, listeners, backend_servers) - - def _to_port_and_protocol(self, el): - port = findtext(el, 'ListenerPort', namespace=self.namespace) - protocol = findtext(el, 'ListenerProtocol', namespace=self.namespace) - return {'ListenerPort': port, 'ListenerProtocol': protocol} - - def _to_server_and_weight(self, el): - server_id = findtext(el, 'ServerId', namespace=self.namespace) - weight = findtext(el, 'Weight', namespace=self.namespace) - return {'ServerId': server_id, 'Weight': weight} - - def _to_server_certificate(self, el): - _id = findtext(el, 'ServerCertificateId', namespace=self.namespace) - name = findtext(el, 'ServerCertificateName', namespace=self.namespace) - fingerprint = findtext(el, 'Fingerprint', namespace=self.namespace) - return SLBServerCertificate(id=_id, name=name, - fingerprint=fingerprint) - - def _list_to_json(self, value): - try: - return json.dumps(value) - except Exception: - return '[]'
http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py deleted file mode 100644 index 556e4fb..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/drivers/softlayer.py +++ /dev/null @@ -1,435 +0,0 @@ -# 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 withv -# 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. - -__all__ = [ - 'SoftlayerLBDriver' -] - -from libcloud.common.types import LibcloudError -from libcloud.common.softlayer import SoftLayerConnection -from libcloud.utils.misc import find, reverse_dict -from libcloud.loadbalancer.types import State -from libcloud.loadbalancer.base import Algorithm, Driver, LoadBalancer -from libcloud.loadbalancer.base import DEFAULT_ALGORITHM, Member - -lb_service = 'SoftLayer_Network_Application_Delivery_Controller_LoadBalancer_'\ - 'VirtualIpAddress' - - -class LBPackage(object): - - """ - Defines a single Softlayer package to be used when placing orders ( - e.g. via ex_place_balancer_order method). - - :param id: Package id. - :type id: ``int`` - - :param name: Package name. - :type name: ``str`` - - :param description: Package short description. - :type description: ``str`` - - :param price_id: Id of the price for this package. - :type price_id: ``int`` - - :param capacity: Provides a numerical representation of the capacity given - in the description of this package. - :type capacity: ``int`` - - """ - - def __init__(self, id, name, description, price_id, capacity): - self.id = id - self.name = name - self.description = description - self.price_id = price_id - self.capacity = capacity - - def __repr__(self): - return ( - '<LBPackage: id=%s, name=%s, description=%s, price_id=%s, ' - 'capacity=%s>' % (self.id, self.name, self.description, - self.price_id, self.capacity)) - - -class SoftlayerLBDriver(Driver): - name = 'Softlayer Load Balancing' - website = 'http://www.softlayer.com/' - connectionCls = SoftLayerConnection - - _VALUE_TO_ALGORITHM_MAP = { - 'ROUND_ROBIN': Algorithm.ROUND_ROBIN, - 'LEAST_CONNECTIONS': Algorithm.LEAST_CONNECTIONS, - 'SHORTEST_RESPONSE': Algorithm.SHORTEST_RESPONSE, - 'PERSISTENT_IP': Algorithm.PERSISTENT_IP - } - - _ALGORITHM_TO_VALUE_MAP = reverse_dict(_VALUE_TO_ALGORITHM_MAP) - - def list_balancers(self): - mask = { - 'adcLoadBalancers': { - 'ipAddress': '', - 'loadBalancerHardware': { - 'datacenter': '' - }, - 'virtualServers': { - 'serviceGroups': { - 'routingMethod': '', - 'routingType': '', - 'services': { - 'ipAddress': '' - } - } - } - } - } - - res = self.connection.request( - 'SoftLayer_Account', 'getAdcLoadBalancers', - object_mask=mask).object - - return [self._to_balancer(lb) for lb in res] - - def get_balancer(self, balancer_id): - balancers = self.list_balancers() - balancer = find(balancers, lambda b: b.id == balancer_id) - if not balancer: - raise LibcloudError(value='No balancer found for id: %s' % - balancer_id, driver=self) - return balancer - - def list_protocols(self): - """ - Return a list of supported protocols. - - :rtype: ``list`` of ``str`` - """ - return ['dns', 'ftp', 'http', 'https', 'tcp', 'udp'] - - def balancer_list_members(self, balancer): - lb = self._get_balancer_model(balancer.id) - members = [] - vs = self._locate_service_group(lb, balancer.port) - if vs: - if vs['serviceGroups']: - srvgrp = vs['serviceGroups'][0] - members = [self._to_member(srv, balancer) for - srv in srvgrp['services']] - - return members - - def balancer_attach_member(self, balancer, member): - lb = self._get_balancer_model(balancer.id) - vs = self._locate_service_group(lb, balancer.port) - if not vs: - raise LibcloudError(value='No service_group found for balancer ' - 'port: %s' % balancer.port, driver=self) - - if vs['serviceGroups']: - services = vs['serviceGroups'][0]['services'] - services.append(self._to_service_template(member.ip, - member.port)) - - self.connection.request(lb_service, 'editObject', lb, id=balancer.id) - - return [m for m in balancer.list_members() if m.ip == member.ip][0] - - def balancer_detach_member(self, balancer, member): - svc_lbsrv = 'SoftLayer_Network_Application_Delivery_Controller_'\ - 'LoadBalancer_Service' - - self.connection.request(svc_lbsrv, 'deleteObject', id=member.id) - return True - - def destroy_balancer(self, balancer): - res_billing = self.connection.request(lb_service, 'getBillingItem', - id=balancer.id).object - - self.connection.request('SoftLayer_Billing_Item', 'cancelService', - id=res_billing['id']) - return True - - def ex_list_balancer_packages(self): - """ - Retrieves the available local load balancer packages. - - :rtype: ``list`` of :class:`LBPackage` - """ - mask = { - 'prices': '' - } - res = self.connection.request('SoftLayer_Product_Package', 'getItems', - id=0, object_mask=mask).object - - res_lb_pkgs = [r for r in res if r['description'].find - ('Load Balancer') != -1] - res_lb_pkgs = [r for r in res_lb_pkgs if not r['description']. - startswith('Global')] - - return [self._to_lb_package(r) for r in res_lb_pkgs] - - def ex_place_balancer_order(self, package, location): - """ - Places an order for a local loadbalancer in the specified - location. - - :param package: The package to create the loadbalancer from. - :type package: :class:`LBPackage` - - :param string location: The location (datacenter) to create the - loadbalancer. - :type location: :class:`NodeLocation` - - :return: ``True`` if ex_place_balancer_order was successful. - :rtype: ``bool`` - """ - data = { - 'complexType': 'SoftLayer_Container_Product_Order_Network_' - 'LoadBalancer', - 'quantity': 1, - 'packageId': 0, - 'location': self._get_location(location.id), - 'prices': [{'id': package.price_id}] - } - - self.connection.request('SoftLayer_Product_Order', 'placeOrder', - data) - return True - - def ex_configure_load_balancer(self, balancer, port=80, - protocol='http', - algorithm=DEFAULT_ALGORITHM, - ex_allocation=100): - """ - Configure the loadbalancer by adding it with a front-end port (aka - a service group in the Softlayer loadbalancer model). - - Softlayer loadbalancer may be defined with multiple service - groups (front-end ports) each defined with a unique port number. - - :param balancer: The loadbalancer. - :type balancer: :class:`LoadBalancer` - - :param port: Port of the service group, defaults to 80. - :type port: ``int`` - - :param protocol: Loadbalancer protocol, defaults to http. - :type protocol: ``str`` - - :param algorithm: Load balancing algorithm, defaults to - Algorithm.ROUND_ROBIN - :type algorithm: :class:`Algorithm` - - :param ex_allocation: The percentage of the total connection - allocations to allocate for this group. - :type ex_allocation: ``int`` - - :return: ``True`` if ex_add_service_group was successful. - :rtype: ``bool`` - """ - _types = self._get_routing_types() - _methods = self._get_routing_methods() - - rt = find(_types, lambda t: t['keyname'] == protocol.upper()) - if not rt: - raise LibcloudError(value='Invalid protocol %s' % protocol, - driver=self) - - value = self._algorithm_to_value(algorithm) - meth = find(_methods, lambda m: m['keyname'] == value) - if not meth: - raise LibcloudError(value='Invalid algorithm %s' % algorithm, - driver=self) - - service_group_template = { - 'port': port, - 'allocation': ex_allocation, - 'serviceGroups': [{ - 'routingTypeId': rt['id'], - 'routingMethodId': meth['id'] - }] - } - - lb = self._get_balancer_model(balancer.id) - if len(lb['virtualServers']) > 0: - port = lb['virtualServers'][0]['port'] - raise LibcloudError(value='Loadbalancer already configured with ' - 'a service group (front-end port)' % port, - driver=self) - - lb['virtualServers'].append(service_group_template) - self.connection.request(lb_service, 'editObject', lb, id=balancer.id) - return True - - def _get_balancer_model(self, balancer_id): - """ - Retrieve Softlayer loadbalancer model. - """ - lb_mask = { - 'virtualServers': { - 'serviceGroups': { - 'services': { - 'ipAddress': '', - 'groupReferences': '', - } - } - } - } - - lb_res = self.connection.request(lb_service, 'getObject', - object_mask=lb_mask, id=balancer_id).\ - object - return lb_res - - def _locate_service_group(self, lb, port): - """ - Locate service group with given port. - - Return virtualServers (vs) entry whose port matches the - supplied parameter port. For a negative port, just return - the first vs entry. - None is returned if no match found. - - :param lb: Softlayer loadbalancer model. - :type lb: ``dict`` - - :param port: loadbalancer front-end port. - :type port: ``int`` - - :return: Matched entry in the virtualServers array of the supplied - model. - :rtype: ``dict`` - """ - vs = None - if port < 0: - vs = lb['virtualServers'][0] if lb['virtualServers']\ - else None - else: - vs = find(lb['virtualServers'], lambda v: v['port'] == port) - - return vs - - def _get_routing_types(self): - svc_rtype = 'SoftLayer_Network_Application_Delivery_Controller_'\ - 'LoadBalancer_Routing_Type' - - return self.connection.request(svc_rtype, 'getAllObjects').object - - def _get_routing_methods(self): - svc_rmeth = 'SoftLayer_Network_Application_Delivery_Controller_'\ - 'LoadBalancer_Routing_Method' - - return self.connection.request(svc_rmeth, 'getAllObjects').object - - def _get_location(self, location_id): - res = self.connection.request('SoftLayer_Location_Datacenter', - 'getDatacenters').object - - dcenter = find(res, lambda d: d['name'] == location_id) - if not dcenter: - raise LibcloudError(value='Invalid value %s' % location_id, - driver=self) - return dcenter['id'] - - def _get_ipaddress(self, ip): - svc_ipaddress = 'SoftLayer_Network_Subnet_IpAddress' - - return self.connection.request(svc_ipaddress, 'getByIpAddress', - ip).object - - def _to_lb_package(self, pkg): - try: - price_id = pkg['prices'][0]['id'] - except: - price_id = -1 - - capacity = int(pkg.get('capacity', 0)) - return LBPackage(id=pkg['id'], name=pkg['keyName'], - description=pkg['description'], - price_id=price_id, capacity=capacity) - - def _to_service_template(self, ip, port): - """ - Builds single member entry in Softlayer loadbalancer model - """ - template = { - 'enabled': 1, # enable the service - 'port': port, # back-end port - 'ipAddressId': self._get_ipaddress(ip)['id'], - 'healthChecks': [{ - 'healthCheckTypeId': 21 # default health check - }], - 'groupReferences': [{ - 'weight': 1 - }] - } - - return template - - def _to_balancer(self, lb): - ipaddress = lb['ipAddress']['ipAddress'] - - extra = {} - extra['connection_limit'] = lb['connectionLimit'] - extra['ssl_active'] = lb['sslActiveFlag'] - extra['ssl_enabled'] = lb['sslEnabledFlag'] - extra['ha'] = lb['highAvailabilityFlag'] - extra['datacenter'] = \ - lb['loadBalancerHardware'][0]['datacenter']['name'] - - # In Softlayer, there could be multiple group of members (aka service - # groups), so retrieve the first one - vs = self._locate_service_group(lb, -1) - if vs: - port = vs['port'] - if vs['serviceGroups']: - srvgrp = vs['serviceGroups'][0] - routing_method = srvgrp['routingMethod']['keyname'] - routing_type = srvgrp['routingType']['keyname'] - try: - extra['algorithm'] = self.\ - _value_to_algorithm(routing_method) - except: - pass - extra['protocol'] = routing_type.lower() - - if not vs: - port = -1 - - balancer = LoadBalancer( - id=lb['id'], - name='', - state=State.UNKNOWN, - ip=ipaddress, - port=port, - driver=self.connection.driver, - extra=extra - ) - - return balancer - - def _to_member(self, srv, balancer=None): - svc_id = srv['id'] - ip = srv['ipAddress']['ipAddress'] - port = srv['port'] - - extra = {} - extra['status'] = srv['status'] - extra['enabled'] = srv['enabled'] - return Member(id=svc_id, ip=ip, port=port, balancer=balancer, - extra=extra) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py deleted file mode 100644 index 49a0f3a..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/providers.py +++ /dev/null @@ -1,59 +0,0 @@ -# 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 libcloud.loadbalancer.types import Provider -from libcloud.loadbalancer.types import OLD_CONSTANT_TO_NEW_MAPPING -from libcloud.common.providers import get_driver as _get_provider_driver -from libcloud.common.providers import set_driver as _set_provider_driver - -__all__ = [ - "Provider", - "DRIVERS", - "get_driver", -] - -DRIVERS = { - Provider.RACKSPACE: - ('libcloud.loadbalancer.drivers.rackspace', 'RackspaceLBDriver'), - Provider.GOGRID: - ('libcloud.loadbalancer.drivers.gogrid', 'GoGridLBDriver'), - Provider.NINEFOLD: - ('libcloud.loadbalancer.drivers.ninefold', 'NinefoldLBDriver'), - Provider.BRIGHTBOX: - ('libcloud.loadbalancer.drivers.brightbox', 'BrightboxLBDriver'), - Provider.ELB: - ('libcloud.loadbalancer.drivers.elb', 'ElasticLBDriver'), - Provider.CLOUDSTACK: - ('libcloud.loadbalancer.drivers.cloudstack', 'CloudStackLBDriver'), - Provider.GCE: - ('libcloud.loadbalancer.drivers.gce', 'GCELBDriver'), - Provider.SOFTLAYER: - ('libcloud.loadbalancer.drivers.softlayer', 'SoftlayerLBDriver'), - Provider.DIMENSIONDATA: - ('libcloud.loadbalancer.drivers.dimensiondata', 'DimensionDataLBDriver'), - Provider.ALIYUN_SLB: - ('libcloud.loadbalancer.drivers.slb', 'SLBDriver'), -} - - -def get_driver(provider): - deprecated_constants = OLD_CONSTANT_TO_NEW_MAPPING - return _get_provider_driver(drivers=DRIVERS, provider=provider, - deprecated_constants=deprecated_constants) - - -def set_driver(provider, module, klass): - return _set_provider_driver(drivers=DRIVERS, provider=provider, - module=module, klass=klass) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py b/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py deleted file mode 100644 index b0fba05..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/loadbalancer/types.py +++ /dev/null @@ -1,84 +0,0 @@ -# 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. - -__all__ = [ - "Provider", - "State", - "LibcloudLBError", - "LibcloudLBImmutableError", - - "OLD_CONSTANT_TO_NEW_MAPPING" -] - -from libcloud.common.types import LibcloudError - - -class LibcloudLBError(LibcloudError): - pass - - -class LibcloudLBImmutableError(LibcloudLBError): - pass - - -class Provider(object): - """ - :cvar ALIYUN_SLB: Aliyun SLB loadbalancer driver - """ - RACKSPACE = 'rackspace' - GOGRID = 'gogrid' - NINEFOLD = 'ninefold' - BRIGHTBOX = 'brightbox' - ELB = 'elb' - CLOUDSTACK = 'cloudstack' - GCE = 'gce' - SOFTLAYER = 'softlayer' - DIMENSIONDATA = 'dimensiondata' - ALIYUN_SLB = 'aliyun_slb' - - # Deprecated - RACKSPACE_US = 'rackspace_us' - RACKSPACE_UK = 'rackspace_uk' - - -OLD_CONSTANT_TO_NEW_MAPPING = { - Provider.RACKSPACE_US: Provider.RACKSPACE, - Provider.RACKSPACE_UK: Provider.RACKSPACE, -} - - -class State(object): - """ - Standard states for a loadbalancer - - :cvar RUNNING: loadbalancer is running and ready to use - :cvar UNKNOWN: loabalancer state is unknown - """ - - RUNNING = 0 - PENDING = 1 - UNKNOWN = 2 - ERROR = 3 - DELETED = 4 - - -class MemberCondition(object): - """ - Each member of a load balancer can have an associated condition - which determines its role within the load balancer. - """ - ENABLED = 0 - DISABLED = 1 - DRAINING = 2 http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/pricing.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/pricing.py b/apache-libcloud-1.0.0rc2/libcloud/pricing.py deleted file mode 100644 index 42075fb..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/pricing.py +++ /dev/null @@ -1,224 +0,0 @@ -# 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 __future__ import with_statement - -""" -A class which handles loading the pricing files. -""" - -import os.path -from os.path import join as pjoin - -try: - import simplejson as json - try: - JSONDecodeError = json.JSONDecodeError - except AttributeError: - # simplejson < 2.1.0 does not have the JSONDecodeError exception class - JSONDecodeError = ValueError -except ImportError: - import json - JSONDecodeError = ValueError - -from libcloud.utils.connection import get_response_object - -__all__ = [ - 'get_pricing', - 'get_size_price', - 'set_pricing', - 'clear_pricing_data', - 'download_pricing_file' -] - -# Default URL to the pricing file -DEFAULT_FILE_URL = 'https://git-wip-us.apache.org/repos/asf?p=libcloud.git;a=blob_plain;f=libcloud/data/pricing.json' # NOQA - -CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__)) -DEFAULT_PRICING_FILE_PATH = pjoin(CURRENT_DIRECTORY, 'data/pricing.json') -CUSTOM_PRICING_FILE_PATH = os.path.expanduser('~/.libcloud/pricing.json') - -# Pricing data cache -PRICING_DATA = { - 'compute': {}, - 'storage': {} -} - -VALID_PRICING_DRIVER_TYPES = ['compute', 'storage'] - - -def get_pricing_file_path(file_path=None): - if os.path.exists(CUSTOM_PRICING_FILE_PATH) and \ - os.path.isfile(CUSTOM_PRICING_FILE_PATH): - # Custom pricing file is available, use it - return CUSTOM_PRICING_FILE_PATH - - return DEFAULT_PRICING_FILE_PATH - - -def get_pricing(driver_type, driver_name, pricing_file_path=None): - """ - Return pricing for the provided driver. - - :type driver_type: ``str`` - :param driver_type: Driver type ('compute' or 'storage') - - :type driver_name: ``str`` - :param driver_name: Driver name - - :type pricing_file_path: ``str`` - :param pricing_file_path: Custom path to a price file. If not provided - it uses a default path. - - :rtype: ``dict`` - :return: Dictionary with pricing where a key name is size ID and - the value is a price. - """ - if driver_type not in VALID_PRICING_DRIVER_TYPES: - raise AttributeError('Invalid driver type: %s', driver_type) - - if driver_name in PRICING_DATA[driver_type]: - return PRICING_DATA[driver_type][driver_name] - - if not pricing_file_path: - pricing_file_path = get_pricing_file_path(file_path=pricing_file_path) - - with open(pricing_file_path) as fp: - content = fp.read() - - pricing_data = json.loads(content) - size_pricing = pricing_data[driver_type][driver_name] - - for driver_type in VALID_PRICING_DRIVER_TYPES: - # pylint: disable=maybe-no-member - pricing = pricing_data.get(driver_type, None) - if pricing: - PRICING_DATA[driver_type] = pricing - - return size_pricing - - -def set_pricing(driver_type, driver_name, pricing): - """ - Populate the driver pricing dictionary. - - :type driver_type: ``str`` - :param driver_type: Driver type ('compute' or 'storage') - - :type driver_name: ``str`` - :param driver_name: Driver name - - :type pricing: ``dict`` - :param pricing: Dictionary where a key is a size ID and a value is a price. - """ - - PRICING_DATA[driver_type][driver_name] = pricing - - -def get_size_price(driver_type, driver_name, size_id): - """ - Return price for the provided size. - - :type driver_type: ``str`` - :param driver_type: Driver type ('compute' or 'storage') - - :type driver_name: ``str`` - :param driver_name: Driver name - - :type size_id: ``str`` or ``int`` - :param size_id: Unique size ID (can be an integer or a string - depends on - the driver) - - :rtype: ``float`` - :return: Size price. - """ - pricing = get_pricing(driver_type=driver_type, driver_name=driver_name) - price = float(pricing[size_id]) - return price - - -def invalidate_pricing_cache(): - """ - Invalidate pricing cache for all the drivers. - """ - PRICING_DATA['compute'] = {} - PRICING_DATA['storage'] = {} - - -def clear_pricing_data(): - """ - Invalidate pricing cache for all the drivers. - - Note: This method does the same thing as invalidate_pricing_cache and is - here for backward compatibility reasons. - """ - invalidate_pricing_cache() - - -def invalidate_module_pricing_cache(driver_type, driver_name): - """ - Invalidate the cache for the specified driver. - - :type driver_type: ``str`` - :param driver_type: Driver type ('compute' or 'storage') - - :type driver_name: ``str`` - :param driver_name: Driver name - """ - if driver_name in PRICING_DATA[driver_type]: - del PRICING_DATA[driver_type][driver_name] - - -def download_pricing_file(file_url=DEFAULT_FILE_URL, - file_path=CUSTOM_PRICING_FILE_PATH): - """ - Download pricing file from the file_url and save it to file_path. - - :type file_url: ``str`` - :param file_url: URL pointing to the pricing file. - - :type file_path: ``str`` - :param file_path: Path where a download pricing file will be saved. - """ - dir_name = os.path.dirname(file_path) - - if not os.path.exists(dir_name): - # Verify a valid path is provided - msg = ('Can\'t write to %s, directory %s, doesn\'t exist' % - (file_path, dir_name)) - raise ValueError(msg) - - if os.path.exists(file_path) and os.path.isdir(file_path): - msg = ('Can\'t write to %s file path because it\'s a' - ' directory' % (file_path)) - raise ValueError(msg) - - response = get_response_object(file_url) - body = response.body - - # Verify pricing file is valid - try: - data = json.loads(body) - except JSONDecodeError: - msg = 'Provided URL doesn\'t contain valid pricing data' - raise Exception(msg) - - # pylint: disable=maybe-no-member - if not data.get('updated', None): - msg = 'Provided URL doesn\'t contain valid pricing data' - raise Exception(msg) - - # No need to stream it since file is small - with open(file_path, 'w') as file_handle: - file_handle.write(body) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/security.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/security.py b/apache-libcloud-1.0.0rc2/libcloud/security.py deleted file mode 100644 index 4d024db..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/security.py +++ /dev/null @@ -1,89 +0,0 @@ -# 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. -""" -Security (SSL) Settings - -Usage: - import libcloud.security - libcloud.security.VERIFY_SSL_CERT = True - - # Optional. - libcloud.security.CA_CERTS_PATH.append('/path/to/cacert.txt') -""" - -import os -import ssl - -__all__ = [ - 'VERIFY_SSL_CERT', - 'SSL_VERSION', - 'CA_CERTS_PATH' -] - -VERIFY_SSL_CERT = True - -SSL_VERSION = ssl.PROTOCOL_TLSv1 - -# File containing one or more PEM-encoded CA certificates -# concatenated together. -CA_CERTS_PATH = [ - # centos/fedora: openssl - '/etc/pki/tls/certs/ca-bundle.crt', - - # debian/ubuntu/arch/gentoo: ca-certificates - '/etc/ssl/certs/ca-certificates.crt', - - # freebsd: ca_root_nss - '/usr/local/share/certs/ca-root-nss.crt', - - # macports: curl-ca-bundle - '/opt/local/share/curl/curl-ca-bundle.crt', - - # homebrew: openssl - '/usr/local/etc/openssl/cert.pem', - - # homebrew: curl-ca-bundle (backward compatibility) - '/usr/local/opt/curl-ca-bundle/share/ca-bundle.crt', -] - -# Allow user to explicitly specify which CA bundle to use, using an environment -# variable -environment_cert_file = os.getenv('SSL_CERT_FILE', None) -if environment_cert_file is not None: - # Make sure the file exists - if not os.path.exists(environment_cert_file): - raise ValueError('Certificate file %s doesn\'t exist' % - (environment_cert_file)) - - if not os.path.isfile(environment_cert_file): - raise ValueError('Certificate file can\'t be a directory') - - # If a provided file exists we ignore other common paths because we - # don't want to fall-back to a potentially less restrictive bundle - CA_CERTS_PATH = [environment_cert_file] - -CA_CERTS_UNAVAILABLE_ERROR_MSG = ( - 'No CA Certificates were found in CA_CERTS_PATH. For information on ' - 'how to get required certificate files, please visit ' - 'https://libcloud.readthedocs.org/en/latest/other/' - 'ssl-certificate-validation.html' -) - -VERIFY_SSL_DISABLED_MSG = ( - 'SSL certificate verification is disabled, this can pose a ' - 'security risk. For more information how to enable the SSL ' - 'certificate verification, please visit the libcloud ' - 'documentation.' -) http://git-wip-us.apache.org/repos/asf/libcloud/blob/8afcda91/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py ---------------------------------------------------------------------- diff --git a/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py b/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py deleted file mode 100644 index f73ddf0..0000000 --- a/apache-libcloud-1.0.0rc2/libcloud/storage/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -Module for working with Storage -"""
