Example #1
0
    def test_index_detail(self, mock_enforce):
        self._mock_enforce_setup(mock_enforce, 'index', True)
        res_name = 'WikiDatabase'
        stack_identity = identifier.HeatIdentifier(self.tenant, 'wordpress',
                                                   '1')
        res_identity = identifier.ResourceIdentifier(resource_name=res_name,
                                                     **stack_identity)

        req = self._get(stack_identity._tenant_path() + '/resources',
                        {'with_detail': 'true'})

        resp_parameters = {
            "OS::project_id": "3ab5b02fa01f4f95afa1e254afc4a435",
            "network": "cf05086d-07c7-4ed6-95e5-e4af724677e6",
            "OS::stack_name": "s1",
            "admin_pass": "******",
            "key_name": "kk",
            "image": "fa5d387e-541f-4dfb-ae8a-83a614683f84",
            "db_port": "50000",
            "OS::stack_id": "723d7cee-46b3-4433-9c21-f3378eb0bfc4",
            "flavor": "1"
        },

        engine_resp = [{
            u'resource_identity':
            dict(res_identity),
            u'stack_name':
            stack_identity.stack_name,
            u'resource_name':
            res_name,
            u'resource_status_reason':
            None,
            u'updated_time':
            u'2012-07-23T13:06:00Z',
            u'stack_identity':
            stack_identity,
            u'resource_action':
            u'CREATE',
            u'resource_status':
            u'COMPLETE',
            u'physical_resource_id':
            u'a3455d8c-9f88-404d-a85b-5315293e67de',
            u'resource_type':
            u'AWS::EC2::Instance',
            u'parameters':
            resp_parameters,
            u'description':
            u'Hello description',
            u'stack_user_project_id':
            u'6f38bcfebbc4400b82d50c1a2ea3057d',
        }]
        mock_call = self.patchobject(rpc_client.EngineClient,
                                     'call',
                                     return_value=engine_resp)

        result = self.controller.index(req,
                                       tenant_id=self.tenant,
                                       stack_name=stack_identity.stack_name,
                                       stack_id=stack_identity.stack_id)

        expected = {
            'resources': [{
                'links': [{
                    'href': self._url(res_identity),
                    'rel': 'self'
                }, {
                    'href': self._url(stack_identity),
                    'rel': 'stack'
                }],
                u'resource_name':
                res_name,
                u'logical_resource_id':
                res_name,
                u'resource_status_reason':
                None,
                u'updated_time':
                u'2012-07-23T13:06:00Z',
                u'resource_status':
                u'CREATE_COMPLETE',
                u'physical_resource_id':
                u'a3455d8c-9f88-404d-a85b-5315293e67de',
                u'resource_type':
                u'AWS::EC2::Instance',
                u'parameters':
                resp_parameters,
                u'description':
                u'Hello description',
                u'stack_user_project_id':
                u'6f38bcfebbc4400b82d50c1a2ea3057d'
            }]
        }
        self.assertEqual(expected, result)

        mock_call.assert_called_once_with(req.context,
                                          ('list_stack_resources', {
                                              'stack_identity': stack_identity,
                                              'nested_depth': 0,
                                              'with_detail': True,
                                              'filters': {}
                                          }),
                                          version='1.25')
Example #2
0
 def test_event_resource(self):
     si = identifier.HeatIdentifier('t', 's', 'i')
     pi = identifier.ResourceIdentifier(resource_name='r', **si)
     ei = identifier.EventIdentifier(event_id='e', **pi)
     self.assertEqual(pi, ei.resource())
