Merge "api: Add response body schemas for server usage audit log APIs"
This commit is contained in:
@@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"instance_usage_audit_logs": {
|
"instance_usage_audit_logs": {
|
||||||
"hosts_not_run": [
|
"hosts_not_run": [
|
||||||
"samplehost3"
|
"329fa448-f6bb-4e72-b954-faa66c30d4fa"
|
||||||
],
|
],
|
||||||
"log": {
|
"log": {
|
||||||
"samplehost0": {
|
"2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost1": {
|
"60dbe74d-0cf3-419b-83f5-407e4b78c7b4": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 2,
|
"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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost2": {
|
"2aa90c00-23eb-4da6-aff9-eda66bb56182": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 3,
|
"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"
|
"state": "DONE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"instance_usage_audit_log": {
|
"instance_usage_audit_log": {
|
||||||
"hosts_not_run": [
|
"hosts_not_run": [
|
||||||
"samplehost3"
|
"329fa448-f6bb-4e72-b954-faa66c30d4fa"
|
||||||
],
|
],
|
||||||
"log": {
|
"log": {
|
||||||
"samplehost0": {
|
"2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost1": {
|
"60dbe74d-0cf3-419b-83f5-407e4b78c7b4": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 2,
|
"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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost2": {
|
"2aa90c00-23eb-4da6-aff9-eda66bb56182": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 3,
|
"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"
|
"state": "DONE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from nova.policies import instance_usage_audit_log as iual_policies
|
|||||||
from nova import utils
|
from nova import utils
|
||||||
|
|
||||||
|
|
||||||
|
@validation.validated
|
||||||
class InstanceUsageAuditLogController(wsgi.Controller):
|
class InstanceUsageAuditLogController(wsgi.Controller):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -35,6 +36,7 @@ class InstanceUsageAuditLogController(wsgi.Controller):
|
|||||||
|
|
||||||
@wsgi.expected_errors(())
|
@wsgi.expected_errors(())
|
||||||
@validation.query_schema(schema.index_query)
|
@validation.query_schema(schema.index_query)
|
||||||
|
@validation.response_body_schema(schema.index_response)
|
||||||
def index(self, req):
|
def index(self, req):
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
context.can(iual_policies.BASE_POLICY_NAME % 'list', target={})
|
context.can(iual_policies.BASE_POLICY_NAME % 'list', target={})
|
||||||
@@ -43,16 +45,17 @@ class InstanceUsageAuditLogController(wsgi.Controller):
|
|||||||
|
|
||||||
@wsgi.expected_errors(400)
|
@wsgi.expected_errors(400)
|
||||||
@validation.query_schema(schema.show_query)
|
@validation.query_schema(schema.show_query)
|
||||||
|
@validation.response_body_schema(schema.show_response)
|
||||||
def show(self, req, id):
|
def show(self, req, id):
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
context.can(iual_policies.BASE_POLICY_NAME % 'show', target={})
|
context.can(iual_policies.BASE_POLICY_NAME % 'show', target={})
|
||||||
try:
|
try:
|
||||||
if '.' in id:
|
if '.' in id:
|
||||||
before_date = datetime.datetime.strptime(str(id),
|
before_date = datetime.datetime.strptime(
|
||||||
"%Y-%m-%d %H:%M:%S.%f")
|
str(id), "%Y-%m-%d %H:%M:%S.%f")
|
||||||
else:
|
else:
|
||||||
before_date = datetime.datetime.strptime(str(id),
|
before_date = datetime.datetime.strptime(
|
||||||
"%Y-%m-%d %H:%M:%S")
|
str(id), "%Y-%m-%d %H:%M:%S")
|
||||||
except ValueError:
|
except ValueError:
|
||||||
msg = _("Invalid timestamp for date %s") % id
|
msg = _("Invalid timestamp for date %s") % id
|
||||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
|
|||||||
@@ -21,3 +21,66 @@ show_query = {
|
|||||||
'properties': {},
|
'properties': {},
|
||||||
'additionalProperties': True,
|
'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,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"instance_usage_audit_logs": {
|
"instance_usage_audit_logs": {
|
||||||
"hosts_not_run": [
|
"hosts_not_run": [
|
||||||
"samplehost3"
|
"329fa448-f6bb-4e72-b954-faa66c30d4fa"
|
||||||
],
|
],
|
||||||
"log": {
|
"log": {
|
||||||
"samplehost0": {
|
"2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost1": {
|
"60dbe74d-0cf3-419b-83f5-407e4b78c7b4": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 2,
|
"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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost2": {
|
"2aa90c00-23eb-4da6-aff9-eda66bb56182": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 3,
|
"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"
|
"state": "DONE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"instance_usage_audit_log": {
|
"instance_usage_audit_log": {
|
||||||
"hosts_not_run": [
|
"hosts_not_run": [
|
||||||
"samplehost3"
|
"329fa448-f6bb-4e72-b954-faa66c30d4fa"
|
||||||
],
|
],
|
||||||
"log": {
|
"log": {
|
||||||
"samplehost0": {
|
"2c8ef37b-f0cc-4a9e-92a6-32df0095cb12": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost1": {
|
"60dbe74d-0cf3-419b-83f5-407e4b78c7b4": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 2,
|
"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"
|
"state": "DONE"
|
||||||
},
|
},
|
||||||
"samplehost2": {
|
"2aa90c00-23eb-4da6-aff9-eda66bb56182": {
|
||||||
"errors": 1,
|
"errors": 1,
|
||||||
"instances": 3,
|
"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"
|
"state": "DONE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -28,13 +28,16 @@ class InstanceUsageAuditLogJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(InstanceUsageAuditLogJsonTest, self).setUp()
|
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,
|
def fake_service_get_all(self, context,
|
||||||
filters=None, set_zones=False):
|
filters=None, set_zones=False):
|
||||||
services = [objects.Service(host='samplehost0'),
|
return [objects.Service(host=host) for host in hosts]
|
||||||
objects.Service(host='samplehost1'),
|
|
||||||
objects.Service(host='samplehost2'),
|
|
||||||
objects.Service(host='samplehost3')]
|
|
||||||
return services
|
|
||||||
|
|
||||||
def fake_utcnow(with_timezone=False):
|
def fake_utcnow(with_timezone=False):
|
||||||
# It is not UTC time, but no effect for testing
|
# It is not UTC time, but no effect for testing
|
||||||
@@ -46,7 +49,7 @@ class InstanceUsageAuditLogJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
|||||||
fake_service_get_all)
|
fake_service_get_all)
|
||||||
|
|
||||||
for i in range(0, 3):
|
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):
|
def _create_task_log(self, host, num_instances):
|
||||||
task_log = objects.TaskLog(context.get_admin_context())
|
task_log = objects.TaskLog(context.get_admin_context())
|
||||||
|
|||||||
Reference in New Issue
Block a user