From 515ffadaecae3f51cc50f0263226fa526aad303d Mon Sep 17 00:00:00 2001 From: spisarski Date: Tue, 20 Jun 2017 13:07:49 -0600 Subject: Changes StackSettings constructor to use kwargs. And changed line lengths to 79 for pep8. JIRA: SNAPS-103 Change-Id: Iacc3a42cbf3bebe7336d17fc4a4574590f15b93a Signed-off-by: spisarski --- snaps/openstack/create_stack.py | 119 ++++++++++++++----------- snaps/openstack/tests/create_stack_tests.py | 132 +++++++++++++++++----------- 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() -- cgit 1.2.3-korg