libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject [04/10] libcloud git commit: Completed functions for firewall rules in network domains, get, list, update (disable/enable), create and delete. Inc unit tests
Date Thu, 08 Oct 2015 12:19:22 GMT
Completed functions for firewall rules in network domains, get, list, update (disable/enable),
create and delete. Inc unit tests

Closes #593


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

Branch: refs/heads/trunk
Commit: 9743a722fff4ff33bb81271000b5b97a35761eb9
Parents: 4ee01b6
Author: Anthony Shaw <anthony.p.shaw@gmail.com>
Authored: Tue Oct 6 14:11:16 2015 +1100
Committer: Tomaz Muraus <tomaz@apache.org>
Committed: Thu Oct 8 14:12:09 2015 +0200

----------------------------------------------------------------------
 libcloud/common/dimensiondata.py                |  39 ++++
 libcloud/compute/drivers/dimensiondata.py       | 125 ++++++++++-
 ..._8dabe5a7d0e4_network_createFirewallRule.xml |   8 +
 ..._8dabe5a7d0e4_network_deleteFirewallRule.xml |   8 +
 ...bc_8dabe5a7d0e4_network_editFirewallRule.xml |   8 +
 ...a_9cbc_8dabe5a7d0e4_network_firewallRule.xml | 210 +++++++++++++++++++
 ...ule_d0a20f59_77b9_4f28_a63b_e58496b73a6c.xml |  18 ++
 libcloud/test/compute/test_dimensiondata.py     |  60 ++++++
 8 files changed, 475 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/common/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/common/dimensiondata.py b/libcloud/common/dimensiondata.py
index 6c517fc..cb41484 100644
--- a/libcloud/common/dimensiondata.py
+++ b/libcloud/common/dimensiondata.py
@@ -322,6 +322,45 @@ class DimensionDataPublicIpBlock(object):
                    self.status))
 
 
