summaryrefslogtreecommitdiffstats
path: root/snaps/openstack/utils
diff options
context:
space:
mode:
authorSteven Pisarski <s.pisarski@cablelabs.com>2017-10-23 14:55:20 +0000
committerGerrit Code Review <gerrit@opnfv.org>2017-10-23 14:55:20 +0000
commitb878acf1ec1132335120277bf03976758e06d86c (patch)
tree9b43f87847fdee0373f8987678fbdfebcbe827c7 /snaps/openstack/utils
parent7766bd2f8ef5f7ddb9ee231179bb38023d65a972 (diff)
parent38d6a8ce3c9bce63cf1bc8222c5a94070701ef17 (diff)
Merge "Third patch for volume support."
Diffstat (limited to 'snaps/openstack/utils')
-rw-r--r--snaps/openstack/utils/cinder_utils.py84
-rw-r--r--snaps/openstack/utils/tests/cinder_utils_tests.py110
2 files changed, 193 insertions, 1 deletions
diff --git a/snaps/openstack/utils/cinder_utils.py b/snaps/openstack/utils/cinder_utils.py
index d13277d..e40b471 100644
--- a/snaps/openstack/utils/cinder_utils.py
+++ b/snaps/openstack/utils/cinder_utils.py
@@ -17,7 +17,8 @@ import logging
from cinderclient.client import Client
from cinderclient.exceptions import NotFound
-from snaps.domain.volume import QoSSpec, VolumeType, VolumeTypeEncryption
+from snaps.domain.volume import (
+ QoSSpec, VolumeType, VolumeTypeEncryption, Volume)
from snaps.openstack.utils import keystone_utils
__author__ = 'spisarski'
@@ -42,6 +43,87 @@ def cinder_client(os_creds):
region_name=os_creds.region_name)
+def get_volume(cinder, volume_name=None, volume_settings=None):
+ """
+ Returns an OpenStack volume object for a given name
+ :param cinder: the Cinder client
+ :param volume_name: the volume name to lookup
+ :param volume_settings: the volume settings used for lookups
+ :return: the volume object or None
+ """
+ if volume_settings:
+ volume_name = volume_settings.name
+
+ volumes = cinder.volumes.list()
+ for volume in volumes:
+ if volume.name == volume_name:
+ return Volume(
+ name=volume.name, volume_id=volume.id,
+ description=volume.description, size=volume.size,
+ vol_type=volume.volume_type,
+ availability_zone=volume.availability_zone,
+ multi_attach=volume.multiattach)
+
+
+def get_volume_by_id(cinder, volume_id):
+ """
+ Returns an OpenStack volume object for a given name
+ :param cinder: the Cinder client
+ :param volume_id: the volume ID to lookup
+ :return: the SNAPS-OO Domain Volume object or None
+ """
+ volume = cinder.volumes.get(volume_id)
+ return Volume(
+ name=volume.name, volume_id=volume.id, description=volume.description,
+ size=volume.size, vol_type=volume.volume_type,
+ availability_zone=volume.availability_zone,
+ multi_attach=volume.multiattach)
+
+
+def get_volume_status(cinder, volume):
+ """
+ Returns a new OpenStack Volume object for a given OpenStack volume object
+ :param cinder: the Cinder client
+ :param volume: the domain Volume object
+ :return: the OpenStack Volume object
+ """
+ os_volume = cinder.volumes.get(volume.id)
+ return os_volume.status
+
+
+def create_volume(cinder, volume_settings):
+ """
+ Creates and returns OpenStack volume object with an external URL
+ :param cinder: the cinder client
+ :param volume_settings: the volume settings object
+ :return: the OpenStack volume object
+ :raise Exception if using a file and it cannot be found
+ """
+ created_volume = cinder.volumes.create(
+ name=volume_settings.name, description=volume_settings.description,
+ size=volume_settings.size, imageRef=volume_settings.image_name,
+ volume_type=volume_settings.type_name,
+ availability_zone=volume_settings.availability_zone,
+ multiattach=volume_settings.multi_attach)
+
+ return Volume(
+ name=created_volume.name, volume_id=created_volume.id,
+ description=created_volume.description,
+ size=created_volume.size, vol_type=created_volume.volume_type,
+ availability_zone=created_volume.availability_zone,
+ multi_attach=created_volume.multiattach)
+
+
+def delete_volume(cinder, volume):
+ """
+ Deletes an volume from OpenStack
+ :param cinder: the cinder client
+ :param volume: the volume to delete
+ """
+ logger.info('Deleting volume named - %s', volume.name)
+ cinder.volumes.delete(volume.id)
+
+
def get_volume_type(cinder, volume_type_name=None, volume_type_settings=None):
"""
Returns an OpenStack volume type object for a given name
diff --git a/snaps/openstack/utils/tests/cinder_utils_tests.py b/snaps/openstack/utils/tests/cinder_utils_tests.py
index a45167e..6fd92e3 100644
--- a/snaps/openstack/utils/tests/cinder_utils_tests.py
+++ b/snaps/openstack/utils/tests/cinder_utils_tests.py
@@ -15,9 +15,12 @@
import logging
import uuid
+import time
from cinderclient.exceptions import NotFound, BadRequest
+from snaps.openstack import create_volume
from snaps.openstack.create_qos import QoSSettings, Consumer
+from snaps.openstack.create_volume import VolumeSettings
from snaps.openstack.create_volume_type import (
VolumeTypeSettings, VolumeTypeEncryptionSettings, ControlLocation)
from snaps.openstack.tests import validation_utils
@@ -57,6 +60,113 @@ class CinderSmokeTests(OSComponentTestCase):
cinder.volumes.list()
+class CinderUtilsVolumeTests(OSComponentTestCase):
+ """
+ Test for the CreateVolume class defined in create_volume.py
+ """
+
+ def setUp(self):
+ """
+ Instantiates the CreateVolume object that is responsible for
+ downloading and creating an OS volume file within OpenStack
+ """
+ guid = uuid.uuid4()
+ self.volume_name = self.__class__.__name__ + '-' + str(guid)
+ self.volume = None
+ self.cinder = cinder_utils.cinder_client(self.os_creds)
+
+ def tearDown(self):
+ """
+ Cleans the remote OpenStack objects
+ """
+ if self.volume:
+ try:
+ cinder_utils.delete_volume(self.cinder, self.volume)
+ except NotFound:
+ pass
+
+ self.assertTrue(volume_deleted(self.cinder, self.volume))
+
+ def test_create_simple_volume(self):
+ """
+ Tests the cinder_utils.create_volume()
+ """
+ volume_settings = VolumeSettings(name=self.volume_name)
+ self.volume = cinder_utils.create_volume(
+ self.cinder, volume_settings)
+ self.assertIsNotNone(self.volume)
+ self.assertEqual(self.volume_name, self.volume.name)
+
+ self.assertTrue(volume_active(self.cinder, self.volume))
+
+ volume = cinder_utils.get_volume(
+ self.cinder, volume_settings=volume_settings)
+ self.assertIsNotNone(volume)
+ validation_utils.objects_equivalent(self.volume, volume)
+
+ def test_create_delete_volume(self):
+ """
+ Tests the cinder_utils.create_volume()
+ """
+ volume_settings = VolumeSettings(name=self.volume_name)
+ self.volume = cinder_utils.create_volume(
+ self.cinder, volume_settings)
+ self.assertIsNotNone(self.volume)
+ self.assertEqual(self.volume_name, self.volume.name)
+
+ self.assertTrue(volume_active(self.cinder, self.volume))
+
+ volume = cinder_utils.get_volume(
+ self.cinder, volume_settings=volume_settings)
+ self.assertIsNotNone(volume)
+ validation_utils.objects_equivalent(self.volume, volume)
+
+ cinder_utils.delete_volume(self.cinder, self.volume)
+ self.assertTrue(volume_deleted(self.cinder, self.volume))
+ self.assertIsNone(
+ cinder_utils.get_volume(self.cinder, volume_settings))
+
+
+def volume_active(cinder, volume):
+ """
+ Returns true if volume becomes active
+ :param cinder:
+ :param volume:
+ :return:
+ """
+ end_time = time.time() + create_volume.VOLUME_ACTIVE_TIMEOUT
+ while time.time() < end_time:
+ status = cinder_utils.get_volume_status(cinder, volume)
+ if status == create_volume.STATUS_ACTIVE:
+ return True
+ elif status == create_volume.STATUS_FAILED:
+ return False
+ time.sleep(3)
+
+ return False
+
+
+def volume_deleted(cinder, volume):
+ """
+ Returns true if volume becomes active
+ :param cinder:
+ :param volume:
+ :return:
+ """
+ end_time = time.time() + create_volume.VOLUME_ACTIVE_TIMEOUT
+ while time.time() < end_time:
+ try:
+ status = cinder_utils.get_volume_status(cinder, volume)
+ if status == create_volume.STATUS_DELETED:
+ return True
+ except NotFound:
+ return True
+
+ time.sleep(3)
+
+ return False
+
+
class CinderUtilsQoSTests(OSComponentTestCase):
"""
Test for the CreateQos class defined in create_qos.py