Repository: libcloud
Updated Branches:
  refs/heads/trunk e7d1882dd -> d73d4777d


[LIBCLOUD-749] CloudStack: fixed method ex_authorize_security_group_ingress

Closes #580

Signed-off-by: Tomaz Muraus <to...@apache.org>


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

Branch: refs/heads/trunk
Commit: 550dcf44f97d73c858f43fe1508b3e42e152da92
Parents: e7d1882
Author: lionel <lio...@sixsq.com>
Authored: Tue Sep 15 23:39:15 2015 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Sun Oct 11 16:09:23 2015 +0200

----------------------------------------------------------------------
 libcloud/compute/drivers/cloudstack.py          | 120 ++++++++++++-------
 .../cloudstack/queryAsyncJobResult_17200.json   |   2 +-
 libcloud/test/compute/test_cloudstack.py        |  20 +++-
 3 files changed, 93 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/550dcf44/libcloud/compute/drivers/cloudstack.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/cloudstack.py 
b/libcloud/compute/drivers/cloudstack.py
index 1c77b3b..4e5e835 100644
--- a/libcloud/compute/drivers/cloudstack.py
+++ b/libcloud/compute/drivers/cloudstack.py
@@ -3489,70 +3489,106 @@ class CloudStackNodeDriver(CloudStackDriverMixIn, 
NodeDriver):
                                   params={'name': name},
                                   method='GET')['success']
 
-    def ex_authorize_security_group_ingress(self, securitygroupname,
-                                            protocol, cidrlist, startport,
-                                            endport=None):
+    def ex_authorize_security_group_ingress(self, securitygroupname, protocol,
+                                        cidrlist, startport=None, endport=None,
+                                        icmptype=None, icmpcode=None, 
**kwargs):
         """
         Creates a new Security Group Ingress rule
 
-        :param domainid: An optional domainId for the security group.
-                         If the account parameter is used,
-                         domainId must also be used.
-        :type domainid: ``str``
+        :param   securitygroupname: The name of the security group.
+                                    Mutually exclusive with securitygroupid.
+        :type    securitygroupname: ``str``
 
-        :param startport: Start port for this ingress rule
-        :type  startport: ``int``
+        :param   protocol: Can be TCP, UDP or ICMP.
+                           Sometime other protocols can be used like AH, ESP
+                           or GRE.
+        :type    protocol: ``str``
 
-        :param securitygroupid: The ID of the security group.
-                                Mutually exclusive with securityGroupName
-                                parameter
-        :type  securitygroupid: ``str``
+        :param   cidrlist: Source address CIDR for which this rule applies.
+        :type    cidrlist: ``str``
 
-        :param cidrlist: The cidr list associated
-        :type  cidrlist: ``list``
+        :param   startport: Start port of the range for this ingress rule.
+                            Applies to protocols TCP and UDP.
+        :type    startport: ``int``
 
-        :param usersecuritygrouplist: user to security group mapping
-        :type  usersecuritygrouplist: ``dict``
+        :param   endport: End port of the range for this ingress rule.
+                          It can be None to set only one port.
+                          Applies to protocols TCP and UDP.
+        :type    endport: ``int``
 
-        :param securitygroupname: The name of the security group.
-                                  Mutually exclusive with
-                                  securityGroupName parameter
-        :type  securitygroupname: ``str``
+        :param   icmptype: Type of the ICMP packet (eg: 8 for Echo Request).
+                           -1 or None means "all types".
+                           Applies to protocol ICMP.
+        :type    icmptype: ``int``
 
-        :param account: An optional account for the security group.
-                        Must be used with domainId.
-        :type  account: ``str``
+        :param   icmpcode: Code of the ICMP packet for the specified type.
+                           If the specified type doesn't require a code set 
this
+                           value to 0.
+                           -1 or None means "all codes".
+                           Applies to protocol ICMP.
+        :type    icmpcode: ``int``
 
-        :param icmpcode: Error code for this icmp message
-        :type  icmpcode: ``int``
+        :keyword   account: An optional account for the security group.
+                            Must be used with domainId.
+        :type      account: ``str``
 
-        :param protocol: TCP is default. UDP is the other supported protocol
-        :type  protocol: ``str``
+        :keyword domainid: An optional domainId for the security group.
+                           If the account parameter is used, domainId must also
+                           be used.
 
-        :param icmptype: type of the icmp message being sent
-        :type  icmptype: ``int``
+        :keyword projectid: An optional project of the security group
+        :type    projectid: ``str``
 
-        :param projectid: An optional project of the security group
-        :type  projectid: ``str``
+        :param securitygroupid: The ID of the security group.
+                                Mutually exclusive with securitygroupname
+        :type  securitygroupid: ``str``
 
-        :param endport: end port for this ingress rule
-        :type  endport: ``int``
+        :param usersecuritygrouplist: User to security group mapping
+        :type  usersecuritygrouplist: ``dict``
 
-        :rtype: ``list``
+        :rtype: ``dict``
         """
 