+class DimensionDataFirewallRule(object):
+    """
+    DimensionData Firewall Rule for a network domain
+    """
+
+    def __init__(self, id, name, action, location, network_domain,
+                 status, ipVersion, protocol, source, destination,
+                 enabled):
+        self.id = str(id)
+        self.name = name
+        self.action = action
+        self.location = location
+        self.network_domain = network_domain
+        self.status = status
+        self.ipVersion = ipVersion
+        self.protocol = protocol
+        self.source = source
+        self.destination = destination
+        self.enabled = enabled
+
+    def __repr__(self):
+        return (('<DimensionDataNetworkDomain: id=%s, name=%s,'
+                 'action=%s, location=%s, status=%s>')
+                % (self.id, self.name, self.action, self.location,
+                   self.status))
+
+
+class DimensionDataFirewallAddress(object):
+    """
+    The source or destination model in a firewall rule
+    """
+    def __init__(self, any_ip, ip_address, ip_prefix_size, port_begin, port_end):
+        self.any_ip = any_ip
+        self.ip_address = ip_address
+        self.ip_prefix_size = ip_prefix_size
+        self.port_begin = port_begin
+        self.port_end = port_end
+    
+
 class DimensionDataVlan(object):
     """
     DimensionData VLAN.

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/compute/drivers/dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/dimensiondata.py b/libcloud/compute/drivers/dimensiondata.py
index a2cad9f..1aa3e9f 100644
--- a/libcloud/compute/drivers/dimensiondata.py
+++ b/libcloud/compute/drivers/dimensiondata.py
@@ -29,6 +29,8 @@ from libcloud.common.dimensiondata import DimensionDataNetwork
 from libcloud.common.dimensiondata import DimensionDataNetworkDomain
 from libcloud.common.dimensiondata import DimensionDataVlan
 from libcloud.common.dimensiondata import DimensionDataPublicIpBlock
+from libcloud.common.dimensiondata import DimensionDataFirewallRule
+from libcloud.common.dimensiondata import DimensionDataFirewallAddress
 from libcloud.common.dimensiondata import NetworkDomainServicePlan
 from libcloud.common.dimensiondata import API_ENDPOINTS
 from libcloud.common.dimensiondata import DEFAULT_REGION
@@ -643,7 +645,86 @@ class DimensionDataNodeDriver(NodeDriver):
         response = self.connection \
             .request_with_orgId_api_2('network/firewallRule',
                                       params=params).object
-        return self._to_firewall_rules(response)
+        return self._to_firewall_rules(response, network_domain)
+
+    def ex_create_firewall_rule(self, network_domain, rule, position):
+        create_node = ET.Element('createFirewallRule', {'xmlns': TYPES_URN})
+        ET.SubElement(create_node, "networkDomainId").text = network_domain.id
+        ET.SubElement(create_node, "name").text = rule.name
+        ET.SubElement(create_node, "action").text = rule.action
+        ET.SubElement(create_node, "ipVersion").text = rule.ipVersion
+        ET.SubElement(create_node, "protocol").text = rule.protocol
+        # Setup source port rule
+        source = ET.SubElement(create_node, "source")
+        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)
+            source_ip.set('prefixSize', rule.source.ip_prefix_size)
+            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(create_node, "destination")
+        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)
+            dest_ip.set('prefixSize', rule.destination.ip_prefix_size)
+            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)
+        ET.SubElement(create_node, "enabled").text = 'true'
+        placement = ET.SubElement(create_node, "placement")
+        placement.set('position', position)
+
+        response = self.connection.request_with_orgId_api_2(
+            'network/createFirewallRule',
+            method='POST',
+            data=ET.tostring(create_node)).object
+
+        rule_id = None
+        for info in findall(response, 'info', TYPES_URN):
+            if info.get('name') == 'firewallRuleId':
+                rule_id = info.get('value')
+        rule.id = rule_id
+        return rule
+
+    def ex_get_firewall_rule(self, network_domain, rule_id):
+        locations = self.list_locations()
+        rule = self.connection.request_with_orgId_api_2(
+            'network/firewallRule/%s' % rule_id).object
+        return self._to_firewall_rule(rule, locations, network_domain)
+
+    def ex_set_firewall_rule_state(self, rule, state):
+        """
+        Change the state (enabled or disabled) of a rule
+        """
+        update_node = ET.Element('editFirewallrule', {'xmlns': TYPES_URN})
+        update_node.set('id', rule.id)
+        ET.SubElement(update_node, 'enabled').text = str(state).lower()
+        result = self.connection.request_with_orgId_api_2(
+            'network/editFirewallRule',
+            method='POST',
+            data=ET.tostring(update_node)).object
+
+        responseCode = findtext(result, 'responseCode', TYPES_URN)
+        return responseCode == 'IN_PROGRESS' or responseCode == 'OK'
+
+    def ex_delete_firewall_rule(self, rule):
+        update_node = ET.Element('deleteFirewallrule', {'xmlns': TYPES_URN})
+        update_node.set('id', rule.id)
+        result = self.connection.request_with_orgId_api_2(
+            'network/deleteFirewallRule',
+            method='POST',
+            data=ET.tostring(update_node)).object
+
+        responseCode = findtext(result, 'responseCode', TYPES_URN)
+        return responseCode == 'IN_PROGRESS' or responseCode == 'OK'
 
     def ex_get_location_by_id(self, id):
         """
@@ -660,6 +741,48 @@ class DimensionDataNodeDriver(NodeDriver):
                 filter(lambda x: x.id == id, self.list_locations()))[0]
         return location
 
