From b21deecb672955a2255bf075872144d5bb41ed6f Mon Sep 17 00:00:00 2001 From: Nick Bailey Date: Mon, 20 Aug 2012 09:30:46 -0400 Subject: [PATCH] Add security group functionality. --- libcloud/compute/drivers/ec2.py | 58 ++++++++++++++++++++ .../ec2/authorize_security_group_ingress.xml | 4 ++ .../fixtures/ec2/describe_security_groups.xml | 50 +++++++++++++++++ libcloud/test/compute/test_ec2.py | 16 ++++++ 4 files changed, 128 insertions(+), 0 deletions(-) create mode 100644 libcloud/test/compute/fixtures/ec2/authorize_security_group_ingress.xml create mode 100644 libcloud/test/compute/fixtures/ec2/describe_security_groups.xml diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py index 27354c2..99cd0a1 100644 --- a/libcloud/compute/drivers/ec2.py +++ b/libcloud/compute/drivers/ec2.py @@ -668,6 +668,25 @@ class EC2NodeDriver(NodeDriver): 'keyName': key_name } + def ex_list_security_groups(self): + """List existing Security Groups + + @note: This is a non-standard extension API, and only works for EC2. + + @rtype: C{list} of C{str} + """ + params = {'Action': 'DescribeSecurityGroups'} + response = self.connection.request(self.path, params=params).object + + groups = [] + for group in findall(element=response, xpath='securityGroupInfo/item', + namespace=NAMESPACE): + name = findtext(element=group, xpath='groupName', + namespace=NAMESPACE) + groups.append(name) + + return groups + def ex_create_security_group(self, name, description): """Creates a new Security Group @@ -688,6 +707,45 @@ class EC2NodeDriver(NodeDriver): 'GroupDescription': description} return self.connection.request(self.path, params=params).object + def ex_authorize_security_group(self, name, from_port, to_port, cidr_ip, protocol="tcp"): + """ + Edit a Security Group to allow specific traffic. + + @note: This is a non-standard extension API, and only works for EC2. + + @param name: The name of the security group to edit + @type name: C{str} + + @param from_port: The beginning of the port range to open + @type from_port: C{str} + + @param end_port: The end of the port range to open + @type end_port: C{str} + + @param cidr_ip: The ip to allow traffic for. + @type cidr_ip: C{str} + + @param protocol: tcp/udp/icmp + @type protocol: C{str} + + @rtype: C{boolean} + """ + + params = {'Action': 'AuthorizeSecurityGroupIngress', + 'GroupName': name, + 'IpProtocol': protocol, + 'FromPort': str(from_port), + 'ToPort': str(to_port), + 'CidrIp': cidr_ip} + try: + resp = self.connection.request(self.path, params=params.copy()).object + return bool(findtext(element=resp, xpath='return', + namespace=NAMESPACE)) + except Exception: + e = sys.exc_info()[1] + if e.args[0].find("InvalidPermission.Duplicate") == -1: + raise e + def ex_authorize_security_group_permissive(self, name): """ Edit a Security Group to allow all traffic. diff --git a/libcloud/test/compute/fixtures/ec2/authorize_security_group_ingress.xml b/libcloud/test/compute/fixtures/ec2/authorize_security_group_ingress.xml new file mode 100644 index 0000000..52a74ba --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/authorize_security_group_ingress.xml @@ -0,0 +1,4 @@ + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + true + diff --git a/libcloud/test/compute/fixtures/ec2/describe_security_groups.xml b/libcloud/test/compute/fixtures/ec2/describe_security_groups.xml new file mode 100644 index 0000000..9b6b916 --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/describe_security_groups.xml @@ -0,0 +1,50 @@ + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + + + 111122223333 + sg-443d0a12 + WebServers + Web Servers + + + + tcp + 80 + 80 + + + + 0.0.0.0/0 + + + + + + + + + 111122223333 + sg-5ff8a023 + RangedPortsBySource + Group A + + + tcp + 6000 + 7000 + + + 111122223333 + sg-99gh4012 + Group B + + + + + + + + + + diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py index 49b0740..8238f93 100644 --- a/libcloud/test/compute/test_ec2.py +++ b/libcloud/test/compute/test_ec2.py @@ -139,6 +139,14 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin): self.assertTrue(len(locations) > 0) self.assertTrue(locations[0].availability_zone != None) + def test_list_security_groups(self): + groups = self.driver.ex_list_security_groups() + self.assertEqual(groups, ['WebServers', 'RangedPortsBySource']) + + def test_authorize_security_group(self): + resp = self.driver.ex_authorize_security_group("TestGroup", "22", "22", "0.0.0.0/0") + self.assertTrue(resp) + def test_reboot_node(self): node = Node('i-4382922a', None, None, None, None, self.driver) ret = self.driver.reboot_node(node) @@ -358,6 +366,14 @@ class EC2MockHttp(MockHttp): body = self.fixtures.load('stop_instances.xml') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + def _DescribeSecurityGroups(self, method, url, body, headers): + body = self.fixtures.load('describe_security_groups.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _AuthorizeSecurityGroupIngress(self, method, url, body, headers): + body = self.fixtures.load('authorize_security_group_ingress.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + def _DescribeImages(self, method, url, body, headers): body = self.fixtures.load('describe_images.xml') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) -- 1.7.5.4