template validate API controller and API handler
Change-Id: I1fd681e14eb544e7eddfe17c51c70485c05f041c
This commit is contained in:
parent
9a7fbdb4d7
commit
81e232a1af
@ -3,5 +3,6 @@
|
||||
"get resource": "role:admin",
|
||||
"list resources": "role:admin",
|
||||
"list alarms": "role:admin",
|
||||
"get rca": "role:admin"
|
||||
"get rca": "role:admin",
|
||||
"template validate": "role:admin"
|
||||
}
|
@ -38,20 +38,20 @@ class AlarmsController(RootRestController):
|
||||
enforce("list alarms", pecan.request.headers,
|
||||
pecan.request.enforcer, {})
|
||||
|
||||
LOG.info(_LI('received list alarms with vitrage id %s') %
|
||||
LOG.info(_LI('returns list alarms with vitrage id %s') %
|
||||
vitrage_id)
|
||||
|
||||
try:
|
||||
if pecan.request.cfg.api.use_mock_file:
|
||||
return self.get_mock_data('alarms.sample.json')
|
||||
else:
|
||||
return self.get_alarms(vitrage_id)
|
||||
return self._get_alarms(vitrage_id)
|
||||
except Exception as e:
|
||||
LOG.exception('failed to get alarms %s', e)
|
||||
abort(404, str(e))
|
||||
|
||||
@staticmethod
|
||||
def get_alarms(vitrage_id=None):
|
||||
def _get_alarms(vitrage_id=None):
|
||||
alarms_json = pecan.request.client.call(pecan.request.context,
|
||||
'get_alarms',
|
||||
arg=vitrage_id)
|
||||
|
@ -13,6 +13,7 @@
|
||||
from vitrage.api.controllers.v1 import alarms
|
||||
from vitrage.api.controllers.v1 import rca
|
||||
from vitrage.api.controllers.v1 import resource
|
||||
from vitrage.api.controllers.v1 import template
|
||||
from vitrage.api.controllers.v1 import topology
|
||||
|
||||
|
||||
@ -21,3 +22,4 @@ class V1Controller(object):
|
||||
resources = resource.ResourcesController()
|
||||
alarms = alarms.AlarmsController()
|
||||
rca = rca.RCAController()
|
||||
template = template.TemplateController()
|
||||
|
58
vitrage/api/controllers/v1/template.py
Normal file
58
vitrage/api/controllers/v1/template.py
Normal file
@ -0,0 +1,58 @@
|
||||
# Copyright 2016 - Nokia 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.
|
||||
import json
|
||||
import pecan
|
||||
|
||||
from oslo_log import log
|
||||
from pecan.core import abort
|
||||
|
||||
from vitrage.api.controllers.rest import RootRestController
|
||||
from vitrage.api.policy import enforce
|
||||
from vitrage.i18n import _LI
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class TemplateController(RootRestController):
|
||||
|
||||
@pecan.expose('json')
|
||||
def post(self, **kwargs):
|
||||
|
||||
LOG.info(_LI('validate template. args: %s') % kwargs)
|
||||
|
||||
enforce("template validate",
|
||||
pecan.request.headers,
|
||||
pecan.request.enforcer,
|
||||
{})
|
||||
|
||||
template_def = kwargs['template_def']
|
||||
|
||||
try:
|
||||
return self._validate(template_def)
|
||||
except Exception as e:
|
||||
LOG.exception('failed to validate template(s) %s', e)
|
||||
abort(404, str(e))
|
||||
|
||||
@staticmethod
|
||||
def _validate(template_def):
|
||||
|
||||
result_json = pecan.request.client.call(pecan.request.context,
|
||||
'validate_template',
|
||||
template_def=template_def)
|
||||
try:
|
||||
return json.loads(result_json)
|
||||
except Exception as e:
|
||||
LOG.exception('failed to open file %s ', e)
|
||||
abort(404, str(e))
|
@ -1,4 +1,4 @@
|
||||
# Copyright 2016 - Alcatel-Lucent
|
||||
# Copyright 2016 - Nokia 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
|
@ -23,6 +23,8 @@ from vitrage.datasources.nova.host import NOVA_HOST_DATASOURCE
|
||||
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
|
||||
from vitrage.datasources.nova.zone import NOVA_ZONE_DATASOURCE
|
||||
from vitrage.datasources import OPENSTACK_CLUSTER
|
||||
from vitrage.evaluator.template_validation.template_syntax_validator import \
|
||||
syntax_validation
|
||||
from vitrage.graph import create_algorithm
|
||||
from vitrage.graph import Direction
|
||||
|
||||
@ -112,7 +114,7 @@ class EntityGraphApis(object):
|
||||
root_id=root,
|
||||
depth=depth)
|
||||
|
||||
return found_graph.output_graph()
|
||||
return found_graph.json_output_graph()
|
||||
|
||||
def get_rca(self, ctx, root):
|
||||
LOG.debug("EntityGraphApis get_rca root:%s", str(root))
|
||||
@ -128,7 +130,7 @@ class EntityGraphApis(object):
|
||||
direction=Direction.OUT)
|
||||
unified_graph = found_graph_in
|
||||
unified_graph.union(found_graph_out)
|
||||
json_graph = unified_graph.output_graph(
|
||||
json_graph = unified_graph.json_output_graph(
|
||||
inspected_index=self._find_rca_index(unified_graph, root))
|
||||
return json_graph
|
||||
|
||||
@ -168,3 +170,26 @@ class EntityGraphApis(object):
|
||||
if vertex == root:
|
||||
return root_index
|
||||
return 0
|
||||
|
||||
|
||||
class TemplateApis(object):
|
||||
|
||||
def validate_template(self, ctx, template_def):
|
||||
LOG.debug("EntityGraphApis validate_template template definition:"
|
||||
"%s", str(template_def))
|
||||
|
||||
result = syntax_validation(template_def)
|
||||
|
||||
if not result.is_valid:
|
||||
return self._extract_json_result('validation failed', result)
|
||||
|
||||
return self._extract_json_result('validation OK', result)
|
||||
|
||||
@staticmethod
|
||||
def _extract_json_result(status, result):
|
||||
|
||||
return json.dumps({
|
||||
'status': status,
|
||||
'description': result.description,
|
||||
'message': str(result.comment)
|
||||
})
|
@ -17,7 +17,8 @@ from oslo_log import log
|
||||
import oslo_messaging
|
||||
from oslo_service import service as os_service
|
||||
|
||||
from vitrage.entity_graph.api_handler.entity_graph_api import EntityGraphApis
|
||||
from vitrage.api_handler.entity_graph_api import EntityGraphApis
|
||||
from vitrage.api_handler.entity_graph_api import TemplateApis
|
||||
from vitrage import messaging
|
||||
from vitrage import rpc as vitrage_rpc
|
||||
|
||||
@ -43,7 +44,7 @@ class VitrageApiHandlerService(os_service.Service):
|
||||
target = oslo_messaging.Target(topic=self.conf.rpc_topic,
|
||||
server=rabbit_hosts)
|
||||
|
||||
endpoints = [EntityGraphApis(self.entity_graph), ]
|
||||
endpoints = [EntityGraphApis(self.entity_graph), TemplateApis()]
|
||||
|
||||
server = vitrage_rpc.get_server(target, endpoints, transport)
|
||||
|
@ -19,10 +19,10 @@ import sys
|
||||
|
||||
from oslo_service import service as os_service
|
||||
|
||||
from vitrage.api_handler import service as api_handler_svc
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.datasources import launcher as datasource_launcher
|
||||
from vitrage.datasources import OPENSTACK_CLUSTER
|
||||
from vitrage.entity_graph.api_handler import service as api_handler_svc
|
||||
from vitrage.entity_graph.consistency import service as consistency_svc
|
||||
from vitrage.entity_graph.initialization_status import InitializationStatus
|
||||
from vitrage.entity_graph.processor import entity_graph
|
||||
|
@ -18,49 +18,49 @@ from vitrage.evaluator.actions.base import action_types
|
||||
error_msgs = {
|
||||
|
||||
# General 1-19
|
||||
1: '"template_id" field contains incorrect string value.',
|
||||
1: 'template_id field contains incorrect string value.',
|
||||
2: 'Duplicate template_id definition.',
|
||||
3: '"template_id" does not appear in the definition block.',
|
||||
3: 'template_id does not appear in the definition block.',
|
||||
|
||||
# definitions section 20-39
|
||||
20: 'definitions section must contain "entities" field.',
|
||||
21: '"definitions" section is a mandatory section.',
|
||||
20: 'definitions section must contain entities field.',
|
||||
21: 'definitions section is a mandatory section.',
|
||||
|
||||
# Entities syntax error messages 40-59
|
||||
41: 'Entity definition must contain "template_id" field.',
|
||||
42: 'Entity definition must contain "category" field.',
|
||||
41: 'Entity definition must contain template_id field.',
|
||||
42: 'Entity definition must contain category field.',
|
||||
43: 'At least one entity must be defined.',
|
||||
45: 'Invalid entity category. Category must be from types: '
|
||||
'%s' % entities_categories,
|
||||
46: 'Entity field is required.',
|
||||
|
||||
# metadata section syntax error messages 60-79
|
||||
60: 'metadata section must contain "id" field.',
|
||||
62: '"metadata" is a mandatory section.',
|
||||
60: 'metadata section must contain id field.',
|
||||
62: 'metadata is a mandatory section.',
|
||||
|
||||
# scenarios section 80-99
|
||||
80: '"scenarios" is a mandatory section].',
|
||||
80: 'scenarios is a mandatory section].',
|
||||
81: 'At least one scenario must be defined.',
|
||||
82: 'scenario field is required.',
|
||||
83: 'Entity definition must contain "condition" field.',
|
||||
84: 'Entity definition must contain "actions" field.',
|
||||
83: 'Entity definition must contain condition field.',
|
||||
84: 'Entity definition must contain actions field.',
|
||||
85: 'Failed to convert condition.',
|
||||
|
||||
# relationships syntax error messages 100-119
|
||||
100: 'Invalid relation type. Relation type must be from types: '
|
||||
'%s' % edge_labels,
|
||||
101: 'Relationship field is required.',
|
||||
102: 'Relationship definition must contain "source" field.',
|
||||
103: 'Relationship definition must contain "target" field.',
|
||||
104: 'Relationship definition must contain "template_id" field.',
|
||||
102: 'Relationship definition must contain source field.',
|
||||
103: 'Relationship definition must contain target field.',
|
||||
104: 'Relationship definition must contain template_id field.',
|
||||
|
||||
# actions syntax error messages 120-139
|
||||
120: 'Invalid action type. Action type must be from types: '
|
||||
'%s' % action_types,
|
||||
121: 'At least one action must be defined.',
|
||||
122: 'Action field is required.',
|
||||
123: 'Relationship definition must contain "action_type" field.',
|
||||
124: 'Relationship definition must contain "action_target" field.',
|
||||
123: 'Relationship definition must contain action_type field.',
|
||||
124: 'Relationship definition must contain action_target field.',
|
||||
125: 'raise_alarm action must contain alarm_name field in properties '
|
||||
'block.',
|
||||
126: 'raise_alarm action must contain severity field in properties block.',
|
||||
|
@ -323,7 +323,7 @@ class Graph(object):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def output_graph(self, **kwargs):
|
||||
def json_output_graph(self, **kwargs):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@ -260,7 +260,7 @@ class NXGraph(Graph):
|
||||
nodes.append((node_id_to_test, node_data))
|
||||
return nodes, edges_filtered2
|
||||
|
||||
def output_graph(self, **kwargs):
|
||||
def json_output_graph(self, **kwargs):
|
||||
node_link_data = json_graph.node_link_data(self._g)
|
||||
node_link_data.update(kwargs)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user