Cameron & Ed | Extract looping over groups and refreshing their rules to GroupRuleRefresher
This commit is contained in:
parent
6d4ec264a5
commit
a8f09b1ccb
65
ec2driver.py
65
ec2driver.py
@ -25,6 +25,8 @@ from boto.exception import EC2ResponseError
|
||||
from boto.regioninfo import RegionInfo
|
||||
from oslo.config import cfg
|
||||
from novaclient.v1_1 import client
|
||||
from ec2_rule_service import EC2RuleService
|
||||
from ec2_rule_transformer import EC2RuleTransformer
|
||||
|
||||
from ec2driver_config import *
|
||||
from nova import block_device
|
||||
@ -39,8 +41,13 @@ from nova.openstack.common import loopingcall
|
||||
from nova.virt import driver
|
||||
from nova.virt import virtapi
|
||||
from credentials import get_nova_creds
|
||||
from instance_rule_refresher import InstanceRuleRefresher
|
||||
from openstack_group_service import OpenstackGroupService
|
||||
from openstack_rule_service import OpenstackRuleService
|
||||
from openstack_rule_transformer import OpenstackRuleTransformer
|
||||
|
||||
import rule_comparator
|
||||
from group_rule_refresher import GroupRuleRefresher
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -156,7 +163,20 @@ class EC2Driver(driver.ComputeDriver):
|
||||
aws_region, aws_access_key_id=CONF.ec2driver.ec2_access_key_id, aws_secret_access_key=CONF.ec2driver.ec2_secret_access_key)
|
||||
|
||||
self.security_group_lock = Lock()
|
||||
self.rule_comparator = rule_comparator.RuleComparator(self.ec2_conn)
|
||||
|
||||
self.instance_rule_refresher = InstanceRuleRefresher(
|
||||
GroupRuleRefresher(
|
||||
ec2_connection=self.ec2_conn,
|
||||
openstack_rule_service=OpenstackRuleService(
|
||||
group_service=OpenstackGroupService(self.nova.security_groups),
|
||||
openstack_rule_transformer=OpenstackRuleTransformer()
|
||||
),
|
||||
ec2_rule_service=EC2RuleService(
|
||||
ec2_connection=self.ec2_conn,
|
||||
ec2_rule_transformer=EC2RuleTransformer()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
if not '_EC2_NODES' in globals():
|
||||
set_nodes([CONF.host])
|
||||
@ -720,48 +740,7 @@ class EC2Driver(driver.ComputeDriver):
|
||||
|
||||
# TODO: lock for case when group is associated with multiple instances [Cameron & Ed]
|
||||
|
||||
openstack_instance = self.nova.servers.get(instance['id'])
|
||||
|
||||
for group_dict in openstack_instance.security_groups:
|
||||
|
||||
openstack_group =\
|
||||
[group for group in self.nova.security_groups.list() if group.name == group_dict['name']][0]
|
||||
|
||||
ec2_group = self.ec2_conn.get_all_security_groups(groupnames=group_dict['name'])[0]
|
||||
|
||||
for openstack_rule in openstack_group.rules:
|
||||
equivalent_rule_found_in_ec2 = False
|
||||
for ec2_rule in ec2_group.rules:
|
||||
if self.rule_comparator.rules_are_equal(openstack_rule, ec2_rule):
|
||||
equivalent_rule_found_in_ec2 = True
|
||||
break
|
||||
|
||||
if not equivalent_rule_found_in_ec2:
|
||||
self.ec2_conn.authorize_security_group(
|
||||
group_name=ec2_group.name,
|
||||
ip_protocol=openstack_rule['ip_protocol'],
|
||||
from_port=openstack_rule['from_port'],
|
||||
to_port=openstack_rule['to_port'],
|
||||
src_security_group_name=self._get_allowed_group_name_from_openstack_rule_if_present(openstack_rule),
|
||||
cidr_ip=self._get_allowed_ip_range_from_openstack_rule_if_present(openstack_rule)
|
||||
)
|
||||
|
||||
for ec2_rule in ec2_group.rules:
|
||||
equivalent_rule_found_in_openstack = False
|
||||
for openstack_rule in openstack_group.rules:
|
||||
if self.rule_comparator.rules_are_equal(openstack_rule, ec2_rule):
|
||||
equivalent_rule_found_in_openstack = True
|
||||
break
|
||||
|
||||
if not equivalent_rule_found_in_openstack:
|
||||
self.ec2_conn.revoke_security_group(
|
||||
group_name=ec2_group.name,
|
||||
ip_protocol=ec2_rule.ip_protocol,
|
||||
from_port=ec2_rule.from_port,
|
||||
to_port=ec2_rule.to_port,
|
||||
cidr_ip=ec2_rule.grants[0].cidr_ip,
|
||||
src_security_group_group_id=ec2_rule.grants[0].group_id
|
||||
)
|
||||
self.instance_rule_refresher.refresh(self.nova.servers.get(instance['id']))
|
||||
|
||||
return
|
||||
|
||||
|
22
group_rule_refresher.py
Normal file
22
group_rule_refresher.py
Normal file
@ -0,0 +1,22 @@
|
||||
class GroupRuleRefresher:
|
||||
|
||||
def __init__(self, ec2_connection, openstack_rule_service, ec2_rule_service):
|
||||
self.ec2_conn = ec2_connection
|
||||
self.openstack_rule_service = openstack_rule_service
|
||||
self.ec2_rule_service = ec2_rule_service
|
||||
|
||||
def refresh(self, group_name):
|
||||
openstack_rules = self.openstack_rule_service.get_rules_for_group(group_name)
|
||||
ec2_rules = self.ec2_rule_service.get_rules_for_group(group_name)
|
||||
|
||||
for rule in openstack_rules - ec2_rules:
|
||||
self._create_rule_on_ec2(group_name, rule)
|
||||
|
||||
def _create_rule_on_ec2(self, group_name, rule):
|
||||
self.ec2_conn.authorize_security_group(
|
||||
group_name=group_name,
|
||||
ip_protocol=rule.ip_protocol,
|
||||
from_port=rule.from_port,
|
||||
to_port=rule.to_port,
|
||||
cidr_ip=rule.ip_range
|
||||
)
|
11
instance_rule_refresher.py
Normal file
11
instance_rule_refresher.py
Normal file
@ -0,0 +1,11 @@
|
||||
class InstanceRuleRefresher:
|
||||
|
||||
def __init__(self, group_rule_refresher):
|
||||
self.group_rule_refresher = group_rule_refresher
|
||||
|
||||
def refresh(self, instance):
|
||||
for group_name in self._get_group_names(instance):
|
||||
self.group_rule_refresher.refresh(group_name)
|
||||
|
||||
def _get_group_names(self, instance):
|
||||
return [group['name'] for group in instance.security_groups]
|
@ -1,29 +0,0 @@
|
||||
class RuleRefresher:
|
||||
|
||||
def __init__(self, ec2_conn, openstack_rule_service, ec2_rule_service):
|
||||
self.ec2_conn = ec2_conn
|
||||
self.openstack_rule_service = openstack_rule_service
|
||||
self.ec2_rule_service = ec2_rule_service
|
||||
|
||||
def refresh(self, openstack_instance):
|
||||
for group_dict in openstack_instance.security_groups:
|
||||
# openstack_group = [group for group in self.openstack_group_manager.list() if group.name == group_dict['name']][0]
|
||||
# transformed_openstack_group = self.openstack_group_transformer.to_group(openstack_group)
|
||||
# ec2_group = self.ec2_conn.get_all_security_groups(groupnames=group_dict['name'])[0]
|
||||
# transformed_ec2_group = self.ec2_group_transformer.to_group(ec2_group)
|
||||
|
||||
# TODO: transform openstack rules before finding difference
|
||||
openstack_rules = self.openstack_rule_service.get_rules_for_group(group_dict['name'])
|
||||
ec2_rules = self.ec2_rule_service.get_rules_for_group(group_dict['name'])
|
||||
|
||||
for rule in openstack_rules - ec2_rules:
|
||||
self._create_rule_on_ec2(group_dict['name'], rule)
|
||||
|
||||
def _create_rule_on_ec2(self, group_name, rule):
|
||||
self.ec2_conn.authorize_security_group(
|
||||
group_name=group_name,
|
||||
ip_protocol=rule.ip_protocol,
|
||||
from_port=rule.from_port,
|
||||
to_port=rule.to_port,
|
||||
cidr_ip=rule.ip_range
|
||||
)
|
@ -3,7 +3,7 @@ import unittest
|
||||
from boto.ec2 import EC2Connection
|
||||
from mock import Mock
|
||||
|
||||
from nova.virt.ec2.rule_refresher import RuleRefresher
|
||||
from nova.virt.ec2.group_rule_refresher import GroupRuleRefresher
|
||||
from nova.virt.ec2.rule import Rule
|
||||
from nova.virt.ec2.openstack_rule_service import OpenstackRuleService
|
||||
from nova.virt.ec2.ec2_rule_service import EC2RuleService
|
||||
@ -11,7 +11,7 @@ from nova.virt.ec2.ec2_rule_service import EC2RuleService
|
||||
GROUP_NAME = 'secGroup'
|
||||
OTHER_GROUP_NAME = "otherSecGroup"
|
||||
|
||||
class TestRuleRefresher(unittest.TestCase):
|
||||
class TestGroupRuleRefresher(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.new_rule = Rule('hjkl', 7, 8, '9.9.9.9/99')
|
||||
self.openstack_instance = Mock()
|
||||
@ -20,19 +20,17 @@ class TestRuleRefresher(unittest.TestCase):
|
||||
self.openstack_rule_service = Mock(OpenstackRuleService)
|
||||
self.ec2_rule_service = Mock(EC2RuleService)
|
||||
|
||||
self.rule_refresher = RuleRefresher(
|
||||
self.group_rule_refresher = GroupRuleRefresher(
|
||||
self.ec2_connection,
|
||||
self.openstack_rule_service,
|
||||
self.ec2_rule_service
|
||||
)
|
||||
|
||||
def test_should_add_rule_to_ec2_security_group_when_rule_associated_with_group_on_openstack(self):
|
||||
self.openstack_instance.security_groups = [{'name': GROUP_NAME}]
|
||||
|
||||
self.openstack_rule_service.get_rules_for_group.return_value = set([self.new_rule])
|
||||
self.ec2_rule_service.get_rules_for_group.return_value = set()
|
||||
|
||||
self.rule_refresher.refresh(self.openstack_instance)
|
||||
self.group_rule_refresher.refresh(GROUP_NAME)
|
||||
|
||||
self.ec2_connection.authorize_security_group.assert_called_once_with(
|
||||
group_name=GROUP_NAME,
|
||||
@ -40,22 +38,4 @@ class TestRuleRefresher(unittest.TestCase):
|
||||
from_port=self.new_rule.from_port,
|
||||
to_port=self.new_rule.to_port,
|
||||
cidr_ip=self.new_rule.ip_range
|
||||
)
|
||||
|
||||
def test_should_add_rule_to_corresponding_ec2_group_when_other_groups_present(self):
|
||||
self.openstack_instance.security_groups = [{'name': GROUP_NAME}, {'name': OTHER_GROUP_NAME}]
|
||||
|
||||
def mock_get_rules_for_openstack_group(group_name):
|
||||
return set() if group_name == GROUP_NAME else set([self.new_rule])
|
||||
self.openstack_rule_service.get_rules_for_group.side_effect = mock_get_rules_for_openstack_group
|
||||
self.ec2_rule_service.get_rules_for_group.return_value = set()
|
||||
|
||||
self.rule_refresher.refresh(self.openstack_instance)
|
||||
|
||||
self.ec2_connection.authorize_security_group.assert_called_once_with(
|
||||
group_name=OTHER_GROUP_NAME,
|
||||
ip_protocol=self.new_rule.ip_protocol,
|
||||
from_port=self.new_rule.from_port,
|
||||
to_port=self.new_rule.to_port,
|
||||
cidr_ip=self.new_rule.ip_range
|
||||
)
|
21
tests/unit/test_instance_rule_refresher.py
Normal file
21
tests/unit/test_instance_rule_refresher.py
Normal file
@ -0,0 +1,21 @@
|
||||
import unittest
|
||||
from mock import Mock, call
|
||||
from nova.virt.ec2.group_rule_refresher import GroupRuleRefresher
|
||||
from nova.virt.ec2.instance_rule_refresher import InstanceRuleRefresher
|
||||
|
||||
|
||||
class TestInstanceRuleRefresher(unittest.TestCase):
|
||||
|
||||
def test_should_call_group_rule_refresher_on_every_group_for_instance(self):
|
||||
|
||||
group_rule_refresher = Mock(spec=GroupRuleRefresher)
|
||||
|
||||
instance = Mock()
|
||||
first_group = {'name': 'firstGroup'}
|
||||
second_group = {'name': 'secondGroup'}
|
||||
instance.security_groups = [first_group, second_group]
|
||||
|
||||
instance_rule_refresher = InstanceRuleRefresher(group_rule_refresher)
|
||||
instance_rule_refresher.refresh(instance)
|
||||
|
||||
group_rule_refresher.refresh.assert_has_calls([call(first_group['name']), call(second_group['name'])])
|
Loading…
x
Reference in New Issue
Block a user