summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcameron-r <crowshanbin@gmail.com>2014-11-05 14:49:02 -0600
committercameron-r <crowshanbin@gmail.com>2014-11-05 15:27:44 -0600
commita8f09b1ccb0c070561ce9a5fea71399430701664 (patch)
tree9cb117b51c30a03979cacfc96ed7b24277f29322
parent6d4ec264a5bdb9977b4a2267e7abbd1e89a5960b (diff)
Cameron & Ed | Extract looping over groups and refreshing their rules to GroupRuleRefresher
-rw-r--r--ec2driver.py65
-rw-r--r--group_rule_refresher.py22
-rw-r--r--instance_rule_refresher.py11
-rw-r--r--rule_refresher.py29
-rw-r--r--tests/unit/test_group_rule_refresher.py (renamed from tests/unit/test_rule_refresher.py)28
-rw-r--r--tests/unit/test_instance_rule_refresher.py21
6 files changed, 80 insertions, 96 deletions
diff --git a/ec2driver.py b/ec2driver.py
index ada1465..f0c9c44 100644
--- a/ec2driver.py
+++ b/ec2driver.py
@@ -25,6 +25,8 @@ from boto.exception import EC2ResponseError
25from boto.regioninfo import RegionInfo 25from boto.regioninfo import RegionInfo
26from oslo.config import cfg 26from oslo.config import cfg
27from novaclient.v1_1 import client 27from novaclient.v1_1 import client
28from ec2_rule_service import EC2RuleService
29from ec2_rule_transformer import EC2RuleTransformer
28 30
29from ec2driver_config import * 31from ec2driver_config import *
30from nova import block_device 32from nova import block_device
@@ -39,8 +41,13 @@ from nova.openstack.common import loopingcall
39from nova.virt import driver 41from nova.virt import driver
40from nova.virt import virtapi 42from nova.virt import virtapi
41from credentials import get_nova_creds 43from credentials import get_nova_creds
44from instance_rule_refresher import InstanceRuleRefresher
45from openstack_group_service import OpenstackGroupService
46from openstack_rule_service import OpenstackRuleService
47from openstack_rule_transformer import OpenstackRuleTransformer
42 48
43import rule_comparator 49import rule_comparator
50from group_rule_refresher import GroupRuleRefresher
44 51
45LOG = logging.getLogger(__name__) 52LOG = logging.getLogger(__name__)
46 53
@@ -156,7 +163,20 @@ class EC2Driver(driver.ComputeDriver):
156 aws_region, aws_access_key_id=CONF.ec2driver.ec2_access_key_id, aws_secret_access_key=CONF.ec2driver.ec2_secret_access_key) 163 aws_region, aws_access_key_id=CONF.ec2driver.ec2_access_key_id, aws_secret_access_key=CONF.ec2driver.ec2_secret_access_key)
157 164
158 self.security_group_lock = Lock() 165 self.security_group_lock = Lock()
159 self.rule_comparator = rule_comparator.RuleComparator(self.ec2_conn) 166
167 self.instance_rule_refresher = InstanceRuleRefresher(
168 GroupRuleRefresher(
169 ec2_connection=self.ec2_conn,
170 openstack_rule_service=OpenstackRuleService(
171 group_service=OpenstackGroupService(self.nova.security_groups),
172 openstack_rule_transformer=OpenstackRuleTransformer()
173 ),
174 ec2_rule_service=EC2RuleService(
175 ec2_connection=self.ec2_conn,
176 ec2_rule_transformer=EC2RuleTransformer()
177 )
178 )
179 )
160 180
161 if not '_EC2_NODES' in globals(): 181 if not '_EC2_NODES' in globals():
162 set_nodes([CONF.host]) 182 set_nodes([CONF.host])
@@ -720,48 +740,7 @@ class EC2Driver(driver.ComputeDriver):
720 740
721 # TODO: lock for case when group is associated with multiple instances [Cameron & Ed] 741 # TODO: lock for case when group is associated with multiple instances [Cameron & Ed]
722 742
723 openstack_instance = self.nova.servers.get(instance['id']) 743 self.instance_rule_refresher.refresh(self.nova.servers.get(instance['id']))
724
725 for group_dict in openstack_instance.security_groups:
726
727 openstack_group =\
728 [group for group in self.nova.security_groups.list() if group.name == group_dict['name']][0]
729
730 ec2_group = self.ec2_conn.get_all_security_groups(groupnames=group_dict['name'])[0]
731
732 for openstack_rule in openstack_group.rules:
733 equivalent_rule_found_in_ec2 = False
734 for ec2_rule in ec2_group.rules:
735 if self.rule_comparator.rules_are_equal(openstack_rule, ec2_rule):
736 equivalent_rule_found_in_ec2 = True
737 break
738
739 if not equivalent_rule_found_in_ec2:
740 self.ec2_conn.authorize_security_group(
741 group_name=ec2_group.name,
742 ip_protocol=openstack_rule['ip_protocol'],
743 from_port=openstack_rule['from_port'],
744 to_port=openstack_rule['to_port'],
745 src_security_group_name=self._get_allowed_group_name_from_openstack_rule_if_present(openstack_rule),
746 cidr_ip=self._get_allowed_ip_range_from_openstack_rule_if_present(openstack_rule)
747 )
748
749 for ec2_rule in ec2_group.rules:
750 equivalent_rule_found_in_openstack = False
751 for openstack_rule in openstack_group.rules:
752 if self.rule_comparator.rules_are_equal(openstack_rule, ec2_rule):
753 equivalent_rule_found_in_openstack = True
754 break
755
756 if not equivalent_rule_found_in_openstack:
757 self.ec2_conn.revoke_security_group(
758 group_name=ec2_group.name,
759 ip_protocol=ec2_rule.ip_protocol,
760 from_port=ec2_rule.from_port,
761 to_port=ec2_rule.to_port,
762 cidr_ip=ec2_rule.grants[0].cidr_ip,
763 src_security_group_group_id=ec2_rule.grants[0].group_id
764 )
765 744
766 return 745 return
767 746
diff --git a/group_rule_refresher.py b/group_rule_refresher.py
new file mode 100644
index 0000000..e8dafbb
--- /dev/null
+++ b/group_rule_refresher.py
@@ -0,0 +1,22 @@
1class GroupRuleRefresher:
2
3 def __init__(self, ec2_connection, openstack_rule_service, ec2_rule_service):
4 self.ec2_conn = ec2_connection
5 self.openstack_rule_service = openstack_rule_service
6 self.ec2_rule_service = ec2_rule_service
7
8 def refresh(self, group_name):
9 openstack_rules = self.openstack_rule_service.get_rules_for_group(group_name)
10 ec2_rules = self.ec2_rule_service.get_rules_for_group(group_name)
11
12 for rule in openstack_rules - ec2_rules:
13 self._create_rule_on_ec2(group_name, rule)
14
15 def _create_rule_on_ec2(self, group_name, rule):
16 self.ec2_conn.authorize_security_group(
17 group_name=group_name,
18 ip_protocol=rule.ip_protocol,
19 from_port=rule.from_port,
20 to_port=rule.to_port,
21 cidr_ip=rule.ip_range
22 ) \ No newline at end of file
diff --git a/instance_rule_refresher.py b/instance_rule_refresher.py
new file mode 100644
index 0000000..03a0d70
--- /dev/null
+++ b/instance_rule_refresher.py
@@ -0,0 +1,11 @@
1class InstanceRuleRefresher:
2
3 def __init__(self, group_rule_refresher):
4 self.group_rule_refresher = group_rule_refresher
5
6 def refresh(self, instance):
7 for group_name in self._get_group_names(instance):
8 self.group_rule_refresher.refresh(group_name)
9
10 def _get_group_names(self, instance):
11 return [group['name'] for group in instance.security_groups]
diff --git a/rule_refresher.py b/rule_refresher.py
deleted file mode 100644
index 0e64921..0000000
--- a/rule_refresher.py
+++ /dev/null
@@ -1,29 +0,0 @@
1class RuleRefresher:
2
3 def __init__(self, ec2_conn, openstack_rule_service, ec2_rule_service):
4 self.ec2_conn = ec2_conn
5 self.openstack_rule_service = openstack_rule_service
6 self.ec2_rule_service = ec2_rule_service
7
8 def refresh(self, openstack_instance):
9 for group_dict in openstack_instance.security_groups:
10 # openstack_group = [group for group in self.openstack_group_manager.list() if group.name == group_dict['name']][0]
11 # transformed_openstack_group = self.openstack_group_transformer.to_group(openstack_group)
12 # ec2_group = self.ec2_conn.get_all_security_groups(groupnames=group_dict['name'])[0]
13 # transformed_ec2_group = self.ec2_group_transformer.to_group(ec2_group)
14
15 # TODO: transform openstack rules before finding difference
16 openstack_rules = self.openstack_rule_service.get_rules_for_group(group_dict['name'])
17 ec2_rules = self.ec2_rule_service.get_rules_for_group(group_dict['name'])
18
19 for rule in openstack_rules - ec2_rules:
20 self._create_rule_on_ec2(group_dict['name'], rule)
21
22 def _create_rule_on_ec2(self, group_name, rule):
23 self.ec2_conn.authorize_security_group(
24 group_name=group_name,
25 ip_protocol=rule.ip_protocol,
26 from_port=rule.from_port,
27 to_port=rule.to_port,
28 cidr_ip=rule.ip_range
29 ) \ No newline at end of file
diff --git a/tests/unit/test_rule_refresher.py b/tests/unit/test_group_rule_refresher.py
index 4513a39..1166a71 100644
--- a/tests/unit/test_rule_refresher.py
+++ b/tests/unit/test_group_rule_refresher.py
@@ -3,7 +3,7 @@ import unittest
3from boto.ec2 import EC2Connection 3from boto.ec2 import EC2Connection
4from mock import Mock 4from mock import Mock
5 5
6from nova.virt.ec2.rule_refresher import RuleRefresher 6from nova.virt.ec2.group_rule_refresher import GroupRuleRefresher
7from nova.virt.ec2.rule import Rule 7from nova.virt.ec2.rule import Rule
8from nova.virt.ec2.openstack_rule_service import OpenstackRuleService 8from nova.virt.ec2.openstack_rule_service import OpenstackRuleService
9from nova.virt.ec2.ec2_rule_service import EC2RuleService 9from nova.virt.ec2.ec2_rule_service import EC2RuleService
@@ -11,7 +11,7 @@ from nova.virt.ec2.ec2_rule_service import EC2RuleService
11GROUP_NAME = 'secGroup' 11GROUP_NAME = 'secGroup'
12OTHER_GROUP_NAME = "otherSecGroup" 12OTHER_GROUP_NAME = "otherSecGroup"
13 13
14class TestRuleRefresher(unittest.TestCase): 14class TestGroupRuleRefresher(unittest.TestCase):
15 def setUp(self): 15 def setUp(self):
16 self.new_rule = Rule('hjkl', 7, 8, '9.9.9.9/99') 16 self.new_rule = Rule('hjkl', 7, 8, '9.9.9.9/99')
17 self.openstack_instance = Mock() 17 self.openstack_instance = Mock()
@@ -20,19 +20,17 @@ class TestRuleRefresher(unittest.TestCase):
20 self.openstack_rule_service = Mock(OpenstackRuleService) 20 self.openstack_rule_service = Mock(OpenstackRuleService)
21 self.ec2_rule_service = Mock(EC2RuleService) 21 self.ec2_rule_service = Mock(EC2RuleService)
22 22
23 self.rule_refresher = RuleRefresher( 23 self.group_rule_refresher = GroupRuleRefresher(
24 self.ec2_connection, 24 self.ec2_connection,
25 self.openstack_rule_service, 25 self.openstack_rule_service,
26 self.ec2_rule_service 26 self.ec2_rule_service
27 ) 27 )
28 28
29 def test_should_add_rule_to_ec2_security_group_when_rule_associated_with_group_on_openstack(self): 29 def test_should_add_rule_to_ec2_security_group_when_rule_associated_with_group_on_openstack(self):
30 self.openstack_instance.security_groups = [{'name': GROUP_NAME}]
31
32 self.openstack_rule_service.get_rules_for_group.return_value = set([self.new_rule]) 30 self.openstack_rule_service.get_rules_for_group.return_value = set([self.new_rule])
33 self.ec2_rule_service.get_rules_for_group.return_value = set() 31 self.ec2_rule_service.get_rules_for_group.return_value = set()
34 32
35 self.rule_refresher.refresh(self.openstack_instance) 33 self.group_rule_refresher.refresh(GROUP_NAME)
36 34
37 self.ec2_connection.authorize_security_group.assert_called_once_with( 35 self.ec2_connection.authorize_security_group.assert_called_once_with(
38 group_name=GROUP_NAME, 36 group_name=GROUP_NAME,
@@ -40,22 +38,4 @@ class TestRuleRefresher(unittest.TestCase):
40 from_port=self.new_rule.from_port, 38 from_port=self.new_rule.from_port,
41 to_port=self.new_rule.to_port, 39 to_port=self.new_rule.to_port,
42 cidr_ip=self.new_rule.ip_range 40 cidr_ip=self.new_rule.ip_range
43 )
44
45 def test_should_add_rule_to_corresponding_ec2_group_when_other_groups_present(self):
46 self.openstack_instance.security_groups = [{'name': GROUP_NAME}, {'name': OTHER_GROUP_NAME}]
47
48 def mock_get_rules_for_openstack_group(group_name):
49 return set() if group_name == GROUP_NAME else set([self.new_rule])
50 self.openstack_rule_service.get_rules_for_group.side_effect = mock_get_rules_for_openstack_group
51 self.ec2_rule_service.get_rules_for_group.return_value = set()
52
53 self.rule_refresher.refresh(self.openstack_instance)
54
55 self.ec2_connection.authorize_security_group.assert_called_once_with(
56 group_name=OTHER_GROUP_NAME,
57 ip_protocol=self.new_rule.ip_protocol,
58 from_port=self.new_rule.from_port,
59 to_port=self.new_rule.to_port,
60 cidr_ip=self.new_rule.ip_range
61 ) \ No newline at end of file 41 ) \ No newline at end of file
diff --git a/tests/unit/test_instance_rule_refresher.py b/tests/unit/test_instance_rule_refresher.py
new file mode 100644
index 0000000..57b1727
--- /dev/null
+++ b/tests/unit/test_instance_rule_refresher.py
@@ -0,0 +1,21 @@
1import unittest
2from mock import Mock, call
3from nova.virt.ec2.group_rule_refresher import GroupRuleRefresher
4from nova.virt.ec2.instance_rule_refresher import InstanceRuleRefresher
5
6
7class TestInstanceRuleRefresher(unittest.TestCase):
8
9 def test_should_call_group_rule_refresher_on_every_group_for_instance(self):
10
11 group_rule_refresher = Mock(spec=GroupRuleRefresher)
12
13 instance = Mock()
14 first_group = {'name': 'firstGroup'}
15 second_group = {'name': 'secondGroup'}
16 instance.security_groups = [first_group, second_group]
17
18 instance_rule_refresher = InstanceRuleRefresher(group_rule_refresher)
19 instance_rule_refresher.refresh(instance)
20
21 group_rule_refresher.refresh.assert_has_calls([call(first_group['name']), call(second_group['name'])]) \ No newline at end of file