summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--snaps/openstack/create_project.py8
-rw-r--r--snaps/openstack/create_router.py24
-rw-r--r--snaps/openstack/tests/create_flavor_tests.py70
-rw-r--r--snaps/openstack/tests/create_image_tests.py9
-rw-r--r--snaps/openstack/tests/create_project_tests.py7
-rw-r--r--snaps/openstack/tests/create_router_tests.py13
-rw-r--r--snaps/openstack/utils/glance_utils.py37
-rw-r--r--snaps/openstack/utils/nova_utils.py11
8 files changed, 126 insertions, 53 deletions
diff --git a/snaps/openstack/create_project.py b/snaps/openstack/create_project.py
index 0384ccc..a20033e 100644
--- a/snaps/openstack/create_project.py
+++ b/snaps/openstack/create_project.py
@@ -131,5 +131,11 @@ class ProjectSettings:
self.enabled = True
if not self.name:
- raise Exception(
+ raise ProjectSettingsError(
"The attribute name is required for ProjectSettings")
+
+
+class ProjectSettingsError(Exception):
+ """
+ Exception to be thrown when project settings attributes are incorrect
+ """
diff --git a/snaps/openstack/create_router.py b/snaps/openstack/create_router.py
index db6ffe3..e50009c 100644
--- a/snaps/openstack/create_router.py
+++ b/snaps/openstack/create_router.py
@@ -39,7 +39,7 @@ class OpenStackRouter:
self.__os_creds = os_creds
if not router_settings:
- raise Exception('router_settings is required')
+ raise RouterCreationError('router_settings is required')
self.router_settings = router_settings
self.__neutron = None
@@ -84,7 +84,7 @@ class OpenStackRouter:
self.__internal_router_interface = neutron_utils.add_interface_router(
self.__neutron, self.__router, subnet=internal_subnet)
else:
- raise Exception(
+ raise RouterCreationError(
'Subnet not found with name ' + internal_subnet_name)
for port_setting in self.router_settings.port_settings:
@@ -108,7 +108,7 @@ class OpenStackRouter:
self.__router,
port=port)
else:
- raise Exception(
+ raise RouterCreationError(
'Error creating port with name - ' + port_setting.name)
return self.__router
@@ -163,6 +163,12 @@ class OpenStackRouter:
return self.__internal_router_interface
+class RouterCreationError(Exception):
+ """
+ Exception to be thrown when an router instance cannot be created
+ """
+
+
class RouterSettings:
"""
Class representing a router configuration
@@ -209,7 +215,7 @@ class RouterSettings:
PortSettings(**interface['port']))
if not self.name:
- raise Exception('Name is required')
+ raise RouterSettingsError('Name is required')
def dict_for_neutron(self, neutron, os_creds):
"""
@@ -239,7 +245,7 @@ class RouterSettings:
if project_id:
out['project_id'] = project_id
else:
- raise Exception(
+ raise RouterSettingsError(
'Could not find project ID for project named - ' +
self.project_name)
if self.admin_state_up is not None:
@@ -251,7 +257,7 @@ class RouterSettings:
ext_gw['network_id'] = ext_net.id
out['external_gateway_info'] = ext_gw
else:
- raise Exception(
+ raise RouterSettingsError(
'Could not find the external network named - ' +
self.external_gateway)
@@ -259,3 +265,9 @@ class RouterSettings:
# TODO: Add external_fixed_ips Tests
return {'router': out}
+
+
+class RouterSettingsError(Exception):
+ """
+ Exception to be thrown when router settings attributes are incorrect
+ """
diff --git a/snaps/openstack/tests/create_flavor_tests.py b/snaps/openstack/tests/create_flavor_tests.py
index 11306f4..4852d06 100644
--- a/snaps/openstack/tests/create_flavor_tests.py
+++ b/snaps/openstack/tests/create_flavor_tests.py
@@ -15,6 +15,7 @@
import unittest
import uuid
+from snaps.openstack import create_flavor
from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor, \
FlavorSettingsError
from snaps.openstack.tests.os_source_file_test import OSComponentTestCase
@@ -294,7 +295,7 @@ class CreateFlavorTests(OSComponentTestCase):
vcpus=1)
self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
flavor = self.flavor_creator.create()
- self.assertTrue(validate_flavor(flavor_settings, flavor))
+ self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
def test_create_flavor_existing(self):
"""
@@ -306,7 +307,7 @@ class CreateFlavorTests(OSComponentTestCase):
vcpus=1)
self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
flavor = self.flavor_creator.create()
- self.assertTrue(validate_flavor(flavor_settings, flavor))
+ self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
flavor_creator_2 = OpenStackFlavor(self.os_creds, flavor_settings)
flavor2 = flavor_creator_2.create()
@@ -322,7 +323,7 @@ class CreateFlavorTests(OSComponentTestCase):
vcpus=1)
self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
flavor = self.flavor_creator.create()
- self.assertTrue(validate_flavor(flavor_settings, flavor))
+ self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
# Clean Flavor
self.flavor_creator.clean()
@@ -333,7 +334,7 @@ class CreateFlavorTests(OSComponentTestCase):
def test_create_delete_flavor(self):
"""
- Tests the creation of an OpenStack Security Group, the deletion, then
+ Tests the creation of an OpenStack Flavor, the deletion, then
cleanup to ensure clean() does not
raise any exceptions.
"""
@@ -342,7 +343,7 @@ class CreateFlavorTests(OSComponentTestCase):
vcpus=1)
self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
flavor = self.flavor_creator.create()
- self.assertTrue(validate_flavor(flavor_settings, flavor))
+ self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
# Delete Flavor
nova_utils.delete_flavor(self.nova, flavor)
@@ -354,17 +355,62 @@ class CreateFlavorTests(OSComponentTestCase):
self.assertIsNone(self.flavor_creator.get_flavor())
- # TODO - Add more tests to exercise all configuration options
+ def test_create_flavor_all_settings(self):
+ """
+ Tests the creation of an OpenStack Flavor, the deletion, then
+ cleanup to ensure clean() does not
+ raise any exceptions.
+ """
+ # Create Flavor
+ flavor_settings = FlavorSettings(
+ name=self.flavor_name, ram=1, disk=1, vcpus=1, ephemeral=2, swap=3,
+ rxtx_factor=2.2, is_public=False,
+ metadata=create_flavor.MEM_PAGE_SIZE_ANY)
+ self.flavor_creator = OpenStackFlavor(self.os_creds, flavor_settings)
+ flavor = self.flavor_creator.create()
+ self.assertTrue(validate_flavor(self.nova, flavor_settings, flavor))
+
+ # Delete Flavor
+ nova_utils.delete_flavor(self.nova, flavor)
+ self.assertIsNone(
+ nova_utils.get_flavor_by_name(self.nova, flavor_settings.name))
+
+ # Attempt to cleanup
+ self.flavor_creator.clean()
+
+ self.assertIsNone(self.flavor_creator.get_flavor())
-def validate_flavor(flavor_settings, flavor):
+def validate_flavor(nova, flavor_settings, flavor):
"""
Validates the flavor_settings against the OpenStack flavor object
+ :param nova: the nova client
:param flavor_settings: the settings used to create the flavor
:param flavor: the OpenStack flavor object
"""
- return flavor is not None \
- and flavor_settings.name == flavor.name \
- and flavor_settings.ram == flavor.ram \
- and flavor_settings.disk == flavor.disk \
- and flavor_settings.vcpus == flavor.vcpus
+ setting_meta = dict()
+ if flavor_settings.metadata:
+ setting_meta = flavor_settings.metadata
+ metadata = nova_utils.get_flavor_keys(nova, flavor)
+
+ equals = True
+ for key, value in setting_meta.items():
+ if metadata[key] != value:
+ equals = False
+ break
+
+ swap = str()
+ if flavor_settings.swap != 0:
+ swap = flavor_settings.swap
+
+ return (
+ flavor is not None and
+ flavor_settings.name == flavor.name and
+ flavor_settings.ram == flavor.ram and
+ flavor_settings.disk == flavor.disk and
+ flavor_settings.vcpus == flavor.vcpus and
+ flavor_settings.ephemeral == flavor.ephemeral and
+ swap == flavor.swap and
+ flavor_settings.rxtx_factor == flavor.rxtx_factor and
+ flavor_settings.is_public == flavor.is_public and
+ equals)
diff --git a/snaps/openstack/tests/create_image_tests.py b/snaps/openstack/tests/create_image_tests.py
index d538fef..6c9b175 100644
--- a/snaps/openstack/tests/create_image_tests.py
+++ b/snaps/openstack/tests/create_image_tests.py
@@ -12,6 +12,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+from glanceclient.exc import HTTPBadRequest
try:
from urllib.request import URLError
@@ -514,8 +515,14 @@ class CreateImageNegativeTests(OSIntegrationTestCase):
img_format=os_image_settings.format,
url="http://foo.bar"))
- with self.assertRaises(URLError):
+ try:
self.image_creator.create()
+ except HTTPBadRequest:
+ pass
+ except URLError:
+ pass
+ except Exception as e:
+ self.fail('Invalid Exception ' + str(e))
def test_bad_image_file(self):
"""
diff --git a/snaps/openstack/tests/create_project_tests.py b/snaps/openstack/tests/create_project_tests.py
index 3c6b2d1..f2af0d9 100644
--- a/snaps/openstack/tests/create_project_tests.py
+++ b/snaps/openstack/tests/create_project_tests.py
@@ -15,7 +15,8 @@
import unittest
import uuid
-from snaps.openstack.create_project import OpenStackProject, ProjectSettings
+from snaps.openstack.create_project import (
+ OpenStackProject, ProjectSettings, ProjectSettingsError)
from snaps.openstack.create_security_group import OpenStackSecurityGroup
from snaps.openstack.create_security_group import SecurityGroupSettings
from snaps.openstack.create_user import OpenStackUser
@@ -32,11 +33,11 @@ class ProjectSettingsUnitTests(unittest.TestCase):
"""
def test_no_params(self):
- with self.assertRaises(Exception):
+ with self.assertRaises(ProjectSettingsError):
ProjectSettings()
def test_empty_config(self):
- with self.assertRaises(Exception):
+ with self.assertRaises(ProjectSettingsError):
ProjectSettings(**dict())
def test_name_only(self):
diff --git a/snaps/openstack/tests/create_router_tests.py b/snaps/openstack/tests/create_router_tests.py
index 5f2534d..efa0993 100644
--- a/snaps/openstack/tests/create_router_tests.py
+++ b/snaps/openstack/tests/create_router_tests.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Cable Television Laboratories, Inc. ("CableLabs")
+# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
# and others. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,7 +20,8 @@ from snaps.openstack import create_router
from snaps.openstack.create_network import (
NetworkSettings, PortSettings)
from snaps.openstack.create_network import OpenStackNetwork
-from snaps.openstack.create_router import RouterSettings
+from snaps.openstack.create_router import (
+ RouterSettings, RouterSettingsError, RouterCreationError)
from snaps.openstack.tests.os_source_file_test import OSIntegrationTestCase
from snaps.openstack.utils import neutron_utils
@@ -38,11 +39,11 @@ class RouterSettingsUnitTests(unittest.TestCase):
"""
def test_no_params(self):
- with self.assertRaises(Exception):
+ with self.assertRaises(RouterSettingsError):
RouterSettings()
def test_empty_config(self):
- with self.assertRaises(Exception):
+ with self.assertRaises(RouterSettingsError):
RouterSettings(**dict())
def test_name_only(self):
@@ -338,7 +339,7 @@ class CreateRouterNegativeTests(OSIntegrationTestCase):
"""
Test creating a router without a name.
"""
- with self.assertRaises(Exception):
+ with self.assertRaises(RouterSettingsError):
router_settings = RouterSettings(
name=None, external_gateway=self.ext_net_name)
self.router_creator = create_router.OpenStackRouter(
@@ -349,7 +350,7 @@ class CreateRouterNegativeTests(OSIntegrationTestCase):
"""
Test creating a router without a valid network gateway name.
"""
- with self.assertRaises(Exception):
+ with self.assertRaises(RouterSettingsError):
router_settings = RouterSettings(name=self.guid + '-pub-router',
external_gateway="Invalid_name")
self.router_creator = create_router.OpenStackRouter(
diff --git a/snaps/openstack/utils/glance_utils.py b/snaps/openstack/utils/glance_utils.py
index 1010757..090846c 100644
--- a/snaps/openstack/utils/glance_utils.py
+++ b/snaps/openstack/utils/glance_utils.py
@@ -106,35 +106,24 @@ def __create_image_v1(glance, image_settings):
:return: the OpenStack image object
:raise exceptions from the Glance client or IOError when opening a file
"""
- created_image = None
+ kwargs = {
+ 'name': image_settings.name, 'disk_format': image_settings.format,
+ 'container_format': 'bare', 'is_public': image_settings.public}
+
+ if image_settings.extra_properties:
+ kwargs['properties'] = image_settings.extra_properties
- # TODO/REFACTOR - replace each call with one including kwargs
if image_settings.url:
- if image_settings.extra_properties:
- created_image = glance.images.create(
- name=image_settings.name, disk_format=image_settings.format,
- container_format="bare", location=image_settings.url,
- properties=image_settings.extra_properties,
- is_public=image_settings.public)
- else:
- created_image = glance.images.create(
- name=image_settings.name, disk_format=image_settings.format,
- container_format="bare", location=image_settings.url,
- is_public=image_settings.public)
+ kwargs['location'] = image_settings.url
elif image_settings.image_file:
image_file = open(image_settings.image_file, 'rb')
- if image_settings.extra_properties:
- created_image = glance.images.create(
- name=image_settings.name, disk_format=image_settings.format,
- container_format="bare", data=image_file,
- properties=image_settings.extra_properties,
- is_public=image_settings.public)
- else:
- created_image = glance.images.create(
- name=image_settings.name, disk_format=image_settings.format,
- container_format="bare", data=image_file,
- is_public=image_settings.public)
+ kwargs['data'] = image_file
+ else:
+ logger.warn('Unable to create image with name - %s. No file or URL',
+ image_settings.name)
+ return None
+ created_image = glance.images.create(**kwargs)
return Image(name=image_settings.name, image_id=created_image.id,
size=created_image.size, properties=created_image.properties)
diff --git a/snaps/openstack/utils/nova_utils.py b/snaps/openstack/utils/nova_utils.py
index 16b3984..70b1e7b 100644
--- a/snaps/openstack/utils/nova_utils.py
+++ b/snaps/openstack/utils/nova_utils.py
@@ -454,6 +454,17 @@ def set_flavor_keys(nova, flavor, metadata):
os_flavor.set_keys(metadata)
+def get_flavor_keys(nova, flavor):
+ """
+ Sets metadata on the flavor
+ :param nova: the Nova client
+ :param flavor: the SNAPS flavor domain object
+ """
+ os_flavor = __get_os_flavor(nova, flavor)
+ if os_flavor:
+ return os_flavor.get_keys()
+
+
def add_security_group(nova, vm, security_group_name):
"""
Adds a security group to an existing VM