Add os-server-external-events support
This adds support for the os-server-external-events extension in nova, which allows other services to deliver events to nova. It also adds a shell command to trigger the "network-changed" event manually, which will cause nova to refresh its network cache from neutron. Related to blueprint admin-event-callback-api Change-Id: I1a302a43b6b7a6d8bdc03965a8f4c1a151bcab88
This commit is contained in:
parent
bd72fb0a2e
commit
04a123cdee
@ -146,6 +146,7 @@ You'll find complete documentation on the shell by running
|
|||||||
rate-limits Print a list of rate limits for a user
|
rate-limits Print a list of rate limits for a user
|
||||||
reboot Reboot a server.
|
reboot Reboot a server.
|
||||||
rebuild Shutdown, re-image, and re-boot a server.
|
rebuild Shutdown, re-image, and re-boot a server.
|
||||||
|
refresh-network Refresh server network information.
|
||||||
remove-fixed-ip Remove an IP address from a server.
|
remove-fixed-ip Remove an IP address from a server.
|
||||||
remove-floating-ip Remove a floating IP address from a server.
|
remove-floating-ip Remove a floating IP address from a server.
|
||||||
rename Rename a server.
|
rename Rename a server.
|
||||||
|
@ -134,3 +134,14 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
|
|||||||
|
|
||||||
def delete_os_assisted_volume_snapshots_x(self, **kw):
|
def delete_os_assisted_volume_snapshots_x(self, **kw):
|
||||||
return (202, {}, {})
|
return (202, {}, {})
|
||||||
|
|
||||||
|
def post_os_server_external_events(self, **kw):
|
||||||
|
return (200, {}, {'events': [
|
||||||
|
{'name': 'test-event',
|
||||||
|
'status': 'completed',
|
||||||
|
'tag': 'tag',
|
||||||
|
'server_uuid': 'fake-uuid1'},
|
||||||
|
{'name': 'test-event',
|
||||||
|
'status': 'completed',
|
||||||
|
'tag': 'tag',
|
||||||
|
'server_uuid': 'fake-uuid2'}]})
|
||||||
|
44
novaclient/tests/v1_1/contrib/test_server_external_events.py
Normal file
44
novaclient/tests/v1_1/contrib/test_server_external_events.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Copyright (C) 2014, Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
External event triggering for servers, not to be used by users.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from novaclient import extension
|
||||||
|
from novaclient.tests import utils
|
||||||
|
from novaclient.tests.v1_1.contrib import fakes
|
||||||
|
from novaclient.v1_1.contrib import server_external_events as ext_events
|
||||||
|
|
||||||
|
|
||||||
|
extensions = [
|
||||||
|
extension.Extension(ext_events.__name__.split(".")[-1],
|
||||||
|
ext_events),
|
||||||
|
]
|
||||||
|
cs = fakes.FakeClient(extensions=extensions)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerExternalEventsTestCase(utils.TestCase):
|
||||||
|
def test_external_event(self):
|
||||||
|
events = [{'server_uuid': 'fake-uuid1',
|
||||||
|
'name': 'test-event',
|
||||||
|
'status': 'completed',
|
||||||
|
'tag': 'tag'},
|
||||||
|
{'server_uuid': 'fake-uuid2',
|
||||||
|
'name': 'test-event',
|
||||||
|
'status': 'completed',
|
||||||
|
'tag': 'tag'}]
|
||||||
|
result = cs.server_external_events.create(events)
|
||||||
|
self.assertEqual(events, result)
|
||||||
|
cs.assert_called('POST', '/os-server-external-events')
|
@ -1991,3 +1991,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
|||||||
"updated_at": "2012-10-29T13:42:02.000000"
|
"updated_at": "2012-10-29T13:42:02.000000"
|
||||||
}]}
|
}]}
|
||||||
return (200, {}, migrations)
|
return (200, {}, migrations)
|
||||||
|
|
||||||
|
def post_os_server_external_events(self, **kw):
|
||||||
|
return (200, {}, {'events': [
|
||||||
|
{'name': 'network-changed',
|
||||||
|
'server_uuid': '1234'}]})
|
||||||
|
@ -946,6 +946,12 @@ class ShellTest(utils.TestCase):
|
|||||||
self.run_command('diagnostics sample-server')
|
self.run_command('diagnostics sample-server')
|
||||||
self.assert_called('GET', '/servers/1234/diagnostics')
|
self.assert_called('GET', '/servers/1234/diagnostics')
|
||||||
|
|
||||||
|
def test_refresh_network(self):
|
||||||
|
self.run_command('refresh-network 1234')
|
||||||
|
self.assert_called('POST', '/os-server-external-events',
|
||||||
|
{'events': [{'name': 'network-changed',
|
||||||
|
'server_uuid': 1234}]})
|
||||||
|
|
||||||
def test_set_meta_set(self):
|
def test_set_meta_set(self):
|
||||||
self.run_command('meta 1234 set key1=val1 key2=val2')
|
self.run_command('meta 1234 set key1=val1 key2=val2')
|
||||||
self.assert_called('POST', '/servers/1234/metadata',
|
self.assert_called('POST', '/servers/1234/metadata',
|
||||||
|
43
novaclient/v1_1/contrib/server_external_events.py
Normal file
43
novaclient/v1_1/contrib/server_external_events.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# Copyright (C) 2014, Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
"""
|
||||||
|
External event triggering for servers, not to be used by users.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from novaclient import base
|
||||||
|
|
||||||
|
|
||||||
|
class Event(base.Resource):
|
||||||
|
def __repr__(self):
|
||||||
|
return "<Event: %s>" % self.name
|
||||||
|
|
||||||
|
|
||||||
|
class ServerExternalEventManager(base.Manager):
|
||||||
|
resource_class = Event
|
||||||
|
|
||||||
|
def create(self, events):
|
||||||
|
"""Create one or more server events.
|
||||||
|
|
||||||
|
:param:events: A list of dictionaries containing 'server_uuid', 'name',
|
||||||
|
'status', and 'tag' (which may be absent)
|
||||||
|
"""
|
||||||
|
|
||||||
|
body = {'events': events}
|
||||||
|
return self._create('/os-server-external-events', body, 'events',
|
||||||
|
return_raw=True)
|
||||||
|
|
||||||
|
|
||||||
|
manager_class = ServerExternalEventManager
|
||||||
|
name = 'server_external_events'
|
@ -1366,6 +1366,16 @@ def do_diagnostics(cs, args):
|
|||||||
utils.print_dict(cs.servers.diagnostics(server)[1], wrap=80)
|
utils.print_dict(cs.servers.diagnostics(server)[1], wrap=80)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('server', metavar='<server>',
|
||||||
|
help=_('Name or ID of a server for which the network cache should '
|
||||||
|
'be refreshed from neutron (Admin only).'))
|
||||||
|
def do_refresh_network(cs, args):
|
||||||
|
"""Refresh server network information."""
|
||||||
|
server = _find_server(cs, args.server)
|
||||||
|
cs.server_external_events.create([{'server_uuid': server.id,
|
||||||
|
'name': 'network-changed'}])
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
@utils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||||
def do_root_password(cs, args):
|
def do_root_password(cs, args):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user