From d841a23003de976150801a5065c3fce6064391be Mon Sep 17 00:00:00 2001 From: Avi Nanhkoesingh Date: Thu, 19 Feb 2015 14:26:26 +0100 Subject: [PATCH] Adds S2S VPN functionality for CloudStack. --- libcloud/compute/drivers/cloudstack.py | 708 ++++++++++++++++++ .../createVpnConnection_default.json | 5 + .../createVpnCustomerGateway_default.json | 5 + .../cloudstack/createVpnGateway_default.json | 6 + .../deleteVpnConnection_default.json | 1 + .../deleteVpnCustomerGateway_default.json | 5 + .../cloudstack/deleteVpnGateway_default.json | 1 + .../listVpnConnections_default.json | 27 + .../listVpnCustomerGateways_default.json | 22 + .../cloudstack/listVpnGateways_default.json | 15 + ...eryAsyncJobResult_createVpnConnection.json | 35 + ...yncJobResult_createVpnCustomerGateway.json | 30 + .../queryAsyncJobResult_createVpnGateway.json | 23 + ...eryAsyncJobResult_deleteVpnConnection.json | 16 + ...yncJobResult_deleteVpnCustomerGateway.json | 16 + .../queryAsyncJobResult_deleteVpnGateway.json | 16 + libcloud/test/compute/test_cloudstack.py | 87 +++ 17 files changed, 1018 insertions(+) create mode 100644 libcloud/test/compute/fixtures/cloudstack/createVpnConnection_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/createVpnCustomerGateway_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/createVpnGateway_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/deleteVpnConnection_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/deleteVpnCustomerGateway_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/deleteVpnGateway_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/listVpnConnections_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/listVpnCustomerGateways_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/listVpnGateways_default.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnConnection.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnCustomerGateway.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnGateway.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnConnection.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnCustomerGateway.json create mode 100644 libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnGateway.json diff --git a/libcloud/compute/drivers/cloudstack.py b/libcloud/compute/drivers/cloudstack.py index 5f8af352f5..ef3b4d3146 100644 --- a/libcloud/compute/drivers/cloudstack.py +++ b/libcloud/compute/drivers/cloudstack.py @@ -312,6 +312,80 @@ 'key_name': 'secondaryip', 'transform_func': list } + }, + 'vpngateway': { + 'for_display': { + 'key_name': 'fordisplay', + 'transform_func': str + }, + 'project': { + 'key_name': 'project', + 'transform_func': str + }, + 'project_id': { + 'key_name': 'projectid', + 'transform_func': str + }, + 'removed': { + 'key_name': 'removed', + 'transform_func': str + } + }, + 'vpncustomergateway': { + 'account': { + 'key_name': 'account', + 'transform_func': str + }, + 'domain': { + 'key_name': 'domain', + 'transform_func': str + }, + 'domain_id': { + 'key_name': 'domainid', + 'transform_func': str + }, + 'dpd': { + 'key_name': 'dpd', + 'transform_func': bool + }, + 'esp_lifetime': { + 'key_name': 'esplifetime', + 'transform_func': int + }, + 'ike_lifetime': { + 'key_name': 'ikelifetime', + 'transform_func': int + }, + 'name': { + 'key_name': 'name', + 'transform_func': str + } + }, + 'vpnconnection': { + 'account': { + 'key_name': 'account', + 'transform_func': str + }, + 'domain': { + 'key_name': 'domain', + 'transform_func': str + }, + 'domain_id': { + 'key_name': 'domainid', + 'transform_func': str + }, + 'for_display': { + 'key_name': 'fordisplay', + 'transform_func': str + }, + 'project': { + 'key_name': 'project', + 'transform_func': str + }, + 'project_id': { + 'key_name': 'projectid', + 'transform_func': str + } } } @@ -847,6 +921,109 @@ def __repr__(self): self.driver.name)) +class CloudStackVpnGateway(object): + """ + Class representing a CloudStack VPN Gateway. + """ + def __init__(self, id, account, domain, domain_id, + public_ip, vpc_id, driver, extra=None): + self.id = id + self.account = account + self.domain = domain + self.domain_id = domain_id + self.public_ip = public_ip + self.vpc_id = vpc_id + self.driver = driver + self.extra = extra or {} + + @property + def vpc(self): + for vpc in self.ex_list_vpcs(): + if self.vpc_id == vpc.id: + break + else: + raise LibcloudError('VPC with id=%s not found' % self.vpc_id) + + def delete(self): + return self.driver.ex_delete_vpn_gateway(vpn_gateway=self) + + def __repr__(self): + return (('') + % (self.account, self.domain, self.domain_id, + self.id, self.public_ip, self.vpc_id, self.driver.name)) + + +class CloudStackVpnCustomerGateway(object): + """ + Class representing a CloudStack VPN Customer Gateway. + """ + def __init__(self, id, cidr_list, esp_policy, gateway, + ike_policy, ipsec_psk, driver, extra=None): + self.id = id + self.cidr_list = cidr_list + self.esp_policy = esp_policy + self.gateway = gateway + self.ike_policy = ike_policy + self.ipsec_psk = ipsec_psk + self.driver = driver + self.extra = extra or {} + + def delete(self): + return self.driver.ex_delete_vpn_customer_gateway( + vpn_customer_gateway=self) + + def __repr__(self): + return (('') + % (self.id, self.cidr_list, self.esp_policy, self.gateway, + self.ike_policy, self.ipsec_psk, self.driver.name)) + + +class CloudStackVpnConnection(object): + """ + Class representing a CloudStack VPN Connection. + """ + def __init__(self, id, passive, vpn_customer_gateway_id, + vpn_gateway_id, state, driver, extra=None): + self.id = id + self.passive = passive + self.vpn_customer_gateway_id = vpn_customer_gateway_id + self.vpn_gateway_id = vpn_gateway_id + self.state = state + self.driver = driver + self.extra = extra or {} + + @property + def vpn_customer_gateway(self): + try: + return self.driver.ex_list_vpn_customer_gateways( + id=self.vpn_customer_gateway_id)[0] + except IndexError: + raise LibcloudError('VPN Customer Gateway with id=%s not found' % + self.vpn_customer_gateway_id) + + @property + def vpn_gateway(self): + try: + return self.driver.ex_list_vpn_gateways(id=self.vpn_gateway_id)[0] + except IndexError: + raise LibcloudError('VPN Gateway with id=%s not found' % + self.vpn_gateway_id) + + def delete(self): + return self.driver.ex_delete_vpn_connection(vpn_connection=self) + + def __repr__(self): + return (('') + % (self.id, self.passive, self.vpn_customer_gateway_id, + self.vpn_gateway_id, self.state, self.driver.name)) + + class CloudStackRouter(object): """ Class representing a CloudStack Router. @@ -3226,6 +3403,537 @@ def ex_detach_nic_from_node(self, nic, node): return True + def ex_list_vpn_gateways(self, account=None, domain_id=None, + for_display=None, id=None, is_recursive=None, + keyword=None, list_all=None, page=None, + page_size=None, project_id=None, vpc_id=None): + """ + List VPN Gateways. + + :param account: List resources by account (must be + used with the domain_id parameter). + :type account: ``str`` + + :param domain_id: List only resources belonging + to the domain specified. + :type domain_id: ``str`` + + :param for_display: List resources by display flag (only root + admin is eligible to pass this parameter). + :type for_display: ``bool`` + + :param id: ID of the VPN Gateway. + :type id: ``str`` + + :param is_recursive: Defaults to False, but if true, lists all + resources from the parent specified by the + domain ID till leaves. + :type is_recursive: ``bool`` + + :param keyword: List by keyword. + :type keyword: ``str`` + + :param list_all: If set to False, list only resources belonging to + the command's caller; if set to True - list + resources that the caller is authorized to see. + Default value is False. + :type list_all: ``str`` + + :param page: Start from page. + :type page: ``int`` + + :param page_size: Items per page. + :type page_size: ``int`` + + :param project_id: List objects by project. + :type project_id: ``str`` + + :param vpc_id: List objects by VPC. + :type vpc_id: ``str`` + + :rtype: ``list`` of :class:`CloudStackVpnGateway` + """ + args = {} + + if account is not None: + args['account'] = account + + if domain_id is not None: + args['domainid'] = domain_id + + if for_display is not None: + args['fordisplay'] = for_display + + if id is not None: + args['id'] = id + + if is_recursive is not None: + args['isrecursive'] = is_recursive + + if keyword is not None: + args['keyword'] = keyword + + if list_all is not None: + args['listall'] = list_all + + if page is not None: + args['page'] = page + + if page_size is not None: + args['pagesize'] = page_size + + if project_id is not None: + args['projectid'] = project_id + + if vpc_id is not None: + args['vpcid'] = vpc_id + + res = self._sync_request(command='listVpnGateways', + params=args, + method='GET') + + items = res.get('vpngateway', []) + vpn_gateways = [] + extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['vpngateway'] + + for item in items: + extra = self._get_extra_dict(item, extra_map) + + vpn_gateways.append(CloudStackVpnGateway( + id=item['id'], + account=item['account'], + domain=item['domain'], + domain_id=item['domainid'], + public_ip=item['publicip'], + vpc_id=item['vpcid'], + driver=self, + extra=extra)) + + return vpn_gateways + + def ex_create_vpn_gateway(self, vpc, for_display=None): + """ + Creates a VPN Gateway. + + :param vpc: VPC to create the Gateway for (required). + :type vpc: :class: `CloudStackVPC` + + :param for_display: Display the VPC to the end user or not. + :type for_display: ``bool`` + + :rtype: :class: `CloudStackVpnGateway` + """ + args = { + 'vpcid': vpc.id, + } + + if for_display is not None: + args['fordisplay'] = for_display + + res = self._async_request(command='createVpnGateway', + params=args, + method='GET') + + item = res['vpngateway'] + extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['vpngateway'] + + return CloudStackVpnGateway(id=item['id'], + account=item['account'], + domain=item['domain'], + domain_id=item['domainid'], + public_ip=item['publicip'], + vpc_id=vpc.id, + driver=self, + extra=self._get_extra_dict(item, + extra_map)) + + def ex_delete_vpn_gateway(self, vpn_gateway): + """ + Deletes a VPN Gateway. + + :param vpn_gateway: The VPN Gateway (required). + :type vpn_gateway: :class:`CloudStackVpnGateway` + + :rtype: ``bool`` + """ + res = self._async_request(command='deleteVpnGateway', + params={'id': vpn_gateway.id}, + method='GET') + + return res['success'] + + def ex_list_vpn_customer_gateways(self, account=None, domain_id=None, + id=None, is_recursive=None, + keyword=None, list_all=None, + page=None, page_size=None, + project_id=None): + """ + List VPN Customer Gateways. + + :param account: List resources by account (must be + used with the domain_id parameter). + :type account: ``str`` + + :param domain_id: List only resources belonging + to the domain specified. + :type domain_id: ``str`` + + :param id: ID of the VPN Customer Gateway. + :type id: ``str`` + + :param is_recursive: Defaults to False, but if true, lists all + resources from the parent specified by the + domain_id till leaves. + :type is_recursive: ``bool`` + + :param keyword: List by keyword. + :type keyword: ``str`` + + :param list_all: If set to False, list only resources belonging to + the command's caller; if set to True - list + resources that the caller is authorized to see. + Default value is False. + :type list_all: ``str`` + + :param page: Start from page. + :type page: ``int`` + + :param page_size: Items per page. + :type page_size: ``int`` + + :param project_id: List objects by project. + :type project_id: ``str`` + + :rtype: ``list`` of :class:`CloudStackVpnCustomerGateway` + """ + args = {} + + if account is not None: + args['account'] = account + + if domain_id is not None: + args['domainid'] = domain_id + + if id is not None: + args['id'] = id + + if is_recursive is not None: + args['isrecursive'] = is_recursive + + if keyword is not None: + args['keyword'] = keyword + + if list_all is not None: + args['listall'] = list_all + + if page is not None: + args['page'] = page + + if page_size is not None: + args['pagesize'] = page_size + + if project_id is not None: + args['projectid'] = project_id + + res = self._sync_request(command='listVpnCustomerGateways', + params=args, + method='GET') + + items = res.get('vpncustomergateway', []) + vpn_customer_gateways = [] + extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['vpncustomergateway'] + + for item in items: + extra = self._get_extra_dict(item, extra_map) + + vpn_customer_gateways.append(CloudStackVpnCustomerGateway( + id=item['id'], + cidr_list=item['cidrlist'], + esp_policy=item['esppolicy'], + gateway=item['gateway'], + ike_policy=item['ikepolicy'], + ipsec_psk=item['ipsecpsk'], + driver=self, + extra=extra)) + + return vpn_customer_gateways + + def ex_create_vpn_customer_gateway(self, cidr_list, esp_policy, gateway, + ike_policy, ipsec_psk, account=None, + domain_id=None, dpd=None, + esp_lifetime=None, ike_lifetime=None, + name=None): + """ + Creates a VPN Customer Gateway. + + :param cidr_list: Guest CIDR list of the Customer Gateway (required). + :type cidr_list: ``str`` + + :param esp_policy: ESP policy of the Customer Gateway (required). + :type esp_policy: ``str`` + + :param gateway: Public IP address of the Customer Gateway (required). + :type gateway: ``str`` + + :param ike_policy: IKE policy of the Customer Gateway (required). + :type ike_policy: ``str`` + + :param ipsec_psk: IPsec preshared-key of the Customer Gateway + (required). + :type ipsec_psk: ``str`` + + :param account: The associated account with the Customer Gateway + (must be used with the domain_id param). + :type account: ``str`` + + :param domain_id: The domain ID associated with the Customer Gateway. + If used with the account parameter returns the + gateway associated with the account for the + specified domain. + :type domain_id: ``str`` + + :param dpd: If DPD is enabled for the VPN connection. + :type dpd: ``bool`` + + :param esp_lifetime: Lifetime of phase 2 VPN connection to the + Customer Gateway, in seconds. + :type esp_lifetime: ``int`` + + :param ike_lifetime: Lifetime of phase 1 VPN connection to the + Customer Gateway, in seconds. + :type ike_lifetime: ``int`` + + :param name: Name of the Customer Gateway. + :type name: ``str`` + + :rtype: :class: `CloudStackVpnCustomerGateway` + """ + args = { + 'cidrlist': cidr_list, + 'esppolicy': esp_policy, + 'gateway': gateway, + 'ikepolicy': ike_policy, + 'ipsecpsk': ipsec_psk + } + + if account is not None: + args['account'] = account + + if domain_id is not None: + args['domainid'] = domain_id + + if dpd is not None: + args['dpd'] = dpd + + if esp_lifetime is not None: + args['esplifetime'] = esp_lifetime + + if ike_lifetime is not None: + args['ikelifetime'] = ike_lifetime + + if name is not None: + args['name'] = name + + res = self._async_request(command='createVpnCustomerGateway', + params=args, + method='GET') + + item = res['vpncustomergateway'] + extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['vpncustomergateway'] + + return CloudStackVpnCustomerGateway(id=item['id'], + cidr_list=cidr_list, + esp_policy=esp_policy, + gateway=gateway, + ike_policy=ike_policy, + ipsec_psk=ipsec_psk, + driver=self, + extra=self._get_extra_dict( + item, extra_map)) + + def ex_delete_vpn_customer_gateway(self, vpn_customer_gateway): + """ + Deletes a VPN Customer Gateway. + + :param vpn_customer_gateway: The VPN Customer Gateway (required). + :type vpn_customer_gateway: :class:`CloudStackVpnCustomerGateway` + + :rtype: ``bool`` + """ + res = self._async_request(command='deleteVpnCustomerGateway', + params={'id': vpn_customer_gateway.id}, + method='GET') + + return res['success'] + + def ex_list_vpn_connections(self, account=None, domain_id=None, + for_display=None, id=None, is_recursive=None, + keyword=None, list_all=None, page=None, + page_size=None, project_id=None, vpc_id=None): + """ + List VPN Connections. + + :param account: List resources by account (must be + used with the domain_id parameter). + :type account: ``str`` + + :param domain_id: List only resources belonging + to the domain specified. + :type domain_id: ``str`` + + :param for_display: List resources by display flag (only root + admin is eligible to pass this parameter). + :type for_display: ``bool`` + + :param id: ID of the VPN Connection. + :type id: ``str`` + + :param is_recursive: Defaults to False, but if true, lists all + resources from the parent specified by the + domain_id till leaves. + :type is_recursive: ``bool`` + + :param keyword: List by keyword. + :type keyword: ``str`` + + :param list_all: If set to False, list only resources belonging to + the command's caller; if set to True - list + resources that the caller is authorized to see. + Default value is False. + :type list_all: ``str`` + + :param page: Start from page. + :type page: ``int`` + + :param page_size: Items per page. + :type page_size: ``int`` + + :param project_id: List objects by project. + :type project_id: ``str`` + + :param vpc_id: List objects by VPC. + :type vpc_id: ``str`` + + :rtype: ``list`` of :class:`CloudStackVpnConnection` + """ + args = {} + + if account is not None: + args['account'] = account + + if domain_id is not None: + args['domainid'] = domain_id + + if for_display is not None: + args['fordisplay'] = for_display + + if id is not None: + args['id'] = id + + if is_recursive is not None: + args['isrecursive'] = is_recursive + + if keyword is not None: + args['keyword'] = keyword + + if list_all is not None: + args['listall'] = list_all + + if page is not None: + args['page'] = page + + if page_size is not None: + args['pagesize'] = page_size + + if project_id is not None: + args['projectid'] = project_id + + if vpc_id is not None: + args['vpcid'] = vpc_id + + res = self._sync_request(command='listVpnConnections', + params=args, + method='GET') + + items = res.get('vpnconnection', []) + vpn_connections = [] + extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['vpnconnection'] + + for item in items: + extra = self._get_extra_dict(item, extra_map) + + vpn_connections.append(CloudStackVpnConnection( + id=item['id'], + passive=item['passive'], + vpn_customer_gateway_id=item['s2scustomergatewayid'], + vpn_gateway_id=item['s2svpngatewayid'], + state=item['state'], + driver=self, + extra=extra)) + + return vpn_connections + + def ex_create_vpn_connection(self, vpn_customer_gateway, vpn_gateway, + for_display=None, passive=None): + """ + Creates a VPN Connection. + + :param vpn_customer_gateway: The VPN Customer Gateway (required). + :type vpn_customer_gateway: :class:`CloudStackVpnCustomerGateway` + + :param vpn_gateway: The VPN Gateway (required). + :type vpn_gateway: :class:`CloudStackVpnGateway` + + :param for_display: Display the Connection to the end user or not. + :type for_display: ``str`` + + :param passive: If True, sets the connection to be passive. + :type passive: ``bool`` + + :rtype: :class: `CloudStackVpnConnection` + """ + args = { + 's2scustomergatewayid': vpn_customer_gateway.id, + 's2svpngatewayid': vpn_gateway.id, + } + + if for_display is not None: + args['fordisplay'] = for_display + + if passive is not None: + args['passive'] = passive + + res = self._async_request(command='createVpnConnection', + params=args, + method='GET') + + item = res['vpnconnection'] + extra_map = RESOURCE_EXTRA_ATTRIBUTES_MAP['vpnconnection'] + + return CloudStackVpnConnection( + id=item['id'], + passive=item['passive'], + vpn_customer_gateway_id=vpn_customer_gateway.id, + vpn_gateway_id=vpn_gateway.id, + state=item['state'], + driver=self, + extra=self._get_extra_dict(item, extra_map)) + + def ex_delete_vpn_connection(self, vpn_connection): + """ + Deletes a VPN Connection. + + :param vpn_connection: The VPN Connection (required). + :type vpn_connection: :class:`CloudStackVpnConnection` + + :rtype: ``bool`` + """ + res = self._async_request(command='deleteVpnConnection', + params={'id': vpn_connection.id}, + method='GET') + + return res['success'] + def _to_snapshot(self, data): """ Create snapshot object from data diff --git a/libcloud/test/compute/fixtures/cloudstack/createVpnConnection_default.json b/libcloud/test/compute/fixtures/cloudstack/createVpnConnection_default.json new file mode 100644 index 0000000000..500528eda6 --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/createVpnConnection_default.json @@ -0,0 +1,5 @@ +{ + "createvpnconnectionresponse" : { + "jobid" : "createVpnConnection" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/createVpnCustomerGateway_default.json b/libcloud/test/compute/fixtures/cloudstack/createVpnCustomerGateway_default.json new file mode 100644 index 0000000000..5129ac9b0c --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/createVpnCustomerGateway_default.json @@ -0,0 +1,5 @@ +{ + "createvpncustomergatewayresponse" : { + "jobid" : "createVpnCustomerGateway" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/createVpnGateway_default.json b/libcloud/test/compute/fixtures/cloudstack/createVpnGateway_default.json new file mode 100644 index 0000000000..81d220b5ec --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/createVpnGateway_default.json @@ -0,0 +1,6 @@ +{ + "createvpngatewayresponse": { + "id": "5ef6794e-cec8-4018-9fef-c4dacbadee14", + "jobid": "createVpnGateway" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/deleteVpnConnection_default.json b/libcloud/test/compute/fixtures/cloudstack/deleteVpnConnection_default.json new file mode 100644 index 0000000000..e38a797436 --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/deleteVpnConnection_default.json @@ -0,0 +1 @@ +{ "deletevpnconnectionresponse" : {"jobid":"deleteVpnConnection"} } diff --git a/libcloud/test/compute/fixtures/cloudstack/deleteVpnCustomerGateway_default.json b/libcloud/test/compute/fixtures/cloudstack/deleteVpnCustomerGateway_default.json new file mode 100644 index 0000000000..57687153b0 --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/deleteVpnCustomerGateway_default.json @@ -0,0 +1,5 @@ +{ + "deletevpncustomergatewayresponse" : { + "jobid" : "deleteVpnCustomerGateway" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/deleteVpnGateway_default.json b/libcloud/test/compute/fixtures/cloudstack/deleteVpnGateway_default.json new file mode 100644 index 0000000000..5f7ed1a0d5 --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/deleteVpnGateway_default.json @@ -0,0 +1 @@ +{ "deletevpngatewayresponse" : {"jobid":"deleteVpnGateway"} } diff --git a/libcloud/test/compute/fixtures/cloudstack/listVpnConnections_default.json b/libcloud/test/compute/fixtures/cloudstack/listVpnConnections_default.json new file mode 100644 index 0000000000..1d099d90eb --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/listVpnConnections_default.json @@ -0,0 +1,27 @@ +{ + "listvpnconnectionsresponse": { + "count": 1, + "vpnconnection": [ + { + "account": "some_admin", + "cidrlist": "10.2.2.0/24", + "created": "2015-02-20T13:32:58+0100", + "domain": "some_domain", + "domainid": "9b397dea-25ef-4c5d-b47d-627eaebe8ed8", + "dpd": false, + "esplifetime": 3600, + "esppolicy": "3des-md5", + "gateway": "10.2.2.1", + "id": "8f482d9a-6cee-453b-9e78-b0e1338ffce9", + "ikelifetime": 86400, + "ikepolicy": "3des-md5", + "ipsecpsk": "xxx", + "passive": false, + "publicip": "1.2.3.4", + "s2scustomergatewayid": "ea67eaae-1c2a-4e65-b910-441e77f69bea", + "s2svpngatewayid": "cffa0cab-d1da-42a7-92f6-41379267a29f", + "state": "Connected" + } + ] + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/listVpnCustomerGateways_default.json b/libcloud/test/compute/fixtures/cloudstack/listVpnCustomerGateways_default.json new file mode 100644 index 0000000000..58aaecad7d --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/listVpnCustomerGateways_default.json @@ -0,0 +1,22 @@ +{ + "listvpncustomergatewaysresponse": { + "count": 1, + "vpncustomergateway": [ + { + "account": "some_account", + "cidrlist": "10.2.2.0/24", + "domain": "some_domain", + "domainid": "9b397dea-25ef-4c5d-b47d-627eaebe8ed8", + "dpd": false, + "esplifetime": 3600, + "esppolicy": "3des-md5", + "gateway": "10.2.2.1", + "id": "ea67eaae-1c2a-4e65-b910-441e77f69bea", + "ikelifetime": 86400, + "ikepolicy": "3des-md5", + "ipsecpsk": "some_psk", + "name": "some_name" + } + ] + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/listVpnGateways_default.json b/libcloud/test/compute/fixtures/cloudstack/listVpnGateways_default.json new file mode 100644 index 0000000000..33d81165d4 --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/listVpnGateways_default.json @@ -0,0 +1,15 @@ +{ + "listvpngatewaysresponse": { + "count": 1, + "vpngateway": [ + { + "account": "some_account", + "domain": "some_domain", + "domainid": "9b397dea-25ef-4c5d-b47d-627eaebe8ed8", + "id": "cffa0cab-d1da-42a7-92f6-41379267a29f", + "publicip": "1.2.3.4", + "vpcid": "4d25e181-8850-4d52-8ecb-a6f35bbbabde" + } + ] + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnConnection.json b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnConnection.json new file mode 100644 index 0000000000..f156b185ac --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnConnection.json @@ -0,0 +1,35 @@ +{ + "queryasyncjobresultresponse" : { + "cmd" : "org.apache.cloudstack.api.command.user.vpn.CreateVpnConnectionCmd", + "jobid" : "createVpnConnection", + "userid" : "user_id", + "accountid" : "account_id", + "jobprocstatus" : 0, + "created" : "2015-02-23T08:36:09+0100", + "jobstatus" : 1, + "jobresult" : { + "vpnconnection" : { + "esplifetime" : 3600, + "cidrlist" : "10.0.0.0/24", + "gateway" : "10.0.0.1", + "ikelifetime" : 86400, + "state" : "Connected", + "ikepolicy" : "3des-md5", + "domain" : "domain", + "dpd" : false, + "id" : "f45c3af8-f909-4f16-9d40-ed4409c575f8", + "s2svpngatewayid" : "515aefbc-448b-484b-8d6a-ff3b67637bf1", + "s2scustomergatewayid" : "201fc1d1-05e1-4e9c-a025-d72e954dd856", + "account" : "account", + "domainid" : "domain_id", + "esppolicy" : "3des-md5", + "created" : "2015-02-23T08:36:09+0100", + "passive" : false, + "ipsecpsk" : "ipsecpsk", + "publicip" : "1.2.3.4" + } + }, + "jobresultcode" : 0, + "jobresulttype" : "object" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnCustomerGateway.json b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnCustomerGateway.json new file mode 100644 index 0000000000..1746885ae1 --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnCustomerGateway.json @@ -0,0 +1,30 @@ +{ + "queryasyncjobresultresponse" : { + "cmd" : "org.apache.cloudstack.api.command.user.vpn.CreateVpnCustomerGatewayCmd", + "jobid" : "createVpnCustomerGateway", + "userid" : "user_id", + "accountid" : "account_id", + "jobprocstatus" : 0, + "created" : "2015-02-23T08:25:01+0100", + "jobstatus" : 1, + "jobresult" : { + "vpncustomergateway" : { + "esplifetime" : 3600, + "cidrlist" : "10.0.0.0/24", + "account" : "account", + "gateway" : "10.0.0.1", + "ikelifetime" : 86400, + "name" : "VPN-10.0.0.1", + "domainid" : "domain_id", + "esppolicy" : "3des-md5", + "ikepolicy" : "3des-md5", + "domain" : "domain", + "dpd" : false, + "id" : "cef3c766-116a-4e83-9844-7d08ab7d3fd4", + "ipsecpsk" : "ipsecpsk" + } + }, + "jobresultcode" : 0, + "jobresulttype" : "object" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnGateway.json b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnGateway.json new file mode 100644 index 0000000000..b695cbd79a --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_createVpnGateway.json @@ -0,0 +1,23 @@ +{ + "queryasyncjobresultresponse" : { + "cmd" : "org.apache.cloudstack.api.command.user.vpn.CreateVpnGatewayCmd", + "jobid" : "b26272a4-f5e4-4ebe-a7d3-eaaf3ec8280c", + "userid" : "2f517f5b-cac9-48b5-aafc-e9d7ca879784", + "accountid" : "4009e75e-5311-43f2-bc92-b92676455eed", + "jobprocstatus" : 0, + "created" : "2015-02-20T15:53:54+0100", + "jobstatus" : 1, + "jobresult" : { + "vpngateway" : { + "domain" : "some_domain", + "vpcid" : "4d25e181-8850-4d52-8ecb-a6f35bbbabde", + "account" : "some_account", + "domainid" : "9b397dea-25ef-4c5d-b47d-627eaebe8ed8", + "id" : "5ef6794e-cec8-4018-9fef-c4dacbadee14", + "publicip" : "2.3.4.5" + } + }, + "jobresultcode" : 0, + "jobresulttype" : "object" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnConnection.json b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnConnection.json new file mode 100644 index 0000000000..9e4baa9d8e --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnConnection.json @@ -0,0 +1,16 @@ +{ + "queryasyncjobresultresponse" : { + "cmd" : "org.apache.cloudstack.api.command.user.vpn.DeleteVpnConnectionCmd", + "jobid" : "deleteVpnConnection", + "userid" : "user_id", + "accountid" : "account_id", + "jobprocstatus" : 0, + "created" : "2015-02-23T08:17:41+0100", + "jobstatus" : 1, + "jobresult" : { + "success" : true + }, + "jobresultcode" : 0, + "jobresulttype" : "object" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnCustomerGateway.json b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnCustomerGateway.json new file mode 100644 index 0000000000..e8f5628cad --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnCustomerGateway.json @@ -0,0 +1,16 @@ +{ + "queryasyncjobresultresponse" : { + "cmd" : "org.apache.cloudstack.api.command.user.vpn.DeleteVpnCustomerGatewayCmd", + "jobid" : "deleteVpnCustomerGateway", + "userid" : "user_id", + "accountid" : "account_id", + "jobprocstatus" : 0, + "created" : "2015-02-23T08:20:47+0100", + "jobstatus" : 1, + "jobresult" : { + "success" : true + }, + "jobresultcode" : 0, + "jobresulttype" : "object" + } +} diff --git a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnGateway.json b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnGateway.json new file mode 100644 index 0000000000..93feb0a9cf --- /dev/null +++ b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_deleteVpnGateway.json @@ -0,0 +1,16 @@ +{ + "queryasyncjobresultresponse": { + "accountid": "4009e75e-5311-43f2-bc92-b92676455eed", + "cmd": "org.apache.cloudstack.api.command.user.vpn.DeleteVpnGatewayCmd", + "created": "2015-02-20T16:32:40+0100", + "jobid": "0648122e-fb16-495b-96d0-86e16b742557", + "jobprocstatus": 0, + "jobresult": { + "success": true + }, + "jobresultcode": 0, + "jobresulttype": "object", + "jobstatus": 1, + "userid": "2f517f5b-cac9-48b5-aafc-e9d7ca879784" + } +} diff --git a/libcloud/test/compute/test_cloudstack.py b/libcloud/test/compute/test_cloudstack.py index 413bdcd441..5726a7502e 100644 --- a/libcloud/test/compute/test_cloudstack.py +++ b/libcloud/test/compute/test_cloudstack.py @@ -992,6 +992,93 @@ def test_ex_list_os_types(self): self.assertEqual(os_types[0]['oscategoryid'], 7) self.assertEqual(os_types[0]['description'], "Asianux 3(32-bit)") + def test_ex_list_vpn_gateways(self): + vpn_gateways = self.driver.ex_list_vpn_gateways() + + self.assertEqual(len(vpn_gateways), 1) + + self.assertEqual(vpn_gateways[0].id, 'cffa0cab-d1da-42a7-92f6-41379267a29f') + self.assertEqual(vpn_gateways[0].account, 'some_account') + self.assertEqual(vpn_gateways[0].domain, 'some_domain') + self.assertEqual(vpn_gateways[0].domain_id, '9b397dea-25ef-4c5d-b47d-627eaebe8ed8') + self.assertEqual(vpn_gateways[0].public_ip, '1.2.3.4') + self.assertEqual(vpn_gateways[0].vpc_id, '4d25e181-8850-4d52-8ecb-a6f35bbbabde') + + def test_ex_create_vpn_gateway(self): + vpc = self.driver.ex_list_vpcs()[0] + + vpn_gateway = self.driver.ex_create_vpn_gateway(vpc) + + self.assertEqual(vpn_gateway.id, '5ef6794e-cec8-4018-9fef-c4dacbadee14') + self.assertEqual(vpn_gateway.account, 'some_account') + self.assertEqual(vpn_gateway.domain, 'some_domain') + self.assertEqual(vpn_gateway.domain_id, '9b397dea-25ef-4c5d-b47d-627eaebe8ed8') + self.assertEqual(vpn_gateway.public_ip, '2.3.4.5') + self.assertEqual(vpn_gateway.vpc_id, vpc.id) + + def test_ex_delete_vpn_gateway(self): + vpn_gateway = self.driver.ex_list_vpn_gateways()[0] + self.assertTrue(vpn_gateway.delete()) + + def test_ex_list_vpn_customer_gateways(self): + vpn_customer_gateways = self.driver.ex_list_vpn_customer_gateways() + + self.assertEqual(len(vpn_customer_gateways), 1) + + self.assertEqual(vpn_customer_gateways[0].id, 'ea67eaae-1c2a-4e65-b910-441e77f69bea') + self.assertEqual(vpn_customer_gateways[0].cidr_list, '10.2.2.0/24') + self.assertEqual(vpn_customer_gateways[0].esp_policy, '3des-md5') + self.assertEqual(vpn_customer_gateways[0].gateway, '10.2.2.1') + self.assertEqual(vpn_customer_gateways[0].ike_policy, '3des-md5') + self.assertEqual(vpn_customer_gateways[0].ipsec_psk, 'some_psk') + + def test_ex_create_vpn_customer_gateway(self): + vpn_customer_gateway = self.driver.ex_create_vpn_customer_gateway( + cidr_list='10.0.0.0/24', + esp_policy='3des-md5', + gateway='10.0.0.1', + ike_policy='3des-md5', + ipsec_psk='ipsecpsk') + + self.assertEqual(vpn_customer_gateway.id, 'cef3c766-116a-4e83-9844-7d08ab7d3fd4') + self.assertEqual(vpn_customer_gateway.esp_policy, '3des-md5') + self.assertEqual(vpn_customer_gateway.gateway, '10.0.0.1') + self.assertEqual(vpn_customer_gateway.ike_policy, '3des-md5') + self.assertEqual(vpn_customer_gateway.ipsec_psk, 'ipsecpsk') + + def test_ex_ex_delete_vpn_customer_gateway(self): + vpn_customer_gateway = self.driver.ex_list_vpn_customer_gateways()[0] + self.assertTrue(vpn_customer_gateway.delete()) + + def test_ex_list_vpn_connections(self): + vpn_connections = self.driver.ex_list_vpn_connections() + + self.assertEqual(len(vpn_connections), 1) + + self.assertEqual(vpn_connections[0].id, '8f482d9a-6cee-453b-9e78-b0e1338ffce9') + self.assertEqual(vpn_connections[0].passive, False) + self.assertEqual(vpn_connections[0].vpn_customer_gateway_id, 'ea67eaae-1c2a-4e65-b910-441e77f69bea') + self.assertEqual(vpn_connections[0].vpn_gateway_id, 'cffa0cab-d1da-42a7-92f6-41379267a29f') + self.assertEqual(vpn_connections[0].state, 'Connected') + + def test_ex_create_vpn_connection(self): + vpn_customer_gateway = self.driver.ex_list_vpn_customer_gateways()[0] + vpn_gateway = self.driver.ex_list_vpn_gateways()[0] + + vpn_connection = self.driver.ex_create_vpn_connection( + vpn_customer_gateway, + vpn_gateway) + + self.assertEqual(vpn_connection.id, 'f45c3af8-f909-4f16-9d40-ed4409c575f8') + self.assertEqual(vpn_connection.passive, False) + self.assertEqual(vpn_connection.vpn_customer_gateway_id, 'ea67eaae-1c2a-4e65-b910-441e77f69bea') + self.assertEqual(vpn_connection.vpn_gateway_id, 'cffa0cab-d1da-42a7-92f6-41379267a29f') + self.assertEqual(vpn_connection.state, 'Connected') + + def test_ex_delete_vpn_connection(self): + vpn_connection = self.driver.ex_list_vpn_connections()[0] + self.assertTrue(vpn_connection.delete()) + class CloudStackTestCase(CloudStackCommonTestCase, unittest.TestCase): def test_driver_instantiation(self):