+    def _to_firewall_rules(self, object, network_domain):
+        rules = []
+        locations = self.list_locations()
+        for element in findall(object, 'firewallRule', TYPES_URN):
+            rules.append(
+                self._to_firewall_rule(element, locations, network_domain))
+
+        return rules
+
+    def _to_firewall_rule(self, element, locations, network_domain):
+        status = self._to_status(element.find(fixxpath('state', TYPES_URN)))
+
+        location_id = element.get('datacenterId')
+        location = list(filter(lambda x: x.id == location_id,
+                               locations))[0]
+
+        return DimensionDataFirewallRule(
+            id=element.get('id'),
+            network_domain=network_domain,
+            name=findtext(element, 'name', TYPES_URN),
+            action=findtext(element, 'action', TYPES_URN),
+            ipVersion=findtext(element, 'ipVersion', TYPES_URN),
+            protocol=findtext(element, 'protocol', TYPES_URN),
+            enabled=findtext(element, 'enabled', TYPES_URN),
+            source=self._to_firewall_address(
+                element.find(fixxpath('source', TYPES_URN))),
+            destination=self._to_firewall_address(
+                element.find(fixxpath('destination', TYPES_URN))),
+            location=location,
+            status=status)
+
+    def _to_firewall_address(self, element):
+        ip = element.find(fixxpath('ip', TYPES_URN))
+        port = element.find(fixxpath('port', TYPES_URN))
+        return DimensionDataFirewallAddress(
+            any_ip=ip.get('address') == 'ANY',
+            ip_address=ip.get('address'),
+            ip_prefix_size=ip.get('prefixSize'),
+            port_begin=port.get('begin') if port is not None else None,
+            port_end=port.get('end') if port is not None else None
+        )
+
     def _to_ip_blocks(self, object):
         blocks = []
         locations = self.list_locations()

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createFirewallRule.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createFirewallRule.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createFirewallRule.xml
new file mode 100644
index 0000000..ac3162e
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createFirewallRule.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<response
+xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-03-06T02:28:56.679-05:00/1003070b-dea9-41bd-9f0c-5c24086589b8">
+<operation>CREATE_FIREWALL_RULE</operation>
+<responseCode>OK</responseCode>
+<message>Request create Firewall Rule 'My.Rule.2' successful</message>
+<info name="firewallRuleId" value="d0a20f59-77b9-4f28-a63b-e58496b73a6c"/>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteFirewallRule.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteFirewallRule.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteFirewallRule.xml
new file mode 100644
index 0000000..3016297
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteFirewallRule.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<response requestId="NA9/2015-03-06T04:49:42.721-05:00/f69f1106-0df7-4614-b517-844ce29013e4"
+xmlns="urn:didata.com:api:cloud:types">
+<operation>DELETE_FIREWALL_RULE</operation>
+<responseCode>OK</responseCode>
+<message>Firewall Rule (Id:84e34850-595d-436e-a885-7cd37edb24a4) has been
+deleted</message>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_editFirewallRule.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_editFirewallRule.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_editFirewallRule.xml
new file mode 100644
index 0000000..eff18c4
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_editFirewallRule.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<response
+xmlns="urn:didata.com:api:cloud:types" requestId="NA9/2015-03-06T03:34:21.951-05:00/d7e37b41-ceff-4a8c-992d-a0220b8ebd76">
+<operation>EDIT_FIREWALL_RULE</operation>
+<responseCode>OK</responseCode>
+<message>Firewall Rule with id 1aa3d0ce-d95d-4296-8338-9717e0d37ff9 has
+been edited</message>
+</response>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule.xml
new file mode 100644
index 0000000..b09d963
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule.xml
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<firewallRules xmlns="urn:didata.com:api:cloud:types" pageNumber="1" pageCount="13" totalCount="13"
pageSize="50">
+    <firewallRule id="756cba02-b0bc-48f4-aea5-9445870b6148" datacenterId="NA9" ruleType="DEFAULT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>CCDEFAULT.BlockOutboundMailIPv4</name>
+        <action>DROP</action>
+        <ipVersion>IPV4</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="25"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="8ffbe8c1-e545-424b-bfcc-e25c2017537d" datacenterId="NA9" ruleType="DEFAULT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>CCDEFAULT.BlockOutboundMailIPv4Secure</name>
+        <action>DROP</action>
+        <ipVersion>IPV4</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="587"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="f93b5139-402b-45c5-af80-aa00e311572e" datacenterId="NA9" ruleType="DEFAULT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>CCDEFAULT.BlockOutboundMailIPv6</name>
+        <action>DROP</action>
+        <ipVersion>IPV6</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="25"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="83ade810-3983-4009-a250-155c5ab47f54" datacenterId="NA9" ruleType="DEFAULT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>CCDEFAULT.BlockOutboundMailIPv6Secure</name>
+        <action>DROP</action>
+        <ipVersion>IPV6</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="587"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="cc9e1475-9218-484d-af5f-aba5c9a37c2d" datacenterId="NA9" ruleType="DEFAULT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>CCDEFAULT.DenyExternalInboundIPv6</name>
+        <action>DROP</action>
+        <ipVersion>IPV6</ipVersion>
+        <protocol>IP</protocol>
+        <source>
+            <ip address="EXTERNAL_IPV6"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="a23db203-99c9-42de-9dce-3a97724b7d4d" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>AllowOctopusTentacleComms6</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV6</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="2607:f480:111:1336:6503:544c:74a6:3a28"/>
+            <port begin="10933"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="bc26b74f-9b52-4923-8eda-7fc434759611" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>AllowOctopusComms4</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV4</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="10933"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="0bb8cc91-75fd-48a1-b9f8-1d728dabbca1" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>AllowHTTPSinbound</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV4</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="443"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="38ff959f-58c5-47b9-af6b-568a23e3c299" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>AllowHTTPSinbound6</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV6</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="2607:f480:111:1336:6503:544c:74a6:3a28"/>
+            <port begin="443"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="04159804-e48c-40b5-80f5-48c40d1b7f2f" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>Allow8843Inbound</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV4</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="8443"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="4250d8db-db42-4e40-acb0-672ec1a1af1b" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>Allow9443Inbound</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV4</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="ANY"/>
+            <port begin="9443"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="f0119d2f-e891-44ee-af89-76122b4be219" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>Allow9443Inbound6</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV6</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="2607:f480:111:1336:6503:544c:74a6:3a28"/>
+            <port begin="8443"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+    <firewallRule id="b976e0e6-4fb2-4f3e-a016-652e02d191b4" datacenterId="NA9" ruleType="CLIENT_RULE">
+        <networkDomainId>b30c224c-c95b-4cd9-bb8b-bfdfb5486abf</networkDomainId>
+        <name>AllowSTSInbound6</name>
+        <action>ACCEPT_DECISIVELY</action>
+        <ipVersion>IPV6</ipVersion>
+        <protocol>TCP</protocol>
+        <source>
+            <ip address="ANY"/>
+        </source>
+        <destination>
+            <ip address="2607:f480:111:1336:6503:544c:74a6:3a28"/>
+            <port begin="9443"/>
+        </destination>
+        <enabled>true</enabled>
+        <state>NORMAL</state>
+    </firewallRule>
+</firewallRules>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule_d0a20f59_77b9_4f28_a63b_e58496b73a6c.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule_d0a20f59_77b9_4f28_a63b_e58496b73a6c.xml
b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule_d0a20f59_77b9_4f28_a63b_e58496b73a6c.xml
new file mode 100644
index 0000000..876f37d
--- /dev/null
+++ b/libcloud/test/compute/fixtures/dimensiondata/caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule_d0a20f59_77b9_4f28_a63b_e58496b73a6c.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<firewallRule
+xmlns="urn:didata.com:api:cloud:types" id="d0a20f59-77b9-4f28-a63b-e58496b73a6c" datacenterId="NA9"
ruleType="DEFAULT_RULE">
+<networkDomainId>8cdfd607-f429-4df6-9352-162cfc0891be</networkDomainId>
+<name>CCDEFAULT.BlockOutboundMailIPv4</name>
+<action>DROP</action>
+<ipVersion>IPV4</ipVersion>
+<protocol>TCP</protocol>
+<source>
+<ip address="ANY"/>
+</source>
+<destination>
+<ip address="ANY"/>
+<port begin="25"/>
+</destination>
+<enabled>true</enabled>
+<state>NORMAL</state>
+</firewallRule>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/9743a722/libcloud/test/compute/test_dimensiondata.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_dimensiondata.py b/libcloud/test/compute/test_dimensiondata.py
index 7139633..2e16dab 100644
--- a/libcloud/test/compute/test_dimensiondata.py
+++ b/libcloud/test/compute/test_dimensiondata.py
@@ -300,6 +300,42 @@ class DimensionDataTests(unittest.TestCase, TestCaseMixin):
         result = self.driver.ex_delete_public_ip_block(block)
         self.assertTrue(result)
 
