import contextlib
+from copy import deepcopy
import functools
import os
import socket
'ResourceStatus': e.name}
return {'events': [parse_event(e) for e in events]}
+
+ def metadata_list_stacks(self, context):
+ """
+ Return the names of the stacks registered with Heat.
+ """
+ stacks = db_api.stack_get_all(None)
+ return [s.name for s in stacks]
+
+ def metadata_list_resources(self, context, stack_name):
+ """
+ Return the resource IDs of the given stack.
+ """
+ stack = db_api.stack_get(None, stack_name)
+ if stack:
+ return [r.name for r in stack.resources]
+ else:
+ return None
+
+ def metadata_get_resource(self, context, stack_name, resource_id):
+ """
+ Get the metadata for the given resource.
+ """
+ s = db_api.stack_get(None, stack_name)
+ if not s:
+ return ['stack', None]
+
+ raw_template = db_api.raw_template_get(None, s.raw_template_id)
+ template = raw_template.template
+
+ if not resource_id in template.get('Resources', {}):
+ return ['resource', None]
+
+ metadata = template['Resources'][resource_id].get('Metadata', {})
+ return [None, metadata]
+
+ def metadata_update(self, context, stack_name, resource_id, metadata):
+ """
+ Update the metadata for the given resource.
+ """
+ s = db_api.stack_get(None, stack_name)
+ if not s:
+ return ['stack', None]
+
+ raw_template = db_api.raw_template_get(None, s.raw_template_id)
+
+ if not resource_id in raw_template.template.get('Resources', {}):
+ return ['resource', None]
+
+ # TODO(shadower) deep copy of the template is required here. Without it,
+ # we directly modify raw_template.template by assigning the new
+ # metadata. When we then call raw_template.update_and_save, the session
+ # will detect no changes and thus not update the database.
+ # Just updating the values and calling save didn't seem to work either.
+ # There's probably an idiomatic way I'm missing right now.
+ t = deepcopy(raw_template.template)
+ t['Resources'][resource_id]['Metadata'] = metadata
+ raw_template.update_and_save({'template': t})
+ return [None, metadata]
from webob.exc import Response
from heat.common import wsgi
+from heat import context
from heat.metadata import db as db_api
from heat.metadata.db import (ConflictError, StackNotFoundError,
ResourceNotFoundError)
+from heat import rpc
def json_response(http_status, data):
}
def list_stacks(self, req):
- return db_api.list_stacks()
+ con = context.get_admin_context()
+ resp = rpc.call(con, 'engine',
+ {'method': 'metadata_list_stacks'})
+ return resp
def list_resources(self, req, stack_name):
- try:
- resources = db_api.list_resources(stack_name)
- except StackNotFoundError:
+ con = context.get_admin_context()
+ resources = rpc.call(con, 'engine',
+ {'method': 'metadata_list_resources',
+ 'args': {'stack_name': stack_name}})
+ if resources:
+ return resources
+ else:
return json_error(404, 'The stack "%s" does not exist.' % stack_name)
- return resources
def get_resource(self, req, stack_name, resource_id):
- try:
- resource = db_api.get_resource(stack_name, resource_id)
- except StackNotFoundError:
- return json_error(404, 'The stack "%s" does not exist.' % stack_name)
- except ResourceNotFoundError:
- return json_error(404, 'The resource "%s" does not exist.' % resource_id)
- return resource
-
- def create_stack(self, req, body, stack_name):
- try:
- stack = db_api.create_stack(stack_name, body)
- except ConflictError:
- return json_error(409, 'The stack "%s" already exists.' % stack_name)
- return json_response(201, stack)
+ con = context.get_admin_context()
+ [error, metadata] = rpc.call(con, 'engine',
+ {'method': 'metadata_get_resource',
+ 'args': {'stack_name': stack_name,
+ 'resource_id': resource_id}})
+ if error:
+ if error == 'stack':
+ return json_error(404, 'The stack "%s" does not exist.' % stack_name)
+ else:
+ return json_error(404, 'The resource "%s" does not exist.' % resource_id)
+ return metadata
def update_metadata(self, req, body, stack_name, resource_id):
- try:
- db_api.update_resource_metadata(stack_name, resource_id, body)
- except StackNotFoundError:
- return json_error(409, 'The stack "%s" does not exist.' % stack_name)
- except ResourceNotFoundError:
- # The resource doesn't exit yet, create it.
- db_api.create_resource_metadata(stack_name, resource_id, body)
+ con = context.get_admin_context()
+ [error, metadata] = rpc.call(con, 'engine',
+ {'method': 'metadata_update',
+ 'args': {'stack_name': stack_name,
+ 'resource_id': resource_id,
+ 'metadata': body}})
+ if error:
+ if error == 'stack':
+ return json_error(404, 'The stack "%s" does not exist.' % stack_name)
+ else:
+ return json_error(404, 'The resource "%s" does not exist.' % resource_id)
return json_response(201, {
'resource': resource_id,
'metadata': body,