Netconf Plugin
cloudify-netconf-plugin
Cloudify plugin for serializing TOSCA node templates to netconf configuration.
Features
Full support for:
- Both version of netconf protocol from rfc6242.
- Ssh based communication
Partial support (only in use case of DSL validation):
- validation of complicated types with restriction for type of values (length, regexp and etc.)
- validation of type element in list (unsupported list of some types)
- validation of enumerations in value and in xml node name
Not supported:
- Conditional statements with dependencies capabilities available on hardware level,
- Can be described only input structures for netconf, output(received structures from netconf) does not validated and not described in yaml blueprints.
- Complicated structures with list of types can be described only as static(not dynamic) in sophisticated cases
- Case when we have to different structures by some condition, like we send configuration that in case dhcp - contain only flag that we have dhcp configuration, otherwise we have full structures that have described static connection. So if in description we have both fields, in first case we send empty values, so we need to have 2 node types/configurations for dhcp and for static
For check generation:
* install tools/setup.py and yttc from https://github.com/cloudify-cosmo/yttc
* xml to yaml: netconfxml2yaml.py cloudify-netconf-plugin/tools/examples/rpc.xml
* yaml to xml: yaml2netconfxml.py cloudify-netconf-plugin/tools/examples/rpc.yaml
* generate parent yaml blueprint for include:
cd tools/examples
yttc turing-machine.yang
Vyatta example is valid only for Brocade Vyatta Network OS 4.1 R2 and before run vyatta blueprint run as root on router: * cd /usr/share/doc/openvpn/examples/sample-keys/ * bash gen-sample-keys.sh
Script name can be different and related to Brocade vRouter version.
Authentication
Each node template, has a netconf_auth
property which stores your account credentials. Use an intrinsic function to assign these to the values of secrets](/working_with/manager/using-secrets/) in your manager.
some-implementation:
type: cloudify.netconf.nodes.xml_rpc
properties:
netconf_auth:
user: { get_secret: device_user }
password: { get_secret: device_password }
ip: { get_secret: list_of_fallback_ips }
key_content: { get_secret: private_key_content }
port: { get_secret: device_port }
Note Types
cloudify.netconf.nodes.xml_rpc
Properties
netconf_auth
: A dictionary containing these keys:user
: Username on the device.password
: The password ofuser
. Optional.ip
: The IP or list of fallback IPs for the device.key_content
: The content of the private key.port
: The device port. Default is830
.store_logs
: Store all communication logs. Default isfalse
.
metadata
: List of namespaces and capabilities.Default:
xmlns: # try to use this value of namespace as default _: urn:ietf:params:xml:ns:netconf:base:1.0 capabilities: {}
base_xmlns
: System xml namespaces. Please do not override.rfc6020@get
: Templates for rpc calls.rfc6020@get-config
: Templates for rpc calls.rfc6020@edit-config
: Templates for rpc calls.rfc6020@copy-config
: Templates for rpc calls.rfc6020@delete-config
: Templates for rpc calls.rfc6020@lock
: Templates for rpc calls.rfc6020@unlock
: Templates for rpc calls.rfc6020@close-session
: Templates for rpc calls.rfc6020@kill-session
: Templates for rpc calls.
Example
node_templates:
some-implementation:
type: cloudify.netconf.nodes.xml_rpc
properties:
netconf_auth:
user: <user on device>
password: <password on device, optional>
ip: <ip for device or list of ip's if have failback ip's>
key_content: <private key content>
port: <port for device, optional by default 830>
store_logs: <store all communication logs, optional by default false>
metadata:
dsdl:
<optional dsdl generated by pyang>
xmlns:
_: <default namespace>
capabilities:
<list of capabilities, optional>
interfaces:
cloudify.interfaces.lifecycle:
create: // can be create / configure / start / stop / delete
inputs:
lock:
<list databased for lock, optional>
back_database: <datebase to copy, optional>
front_database: <database for copy, optional>
strict_check: <ignore not critical errors in xml, optional>
calls:
- action: <action name for netconf>
validate_xml: <validate by dsdl, optional by default true>
payload:
<dict for put to payload>
save_to: <field name for save to runtime properties, optional>
deep_error_check: <look deeply for errors, optional by default false>
xml command list file part (template file)
<?xml version='1.0' encoding='UTF-8'?>
<rfc6020:rpc xmlns:rfc6020="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" rfc6020:message-id="1001">
<rpc-command-one/>
</rfc6020:rpc>]]>]]>
<?xml version='1.0' encoding='UTF-8'?>
<rfc6020:rpc xmlns:rfc6020="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm" rfc6020:message-id="1002">
<rpc-command-two>
{{ some_param_name }}
</rpc-command-two>
</rfc6020:rpc>]]>]]>
Another Example
node_templates:
some-implementation:
type: cloudify.netconf.nodes.xml_rpc
properties:
netconf_auth:
user: <user on device>
password: <password on device, optional>
ip: <ip for device>
key_content: <private key content>
port: <port for device, optional by default 830>
metadata:
xmlns:
_: <default namespace>
capabilities:
<list of capabilities, optional>
interfaces:
cloudify.interfaces.lifecycle:
create: // can be create / configure / start / stop / delete
inputs:
strict_check: <ignore not critical errors in xml, optional>
deep_error_check: <look deeply for errors, optional by default false>
template: <template file name>
params: <dict params for template, optional>
some_param_name: some param name
cloudify.netconf.translator.xml2netconf
Save a configuration to runtime properties.
Example
node_templates:
some-implementation:
type: cloudify.netconf.translator.xml2netconf
interfaces:
cloudify.interfaces.lifecycle:
create:
inputs:
# list predifined namespaces, please put all namespases
# from xmls, if you want reuse
xmlns:
some: some_ns
# list xml for translate and reuse
xmls:
- save_to: some_name_in_runtime_properties
raw: >
<nc_ns:rpc xmlns:nc_ns="urn:ietf:params:xml:ns:netconf:base:1.0">
<nc_ns:get-config>
<nc_ns:source>
<nc_ns:running/>
</nc_ns:source>
</nc_ns:get-config>
</nc_ns:rpc>
````
_Note: As separator between commands must be used ```]]>]]>```__
#### tags name conversions logic:
* ```a``` -> tag with name "a" and namespaces will be same as parent
* ```a@b``` -> tag with name "b" and namespace a
* ```_@@a``` -> attribute with name a and namespace will be same as parent
* ```_@a@b``` -> attribute with name b and namespace will be a
* ```_@@``` -> text content for tag
* ```_!_``` -> text will be inserted as xml to parent node
#### examples of conversion
**List**
from:
json { “b”: { “a”: [1, 2, 3], “c”: 4 } }
to:
**Dictionary**
from:
yaml { “b”: { “a”: 1, “c”: 2 } }
to:
xml
1
**Attributes**
from:
json { “b”: { “@@a”: 1, “@@”: 2 } }
to:
xml 2
**Text value for tag with attibutes**
from:
json { “b@a”: { “@c@a”: 1, “@@”: 2, “_@@g”: 3 } }
to:
xml
**Text value for raw insert**
from:
to:
Notes:
- All content in metadata in common usage generated by yttc command, and you can use output of such tool for ‘parent/template’ blueprint that can be base of yours blueprint. Its not strictly needed but very useful because you can use results of such tools as base for validate your blueprint. Of course yaml validation with dsdl based validation can’t predict and check all of possible errors but you can use it for minimal validation.
- In general case validation works in such way: you creates some parent blueprint by yttc that have all descriptions for data types described in yang module in 2 sections properties->config and properties->rpc. First contain minimal description of your edit configuration data and can check that you have all fields in correct places, and you can describe all you data by override this properties. Second can be used for yours rpc call - it also contain template of your data but of rpc calls. After override this sections you can use this validated data in interfaces->
action
->input->payload. This validation have several drawbacks like can’t check type of element in list, but it covers all minimal cases. After such validation - plugin will validate you data on xml level, for do such we have dsdl section in metadata, plugin try to convert dsdl to relaxng and schematron validation rules and validate data. For simple cases it works but sometime you have additional fields in your data or complicated cases in when current dsdl transformation have issues, so you can disable this validation by setvalidate_xml
to false. - You have examples for all basic operation of netconf protocol in properties of base class of node (described in plugin.yaml) so you can use all of such operation by
payload: { get_property: [ your_node, rfc6020@unlock ] }
. - If you feel self as confidential person - you can write any structure to payload without any validation by in yanl and dsdl. Sometime it will be very useful for crazy devices without correct yang schemas.
- Also we have magic help functionality like
lock
,back_database
,front_database
. So one by one:lock
- we will lock database in list for you before any operation and unlock after operations, its very useful if you have several consumers that want to change configuration and doesn’t like to sync before change.back_database
/front_database
- we can copy configuration from front database to back database before run operations and all operations we will do in this database(if you don’t set any in rfc6020@target) and after will move your changes to front database. Such functionality is useful for case when you want to have consistent settings with apply after all changes. And sometime device does not support change configuration in place. save_to
- response from server will be saved to runtime node properties files with such name and namespaces for this result will be saved to field with same name and suffix_ns
.- We have copy of xslt/relaxng files from
pyang
inshare-files
and have fully same license as original files from pyang. - you can use
cloudify.netconf.translator.xml2netconf
for convert raw xml tocorrect
struct that can be later used in payload. Please look toblueprint_examples/translator_example.yaml
. - you can skip set
ip
innetconf_auth
in case if your node havecloudify.nodes.Compute
node in relationships with typecloudify.relationships.contained_in
. In such case asip
will be usedip
from compute node. - as value
ip
innetconf_auth
can be list ofip's
if you have failback.
Versions:
Look to ChangeLog.