Ed & Cameron | Refactoring: extract rule comparison between openstack and ec2 groups to common group class

This commit is contained in:
cameron-r 2014-11-04 14:59:41 -06:00
parent 3751616fbf
commit e5ae501335
5 changed files with 75 additions and 85 deletions

4
ec2_group_transformer.py Normal file
View File

@ -0,0 +1,4 @@
class EC2GroupTransformer:
def to_group(self, ec2_group):
pass

4
group.py Normal file
View File

@ -0,0 +1,4 @@
class Group:
def rule_diff(self, other_group):
pass

View File

@ -0,0 +1,3 @@
class OpenstackGroupTransformer:
def to_group(self, openstack_group):
pass

View File

@ -1,28 +1,29 @@
class RuleRefresher:
def __init__(self, openstack_group_manager, ec2_conn, openstack_rule_transformer, ec2_rule_transformer):
def __init__(self, openstack_group_manager, ec2_conn, openstack_group_transformer, ec2_group_transformer):
self.openstack_group_manager = openstack_group_manager
self.ec2_conn = ec2_conn
self.openstack_rule_transformer = openstack_rule_transformer
self.ec2_rule_transformer = ec2_rule_transformer
self.openstack_group_transformer = openstack_group_transformer
self.ec2_group_transformer = ec2_group_transformer
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)
for openstack_rule in openstack_group.rules:
same_rule_exists_on_ec2 = False
for ec2_rule in ec2_group.rules:
if self.openstack_rule_transformer.to_rule(openstack_rule) == self.ec2_rule_transformer.to_rule(ec2_rule):
same_rule_exists_on_ec2 = True
break
rules_in_openstack_group_not_in_ec2 = transformed_openstack_group.rule_diff(transformed_ec2_group)
if not same_rule_exists_on_ec2:
self.ec2_conn.authorize_security_group(
group_name=openstack_group.name,
ip_protocol=openstack_rule['ip_protocol'],
from_port=openstack_rule['from_port'],
to_port=openstack_rule['to_port'],
cidr_ip=openstack_rule['ip_range']['cidr']
)
for rule in rules_in_openstack_group_not_in_ec2:
self._create_rule_on_ec2(openstack_group, rule)
def _create_rule_on_ec2(self, openstack_group, rule):
self.ec2_conn.authorize_security_group(
group_name=openstack_group.name,
ip_protocol=rule.ip_protocol,
from_port=rule.from_port,
to_port=rule.to_port,
cidr_ip=rule.ip_range
)

View File