+        args = kwargs.copy()
         protocol = protocol.upper()
-        if protocol not in ('TCP', 'ICMP'):
-            raise LibcloudError('Only TCP and ICMP are allowed')
 
-        args = {
+        args.update({
             'securitygroupname': securitygroupname,
             'protocol': protocol,
-            'startport': int(startport),
             'cidrlist': cidrlist
-        }
-        if endport is None:
-            args['endport'] = int(startport)
+        })
+
+        if protocol not in ('TCP', 'UDP') and \
+                (startport is not None or endport is not None):
+            raise LibcloudError('"startport" and "endport" are only valid with 
'
+                                'protocol TCP or UDP.')
+
+        if protocol != 'ICMP' and (icmptype is not None or icmpcode is not 
None):
+            raise LibcloudError('"icmptype" and "icmpcode" are only valid with 
'
+                                'protocol ICMP.')
+
+        if protocol in ('TCP', 'UDP'):
+            if startport is None:
+                raise LibcloudError('Protocols TCP and UDP require at least '
+                                    '"startport" to be set.')
+            if startport is not None and endport is None:
+                endport = startport
+
+            args.update({
+                'startport': startport,
+                'endport': endport
+            })
+
+        if protocol == 'ICMP':
+            if icmptype is None:
+                icmptype = -1
+            if icmpcode is None:
+                icmpcode = -1
+
+            args.update({
+                'icmptype': icmptype,
+                'icmpcode': icmpcode
+            })
 
         return self._async_request(command='authorizeSecurityGroupIngress',
                                    params=args,

http://git-wip-us.apache.org/repos/asf/libcloud/blob/550dcf44/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_17200.json
----------------------------------------------------------------------
diff --git 
a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_17200.json 
b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_17200.json
index d028ab4..61645f9 100644
--- a/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_17200.json
+++ b/libcloud/test/compute/fixtures/cloudstack/queryAsyncJobResult_17200.json
@@ -1 +1 @@
-{"queryasyncjobresultresponse":{"jobid":17200,"jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"securitygroup":[{"egressrule":[],"account":"run...@gmail.com","domainid":"ab53d864-6f78-4993-bb28-9b8667b535a1","name":"MySG","domain":"run...@gmail.com","ingressrule":[{"startport":22,"cidr":"0.0.0.0/0","protocol":"tcp","endport":22,"ruleid":"7df1edc8-6e56-48d7-b816-39377506d787"}],"id":"fa334c44-21c6-4809-ad7d-287bbb23c29b"}]}}}
+{ "queryasyncjobresultresponse" : 
{"accountid":"00000000-0000-0000-0000-000000000000","userid":"111111-1111-1111-1111-111111111111","cmd":"org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd","jobstatus":1,"jobprocstatus":0,"jobresultcode":0,"jobresulttype":"object","jobresult":{"securitygroup":{"id":"222222-2222-2222-2222-222222222222","name":"test_sg","description":"Test
 security 
group","account":"sm...@example.com","domainid":"333333-3333-3333-3333-333333333333","domain":"sm...@example.com","ingressrule":[{"ruleid":"444444-4444-4444-4444-444444444444","protocol":"udp","startport":0,"endport":65535,"cidr":"0.0.0.0/0"}],"egressrule":[],"tags":[]}},"created":"2015-09-15T15:00:00+0200","jobid":"17200"}
 }

http://git-wip-us.apache.org/repos/asf/libcloud/blob/550dcf44/libcloud/test/compute/test_cloudstack.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_cloudstack.py 
b/libcloud/test/compute/test_cloudstack.py
index ed83d70..7189821 100644
--- a/libcloud/test/compute/test_cloudstack.py
+++ b/libcloud/test/compute/test_cloudstack.py
@@ -740,12 +740,20 @@ class CloudStackCommonTestCase(TestCaseMixin):
         self.assertTrue(res)
 
     def test_ex_authorize_security_group_ingress(self):
-        res = self.driver.ex_authorize_security_group_ingress('MySG',
-                                                              'TCP',
-                                                              '22',
-                                                              '22',
-                                                              '0.0.0.0/0')
-        self.assertTrue(res)
+        res = self.driver.ex_authorize_security_group_ingress('test_sg',
+                                                              'udp',
+                                                              '0.0.0.0/0',
+                                                              '0',
+                                                              '65535')
+        self.assertEqual(res.get('name'), 'test_sg')
+        self.assertTrue('ingressrule' in res)
+        rules = res['ingressrule']
+        self.assertEqual(len(rules), 1)
+        rule = rules[0]
+        self.assertEqual(rule['cidr'], '0.0.0.0/0')
+        self.assertEqual(rule['endport'], 65535)
+        self.assertEqual(rule['protocol'], 'udp')
+        self.assertEqual(rule['startport'], 0)
 
     def test_ex_create_affinity_group(self):
         res = self.driver.ex_create_affinity_group('MyAG2',

Reply via email to