libcloud/compute/drivers/dimensiondata.py [109:540]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    features = {"create_node": ["password"]}
    api_version = 1.0

    def __init__(
        self,
        key,
        secret=None,
        secure=True,
        host=None,
        port=None,
        api_version=None,
        region=DEFAULT_REGION,
        **kwargs,
    ):
        if region not in API_ENDPOINTS and host is None:
            raise ValueError("Invalid region: %s, no host specified" % (region))
        if region is not None:
            self.selected_region = API_ENDPOINTS[region]

        if api_version is not None:
            self.api_version = api_version

        super().__init__(
            key=key,
            secret=secret,
            secure=secure,
            host=host,
            port=port,
            api_version=api_version,
            region=region,
            **kwargs,
        )

    def _ex_connection_class_kwargs(self):
        """
        Add the region to the kwargs before the connection is instantiated
        """

        kwargs = super()._ex_connection_class_kwargs()
        kwargs["region"] = self.selected_region
        kwargs["api_version"] = self.api_version
        return kwargs

    def _create_node_mcp1(
        self,
        name,
        image,
        auth,
        ex_description,
        ex_network=None,
        ex_memory_gb=None,
        ex_cpu_specification=None,
        ex_is_started=True,
        ex_primary_dns=None,
        ex_secondary_dns=None,
        **kwargs,
    ):
        """
        Create a new DimensionData node

        :keyword    name:   String with a name for this new node (required)
        :type       name:   ``str``

        :keyword    image:  OS Image to boot on node. (required)
        :type       image:  :class:`NodeImage` or ``str``

        :keyword    auth:   Initial authentication information for the
                            node. (If this is a customer LINUX
                            image auth will be ignored)
        :type       auth:   :class:`NodeAuthPassword` or ``str`` or
                            ``None``

        :keyword    ex_description:  description for this node (required)
        :type       ex_description:  ``str``

        :keyword    ex_network:  Network to create the node within
                                 (required unless using ex_network_domain
                                 or ex_primary_ipv4)

        :type       ex_network: :class:`DimensionDataNetwork` or ``str``

        :keyword    ex_memory_gb:  The amount of memory in GB for the
                                   server
        :type       ex_memory_gb: ``int``

        :keyword    ex_cpu_specification: The spec of CPU to deploy (
                                          optional)
        :type       ex_cpu_specification:
                        :class:`DimensionDataServerCpuSpecification`

        :keyword    ex_is_started:  Start server after creation? default
                                    true (required)
        :type       ex_is_started:  ``bool``

        :keyword    ex_primary_dns: The node's primary DNS

        :type       ex_primary_dns: ``str``

        :keyword    ex_secondary_dns: The node's secondary DNS

        :type       ex_secondary_dns: ``str``

        :return: The newly created :class:`Node`.
        :rtype: :class:`Node`
        """
        password = None
        image_needs_auth = self._image_needs_auth(image)
        if image_needs_auth:
            if isinstance(auth, basestring):
                auth_obj = NodeAuthPassword(password=auth)
                password = auth
            else:
                auth_obj = self._get_and_check_auth(auth)
                password = auth_obj.password

        server_elm = ET.Element("deployServer", {"xmlns": TYPES_URN})
        ET.SubElement(server_elm, "name").text = name
        ET.SubElement(server_elm, "description").text = ex_description
        image_id = self._image_to_image_id(image)
        ET.SubElement(server_elm, "imageId").text = image_id
        ET.SubElement(server_elm, "start").text = str(ex_is_started).lower()
        if password is not None:
            ET.SubElement(server_elm, "administratorPassword").text = password

        if ex_cpu_specification is not None:
            cpu = ET.SubElement(server_elm, "cpu")
            cpu.set("speed", ex_cpu_specification.performance)
            cpu.set("count", str(ex_cpu_specification.cpu_count))
            cpu.set("coresPerSocket", str(ex_cpu_specification.cores_per_socket))

        if ex_memory_gb is not None:
            ET.SubElement(server_elm, "memoryGb").text = str(ex_memory_gb)

        if ex_network is not None:
            network_elm = ET.SubElement(server_elm, "network")
            network_id = self._network_to_network_id(ex_network)
            ET.SubElement(network_elm, "networkId").text = network_id

        if ex_primary_dns:
            dns_elm = ET.SubElement(server_elm, "primaryDns")
            dns_elm.text = ex_primary_dns

        if ex_secondary_dns:
            dns_elm = ET.SubElement(server_elm, "secondaryDns")
            dns_elm.text = ex_secondary_dns

        response = self.connection.request_with_orgId_api_2(
            "server/deployServer", method="POST", data=ET.tostring(server_elm)
        ).object

        node_id = None
        for info in findall(response, "info", TYPES_URN):
            if info.get("name") == "serverId":
                node_id = info.get("value")

        node = self.ex_get_node_by_id(node_id)

        if image_needs_auth:
            if getattr(auth_obj, "generated", False):
                node.extra["password"] = auth_obj.password

        return node

    def create_node(
        self,
        name,
        image,
        auth,
        ex_network_domain=None,
        ex_primary_nic_private_ipv4=None,
        ex_primary_nic_vlan=None,
        ex_primary_nic_network_adapter=None,
        ex_additional_nics=None,
        ex_description=None,
        ex_disks=None,
        ex_cpu_specification=None,
        ex_memory_gb=None,
        ex_is_started=True,
        ex_primary_dns=None,
        ex_secondary_dns=None,
        ex_ipv4_gateway=None,
        ex_microsoft_time_zone=None,
        **kwargs,
    ):
        """
        Create a new DimensionData node in MCP2. However, it is still
        backward compatible for MCP1 for a limited time. Please consider
        using MCP2 datacenter as MCP1 will phase out soon.

        Legacy Create Node for MCP1 datacenter

        >>> from pprint import pprint
        >>> from libcloud.compute.types import Provider
        >>> from libcloud.compute.base import NodeAuthPassword
        >>> from libcloud.compute.providers import get_driver
        >>> import libcloud.security
        >>>
        >>> # Get dimension data driver
        >>> libcloud.security.VERIFY_SSL_CERT = False
        >>> DimensionData = get_driver(Provider.DIMENSIONDATA)
        >>> driver = cls('myusername','mypassword', region='dd-au')
        >>>
        >>> # Password
        >>> root_pw = NodeAuthPassword('password123')
        >>>
        >>> # Get location
        >>> location = driver.ex_get_location_by_id(id='AU1')
        >>>
        >>> # Get network by location
        >>> my_network = driver.list_networks(location=location)[0]
        >>> pprint(my_network)
        >>>
        >>> # Get Image
        >>> images = driver.list_images(location=location)
        >>> image = images[0]
        >>>
        >>> node = driver.create_node(name='test_blah_2', image=image,
        >>>                           auth=root_pw,
        >>>                           ex_description='test3 node',
        >>>                           ex_network=my_network,
        >>>                           ex_is_started=False)
        >>> pprint(node)


        Create Node in MCP2 Data Center

        >>> from pprint import pprint
        >>> from libcloud.compute.types import Provider
        >>> from libcloud.compute.base import NodeAuthPassword
        >>> from libcloud.compute.providers import get_driver
        >>> import libcloud.security
        >>>
        >>> # Get dimension data driver
        >>> libcloud.security.VERIFY_SSL_CERT = True
        >>> cls = get_driver(Provider.DIMENSIONDATA)
        >>> driver = cls('myusername','mypassword', region='dd-au')
        >>>
        >>> # Password
        >>> root_pw = NodeAuthPassword('password123')
        >>>
        >>> # Get location
        >>> location = driver.ex_get_location_by_id(id='AU9')
        >>>
        >>> # Get network domain by location
        >>> networkDomainName = "Baas QA"
        >>> network_domains = driver.ex_list_network_domains(location=location)
        >>> my_network_domain = [d for d in network_domains if d.name ==
                              networkDomainName][0]
        >>>
        >>> vlan = driver.ex_list_vlans(location=location,
        >>>                             network_domain=my_network_domain)[0]
        >>> pprint(vlan)
        >>>
        >>> # Get Image
        >>> images = driver.list_images(location=location)
        >>> image = images[0]
        >>>
        >>> # Create node using vlan instead of private IPv4
        >>> node = driver.create_node(name='test_server_01', image=image,
        >>>                           auth=root_pw,
        >>>                           ex_description='test2 node',
        >>>                           ex_network_domain=my_network_domain,
        >>>                           ex_primary_nic_vlan=vlan,
        >>>                           ex_is_started=False)
        >>>
        >>> # Option: Create node using private IPv4 instead of vlan
        >>> # node = driver.create_node(name='test_server_02', image=image,
        >>> #                           auth=root_pw,
        >>> #                           ex_description='test2 node',
        >>> #                           ex_network_domain=my_network_domain,
        >>> #                           ex_primary_nic_private_ipv4='10.1.1.7',
        >>> #                           ex_is_started=False)
        >>>
        >>> # Option: Create node using by specifying Network Adapter
        >>> # node = driver.create_node(name='test_server_03', image=image,
        >>> #                           auth=root_pw,
        >>> #                           ex_description='test2 node',
        >>> #                           ex_network_domain=my_network_domain,
        >>> #                           ex_primary_nic_vlan=vlan,
        >>> #                           ex_primary_nic_network_adapter='E1000',
        >>> #                           ex_is_started=False)
        >>>

        :keyword    name:   (required) String with a name for this new node
        :type       name:   ``str``

        :keyword    image:  (required) OS Image to boot on node.
        :type       image:  :class:`NodeImage` or ``str``

        :keyword    auth:   Initial authentication information for the
                            node. (If this is a customer LINUX
                            image auth will be ignored)
        :type       auth:   :class:`NodeAuthPassword` or ``str`` or ``None``

        :keyword    ex_description:  (optional) description for this node
        :type       ex_description:  ``str``


        :keyword    ex_network_domain:  (required) Network Domain or Network
                                        Domain ID to create the node
        :type       ex_network_domain: :class:`DimensionDataNetworkDomain`
                                        or ``str``

        :keyword    ex_primary_nic_private_ipv4:  Provide private IPv4. Ignore
                                                  if ex_primary_nic_vlan is
                                                  provided. Use one or the
                                                  other. Not both.
        :type       ex_primary_nic_private_ipv4: :``str``

        :keyword    ex_primary_nic_vlan:  Provide VLAN for the node if
                                          ex_primary_nic_private_ipv4 NOT
                                          provided. One or the other. Not both.
        :type       ex_primary_nic_vlan: :class: DimensionDataVlan or ``str``

        :keyword    ex_primary_nic_network_adapter: (Optional) Default value
                                                    for the Operating System
                                                    will be used if leave
                                                    empty. Example: "E1000".
        :type       ex_primary_nic_network_adapter: :``str``

        :keyword    ex_additional_nics: (optional) List
                                        :class:'DimensionDataNic' or None
        :type       ex_additional_nics: ``list`` of :class:'DimensionDataNic'
                                        or ``str``

        :keyword    ex_memory_gb:  (optional) The amount of memory in GB for
                                   the server Can be used to override the
                                   memory value inherited from the source
                                   Server Image.
        :type       ex_memory_gb: ``int``

        :keyword    ex_cpu_specification: (optional) The spec of CPU to deploy
        :type       ex_cpu_specification:
                        :class:`DimensionDataServerCpuSpecification`

        :keyword    ex_is_started: (required) Start server after creation.
                                   Default is set to true.
        :type       ex_is_started:  ``bool``

        :keyword    ex_primary_dns: (Optional) The node's primary DNS
        :type       ex_primary_dns: ``str``

        :keyword    ex_secondary_dns: (Optional) The node's secondary DNS
        :type       ex_secondary_dns: ``str``

        :keyword    ex_ipv4_gateway: (Optional) IPv4 address in dot-decimal
                                     notation, which will be used as the
                                     Primary NIC gateway instead of the default
                                     gateway assigned by the system. If
                                     ipv4Gateway is provided it does not have
                                     to be on the VLAN of the Primary NIC
                                     but MUST be reachable or the Guest OS
                                     will not be configured correctly.
        :type       ex_ipv4_gateway: ``str``

        :keyword    ex_disks: (optional) Dimensiondata disks. Optional disk
                            elements can be used to define the disk speed
                            that each disk on the Server; inherited from the
                            source Server Image will be deployed to. It is
                            not necessary to include a diskelement for every
                            disk; only those that you wish to set a disk
                            speed value for. Note that scsiId 7 cannot be
                            used.Up to 13 disks can be present in addition to
                            the required OS disk on SCSI ID 0. Refer to
                            https://docs.mcp-services.net/x/UwIu for disk

        :type       ex_disks: List or tuple of :class:'DimensionDataServerDisk`

        :keyword    ex_microsoft_time_zone: (optional) For use with
                    Microsoft Windows source Server Images only. For the exact
                    value to use please refer to the table of time zone
                    indexes in the following Microsoft Technet
                    documentation. If none is supplied, the default time
                    zone for the data center geographic region will be used.
        :type       ex_microsoft_time_zone: `str``


        :return: The newly created :class:`Node`.
        :rtype: :class:`Node`
        """

        # Neither legacy MCP1 network nor MCP2 network domain provided
        if ex_network_domain is None and "ex_network" not in kwargs:
            raise ValueError(
                "You must provide either ex_network_domain "
                "for MCP2 or ex_network for legacy MCP1"
            )

        # Ambiguous parameter provided. Can't determine if it is MCP 1 or 2.
        if ex_network_domain is not None and "ex_network" in kwargs:
            raise ValueError(
                "You can only supply either "
                "ex_network_domain "
                "for MCP2 or ex_network for legacy MCP1"
            )

        # Set ex_is_started to False by default if none bool data type provided
        if not isinstance(ex_is_started, bool):
            ex_is_started = True

        # Handle MCP1 legacy
        if "ex_network" in kwargs:
            new_node = self._create_node_mcp1(
                name=name,
                image=image,
                auth=auth,
                ex_network=kwargs.get("ex_network"),
                ex_description=ex_description,
                ex_memory_gb=ex_memory_gb,
                ex_cpu_specification=ex_cpu_specification,
                ex_is_started=ex_is_started,
                ex_primary_ipv4=ex_primary_nic_private_ipv4,
                ex_disks=ex_disks,
                ex_additional_nics_vlan=kwargs.get("ex_additional_nics_vlan"),
                ex_additional_nics_ipv4=kwargs.get("ex_additional_nics_ipv4"),
                ex_primary_dns=ex_primary_dns,
                ex_secondary_dns=ex_secondary_dns,
            )
        else:
            # Handle MCP2 legacy. CaaS api 2.2 or earlier
            if "ex_vlan" in kwargs:
                ex_primary_nic_vlan = kwargs.get("ex_vlan")

            if "ex_primary_ipv4" in kwargs:
                ex_primary_nic_private_ipv4 = kwargs.get("ex_primary_ipv4")

            additional_nics = []

            if "ex_additional_nics_vlan" in kwargs:
                vlans = kwargs.get("ex_additional_nics_vlan")
                if isinstance(vlans, (list, tuple)):
                    for v in vlans:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



