Beispiel #1
0
 def test_dict_round_trip(self):
     hii = identifier.HeatIdentifier('t', 's', 'i', 'p')
     hio = identifier.HeatIdentifier(**dict(hii))
     self.assertEqual(hio.tenant, hii.tenant)
     self.assertEqual(hio.stack_name, hii.stack_name)
     self.assertEqual(hio.stack_id, hii.stack_id)
     self.assertEqual(hio.path, hii.path)
Beispiel #2
0
 def test_not_equal_dict(self):
     hi1 = identifier.HeatIdentifier('t', 's', 'i', 'p')
     hi2 = identifier.HeatIdentifier('t', 's', 'i', 'q')
     self.assertFalse(hi1 == dict(hi2))
     self.assertFalse(dict(hi1) == hi2)
     self.assertFalse(hi1 == {
         'tenant': 't',
         'stack_name': 's',
         'stack_id': 'i'
     })
     self.assertFalse({
         'tenant': 't',
         'stack_name': 's',
         'stack_id': 'i'
     } == hi1)
Beispiel #3
0
 def test_arn_escape_decode_round_trip(self):
     hii = identifier.HeatIdentifier(':/', ':/', ':/', ':/')
     hio = identifier.HeatIdentifier.from_arn(hii.arn())
     self.assertEqual(hio.tenant, hii.tenant)
     self.assertEqual(hio.stack_name, hii.stack_name)
     self.assertEqual(hio.stack_id, hii.stack_id)
     self.assertEqual(hio.path, hii.path)
Beispiel #4
0
    def test_lookup(self):
        identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1')

        req = self._get('/stacks/%(stack_name)s' % identity)

        self.m.StubOutWithMock(rpc, 'call')
        rpc.call(
            req.context, self.topic, {
                'method': 'identify_stack',
                'args': {
                    'stack_name': identity.stack_name
                },
                'version': self.api_version
            }, None).AndReturn(identity)

        self.m.ReplayAll()

        try:
            result = self.controller.lookup(req,
                                            tenant_id=identity.tenant,
                                            stack_name=identity.stack_name)
        except webob.exc.HTTPFound as found:
            self.assertEqual(found.location, self._url(identity))
        else:
            self.fail('No redirect generated')
        self.m.VerifyAll()
Beispiel #5
0
    def test_delete_bad_name(self):
        identity = identifier.HeatIdentifier(self.tenant, 'wibble', '6')
        template = {u'Foo': u'bar'}
        json_template = json.dumps(template)
        parameters = {u'InstanceType': u'm1.xlarge'}
        body = {
            'template': template,
            'parameters': parameters,
            'timeout_mins': 30
        }

        req = self._delete('/stacks/%(stack_name)s/%(stack_id)s' % identity)

        self.m.StubOutWithMock(rpc, 'call')
        # Engine returns None when delete successful
        rpc.call(
            req.context, self.topic, {
                'method': 'delete_stack',
                'args': {
                    'stack_identity': dict(identity)
                },
                'version': self.api_version
            }, None).AndRaise(rpc_common.RemoteError("AttributeError"))
        self.m.ReplayAll()

        self.assertRaises(webob.exc.HTTPNotFound,
                          self.controller.delete,
                          req,
                          tenant_id=identity.tenant,
                          stack_name=identity.stack_name,
                          stack_id=identity.stack_id)
        self.m.VerifyAll()
Beispiel #6
0
def stack_url(req, identity):
    try:
        stack_identity = identifier.HeatIdentifier(**identity)
    except ValueError:
        err_reason = _("Invalid Stack address")
        raise exc.HTTPInternalServerError(explanation=err_reason)

    return req.relative_url(stack_identity.url_path(), True)
Beispiel #7
0
def make_url(req, identity):
    '''Return the URL for the supplied identity dictionary.'''
    try:
        stack_identity = identifier.HeatIdentifier(**identity)
    except ValueError:
        err_reason = _('Invalid Stack address')
        raise exc.HTTPInternalServerError(explanation=err_reason)

    return req.relative_url(stack_identity.url_path(), True)
Beispiel #8
0
 def _stackid_format(self, resp):
     """
     Add a host:port:stack prefix, this formats the StackId in the response
     more like the AWS spec
     """
     if 'StackId' in resp:
         identity = identifier.HeatIdentifier(**resp['StackId'])
         resp['StackId'] = identity.arn()
     return resp
