Add host/hostId to instance action events API
This patch adds a new microversion to ``GET /servers/{server_id}/os-instance-actions/{req_id}`` API to include the ``host`` field for admin and an ``hostId`` for all users by default. And the display of newly added ``host`` field will be controlled by the same policy as the ``traceback`` field. The newly added fields can be used to determine on which host a given action event occurred. Part of blueprint: add-host-to-instance-action-events Change-Id: I2f8b4a12a088b9ed96b428eafde2e0c478fb1db5
This commit is contained in:
parent
577cb4b2f4
commit
c2f7d65858
@ -111,14 +111,16 @@ Response
|
||||
- events.finish_time: event_finish_time
|
||||
- events.result: event_result
|
||||
- events.traceback: event_traceback
|
||||
- events.hostId: event_hostId
|
||||
- events.host: event_host
|
||||
- updated_at: updated_instance_action
|
||||
|
||||
**Example Show Server Action Details For Admin (v2.1)**
|
||||
**Example Show Server Action Details For Admin (v2.62)**
|
||||
|
||||
.. literalinclude:: ../../doc/api_samples/os-instance-actions/instance-action-get-resp.json
|
||||
.. literalinclude:: ../../doc/api_samples/os-instance-actions/v2.62/instance-action-get-resp.json
|
||||
:language: javascript
|
||||
|
||||
**Example Show Server Action Details For Non-Admin (v2.51)**
|
||||
**Example Show Server Action Details For Non-Admin (v2.62)**
|
||||
|
||||
.. literalinclude:: ../../doc/api_samples/os-instance-actions/v2.51/instance-action-get-non-admin-resp.json
|
||||
.. literalinclude:: ../../doc/api_samples/os-instance-actions/v2.62/instance-action-get-non-admin-resp.json
|
||||
:language: javascript
|
||||
|
@ -2357,6 +2357,29 @@ event_finish_time:
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
event_host:
|
||||
min_version: 2.62
|
||||
description: |
|
||||
The name of the host on which the event occurred.
|
||||
|
||||
Policy defaults enable only users with the administrative role to see
|
||||
an instance action event host. Cloud providers can change these
|
||||
permissions through the ``policy.json`` file.
|
||||
in: body
|
||||
required: false
|
||||
type: string
|
||||
event_hostId:
|
||||
min_version: 2.62
|
||||
description: |
|
||||
An obfuscated hashed host ID string, or the empty string if there is no
|
||||
host for the event. This is a hashed value so will not actually look like
|
||||
a hostname, and is hashed with data from the project_id, so the same
|
||||
physical host as seen by two different project_ids will be different.
|
||||
This is useful when within the same project you need to determine if two
|
||||
events occurred on the same or different physical hosts.
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
event_name:
|
||||
description: |
|
||||
The event name. A valid value is ``network-changed``, ``network-vif-plugged``,
|
||||
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"instanceAction": {
|
||||
"action": "stop",
|
||||
"events": [
|
||||
{
|
||||
"event": "compute_stop_instance",
|
||||
"finish_time": "2018-04-25T01:26:34.784165",
|
||||
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
|
||||
"result": "Success",
|
||||
"start_time": "2018-04-25T01:26:34.612020"
|
||||
}
|
||||
],
|
||||
"instance_uuid": "79edaa44-ad4f-4af7-b994-154518c2b927",
|
||||
"message": null,
|
||||
"project_id": "6f70656e737461636b20342065766572",
|
||||
"request_id": "req-8eb28d4a-db6c-4337-bab8-ce154e9c620e",
|
||||
"start_time": "2018-04-25T01:26:34.388280",
|
||||
"updated_at": "2018-04-25T01:26:34.784165",
|
||||
"user_id": "fake"
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"instanceAction": {
|
||||
"action": "stop",
|
||||
"events": [
|
||||
{
|
||||
"event": "compute_stop_instance",
|
||||
"finish_time": "2018-04-25T01:26:36.790544",
|
||||
"host": "compute",
|
||||
"hostId": "2091634baaccdc4c5a1d57069c833e402921df696b7f970791b12ec6",
|
||||
"result": "Success",
|
||||
"start_time": "2018-04-25T01:26:36.539271",
|
||||
"traceback": null
|
||||
}
|
||||
],
|
||||
"instance_uuid": "4bf3473b-d550-4b65-9409-292d44ab14a2",
|
||||
"message": null,
|
||||
"project_id": "6f70656e737461636b20342065766572",
|
||||
"request_id": "req-0d819d5c-1527-4669-bdf0-ffad31b5105b",
|
||||
"start_time": "2018-04-25T01:26:36.341290",
|
||||
"updated_at": "2018-04-25T01:26:36.790544",
|
||||
"user_id": "admin"
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "stop",
|
||||
"instance_uuid": "15835b6f-1e14-4cfa-9f66-1abea1a1c0d5",
|
||||
"message": null,
|
||||
"project_id": "6f70656e737461636b20342065766572",
|
||||
"request_id": "req-f04d4b92-6241-42da-b82d-2cedb225c58d",
|
||||
"start_time": "2018-04-25T01:26:36.036697",
|
||||
"updated_at": "2018-04-25T01:26:36.525308",
|
||||
"user_id": "admin"
|
||||
},
|
||||
{
|
||||
"action": "create",
|
||||
"instance_uuid": "15835b6f-1e14-4cfa-9f66-1abea1a1c0d5",
|
||||
"message": null,
|
||||
"project_id": "6f70656e737461636b20342065766572",
|
||||
"request_id": "req-d8790618-9bbf-4df0-8af8-fc9e24de29c0",
|
||||
"start_time": "2018-04-25T01:26:33.692125",
|
||||
"updated_at": "2018-04-25T01:26:35.993821",
|
||||
"user_id": "admin"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "stop",
|
||||
"instance_uuid": "7a580cc0-3469-441a-9736-d5fce91003f9",
|
||||
"message": null,
|
||||
"project_id": "6f70656e737461636b20342065766572",
|
||||
"request_id": "req-b8ffb713-61a2-4e7c-a705-37052cba9d6e",
|
||||
"start_time": "2018-04-25T01:26:28.955571",
|
||||
"updated_at": "2018-04-25T01:26:29.414973",
|
||||
"user_id": "fake"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"href": "http://openstack.example.com/v2.1/6f70656e737461636b20342065766572/servers/7a580cc0-3469-441a-9736-d5fce91003f9/os-instance-actions?limit=1&marker=req-b8ffb713-61a2-4e7c-a705-37052cba9d6e",
|
||||
"rel": "next"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "create",
|
||||
"instance_uuid": "9bde1fd5-8435-45c5-afc1-bedd0605275b",
|
||||
"message": null,
|
||||
"project_id": "6f70656e737461636b20342065766572",
|
||||
"request_id": "req-4510fb10-447f-4572-a64d-c2324547d86c",
|
||||
"start_time": "2018-04-25T01:26:33.710291",
|
||||
"updated_at": "2018-04-25T01:26:35.374936",
|
||||
"user_id": "fake"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "stop",
|
||||
"instance_uuid": "2150964c-30fe-4214-9547-8822375aa7d0",
|
||||
"message": null,
|
||||
"project_id": "6f70656e737461636b20342065766572",
|
||||
"request_id": "req-0c3b2079-0a44-474d-a5b2-7466d4b4c642",
|
||||
"start_time": "2018-04-25T01:26:29.594237",
|
||||
"updated_at": "2018-04-25T01:26:30.065061",
|
||||
"user_id": "admin"
|
||||
}
|
||||
]
|
||||
}
|
@ -19,7 +19,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.61",
|
||||
"version": "2.62",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
}
|
||||
],
|
||||
"status": "CURRENT",
|
||||
"version": "2.61",
|
||||
"version": "2.62",
|
||||
"min_version": "2.1",
|
||||
"updated": "2013-07-23T11:33:21Z"
|
||||
}
|
||||
|
@ -146,6 +146,8 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
* 2.61 - Exposes flavor extra_specs in the flavor representation. Flavor
|
||||
extra_specs will be included in Response body of GET, POST, PUT
|
||||
/flavors APIs.
|
||||
* 2.62 - Add ``host`` and ``hostId`` fields to instance action detail API
|
||||
responses.
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
@ -154,7 +156,7 @@ REST_API_VERSION_HISTORY = """REST API Version History:
|
||||
# Note(cyeoh): This only applies for the v2.1 API once microversions
|
||||
# support is fully merged. It does not affect the V2 API.
|
||||
_MIN_API_VERSION = "2.1"
|
||||
_MAX_API_VERSION = "2.61"
|
||||
_MAX_API_VERSION = "2.62"
|
||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||
|
||||
# Almost all proxy APIs which are related to network, images and baremetal
|
||||
|
@ -53,13 +53,20 @@ class InstanceActionsController(wsgi.Controller):
|
||||
action[key] = action_raw.get(key)
|
||||
return action
|
||||
|
||||
def _format_event(self, event_raw, show_traceback=False):
|
||||
def _format_event(self, event_raw, project_id, show_traceback=False,
|
||||
show_host=False, show_hostid=False):
|
||||
event = {}
|
||||
for key in EVENT_KEYS:
|
||||
# By default, non-admins are not allowed to see traceback details.
|
||||
if key == 'traceback' and not show_traceback:
|
||||
continue
|
||||
event[key] = event_raw.get(key)
|
||||
# By default, non-admins are not allowed to see host.
|
||||
if show_host:
|
||||
event['host'] = event_raw['host']
|
||||
if show_hostid:
|
||||
event['hostId'] = utils.generate_hostid(event_raw['host'],
|
||||
project_id)
|
||||
return event
|
||||
|
||||
@wsgi.Controller.api_version("2.1", "2.20")
|
||||
@ -138,18 +145,26 @@ class InstanceActionsController(wsgi.Controller):
|
||||
# by default.
|
||||
show_events = False
|
||||
show_traceback = False
|
||||
show_host = False
|
||||
if context.can(ia_policies.POLICY_ROOT % 'events', fatal=False):
|
||||
# For all microversions, the user can see all event details
|
||||
# including the traceback.
|
||||
show_events = show_traceback = True
|
||||
show_host = api_version_request.is_supported(req, '2.62')
|
||||
elif api_version_request.is_supported(req, '2.51'):
|
||||
# The user is not able to see all event details, but they can at
|
||||
# least see the non-traceback event details.
|
||||
show_events = True
|
||||
|
||||
# An obfuscated hashed host id is returned since microversion 2.62
|
||||
# for all users.
|
||||
show_hostid = api_version_request.is_supported(req, '2.62')
|
||||
|
||||
if show_events:
|
||||
events_raw = self.action_api.action_events_get(context, instance,
|
||||
action_id)
|
||||
action['events'] = [self._format_event(evt, show_traceback)
|
||||
for evt in events_raw]
|
||||
action['events'] = [self._format_event(
|
||||
evt, action['project_id'], show_traceback=show_traceback,
|
||||
show_host=show_host, show_hostid=show_hostid
|
||||
) for evt in events_raw]
|
||||
return {'instanceAction': action}
|
||||
|
@ -780,3 +780,14 @@ Response body of the following APIs:
|
||||
* ``GET /flavors/{flavor_id}``
|
||||
* ``POST /flavors``
|
||||
* ``PUT /flavors/{flavor_id}``
|
||||
|
||||
2.62
|
||||
----
|
||||
|
||||
Adds ``host`` (hostname) and ``hostId`` (an obfuscated hashed host id string)
|
||||
fields to the instance action
|
||||
``GET /servers/{server_id}/os-instance-actions/{req_id}`` API. The display of
|
||||
the newly added ``host`` field will be controlled via policy rule
|
||||
``os_compute_api:os-instance-actions:events``, which is the same policy used
|
||||
for the ``events.traceback`` field. If the user is prevented by policy, only
|
||||
``hostId`` will be displayed.
|
||||
|
@ -31,7 +31,10 @@ instance_actions_policies = [
|
||||
This check is performed only after the check
|
||||
os_compute_api:os-instance-actions passes. Beginning with
|
||||
Microversion 2.51, events details are always included; traceback
|
||||
information is provided per event if policy enforcement passes.""",
|
||||
information is provided per event if policy enforcement passes.
|
||||
Beginning with Microversion 2.62, each event includes a hashed
|
||||
host identifier and, if policy enforcement passes, the name of
|
||||
the host.""",
|
||||
[
|
||||
{
|
||||
'method': 'GET',
|
||||
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"instanceAction": {
|
||||
"action": "stop",
|
||||
"instance_uuid": "%(uuid)s",
|
||||
"request_id": "%(request_id)s",
|
||||
"user_id": "%(user_id)s",
|
||||
"project_id": "%(project_id)s",
|
||||
"start_time": "%(strtime)s",
|
||||
"updated_at": "%(strtime)s",
|
||||
"message": null,
|
||||
"events": [
|
||||
{
|
||||
"event": "compute_stop_instance",
|
||||
"start_time": "%(strtime)s",
|
||||
"finish_time": "%(strtime)s",
|
||||
"result": "Success",
|
||||
"hostId": "%(event_hostId)s"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
{
|
||||
"instanceAction": {
|
||||
"action": "stop",
|
||||
"instance_uuid": "%(uuid)s",
|
||||
"request_id": "%(request_id)s",
|
||||
"user_id": "%(user_id)s",
|
||||
"project_id": "%(project_id)s",
|
||||
"start_time": "%(strtime)s",
|
||||
"updated_at": "%(strtime)s",
|
||||
"message": null,
|
||||
"events": [
|
||||
{
|
||||
"event": "compute_stop_instance",
|
||||
"start_time": "%(strtime)s",
|
||||
"finish_time": "%(strtime)s",
|
||||
"result": "Success",
|
||||
"traceback": null,
|
||||
"host": "%(event_host)s",
|
||||
"hostId": "%(event_hostId)s"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "stop",
|
||||
"instance_uuid": "%(uuid)s",
|
||||
"request_id": "%(request_id)s",
|
||||
"user_id": "%(user_id)s",
|
||||
"project_id": "%(project_id)s",
|
||||
"start_time": "%(strtime)s",
|
||||
"updated_at": "%(strtime)s",
|
||||
"message": null
|
||||
},
|
||||
{
|
||||
"action": "create",
|
||||
"instance_uuid": "%(uuid)s",
|
||||
"request_id": "%(request_id)s",
|
||||
"user_id": "%(user_id)s",
|
||||
"project_id": "%(project_id)s",
|
||||
"start_time": "%(strtime)s",
|
||||
"updated_at": "%(strtime)s",
|
||||
"message": null
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "stop",
|
||||
"instance_uuid": "%(uuid)s",
|
||||
"request_id": "%(request_id)s",
|
||||
"user_id": "%(user_id)s",
|
||||
"project_id": "%(project_id)s",
|
||||
"start_time": "%(strtime)s",
|
||||
"updated_at": "%(strtime)s",
|
||||
"message": null
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"href": "%(versioned_compute_endpoint)s/servers/%(uuid)s/os-instance-actions?limit=1&marker=%(request_id)s",
|
||||
"rel": "next"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "create",
|
||||
"instance_uuid": "%(uuid)s",
|
||||
"request_id": "%(request_id)s",
|
||||
"user_id": "%(user_id)s",
|
||||
"project_id": "%(project_id)s",
|
||||
"start_time": "%(strtime)s",
|
||||
"updated_at": "%(strtime)s",
|
||||
"message": null
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
{
|
||||
"instanceActions": [
|
||||
{
|
||||
"action": "stop",
|
||||
"instance_uuid": "%(uuid)s",
|
||||
"request_id": "%(request_id)s",
|
||||
"user_id": "%(user_id)s",
|
||||
"project_id": "%(project_id)s",
|
||||
"start_time": "%(strtime)s",
|
||||
"updated_at": "%(strtime)s",
|
||||
"message": null
|
||||
}
|
||||
]
|
||||
}
|
@ -122,3 +122,20 @@ class ServerActionsV258SampleJsonTest(ServerActionsV251AdminSampleJsonTest):
|
||||
|
||||
class ServerActionsV258NonAdminSampleJsonTest(ServerActionsV258SampleJsonTest):
|
||||
ADMIN_API = False
|
||||
|
||||
|
||||
class ServerActionsV262SampleJsonTest(ServerActionsV258SampleJsonTest):
|
||||
microversion = '2.62'
|
||||
scenarios = [('v2_62', {'api_major_version': 'v2.1'})]
|
||||
|
||||
def _get_subs(self):
|
||||
return {
|
||||
'uuid': self.uuid,
|
||||
'project_id': self.action_stop['project_id'],
|
||||
'event_host': r'\w+',
|
||||
'event_hostId': '[a-f0-9]+'
|
||||
}
|
||||
|
||||
|
||||
class ServerActionsV262NonAdminSampleJsonTest(ServerActionsV262SampleJsonTest):
|
||||
ADMIN_API = False
|
||||
|
@ -38,7 +38,8 @@ FAKE_EVENT_ID = fake_server_actions.FAKE_ACTION_ID1
|
||||
FAKE_REQUEST_NOTFOUND_ID = 'req-' + uuids.req_not_found
|
||||
|
||||
|
||||
def format_action(action, expect_traceback=True):
|
||||
def format_action(action, expect_traceback=True, expect_host=False,
|
||||
expect_hostId=False):
|
||||
'''Remove keys that aren't serialized.'''
|
||||
to_delete = ('id', 'finish_time', 'created_at', 'updated_at', 'deleted_at',
|
||||
'deleted')
|
||||
@ -49,11 +50,14 @@ def format_action(action, expect_traceback=True):
|
||||
# NOTE(danms): Without WSGI above us, these will be just stringified
|
||||
action['start_time'] = str(action['start_time'].replace(tzinfo=None))
|
||||
for event in action.get('events', []):
|
||||
format_event(event, expect_traceback)
|
||||
format_event(event, action.get('project_id'),
|
||||
expect_traceback=expect_traceback,
|
||||
expect_host=expect_host, expect_hostId=expect_hostId)
|
||||
return action
|
||||
|
||||
|
||||
def format_event(event, expect_traceback=True, expect_host=False):
|
||||
def format_event(event, project_id, expect_traceback=True, expect_host=False,
|
||||
expect_hostId=False):
|
||||
'''Remove keys that aren't serialized.'''
|
||||
to_delete = ['id', 'created_at', 'updated_at', 'deleted_at', 'deleted',
|
||||
'action_id']
|
||||
@ -61,6 +65,8 @@ def format_event(event, expect_traceback=True, expect_host=False):
|
||||
to_delete.append('traceback')
|
||||
if not expect_host:
|
||||
to_delete.append('host')
|
||||
if not expect_hostId:
|
||||
to_delete.append('hostId')
|
||||
for key in to_delete:
|
||||
if key in event:
|
||||
del(event[key])
|
||||
@ -116,6 +122,8 @@ class InstanceActionsTestV21(test.NoDBTestCase):
|
||||
instance_actions = instance_actions_v21
|
||||
wsgi_api_version = os_wsgi.DEFAULT_API_VERSION
|
||||
expect_events_non_admin = False
|
||||
expect_event_hostId = False
|
||||
expect_event_host = False
|
||||
|
||||
def fake_get(self, context, instance_uuid, expected_attrs=None):
|
||||
return objects.Instance(uuid=instance_uuid)
|
||||
@ -181,8 +189,12 @@ class InstanceActionsTestV21(test.NoDBTestCase):
|
||||
fake_action = self.fake_actions[FAKE_UUID][FAKE_REQUEST_ID]
|
||||
fake_events = self.fake_events[fake_action['id']]
|
||||
fake_action['events'] = fake_events
|
||||
self.assertEqual(format_action(fake_action),
|
||||
format_action(res_dict['instanceAction']))
|
||||
self.assertEqual(format_action(fake_action,
|
||||
expect_host=self.expect_event_host,
|
||||
expect_hostId=self.expect_event_hostId),
|
||||
format_action(res_dict['instanceAction'],
|
||||
expect_host=self.expect_event_host,
|
||||
expect_hostId=self.expect_event_hostId))
|
||||
|
||||
def test_get_action_with_events_not_allowed(self):
|
||||
def fake_get_action(context, uuid, request_id):
|
||||
@ -201,10 +213,16 @@ class InstanceActionsTestV21(test.NoDBTestCase):
|
||||
if self.expect_events_non_admin:
|
||||
fake_event = fake_server_actions.FAKE_EVENTS[FAKE_EVENT_ID]
|
||||
fake_action['events'] = copy.deepcopy(fake_event)
|
||||
# By default, non-admins are not allowed to see traceback details.
|
||||
self.assertEqual(format_action(fake_action, expect_traceback=False),
|
||||
# By default, non-admins are not allowed to see traceback details
|
||||
# and event host.
|
||||
self.assertEqual(format_action(fake_action,
|
||||
expect_traceback=False,
|
||||
expect_host=False,
|
||||
expect_hostId=self.expect_event_hostId),
|
||||
format_action(res_dict['instanceAction'],
|
||||
expect_traceback=False))
|
||||
expect_traceback=False,
|
||||
expect_host=False,
|
||||
expect_hostId=self.expect_event_hostId))
|
||||
|
||||
def test_action_not_found(self):
|
||||
def fake_no_action(context, uuid, action_id):
|
||||
@ -294,3 +312,9 @@ class InstanceActionsTestV258(InstanceActionsTestV251):
|
||||
self.controller.index, req)
|
||||
self.assertIn('Invalid input for query parameters marker',
|
||||
six.text_type(ex))
|
||||
|
||||
|
||||
class InstanceActionsTestV262(InstanceActionsTestV251):
|
||||
wsgi_api_version = "2.62"
|
||||
expect_event_hostId = True
|
||||
expect_event_host = True
|
||||
|
@ -20,6 +20,8 @@ FAKE_REQUEST_ID1 = 'req-3293a3f1-b44c-4609-b8d2-d81b105636b8'
|
||||
FAKE_REQUEST_ID2 = 'req-25517360-b757-47d3-be45-0e8d2a01b36a'
|
||||
FAKE_ACTION_ID1 = 123
|
||||
FAKE_ACTION_ID2 = 456
|
||||
FAKE_HOST_ID1 = '74824069503a752aaa3abf194f73200fcdd117ef70ab28b576e5bf7a'
|
||||
FAKE_HOST_ID2 = '858f5ed465b4967dd1306a38078e9b83b8705bdedfa7f16f898119b4'
|
||||
|
||||
FAKE_ACTIONS = {
|
||||
FAKE_UUID: {
|
||||
@ -70,7 +72,8 @@ FAKE_EVENTS = {
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
'host': 'host1'
|
||||
'host': 'host1',
|
||||
'hostId': FAKE_HOST_ID1
|
||||
},
|
||||
{'id': 2,
|
||||
'action_id': FAKE_ACTION_ID1,
|
||||
@ -85,7 +88,8 @@ FAKE_EVENTS = {
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
'host': 'host1'
|
||||
'host': 'host1',
|
||||
'hostId': FAKE_HOST_ID1
|
||||
}
|
||||
],
|
||||
FAKE_ACTION_ID2: [{'id': 3,
|
||||
@ -101,7 +105,8 @@ FAKE_EVENTS = {
|
||||
'updated_at': None,
|
||||
'deleted_at': None,
|
||||
'deleted': False,
|
||||
'host': 'host2'
|
||||
'host': 'host2',
|
||||
'hostId': FAKE_HOST_ID2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The microversion 2.62 adds ``host`` (hostname) and ``hostId`` (an
|
||||
obfuscated hashed host id string) fields to the instance action
|
||||
``GET /servers/{server_id}/os-instance-actions/{req_id}`` API. The display
|
||||
of the newly added ``host`` field will be controlled via policy rule
|
||||
``os_compute_api:os-instance-actions:events``, which is the same policy
|
||||
used for the ``events.traceback`` field. If the user is prevented by
|
||||
policy, only ``hostId`` will be displayed.
|
Loading…
x
Reference in New Issue
Block a user