You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by an...@apache.org on 2018/12/13 11:26:37 UTC

[28/45] libcloud git commit: added ssl cert chain imports, listing cert chains, get a cert chain. Created fixtures and pytest tests for certs

added ssl cert chain imports, listing cert chains, get a cert chain.  Created fixtures and pytest tests for certs


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/9e347241
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/9e347241
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/9e347241

Branch: refs/heads/trunk
Commit: 9e3472417fe01a0638c53c18697bf8cd1e906124
Parents: 35131c8
Author: mitch <mi...@itaas.dimensiondata.com>
Authored: Mon Nov 19 16:15:17 2018 -0500
Committer: mitch <mi...@itaas.dimensiondata.com>
Committed: Mon Nov 19 16:15:17 2018 -0500

----------------------------------------------------------------------
 libcloud/common/nttcis.py                       |  21 +++
 libcloud/drs/drivers/nttcis.py                  |  42 ++----
 libcloud/loadbalancer/drivers/nttcis.py         | 146 +++++++++++++++----
 libcloud/test/compute/test_nttcis.py            |   2 +
 .../test/loadbalancer/fixtures/nttcis/alice.crt |  23 +++
 .../test/loadbalancer/fixtures/nttcis/alice.key |  32 ++++
 .../test/loadbalancer/fixtures/nttcis/chain.crt |  47 ++++++
 .../test/loadbalancer/fixtures/nttcis/denis.crt | 124 ++++++++++++++++
 .../test/loadbalancer/fixtures/nttcis/denis.key |  51 +++++++
 .../loadbalancer/fixtures/nttcis/get_cert.xml   |   9 ++
 .../fixtures/nttcis/ssl_cert_by_name.xml        |  11 ++
 .../fixtures/nttcis/ssl_cert_list.xml           |  19 +++
 .../fixtures/nttcis/ssl_get_cert_chain.xml      |   9 ++
 .../fixtures/nttcis/ssl_import_cert_chain.xml   |   7 +
 .../nttcis/ssl_list_cert_chain_by_name.xml      |  11 ++
 libcloud/test/loadbalancer/test_nttcis.py       |  40 ++++-
 tests/lib_create_test.py                        |  14 +-
 tests/lib_list_test.py                          |  29 +++-
 18 files changed, 575 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/common/nttcis.py
----------------------------------------------------------------------
diff --git a/libcloud/common/nttcis.py b/libcloud/common/nttcis.py
index 2908dfc..aac16fa 100644
--- a/libcloud/common/nttcis.py
+++ b/libcloud/common/nttcis.py
@@ -16,6 +16,8 @@
 NTTCIS Common Components
 """
 import xml.etree.ElementTree as etree
+import re
+import functools
 from copy import deepcopy
 from base64 import b64encode
 from time import sleep
@@ -291,6 +293,25 @@ BAD_MESSAGE_XML_ELEMENTS = (
 )
 
 
+def get_params(func):
+    @functools.wraps(func)
+    def paramed(*args, **kwargs):
+        if kwargs:
+            for k, v in kwargs.items():
+                old_key = k
+                matches = re.findall(r'_(\w)', k)
+                for match in matches:
+                    k = k.replace('_' + match, match.upper())
+                del kwargs[old_key]
+                kwargs[k] = v
+            params = kwargs
+            result = func(args[0], params)
+        else:
+            result = func(args[0])
+        return result
+    return paramed
+
+
 def dd_object_to_id(obj, obj_type, id_value='id'):
     """
     Takes in a DD object or string and prints out it's id

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/drs/drivers/nttcis.py
----------------------------------------------------------------------
diff --git a/libcloud/drs/drivers/nttcis.py b/libcloud/drs/drivers/nttcis.py
index c5695d1..3c88bbe 100644
--- a/libcloud/drs/drivers/nttcis.py
+++ b/libcloud/drs/drivers/nttcis.py
@@ -4,33 +4,13 @@ from libcloud.utils.py3 import ET
 from libcloud.common.nttcis import NttCisConnection
 from libcloud.common.nttcis import API_ENDPOINTS
 from libcloud.common.nttcis import DEFAULT_REGION
-from libcloud.common.nttcis import process_xml
+from libcloud.common.nttcis import process_xml, get_params
 from libcloud.drs.types import Provider
 from libcloud.drs.base import DRSDriver
 from libcloud.common.nttcis import TYPES_URN
 from libcloud.utils.xml import fixxpath, findtext, findall
 
 
-def get_params(func):
-    @functools.wraps(func)
-    def paramed(*args, **kwargs):
-
-        if kwargs:
-            for k, v in kwargs.items():
-                old_key = k
-                matches = re.findall(r'_(\w)', k)
-                for match in matches:
-                    k = k.replace('_' + match, match.upper())
-                del kwargs[old_key]
-                kwargs[k] = v
-            params = kwargs
-            result = func(args[0], params)
-        else:
-            result = func(args[0])
-        return result
-    return paramed
-
-
 class NttCisDRSDriver(DRSDriver):
     """
     NttCis DRS driver.
@@ -116,16 +96,16 @@ class NttCisDRSDriver(DRSDriver):
         """
         Functions takes a named parameter that must be one of the following
         :param params: A dictionary composed of one of the following keys
-         and a value
-                       * target_data_center_id=
-                       * source_network_domain_id=
-                       * target_network_domain_id=
-                       * source_server_id=
-                       * target_server_id=
-                       * name=
-                       * state=
-                       * operation_status=
-                       * drs_infrastructure_status=
+        and a value
+        * target_data_center_id=
+        * source_network_domain_id=
+        * target_network_domain_id=
+        * source_server_id=
+        * target_server_id=
+        * name=
+        * state=
+        * operation_status=
+        * drs_infrastructure_status=
         :return:  `list` of :class: `NttCisConsistencyGroup`
         """
 

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/loadbalancer/drivers/nttcis.py
----------------------------------------------------------------------
diff --git a/libcloud/loadbalancer/drivers/nttcis.py b/libcloud/loadbalancer/drivers/nttcis.py
index 690ecf8..da2165a 100644
--- a/libcloud/loadbalancer/drivers/nttcis.py
+++ b/libcloud/loadbalancer/drivers/nttcis.py
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 import OpenSSL.crypto
-import functools
 from libcloud.utils.py3 import ET
 from libcloud.common.nttcis import NttCisConnection
 from libcloud.common.nttcis import NttCisPool
@@ -28,7 +27,7 @@ from libcloud.common.nttcis import NttCisDefaultiRule
 from libcloud.common.nttcis import API_ENDPOINTS
 from libcloud.common.nttcis import DEFAULT_REGION
 from libcloud.common.nttcis import TYPES_URN
-from libcloud.common.nttcis import process_xml
+from libcloud.common.nttcis import process_xml, get_params
 from libcloud.utils.misc import reverse_dict
 from libcloud.utils.xml import fixxpath, findtext, findall
 from libcloud.loadbalancer.types import State
@@ -38,26 +37,6 @@ from libcloud.loadbalancer.base import Member
 from libcloud.loadbalancer.types import Provider
 
 
-def get_params(func):
-    @functools.wraps(func)
-    def paramed(*args, **kwargs):
-
-        if kwargs:
-            for k, v in kwargs.items():
-                old_key = k
-                matches = re.findall(r'_(\w)', k)
-                for match in matches:
-                    k = k.replace('_' + match, match.upper())
-                del kwargs[old_key]
-                kwargs[k] = v
-            params = kwargs
-            result = func(args[0], params)
-        else:
-            result = func(args[0])
-        return result
-    return paramed
-
-
 class NttCisLBDriver(Driver):
     """
     NttCis LB driver.