libcloud/compute/drivers/nttcis.py [112:555]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    features = {"create_node": ["password"]}
    api_version = 1.0

    def __init__(
        self,
        key,
        secret=None,
        secure=True,
        host=None,
        port=None,
        api_version=None,
        region=DEFAULT_REGION,
        **kwargs,
    ):
        if region not in API_ENDPOINTS and host is None:
            raise ValueError("Invalid region: %s, no host specified" % (region))

        if region is not None:
            self.selected_region = API_ENDPOINTS[region]

        if api_version is not None:
            self.api_version = api_version

        super().__init__(
            key=key,
            secret=secret,
            secure=secure,
            host=host,
            port=port,
            api_version=api_version,
            region=region,
            **kwargs,
        )

    def _ex_connection_class_kwargs(self):
        """
        Add the region to the kwargs before the connection is instantiated
        """

        kwargs = super()._ex_connection_class_kwargs()
        kwargs["region"] = self.selected_region
        kwargs["api_version"] = self.api_version

        return kwargs

    def _create_node_mcp1(
        self,
        name,
        image,
        auth,
        ex_description,
        ex_network=None,
        ex_memory_gb=None,
        ex_cpu_specification=None,
        ex_is_started=True,
        ex_primary_dns=None,
        ex_secondary_dns=None,
        **kwargs,
    ):
        """
        Create a new NTTCIS node

        :keyword    name:   String with a name for this new node (required)
        :type       name:   ``str``

        :keyword    image:  OS Image to boot on node. (required)
        :type       image:  :class:`NodeImage` or ``str``

        :keyword    auth:   Initial authentication information for the
                            node. (If this is a customer LINUX
                            image auth will be ignored)
        :type       auth:   :class:`NodeAuthPassword` or ``str`` or
                            ``None``

        :keyword    ex_description:  description for this node (required)
        :type       ex_description:  ``str``

        :keyword    ex_network:  Network to create the node within
                                 (required unless using ex_network_domain
                                 or ex_primary_ipv4)

        :type       ex_network: :class:`NttCisNetwork` or ``str``

        :keyword    ex_memory_gb:  The amount of memory in GB for the
                                   server
        :type       ex_memory_gb: ``int``

        :keyword    ex_cpu_specification: The spec of CPU to deploy (
                                          optional)
        :type       ex_cpu_specification:
                        :class:`DimensionDataServerCpuSpecification`

        :keyword    ex_is_started:  Start server after creation? default
                                    true (required)
        :type       ex_is_started:  ``bool``

        :keyword    ex_primary_dns: The node's primary DNS

        :type       ex_primary_dns: ``str``

        :keyword    ex_secondary_dns: The node's secondary DNS

        :type       ex_secondary_dns: ``str``

        :return: The newly created :class:`Node`.
        :rtype: :class:`Node`
        """

        password = None
        image_needs_auth = self._image_needs_auth(image)

        if image_needs_auth:
            if isinstance(auth, basestring):
                auth_obj = NodeAuthPassword(password=auth)
                password = auth
            else:
                auth_obj = self._get_and_check_auth(auth)
                password = auth_obj.password

        server_elm = ET.Element("deployServer", {"xmlns": TYPES_URN})
        ET.SubElement(server_elm, "name").text = name
        ET.SubElement(server_elm, "description").text = ex_description
        image_id = self._image_to_image_id(image)
        ET.SubElement(server_elm, "imageId").text = image_id
        ET.SubElement(server_elm, "start").text = str(ex_is_started).lower()

        if password is not None:
            ET.SubElement(server_elm, "administratorPassword").text = password

        if ex_cpu_specification is not None:
            cpu = ET.SubElement(server_elm, "cpu")
            cpu.set("speed", ex_cpu_specification.performance)
            cpu.set("count", str(ex_cpu_specification.cpu_count))
            cpu.set("coresPerSocket", str(ex_cpu_specification.cores_per_socket))

        if ex_memory_gb is not None:
            ET.SubElement(server_elm, "memoryGb").text = str(ex_memory_gb)

        if ex_network is not None:
            network_elm = ET.SubElement(server_elm, "network")
            network_id = self._network_to_network_id(ex_network)
            ET.SubElement(network_elm, "networkId").text = network_id

        if ex_primary_dns:
            dns_elm = ET.SubElement(server_elm, "primaryDns")
            dns_elm.text = ex_primary_dns

        if ex_secondary_dns:
            dns_elm = ET.SubElement(server_elm, "secondaryDns")
            dns_elm.text = ex_secondary_dns

        response = self.connection.request_with_orgId_api_2(
            "server/deployServer", method="POST", data=ET.tostring(server_elm)
        ).object

        node_id = None

        for info in findall(response, "info", TYPES_URN):
            if info.get("name") == "serverId":
                node_id = info.get("value")

        node = self.ex_get_node_by_id(node_id)

        if image_needs_auth:
            if getattr(auth_obj, "generated", False):
                node.extra["password"] = auth_obj.password

        return node

    def create_node(
        self,
        name,
        image,
        auth,
        ex_network_domain=None,
        ex_primary_nic_private_ipv4=None,
        ex_primary_nic_vlan=None,
        ex_primary_nic_network_adapter=None,
        ex_additional_nics=None,
        ex_description=None,
        ex_disks=None,
        ex_cpu_specification=None,
        ex_memory_gb=None,
        ex_is_started=True,
        ex_primary_dns=None,
        ex_secondary_dns=None,
        ex_ipv4_gateway=None,
        ex_microsoft_time_zone=None,
        **kwargs,
    ):
        """
        Create a new NTTCIS node in MCP2. However, it is still
        backward compatible for MCP1 for a limited time. Please consider
        using MCP2 datacenter as MCP1 will phase out soon.

        Legacy Create Node for MCP1 datacenter

        >>> from pprint import pprint
        >>> from libcloud.compute.types import Provider
        >>> from libcloud.compute.base import NodeAuthPassword
        >>> from libcloud.compute.providers import get_driver
        >>> import libcloud.security
        >>>
        >>> # Get NTTC-CIS driver
        >>> libcloud.security.VERIFY_SSL_CERT = False
        >>> NTTCIS = get_driver(Provider.NTTCIS)
        >>> driver = cls('myusername','mypassword', region='dd-au')
        >>>
        >>> # Password
        >>> root_pw = NodeAuthPassword('password123')
        >>>
        >>> # Get location
        >>> location = driver.ex_get_location_by_id(id='AU1')
        >>>
        >>> # Get network by location
        >>> my_network = driver.list_networks(location=location)[0]
        >>> pprint(my_network)
        >>>
        >>> # Get Image
        >>> images = driver.list_images(location=location)
        >>> image = images[0]
        >>>
        >>> node = driver.create_node(name='test_blah_2', image=image,
        >>>                           auth=root_pw,
        >>>                           ex_description='test3 node',
        >>>                           ex_network=my_network,
        >>>                           ex_is_started=False)
        >>> pprint(node)


        Create Node in MCP2 Data CenterF

        >>> from pprint import pprint
        >>> from libcloud.compute.types import Provider
        >>> from libcloud.compute.base import NodeAuthPassword
        >>> from libcloud.compute.providers import get_driver
        >>> import libcloud.security
        >>>
        >>> # Get NTTC-CIS driver
        >>> libcloud.security.VERIFY_SSL_CERT = True
        >>> cls = get_driver(Provider.NTTCIS)
        >>> driver = cls('myusername','mypassword', region='dd-au')
        >>>
        >>> # Password
        >>> root_pw = NodeAuthPassword('password123')
        >>>
        >>> # Get location
        >>> location = driver.ex_get_location_by_id(id='AU9')
        >>>
        >>> # Get network domain by location
        >>> networkDomainName = "Baas QA"
        >>> network_domains = driver.ex_list_network_domains(location=location)
        >>> my_network_domain = [d for d in network_domains if d.name ==
                              networkDomainName][0]
        >>>
        >>> vlan = driver.ex_list_vlans(location=location,
        >>>                             network_domain=my_network_domain)[0]
        >>> pprint(vlan)
        >>>
        >>> # Get Image
        >>> images = driver.list_images(location=location)
        >>> image = images[0]
        >>>
        >>> # Create node using vlan instead of private IPv4
        >>> node = driver.create_node(name='test_server_01', image=image,
        >>>                           auth=root_pw,
        >>>                           ex_description='test2 node',
        >>>                           ex_network_domain=my_network_domain,
        >>>                           ex_primary_nic_vlan=vlan,
        >>>                           ex_is_started=False)
        >>>
        >>> # Option: Create node using private IPv4 instead of vlan
        >>> # node = driver.create_node(name='test_server_02', image=image,
        >>> #                           auth=root_pw,
        >>> #                           ex_description='test2 node',
        >>> #                           ex_network_domain=my_network_domain,
        >>> #                           ex_primary_nic_private_ipv4='10.1.1.7',
        >>> #                           ex_is_started=False)
        >>>
        >>> # Option: Create node using by specifying Network Adapter
        >>> # node = driver.create_node(name='test_server_03', image=image,
        >>> #                           auth=root_pw,
        >>> #                           ex_description='test2 node',
        >>> #                           ex_network_domain=my_network_domain,
        >>> #                           ex_primary_nic_vlan=vlan,
        >>> #                           ex_primary_nic_network_adapter='E1000',
        >>> #                           ex_is_started=False)
        >>>

        :keyword    name:   (required) String with a name for this new node
        :type       name:   ``str``

        :keyword    image:  (required) OS Image to boot on node.
        :type       image:  :class:`NodeImage` or ``str``

        :keyword    auth:   Initial authentication information for the
                            node. (If this is a customer LINUX
                            image auth will be ignored)
        :type       auth:   :class:`NodeAuthPassword` or ``str`` or ``None``

        :keyword    ex_description:  (optional) description for this node
        :type       ex_description:  ``str``


        :keyword    ex_network_domain:  (required) Network Domain or Network
                                        Domain ID to create the node
        :type       ex_network_domain: :class:`DimensionDataNetworkDomain`
                                        or ``str``

        :keyword    ex_primary_nic_private_ipv4:  Provide private IPv4. Ignore
                                                  if ex_primary_nic_vlan is
                                                  provided. Use one or the
                                                  other. Not both.
        :type       ex_primary_nic_private_ipv4: :``str``

        :keyword    ex_primary_nic_vlan:  Provide VLAN for the node if
                                          ex_primary_nic_private_ipv4 NOT
                                          provided. One or the other. Not both.
        :type       ex_primary_nic_vlan: :class: DimensionDataVlan or ``str``

        :keyword    ex_primary_nic_network_adapter: (Optional) Default value
                                                    for the Operating System
                                                    will be used if leave
                                                    empty. Example: "E1000".
        :type       ex_primary_nic_network_adapter: :``str``

        :keyword    ex_additional_nics: (optional) List
                                        :class:'NttCisNic' or None
        :type       ex_additional_nics: ``list`` of :class:'NttCisNic'
                                        or ``str``

        :keyword    ex_memory_gb:  (optional) The amount of memory in GB for
                                   the server Can be used to override the
                                   memory value inherited from the source
                                   Server Image.
        :type       ex_memory_gb: ``int``

        :keyword    ex_cpu_specification: (optional) The spec of CPU to deploy
        :type       ex_cpu_specification:
                        :class:`DimensionDataServerCpuSpecification`

        :keyword    ex_is_started: (required) Start server after creation.
                                   Default is set to true.
        :type       ex_is_started:  ``bool``

        :keyword    ex_primary_dns: (Optional) The node's primary DNS
        :type       ex_primary_dns: ``str``

        :keyword    ex_secondary_dns: (Optional) The node's secondary DNS
        :type       ex_secondary_dns: ``str``

        :keyword    ex_ipv4_gateway: (Optional) IPv4 address in dot-decimal
                                     notation, which will be used as the
                                     Primary NIC gateway instead of the default
                                     gateway assigned by the system. If
                                     ipv4Gateway is provided it does not have
                                     to be on the VLAN of the Primary NIC
                                     but MUST be reachable or the Guest OS
                                     will not be configured correctly.
        :type       ex_ipv4_gateway: ``str``

        :keyword    ex_disks: (optional) NTTCIS disks. Optional disk
                            elements can be used to define the disk speed
                            that each disk on the Server; inherited from the
                            source Server Image will be deployed to. It is
                            not necessary to include a diskelement for every
                            disk; only those that you wish to set a disk
                            speed value for. Note that scsiId 7 cannot be
                            used.Up to 13 disks can be present in addition to
                            the required OS disk on SCSI ID 0. Refer to
                            https://docs.mcp-services.net/x/UwIu for disk

        :type       ex_disks: List or tuple of :class:'DimensionDataServerDisk`

        :keyword    ex_microsoft_time_zone: (optional) For use with
                    Microsoft Windows source Server Images only. For the exact
                    value to use please refer to the table of time zone
                    indexes in the following Microsoft Technet
                    documentation. If none is supplied, the default time
                    zone for the data center geographic region will be used.
        :type       ex_microsoft_time_zone: `str``


        :return: The newly created :class:`Node`.
        :rtype: :class:`Node`
        """

        # Neither legacy MCP1 network nor MCP2 network domain provided

        if ex_network_domain is None and "ex_network" not in kwargs:
            raise ValueError(
                "You must provide either ex_network_domain "
                "for MCP2 or ex_network for legacy MCP1"
            )

        # Ambiguous parameter provided. Can't determine if it is MCP 1 or 2.

        if ex_network_domain is not None and "ex_network" in kwargs:
            raise ValueError(
                "You can only supply either "
                "ex_network_domain "
                "for MCP2 or ex_network for legacy MCP1"
            )

        # Set ex_is_started to False by default if none bool data type provided

        if not isinstance(ex_is_started, bool):
            ex_is_started = True

        # Handle MCP1 legacy

        if "ex_network" in kwargs:
            new_node = self._create_node_mcp1(
                name=name,
                image=image,
                auth=auth,
                ex_network=kwargs.get("ex_network"),
                ex_description=ex_description,
                ex_memory_gb=ex_memory_gb,
                ex_cpu_specification=ex_cpu_specification,
                ex_is_started=ex_is_started,
                ex_primary_ipv4=ex_primary_nic_private_ipv4,
                ex_disks=ex_disks,
                ex_additional_nics_vlan=kwargs.get("ex_additional_nics_vlan"),
                ex_additional_nics_ipv4=kwargs.get("ex_additional_nics_ipv4"),
                ex_primary_dns=ex_primary_dns,
                ex_secondary_dns=ex_secondary_dns,
            )
        else:
            # Handle MCP2 legacy. CaaS api 2.2 or earlier

            if "ex_vlan" in kwargs:
                ex_primary_nic_vlan = kwargs.get("ex_vlan")

            if "ex_primary_ipv4" in kwargs:
                ex_primary_nic_private_ipv4 = kwargs.get("ex_primary_ipv4")

            additional_nics = []

            if "ex_additional_nics_vlan" in kwargs:
                vlans = kwargs.get("ex_additional_nics_vlan")

                if isinstance(vlans, (list, tuple)):
                    for v in vlans:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



