Browse Source

Cameron & Ed | Extract looping over groups and refreshing their rules to GroupRuleRefresher

changes/85/139985/1
cameron-r 4 years ago
parent
commit
a8f09b1ccb

+ 22
- 43
ec2driver.py View File

@@ -25,6 +25,8 @@ from boto.exception import EC2ResponseError
25 25
 from boto.regioninfo import RegionInfo
26 26
 from oslo.config import cfg
27 27
 from novaclient.v1_1 import client
28
+from ec2_rule_service import EC2RuleService
29
+from ec2_rule_transformer import EC2RuleTransformer
28 30
 
29 31
 from ec2driver_config import *
30 32
 from nova import block_device
@@ -39,8 +41,13 @@ from nova.openstack.common import loopingcall
39 41
 from nova.virt import driver
40 42
 from nova.virt import virtapi
41 43
 from credentials import get_nova_creds
44
+from instance_rule_refresher import InstanceRuleRefresher
45
+from openstack_group_service import OpenstackGroupService
46
+from openstack_rule_service import OpenstackRuleService
47
+from openstack_rule_transformer import OpenstackRuleTransformer
42 48
 
43 49
 import rule_comparator
50
+from group_rule_refresher import GroupRuleRefresher
44 51
 
45 52
 LOG = logging.getLogger(__name__)
46 53
 
@@ -156,7 +163,20 @@ class EC2Driver(driver.ComputeDriver):
156 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 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 181
         if not '_EC2_NODES' in globals():
162 182
             set_nodes([CONF.host])
@@ -720,48 +740,7 @@ class EC2Driver(driver.ComputeDriver):
720 740
 
721 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'])
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
-                    )
743
+        self.instance_rule_refresher.refresh(self.nova.servers.get(instance['id']))
765 744
 
766 745
         return
767 746
 

+ 22
- 0
group_rule_refresher.py View File

@@ -0,0 +1,22 @@
1
+class 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
+        )

+ 11
- 0
instance_rule_refresher.py View File

@@ -0,0 +1,11 @@
1
+class 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]

+ 0
- 29
rule_refresher.py View File

@@ -1,29 +0,0 @@
1
-class 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
-        )

tests/unit/test_rule_refresher.py → tests/unit/test_group_rule_refresher.py View File

@@ -3,7 +3,7 @@ import unittest
3 3
 from boto.ec2 import EC2Connection
4 4
 from mock import Mock
5 5
 
6
-from nova.virt.ec2.rule_refresher import RuleRefresher
6
+from nova.virt.ec2.group_rule_refresher import GroupRuleRefresher
7 7
 from nova.virt.ec2.rule import Rule
8 8
 from nova.virt.ec2.openstack_rule_service import OpenstackRuleService
9 9
 from nova.virt.ec2.ec2_rule_service import EC2RuleService
@@ -11,7 +11,7 @@ from nova.virt.ec2.ec2_rule_service import EC2RuleService
11 11
 GROUP_NAME = 'secGroup'
12 12
 OTHER_GROUP_NAME = "otherSecGroup"
13 13
 
14
-class TestRuleRefresher(unittest.TestCase):
14
+class TestGroupRuleRefresher(unittest.TestCase):
15 15
     def setUp(self):
16 16
         self.new_rule = Rule('hjkl', 7, 8, '9.9.9.9/99')
17 17
         self.openstack_instance = Mock()
@@ -20,19 +20,17 @@ class TestRuleRefresher(unittest.TestCase):
20 20
         self.openstack_rule_service = Mock(OpenstackRuleService)
21 21
         self.ec2_rule_service = Mock(EC2RuleService)
22 22
 
23
-        self.rule_refresher = RuleRefresher(
23
+        self.group_rule_refresher = GroupRuleRefresher(
24 24
             self.ec2_connection,
25 25
             self.openstack_rule_service,
26 26
             self.ec2_rule_service
27 27
         )
28 28
 
29 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 30
         self.openstack_rule_service.get_rules_for_group.return_value = set([self.new_rule])
33 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 35
         self.ec2_connection.authorize_security_group.assert_called_once_with(
38 36
             group_name=GROUP_NAME,
@@ -40,22 +38,4 @@ class TestRuleRefresher(unittest.TestCase):
40 38
             from_port=self.new_rule.from_port,
41 39
             to_port=self.new_rule.to_port,
42 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 41
         )

+ 21
- 0
tests/unit/test_instance_rule_refresher.py View File

@@ -0,0 +1,21 @@
1
+import unittest
2
+from mock import Mock, call
3
+from nova.virt.ec2.group_rule_refresher import GroupRuleRefresher
4
+from nova.virt.ec2.instance_rule_refresher import InstanceRuleRefresher
5
+
6
+
7
+class 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'])])

Loading…
Cancel
Save