@ -1,115 +1,93 @@
import unittest
import boto
from boto.ec2 import EC2Connection
from mock import Mock
import novaclient
from novaclient.v1_1.servers import Server
from nova.virt.ec2.rule_refresher import RuleRefresher
from nova.virt.ec2.openstack_rule_transformer import OpenstackRuleTransformer
from nova.virt.ec2.ec2_rule_transformer import EC2RuleTransformer
from nova.virt.ec2.rule import Rule
from nova.virt.ec2.ec2_group_transformer import EC2GroupTransformer
from nova.virt.ec2.openstack_group_transformer import OpenstackGroupTransformer
from nova.virt.ec2.group import Group
GROUP_NAME = 'secGroup'
OTHER_GROUP_NAME = "otherSecGroup"
class TestRuleRefresher(unittest.TestCase):
def setUp(self):
self.existing_new_rule = {'ip_protocol': 'abc', 'from_port': 1111, 'to_port': 2222, 'ip_range': {'cidr': '1.2.3.4/55'}}
self.openstack_group = Mock()
self.openstack_group.name = GROUP_NAME
self.ec2_group = Mock()
self.ec2_group.name = GROUP_NAME
self.new_openstack_rule = {'ip_protocol': 'abc', 'from_port': 1111, 'to_port': 2222, 'ip_range': {'cidr': '1.2.3.4/55'}}
self.openstack_instance = Mock()
self.openstack_instance.security_groups = [{'name': GROUP_NAME}]
self.openstack_group = Mock()
self.openstack_group.name = GROUP_NAME
self.openstack_group_manager = Mock(spec=novaclient.v1_1.security_groups.SecurityGroupManager)
self.openstack_group_manager.list.return_value = [self.openstack_group]
self.ec2_group = Mock()
self.ec2_group.name = GROUP_NAME
self.ec2_connection = Mock(spec=EC2Connection)
self.ec2_connection.get_all_security_groups.return_value = [self.ec2_group]
self.openstack_rule_transformer = Mock(spec=OpenstackRuleTransformer)
self.ec2_rule_transformer = Mock(spec=EC2RuleTransformer)
self.openstack_group_transformer = Mock(spec=OpenstackGroupTransformer)
self.ec2_group_transformer = Mock(spec=EC2GroupTransformer)
self.rule_refresher = RuleRefresher(self.openstack_group_manager, self.ec2_connection,
self.openstack_rule_transformer, self.ec2_rule_transformer)
self.openstack_group_transformer, self.ec2_group_transformer)
def test_should_add_rule_to_ec2_security_group_when_rule_associated_with_group_on_openstack(self):
self.openstack_group.rules = [self.existing_new_rule]
self.ec2_group.rules = []
new_rule = Rule('hjkl', 7, 8, '9.9.9.9/99')
transformed_openstack_group = Mock(spec=Group)
transformed_openstack_group.rule_diff.return_value = [new_rule]
self.openstack_group_transformer.to_group.return_value = transformed_openstack_group
self.rule_refresher.refresh(self.openstack_instance)
self.ec2_connection.authorize_security_group.assert_called_once_with(
group_name=GROUP_NAME,
ip_protocol='abc',
from_port=1111,
to_port=2222,
cidr_ip="1.2.3.4/55"
)
def test_should_add_rule_to_ec2_security_group_when_other_rule_already_on_both(self):
existing_openstack_rule = {'ip_protocol': 'hi', 'from_port': 3333, 'to_port': 4444, 'ip_range': {'cidr': '6.7.8.9/00'}}
existing_ec2_rule = {'attribute': 'value'}
existing_transformed_rule = Rule('sdfg', 5, 6, '7.7.7.7/77')
new_transformed_rule = Rule('hjkl', 7, 8, '9.9.9.9/99')
self.openstack_group.rules = [
existing_openstack_rule,
self.existing_new_rule
]
self.ec2_group.rules = [existing_ec2_rule]
def mock_openstack_to_rule(openstack_rule):
return existing_transformed_rule if openstack_rule == existing_openstack_rule else new_transformed_rule
def mock_ec2_to_rule(ec2_rule):
if ec2_rule == existing_ec2_rule:
return existing_transformed_rule
self.openstack_rule_transformer.to_rule.side_effect = mock_openstack_to_rule
self.ec2_rule_transformer.to_rule.side_effect = mock_ec2_to_rule
self.rule_refresher.refresh(self.openstack_instance)
self.ec2_connection.authorize_security_group.assert_called_once_with(
group_name=GROUP_NAME,
ip_protocol=self.existing_new_rule['ip_protocol'],
from_port=self.existing_new_rule['from_port'],
to_port=self.existing_new_rule['to_port'],
cidr_ip=self.existing_new_rule['ip_range']['cidr']
ip_protocol=new_rule.ip_protocol,
from_port=new_rule.from_port,
to_port=new_rule.to_port,
cidr_ip=new_rule.ip_range
)
def test_should_add_rule_to_corresponding_ec2_group_when_other_groups_present(self):
openstack_group2 = Mock()
openstack_group2.name = "group2"
ec2_group2 = Mock()
ec2_group2.rules = []
self.ec2_group.rules = []
openstack_group_with_new_rule = Mock()
openstack_group_with_new_rule.name = OTHER_GROUP_NAME
other_ec2_group = Mock()
self.openstack_group.rules = [self.existing_new_rule]
openstack_group2.rules = []
self.openstack_instance.security_groups = [{'name': GROUP_NAME}, {'name': openstack_group2.name}]
self.openstack_instance.security_groups = [{'name': GROUP_NAME}, {'name': OTHER_GROUP_NAME}]
self.openstack_group_manager.list.return_value = [openstack_group2, self.openstack_group]
self.openstack_group_manager.list.return_value = [openstack_group_with_new_rule, self.openstack_group]
def mock_get_all_security_groups(groupnames=None):
if groupnames == ec2_group2.name:
return [ec2_group2]
if groupnames == other_ec2_group.name:
return [other_ec2_group]
return [self.ec2_group]
self.ec2_connection.get_all_security_groups.side_effect = mock_get_all_security_groups
new_rule = Rule('hjkl', 7, 8, '9.9.9.9/99')
transformed_openstack_group = Mock(spec=Group)
transformed_openstack_group.rule_diff.return_value = []
transformed_openstack_group_with_new_rule = Mock(spec=Group)
transformed_openstack_group_with_new_rule.rule_diff.return_value = [new_rule]
def mock_openstack_to_group(openstack_group):
if openstack_group == self.openstack_group:
return transformed_openstack_group
else:
return transformed_openstack_group_with_new_rule
self.openstack_group_transformer.to_group.side_effect = mock_openstack_to_group
self.rule_refresher.refresh(self.openstack_instance)
self.ec2_connection.authorize_security_group.assert_called_once_with(
group_name=GROUP_NAME,
ip_protocol=self.existing_new_rule['ip_protocol'],
from_port=self.existing_new_rule['from_port'],
to_port=self.existing_new_rule['to_port'],
cidr_ip=self.existing_new_rule['ip_range']['cidr']
group_name=OTHER_GROUP_NAME,
ip_protocol=new_rule.ip_protocol,
from_port=new_rule.from_port,
to_port=new_rule.to_port,
cidr_ip=new_rule.ip_range
)