| #!/usr/bin/env python |
| # |
| # Copyright 2017 the original author or authors. |
| # |
| # 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. |
| # |
| from lxml import etree |
| import structlog |
| from netconf.nc_rpc.rpc import Rpc |
| import netconf.nc_common.error as ncerror |
| from netconf.constants import Constants as C |
| from netconf.nc_common.utils import qmap |
| from twisted.internet.defer import inlineCallbacks, returnValue |
| |
| log = structlog.get_logger() |
| |
| class GetSchema(Rpc): |
| def __init__(self, request, request_xml, grpc_client, session, capabilities): |
| super(GetSchema, self).__init__(request, request_xml, grpc_client, session) |
| self.capabilities = capabilities |
| # specific schema parsing required |
| self.parse_schema_request(request_xml) |
| self._validate_parameters() |
| |
| @inlineCallbacks |
| def execute(self): |
| if self.rpc_response.is_error: |
| returnValue(self.rpc_response) |
| |
| log.info('get-schema-request', session=self.session.session_id, |
| request=self.request) |
| |
| # Get the yang schema content |
| # TODO: Use version as well |
| content = yield self.capabilities.get_schema_content(self.request[ |
| 'identifier']) |
| if not content: |
| self.rpc_response.is_error = True |
| self.rpc_response.node = ncerror.BadMsg(self.request_xml) |
| returnValue(self.rpc_response) |
| |
| self.rpc_response.node = yield self.create_xml_response(content) |
| |
| self.rpc_response.is_error = False |
| |
| returnValue(self.rpc_response) |
| |
| def _validate_parameters(self): |
| log.info('validate-parameters', session=self.session.session_id) |
| # Validate the GET command |
| if self.request: |
| try: |
| if self.request['command'] != 'get-schema' or \ |
| not self.request.has_key('identifier') or \ |
| not self.request.has_key('format') or \ |
| not self.request.has_key('version'): |
| self.rpc_response.is_error = True |
| self.rpc_response.node = ncerror.BadMsg(self.request_xml) |
| return |
| |
| if self.request.has_key('filter'): |
| if not self.request.has_key('class'): |
| self.rpc_response.is_error = True |
| self.rpc_response.node = ncerror.BadMsg( |
| self.request_xml) |
| return |
| |
| # Verify that the requested schema exists |
| if not self.capabilities.is_schema_supported(self.request[ |
| 'identifier']) \ |
| or self.request['format'] != 'yang' : |
| self.rpc_response.is_error = True |
| self.rpc_response.node = ncerror.BadMsg(self.request_xml) |
| return |
| |
| except Exception as e: |
| self.rpc_response.is_error = True |
| self.rpc_response.node = ncerror.BadMsg(self.request) |
| return |
| |
| # Parse context-specific parameters |
| def parse_schema_request(self, node): |
| if not len(node): |
| return |
| schema_node = node.find(''.join([qmap(C.NCM), 'get-schema'])) |
| if schema_node is not None: |
| for item in ['identifier', 'version', 'format']: |
| elem = schema_node.find(''.join([qmap(C.NCM), item])) |
| if elem is not None: |
| self.request[item] = elem.text |
| |
| def create_xml_response(self, content): |
| ns = {} |
| ns['xmlns'] = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring" |
| |
| elem = etree.Element('data', attrib=ns) |
| elem.text = unicode(content, "utf-8") |
| return elem |