diff --git a/unit_tests/utilitites/test_zaza_utilitites_openstack_utils.py b/unit_tests/utilitites/test_zaza_utilitites_openstack_utils.py new file mode 100644 index 0000000..29e1685 --- /dev/null +++ b/unit_tests/utilitites/test_zaza_utilitites_openstack_utils.py @@ -0,0 +1,69 @@ +import mock +import unit_tests.utils as ut_utils +from zaza.utilities import openstack_utils + + +class TestOpenStackUtils(ut_utils.BaseTestCase): + + def setUp(self): + super(TestOpenStackUtils, self).setUp() + self.port_name = 'port_name' + self.net_uuid = 'uuid' + self.port = { + 'port': {'id': 'port_id', + 'name': self.port_name, + 'network_id': self.net_uuid}} + + self.ports = {'ports': [self.port['port']]} + self.floatingip = { + 'floatingip': {'id': 'floatingip_id', + 'floating_network_id': self.net_uuid, + 'port_id': 'port_id'}} + + self.floatingips = {'floatingips': [self.floatingip['floatingip']]} + + self.neutronclient = mock.MagicMock() + self.neutronclient.list_ports.return_value = self.ports + self.neutronclient.create_port.return_value = self.port + + self.neutronclient.list_floatingips.return_value = self.floatingips + self.neutronclient.create_floatingip.return_value = self.floatingip + self.ext_net = 'ext_net' + self.private_net = 'private_net' + + def test_create_port(self): + self.patch_object(openstack_utils, 'get_net_uuid') + self.get_net_uuid.return_value = self.net_uuid + + # Already exists + port = openstack_utils.create_port( + self.neutronclient, self.port_name, self.private_net) + self.assertEqual(port, self.port['port']) + self.neutronclient.create_port.assert_not_called() + + # Does not yet exist + self.neutronclient.list_ports.return_value = {'ports': []} + self.port['port'].pop('id') + port = openstack_utils.create_port( + self.neutronclient, self.port_name, self.private_net) + self.assertEqual(port, self.port['port']) + self.neutronclient.create_port.assert_called_once_with(self.port) + + def test_create_floating_ip(self): + self.patch_object(openstack_utils, 'get_net_uuid') + self.get_net_uuid.return_value = self.net_uuid + + # Already exists + floatingip = openstack_utils.create_floating_ip( + self.neutronclient, self.ext_net, port=self.port['port']) + self.assertEqual(floatingip, self.floatingip['floatingip']) + self.neutronclient.create_floatingip.assert_not_called() + + # Does not yet exist + self.neutronclient.list_floatingips.return_value = {'floatingips': []} + self.floatingip['floatingip'].pop('id') + floatingip = openstack_utils.create_floating_ip( + self.neutronclient, self.private_net, port=self.port['port']) + self.assertEqual(floatingip, self.floatingip['floatingip']) + self.neutronclient.create_floatingip.assert_called_once_with( + self.floatingip) diff --git a/zaza/utilities/openstack_utils.py b/zaza/utilities/openstack_utils.py old mode 100755 new mode 100644 index 6b69567..c381e87 --- a/zaza/utilities/openstack_utils.py +++ b/zaza/utilities/openstack_utils.py @@ -377,7 +377,7 @@ def configure_gateway_ext_port(novaclient, neutronclient, model.set_application_config( lifecycle_utils.get_juju_model(), application_name, configuration={config_key: ext_br_macs_str}) - juju_wait.wait(wait_for_workload=True) + juju_wait.wait() def create_project_network(neutron_client, project_id, net_name='private', @@ -930,6 +930,75 @@ def add_neutron_secgroup_rules(neutron_client, project_id): }) +def create_port(neutron_client, name, network_name): + """Create port on network + + :param neutron_client: Authenticated neutronclient + :type neutron_client: neutronclient.Client object + :param name: Port name + :type name: string + :param network_name: Network name the port is on + :type network_name: string + :returns: Port object + :rtype: dict + """ + + ports = neutron_client.list_ports(name=name) + if len(ports['ports']) == 0: + logging.info('Creating port: {}'.format(name)) + network_id = get_net_uuid(neutron_client, network_name) + port_msg = { + 'port': { + 'name': name, + 'network_id': network_id, + } + } + port = neutron_client.create_port(port_msg)['port'] + else: + logging.debug('Port {} already exists.'.format(name)) + port = ports['ports'][0] + + return port + + +def create_floating_ip(neutron_client, network_name, port=None): + """Create floating IP on network and optionally associate to a port + + :param neutron_client: Authenticated neutronclient + :type neutron_client: neutronclient.Client object + :param network_name: Name of external netowrk for FIPs + :type network_name: string + :param port: Port object + :type port: dict + :returns: Floating IP object + :rtype: dict + """ + + floatingips = neutron_client.list_floatingips() + if len(floatingips['floatingips']) > 0: + if port: + for floatingip in floatingips['floatingips']: + if floatingip.get('port_id') == port['id']: + logging.debug('Floating IP with port, {}, already' + 'exists.'.format(port['name'])) + return floatingip + logging.warning('A floating IP already exists but ports do not match ' + 'Potentially creating more than one.') + + logging.info('Creating floatingip') + network_id = get_net_uuid(neutron_client, network_name) + floatingip_msg = { + 'floatingip': { + 'floating_network_id': network_id, + } + } + if port: + floatingip_msg['floatingip']['port_id'] = port['id'] + floatingip = neutron_client.create_floatingip( + floatingip_msg)['floatingip'] + return floatingip + + # Codename and package versions def get_swift_codename(version): """Determine OpenStack codename that corresponds to swift version