Added support for expanding a VM's disk. Added a get snapshot using snapshot id. Removed 'dd' prefix from locations in nttcis module under common.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/d4ae1aba Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/d4ae1aba Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/d4ae1aba Branch: refs/heads/trunk Commit: d4ae1ababf549bf88b4971fad4eff733d2d711f0 Parents: f63a13d Author: mitch <[email protected]> Authored: Wed Sep 26 13:21:26 2018 -0400 Committer: mitch <[email protected]> Committed: Wed Sep 26 13:27:05 2018 -0400 ---------------------------------------------------------------------- libcloud/common/nttcis.py | 47 ++++++++++----------- libcloud/compute/drivers/nttcis.py | 67 ++++++++++++++++++----------- tests/conftest.py | 9 +++- tests/lib_create_test.py | 18 +++++++- tests/lib_edit_test.py | 74 ++++++++++++++++++++++++++++++++- tests/lib_list_test.py | 11 +++++ 6 files changed, 174 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/d4ae1aba/libcloud/common/nttcis.py ---------------------------------------------------------------------- diff --git a/libcloud/common/nttcis.py b/libcloud/common/nttcis.py index 75bd875..d58e2d3 100644 --- a/libcloud/common/nttcis.py +++ b/libcloud/common/nttcis.py @@ -33,7 +33,7 @@ from keyword import iskeyword # # 1.0 - Copied from OpSource API, named provider details. -# setup a few variables to represent all of the DimensionData cloud namespaces +# setup a few variables to represent all of the NTTC-CIS cloud namespaces NAMESPACE_BASE = "http://oec.api.opsource.net/schemas" ORGANIZATION_NS = NAMESPACE_BASE + "/organization" SERVER_NS = NAMESPACE_BASE + "/server" @@ -47,45 +47,40 @@ TYPES_URN = "urn:didata.com:api:cloud:types" # API end-points API_ENDPOINTS = { - 'dd-na': { + 'na': { 'name': 'North America (NA)', 'host': 'api-na.dimensiondata.com', - 'vendor': 'DimensionData' + 'vendor': 'NTTC-CIS' }, - 'dd-eu': { + 'eu': { 'name': 'Europe (EU)', 'host': 'api-eu.dimensiondata.com', - 'vendor': 'DimensionData' + 'vendor': 'NTTC-CIS' }, - 'dd-au': { + 'au': { 'name': 'Australia (AU)', 'host': 'api-au.dimensiondata.com', - 'vendor': 'DimensionData' + 'vendor': 'NTTC-CIS' }, - 'dd-au-gov': { + 'au-gov': { 'name': 'Australia Canberra ACT (AU)', 'host': 'api-canberra.dimensiondata.com', - 'vendor': 'DimensionData' + 'vendor': 'NTTC-CIS' }, - 'dd-af': { + 'af': { 'name': 'Africa (AF)', 'host': 'api-mea.dimensiondata.com', - 'vendor': 'DimensionData' + 'vendor': 'NTTC-CIS' }, - 'dd-ap': { + 'ap': { 'name': 'Asia Pacific (AP)', 'host': 'api-ap.dimensiondata.com', - 'vendor': 'DimensionData' + 'vendor': 'NTTC-CIS' }, - 'dd-latam': { - 'name': 'South America (LATAM)', - 'host': 'api-latam.dimensiondata.com', - 'vendor': 'DimensionData' - }, - 'dd-canada': { + 'canada': { 'name': 'Canada (CA)', 'host': 'api-canada.dimensiondata.com', - 'vendor': 'DimensionData' + 'vendor': 'NTTC-CIS' }, 'is-na': { 'name': 'North America (NA)', @@ -617,7 +612,7 @@ class NttCisConnection(ConnectionUserAndKey): def _get_orgId(self): """ - Send the /myaccount API request to DimensionData cloud and parse the + Send the /myaccount API request to NTTC-CIS cloud and parse the 'orgId' from the XML response object. We need the orgId to use most of the other API functions """ @@ -1692,8 +1687,8 @@ class NttCisTagKey(object): self.display_on_report = display_on_report def __repr__(self): - return (('NttCisTagKey: name=%s>') - % (self.name)) + return (('NttCisTagKey: id=%s name=%s>') + % (self.id, self.name)) class NttCisFactory(object): @@ -2034,4 +2029,8 @@ class Generic: def __repr__(self): values = ','.join("{}={!r}".format(k, v) for k,v in self.__data.items()) - return values \ No newline at end of file + return values + + +def cloud_factory(from_dict: dict): + pass http://git-wip-us.apache.org/repos/asf/libcloud/blob/d4ae1aba/libcloud/compute/drivers/nttcis.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/nttcis.py b/libcloud/compute/drivers/nttcis.py index 61a9815..bce144f 100644 --- a/libcloud/compute/drivers/nttcis.py +++ b/libcloud/compute/drivers/nttcis.py @@ -296,7 +296,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = False >>> DimensionData = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -331,7 +331,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -1306,6 +1306,12 @@ class NttCisNodeDriver(NodeDriver): 'snapshot/snapshot', params=params).object) + def get_snapshot(self, snapshot_id: str) -> list: + return self._to_snapshot(self.connection.request_with_orgId_api_2( + 'snapshot/snapshot/%s' % snapshot_id).object) + + + def ex_disable_snapshots(self, node: str) -> bool: update_node = ET.Element('disableSnapshotService', {'xmlns': TYPES_URN}) @@ -1346,6 +1352,9 @@ class NttCisNodeDriver(NodeDriver): response_code = findtext(result, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'OK'] + def ex_create_snapshot_preview_server(self, ): + pass + def ex_create_anti_affinity_rule(self, node_list): """ Edited to work with api 2.x. No longer supports 1.0 @@ -2306,7 +2315,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -2844,7 +2853,7 @@ class NttCisNodeDriver(NodeDriver): response_code = findtext(result, 'responseCode', TYPES_URN) return response_code in ['IN_PROGRESS', 'SUCCESS'] - def ex_change_storage_size(self, node, disk_id, size): + def ex_change_storage_size(self, disk_id, size): """ Change the size of a disk @@ -2859,15 +2868,23 @@ class NttCisNodeDriver(NodeDriver): :rtype: ``bool`` """ - create_node = ET.Element('ChangeDiskSize', {'xmlns': SERVER_NS}) + create_node = ET.Element('expandDisk', {'xmlns': TYPES_URN, + 'id': disk_id}) ET.SubElement(create_node, 'newSizeGb').text = str(size) + ''' + This code is for version 1 of MCP, need version 2 result = self.connection.request_with_orgId_api_1( 'server/%s/disk/%s/changeSize' % (node.id, disk_id), method='POST', data=ET.tostring(create_node)).object - response_code = findtext(result, 'result', GENERAL_NS) - return response_code in ['IN_PROGRESS', 'SUCCESS'] + ''' + result = self.connection.request_with_orgId_api_2( + 'server/expandDisk', + method='POST', + data=ET.tostring(create_node)).object + response_code = findtext(result, 'responseCode', TYPES_URN) + return response_code in ['IN_PROGRESS', 'OK'] def ex_reconfigure_node(self, node, memory_gb=None, cpu_count=None, cores_per_socket=None, cpu_performance=None): @@ -3022,7 +3039,7 @@ class NttCisNodeDriver(NodeDriver): def ex_get_base_image_by_id(self, id): """ - Gets a Base image in the Dimension Data Cloud given the id + Gets a Base image in the NTTC-CIS Cloud given the id :param id: The id of the image :type id: ``str`` @@ -3035,7 +3052,7 @@ class NttCisNodeDriver(NodeDriver): def ex_get_customer_image_by_id(self, id): """ - Gets a Customer image in the Dimension Data Cloud given the id + Gets a Customer image in the NTTC-CIS Cloud given the id :param id: The id of the image :type id: ``str`` @@ -3048,7 +3065,7 @@ class NttCisNodeDriver(NodeDriver): def ex_get_image_by_id(self, id): """ - Gets a Base/Customer image in the Dimension Data Cloud given the id + Gets a Base/Customer image in the NTTC-CIS Cloud given the id Note: This first checks the base image If it is not a base image we check if it is a customer image @@ -3070,7 +3087,7 @@ class NttCisNodeDriver(NodeDriver): def ex_create_tag_key(self, name, description=None, value_required=True, display_on_report=True): """ - Creates a tag key in the Dimension Data Cloud + Creates a tag key in the NTTC-CIS Cloud :param name: The name of the tag key (required) :type name: ``str`` @@ -3106,7 +3123,7 @@ class NttCisNodeDriver(NodeDriver): def ex_list_tag_keys(self, id=None, name=None, value_required=None, display_on_report=None): """ - List tag keys in the Dimension Data Cloud + List tag keys in the NTTC-CIS Cloud :param id: Filter the list to the id of the tag key :type id: ``str`` @@ -3160,6 +3177,8 @@ class NttCisNodeDriver(NodeDriver): def ex_get_tag_key_by_name(self, name): """ + NOTICE: Tag key is one of those instances where Libloud handles the search of a list for the client code. + This behavior exists inconsistently across libcloud. Get a specific tag key by Name :param name: Name of the tag key you want (required) @@ -3239,7 +3258,7 @@ class NttCisNodeDriver(NodeDriver): def ex_apply_tag_to_asset(self, asset, tag_key, value=None): """ - Apply a tag to a Dimension Data Asset + Apply a tag to a NTTC-CIS Asset :param asset: The asset to apply a tag to. (required) :type asset: :class:`Node` or :class:`NodeImage` or @@ -3309,7 +3328,7 @@ class NttCisNodeDriver(NodeDriver): tag_key_name=None, tag_key_id=None, value=None, value_required=None, display_on_report=None): """ - List tags in the Dimension Data Cloud + List tags in the NTTC-CIS Cloud :param asset_id: Filter the list by asset id :type asset_id: ``str`` @@ -3467,7 +3486,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -3508,7 +3527,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -3558,7 +3577,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.common.dimensiondata import DimensionDataIpAddress >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -3691,7 +3710,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.common.dimensiondata import DimensionDataIpAddress >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -3796,7 +3815,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -3835,7 +3854,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -3876,7 +3895,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -3908,7 +3927,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.common.dimensiondata import DimensionDataPort >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -4011,7 +4030,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.common.dimensiondata import DimensionDataPort >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') @@ -4110,7 +4129,7 @@ class NttCisNodeDriver(NodeDriver): >>> from libcloud.compute.providers import get_driver >>> import libcloud.security >>> - >>> # Get dimension data driver + >>> # Get NTTC-CIS driver >>> libcloud.security.VERIFY_SSL_CERT = True >>> cls = get_driver(Provider.DIMENSIONDATA) >>> driver = cls('myusername','mypassword', region='dd-au') http://git-wip-us.apache.org/repos/asf/libcloud/blob/d4ae1aba/tests/conftest.py ---------------------------------------------------------------------- diff --git a/tests/conftest.py b/tests/conftest.py index 4bb21bc..c736040 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,7 +5,14 @@ import libcloud @pytest.fixture(scope="module") def compute_driver(): cls = libcloud.get_driver(libcloud.DriverType.COMPUTE, libcloud.DriverType.COMPUTE.NTTCIS) - compute_driver = cls('mitchgeo-test', 'Snmpv2c!', region='dd-eu') + compute_driver = cls('mitchgeo-test', 'Snmpv2c!', region='eu') + return compute_driver + + [email protected](scope="module") +def compute_driver_na(): + cls = libcloud.get_driver(libcloud.DriverType.COMPUTE, libcloud.DriverType.COMPUTE.NTTCIS) + compute_driver = cls('mitchgeo-test', 'Snmpv2c!', region='na') return compute_driver http://git-wip-us.apache.org/repos/asf/libcloud/blob/d4ae1aba/tests/lib_create_test.py ---------------------------------------------------------------------- diff --git a/tests/lib_create_test.py b/tests/lib_create_test.py index 2dadb90..3beec92 100644 --- a/tests/lib_create_test.py +++ b/tests/lib_create_test.py @@ -236,5 +236,19 @@ def test_add_pool_member(compute_driver, lbdriver): print(result) -def test_create_server_monitor(compute_driver): - pass \ No newline at end of file +def test_create_and_apply_tag(compute_driver, compute_driver_na): + tag_name = "sdk_test_tag" + description = "Tagged assets for test domain" + result = compute_driver_na.ex_create_tag_key(tag_name, description=description) + assert result is True + key = compute_driver_na.ex_get_tag_key_by_name(tag_name) + server_name = 'web2' + net_domain_name = 'sdk_test_1' + network_domains = compute_driver.ex_list_network_domains(location='EU6') + assets = [compute_driver.list_nodes(ex_name=server_name)[0], + [nd for nd in network_domains if nd.name == net_domain_name][0]] + for asset in assets: + result = compute_driver.ex_apply_tag_to_asset(asset, key, value='IT') + assert result is True + + http://git-wip-us.apache.org/repos/asf/libcloud/blob/d4ae1aba/tests/lib_edit_test.py ---------------------------------------------------------------------- diff --git a/tests/lib_edit_test.py b/tests/lib_edit_test.py index 32984ee..079e7d7 100644 --- a/tests/lib_edit_test.py +++ b/tests/lib_edit_test.py @@ -1,8 +1,9 @@ import pytest +import time import libcloud from libcloud import loadbalancer from libcloud.compute.drivers.nttcis import NttCisPort -from libcloud.common.nttcis import NttCisIpAddress, NttCisVlan, NttCisVIPNode +from libcloud.common.nttcis import NttCisIpAddress, NttCisVlan, NttCisVIPNode, NttCisAPIException from tests.lib_create_test import test_deploy_vlan @@ -168,6 +169,28 @@ def test_changing_diskspeed_iops(compute_driver): assert result is True +def test_expand_disk(compute_driver): + server_name = "web2" + server = compute_driver.list_nodes(ex_name=server_name)[0] + + disk = server.extra['disks'][0] + size = 95 + result = compute_driver.ex_change_storage_size(disk.id, size) + assert result is True + while True: + try: + shut_result = compute_driver.ex_shutdown_graceful(server) + except NttCisAPIException: + time.sleep(2) + continue + else: + break + assert shut_result is True + compute_driver.ex_wait_for_state('stopped', compute_driver.ex_get_node_by_id, 2, 45, server.id) + compute_driver.ex_start_node(server) + compute_driver.ex_wait_for_state('running', compute_driver.ex_get_node_by_id, 2, 45, server.id) + + def test_add_scsi_controller(compute_driver): node = compute_driver.ex_get_node_by_id('803e5e00-b22a-450a-8827-066ff15ec977') shut_result = compute_driver.ex_shutdown_graceful(node) @@ -450,3 +473,52 @@ def test_delete_listener(compute_driver, lbdriver): listener = [l for l in listeners if l.name == listener_name][0] result = lbdriver.destroy_balancer(listener) assert result is True + + +def test_add_server_monitor(compute_driver): + server_name = "web2" + server = compute_driver.list_nodes(ex_name=server_name)[0] + service_plan = 'ADVANCED' + result = compute_driver.ex_enable_monitoring(server, service_plan=service_plan) + assert result is True + + +def test_edit_server_monitor(compute_driver): + server_name = "web2" + server = compute_driver.list_nodes(ex_name=server_name)[0] + service_plan = 'ESSENTIALS' + result = compute_driver.ex_update_monitoring_plan(server, service_plan=service_plan) + assert result is True + + +def test_delete_server_monitor(compute_driver): + server_name = "web2" + server = compute_driver.list_nodes(ex_name=server_name)[0] + result = compute_driver.ex_disable_monitoring(server) + assert result is True + + +def test_delete_tag_key(compute_driver_na): + tag_name = "sdk_test_tag" + tag_key = compute_driver_na.ex_get_tag_key_by_name(tag_name) + tag_id = tag_key.id + result = compute_driver_na.ex_remove_tag_key(tag_id) + assert result is True + + +def test_modify_tag(compute_driver_na): + tag_name = "sdk_test_tag" + description = "Tagged assets for NetDomain sdk_test_1" + tag_key = compute_driver_na.ex_get_tag_key_by_name(tag_name) + result = compute_driver_na.ex_modify_tag_key(tag_key, description=description) + assert result is True + + +def test_remove_tag_from_asset(compute_driver, compute_driver_na): + tag_name = "sdk_test_tag" + tag_key = compute_driver_na.ex_get_tag_key_by_name(tag_name) + net_domain_name = 'sdk_test_1' + network_domains = compute_driver.ex_list_network_domains(location='EU6') + asset = [nd for nd in network_domains if nd.name == net_domain_name][0] + result = compute_driver.ex_remove_tag_from_asset(asset, tag_key) + assert result is True http://git-wip-us.apache.org/repos/asf/libcloud/blob/d4ae1aba/tests/lib_list_test.py ---------------------------------------------------------------------- diff --git a/tests/lib_list_test.py b/tests/lib_list_test.py index 7b896f4..77079ef 100644 --- a/tests/lib_list_test.py +++ b/tests/lib_list_test.py @@ -388,3 +388,14 @@ def test_list_health_monitors(compute_driver, lbdriver): for monitor in monitors: print(monitor) + +def test_list_tag_key(compute_driver_na): + tag_keys = compute_driver_na.ex_list_tag_keys() + for key in tag_keys: + print(key) + + +def test_get_snapshot(compute_driver): + snapshot_id = '7118cd30-3184-4a3a-b097-2a2d25b9cb28' + snapshot = compute_driver.get_snapshot(snapshot_id) + print(snapshot)