@@ -779,14 +758,30 @@ class NttCisLBDriver(Driver):
             status=State.RUNNING
         )
 
-    def import_ssl_cert(self, network_domain_id, name, crt_file, key_file,
+    def ex_import_ssl_cert(self, network_domain_id, name, crt_file, key_file,
                         description=None):
+        """
+        Import an ssl cert for ssl offloading onto the the load balancer
+        :param network_domain_id:  The Network Domain's Id.
+        :type ``str``
+        :param name: The name of the ssl certificate
+        :type ``str``
+        :param crt_file: The complete path to the certificate file
+        :type ``str``
+        :param key_file: The complete pathy to the key file
+        :type ``str``
+        :param description: (Optional) A description of the certificate
+        :type ``str``
+        :return: ``bool``
+        """
         c = OpenSSL.crypto.load_certificate(
             OpenSSL.crypto.FILETYPE_PEM, open(crt_file).read())
-        cert = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, c).decode(encoding='utf-8')
+        cert = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, c)\
+            .decode(encoding='utf-8')
         k = OpenSSL.crypto.load_privatekey(
             OpenSSL.crypto.FILETYPE_PEM, open(key_file).read())
-        key = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, k).decode(encoding='utf-8')
+        key = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, k)\
+            .decode(encoding='utf-8')
         cert_elem = ET.Element("importSslDomainCertificate", {"xmlns": TYPES_URN})
         ET.SubElement(cert_elem, "networkDomainId").text = network_domain_id
         ET.SubElement(cert_elem, "name").text = name
@@ -801,6 +796,38 @@ class NttCisLBDriver(Driver):
         response_code = findtext(result, 'responseCode', TYPES_URN)
         return response_code in ['IN_PROGRESS', 'OK']
 
