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',