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 2016/10/10 00:02:00 UTC
[06/13] libcloud git commit: Added Edit firewall rule feature and
CRUD operation for IpAddressList, PortList in DD driver
Added Edit firewall rule feature and CRUD operation for IpAddressList, PortList in DD driver
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/2eb1b4a3
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/2eb1b4a3
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/2eb1b4a3
Branch: refs/heads/trunk
Commit: 2eb1b4a32e1048d063da0ebea4cac01f2da60270
Parents: e6d582e
Author: Samuel Chong <sa...@gmail.com>
Authored: Thu Oct 6 11:43:28 2016 +1100
Committer: Samuel Chong <sa...@gmail.com>
Committed: Thu Oct 6 11:43:28 2016 +1100
----------------------------------------------------------------------
libcloud/compute/drivers/dimensiondata.py | 640 +++++++++++++++++++++++++
1 file changed, 640 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/2eb1b4a3/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index 9bdeb86..89f7c66 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -38,6 +38,13 @@ from libcloud.common.dimensiondata import DimensionDataFirewallRule
from libcloud.common.dimensiondata import DimensionDataFirewallAddress
from libcloud.common.dimensiondata import DimensionDataNatRule
from libcloud.common.dimensiondata import DimensionDataAntiAffinityRule
+from libcloud.common.dimensiondata import DimensionDataIpAddressList
+from libcloud.common.dimensiondata import DimensionDataChildIpAddressList
+from libcloud.common.dimensiondata import DimensionDataIpAddress
+from libcloud.common.dimensiondata import DimensionDataPortList
+from libcloud.common.dimensiondata import DimensionDataPort
+from libcloud.common.dimensiondata import DimensionDataChildPortList
+from libcloud.common.dimensiondata import DimensionDataNic
from libcloud.common.dimensiondata import NetworkDomainServicePlan
from libcloud.common.dimensiondata import DimensionDataTagKey
from libcloud.common.dimensiondata import DimensionDataTag
@@ -1470,6 +1477,113 @@ class DimensionDataNodeDriver(NodeDriver):
rule.id = rule_id
return rule
+ def ex_edit_firewall_rule(self, rule, position,
+ relative_rule_for_position=None):
+ """
+ Edit a firewall rule
+
+ :param rule: (required) The rule in which to create
+ :type rule: :class:`DimensionDataFirewallRule`
+
+ :param position: (required) There are two types of positions
+ with position_relative_to_rule arg and without it
+ With: 'BEFORE' or 'AFTER'
+ Without: 'FIRST' or 'LAST'
+ :type position: ``str``
+
+ :param relative_rule_for_position: (optional) The rule or rule name in
+ which to decide the relative rule
+ for positioning.
+ :type relative_rule_for_position:
+ :class:`DimensionDataFirewallRule` or ``str``
+
+ :rtype: ``bool``
+ """
+
+ positions_without_rule = ('FIRST', 'LAST')
+ positions_with_rule = ('BEFORE', 'AFTER')
+
+ edit_node = ET.Element('editFirewallRule',
+ {'xmlns': TYPES_URN, 'id': rule.id})
+ ET.SubElement(edit_node, "action").text = rule.action
+ ET.SubElement(edit_node, "protocol").text = rule.protocol
+
+ # Source address
+ source = ET.SubElement(edit_node, "source")
+ if rule.source.address_list_id is not None:
+ source_ip = ET.SubElement(source, 'ipAddressListId')
+ source_ip.text = rule.source.address_list_id
+ else:
+ source_ip = ET.SubElement(source, 'ip')
+ if rule.source.any_ip:
+ source_ip.set('address', 'ANY')
+ else:
+ source_ip.set('address', rule.source.ip_address)
+ if rule.source.ip_prefix_size is not None:
+ source_ip.set('prefixSize',
+ str(rule.source.ip_prefix_size))
+
+ # Setup source port rule
+ if rule.source.port_list_id is not None:
+ source_port = ET.SubElement(source, 'portListId')
+ source_port.text = rule.source.port_list_id
+ else:
+ if rule.source.port_begin is not None:
+ source_port = ET.SubElement(source, 'port')
+ source_port.set('begin', rule.source.port_begin)
+ if rule.source.port_end is not None:
+ source_port.set('end', rule.source.port_end)
+ # Setup destination port rule
+ dest = ET.SubElement(edit_node, "destination")
+ if rule.destination.address_list_id is not None:
+ dest_ip = ET.SubElement(dest, 'ipAddressListId')
+ dest_ip.text = rule.destination.address_list_id
+ else:
+ dest_ip = ET.SubElement(dest, 'ip')
+ if rule.destination.any_ip:
+ dest_ip.set('address', 'ANY')
+ else:
+ dest_ip.set('address', rule.destination.ip_address)
+ if rule.destination.ip_prefix_size is not None:
+ dest_ip.set('prefixSize', rule.destination.ip_prefix_size)
+ if rule.destination.port_list_id is not None:
+ dest_port = ET.SubElement(dest, 'portListId')
+ dest_port.text = rule.destination.port_list_id
+ else:
+ if rule.destination.port_begin is not None:
+ dest_port = ET.SubElement(dest, 'port')
+ dest_port.set('begin', rule.destination.port_begin)
+ if rule.destination.port_end is not None:
+ dest_port.set('end', rule.destination.port_end)
+ # Set up positioning of rule
+ ET.SubElement(edit_node, "enabled").text = str(rule.enabled).lower()
+ placement = ET.SubElement(edit_node, "placement")
+ if relative_rule_for_position is not None:
+ if position not in positions_with_rule:
+ raise ValueError("When position_relative_to_rule is specified"
+ " position must be %s"
+ % ', '.join(positions_with_rule))
+ if isinstance(relative_rule_for_position,
+ DimensionDataFirewallRule):
+ rule_name = relative_rule_for_position.name
+ else:
+ rule_name = relative_rule_for_position
+ placement.set('relativeToRule', rule_name)
+ else:
+ if position not in positions_without_rule:
+ raise ValueError("When position_relative_to_rule is not"
+ " specified position must be %s"
+ % ', '.join(positions_without_rule))
+ placement.set('position', position)
+
+ response = self.connection.request_with_orgId_api_2(
+ 'network/editFirewallRule',
+ method='POST',
+ data=ET.tostring(edit_node)).object
+
+ response_code = findtext(response, 'responseCode', TYPES_URN)
+ return response_code in ['IN_PROGRESS', 'OK']
+
def ex_get_firewall_rule(self, network_domain, rule_id):
locations = self.list_locations()
rule = self.connection.request_with_orgId_api_2(
@@ -2379,6 +2493,427 @@ class DimensionDataNodeDriver(NodeDriver):
% (datacenter_id, start_date, end_date))
return self._format_csv(result.response)
+ def ex_list_ip_address_list(self, ex_network_domain):
+ """
+ List IP Address List by network domain ID specified
+
+ :param ex_network_domain: The network domain or network domain ID
+ :type ex_network_domain: :class:`DimensionDataNetworkDomain` or 'str'
+
+ :return: a list of DimensionDataIpAddressList objects
+ :rtype: ``list`` of :class:`DimensionDataIpAddressList`
+ """
+ params = {'networkDomainId': self._network_domain_to_network_domain_id(
+ ex_network_domain)}
+ response = self.connection.request_with_orgId_api_2(
+ 'network/ipAddressList', params=params).object
+ return self._to_ip_address_lists(response)
+
+ def ex_get_ip_address_list(self, ex_network_domain,
+ ex_ip_address_list_name):
+ """
+ Get IP Address List by name in network domain specified
+
+ :param ex_network_domain: (required) The network domain or network
+ domain ID in which ipaddresslist resides.
+ :type ex_network_domain: :class:`DimensionDataNetworkDomain` or 'str'
+
+ :param ex_ip_address_list_name: (required) Get 'IP Address List' by
+ name
+ :type ex_ip_address_list_name: :``str``
+
+ :return: a list of DimensionDataIpAddressList objects
+ :rtype: ``list`` of :class:`DimensionDataIpAddressList`
+ """
+
+ ip_address_lists = self.ex_list_ip_address_list(ex_network_domain)
+ return list(filter(lambda x: x.name == ex_ip_address_list_name,
+ ip_address_lists))
+
+ def ex_create_ip_address_list(self, ex_network_domain, name,
+ description,
+ ip_version, ip_address_collection,
+ child_ip_address_list=None):
+ """
+ Create IP Address List. IP Address list.
+
+ :param ex_network_domain: The network domain or network domain ID
+ :type ex_network_domain: :class:`DimensionDataNetworkDomain` or 'str'
+
+ :param name: IP Address List Name (required)
+ :type name: :``str``
+
+ :param description: IP Address List Description (optional)
+ :type description: :``str``
+
+ :param ip_version: IP Version of ip address (required)
+ :type ip_version: :``str``
+
+ :param ip_address_collection: List of IP Address. At least one
+ ipAddress element or one
+ childIpAddressListId element must
+ be provided.
+ :type ip_address_collection: :``str``
+
+ :param child_ip_address_list: Child IP Address List or id to be
+ included in this IP Address List.
+ At least one ipAddress or
+ one childIpAddressListId
+ must be provided.
+ :type child_ip_address_list:
+ :class:'DimensionDataChildIpAddressList` or `str``
+
+ :return: a list of DimensionDataIpAddressList objects
+ :rtype: ``list`` of :class:`DimensionDataIpAddressList`
+ """
+ if (ip_address_collection is None and
+ child_ip_address_list is None):
+ raise ValueError("At least one ipAddress element or one "
+ "childIpAddressListId element must be "
+ "provided.")
+
+ create_ip_address_list = ET.Element('createIpAddressList',
+ {'xmlns': TYPES_URN})
+ ET.SubElement(
+ create_ip_address_list,
+ 'networkDomainId'
+ ).text = self._network_domain_to_network_domain_id(ex_network_domain)
+
+ ET.SubElement(
+ create_ip_address_list,
+ 'name'
+ ).text = name
+
+ ET.SubElement(
+ create_ip_address_list,
+ 'description'
+ ).text = description
+
+ ET.SubElement(
+ create_ip_address_list,
+ 'ipVersion'
+ ).text = ip_version
+
+ for ip in ip_address_collection:
+ ip_address = ET.SubElement(
+ create_ip_address_list,
+ 'ipAddress',
+ )
+ ip_address.set('begin', ip.begin)
+
+ if ip.end:
+ ip_address.set('end', ip.end)
+
+ if ip.prefix_size:
+ ip_address.set('prefixSize', ip.prefix_size)
+
+ if child_ip_address_list is not None:
+ ET.SubElement(
+ create_ip_address_list,
+ 'childIpAddressListId'
+ ).text = \
+ self._child_ip_address_list_to_child_ip_address_list_id(
+ child_ip_address_list)
+
+ response = self.connection.request_with_orgId_api_2(
+ 'network/createIpAddressList',
+ method='POST',
+ data=ET.tostring(create_ip_address_list)).object
+
+ response_code = findtext(response, 'responseCode', TYPES_URN)
+ return response_code in ['IN_PROGRESS', 'OK']
+
+ def ex_edit_ip_address_list(self, ex_ip_address_list, description,
+ ip_address_collection,
+ child_ip_address_lists=None):
+ """
+ Edit IP Address List. IP Address list.
+
+ :param ex_ip_address_list: (required) IpAddressList object or
+ IpAddressList ID
+ :type ex_ip_address_list: :class:'DimensionDataIpAddressList'
+ or ``str``
+
+ :param description: IP Address List Description
+ :type description: :``str``
+
+ :param ip_address_collection: List of IP Address
+ :type ip_address_collection: ''list'' of
+ :class:'DimensionDataIpAddressList'
+
+ :param child_ip_address_lists: Child IP Address List or id to be
+ included in this IP Address List
+ :type child_ip_address_lists: ``list`` of
+ :class:'DimensionDataChildIpAddressList'
+ or ``str``
+
+ :return: a list of DimensionDataIpAddressList objects
+ :rtype: ``list`` of :class:`DimensionDataIpAddressList`
+ """
+ edit_ip_address_list = ET.Element(
+ 'editIpAddressList',
+ {'xmlns': TYPES_URN,
+ "id": self._ip_address_list_to_ip_address_list_id(
+ ex_ip_address_list),
+ 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"
+ })
+
+ ET.SubElement(
+ edit_ip_address_list,
+ 'description'
+ ).text = description
+
+ for ip in ip_address_collection:
+ ip_address = ET.SubElement(
+ edit_ip_address_list,
+ 'ipAddress',
+ )
+ ip_address.set('begin', ip.begin)
+
+ if ip.end:
+ ip_address.set('end', ip.end)
+
+ if ip.prefix_size:
+ ip_address.set('prefixSize', ip.prefix_size)
+
+ if child_ip_address_lists is not None:
+ ET.SubElement(
+ edit_ip_address_list,
+ 'childIpAddressListId'
+ ).text = self._child_ip_address_list_to_child_ip_address_list_id(
+ child_ip_address_lists)
+ else:
+ ET.SubElement(
+ edit_ip_address_list,
+ 'childIpAddressListId',
+ {'xsi:nil': 'true'}
+ )
+
+ response = self.connection.request_with_orgId_api_2(
+ 'network/editIpAddressList',
+ method='POST',
+ data=ET.tostring(edit_ip_address_list)).object
+
+ response_code = findtext(response, 'responseCode', TYPES_URN)
+ return response_code in ['IN_PROGRESS', 'OK']
+
+ def ex_delete_ip_address_list(self, ex_ip_address_list):
+ """
+ Delete IP Address List by ID
+
+ :param ex_ip_address_list: IP Address List object or IP Address
+ List ID (required)
+ :type ex_ip_address_list: :class:'DimensionDataIpAddressList'
+ or ``str``
+
+ :rtype: ``bool``
+ """
+
+ delete_ip_address_list = \
+ ET.Element('deleteIpAddressList', {'xmlns': TYPES_URN, 'id': self
+ ._ip_address_list_to_ip_address_list_id(
+ ex_ip_address_list)})
+
+ response = self.connection.request_with_orgId_api_2(
+ 'network/deleteIpAddressList',
+ method='POST',
+ data=ET.tostring(delete_ip_address_list)).object
+
+ response_code = findtext(response, 'responseCode', TYPES_URN)
+ return response_code in ['IN_PROGRESS', 'OK']
+
+ def ex_list_port_list(self, ex_network_domain):
+ """
+ List Port List by network domain ID specified
+
+ :param ex_network_domain: The network domain or network domain ID
+ :type ex_network_domain: :class:`DimensionDataNetworkDomain` or 'str'
+
+ :return: a list of DimensionDataPortList objects
+ :rtype: ``list`` of :class:`DimensionDataPortList`
+ """
+ params = {'networkDomainId':
+ self._network_domain_to_network_domain_id(ex_network_domain)}
+ response = self.connection.request_with_orgId_api_2(
+ 'network/portList', params=params).object
+ return self._to_port_lists(response)
+
+ def ex_get_port_list(self, ex_port_list):
+ """
+ Get Port List
+
+ :param ex_port_list: The ex_port_list or ex_port_list ID
+ :type ex_port_list: :class:`DimensionDataNetworkDomain` or 'str'
+
+ :return: DimensionDataPortList object
+ :rtype: :class:`DimensionDataPort`
+ """
+
+ url_path = ('network/portList/%s' % self._port_list_to_port_list_id(
+ ex_port_list))
+ response = self.connection.request_with_orgId_api_2(
+ url_path).object
+ return self._to_port_list(response)
+
+ def ex_create_port_list(self, ex_network_domain, name, description,
+ port_collection, child_port_list_lists=None):
+ """
+ Create Port List.
+
+ :param ex_network_domain: (required) The network domain in
+ which to create PortList. Provide
+ networkdomain object or its id.
+ :type ex_network_domain: :``str``
+
+ :param name: Port List Name
+ :type name: :``str``
+
+ :param description: IP Address List Description
+ :type description: :``str``
+
+ :param port_collection: List of Port Address
+ :type port_collection: :``str``
+
+ :param child_port_list_lists: Child Port List to be included in
+ this Port List
+ :type child_port_list_lists: :``str`` or ''list of
+ :class:'DimensionDataChildPortList'
+
+ :return: result of operation
+ :rtype: ``bool``
+ """
+ new_port_list = ET.Element('createPortList', {'xmlns': TYPES_URN})
+ ET.SubElement(
+ new_port_list,
+ 'networkDomainId'
+ ).text = self._network_domain_to_network_domain_id(ex_network_domain)
+
+ ET.SubElement(
+ new_port_list,
+ 'name'
+ ).text = name
+
+ ET.SubElement(
+ new_port_list,
+ 'description'
+ ).text = description
+
+ for port in port_collection:
+ p = ET.SubElement(
+ new_port_list,
+ 'port'
+ )
+ p.set('begin', port.begin)
+
+ if port.end:
+ p.set('end', port.end)
+
+ if child_port_list_lists is not None:
+ for child in child_port_list_lists:
+ ET.SubElement(
+ new_port_list,
+ 'childPortListId'
+ ).text = self._child_port_list_to_child_port_list_id(child)
+
+ response = self.connection.request_with_orgId_api_2(
+ 'network/createPortList',
+ method='POST',
+ data=ET.tostring(new_port_list)).object
+
+ response_code = findtext(response, 'responseCode', TYPES_URN)
+ return response_code in ['IN_PROGRESS', 'OK']
+
+ def ex_edit_port_list(self, ex_port_list, description,
+ port_collection, child_port_list_lists=None):
+ """
+ Edit Port List.
+
+ :param ex_port_list: Port List to be edited
+ (required)
+ :type ex_port_list: :``str`` or :class:'DimensionDataPortList'
+
+ :param description: Port List Description
+ :type description: :``str``
+
+ :param port_collection: List of Port Address
+ :type port_collection: :``str``
+
+ :param child_port_list_lists: Child Port List to be included in
+ this IP Address List
+ :type child_port_list_lists: :``list`` of
+ :class'DimensionDataChildPortList'
+ or ''str''
+
+ :return: a list of DimensionDataPortList objects
+ :rtype: ``list`` of :class:`DimensionDataPortList`
+ """
+
+ existing_port_address_list = ET.Element(
+ 'editPortList',
+ {
+ "id": self._port_list_to_port_list_id(ex_port_list),
+ 'xmlns': TYPES_URN,
+ 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"
+ })
+
+ ET.SubElement(
+ existing_port_address_list,
+ 'description'
+ ).text = description
+
+ for port in port_collection:
+ p = ET.SubElement(
+ existing_port_address_list,
+ 'port'
+ )
+ p.set('begin', port.begin)
+
+ if port.end:
+ p.set('end', port.end)
+
+ if child_port_list_lists is not None:
+ for child in child_port_list_lists:
+ ET.SubElement(
+ existing_port_address_list,
+ 'childPortListId'
+ ).text = self._child_port_list_to_child_port_list_id(child)
+ else:
+ ET.SubElement(
+ existing_port_address_list,
+ 'childPortListId',
+ {'xsi:nil': 'true'}
+ )
+
+ response = self.connection.request_with_orgId_api_2(
+ 'network/editPortList',
+ method='POST',
+ data=ET.tostring(existing_port_address_list)).object
+
+ response_code = findtext(response, 'responseCode', TYPES_URN)
+ return response_code in ['IN_PROGRESS', 'OK']
+
+ def ex_delete_port_list(self, ex_port_list):
+ """
+ Delete Port List
+ :param ex_port_list: Port List to be deleted
+ :type ex_port_list: :``str`` or :class:'DimensionDataPortList'
+
+ :rtype: ``bool``
+ """
+
+ delete_port_list = ET.Element(
+ 'deletePortList',
+ {'xmlns': TYPES_URN,
+ 'id': self._port_list_to_port_list_id(ex_port_list)})
+
+ response = self.connection.request_with_orgId_api_2(
+ 'network/deletePortList',
+ method='POST',
+ data=ET.tostring(delete_port_list)).object
+
+ response_code = findtext(response, 'responseCode', TYPES_URN)
+ return response_code in ['IN_PROGRESS', 'OK']
+
def _format_csv(self, http_response):
text = http_response.read()
lines = str.splitlines(ensure_string(text))
@@ -2828,6 +3363,75 @@ class DimensionDataNodeDriver(NodeDriver):
TYPES_URN))
return s
+ def _to_ip_address_lists(self, object):
+ ip_address_lists = []
+ for element in findall(object, 'ipAddressList', TYPES_URN):
+ ip_address_lists.append(self._to_ip_address_list(element))
+
+ return ip_address_lists
+
+ def _to_ip_address_list(self, element):
+ ipAddresses = []
+ for ip in findall(element, 'ipAddress', TYPES_URN):
+ ipAddresses.append(self._to_ip_address(ip))
+
+ child_ip_address_lists = []
+ for child_ip_list in findall(element, 'childIpAddressList',
+ TYPES_URN):
+ child_ip_address_lists.append(self
+ ._to_child_ip_list(child_ip_list))
+
+ return DimensionDataIpAddressList(
+ id=element.get('id'),
+ name=findtext(element, 'name', TYPES_URN),
+ description=findtext(element, 'description', TYPES_URN),
+ ip_version=findtext(element, 'ipVersion', TYPES_URN),
+ ip_address_collection=ipAddresses,
+ state=findtext(element, 'state', TYPES_URN),
+ create_time=findtext(element, 'createTime', TYPES_URN),
+ child_ip_address_lists=child_ip_address_lists
+ )
+
+ def _to_child_ip_list(self, element):
+ return DimensionDataChildIpAddressList(
+ id=element.get('id'),
+ name=element.get('name')
+ )
+
+ def _to_ip_address(self, element):
+ return DimensionDataIpAddress(
+ begin=element.get('begin'),
+ end=element.get('end'),
+ prefix_size=element.get('prefixSize')
+ )
+
+ def _to_port_lists(self, object):
+ port_lists = []
+ for element in findall(object, 'portList', TYPES_URN):
+ port_lists.append(self._to_port_list(element))
+
+ return port_lists
+
+ def _to_port_list(self, element):
+ ports = []
+ for port in findall(element, 'port', TYPES_URN):
+ ports.append(self._to_port(element=port))
+
+ child_port_list_lists = []
+ for child in findall(element, 'childPortList', TYPES_URN):
+ child_port_list_lists.append(
+ self._to_child_port_list(element=child))
+
+ return DimensionDataPortList(
+ id=element.get('id'),
+ name=findtext(element, 'name', TYPES_URN),
+ description=findtext(element, 'description', TYPES_URN),
+ port_collection=ports,
+ child_port_list_lists=child_port_list_lists,
+ state=findtext(element, 'state', TYPES_URN),
+ create_time=findtext(element, 'createTime', TYPES_URN)
+ )
+
def _image_needs_auth(self, image):
if not isinstance(image, NodeImage):
image = self.ex_get_image_by_id(image)
@@ -2836,6 +3440,20 @@ class DimensionDataNodeDriver(NodeDriver):
return True
@staticmethod
+ def _to_port(element):
+ return DimensionDataPort(
+ begin=element.get('begin'),
+ end=element.get('end')
+ )
+
+ @staticmethod
+ def _to_child_port_list(element):
+ return DimensionDataChildPortList(
+ id=element.get('id'),
+ name=element.get('name')
+ )
+
+ @staticmethod
def _get_node_state(state, started, action):
try:
return NODE_STATE_MAP[(state, started, action)]
@@ -2882,5 +3500,27 @@ class DimensionDataNodeDriver(NodeDriver):
return dd_object_to_id(tag_key, DimensionDataTagKey, id_value='name')
@staticmethod
+ def _ip_address_list_to_ip_address_list_id(ip_addr_list):
+ return dd_object_to_id(ip_addr_list, DimensionDataIpAddressList,
+ id_value='id')
+
+ @staticmethod
+ def _child_ip_address_list_to_child_ip_address_list_id(child_ip_addr_list):
+ return dd_object_to_id(child_ip_addr_list,
+ DimensionDataChildIpAddressList,
+ id_value='id')
+
+ @staticmethod
+ def _port_list_to_port_list_id(port_list):
+ return dd_object_to_id(port_list, DimensionDataPortList,
+ id_value='id')
+
+ @staticmethod
+ def _child_port_list_to_child_port_list_id(child_port_list):
+ return dd_object_to_id(child_port_list,
+ DimensionDataChildPortList,
+ id_value='id')
+
+ @staticmethod
def _str2bool(string):
return string.lower() in ("true")