Add masakari openstackclient notification command

Implemented to notification command for openstackclient.

Change-Id: I35d037601def5cac447fd36d2e1b5680cf072963
This commit is contained in:
Takahiro Izumi 2016-11-03 12:12:14 +00:00 committed by Izumi Takahiro
parent d59e8b967d
commit 30adb650d2
7 changed files with 330 additions and 0 deletions

View File

@ -0,0 +1,26 @@
# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation
#
# 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.
class BaseException(Exception):
"""An error occurred."""
def __init__(self, message=None):
self.message = message
def __str__(self):
return self.message or self.__class__.__doc__
class CommandError(BaseException):
"""Invalid usage of CLI."""

View File

@ -0,0 +1,45 @@
# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation
#
# 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 masakariclient.common import exception as exc
from masakariclient.common.i18n import _
def format_parameters(params, parse_semicolon=True):
"""Reformat parameters into dict of format expected by the API."""
if not params:
return {}
if parse_semicolon:
# expect multiple invocations of --parameters but fall back to ';'
# delimited if only one --parameters is specified
if len(params) == 1:
params = params[0].split(';')
parameters = {}
for p in params:
try:
(n, v) = p.split(('='), 1)
except ValueError:
msg = _('Malformed parameter(%s). Use the key=value format.') % p
raise exc.CommandError(msg)
if n not in parameters:
parameters[n] = v
else:
if not isinstance(parameters[n], list):
parameters[n] = [parameters[n]]
parameters[n].append(v)
return parameters

View File

@ -0,0 +1,162 @@
# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation
#
# 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 openstack import exceptions as sdk_exc
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from oslo_serialization import jsonutils
from masakariclient.common.i18n import _
import masakariclient.common.utils as masakari_utils
class ListNotification(command.Lister):
"""List notifications."""
def get_parser(self, prog_name):
parser = super(ListNotification, self).get_parser(prog_name)
parser.add_argument(
'--limit',
metavar='<limit>',
help=_('Limit the number of policies returned')
)
parser.add_argument(
'--marker',
metavar='<id>',
help=_('Only return policies that appear after the given policy '
'ID')
)
parser.add_argument(
'--sort',
metavar='<key>[:<direction>]',
help=_("Sorting option which is a string containing a list of "
"keys separated by commas. Each key can be optionally "
"appended by a sort direction (:asc or :desc). The valid "
"sort keys are: ['type', 'name', 'created_at', "
"'updated_at']")
)
parser.add_argument(
'--filters',
metavar='<"key1=value1;key2=value2...">',
help=_("Filter parameters to apply on returned policies. "
"This can be specified multiple times, or once with "
"parameters separated by a semicolon. The valid filter "
"keys are: ['type', 'name']"),
action='append'
)
return parser
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.vmha
columns = ['notification_uuid', 'generated_time', 'status',
'type', 'source_host_uuid', 'payload']
queries = {
'limit': parsed_args.limit,
'marker': parsed_args.marker,
'sort': parsed_args.sort,
}
if parsed_args.filters:
queries.update(masakari_utils.format_parameters(
parsed_args.filters))
notifications = masakari_client.notifications(**queries)
formatters = {}
return (
columns,
(utils.get_item_properties(p, columns, formatters=formatters)
for p in notifications)
)
class ShowNotification(command.ShowOne):
"""Show notification details."""
def get_parser(self, prog_name):
parser = super(ShowNotification, self).get_parser(prog_name)
parser.add_argument(
'notification',
metavar='<notification>',
help='Notification to display (name or ID)',
)
return parser
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.vmha
return _show_notification(masakari_client,
notification_uuid=parsed_args.notification)
class CreateNotification(command.ShowOne):
"""Create notification."""
def get_parser(self, prog_name):
parser = super(CreateNotification, self).get_parser(prog_name)
parser.add_argument(
'type',
metavar='<type>',
help=_('Type of failure.')
)
parser.add_argument(
'hostname',
metavar='<hostname>',
help=_('Hostname of notification.')
)
parser.add_argument(
'generated_time',
metavar='<generated_time>',
help=_('Timestamp for notification. e.g. 2016-01-01T01:00:00.000')
)
parser.add_argument(
'payload',
metavar='<payload>',
help=_('JSON string about failure event.')
)
return parser
def take_action(self, parsed_args):
masakari_client = self.app.client_manager.vmha
payload = jsonutils.loads(parsed_args.payload)
attrs = {
'type': parsed_args.type,
'hostname': parsed_args.hostname,
'generated_time': parsed_args.generated_time,
'payload': payload,
}
notification = masakari_client.create_notification(**attrs)
return _show_notification(masakari_client,
notification.notification_uuid)
def _show_notification(masakari_client, notification_uuid):
try:
notification = masakari_client.get_notification(notification_uuid)
except sdk_exc.ResourceNotFound:
raise exceptions.CommandError(_('Notification not found: %s'
) % notification_uuid)
formatters = {}
columns = [
'created_at',
'updated_at',
'notification_uuid',
'type',
'source_host_uuid',
'generated_time',
'payload',
]
return columns, utils.get_dict_properties(notification.to_dict(), columns,
formatters=formatters)