Beispiel #9
0
    def test_index(self):
        req = self._get('/stacks')

        identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1')

        engine_resp = {
            u'stacks': [{
                u'stack_identity': dict(identity),
                u'updated_time': u'2012-07-09T09:13:11Z',
                u'template_description': u'blah',
                u'description': u'blah',
                u'stack_status_reason': u'Stack successfully created',
                u'creation_time': u'2012-07-09T09:12:45Z',
                u'stack_name': identity.stack_name,
                u'stack_status': u'CREATE_COMPLETE',
                u'parameters': {},
                u'outputs': [],
                u'notification_topics': [],
                u'capabilities': [],
                u'disable_rollback': True,
                u'timeout_mins': 60,
            }]
        }
        self.m.StubOutWithMock(rpc, 'call')
        rpc.call(
            req.context, self.topic, {
                'method': 'show_stack',
                'args': {
                    'stack_identity': None
                },
                'version': self.api_version
            }, None).AndReturn(engine_resp)
        self.m.ReplayAll()

        result = self.controller.index(req, tenant_id=identity.tenant)

        expected = {
            'stacks': [{
                'links': [{
                    "href": self._url(identity),
                    "rel": "self"
                }],
                'id': '1',
                u'updated_time': u'2012-07-09T09:13:11Z',
                u'description': u'blah',
                u'stack_status_reason': u'Stack successfully created',
                u'creation_time': u'2012-07-09T09:12:45Z',
                u'stack_name': u'wordpress',
                u'stack_status': u'CREATE_COMPLETE'
            }]
        }
        self.assertEqual(result, expected)
        self.m.VerifyAll()
Beispiel #10
0
 def _id_format(resp):
     """
     Format the StackId field in the response as an ARN, and process other
     IDs into the correct format.
     """
     if 'StackId' in resp:
         identity = identifier.HeatIdentifier(**resp['StackId'])
         resp['StackId'] = identity.arn()
     if 'EventId' in resp:
         identity = identifier.EventIdentifier(**resp['EventId'])
         resp['EventId'] = identity.event_id
     return resp
Beispiel #11
0
    def _get_stack(self, context, stack_identity):
        identity = identifier.HeatIdentifier(**stack_identity)

        if identity.tenant != context.tenant_id:
            raise AttributeError('Invalid tenant')

        s = db_api.stack_get(context, identity.stack_id)

        if s is None:
            raise AttributeError('Stack not found')

        if identity.path or s.name != identity.stack_name:
            raise AttributeError('Invalid stack ID')

        return s
Beispiel #12
0
    def test_update(self):
        identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '6')
        stack_name = u'wordpress'
        stack_id = u'6'
        template = {u'Foo': u'bar'}
        json_template = json.dumps(template)
        parameters = {u'InstanceType': u'm1.xlarge'}
        body = {
            'template': template,
            'parameters': parameters,
            'timeout_mins': 30
        }

        req = self._put('/stacks/%(stack_name)s/%(stack_id)s' % identity,
                        json.dumps(body))

        self.m.StubOutWithMock(rpc, 'call')
        rpc.call(
            req.context, self.topic, {
                'method': 'update_stack',
                'args': {
                    'stack_identity': dict(identity),
                    'template': template,
                    'params': parameters,
                    'args': {
                        'timeout_mins': 30
                    }
                },
                'version': self.api_version
            }, None).AndReturn(dict(identity))
        self.m.ReplayAll()

        self.assertRaises(webob.exc.HTTPAccepted,
                          self.controller.update,
                          req,
                          tenant_id=identity.tenant,
                          stack_name=identity.stack_name,
                          stack_id=identity.stack_id,
                          body=body)
        self.m.VerifyAll()
Beispiel #13
0
    def test_create(self):
        identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '1')
        template = {u'Foo': u'bar'}
        json_template = json.dumps(template)
        parameters = {u'InstanceType': u'm1.xlarge'}
        body = {
            'template': template,
            'stack_name': identity.stack_name,
            'parameters': parameters,
            'timeout_mins': 30
        }

        req = self._post('/stacks', json.dumps(body))

        self.m.StubOutWithMock(rpc, 'call')
        rpc.call(
            req.context, self.topic, {
                'method': 'create_stack',
                'args': {
                    'stack_name': identity.stack_name,
                    'template': template,
                    'params': parameters,
                    'args': {
                        'timeout_mins': 30
                    }
                },
                'version': self.api_version
            }, None).AndReturn(dict(identity))
        self.m.ReplayAll()

        try:
            response = self.controller.create(req,
                                              tenant_id=identity.tenant,
                                              body=body)
        except webob.exc.HTTPCreated as created:
            self.assertEqual(created.location, self._url(identity))
        else:
            self.fail('HTTPCreated not raised')
        self.m.VerifyAll()
