summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorspisarski <s.pisarski@cablelabs.com>2017-07-06 13:09:46 -0600
committerspisarski <s.pisarski@cablelabs.com>2017-07-06 13:18:37 -0600
commit8bd26c2d75108037430fde83ea57ab0b964f0058 (patch)
treebc7a2985000041e9c46eaec46e8aec28e45ca355
parent5616cafabcc5f8ab75ee6fcaefa87e3fbd126ce9 (diff)
Created domain object for flavors.
OpenStack implementation details were leaking out into the flavor creator. JIRA: SNAPS-111 Change-Id: I59a77d02e30065a7f4560e74295b2084a83686df Signed-off-by: spisarski <s.pisarski@cablelabs.com>
-rw-r--r--snaps/domain/flavor.py43
-rw-r--r--snaps/domain/test/flavor_tests.py50
-rw-r--r--snaps/openstack/create_flavor.py5
-rw-r--r--snaps/openstack/utils/nova_utils.py97
-rw-r--r--snaps/test_suite_builder.py8
5 files changed, 183 insertions, 20 deletions
diff --git a/snaps/domain/flavor.py b/snaps/domain/flavor.py
new file mode 100644
index 0000000..035ca64
--- /dev/null
+++ b/snaps/domain/flavor.py
@@ -0,0 +1,43 @@
+# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
+# and others. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+
+class Flavor:
+ """
+ SNAPS domain object for Flavors. Should contain attributes that
+ are shared amongst cloud providers
+ """
+ def __init__(self, **kwargs):
+ """
+ Constructor
+ :param name: the flavor's name
+ :param flavor_id: the flavor's id
+ :param ram: the flavor's RAM in MB
+ :param disk: the flavor's disk size in GB
+ :param vcpus: the flavor's number of virtual CPUs
+ :param ephemeral: the flavor's ephemeral disk in GB
+ :param swap: the flavor's swap space in MB
+ :param rxtx_factor: the flavor's RX/TX factor integer value
+ :param is_public: denotes if flavor can be used by other projects
+ """
+ self.name = kwargs.get('name')
+ self.id = kwargs.get('id')
+ self.ram = kwargs.get('ram')
+ self.disk = kwargs.get('disk')
+ self.vcpus = kwargs.get('vcpus')
+ self.ephemeral = kwargs.get('ephemeral')
+ self.swap = kwargs.get('swap')
+ self.rxtx_factor = kwargs.get('rxtx_factor')
+ self.is_public = kwargs.get('is_public')
diff --git a/snaps/domain/test/flavor_tests.py b/snaps/domain/test/flavor_tests.py
new file mode 100644
index 0000000..4b74bd7
--- /dev/null
+++ b/snaps/domain/test/flavor_tests.py
@@ -0,0 +1,50 @@
+# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
+# and others. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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.
+
+import unittest
+from snaps.domain.flavor import Flavor
+
+
+class FlavorDomainObjectTests(unittest.TestCase):
+ """
+ Tests the construction of the snaps.domain.test.Flavor class
+ """
+
+ def test_construction_kwargs(self):
+ flavor = Flavor(**{'name': 'name', 'id': 'id', 'ram': 10, 'disk': 20,
+ 'vcpus': 3, 'ephemeral': 30, 'swap': 100,
+ 'rxtx_factor': 5, 'is_public': True})
+ self.assertEqual('name', flavor.name)
+ self.assertEqual('id', flavor.id)
+ self.assertEqual(10, flavor.ram)
+ self.assertEqual(20, flavor.disk)
+ self.assertEqual(3, flavor.vcpus)
+ self.assertEqual(30, flavor.ephemeral)
+ self.assertEqual(100, flavor.swap)
+ self.assertEqual(5, flavor.rxtx_factor)
+ self.assertTrue(flavor.is_public)
+
+ def test_construction_named(self):
+ flavor = Flavor(is_public=True, rxtx_factor=5, swap=100, ephemeral=30,
+ vcpus=3, disk=20, ram=10, id='id', name='name')
+ self.assertEqual('name', flavor.name)
+ self.assertEqual('id', flavor.id)
+ self.assertEqual(10, flavor.ram)
+ self.assertEqual(20, flavor.disk)
+ self.assertEqual(3, flavor.vcpus)
+ self.assertEqual(30, flavor.ephemeral)
+ self.assertEqual(100, flavor.swap)
+ self.assertEqual(5, flavor.rxtx_factor)
+ self.assertTrue(flavor.is_public)
diff --git a/snaps/openstack/create_flavor.py b/snaps/openstack/create_flavor.py
index f1c7ee3..42264b0 100644
--- a/snaps/openstack/create_flavor.py
+++ b/snaps/openstack/create_flavor.py
@@ -60,9 +60,8 @@ class OpenStackFlavor:
self.__flavor = nova_utils.create_flavor(
self.__nova, self.flavor_settings)
if self.flavor_settings.metadata:
- self.__flavor.set_keys(self.flavor_settings.metadata)
- self.__flavor = nova_utils.get_flavor_by_name(
- self.__nova, self.flavor_settings.name)
+ nova_utils.set_flavor_keys(self.__nova, self.__flavor,
+ self.flavor_settings.metadata)
else:
logger.info('Did not create flavor due to cleanup mode')
diff --git a/snaps/openstack/utils/nova_utils.py b/snaps/openstack/utils/nova_utils.py
index bab0533..d6f9a19 100644
--- a/snaps/openstack/utils/nova_utils.py
+++ b/snaps/openstack/utils/nova_utils.py
@@ -21,6 +21,8 @@ from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from novaclient.client import Client
from novaclient.exceptions import NotFound
+
+from snaps.domain.flavor import Flavor
from snaps.domain.vm_inst import VmInst
from snaps.openstack.utils import keystone_utils, glance_utils, neutron_utils
@@ -290,12 +292,45 @@ def delete_vm_instance(nova, vm_inst):
nova.servers.delete(vm_inst.id)
-def get_flavor_by_name(nova, name):
+def get_os_flavor(nova, flavor):
"""
- Returns a flavor by name
+ Returns to OpenStack flavor object by name
:param nova: the Nova client
- :param name: the flavor name to return
- :return: the OpenStack flavor object or None if not exists
+ :param flavor: the SNAPS flavor domain object
+ :return: the OpenStack Flavor object
+ """
+ try:
+ return nova.flavors.get(flavor.id)
+ except NotFound:
+ return None
+
+
+def get_flavor(nova, flavor):
+ """
+ Returns to OpenStack flavor object by name
+ :param nova: the Nova client
+ :param flavor: the SNAPS flavor domain object
+ :return: the SNAPS Flavor domain object
+ """
+ os_flavor = get_os_flavor(nova, flavor)
+ if os_flavor:
+ return Flavor(
+ name=os_flavor.name, id=os_flavor.id, ram=os_flavor.ram,
+ disk=os_flavor.disk, vcpus=os_flavor.vcpus,
+ ephemeral=os_flavor.ephemeral, swap=os_flavor.swap,
+ rxtx_factor=os_flavor.rxtx_factor, is_public=os_flavor.is_public)
+ try:
+ return nova.flavors.get(flavor.id)
+ except NotFound:
+ return None
+
+
+def get_os_flavor_by_name(nova, name):
+ """
+ Returns to OpenStack flavor object by name
+ :param nova: the Nova client
+ :param name: the name of the flavor to query
+ :return: OpenStack flavor object
"""
try:
return nova.flavors.find(name=name)
@@ -303,31 +338,61 @@ def get_flavor_by_name(nova, name):
return None
+def get_flavor_by_name(nova, name):
+ """
+ Returns a flavor by name
+ :param nova: the Nova client
+ :param name: the flavor name to return
+ :return: the SNAPS flavor domain object or None if not exists
+ """
+ os_flavor = get_os_flavor_by_name(nova, name)
+ if os_flavor:
+ return Flavor(
+ name=os_flavor.name, id=os_flavor.id, ram=os_flavor.ram,
+ disk=os_flavor.disk, vcpus=os_flavor.vcpus,
+ ephemeral=os_flavor.ephemeral, swap=os_flavor.swap,
+ rxtx_factor=os_flavor.rxtx_factor, is_public=os_flavor.is_public)
+
+
def create_flavor(nova, flavor_settings):
"""
Creates and returns and OpenStack flavor object
:param nova: the Nova client
:param flavor_settings: the flavor settings
- :return: the Flavor
+ :return: the SNAPS flavor domain object
"""
- return nova.flavors.create(name=flavor_settings.name,
- flavorid=flavor_settings.flavor_id,
- ram=flavor_settings.ram,
- vcpus=flavor_settings.vcpus,
- disk=flavor_settings.disk,
- ephemeral=flavor_settings.ephemeral,
- swap=flavor_settings.swap,
- rxtx_factor=flavor_settings.rxtx_factor,
- is_public=flavor_settings.is_public)
+ os_flavor = nova.flavors.create(
+ name=flavor_settings.name, flavorid=flavor_settings.flavor_id,
+ ram=flavor_settings.ram, vcpus=flavor_settings.vcpus,
+ disk=flavor_settings.disk, ephemeral=flavor_settings.ephemeral,
+ swap=flavor_settings.swap, rxtx_factor=flavor_settings.rxtx_factor,
+ is_public=flavor_settings.is_public)
+ return Flavor(
+ name=os_flavor.name, id=os_flavor.id, ram=os_flavor.ram,
+ disk=os_flavor.disk, vcpus=os_flavor.vcpus,
+ ephemeral=os_flavor.ephemeral, swap=os_flavor.swap,
+ rxtx_factor=os_flavor.rxtx_factor, is_public=os_flavor.is_public)
def delete_flavor(nova, flavor):
"""
Deletes a flavor
:param nova: the Nova client
- :param flavor: the OpenStack flavor object
+ :param flavor: the SNAPS flavor domain object
+ """
+ nova.flavors.delete(flavor.id)
+
+
+def set_flavor_keys(nova, flavor, metadata):
+ """
+ Sets metadata on the flavor
+ :param nova: the Nova client
+ :param flavor: the SNAPS flavor domain object
+ :param metadata: the metadata to set
"""
- nova.flavors.delete(flavor)
+ os_flavor = get_os_flavor(nova, flavor)
+ if os_flavor:
+ os_flavor.set_keys(metadata)
def add_security_group(nova, vm, security_group_name):
diff --git a/snaps/test_suite_builder.py b/snaps/test_suite_builder.py
index 6c28b7e..eb6e65a 100644
--- a/snaps/test_suite_builder.py
+++ b/snaps/test_suite_builder.py
@@ -16,13 +16,15 @@
import logging
import unittest
+from snaps.domain.test.flavor_tests import FlavorDomainObjectTests
from snaps.domain.test.image_tests import ImageDomainObjectTests
from snaps.domain.test.stack_tests import StackDomainObjectTests
from snaps.domain.test.vm_inst_tests import (VmInstDomainObjectTests,
FloatingIpDomainObjectTests)
from snaps.openstack.tests.conf.os_credentials_tests import (
ProxySettingsUnitTests, OSCredsUnitTests)
-from snaps.openstack.tests.create_flavor_tests import CreateFlavorTests
+from snaps.openstack.tests.create_flavor_tests import (
+ CreateFlavorTests, FlavorSettingsUnitTests)
from snaps.openstack.tests.create_image_tests import (
CreateImageSuccessTests, CreateImageNegativeTests, ImageSettingsUnitTests,
CreateMultiPartImageTests)
@@ -92,6 +94,10 @@ def add_unit_tests(suite):
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
ImageDomainObjectTests))
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
+ FlavorSettingsUnitTests))
+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
+ FlavorDomainObjectTests))
+ suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
KeypairSettingsUnitTests))
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(
UserSettingsUnitTests))