View File

@ -14,9 +14,49 @@
from openstack import proxy from openstack import proxy
from masakariclient.sdk.vmha.v1 import notification as _notification
class Proxy(proxy.BaseProxy): class Proxy(proxy.BaseProxy):
"""Proxy class for vmha resource handling. """Proxy class for vmha resource handling.
Create method for each action of each API. Create method for each action of each API.
""" """
def notifications(self, **query):
"""Retrieve notifications.
:param kwargs \*\*query: Optional query parameters to be sent to
limit the notifications being returned.
:returns: A generator of notifications
"""
return self._list(_notification.Notification, paginated=False, **query)
def get_notification(self, notification):
"""Get a single notification.
:param notification: The value can be the ID of a notification or a
:class:
`~masakariclient.sdk.vmha.v1
.notification.Notification` instance.
:returns: One :class:`~masakariclient.sdk.vmha.v1
.notification.Notification`
:raises: :class:`~openstack.exceptions.ResourceNotFound`
when no resource can be found.
"""
return self._get(_notification.Notification, notification)
def create_notification(self, **attrs):
"""Create a new notification.
:param dict attrs: Keyword arguments which will be used to create
a :class:
`masakariclient.sdk.vmha.v1
.notification.Notification`,
comprised of the propoerties on the Notification
class.
:returns: The result of notification creation
:rtype: :class: `masakariclient.sdk.vmha.v1
.notification.Notification`
"""
return self._create(_notification.Notification, **attrs)

View File

@ -0,0 +1,51 @@
# Copyright(c) 2016 Nippon Telegraph and Telephone Corporation
#
# 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 openstack import resource
from masakariclient.sdk.vmha import vmha_service
class Notification(resource.Resource):
resource_key = "notification"
resources_key = "notifications"
base_path = "/notifications"
service = vmha_service.VMHAService()
# capabilities
# 1] GET /v1/notifications
# 2] GET /v1/notifications/<notification_uuid>
# 3] POST /v1/notifications
allow_list = True
allow_retrieve = True
allow_create = True
allow_update = False
allow_delete = False
# Properties
# Refer "https://github.com/openstack/masakari/tree/
# master/masakari/api/openstack/ha/schemas/notificaions.py"
# for properties of notifications API
#: A ID of representing this notification.
id = resource.prop("id")
#: The type of failure. Valuse values include ''COMPUTE_HOST'',
#: ''VM'', ''PROCESS''
type = resource.prop("type")
#: The hostname of this notification.
hostname = resource.prop("hostname")
#: The generated_time for this notitication.
generated_time = resource.prop("generated_time")
#: The payload of this notification.
payload = resource.prop("payload")

View File

@ -5,4 +5,5 @@
openstacksdk>=0.9.7 # Apache-2.0 openstacksdk>=0.9.7 # Apache-2.0
osc-lib>=1.2.0 # Apache-2.0 osc-lib>=1.2.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0 oslo.i18n>=2.1.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
pbr>=1.6 # Apache-2.0 pbr>=1.6 # Apache-2.0

View File

@ -27,6 +27,11 @@ packages =
openstack.cli.extension = openstack.cli.extension =
vmha = masakariclient.plugin vmha = masakariclient.plugin
openstack.vmha.v1 =
notification_create = masakariclient.osc.v1.notification:CreateNotification
notification_show = masakariclient.osc.v1.notification:ShowNotification
notification_list = masakariclient.osc.v1.notification:ListNotification
[build_sphinx] [build_sphinx]
source-dir = doc/source source-dir = doc/source
build-dir = doc/build build-dir = doc/build