Added handling of secgroup for service_instance module
Change-Id: If3cb5f7436142e4eb8829690117d15c3029ed9d2 Closes-Bug: #1314591
This commit is contained in:
parent
625cea75cd
commit
45dc9bddc5
|
@ -260,7 +260,7 @@ function create_manila_service_image {
|
|||
}
|
||||
|
||||
function create_manila_service_secgroup {
|
||||
MANILA_SERVICE_SECGROUP="manila-service-secgroup"
|
||||
MANILA_SERVICE_SECGROUP="manila-service"
|
||||
|
||||
# Create a secgroup
|
||||
if ! nova secgroup-list | grep -q $MANILA_SERVICE_SECGROUP; then
|
||||
|
|
|
@ -24,3 +24,26 @@ STATUS_ACTIVATING = 'ACTIVATING'
|
|||
STATUS_DEACTIVATING = 'DEACTIVATING'
|
||||
|
||||
SECURITY_SERVICES_ALLOWED_TYPES = ['active_directory', 'ldap', 'kerberos']
|
||||
|
||||
# Below represented ports are ranges (from, to)
|
||||
CIFS_PORTS = (
|
||||
("tcp", (445, 445)),
|
||||
("tcp", (137, 139)),
|
||||
("udp", (137, 139)),
|
||||
("udp", (445, 445)),
|
||||
)
|
||||
NFS_PORTS = (
|
||||
("tcp", (2049, 2049)),
|
||||
("udp", (2049, 2049)),
|
||||
)
|
||||
SSH_PORTS = (
|
||||
("tcp", (22, 22)),
|
||||
)
|
||||
PING_PORTS = (
|
||||
("icmp", (-1, -1)),
|
||||
)
|
||||
|
||||
SERVICE_INSTANCE_SECGROUP_DATA = CIFS_PORTS + \
|
||||
NFS_PORTS + \
|
||||
SSH_PORTS + \
|
||||
PING_PORTS
|
||||
|
|
|
@ -129,6 +129,7 @@ def _untranslate_server_summary_view(server):
|
|||
d['networks'] = server.networks
|
||||
d['tenant_id'] = server.tenant_id
|
||||
d['user_id'] = server.user_id
|
||||
d['security_groups'] = server.security_groups
|
||||
|
||||
return d
|
||||
|
||||
|
@ -154,8 +155,9 @@ def translate_server_exception(method):
|
|||
class API(base.Base):
|
||||
"""API for interacting with novaclient."""
|
||||
|
||||
def server_create(self, context, name, image, flavor, key_name, user_data,
|
||||
security_groups, block_device_mapping=None,
|
||||
def server_create(self, context, name, image, flavor, key_name=None,
|
||||
user_data=None, security_groups=None,
|
||||
block_device_mapping=None,
|
||||
block_device_mapping_v2=None, nics=None,
|
||||
availability_zone=None, instance_count=1,
|
||||
admin_pass=None):
|
||||
|
@ -272,3 +274,25 @@ class API(base.Base):
|
|||
|
||||
def image_list(self, context):
|
||||
return novaclient(context).images.list()
|
||||
|
||||
def add_security_group_to_server(self, context, server, security_group):
|
||||
return novaclient(context).servers.add_security_group(server,
|
||||
security_group)
|
||||
|
||||
def security_group_create(self, context, name, description=""):
|
||||
return novaclient(context).security_groups.create(name, description)
|
||||
|
||||
def security_group_get(self, context, group_id):
|
||||
return novaclient(context).security_groups.get(group_id)
|
||||
|
||||
def security_group_list(self, context, search_opts=None):
|
||||
return novaclient(context).security_groups.list(search_opts)
|
||||
|
||||
def security_group_rule_create(self, context, parent_group_id,
|
||||
ip_protocol=None, from_port=None,
|
||||
to_port=None, cidr=None, group_id=None):
|
||||
return novaclient(context).security_group_rules.create(
|
||||
parent_group_id, ip_protocol, from_port, to_port, cidr, group_id)
|
||||
|
||||
def security_group_rule_delete(self, context, rule):
|
||||
return novaclient(context).security_group_rules.delete(rule)
|
||||
|
|
|
@ -23,6 +23,7 @@ import time
|
|||
|
||||
from oslo.config import cfg
|
||||
|
||||
from manila.common import constants
|
||||
from manila import compute
|
||||
from manila import context
|
||||
from manila import exception
|
||||
|
@ -61,6 +62,10 @@ server_opts = [
|
|||
cfg.IntOpt('max_time_to_build_instance',
|
||||
default=300,
|
||||
help="Maximum time to wait for creating service instance."),
|
||||
cfg.StrOpt('service_instance_security_group',
|
||||
default="manila-service",
|
||||
help="Name of security group, that will be used for "
|
||||
"service instance creation."),
|
||||
cfg.IntOpt('service_instance_flavor_id',
|
||||
default=100,
|
||||
help="ID of flavor, that will be used for service instance "
|
||||
|
@ -195,6 +200,43 @@ class ServiceInstanceManager(object):
|
|||
LOG.error(msg)
|
||||
raise exception.ServiceInstanceException(msg)
|
||||
|
||||
def _get_service_instance_security_group(self, context, name=None):
|
||||
"""Searches for security group by name."""
|
||||
if not (name or CONF.service_instance_security_group):
|
||||
return None
|
||||
if not name:
|
||||
name = CONF.service_instance_security_group
|
||||
s_groups = [s for s in self.compute_api.security_group_list(context)
|
||||
if s.name == name]
|
||||
if not s_groups:
|
||||
return None
|
||||
elif len(s_groups) > 1:
|
||||
msg = _("Ambiguous security_groups.")
|
||||
raise exception.ServiceInstanceException(msg)
|
||||
else:
|
||||
sg = s_groups[0]
|
||||
return sg
|
||||
|
||||
def _create_service_instance_security_group(self, context,
|
||||
name=None, description=None):
|
||||
"""Creates and returns security_group for service vm."""
|
||||
if not name:
|
||||
name = CONF.service_instance_security_group
|
||||
if not description:
|
||||
description = "This security group is intended to "\
|
||||
"be used by share service."
|
||||
LOG.debug("Creating security group with name '%s'." % name)
|
||||
sg = self.compute_api.security_group_create(context, name, description)
|
||||
for protocol, ports in constants.SERVICE_INSTANCE_SECGROUP_DATA:
|
||||
self.compute_api.security_group_rule_create(context,
|
||||
parent_group_id=sg.id,
|
||||
ip_protocol=protocol,
|
||||
from_port=ports[0],
|
||||
to_port=ports[1],
|
||||
cidr="0.0.0.0/0",
|
||||
)
|
||||
return sg
|
||||
|
||||
def _ensure_server(self, context, server, update=False):
|
||||
"""Ensures that server exists and active, otherwise deletes it."""
|
||||
if not server:
|
||||
|
@ -352,6 +394,10 @@ class ServiceInstanceManager(object):
|
|||
raise exception.ServiceInstanceException(_('Neither service '
|
||||
'instance password nor key are available.'))
|
||||
|
||||
security_group = self._get_service_instance_security_group(context)
|
||||
if not security_group and CONF.service_instance_security_group:
|
||||
security_group = self._create_service_instance_security_group(
|
||||
context)
|
||||
port = self._setup_network_for_instance(context,
|
||||
share_network_id,
|
||||
old_server_ip)
|
||||
|
@ -363,13 +409,11 @@ class ServiceInstanceManager(object):
|
|||
raise
|
||||
|
||||
service_instance = self.compute_api.server_create(context,
|
||||
instance_name,
|
||||
service_image_id,
|
||||
CONF.service_instance_flavor_id,
|
||||
key_name,
|
||||
None,
|
||||
None,
|
||||
nics=[{'port-id': port['id']}])
|
||||
name=instance_name,
|
||||
image=service_image_id,
|
||||
flavor=CONF.service_instance_flavor_id,
|
||||
key_name=key_name,
|
||||
nics=[{'port-id': port['id']}])
|
||||
|
||||
t = time.time()
|
||||
while time.time() - t < CONF.max_time_to_build_instance:
|
||||
|
@ -389,6 +433,12 @@ class ServiceInstanceManager(object):
|
|||
_('Instance have not been spawned in %ss. Giving up.') %
|
||||
CONF.max_time_to_build_instance)
|
||||
|
||||
if security_group:
|
||||
LOG.debug("Adding security group "
|
||||
"'%s' to server '%s'." % (security_group.id,
|
||||
service_instance["id"]))
|
||||
self.compute_api.add_security_group_to_server(context,
|
||||
service_instance["id"], security_group.id)
|
||||
service_instance['ip'] = self._get_server_ip(service_instance)
|
||||
if not self._check_server_availability(service_instance):
|
||||
raise exception.ServiceInstanceException(
|
||||
|
|
|
@ -60,6 +60,14 @@ class FakeImage(object):
|
|||
setattr(self, key, value)
|
||||
|
||||
|
||||
class FakeSecurityGroup(object):
|
||||
def __init__(self, **kwargs):
|
||||
self.id = kwargs.pop('id', 'fake_security_group_id')
|
||||
self.name = kwargs.pop('name', 'fake_security_group_name')
|
||||
for key, value in kwargs.items():
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
class API(object):
|
||||
"""Fake Compute API"""
|
||||
def instance_volume_attach(self, ctx, server_id, volume_id, mount_path):
|
||||
|
@ -94,3 +102,15 @@ class API(object):
|
|||
|
||||
def image_list(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def security_group_create(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def security_group_list(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def add_security_group_to_server(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def security_group_rule_create(self, *args, **kwargs):
|
||||
pass
|
||||
|
|
|
@ -123,6 +123,65 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
self.assertRaises(exception.ManilaException,
|
||||
self._manager._get_server_ip, fake_server)
|
||||
|
||||
def test_get_security_group_name_is_unique(self):
|
||||
fake_secgroup = fake_compute.FakeSecurityGroup()
|
||||
self.stubs.Set(self._manager.compute_api, 'security_group_list',
|
||||
mock.Mock(return_value=[fake_secgroup, ]))
|
||||
result = self._manager._get_service_instance_security_group(
|
||||
self._context, fake_secgroup.name)
|
||||
self.assertEqual(result, fake_secgroup)
|
||||
|
||||
def test_get_security_group_name_is_absent(self):
|
||||
self.stubs.Set(self._manager.compute_api, 'security_group_list',
|
||||
mock.Mock(return_value=[]))
|
||||
result = self._manager._get_service_instance_security_group(
|
||||
self._context, "fake_absent_name")
|
||||
self.assertEqual(result, None)
|
||||
|
||||
def test_get_security_group_name_not_unique(self):
|
||||
fake_secgroup1 = fake_compute.FakeSecurityGroup()
|
||||
fake_secgroup2 = fake_compute.FakeSecurityGroup()
|
||||
self.stubs.Set(self._manager.compute_api, 'security_group_list',
|
||||
mock.Mock(return_value=[fake_secgroup1,
|
||||
fake_secgroup2, ]))
|
||||
self.assertRaises(exception.ServiceInstanceException,
|
||||
self._manager._get_service_instance_security_group,
|
||||
self._context,
|
||||
fake_secgroup1.name)
|
||||
|
||||
def test_get_security_group_name_not_provided_at_all(self):
|
||||
fake_secgroup = fake_compute.FakeSecurityGroup(
|
||||
name=CONF.service_instance_security_group)
|
||||
self.stubs.Set(self._manager.compute_api, 'security_group_list',
|
||||
mock.Mock(return_value=[fake_secgroup, ]))
|
||||
default_option = CONF.service_instance_security_group
|
||||
try:
|
||||
CONF.service_instance_security_group = ""
|
||||
result = self._manager._get_service_instance_security_group(
|
||||
context=self._context, name="")
|
||||
self.assertEqual(result, None)
|
||||
finally:
|
||||
CONF.service_instance_security_group = default_option
|
||||
|
||||
def test_get_security_group_name_not_provided(self):
|
||||
fake_secgroup = fake_compute.FakeSecurityGroup(
|
||||
name=CONF.service_instance_security_group)
|
||||
self.stubs.Set(self._manager.compute_api, 'security_group_list',
|
||||
mock.Mock(return_value=[fake_secgroup, ]))
|
||||
result = self._manager._get_service_instance_security_group(
|
||||
context=self._context, name=None)
|
||||
self.assertEqual(result, fake_secgroup)
|
||||
|
||||
def test_create_security_group(self):
|
||||
self.stubs.Set(self._manager.compute_api, 'security_group_create',
|
||||
mock.Mock(return_value=mock.Mock()))
|
||||
self.stubs.Set(self._manager.compute_api, 'security_group_rule_create',
|
||||
mock.Mock(return_value=mock.Mock()))
|
||||
result = self._manager._create_service_instance_security_group(
|
||||
context=self._context, name="fake_name",
|
||||
description="fake_description")
|
||||
self._manager.compute_api.security_group_create.assert_called_once()
|
||||
|
||||
def test_get_service_instance(self):
|
||||
fake_server = fake_compute.FakeServer()
|
||||
self.stubs.Set(self._manager, '_ensure_server',
|
||||
|
@ -358,6 +417,7 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
def test_create_service_instance(self):
|
||||
fake_server = fake_compute.FakeServer()
|
||||
fake_port = fake_network.FakePort()
|
||||
fake_security_group = fake_compute.FakeSecurityGroup()
|
||||
fake_instance_name = 'fake_instance_name'
|
||||
sn_id = 'fake_sn_id'
|
||||
self.stubs.Set(self._manager, '_get_service_image',
|
||||
|
@ -373,6 +433,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
mock.Mock(return_value=fake_server))
|
||||
self.stubs.Set(self._manager, '_get_server_ip',
|
||||
mock.Mock(return_value='fake_ip'))
|
||||
self.stubs.Set(self._manager, '_get_service_instance_security_group',
|
||||
mock.Mock(return_value=fake_security_group))
|
||||
self.stubs.Set(service_instance.socket, 'socket', mock.Mock())
|
||||
self.stubs.Set(self._manager, '_get_service_instance_name',
|
||||
mock.Mock(return_value=fake_instance_name))
|
||||
|
@ -385,19 +447,22 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
self._manager._setup_connectivity_with_service_instances.\
|
||||
assert_called_once()
|
||||
self._manager.compute_api.server_create.assert_called_once_with(
|
||||
self._context, fake_instance_name, 'fake_image_id',
|
||||
CONF.service_instance_flavor_id, 'fake_key_name', None, None,
|
||||
nics=[{'port-id': fake_port['id']}])
|
||||
self._context, name=fake_instance_name, image='fake_image_id',
|
||||
flavor=CONF.service_instance_flavor_id,
|
||||
key_name='fake_key_name', nics=[{'port-id': fake_port['id']}])
|
||||
service_instance.socket.socket.assert_called_once()
|
||||
self.assertEqual(result, fake_server)
|
||||
|
||||
def test_create_service_instance_error(self):
|
||||
fake_server = fake_compute.FakeServer(status='ERROR')
|
||||
fake_port = fake_network.FakePort()
|
||||
fake_security_group = fake_compute.FakeSecurityGroup()
|
||||
self.stubs.Set(self._manager, '_get_service_image',
|
||||
mock.Mock(return_value='fake_image_id'))
|
||||
self.stubs.Set(self._manager, '_get_key',
|
||||
mock.Mock(return_value='fake_key_name'))
|
||||
self.stubs.Set(self._manager, '_get_service_instance_security_group',
|
||||
mock.Mock(return_value=fake_security_group))
|
||||
self.stubs.Set(self._manager, '_setup_network_for_instance',
|
||||
mock.Mock(return_value=fake_port))
|
||||
self.stubs.Set(self._manager,
|
||||
|
@ -420,10 +485,13 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
def test_create_service_instance_failed_setup_connectivity(self):
|
||||
fake_server = fake_compute.FakeServer(status='ERROR')
|
||||
fake_port = fake_network.FakePort()
|
||||
fake_security_group = fake_compute.FakeSecurityGroup()
|
||||
self.stubs.Set(self._manager, '_get_service_image',
|
||||
mock.Mock(return_value='fake_image_id'))
|
||||
self.stubs.Set(self._manager, '_get_key',
|
||||
mock.Mock(return_value='fake_key_name'))
|
||||
self.stubs.Set(self._manager, '_get_service_instance_security_group',
|
||||
mock.Mock(return_value=fake_security_group))
|
||||
self.stubs.Set(self._manager, '_setup_network_for_instance',
|
||||
mock.Mock(return_value=fake_port))
|
||||
self.stubs.Set(self._manager,
|
||||
|
|
Loading…
Reference in New Issue