Beispiel #14
0
    def test_get_template(self):
        identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '6')
        req = self._get('/stacks/%(stack_name)s/%(stack_id)s' % identity)
        template = {u'Foo': u'bar'}

        self.m.StubOutWithMock(rpc, 'call')
        rpc.call(
            req.context, self.topic, {
                'method': 'get_template',
                'args': {
                    'stack_identity': dict(identity)
                },
                'version': self.api_version
            }, None).AndReturn(template)
        self.m.ReplayAll()

        response = self.controller.template(req,
                                            tenant_id=identity.tenant,
                                            stack_name=identity.stack_name,
                                            stack_id=identity.stack_id)

        self.assertEqual(response, template)
        self.m.VerifyAll()
Beispiel #15
0
    def test_show_aterr(self):
        identity = identifier.HeatIdentifier(self.tenant, 'wordpress', '6')

        req = self._get('/stacks/%(stack_name)s/%(stack_id)s' % identity)

        self.m.StubOutWithMock(rpc, 'call')
        rpc.call(
            req.context, self.topic, {
                'method': 'show_stack',
                'args': {
                    'stack_identity': dict(identity)
                },
                'version': self.api_version
            }, None).AndRaise(rpc_common.RemoteError("AttributeError"))
        self.m.ReplayAll()

        self.assertRaises(webob.exc.HTTPNotFound,
                          self.controller.show,
                          req,
                          tenant_id=identity.tenant,
                          stack_name=identity.stack_name,
                          stack_id=identity.stack_id)
        self.m.VerifyAll()
Beispiel #16
0
 def test_invalid_attr(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     hi.identity['foo'] = 'bar'
     self.assertRaises(AttributeError, getattr, hi, 'foo')
Beispiel #17
0
 def test_items(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertEqual(hi['tenant'], 't')
     self.assertEqual(hi['stack_name'], 's')
     self.assertEqual(hi['stack_id'], 'i')
     self.assertEqual(hi['path'], '/p')
Beispiel #18
0
 def test_path_default(self):
     hi = identifier.HeatIdentifier('t', 's', 'i')
     self.assertEqual(hi.path, '')
Beispiel #19
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(ei.resource(), pi)
Beispiel #20
0
 def test_event_init_from_dict(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', '/resources/p/events/42')
     ei = identifier.EventIdentifier(**hi)
     self.assertEqual(ei, hi)
Beispiel #21
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 : Capabilities, DisableRollback, NotificationARNs
            keymap = {'TimeoutInMinutes': engine_api.PARAM_TIMEOUT, }

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

            return result

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

        engine_action = {self.CREATE_STACK: self.engine_rpcapi.create_stack,
                         self.UPDATE_STACK: self.engine_rpcapi.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 = json.loads(templ)
        except ValueError:
            msg = _("The Template must be a JSON document.")
            return exception.HeatInvalidParameterValueError(detail=msg)

        args = {'template': stack,
                'params': stack_parms,
                '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 rpc_common.RemoteError 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)
Beispiel #22
0
 def test_resource_stack(self):
     si = identifier.HeatIdentifier('t', 's', 'i')
     ri = identifier.ResourceIdentifier(resource_name='r', **si)
     self.assertEqual(ri.stack(), si)
Beispiel #23
0
 def test_resource_init_from_dict(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', '/resources/r')
     ri = identifier.ResourceIdentifier(**hi)
     self.assertEqual(ri, hi)
Beispiel #24
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(ri.path, '/resources/p/resources/r')
Beispiel #25
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)
Beispiel #26
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')
Beispiel #27
0
 def test_arn_id_int(self):
     hi = identifier.HeatIdentifier('t', 's', 42, 'p')
     self.assertEqual(hi.arn(), 'arn:openstack:heat::t:stacks/s/42/p')
Beispiel #28
0
 def test_attrs(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p')
     self.assertEqual(hi.tenant, 't')
     self.assertEqual(hi.stack_name, 's')
     self.assertEqual(hi.stack_id, 'i')
     self.assertEqual(hi.path, '/p')
Beispiel #29
0
 def test_path_components(self):
     hi = identifier.HeatIdentifier('t', 's', 'i', 'p1/p2/p3')
     self.assertEqual(hi._path_components(), ['p1', 'p2', 'p3'])
Beispiel #30
0
 def test_event_init(self):
     si = identifier.HeatIdentifier('t', 's', 'i')
     pi = identifier.ResourceIdentifier(resource_name='p', **si)
     ei = identifier.EventIdentifier(event_id='e', **pi)
     self.assertEqual(ei.path, '/resources/p/events/e')