+    def test_ex_list_firewall_rules(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rules = self.driver.ex_list_firewall_rules(net)
+        self.assertEqual(rules[0].id, '756cba02-b0bc-48f4-aea5-9445870b6148')
+        self.assertEqual(rules[0].network_domain.id, '8cdfd607-f429-4df6-9352-162cfc0891be')
+        self.assertEqual(rules[0].name, 'CCDEFAULT.BlockOutboundMailIPv4')
+        self.assertEqual(rules[0].action, 'DROP')
+        self.assertEqual(rules[0].ipVersion, 'IPV4')
+        self.assertEqual(rules[0].protocol, 'TCP')
+        self.assertEqual(rules[0].source.ip_address, 'ANY')
+        self.assertTrue(rules[0].source.any_ip)
+        self.assertTrue(rules[0].destination.any_ip)
+
+    def test_ex_create_firewall_rule(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rules = self.driver.ex_list_firewall_rules(net)
+        rule = self.driver.ex_create_firewall_rule(net, rules[0], 'FIRST')
+        self.assertEqual(rule.id, 'd0a20f59-77b9-4f28-a63b-e58496b73a6c')
+
+    def test_ex_get_firewall_rule(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rule = self.driver.ex_get_firewall_rule(net, 'd0a20f59-77b9-4f28-a63b-e58496b73a6c')
+        self.assertEqual(rule.id, 'd0a20f59-77b9-4f28-a63b-e58496b73a6c')
+
+    def test_ex_set_firewall_rule_state(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rule = self.driver.ex_get_firewall_rule(net, 'd0a20f59-77b9-4f28-a63b-e58496b73a6c')
+        result = self.driver.ex_set_firewall_rule_state(rule, False)
+        self.assertTrue(result)
+
+    def test_ex_delete_firewall_rule(self):
+        net = self.driver.ex_get_network_domain('8cdfd607-f429-4df6-9352-162cfc0891be')
+        rule = self.driver.ex_get_firewall_rule(net, 'd0a20f59-77b9-4f28-a63b-e58496b73a6c')
+        result = self.driver.ex_delete_firewall_rule(rule)
+        self.assertTrue(result)
+
 
 class DimensionDataMockHttp(MockHttp):
 
@@ -553,6 +589,30 @@ class DimensionDataMockHttp(MockHttp):
             'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_removePublicIpBlock.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createFirewallRule(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_createFirewallRule.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule_d0a20f59_77b9_4f28_a63b_e58496b73a6c(self,
method, url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_firewallRule_d0a20f59_77b9_4f28_a63b_e58496b73a6c.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_editFirewallRule(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_editFirewallRule.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteFirewallRule(self, method,
url, body, headers):
+        body = self.fixtures.load(
+            'caas_2_0_8a8f6abc_2745_4d8a_9cbc_8dabe5a7d0e4_network_deleteFirewallRule.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
 if __name__ == '__main__':
     sys.exit(unittest.main())


Mime
View raw message