Support for events list and details
This also replaces resource_id with resource_name in the resources API. Change-Id: Ia5ccec5d94fb8106be2dfe89976db0fceeb73b58
This commit is contained in:
@@ -14,8 +14,9 @@
|
||||
# under the License.
|
||||
|
||||
from heatclient.common import http
|
||||
from heatclient.v1 import stacks
|
||||
from heatclient.v1 import events
|
||||
from heatclient.v1 import resources
|
||||
from heatclient.v1 import stacks
|
||||
|
||||
|
||||
class Client(http.HTTPClient):
|
||||
@@ -33,3 +34,4 @@ class Client(http.HTTPClient):
|
||||
super(Client, self).__init__(*args, **kwargs)
|
||||
self.stacks = stacks.StackManager(self)
|
||||
self.resources = resources.ResourceManager(self)
|
||||
self.events = events.EventManager(self)
|
||||
|
||||
64
heatclient/v1/events.py
Normal file
64
heatclient/v1/events.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# Copyright 2012 OpenStack LLC.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, 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.
|
||||
|
||||
from heatclient.common import base
|
||||
from heatclient.v1 import stacks
|
||||
import heatclient.exc as exc
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
|
||||
|
||||
class Event(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<Event %s>" % self._info
|
||||
|
||||
def update(self, **fields):
|
||||
self.manager.update(self, **fields)
|
||||
|
||||
def delete(self):
|
||||
return self.manager.delete(self)
|
||||
|
||||
def data(self, **kwargs):
|
||||
return self.manager.data(self, **kwargs)
|
||||
|
||||
|
||||
class EventManager(stacks.StackChildManager):
|
||||
resource_class = Event
|
||||
|
||||
def list(self, stack_id, resource_name=None):
|
||||
"""Get a list of events.
|
||||
:param stack_id: ID of stack the events belong to
|
||||
:param resource_name: Optional name of resources to filter events by
|
||||
:rtype: list of :class:`Event`
|
||||
"""
|
||||
if resource_name == None:
|
||||
url = '/stacks/%s/events' % stack_id
|
||||
else:
|
||||
stack_id = self._resolve_stack_id(stack_id)
|
||||
url = '/stacks/%s/resources/%s/events' % (stack_id, resource_name)
|
||||
return self._list(url, "events")
|
||||
|
||||
def get(self, stack_id, resource_name, event_id):
|
||||
"""Get the details for a specific event.
|
||||
|
||||
:param stack_id: ID of stack containing the event
|
||||
:param resource_name: ID of resource the event belongs to
|
||||
:param event_id: ID of event to get the details for
|
||||
"""
|
||||
stack_id = self._resolve_stack_id(stack_id)
|
||||
resp, body = self.api.json_request('GET',
|
||||
'/stacks/%s/resources/%s/events/%s' %
|
||||
(stack_id, resource_name, event_id))
|
||||
return Event(self, body['event'])
|
||||
@@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
from heatclient.common import base
|
||||
from heatclient.v1 import stacks
|
||||
import heatclient.exc as exc
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
@@ -33,7 +34,7 @@ class Resource(base.Resource):
|
||||
return self.manager.data(self, **kwargs)
|
||||
|
||||
|
||||
class ResourceManager(base.Manager):
|
||||
class ResourceManager(stacks.StackChildManager):
|
||||
resource_class = Resource
|
||||
|
||||
def list(self, stack_id):
|
||||
@@ -43,38 +44,27 @@ class ResourceManager(base.Manager):
|
||||
url = '/stacks/%s/resources' % stack_id
|
||||
return self._list(url, "resources")
|
||||
|
||||
def get(self, stack_id, resource_id):
|
||||
def get(self, stack_id, resource_name):
|
||||
"""Get the details for a specific resource.
|
||||
|
||||
:param stack_id: ID of stack containing the resource
|
||||
:param resource_id: ID of resource to get the details for
|
||||
:param resource_name: ID of resource to get the details for
|
||||
"""
|
||||
resp, body = self._get_resolve_fallback(stack_id, resource_id,
|
||||
'/stacks/%s/resources/%s')
|
||||
stack_id = self._resolve_stack_id(stack_id)
|
||||
resp, body = self.api.json_request('GET',
|
||||
'/stacks/%s/resources/%s' %
|
||||
(stack_id, resource_name))
|
||||
|
||||
return Resource(self, body['resource'])
|
||||
|
||||
def metadata(self, stack_id, resource_id):
|
||||
def metadata(self, stack_id, resource_name):
|
||||
"""Get the metadata for a specific resource.
|
||||
|
||||
:param stack_id: ID of stack containing the resource
|
||||
:param resource_id: ID of resource to get metadata for
|
||||
:param resource_name: ID of resource to get metadata for
|
||||
"""
|
||||
resp, body = self._get_resolve_fallback(stack_id, resource_id,
|
||||
'/stacks/%s/resources/%s/metadata')
|
||||
return Resource(self, body['metadata'])
|
||||
|
||||
def _get_resolve_fallback(self, stack_id, resource_id, path_pattern):
|
||||
try:
|
||||
resp, body = self.api.json_request('GET',
|
||||
path_pattern % (stack_id, resource_id))
|
||||
except exc.HTTPNotFound:
|
||||
stack_id = self._resolve_stack_id(stack_id)
|
||||
resp, body = self.api.json_request('GET',
|
||||
path_pattern % (stack_id, resource_id))
|
||||
return (resp, body)
|
||||
|
||||
def _resolve_stack_id(self, stack_id):
|
||||
stack_id = self._resolve_stack_id(stack_id)
|
||||
resp, body = self.api.json_request('GET',
|
||||
'/stacks/%s' % stack_id)
|
||||
stack = body['stack']
|
||||
return '%s/%s' % (stack['stack_name'], stack['id'])
|
||||
'/stacks/%s/resources/%s/metadata' %
|
||||
(stack_id, resource_name))
|
||||
return Resource(self, body['metadata'])
|
||||
|
||||
@@ -176,12 +176,12 @@ def do_resource_list(hc, args):
|
||||
|
||||
@utils.arg('id', metavar='<NAME or ID>',
|
||||
help='Name or ID of stack to show the resource for.')
|
||||
@utils.arg('resource', metavar='<RESOURCE NAME or ID>',
|
||||
help='Name or ID of the resource to show the details for.')
|
||||
@utils.arg('resource', metavar='<RESOURCE>',
|
||||
help='Name of the resource to show the details for.')
|
||||
def do_resource(hc, args):
|
||||
'''Describe the resource'''
|
||||
fields = {'stack_id': args.id,
|
||||
'resource_id': args.resource}
|
||||
'resource_name': args.resource}
|
||||
try:
|
||||
resource = hc.resources.get(**fields)
|
||||
except exc.HTTPNotFound:
|
||||
@@ -198,12 +198,12 @@ def do_resource(hc, args):
|
||||
|
||||
@utils.arg('id', metavar='<NAME or ID>',
|
||||
help='Name or ID of stack to show the resource metadata for.')
|
||||
@utils.arg('resource', metavar='<RESOURCE NAME or ID>',
|
||||
help='Name or ID of the resource to show the metadata for.')
|
||||
@utils.arg('resource', metavar='<RESOURCE>',
|
||||
help='Name of the resource to show the metadata for.')
|
||||
def do_resource_metadata(hc, args):
|
||||
'''List resource metadata'''
|
||||
fields = {'stack_id': args.id,
|
||||
'resource_id': args.resource}
|
||||
'resource_name': args.resource}
|
||||
try:
|
||||
resource = hc.resources.metadata(**fields)
|
||||
except exc.HTTPNotFound:
|
||||
@@ -213,9 +213,47 @@ def do_resource_metadata(hc, args):
|
||||
formatters = {}
|
||||
utils.print_dict(resource.to_dict(), formatters=formatters)
|
||||
|
||||
# TODO only need to implement this once the server supports it
|
||||
#@utils.arg('id', metavar='<NAME or ID>',
|
||||
# help='Name or ID of stack to show the events for.')
|
||||
#def do_event_list(hc, args):
|
||||
# '''List events for a stack'''
|
||||
# pass
|
||||
|
||||
@utils.arg('id', metavar='<NAME or ID>',
|
||||
help='Name or ID of stack to show the events for.')
|
||||
@utils.arg('-r', '--resource', metavar='<RESOURCE>',
|
||||
help='Name of the resource to filter events by')
|
||||
def do_event_list(hc, args):
|
||||
'''List events for a stack'''
|
||||
fields = {'stack_id': args.id,
|
||||
'resource_name': args.resource}
|
||||
try:
|
||||
events = hc.events.list(**fields)
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError('Stack not found: %s' % args.id)
|
||||
else:
|
||||
field_labels = ['Resource', 'ID', 'Reason',
|
||||
'Status', 'Event time']
|
||||
fields = ['logical_resource_id', 'id', 'resource_status_reason',
|
||||
'resource_status', 'event_time']
|
||||
utils.print_list(events, fields, field_labels, sortby=4)
|
||||
|
||||
|
||||
@utils.arg('id', metavar='<NAME or ID>',
|
||||
help='Name or ID of stack to show the events for.')
|
||||
@utils.arg('resource', metavar='<RESOURCE>',
|
||||
help='Name of the resource the event belongs to.')
|
||||
@utils.arg('event', metavar='<EVENT>',
|
||||
help='ID of event to display details for')
|
||||
def do_event(hc, args):
|
||||
'''Describe the event'''
|
||||
fields = {'stack_id': args.id,
|
||||
'resource_name': args.resource,
|
||||
'event_id': args.event}
|
||||
try:
|
||||
event = hc.events.get(**fields)
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError('Stack not found: %s' % args.id)
|
||||
else:
|
||||
link_format = lambda links: '\n'.join([l['href'] for l in links])
|
||||
json_format = lambda js: json.dumps(js, indent=2)
|
||||
formatters = {
|
||||
'links': link_format,
|
||||
'resource_properties': json_format
|
||||
}
|
||||
utils.print_dict(event.to_dict(), formatters=formatters)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import urllib
|
||||
|
||||
from heatclient.common import base
|
||||
import heatclient.exc as exc
|
||||
|
||||
DEFAULT_PAGE_SIZE = 20
|
||||
|
||||
@@ -118,3 +119,16 @@ class StackManager(base.Manager):
|
||||
resp, body = self.api.json_request(
|
||||
'POST', '/validate', body=kwargs)
|
||||
return body
|
||||
|
||||
|
||||
class StackChildManager(base.Manager):
|
||||
|
||||
def _resolve_stack_id(self, stack_id):
|
||||
# if the id already has a slash in it,
|
||||
# then it is already {stack_name}/{stack_id}
|
||||
if stack_id.find('/') > 0:
|
||||
return stack_id
|
||||
resp, body = self.api.json_request('GET',
|
||||
'/stacks/%s' % stack_id)
|
||||
stack = body['stack']
|
||||
return '%s/%s' % (stack['stack_name'], stack['id'])
|
||||
|
||||
Reference in New Issue
Block a user