Example #3
0
 def test_arn(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertEqual('arn:openstack:heat::t:stacks/s/i/p', hi.arn())
Example #4
0
 def test_resource_stack(self):
     si = identifier.HeatIdentifier('t', 's', 'i')
     ri = identifier.ResourceIdentifier(resource_name='r', **si)
     self.assertEqual(si, ri.stack())
Example #5
0
 def _test_event_init(self, event_id):
     si = identifier.HeatIdentifier('t', 's', 'i')
     pi = identifier.ResourceIdentifier(resource_name='p', **si)
     ei = identifier.EventIdentifier(event_id=event_id, **pi)
     self.assertEqual('/resources/p/events/{0}'.format(event_id), ei.path)
Example #6
0
 def test_not_equal(self):
     hi1 = identifier.HeatIdentifier('t', 's', 'i', 'p')
     hi2 = identifier.HeatIdentifier('t', 's', 'i', 'q')
     self.assertFalse(hi1 == hi2)
     self.assertFalse(hi2 == hi1)
Example #7
0
 def test_resource_init_path(self):
     si = identifier.HeatIdentifier('t', 's', 'i')
     pi = identifier.ResourceIdentifier(resource_name='p', **si)
     ri = identifier.ResourceIdentifier(resource_name='r', **pi)
     self.assertEqual('/resources/p/resources/r', ri.path)
Example #8
0
 def test_attrs(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertEqual('t', hi.tenant)
     self.assertEqual('s', hi.stack_name)
     self.assertEqual('i', hi.stack_id)
     self.assertEqual('/p', hi.path)
Example #9
0
 def test_url_path_default(self):
     hi = identifier.HeatIdentifier('t', 's', 'i')
     self.assertEqual('t/stacks/s/i', hi.url_path())
Example #10
0
    def create_or_update(self, req, action=None):
        """
        Implements CreateStack and UpdateStack API actions.
        Create or update stack as defined in template file.
        """
        def extract_args(params):
            """
            Extract request parameters/arguments and reformat them to match
            the engine API.  FIXME: we currently only support a subset of
            the AWS defined parameters (both here and in the engine)
            """
            # TODO(shardy) : Capabilities, NotificationARNs
            keymap = {
                'TimeoutInMinutes': engine_api.PARAM_TIMEOUT,
                'DisableRollback': engine_api.PARAM_DISABLE_ROLLBACK
            }

            if 'DisableRollback' in params and 'OnFailure' in params:
                msg = _('DisableRollback and OnFailure '
                        'may not be used together')
                raise exception.HeatInvalidParameterCombinationError(
                    detail=msg)

            result = {}
            for k in keymap:
                if k in params:
                    result[keymap[k]] = params[k]

            if 'OnFailure' in params:
                value = params['OnFailure']
                if value == 'DO_NOTHING':
                    result[engine_api.PARAM_DISABLE_ROLLBACK] = 'true'
                elif value in ('ROLLBACK', 'DELETE'):
                    result[engine_api.PARAM_DISABLE_ROLLBACK] = 'false'

            return result

        if action not in self.CREATE_OR_UPDATE_ACTION:
            msg = _("Unexpected action %(action)s") % ({'action': action})
            # This should not happen, so return HeatInternalFailureError
            return exception.HeatInternalFailureError(detail=msg)

        engine_action = {
            self.CREATE_STACK: self.rpc_client.create_stack,
            self.UPDATE_STACK: self.rpc_client.update_stack
        }

        con = req.context

        # Extract the stack input parameters
        stack_parms = self._extract_user_params(req.params)

        # Extract any additional arguments ("Request Parameters")
        create_args = extract_args(req.params)

        try:
            templ = self._get_template(req)
        except socket.gaierror:
            msg = _('Invalid Template URL')
            return exception.HeatInvalidParameterValueError(detail=msg)

        if templ is None:
            msg = _("TemplateBody or TemplateUrl were not given.")
            return exception.HeatMissingParameterError(detail=msg)

        try:
            stack = template_format.parse(templ)
        except ValueError:
            msg = _("The Template must be a JSON or YAML document.")
            return exception.HeatInvalidParameterValueError(detail=msg)

        args = {
            'template': stack,
            'params': stack_parms,
            'files': {},
            'args': create_args
        }
        try:
            stack_name = req.params['StackName']
            if action == self.CREATE_STACK:
                args['stack_name'] = stack_name
            else:
                args['stack_identity'] = self._get_identity(con, stack_name)

            result = engine_action[action](con, **args)
        except Exception as ex:
            return exception.map_remote_error(ex)

        try:
            identity = identifier.HeatIdentifier(**result)
        except (ValueError, TypeError):
            response = result
        else:
            response = {'StackId': identity.arn()}

        return api_utils.format_response(action, response)
Example #11
0
 def setUp(self):
     super(EngineRpcAPITestCase, self).setUp()
     self.stubs = stubout.StubOutForTesting()
     self.identity = dict(
         identifier.HeatIdentifier('engine_test_tenant', '6', 'wordpress'))
     self.rpcapi = rpc_client.EngineClient()
Example #12
0
 def identifier(self):
     '''
     Return an identifier for this stack.
     '''
     return identifier.HeatIdentifier(self.tenant_id, self.name, self.id)
Example #13
0
    def test_index(self, mock_enforce):
        self._mock_enforce_setup(mock_enforce, 'index', True)
        res_name = 'WikiDatabase'
        stack_identity = identifier.HeatIdentifier(self.tenant, 'wordpress',
                                                   '1')
        res_identity = identifier.ResourceIdentifier(resource_name=res_name,
                                                     **stack_identity)

        req = self._get(stack_identity._tenant_path() + '/resources')

        engine_resp = [{
            u'resource_identity': dict(res_identity),
            u'stack_name': stack_identity.stack_name,
            u'resource_name': res_name,
            u'resource_status_reason': None,
            u'updated_time': u'2012-07-23T13:06:00Z',
            u'stack_identity': stack_identity,
            u'resource_action': u'CREATE',
            u'resource_status': u'COMPLETE',
            u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de',
            u'resource_type': u'AWS::EC2::Instance',
        }]
        mock_call = self.patchobject(rpc_client.EngineClient,
                                     'call',
                                     return_value=engine_resp)

        result = self.controller.index(req,
                                       tenant_id=self.tenant,
                                       stack_name=stack_identity.stack_name,
                                       stack_id=stack_identity.stack_id)

        expected = {
            'resources': [{
                'links': [{
                    'href': self._url(res_identity),
                    'rel': 'self'
                }, {
                    'href': self._url(stack_identity),
                    'rel': 'stack'
                }],
                u'resource_name':
                res_name,
                u'logical_resource_id':
                res_name,
                u'resource_status_reason':
                None,
                u'updated_time':
                u'2012-07-23T13:06:00Z',
                u'resource_status':
                u'CREATE_COMPLETE',
                u'physical_resource_id':
                u'a3455d8c-9f88-404d-a85b-5315293e67de',
                u'resource_type':
                u'AWS::EC2::Instance'
            }]
        }
        self.assertEqual(expected, result)

        mock_call.assert_called_once_with(req.context,
                                          ('list_stack_resources', {
                                              'stack_identity': stack_identity,
                                              'nested_depth': 0,
                                              'with_detail': False,
                                              'filters': {}
                                          }),
                                          version='1.25')
Example #14
0
    def test_show_with_nested_stack(self, mock_enforce):
        self._mock_enforce_setup(mock_enforce, 'show', True)
        res_name = 'WikiDatabase'
        stack_identity = identifier.HeatIdentifier(self.tenant, 'wordpress',
                                                   '6')
        res_identity = identifier.ResourceIdentifier(resource_name=res_name,
                                                     **stack_identity)
        nested_stack_identity = identifier.HeatIdentifier(
            self.tenant, 'nested', 'some_id')

        req = self._get(stack_identity._tenant_path())

        engine_resp = {
            u'description': u'',
            u'resource_identity': dict(res_identity),
            u'stack_name': stack_identity.stack_name,
            u'resource_name': res_name,
            u'resource_status_reason': None,
            u'updated_time': u'2012-07-23T13:06:00Z',
            u'stack_identity': dict(stack_identity),
            u'resource_action': u'CREATE',
            u'resource_status': u'COMPLETE',
            u'physical_resource_id': u'a3455d8c-9f88-404d-a85b-5315293e67de',
            u'resource_type': u'AWS::EC2::Instance',
            u'attributes': {
                u'foo': 'bar'
            },
            u'metadata': {
                u'ensureRunning': u'true'
            },
            u'nested_stack_id': dict(nested_stack_identity)
        }
        mock_call = self.patchobject(rpc_client.EngineClient,
                                     'call',
                                     return_value=engine_resp)

        result = self.controller.show(req,
                                      tenant_id=self.tenant,
                                      stack_name=stack_identity.stack_name,
                                      stack_id=stack_identity.stack_id,
                                      resource_name=res_name)

        expected = [{
            'href': self._url(res_identity),
            'rel': 'self'
        }, {
            'href': self._url(stack_identity),
            'rel': 'stack'
        }, {
            'href': self._url(nested_stack_identity),
            'rel': 'nested'
        }]
        self.assertEqual(expected, result['resource']['links'])
        self.assertIsNone(result.get(rpc_api.RES_NESTED_STACK_ID))

        mock_call.assert_called_once_with(req.context,
                                          ('describe_stack_resource', {
                                              'stack_identity': stack_identity,
                                              'resource_name': res_name,
                                              'with_attr': None
                                          }),
                                          version='1.2')
Example #15
0
 def test_items(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertEqual('t', hi['tenant'])
     self.assertEqual('s', hi['stack_name'])
     self.assertEqual('i', hi['stack_id'])
     self.assertEqual('/p', hi['path'])
Example #16
0
 def test_url_path_with_unicode_path(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', u'\u5de5')
     self.assertEqual('t/stacks/s/i/%E5%B7%A5', hi.url_path())
Example #17
0
 def test_equal_dict(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertTrue(hi == dict(hi))
     self.assertTrue(dict(hi) == hi)
Example #18
0
 def test_tenant_escape(self):
     hi = identifier.HeatIdentifier(':/', 's', 'i')
     self.assertEqual(':/', hi.tenant)
     self.assertEqual('%3A%2F/stacks/s/i', hi.url_path())
     self.assertEqual('arn:openstack:heat::%3A%2F:stacks/s/i', hi.arn())
Example #19
0
 def test_path_components(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p1/p2/p3')
     self.assertEqual(['p1', 'p2', 'p3'], hi._path_components())
Example #20
0
 def test_name_escape(self):
     hi = identifier.HeatIdentifier('t', ':%', 'i')
     self.assertEqual(':%', hi.stack_name)
     self.assertEqual('t/stacks/%3A%25/i', hi.url_path())
     self.assertEqual('arn:openstack:heat::t:stacks/%3A%25/i', hi.arn())
Example #21
0
 def test_resource_init_from_dict(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', '/resources/r')
     ri = identifier.ResourceIdentifier(**hi)
     self.assertEqual(hi, ri)
Example #22
0
 def test_id_escape(self):
     hi = identifier.HeatIdentifier('t', 's', ':/')
     self.assertEqual(':/', hi.stack_id)
     self.assertEqual('t/stacks/s/%3A%2F', hi.url_path())
     self.assertEqual('arn:openstack:heat::t:stacks/s/%3A%2F', hi.arn())
Example #23
0
 def test_invalid_attr(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     hi.identity['foo'] = 'bar'
     self.assertRaises(AttributeError, getattr, hi, 'foo')
Example #24
0
 def test_path_escape(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', ':/')
     self.assertEqual('/:/', hi.path)
     self.assertEqual('t/stacks/s/i/%3A/', hi.url_path())
     self.assertEqual('arn:openstack:heat::t:stacks/s/i/%3A/', hi.arn())
Example #25
0
 def test_event_init_from_dict(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', '/resources/p/events/42')
     ei = identifier.EventIdentifier(**hi)
     self.assertEqual(hi, ei)
Example #26
0
 def test_path_default(self):
     hi = identifier.HeatIdentifier('t', 's', 'i')
     self.assertEqual('', hi.path)
Example #27
0
 def test_invalid_item(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     hi.identity['foo'] = 'bar'
     self.assertRaises(KeyError, lambda o, k: o[k], hi, 'foo')
Example #28
0
 def test_equal(self):
     hi1 = identifier.HeatIdentifier('t', 's', 'i', 'p')
     hi2 = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertTrue(hi1 == hi2)
Example #29
0
 def test_arn_url(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertEqual('/arn%3Aopenstack%3Aheat%3A%3At%3Astacks%2Fs%2Fi%2Fp',
                      hi.arn_url_path())
Example #30
0
    def _test_resource_index(self, event_id, mock_enforce):
        self._mock_enforce_setup(mock_enforce, 'index', True)
        res_name = 'WikiDatabase'
        stack_identity = identifier.HeatIdentifier(self.tenant, 'wordpress',
                                                   '6')
        res_identity = identifier.ResourceIdentifier(resource_name=res_name,
                                                     **stack_identity)
        ev_identity = identifier.EventIdentifier(event_id=event_id,
                                                 **res_identity)

        req = self._get(stack_identity._tenant_path() + '/resources/' +
                        res_name + '/events')

        kwargs = {
            'stack_identity': stack_identity,
            'limit': None,
            'sort_keys': None,
            'marker': None,
            'sort_dir': None,
            'filters': {
                'resource_name': res_name
            }
        }

        engine_resp = [{
            u'stack_name': u'wordpress',
            u'event_time': u'2012-07-23T13:05:39Z',
            u'stack_identity': dict(stack_identity),
            u'resource_name': res_name,
            u'resource_status_reason': u'state changed',
            u'event_identity': dict(ev_identity),
            u'resource_action': u'CREATE',
            u'resource_status': u'IN_PROGRESS',
            u'physical_resource_id': None,
            u'resource_properties': {
                u'UserData': u'blah'
            },
            u'resource_type': u'AWS::EC2::Instance',
        }]
        self.m.StubOutWithMock(rpc_client.EngineClient, 'call')
        rpc_client.EngineClient.call(
            req.context, ('list_events', kwargs)).AndReturn(engine_resp)
        self.m.ReplayAll()

        result = self.controller.index(req,
                                       tenant_id=self.tenant,
                                       stack_name=stack_identity.stack_name,
                                       stack_id=stack_identity.stack_id,
                                       resource_name=res_name)

        expected = {
            'events': [{
                'id':
                event_id,
                'links': [
                    {
                        'href': self._url(ev_identity),
                        'rel': 'self'
                    },
                    {
                        'href': self._url(res_identity),
                        'rel': 'resource'
                    },
                    {
                        'href': self._url(stack_identity),
                        'rel': 'stack'
                    },
                ],
                u'resource_name':
                res_name,
                u'logical_resource_id':
                res_name,
                u'resource_status_reason':
                u'state changed',
                u'event_time':
                u'2012-07-23T13:05:39Z',
                u'resource_status':
                u'CREATE_IN_PROGRESS',
                u'physical_resource_id':
                None,
            }]
        }

        self.assertEqual(expected, result)
        self.m.VerifyAll()