+    def ex_import_ssl_cert_chain(self, network_domain_id, name,
+                                 chain_crt_file, description=None):
+        """
+        Import an ssl certificate chain for ssl offloading onto the the load balancer
+        :param network_domain_id:  The Network Domain's Id.
+        :type ``str``
+        :param name: The name of the ssl certificate chain
+        :type ``str``
+        :param crt_file: The complete path to the certificate chain file
+        :type ``str``
+        :param description: (Optional) A description of the certificate chain
+        :type ``str``
+        :return: ``bool``
+        """
+        c = OpenSSL.crypto.load_certificate(
+            OpenSSL.crypto.FILETYPE_PEM, open(chain_crt_file).read())
+        cert = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, c)\
+            .decode(encoding='utf-8')
+        cert_chain_elem = ET.Element("importSslCertificateChain", {"xmlns": TYPES_URN})
+        ET.SubElement(cert_chain_elem, "networkDomainId")\
+            .text = network_domain_id
+        ET.SubElement(cert_chain_elem, "name").text = name
+        if description is not None:
+            ET.SubElement(cert_chain_elem, "description").text = description
+        ET.SubElement(cert_chain_elem, "certificateChain").text = cert
+        result = self.connection.request_with_orgId_api_2(
+            "networkDomainVip/importSslCertificateChain",
+            method="POST",
+            data=ET.tostring(cert_chain_elem)).object
+        response_code = findtext(result, 'responseCode', TYPES_URN)
+        return response_code in ['IN_PROGRESS', 'OK']
+
     def ex_get_pools(self, ex_network_domain_id=None):
         """
         Get all of the pools inside the current geography or
@@ -1095,12 +1122,72 @@ class NttCisLBDriver(Driver):
 
     @get_params
     def ex_list_ssl_domain_certs(self, params={}):
+        """
+        Functions takes a named parameter that can be one or none of the
+        following
+        :param params: A dictionary composed of one of the following keys
+        and a value
+        * id=
+        * network_domain_id=
+        * name=
+        * state=
+        * create_time=
+        * expiry_time=
+        * state=
+        :return: `list` of :class: `NttCisdomaincertificate`
+        """
         result = self.connection.request_with_orgId_api_2(
             action="networkDomainVip/sslDomainCertificate",
             params=params,
             method="GET").object
         return self._to_certs(result)
 
+    def ex_get_ssl_domain_cert(self, cert_id):
+        """
+        Function gets the cert by id. Use this if only if the id
+        is already known
+        :param cert_id: The id of the specific cert
+        :return: :class: `NttCisdomaincertificate
+        """
+        result = self.connection.request_with_orgId_api_2(
+            action="networkDomainVip/sslDomainCertificate/%s" % cert_id,
+            method="GET").object
+        return self._to_cert(result)
+
+    @get_params
+    def ex_list_ssl_certificate_chains(self, params={}):
+        """
+        Functions takes a named parameter that can be one or none of the
+        following to filter returned items
+        :param params: A dictionary composed of one of the following keys
+        and a value
+        * id=
+        * network_domain_id=
+        * name=
+        * state=
+        * create_time=
+        * expiry_time=
+        * state=
+        :return: `list` of :class: `NttCissslcertficiatechain`
+        """
+        result = self.connection.request_with_orgId_api_2(
+            action="networkDomainVip/sslCertificateChain",
+            params=params,
+            method="GET").object
+        return self._to_certificate_chains(result)
+
+    def ex_get_ssl_certificate_chain(self, chain_id):
+        """
+        Function gets the certificate chain by id. Use this if only if the id
+        is already known
+        :param cert_id: The id of the specific cert
+        :return: :class: `NttCiscertificatechain
+        """
+        result = self.connection.request_with_orgId_api_2(
+            action="networkDomainVip/sslCertificateChain/%s" % chain_id,
+            method="GET").object
+        return self._to_certificate_chain(result)
+
     def _to_irules(self, object):
         irules = []
         matches = object.findall(
@@ -1297,3 +1384,12 @@ class NttCisLBDriver(Driver):
 
     def _to_cert(self, el):
         return process_xml(ET.tostring(el))
+
+    def _to_certificate_chains(self, object):
+        cert_chains = []
+        for element in object.findall(fixxpath("sslCertificateChain", TYPES_URN)):
+            cert_chains.append(self._to_certificate_chain(element))
+        return cert_chains
+
+    def _to_certificate_chain(self, el):
+        return process_xml(ET.tostring(el))

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/compute/test_nttcis.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_nttcis.py b/libcloud/test/compute/test_nttcis.py
index d5c7b6b..cff7094 100644
--- a/libcloud/test/compute/test_nttcis.py
+++ b/libcloud/test/compute/test_nttcis.py
@@ -424,6 +424,7 @@ def test_create_node_primary_ipv4(driver):
     assert node.id == 'e75ead52-692f-4314-8725-c8a4f4d13a87'
     assert node.extra['status'].action == 'DEPLOY_SERVER'
 
+
 def test_create_node_both_primary_nic_and_vlan_fail(driver):
     rootPw = NodeAuthPassword('pass123')
     image = driver.list_images()[0]
@@ -517,6 +518,7 @@ def test_create_node_ipv4_gateway(driver):
     assert node.id == 'e75ead52-692f-4314-8725-c8a4f4d13a87'
     assert node.extra['status'].action == 'DEPLOY_SERVER'
 
+
 def test_create_node_network_domain_no_vlan_no_ipv4_fail(driver):
     rootPw = NodeAuthPassword('pass123')
     image = driver.list_images()[0]

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/alice.crt
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/alice.crt b/libcloud/test/loadbalancer/fixtures/nttcis/alice.crt
new file mode 100755
index 0000000..bc545a9
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/alice.crt
@@ -0,0 +1,23 @@
+Bag Attributes
+    friendlyName: alice
+    localKeyID: 17 FC F8 5F A1 F3 12 5E 62 D7 49 EE 47 2B FF 78 4D 22 F7 C1 
+subject=/CN=alice/C=US
+issuer=/CN=SdkCA/C=US
+-----BEGIN CERTIFICATE-----
+MIIC3zCCAcegAwIBAgIBAjANBgkqhkiG9w0BAQsFADAdMQ4wDAYDVQQDDAVTZGtD
+QTELMAkGA1UEBhMCVVMwHhcNMTgxMTE2MTg1NTI0WhcNMTkxMTE2MTg1NTI0WjAd
+MQ4wDAYDVQQDDAVhbGljZTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQCusa3hl3F38gjj0u220zZ216wdrOIC+seGSIww9aLQ4B3a
+Mt7Q4isOzyJbqpuJvsVxhEQXQGO1G4ApgfvLkSJTV5p9aoyo0NQKa+42wPKGnBq3
+ekBLPVywcBXU08jXoVv8DeyWdxBA677Ev69mK86skI9uxZXrTp/0CVHuhO1REgf3
+TRT9PRRcO+IuXvjVYk6juFl5nkgZ+IyjGDUy/Y3XpiWgpBl1vowiF/pyXEz+taQ6
+Kug5+uVpISPLlocgayxVRYuf8N8Hzxcqa1pEbfwXAn31AzWKvU7DIrIcsG4jo1uv
+vWJqpQHmzSQtP3Pk/eC4CO4RsMB8A6S2TXVLd9cXAgMBAAGjKjAoMA4GA1UdDwEB
+/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOC
+AQEACE7tRLKvIgeMr87r8jhcKmaiE1OQXDNNnd8ywknptQbk3aa0K53c88fQYCPd
+W1yusJVaI3lmAnt3tNtBB1Dzv8D46jBWQ8EWyvpl1bm1nH5ja+cSxlEw5y3cBf8j
+McyEl86PMakX3gVr2KCpMntnq5w0rni/XMMcV5XXJYzY7g/AUIsyF92iUEhYcfWL
+NggjBHvjXhV8lCtztDs/w9S1k1buSlUlbb08G/2eWGvfMC44y2BMFAWAxN7TSXCc
+VGEo9Jfd2jJfqVf6B9jQu+BXcEIHY9zrqXsVFbHE6wIKjSIn0Bk4k8n8ZcR0EqRR
+mhjLBM2mghvfRRxekqE/WN8uIQ==
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/alice.key
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/alice.key b/libcloud/test/loadbalancer/fixtures/nttcis/alice.key
new file mode 100755
index 0000000..69ab352
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/alice.key
@@ -0,0 +1,32 @@
+Bag Attributes
+    friendlyName: alice
+    localKeyID: 17 FC F8 5F A1 F3 12 5E 62 D7 49 EE 47 2B FF 78 4D 22 F7 C1 
+Key Attributes: <No Attributes>
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCusa3hl3F38gjj
+0u220zZ216wdrOIC+seGSIww9aLQ4B3aMt7Q4isOzyJbqpuJvsVxhEQXQGO1G4Ap
+gfvLkSJTV5p9aoyo0NQKa+42wPKGnBq3ekBLPVywcBXU08jXoVv8DeyWdxBA677E
+v69mK86skI9uxZXrTp/0CVHuhO1REgf3TRT9PRRcO+IuXvjVYk6juFl5nkgZ+Iyj
+GDUy/Y3XpiWgpBl1vowiF/pyXEz+taQ6Kug5+uVpISPLlocgayxVRYuf8N8Hzxcq
+a1pEbfwXAn31AzWKvU7DIrIcsG4jo1uvvWJqpQHmzSQtP3Pk/eC4CO4RsMB8A6S2
+TXVLd9cXAgMBAAECggEBAKiZvVrTgeSkiOXwhhKESLVsM6Y0W7FKfdThIcSC3c+/
+7a/QlvF8xte1G9DimNjZcM+9OsZCE7kQQKJO3Eg826caDnVqpzSqz2r7fd4EXE2E
+Tdi0uWakY1e55agRem56Qj/C5IrXgK1XmTdkVRFDyGUN5BChy65dpMyvTg7o5e3t
+49G+M4/jLH5Lqqv8Y95wkV5q39JIDYbQyW9EOD0arp58DCQV0xuWS3YV3SgQbqHW
++PCVlyoAfhvacSgxQHKVwfLhzl+uR78neLF6CqnF3HaUnwTto/Tg9oiktKcik5ey
+DLQ21x+Z6CaOw6nGQc63c/P7M3oOmPH00lF8IOdjq7kCgYEA13586FGGpaQsOCtD
+4ixH/IwkIk4fsCVTvQ7ppm5LV4sCS2V5qXK0WiFpdXJd7Wp6wPp2StzGJXa0pOtb
+bzLQPNoWJPG1KEjmiRDs+OFannsKa1EA+3JmKaLHtSQqYSQt8hip8Lrt8AdK8gZy
+H60M1k5GzpNgnpX/OzP7iY5BWaUCgYEAz4fn3dX1ydbp4ti+7jlYXAdIhUur7MPD
+MYRNKGSXfAKzNreKn1gbEpj8owP6WPLGKZskOMv4w2j9O8OR3MS40KVQsI0ZTzuJ
+wRSW3tcGyyhU1P0rZa/qJMrDyRJyMxUfIQtIIJZnG2P+1GJQm2VHdAsol6eWd7E9
+km5FhrgCeQsCgYBiQYA+hX25ZQPskH2hUMN5+YQ4SBrWvA5Uc8pBYqTjw7RGIHy6
+sFxfhECLlpwRNq3F8+2f8M5AIsH3OIE2UJr2RBI4wiTxu1uyP49tY4NoI336tLKX
+8+91KI2aoGTaah6w9mH2K6V1/j1D4YCDxOnHhWVvp280n/wCSI92hvBxKQKBgHd0
+V/91t7uNbCT587S152lZe+HV88kdyY4IBE2a0SM9fqChNzaPBU5IJytCD+kBHRU3
+yrqylacNGK483QnBZkway/5DyWy07Y7o5gqwpKVtup66dy9Z+aFh4R4s8vT6VGe1
+0beIOyMmBLmFObaorl9aSOw6N77/k1xlAroP0sSPAoGBAJLCF24ouFYKtGqdAU1c
+uxuhGd+R5eS/+NbejwgWC8xn2vE6xIACqXlpBd3291fkv+gTV9kkhASysvr6zbWm
+coRqw/epAa9tvCa/+lA2N8VsJjVEoFTWUduBMrbl6lfvZpHhrBgcNY2nmMiADu4s
+NoKpFsHFVOjR8LxV6O7WQoFp
+-----END PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/chain.crt
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/chain.crt b/libcloud/test/loadbalancer/fixtures/nttcis/chain.crt
new file mode 100644
index 0000000..122958e
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/chain.crt
@@ -0,0 +1,47 @@
+Bag Attributes
+    friendlyName: ted
+    localKeyID: 8F 9E 3A 57 A1 4A E5 7C A9 36 0E DE E2 CE 1C 69 15 F0 91 9A 
+subject=/CN=ted/C=US
+issuer=/CN=SdkCA/C=US
+-----BEGIN CERTIFICATE-----
+MIIC3TCCAcWgAwIBAgIBBTANBgkqhkiG9w0BAQsFADAdMQ4wDAYDVQQDDAVTZGtD
+QTELMAkGA1UEBhMCVVMwHhcNMTgxMTE5MDAyMTMwWhcNMTkxMTE5MDAyMTMwWjAb
+MQwwCgYDVQQDDAN0ZWQxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAxtoIwKV70myxiAtT/k+L3klqUZ/G6Hp7CV01ixUH7r4mW0Fh
+gYZRZoPZ+9tNWnkizKnG8QNQjLaARJTtnLd2Vl1auPeXMVPobboz/9Dh5RhTLi26
+7LSmNozWacPbv3nExObUDTxaLpqs6ZGL/ngfgqJJJ24g/Ku/ZRFanH0HJvaiRBCQ
+CPW5ZrikUBB5SC/7XPw9UWBQH+yD9s+PJCUD7VUzM/sLU5USn7PKkK0EJW3pQArR
+46J+c2VkJexbCxdZ9BAF1gbB8GqGPbyI73gpCasZ6/xL56kbjQnqSMwn1CSIlNz7
++uU/DF3/Ne87qAIr50FGZ/L2EsSS2takIPDMRwIDAQABoyowKDAOBgNVHQ8BAf8E
+BAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEB
+ABHtRAqvsLwHqFAfj0PcocVPxFa0isZ0K+3YxgG5Ut8Jk02VNZAxwsZSPB2a1U53
+rc27VYejWLyv2LB2WX/4wFje6NMrPMoAEGOSrbfrjUUYD5doNwIAxgQC3et+XH3u
+aqYJh0UEj2CV6r/HAjhxkdtpcXh1QOv0zYx5WbZD6QbBw9sYnitpXK+O5gOv0kh+
+6850FBn58DuKjc5IKbm3DhNaVtEVgTW80nEbk4/sxZ6PSZI0T9PhlHbDILLV/YIE
+UjviE24E18N+uuLFefF6aor/nrTyIPr7Yh8niJ4WJWY+D7nOtOXUp/b8jvtDYSTc
+hHz1swjcoADLnN6my2Z9VMs=
+-----END CERTIFICATE-----
+
+Bag Attributes
+    friendlyName: carol
+    localKeyID: DB 22 50 DE 8E 47 7D FA D6 51 85 89 8C AD B6 9B 6E 23 40 6E 
+subject=/CN=carol/C=US
+issuer=/CN=SdkCA/C=US
+-----BEGIN CERTIFICATE-----
+MIIC3zCCAcegAwIBAgIBBDANBgkqhkiG9w0BAQsFADAdMQ4wDAYDVQQDDAVTZGtD
+QTELMAkGA1UEBhMCVVMwHhcNMTgxMTE5MDAxMTQ5WhcNMTkxMTE5MDAxMTQ5WjAd
+MQ4wDAYDVQQDDAVjYXJvbDELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQC0Pyk2+vc3M9nB/7mjPueTzM5bf+JrzGumiVQ3zB+Ub9tY
+GIaXs5OebSx6B/8G/AC1M0ohr/Id62se9E9OLU+/vhsoFNWpEKDic63L1lxMpZLw
+eqjUNdgp/d4sNkFucSkQLIGMc0lyzzjtooerTci+kLVAzilx1ys7tOHZdF2i3xsG
+OLjEs+0JjgKB/go4E4fO9O8Se016QbYlSKaBhMZl3lI5IzOFPshLk54FBCz+Xkmn
+uyElHGMvUCf7jfPd/tYODiHXo5kVrB9wGwAd45VTNa7Uy8YsnlvsQ65VkrMa/ihP
+YSHb6K3MkwsZvmeP0LeIjH10v0UZawXagdmRHoR9AgMBAAGjKjAoMA4GA1UdDwEB
+/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOC
+AQEArBYvQ494XYc9T+oj34R8Kt5COBpnG0gRjRd10s5wKki3CrArohvWrSt1HdhN
+xYKpWNP5Lx8fsQKNZMfPshzfiBVaJUisE1zh9aITeCOGIRLivLEn+z23LHT9qZZt
+VprL+WfJUlhbS/w2RUp+3FRbl09BGldqYdFXQU3uWepLsOiqHhLsdeaYywKJLAoX
+fXjI0w43emzpcnFxTHwrGMhgfgTKZ2quFpObRb73Irv9t/l2rlKU5URXZ4WE7fuF
+9OqNI1KkxxxhOelQIvo9SPn2sL+B+bnLghqky7FMJ8zeyP8W57yike7aqlYnHZtY
+64so6za/q+LlDMsmFqVlkAPYtg==
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/denis.crt
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/denis.crt b/libcloud/test/loadbalancer/fixtures/nttcis/denis.crt
new file mode 100755
index 0000000..31dd2c0
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/denis.crt
@@ -0,0 +1,124 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4 (0x4)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=FR, ST=Alsace, L=Strasbourg, O=Freelan, CN=ca/emailAddress=contact@freelan.org
+        Validity
+            Not Before: May  5 12:48:56 2012 GMT
+            Not After : May  3 12:48:56 2022 GMT
+        Subject: C=FR, ST=Alsace, O=Freelan, CN=denis/emailAddress=contact@freelan.org
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:ba:89:22:1e:b2:60:d8:f0:82:ef:ee:14:67:79:
+                    47:f4:00:40:62:e7:81:3b:43:62:05:e5:13:e2:30:
+                    f0:97:6f:47:b3:fc:f9:09:74:3c:7a:c8:23:fa:33:
+                    a1:9f:be:7c:72:92:b4:75:f7:83:2f:83:18:79:22:
+                    d9:9d:f7:ed:d7:f0:25:6b:03:89:b1:0e:6f:6c:91:
+                    fd:c7:b1:f0:d8:3a:f9:85:ff:94:1b:cd:02:e9:e6:
+                    f4:2d:5e:c6:8f:f7:8c:13:da:5a:84:9e:f3:38:a9:
+                    e7:5c:54:79:74:99:20:53:82:d5:ae:d9:9d:04:f4:
+                    01:9c:53:73:0f:20:b6:d8:fc:89:ac:71:9c:3b:6f:
+                    1c:db:fa:b2:7f:12:03:6e:55:3f:b6:cf:8b:59:24:
+                    bd:44:72:e8:b6:03:bc:29:40:6d:54:a8:df:67:5f:
+                    45:e5:98:ac:dc:15:85:26:a0:69:ab:4b:41:64:e2:
+                    1f:59:87:ce:99:2d:3b:8e:f0:94:04:a3:b1:9e:75:
+                    31:c9:a5:84:6d:39:cb:ce:36:10:d4:7c:c9:93:68:
+                    4e:a9:60:fd:c1:29:cc:86:f1:05:4e:71:25:10:25:
+                    20:bc:36:db:40:89:32:4b:20:0e:58:25:96:59:0e:
+                    05:63:71:06:4c:7c:58:f6:3c:3e:9c:9f:5b:74:3f:
+                    f3:80:78:78:b1:6c:d9:01:64:c4:4f:55:f0:c6:7d:
+                    18:1c:b6:ca:0f:d2:70:cd:77:a1:9c:28:cb:d0:1e:
+                    ce:42:c0:8f:93:4d:84:55:8c:4c:81:6f:ff:fe:f3:
+                    99:a4:7d:f0:70:a5:19:0b:a2:9d:39:18:93:84:e1:
+                    82:bf:d9:cd:72:ed:46:68:44:19:cf:6e:88:88:64:
+                    3b:fb:23:c7:66:f9:af:be:9e:a7:ac:a0:90:f9:1f:
+                    d3:16:3d:53:7a:03:73:d2:c9:3f:37:1b:a1:c6:c1:
+                    3a:06:a8:03:f5:a0:14:2e:8f:69:d4:3d:14:ba:20:
+                    96:ae:4f:87:57:f6:3b:76:25:b1:ab:55:3b:ae:96:
+                    5b:94:a9:42:25:3b:f7:b9:23:72:ea:ab:d0:bc:8a:
+                    ed:ac:ec:dc:31:04:28:39:59:31:3d:14:96:f7:dc:
+                    8b:d6:b1:65:d2:42:fc:cb:fc:87:a6:4a:1f:0a:11:
+                    ef:28:70:11:72:d2:95:3c:7d:b4:17:3c:e2:77:29:
+                    71:64:10:2a:bc:a0:cd:a1:98:69:0d:81:86:da:a7:
+                    dc:57:f7:57:af:38:67:bb:83:96:9b:c3:84:ba:2e:
+                    5c:9d:ec:8c:fc:87:1b:27:ac:59:41:8e:03:f8:16:
+                    22:54:27:bb:54:5b:c7:ce:22:ab:2e:5d:bc:34:4c:
+                    14:de:e3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                1C:67:E3:2C:25:29:02:00:38:3C:A5:B6:E3:A2:37:9C:8F:A5:DB:34
+            X509v3 Authority Key Identifier: 
+                keyid:42:9C:36:BD:CB:2F:F4:D9:5E:AB:2B:18:24:8B:01:2D:42:C2:E1:47
+
+    Signature Algorithm: sha1WithRSAEncryption
+        b2:da:83:96:6b:a4:78:9e:c5:bf:75:f3:0a:32:a5:f0:fb:c3:
+        1a:58:42:bc:a8:29:1b:ac:b9:f6:cd:d1:a4:7c:e2:76:e2:98:
+        e1:96:8f:1b:ad:86:ee:df:41:74:7f:8a:85:f9:77:92:4d:e8:
+        ca:e5:d5:6b:94:58:72:a1:63:03:f6:a3:8c:c0:6d:6d:53:1c:
+        9a:38:1c:36:5d:6b:0f:cd:8f:d9:8b:e8:f3:eb:ea:b0:b0:0b:
+        c9:de:4c:0d:7e:06:53:1e:e2:78:fb:4a:40:ab:ac:60:6a:e4:
+        60:7f:78:e1:5f:a7:5c:8b:a8:8f:fc:c8:7b:70:d5:b1:47:05:
+        12:e9:2c:49:75:1a:29:dc:38:b4:ec:31:43:14:bd:f9:e6:1c:
+        87:1f:89:0e:08:93:a7:20:28:4c:c4:b2:4d:51:a1:85:c8:11:
+        4a:f5:b7:9c:70:0b:1f:1f:85:3b:d2:9c:a5:5e:ef:8a:0e:7e:
+        83:e6:b3:45:44:2b:2a:7f:a9:a2:cf:4d:64:bb:30:d1:48:ad:
+        03:b0:90:60:e4:54:63:da:3b:ff:74:e1:33:7a:0a:93:45:6c:
+        2b:86:a9:85:59:11:0b:2b:5c:79:b2:e2:5b:e6:da:b1:1d:4c:
+        97:a7:44:d9:2f:4c:f9:50:b9:ed:ae:85:eb:e1:d8:d1:a0:ae:
+        2b:00:47:81:bb:2a:a5:3d:74:d9:dc:f6:93:f9:8d:fb:be:f3:
+        fe:1f:5e:e9:68:3d:27:98:5a:aa:48:22:a3:b2:63:91:40:94:
+        39:36:86:3b:58:f8:7b:be:d5:24:51:72:b1:4b:18:9e:fe:21:
+        82:02:06:eb:d7:41:2a:41:a7:6f:ef:0b:b3:2f:2f:1e:da:6a:
+        d2:de:1f:c3:e4:5a:39:57:4a:da:8e:10:bf:99:54:5b:ca:9e:
+        0c:e5:4c:ce:26:1b:ae:0a:a9:7e:f2:a7:c3:61:6d:56:9c:db:
+        f5:19:56:93:1d:3a:a8:ca:a2:5d:fe:3e:b9:a0:ee:16:b5:c0:
+        b6:67:89:d3:91:aa:b8:43:d1:b8:3c:31:ae:b4:08:72:95:8d:
+        77:3e:95:d8:f1:25:7c:95:8d:0d:28:ea:ce:02:a9:91:19:77:
+        e7:3d:03:a1:02:12:cc:3a:91:42:20:9b:b5:57:bc:4b:db:22:
+        5a:9f:31:5c:f0:e8:8c:7b:77:fe:c0:01:22:7d:c5:73:29:24:
+        a0:1f:41:f2:84:2a:6e:9e:1c:61:13:25:48:56:6b:a9:3f:02:
+        33:6e:f2:21:c8:63:b6:cb:e5:c0:a4:c0:1c:98:13:9f:78:e1:
+        2d:b8:dd:12:17:43:ad:ec:fe:f7:78:17:bc:ae:8f:76:36:26:
+        7e:52:69:0a:5d:55:15:41
+-----BEGIN CERTIFICATE-----
+MIIF0DCCA7igAwIBAgIBBDANBgkqhkiG9w0BAQUFADB2MQswCQYDVQQGEwJGUjEP
+MA0GA1UECAwGQWxzYWNlMRMwEQYDVQQHDApTdHJhc2JvdXJnMRAwDgYDVQQKDAdG
+cmVlbGFuMQswCQYDVQQDDAJjYTEiMCAGCSqGSIb3DQEJARYTY29udGFjdEBmcmVl
+bGFuLm9yZzAeFw0xMjA1MDUxMjQ4NTZaFw0yMjA1MDMxMjQ4NTZaMGQxCzAJBgNV
+BAYTAkZSMQ8wDQYDVQQIDAZBbHNhY2UxEDAOBgNVBAoMB0ZyZWVsYW4xDjAMBgNV
+BAMMBWRlbmlzMSIwIAYJKoZIhvcNAQkBFhNjb250YWN0QGZyZWVsYW4ub3JnMIIC
+IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuokiHrJg2PCC7+4UZ3lH9ABA
+YueBO0NiBeUT4jDwl29Hs/z5CXQ8esgj+jOhn758cpK0dfeDL4MYeSLZnfft1/Al
+awOJsQ5vbJH9x7Hw2Dr5hf+UG80C6eb0LV7Gj/eME9pahJ7zOKnnXFR5dJkgU4LV
+rtmdBPQBnFNzDyC22PyJrHGcO28c2/qyfxIDblU/ts+LWSS9RHLotgO8KUBtVKjf
+Z19F5Zis3BWFJqBpq0tBZOIfWYfOmS07jvCUBKOxnnUxyaWEbTnLzjYQ1HzJk2hO
+qWD9wSnMhvEFTnElECUgvDbbQIkySyAOWCWWWQ4FY3EGTHxY9jw+nJ9bdD/zgHh4
+sWzZAWTET1Xwxn0YHLbKD9JwzXehnCjL0B7OQsCPk02EVYxMgW///vOZpH3wcKUZ
+C6KdORiThOGCv9nNcu1GaEQZz26IiGQ7+yPHZvmvvp6nrKCQ+R/TFj1TegNz0sk/
+NxuhxsE6BqgD9aAULo9p1D0UuiCWrk+HV/Y7diWxq1U7rpZblKlCJTv3uSNy6qvQ
+vIrtrOzcMQQoOVkxPRSW99yL1rFl0kL8y/yHpkofChHvKHARctKVPH20Fzzidylx
+ZBAqvKDNoZhpDYGG2qfcV/dXrzhnu4OWm8OEui5cneyM/IcbJ6xZQY4D+BYiVCe7
+VFvHziKrLl28NEwU3uMCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0E
+HxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFBxn4ywl
+KQIAODyltuOiN5yPpds0MB8GA1UdIwQYMBaAFEKcNr3LL/TZXqsrGCSLAS1CwuFH
+MA0GCSqGSIb3DQEBBQUAA4ICAQCy2oOWa6R4nsW/dfMKMqXw+8MaWEK8qCkbrLn2
+zdGkfOJ24pjhlo8brYbu30F0f4qF+XeSTejK5dVrlFhyoWMD9qOMwG1tUxyaOBw2
+XWsPzY/Zi+jz6+qwsAvJ3kwNfgZTHuJ4+0pAq6xgauRgf3jhX6dci6iP/Mh7cNWx
+RwUS6SxJdRop3Di07DFDFL355hyHH4kOCJOnIChMxLJNUaGFyBFK9beccAsfH4U7
+0pylXu+KDn6D5rNFRCsqf6miz01kuzDRSK0DsJBg5FRj2jv/dOEzegqTRWwrhqmF
+WRELK1x5suJb5tqxHUyXp0TZL0z5ULntroXr4djRoK4rAEeBuyqlPXTZ3PaT+Y37
+vvP+H17paD0nmFqqSCKjsmORQJQ5NoY7WPh7vtUkUXKxSxie/iGCAgbr10EqQadv
+7wuzLy8e2mrS3h/D5Fo5V0rajhC/mVRbyp4M5UzOJhuuCql+8qfDYW1WnNv1GVaT
+HTqoyqJd/j65oO4WtcC2Z4nTkaq4Q9G4PDGutAhylY13PpXY8SV8lY0NKOrOAqmR
+GXfnPQOhAhLMOpFCIJu1V7xL2yJanzFc8OiMe3f+wAEifcVzKSSgH0HyhCpunhxh
+EyVIVmupPwIzbvIhyGO2y+XApMAcmBOfeOEtuN0SF0Ot7P73eBe8ro92NiZ+UmkK
+XVUVQQ==
+-----END CERTIFICATE-----

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/denis.key
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/denis.key b/libcloud/test/loadbalancer/fixtures/nttcis/denis.key
new file mode 100755
index 0000000..dee87ac
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/denis.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/get_cert.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/get_cert.xml b/libcloud/test/loadbalancer/fixtures/nttcis/get_cert.xml
new file mode 100644
index 0000000..b78e886
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/get_cert.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sslDomainCertificate xmlns="urn:didata.com:api:cloud:types" id="352146be-0d6a-40cf-b935-808ab504a868" datacenterId="EU6">
+    <networkDomainId>6aafcf08-cb0b-432c-9c64-7371265db086</networkDomainId>
+    <name>bob</name>
+    <description>test cert</description>
+    <state>NORMAL</state>
+    <createTime>2018-11-17T02:15:04.000Z</createTime>
+    <expiryTime>2019-11-17T02:05:54.000Z</expiryTime>
+</sslDomainCertificate>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_by_name.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_by_name.xml b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_by_name.xml
new file mode 100644
index 0000000..f10cde1
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_by_name.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sslDomainCertificates xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="1" totalCount="1" pageSize="250">
+    <sslDomainCertificate id="4d2e9792-c986-4f2b-80c9-39e457eed8e8" datacenterId="EU6">
+        <networkDomainId>6aafcf08-cb0b-432c-9c64-7371265db086</networkDomainId>
+        <name>alice</name>
+        <description>test cert</description>
+        <state>NORMAL</state>
+        <createTime>2018-11-16T19:52:20.000Z</createTime>
+        <expiryTime>2019-11-16T18:55:24.000Z</expiryTime>
+    </sslDomainCertificate>
+</sslDomainCertificates>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_list.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_list.xml b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_list.xml
new file mode 100644
index 0000000..68042dd
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_cert_list.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sslDomainCertificates xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="2" totalCount="2" pageSize="250">
+    <sslDomainCertificate id="4d2e9792-c986-4f2b-80c9-39e457eed8e8" datacenterId="EU6">
+        <networkDomainId>6aafcf08-cb0b-432c-9c64-7371265db086</networkDomainId>
+        <name>alice</name>
+        <description>test cert</description>
+        <state>NORMAL</state>
+        <createTime>2018-11-16T19:52:20.000Z</createTime>
+        <expiryTime>2019-11-16T18:55:24.000Z</expiryTime>
+    </sslDomainCertificate>
+    <sslDomainCertificate id="352146be-0d6a-40cf-b935-808ab504a868" datacenterId="EU6">
+        <networkDomainId>6aafcf08-cb0b-432c-9c64-7371265db086</networkDomainId>
+        <name>bob</name>
+        <description>test cert</description>
+        <state>NORMAL</state>
+        <createTime>2018-11-17T02:15:04.000Z</createTime>
+        <expiryTime>2019-11-17T02:05:54.000Z</expiryTime>
+    </sslDomainCertificate>
+</sslDomainCertificates>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/ssl_get_cert_chain.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/ssl_get_cert_chain.xml b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_get_cert_chain.xml
new file mode 100644
index 0000000..68b545b
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_get_cert_chain.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sslCertificateChain xmlns="urn:didata.com:api:cloud:types" id="dc5a4235-2f1b-47e1-b6dd-455938a3377b" datacenterId="EU6">
+    <networkDomainId>6aafcf08-cb0b-432c-9c64-7371265db086</networkDomainId>
+    <name>ted_carol</name>
+    <description>test cert chain</description>
+    <state>NORMAL</state>
+    <createTime>2018-11-19T02:07:32.000Z</createTime>
+    <expiryTime>2019-11-19T00:21:30.000Z</expiryTime>
+</sslCertificateChain>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/ssl_import_cert_chain.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/ssl_import_cert_chain.xml b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_import_cert_chain.xml
new file mode 100644
index 0000000..3567572
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_import_cert_chain.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<response xmlns="urn:didata.com:api:cloud:types" requestId="eu_20181119T183847180+0100_4adcc201-ef53-4756-a115-7cfa5291e87d">
+    <operation>IMPORT_SSL_CERTIFICATE_CHAIN</operation>
+    <responseCode>OK</responseCode>
+    <message>SSL Certificate Chain has been imported.</message>
+    <info name="sslCertificateChainId" value="14613439-c24b-45c2-bd53-af4ef6fabd43"/>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/fixtures/nttcis/ssl_list_cert_chain_by_name.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/fixtures/nttcis/ssl_list_cert_chain_by_name.xml b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_list_cert_chain_by_name.xml
new file mode 100644
index 0000000..a268b77
--- /dev/null
+++ b/libcloud/test/loadbalancer/fixtures/nttcis/ssl_list_cert_chain_by_name.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sslCertificateChains xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="1" totalCount="1" pageSize="250">
+    <sslCertificateChain id="dc5a4235-2f1b-47e1-b6dd-455938a3377b" datacenterId="EU6">
+        <networkDomainId>6aafcf08-cb0b-432c-9c64-7371265db086</networkDomainId>
+        <name>ted_carol</name>
+        <description>test cert chain</description>
+        <state>NORMAL</state>
+        <createTime>2018-11-19T02:07:32.000Z</createTime>
+        <expiryTime>2019-11-19T00:21:30.000Z</expiryTime>
+    </sslCertificateChain>
+</sslCertificateChains>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/libcloud/test/loadbalancer/test_nttcis.py
----------------------------------------------------------------------
diff --git a/libcloud/test/loadbalancer/test_nttcis.py b/libcloud/test/loadbalancer/test_nttcis.py
index 1d99fc6..81d42a5 100644
--- a/libcloud/test/loadbalancer/test_nttcis.py
+++ b/libcloud/test/loadbalancer/test_nttcis.py
@@ -19,6 +19,7 @@ from libcloud.utils.py3 import httplib
 from libcloud.common.types import InvalidCredsError
 from libcloud.common.nttcis import NttCisVIPNode, NttCisPool
 from libcloud.common.nttcis import NttCisPoolMember
+from libcloud.common.nttcis import NttCisAPIException
 from libcloud.loadbalancer.base import LoadBalancer, Member, Algorithm
 from libcloud.loadbalancer.drivers.nttcis import NttCisLBDriver as NttCis
 from libcloud.loadbalancer.types import State
@@ -518,6 +519,24 @@ def test_ex_get_default_irules(driver):
     assert irules[0].compatible_listeners[0].type == 'PERFORMANCE_LAYER_4'
 
 
+def test_ex_insert_ssl_certificate(driver):
+    net_dom_id = "6aafcf08-cb0b-432c-9c64-7371265db086 "
+    cert = 'fixtures/nttcis/alice.crt'
+    key = 'fixtures/nttcis/alice.key'
+    result = driver.ex_import_ssl_cert(net_dom_id, "alice", cert, key, description="test cert")
+    assert result is True
+
+
+def test_ex_insert_ssl_certificate_FAIL(driver):
+    NttCisMockHttp.type = "FAIL"
+    net_dom_id = "6aafcf08-cb0b-432c-9c64-7371265db086 "
+    cert = 'fixtures/nttcis/denis.crt'
+    key = 'fixtures/nttcis/denis.key'
+    with pytest.raises(NttCisAPIException) as excinfo:
+        result = driver.ex_import_ssl_cert(net_dom_id, "denis", cert, key, description="test cert")
+    assert excinfo.value.msg == "Data Center EU6 requires key length must be one of 512, 1024, 2048."
+
+
 class NttCisMockHttp(MockHttp):
 
     fixtures = LoadBalancerFileFixtures('nttcis')
@@ -529,7 +548,7 @@ class NttCisMockHttp(MockHttp):
         body = self.fixtures.load('oec_0_9_myaccount.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
-    def _oec_0_9_myaccount_INPROGRESS(self, method, url, body, headers):
+    def _oec_0_9_myaccount_FAIL(self, method, url, body, headers):
         body = self.fixtures.load('oec_0_9_myaccount.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
@@ -643,5 +662,24 @@ class NttCisMockHttp(MockHttp):
             'networkDomainVip_defaultIrule.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _caas_2_7_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_importSslDomainCertificate(self,
+                                                                                                   method,
+                                                                                                   url,
+                                                                                                   body,
+                                                                                                   headers):
+        body = self.fixtures.load(
+            "ssl_import_success.xml"
+        )
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_7_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_networkDomainVip_importSslDomainCertificate_FAIL(self,
+                                                                                                        method,                                                                                                           url,
+                                                                                                        body,
+                                                                                                        headers):
+        body = self.fixtures.load(
+            "ssl_import_fail.xml"
+        )
+        return (httplib.BAD_REQUEST, body, {}, httplib.responses[httplib.OK])
+
 if __name__ == '__main__':
     sys.exit(unittest.main())

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/tests/lib_create_test.py
----------------------------------------------------------------------
diff --git a/tests/lib_create_test.py b/tests/lib_create_test.py
index 944cea0..250d087 100644
--- a/tests/lib_create_test.py
+++ b/tests/lib_create_test.py
@@ -296,7 +296,15 @@ def test_initiate_failover(drsdriver):
 def test_insert_ssl(lbdriver, compute_driver):
     net_dom_name = "sdk_test_1"
     net_dom = compute_driver.ex_list_network_domains(name=net_dom_name)[0]
-    cert = '/home/mraful/client/alice.crt'
-    key = '/home/mraful/client/alice.key'
-    result = lbdriver.import_ssl_cert(net_dom.id, "alice", cert, key, description="test cert")
+    cert = '/home/mraful/client/bob.crt'
+    key = '/home/mraful/client/bob.key'
+    result = lbdriver.ex_import_ssl_cert(net_dom.id, "bob", cert, key, description="test cert")
+    assert result is True
+
+
+def test_insert_ssl_chain(lbdriver, compute_driver):
+    net_dom_name = "sdk_test_1"
+    net_dom = compute_driver.ex_list_network_domains(name=net_dom_name)[0]
+    cert = '/home/mraful/client/chain.crt'
+    result = lbdriver.ex_import_ssl_cert_chain(net_dom.id, "ted_carol", cert, description="test cert chain")
     assert result is True
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9e347241/tests/lib_list_test.py
----------------------------------------------------------------------
diff --git a/tests/lib_list_test.py b/tests/lib_list_test.py
index 650984e..0c25529 100644
--- a/tests/lib_list_test.py
+++ b/tests/lib_list_test.py
@@ -426,7 +426,32 @@ def test_get_snapshots_by_min(drsdriver):
         print(snap)
 
 
-def test_list_domain_certs(compute_driver, lbdriver):
+def test_list_domain_certs(lbdriver):
     certs = lbdriver.ex_list_ssl_domain_certs()
     for cert in certs:
-        print(cert)
\ No newline at end of file
+        print(cert)
+
+
+def test_list_domain_certs_by_name(lbdriver):
+    certs = lbdriver.ex_list_ssl_domain_certs(name="alice")
+    for cert in certs:
+        print(cert)
+
+
+def test_get_domain_cert(lbdriver):
+    cert_id = "352146be-0d6a-40cf-b935-808ab504a868"
+    cert = lbdriver.ex_get_ssl_domain_cert(cert_id)
+    print(cert.name)
+
+
+def test_list_certificate_chains(lbdriver):
+    cert_name = "ted_carol"
+    certs = lbdriver.ex_list_certificate_chains(name=cert_name)
+    for cert in certs:
+        print(cert)
+
+
+def test_get_certificate_chain(lbdriver):
+    chain_id = "dc5a4235-2f1b-47e1-b6dd-455938a3377b"
+    cert_chain = lbdriver.ex_get_ssl_certificate_chain(chain_id)
+    print(cert_chain.name)
\ No newline at end of file