diff --git a/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json b/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json index ff493e7aa5de..bc4363746e2f 100644 --- a/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json +++ b/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json @@ -1,25 +1,25 @@ { "instance_usage_audit_logs": { "hosts_not_run": [ - "samplehost3" + "329fa448-f6bb-4e72-b954-faa66c30d4fa" ], "log": { - "samplehost0": { + "2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": { "errors": 1, "instances": 1, - "message": "Instance usage audit ran for host samplehost0, 1 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2c8ef37b-f0cc-4a9e-92a6-32df0095cb12, 1 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost1": { + "60dbe74d-0cf3-419b-83f5-407e4b78c7b4": { "errors": 1, "instances": 2, - "message": "Instance usage audit ran for host samplehost1, 2 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 60dbe74d-0cf3-419b-83f5-407e4b78c7b4, 2 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost2": { + "2aa90c00-23eb-4da6-aff9-eda66bb56182": { "errors": 1, "instances": 3, - "message": "Instance usage audit ran for host samplehost2, 3 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2aa90c00-23eb-4da6-aff9-eda66bb56182, 3 instances in 0.01 seconds.", "state": "DONE" } }, diff --git a/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json b/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json index e7faabef4ff6..35b0c10aea32 100644 --- a/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json +++ b/doc/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json @@ -1,25 +1,25 @@ { "instance_usage_audit_log": { "hosts_not_run": [ - "samplehost3" + "329fa448-f6bb-4e72-b954-faa66c30d4fa" ], "log": { - "samplehost0": { + "2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": { "errors": 1, "instances": 1, - "message": "Instance usage audit ran for host samplehost0, 1 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2c8ef37b-f0cc-4a9e-92a6-32df0095cb12, 1 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost1": { + "60dbe74d-0cf3-419b-83f5-407e4b78c7b4": { "errors": 1, "instances": 2, - "message": "Instance usage audit ran for host samplehost1, 2 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 60dbe74d-0cf3-419b-83f5-407e4b78c7b4, 2 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost2": { + "2aa90c00-23eb-4da6-aff9-eda66bb56182": { "errors": 1, "instances": 3, - "message": "Instance usage audit ran for host samplehost2, 3 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2aa90c00-23eb-4da6-aff9-eda66bb56182, 3 instances in 0.01 seconds.", "state": "DONE" } }, diff --git a/nova/api/openstack/compute/instance_usage_audit_log.py b/nova/api/openstack/compute/instance_usage_audit_log.py index 261235560c52..17715eae2a28 100644 --- a/nova/api/openstack/compute/instance_usage_audit_log.py +++ b/nova/api/openstack/compute/instance_usage_audit_log.py @@ -27,6 +27,7 @@ from nova.policies import instance_usage_audit_log as iual_policies from nova import utils +@validation.validated class InstanceUsageAuditLogController(wsgi.Controller): def __init__(self): @@ -35,6 +36,7 @@ class InstanceUsageAuditLogController(wsgi.Controller): @wsgi.expected_errors(()) @validation.query_schema(schema.index_query) + @validation.response_body_schema(schema.index_response) def index(self, req): context = req.environ['nova.context'] context.can(iual_policies.BASE_POLICY_NAME % 'list', target={}) @@ -43,16 +45,17 @@ class InstanceUsageAuditLogController(wsgi.Controller): @wsgi.expected_errors(400) @validation.query_schema(schema.show_query) + @validation.response_body_schema(schema.show_response) def show(self, req, id): context = req.environ['nova.context'] context.can(iual_policies.BASE_POLICY_NAME % 'show', target={}) try: if '.' in id: - before_date = datetime.datetime.strptime(str(id), - "%Y-%m-%d %H:%M:%S.%f") + before_date = datetime.datetime.strptime( + str(id), "%Y-%m-%d %H:%M:%S.%f") else: - before_date = datetime.datetime.strptime(str(id), - "%Y-%m-%d %H:%M:%S") + before_date = datetime.datetime.strptime( + str(id), "%Y-%m-%d %H:%M:%S") except ValueError: msg = _("Invalid timestamp for date %s") % id raise webob.exc.HTTPBadRequest(explanation=msg) diff --git a/nova/api/openstack/compute/schemas/instance_usage_audit_log.py b/nova/api/openstack/compute/schemas/instance_usage_audit_log.py index bc50a06d845c..e15e35cc93f1 100644 --- a/nova/api/openstack/compute/schemas/instance_usage_audit_log.py +++ b/nova/api/openstack/compute/schemas/instance_usage_audit_log.py @@ -21,3 +21,66 @@ show_query = { 'properties': {}, 'additionalProperties': True, } + +_instance_usage_audit_log_response = { + 'type': 'object', + 'properties': { + 'hosts_not_run': { + 'type': 'array', + 'items': {'type': 'string', 'format': 'uuid'}, + }, + 'log': { + 'type': 'object', + 'additionalProperties': { + 'instances': {'type': 'integer', 'minimum': 0}, + 'errors': {'type': 'integer', 'minimum': 0}, + 'message': {'type': 'string'}, + 'state': {'type': 'string', 'enum': ['RUNNING', 'DONE']}, + }, + }, + 'num_hosts': {'type': 'integer', 'minimum': 0}, + 'num_hosts_done': {'type': 'integer', 'minimum': 0}, + 'num_hosts_not_run': {'type': 'integer', 'minimum': 0}, + 'num_hosts_running': {'type': 'integer', 'minimum': 0}, + 'overall_status': {'type': 'string'}, + 'period_beginning': {'type': 'string', 'format': 'date-time'}, + 'period_ending': {'type': 'string', 'format': 'date-time'}, + 'total_errors': {'type': 'integer', 'minimum': 0}, + 'total_instances': {'type': 'integer', 'minimum': 0}, + }, + 'required': [ + 'hosts_not_run', + 'log', + 'num_hosts', + 'num_hosts_done', + 'num_hosts_not_run', + 'num_hosts_running', + 'overall_status', + 'period_beginning', + 'period_ending', + 'total_errors', + 'total_instances', + ], + 'additionalProperties': False, +} + +index_response = { + 'type': 'object', + 'properties': { + # NOTE(stephenfin): Yes, this is correct: the index response is + # identical to the show response. In fact, the show response is really + # the index response with a 'before' filter and a singular key + 'instance_usage_audit_logs': _instance_usage_audit_log_response, + }, + 'required': ['instance_usage_audit_logs'], + 'additionalProperties': False, +} + +show_response = { + 'type': 'object', + 'properties': { + 'instance_usage_audit_log': _instance_usage_audit_log_response, + }, + 'required': ['instance_usage_audit_log'], + 'additionalProperties': False, +} diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json.tpl index ff493e7aa5de..bc4363746e2f 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-index-get-resp.json.tpl @@ -1,25 +1,25 @@ { "instance_usage_audit_logs": { "hosts_not_run": [ - "samplehost3" + "329fa448-f6bb-4e72-b954-faa66c30d4fa" ], "log": { - "samplehost0": { + "2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": { "errors": 1, "instances": 1, - "message": "Instance usage audit ran for host samplehost0, 1 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2c8ef37b-f0cc-4a9e-92a6-32df0095cb12, 1 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost1": { + "60dbe74d-0cf3-419b-83f5-407e4b78c7b4": { "errors": 1, "instances": 2, - "message": "Instance usage audit ran for host samplehost1, 2 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 60dbe74d-0cf3-419b-83f5-407e4b78c7b4, 2 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost2": { + "2aa90c00-23eb-4da6-aff9-eda66bb56182": { "errors": 1, "instances": 3, - "message": "Instance usage audit ran for host samplehost2, 3 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2aa90c00-23eb-4da6-aff9-eda66bb56182, 3 instances in 0.01 seconds.", "state": "DONE" } }, diff --git a/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json.tpl b/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json.tpl index e7faabef4ff6..35b0c10aea32 100644 --- a/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json.tpl +++ b/nova/tests/functional/api_sample_tests/api_samples/os-instance-usage-audit-log/inst-usage-audit-log-show-get-resp.json.tpl @@ -1,25 +1,25 @@ { "instance_usage_audit_log": { "hosts_not_run": [ - "samplehost3" + "329fa448-f6bb-4e72-b954-faa66c30d4fa" ], "log": { - "samplehost0": { + "2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": { "errors": 1, "instances": 1, - "message": "Instance usage audit ran for host samplehost0, 1 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2c8ef37b-f0cc-4a9e-92a6-32df0095cb12, 1 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost1": { + "60dbe74d-0cf3-419b-83f5-407e4b78c7b4": { "errors": 1, "instances": 2, - "message": "Instance usage audit ran for host samplehost1, 2 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 60dbe74d-0cf3-419b-83f5-407e4b78c7b4, 2 instances in 0.01 seconds.", "state": "DONE" }, - "samplehost2": { + "2aa90c00-23eb-4da6-aff9-eda66bb56182": { "errors": 1, "instances": 3, - "message": "Instance usage audit ran for host samplehost2, 3 instances in 0.01 seconds.", + "message": "Instance usage audit ran for host 2aa90c00-23eb-4da6-aff9-eda66bb56182, 3 instances in 0.01 seconds.", "state": "DONE" } }, diff --git a/nova/tests/functional/api_sample_tests/test_instance_usage_audit_log.py b/nova/tests/functional/api_sample_tests/test_instance_usage_audit_log.py index 03b1e9231da5..28291e807e9c 100644 --- a/nova/tests/functional/api_sample_tests/test_instance_usage_audit_log.py +++ b/nova/tests/functional/api_sample_tests/test_instance_usage_audit_log.py @@ -28,13 +28,16 @@ class InstanceUsageAuditLogJsonTest(api_sample_base.ApiSampleTestBaseV21): def setUp(self): super(InstanceUsageAuditLogJsonTest, self).setUp() + hosts = ( + '2c8ef37b-f0cc-4a9e-92a6-32df0095cb12', + '60dbe74d-0cf3-419b-83f5-407e4b78c7b4', + '2aa90c00-23eb-4da6-aff9-eda66bb56182', + '329fa448-f6bb-4e72-b954-faa66c30d4fa', + ) + def fake_service_get_all(self, context, filters=None, set_zones=False): - services = [objects.Service(host='samplehost0'), - objects.Service(host='samplehost1'), - objects.Service(host='samplehost2'), - objects.Service(host='samplehost3')] - return services + return [objects.Service(host=host) for host in hosts] def fake_utcnow(with_timezone=False): # It is not UTC time, but no effect for testing @@ -46,7 +49,7 @@ class InstanceUsageAuditLogJsonTest(api_sample_base.ApiSampleTestBaseV21): fake_service_get_all) for i in range(0, 3): - self._create_task_log('samplehost%d' % i, i + 1) + self._create_task_log(hosts[i], i + 1) def _create_task_log(self, host, num_instances): task_log = objects.TaskLog(context.get_admin_context())