summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Pisarski <s.pisarski@cablelabs.com>2017-06-21 13:35:56 +0000
committerGerrit Code Review <gerrit@opnfv.org>2017-06-21 13:35:56 +0000
commit49402e392615f0326b37c772ed91671bd880f92d (patch)
treedeadd0c9699f684a3436d60c327a87e18eb00c22
parent2e0e2c683e2329084f3e7eea6ed5d9ab5ed56661 (diff)
parent515ffadaecae3f51cc50f0263226fa526aad303d (diff)
Merge "Changes StackSettings constructor to use kwargs."
-rw-r--r--snaps/openstack/create_stack.py119
-rw-r--r--snaps/openstack/tests/create_stack_tests.py132
2 files changed, 150 insertions, 101 deletions
diff --git a/snaps/openstack/create_stack.py b/snaps/openstack/create_stack.py
index 8dc5027..1492829 100644
--- a/snaps/openstack/create_stack.py
+++ b/snaps/openstack/create_stack.py
@@ -17,7 +17,6 @@ import logging
import time
from heatclient.exc import HTTPNotFound
-
from snaps.openstack.utils import heat_utils
__author__ = 'spisarski'
@@ -49,23 +48,31 @@ class OpenStackHeatStack:
def create(self, cleanup=False):
"""
- Creates the heat stack in OpenStack if it does not already exist and returns the domain Stack object
- :param cleanup: Denotes whether or not this is being called for cleanup or not
+ Creates the heat stack in OpenStack if it does not already exist and
+ returns the domain Stack object
+ :param cleanup: Denotes whether or not this is being called for cleanup
:return: The OpenStack Stack object
"""
self.__heat_cli = heat_utils.heat_client(self.__os_creds)
- self.__stack = heat_utils.get_stack_by_name(self.__heat_cli, self.stack_settings.name)
+ self.__stack = heat_utils.get_stack_by_name(self.__heat_cli,
+ self.stack_settings.name)
if self.__stack:
logger.info('Found stack with name - ' + self.stack_settings.name)
return self.__stack
elif not cleanup:
- self.__stack = heat_utils.create_stack(self.__heat_cli, self.stack_settings)
- logger.info('Created stack with name - ' + self.stack_settings.name)
+ self.__stack = heat_utils.create_stack(self.__heat_cli,
+ self.stack_settings)
+ logger.info(
+ 'Created stack with name - ' + self.stack_settings.name)
if self.__stack and self.stack_complete(block=True):
- logger.info('Stack is now active with name - ' + self.stack_settings.name)
+ logger.info(
+ 'Stack is now active with name - ' +
+ self.stack_settings.name)
return self.__stack
else:
- raise StackCreationError('Stack was not created or activated in the alloted amount of time')
+ raise StackCreationError(
+ 'Stack was not created or activated in the alloted amount '
+ 'of time')
else:
logger.info('Did not create stack due to cleanup mode')
@@ -86,42 +93,53 @@ class OpenStackHeatStack:
def get_stack(self):
"""
- Returns the domain Stack object as it was populated when create() was called
+ Returns the domain Stack object as it was populated when create() was
+ called
:return: the object
"""
return self.__stack
def get_outputs(self):
"""
- Returns the list of outputs as contained on the OpenStack Heat Stack object
+ Returns the list of outputs as contained on the OpenStack Heat Stack
+ object
:return:
"""
return heat_utils.get_stack_outputs(self.__heat_cli, self.__stack.id)
def get_status(self):
"""
- Returns the list of outputs as contained on the OpenStack Heat Stack object
+ Returns the list of outputs as contained on the OpenStack Heat Stack
+ object
:return:
"""
return heat_utils.get_stack_status(self.__heat_cli, self.__stack.id)
- def stack_complete(self, block=False, timeout=None, poll_interval=POLL_INTERVAL):
+ def stack_complete(self, block=False, timeout=None,
+ poll_interval=POLL_INTERVAL):
"""
- Returns true when the stack status returns the value of expected_status_code
- :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False)
+ Returns true when the stack status returns the value of
+ expected_status_code
+ :param block: When true, thread will block until active or timeout
+ value in seconds has been exceeded (False)
:param timeout: The timeout value
:param poll_interval: The polling interval in seconds
:return: T/F
"""
if not timeout:
timeout = self.stack_settings.stack_create_timeout
- return self._stack_status_check(STATUS_CREATE_COMPLETE, block, timeout, poll_interval)
-
- def _stack_status_check(self, expected_status_code, block, timeout, poll_interval):
- """
- Returns true when the stack status returns the value of expected_status_code
- :param expected_status_code: stack status evaluated with this string value
- :param block: When true, thread will block until active or timeout value in seconds has been exceeded (False)
+ return self._stack_status_check(STATUS_CREATE_COMPLETE, block, timeout,
+ poll_interval)
+
+ def _stack_status_check(self, expected_status_code, block, timeout,
+ poll_interval):
+ """
+ Returns true when the stack status returns the value of
+ expected_status_code
+ :param expected_status_code: stack status evaluated with this string
+ value
+ :param block: When true, thread will block until active or timeout
+ value in seconds has been exceeded (False)
:param timeout: The timeout value
:param poll_interval: The polling interval in seconds
:return: T/F
@@ -135,25 +153,31 @@ class OpenStackHeatStack:
while timeout > time.time() - start:
status = self._status(expected_status_code)
if status:
- logger.debug('Stack is active with name - ' + self.stack_settings.name)
+ logger.debug(
+ 'Stack is active with name - ' + self.stack_settings.name)
return True
- logger.debug('Retry querying stack status in ' + str(poll_interval) + ' seconds')
+ logger.debug('Retry querying stack status in ' + str(
+ poll_interval) + ' seconds')
time.sleep(poll_interval)
- logger.debug('Stack status query timeout in ' + str(timeout - (time.time() - start)))
+ logger.debug('Stack status query timeout in ' + str(
+ timeout - (time.time() - start)))
- logger.error('Timeout checking for stack status for ' + expected_status_code)
+ logger.error(
+ 'Timeout checking for stack status for ' + expected_status_code)
return False
def _status(self, expected_status_code):
"""
Returns True when active else False
- :param expected_status_code: stack status evaluated with this string value
+ :param expected_status_code: stack status evaluated with this string
+ value
:return: T/F
"""
status = self.get_status()
if not status:
- logger.warning('Cannot stack status for stack with ID - ' + self.__stack.id)
+ logger.warning(
+ 'Cannot stack status for stack with ID - ' + self.__stack.id)
return False
if status == 'ERROR':
@@ -163,33 +187,26 @@ class OpenStackHeatStack:
class StackSettings:
- def __init__(self, config=None, name=None, template=None, template_path=None, env_values=None,
- stack_create_timeout=STACK_COMPLETE_TIMEOUT):
+ def __init__(self, **kwargs):
"""
Constructor
- :param config: dict() object containing the configuration settings using the attribute names below as each
- member's the key and overrides any of the other parameters.
:param name: the stack's name (required)
- :param template: the heat template in dict() format (required if template_path attribute is None)
- :param template_path: the location of the heat template file (required if template attribute is None)
- :param env_values: k/v pairs of strings for substitution of template default values (optional)
- """
-
- if config:
- self.name = config.get('name')
- self.template = config.get('template')
- self.template_path = config.get('template_path')
- self.env_values = config.get('env_values')
- if 'stack_create_timeout' in config:
- self.stack_create_timeout = config['stack_create_timeout']
- else:
- self.stack_create_timeout = stack_create_timeout
+ :param template: the heat template in dict() format (required if
+ template_path attribute is None)
+ :param template_path: the location of the heat template file (required
+ if template attribute is None)
+ :param env_values: k/v pairs of strings for substitution of template
+ default values (optional)
+ """
+
+ self.name = kwargs.get('name')
+ self.template = kwargs.get('template')
+ self.template_path = kwargs.get('template_path')
+ self.env_values = kwargs.get('env_values')
+ if 'stack_create_timeout' in kwargs:
+ self.stack_create_timeout = kwargs['stack_create_timeout']
else:
- self.name = name
- self.template = template
- self.template_path = template_path
- self.env_values = env_values
- self.stack_create_timeout = stack_create_timeout
+ self.stack_create_timeout = STACK_COMPLETE_TIMEOUT
if not self.name:
raise StackSettingsError('name is required')
@@ -202,6 +219,7 @@ class StackSettingsError(Exception):
"""
Exception to be thrown when an stack settings are incorrect
"""
+
def __init__(self, message):
Exception.__init__(self, message)
@@ -210,5 +228,6 @@ class StackCreationError(Exception):
"""
Exception to be thrown when an stack cannot be created
"""
+
def __init__(self, message):
Exception.__init__(self, message)
diff --git a/snaps/openstack/tests/create_stack_tests.py b/snaps/openstack/tests/create_stack_tests.py
index e665f82..626fc97 100644
--- a/snaps/openstack/tests/create_stack_tests.py
+++ b/snaps/openstack/tests/create_stack_tests.py
@@ -12,14 +12,12 @@
# 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 pkg_resources
import time
+import pkg_resources
from heatclient.exc import HTTPBadRequest
from snaps import file_utils
-
from snaps.openstack.create_flavor import OpenStackFlavor, FlavorSettings
-
from snaps.openstack.create_image import OpenStackImage
try:
@@ -46,13 +44,14 @@ class StackSettingsUnitTests(unittest.TestCase):
"""
Tests the construction of the StackSettings class
"""
+
def test_no_params(self):
with self.assertRaises(StackSettingsError):
StackSettings()
def test_empty_config(self):
with self.assertRaises(StackSettingsError):
- StackSettings(config=dict())
+ StackSettings(**dict())
def test_name_only(self):
with self.assertRaises(StackSettingsError):
@@ -60,23 +59,25 @@ class StackSettingsUnitTests(unittest.TestCase):
def test_config_with_name_only(self):
with self.assertRaises(StackSettingsError):
- StackSettings(config={'name': 'foo'})
+ StackSettings(**{'name': 'foo'})
def test_config_minimum_template(self):
- settings = StackSettings(config={'name': 'stack', 'template': 'foo'})
+ settings = StackSettings(**{'name': 'stack', 'template': 'foo'})
self.assertEqual('stack', settings.name)
self.assertEqual('foo', settings.template)
self.assertIsNone(settings.template_path)
self.assertIsNone(settings.env_values)
- self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout)
+ self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
+ settings.stack_create_timeout)
def test_config_minimum_template_path(self):
- settings = StackSettings(config={'name': 'stack', 'template_path': 'foo'})
+ settings = StackSettings(**{'name': 'stack', 'template_path': 'foo'})
self.assertEqual('stack', settings.name)
self.assertIsNone(settings.template)
self.assertEqual('foo', settings.template_path)
self.assertIsNone(settings.env_values)
- self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout)
+ self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
+ settings.stack_create_timeout)
def test_minimum_template(self):
settings = StackSettings(name='stack', template='foo')
@@ -84,7 +85,8 @@ class StackSettingsUnitTests(unittest.TestCase):
self.assertEqual('foo', settings.template)
self.assertIsNone(settings.template_path)
self.assertIsNone(settings.env_values)
- self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout)
+ self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
+ settings.stack_create_timeout)
def test_minimum_template_path(self):
settings = StackSettings(name='stack', template_path='foo')
@@ -92,11 +94,13 @@ class StackSettingsUnitTests(unittest.TestCase):
self.assertEqual('foo', settings.template_path)
self.assertIsNone(settings.template)
self.assertIsNone(settings.env_values)
- self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT, settings.stack_create_timeout)
+ self.assertEqual(create_stack.STACK_COMPLETE_TIMEOUT,
+ settings.stack_create_timeout)
def test_all(self):
env_values = {'foo': 'bar'}
- settings = StackSettings(name='stack', template='bar', template_path='foo', env_values=env_values,
+ settings = StackSettings(name='stack', template='bar',
+ template_path='foo', env_values=env_values,
stack_create_timeout=999)
self.assertEqual('stack', settings.name)
self.assertEqual('bar', settings.template)
@@ -107,8 +111,8 @@ class StackSettingsUnitTests(unittest.TestCase):
def test_config_all(self):
env_values = {'foo': 'bar'}
settings = StackSettings(
- config={'name': 'stack', 'template': 'bar', 'template_path': 'foo',
- 'env_values': env_values, 'stack_create_timeout': 999})
+ **{'name': 'stack', 'template': 'bar', 'template_path': 'foo',
+ 'env_values': env_values, 'stack_create_timeout': 999})
self.assertEqual('stack', settings.name)
self.assertEqual('bar', settings.template)
self.assertEqual('foo', settings.template_path)
@@ -123,8 +127,8 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
def setUp(self):
"""
- Instantiates the CreateStack object that is responsible for downloading and creating an OS stack file
- within OpenStack
+ Instantiates the CreateStack object that is responsible for downloading
+ and creating an OS stack file within OpenStack
"""
super(self.__class__, self).__start__()
@@ -134,17 +138,20 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.image_creator = OpenStackImage(
self.os_creds, openstack_tests.cirros_image_settings(
- name=self.__class__.__name__ + '-' + str(self.guid) + '-image', image_metadata=self.image_metadata))
+ name=self.__class__.__name__ + '-' + str(self.guid) + '-image',
+ image_metadata=self.image_metadata))
self.image_creator.create()
# Create Flavor
self.flavor_creator = OpenStackFlavor(
self.admin_os_creds,
- FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10, vcpus=1))
+ FlavorSettings(name=self.guid + '-flavor-name', ram=128, disk=10,
+ vcpus=1))
self.flavor_creator.create()
- self.env_values = {'image_name': self.image_creator.image_settings.name,
- 'flavor_name': self.flavor_creator.flavor_settings.name}
+ self.env_values = {
+ 'image_name': self.image_creator.image_settings.name,
+ 'flavor_name': self.flavor_creator.flavor_settings.name}
self.heat_tmplt_path = pkg_resources.resource_filename(
'snaps.openstack.tests.heat', 'test_heat_template.yaml')
@@ -178,15 +185,19 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
Tests the creation of an OpenStack stack from Heat template file.
"""
# Create Stack
- # Set the default stack settings, then set any custom parameters sent from the app
- stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
- template_path=self.heat_tmplt_path,
- env_values=self.env_values)
- self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings)
+ # Set the default stack settings, then set any custom parameters sent
+ # from the app
+ stack_settings = StackSettings(
+ name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
+ template_path=self.heat_tmplt_path,
+ env_values=self.env_values)
+ self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds,
+ stack_settings)
created_stack = self.stack_creator.create()
self.assertIsNotNone(created_stack)
- retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack.id)
+ retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
+ created_stack.id)
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack.name, retrieved_stack.name)
self.assertEqual(created_stack.id, retrieved_stack.id)
@@ -198,17 +209,21 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
Tests the creation of an OpenStack stack from a heat dict() object.
"""
# Create Stack
- # Set the default stack settings, then set any custom parameters sent from the app
+ # Set the default stack settings, then set any custom parameters sent
+ # from the app
template_dict = heat_utils.parse_heat_template_str(
file_utils.read_file(self.heat_tmplt_path))
- stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
- template=template_dict,
- env_values=self.env_values)
- self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings)
+ stack_settings = StackSettings(
+ name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
+ template=template_dict,
+ env_values=self.env_values)
+ self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds,
+ stack_settings)
created_stack = self.stack_creator.create()
self.assertIsNotNone(created_stack)
- retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack.id)
+ retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
+ created_stack.id)
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack.name, retrieved_stack.name)
self.assertEqual(created_stack.id, retrieved_stack.id)
@@ -217,25 +232,30 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
def test_create_delete_stack(self):
"""
- Tests the creation then deletion of an OpenStack stack to ensure clean() does not raise an Exception.
+ Tests the creation then deletion of an OpenStack stack to ensure
+ clean() does not raise an Exception.
"""
# Create Stack
template_dict = heat_utils.parse_heat_template_str(
file_utils.read_file(self.heat_tmplt_path))
- stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
- template=template_dict,
- env_values=self.env_values)
- self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings)
+ stack_settings = StackSettings(
+ name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
+ template=template_dict,
+ env_values=self.env_values)
+ self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds,
+ stack_settings)
created_stack = self.stack_creator.create()
self.assertIsNotNone(created_stack)
- retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack.id)
+ retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
+ created_stack.id)
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack.name, retrieved_stack.name)
self.assertEqual(created_stack.id, retrieved_stack.id)
self.assertIsNotNone(self.stack_creator.get_outputs())
self.assertEquals(0, len(self.stack_creator.get_outputs()))
- self.assertEqual(create_stack.STATUS_CREATE_COMPLETE, self.stack_creator.get_status())
+ self.assertEqual(create_stack.STATUS_CREATE_COMPLETE,
+ self.stack_creator.get_status())
# Delete Stack manually
heat_utils.delete_stack(self.heat_cli, created_stack)
@@ -243,14 +263,16 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
end_time = time.time() + 90
deleted = False
while time.time() < end_time:
- status = heat_utils.get_stack_status(self.heat_cli, retrieved_stack.id)
+ status = heat_utils.get_stack_status(self.heat_cli,
+ retrieved_stack.id)
if status == create_stack.STATUS_DELETE_COMPLETE:
deleted = True
break
self.assertTrue(deleted)
- # Must not throw an exception when attempting to cleanup non-existent stack
+ # Must not throw an exception when attempting to cleanup non-existent
+ # stack
self.stack_creator.clean()
self.assertIsNone(self.stack_creator.get_stack())
@@ -261,13 +283,16 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
# Create Stack
template_dict = heat_utils.parse_heat_template_str(
file_utils.read_file(self.heat_tmplt_path))
- stack_settings = StackSettings(name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
- template=template_dict,
- env_values=self.env_values)
- self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings)
+ stack_settings = StackSettings(
+ name=self.__class__.__name__ + '-' + str(self.guid) + '-stack',
+ template=template_dict,
+ env_values=self.env_values)
+ self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds,
+ stack_settings)
created_stack1 = self.stack_creator.create()
- retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli, created_stack1.id)
+ retrieved_stack = heat_utils.get_stack_by_id(self.heat_cli,
+ created_stack1.id)
self.assertIsNotNone(retrieved_stack)
self.assertEqual(created_stack1.name, retrieved_stack.name)
self.assertEqual(created_stack1.id, retrieved_stack.id)
@@ -275,7 +300,8 @@ class CreateStackSuccessTests(OSIntegrationTestCase):
self.assertEqual(0, len(self.stack_creator.get_outputs()))
# Should be retrieving the instance data
- stack_creator2 = create_stack.OpenStackHeatStack(self.os_creds, stack_settings)
+ stack_creator2 = create_stack.OpenStackHeatStack(self.os_creds,
+ stack_settings)
stack2 = stack_creator2.create()
self.assertEqual(created_stack1.id, stack2.id)
@@ -302,8 +328,10 @@ class CreateStackNegativeTests(OSIntegrationTestCase):
"""
Expect an StackCreationError when the stack file does not exist
"""
- stack_settings = StackSettings(name=self.stack_name, template_path=self.heat_tmplt_path)
- self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings)
+ stack_settings = StackSettings(name=self.stack_name,
+ template_path=self.heat_tmplt_path)
+ self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds,
+ stack_settings)
with self.assertRaises(HTTPBadRequest):
self.stack_creator.create()
@@ -311,7 +339,9 @@ class CreateStackNegativeTests(OSIntegrationTestCase):
"""
Expect an StackCreationError when the stack file does not exist
"""
- stack_settings = StackSettings(name=self.stack_name, template_path='foo')
- self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds, stack_settings)
+ stack_settings = StackSettings(name=self.stack_name,
+ template_path='foo')
+ self.stack_creator = create_stack.OpenStackHeatStack(self.os_creds,
+ stack_settings)
with self.assertRaises(IOError):
self.stack_creator.create()