def test_parse_response(self):
        """check parse response code"""
        xml = self.CORRECT_REPLY
        netconf_namespace, xmlns = utils.update_xmlns({})
        response = rpc._parse_response(xmlns, netconf_namespace, xml)
        self.assertEqual(response, {
            '_@rfc6020@message-id': '57380',
            'rfc6020@ok': None
        })
        self.assertEqual(xmlns, {netconf_namespace: utils.NETCONF_NAMESPACE})

        # no namespace in reply
        xml = """
            <rpc-reply message-id="57380">
                <ok/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        response = rpc._parse_response(xmlns, netconf_namespace, xml)
        self.assertEqual(response, {'_@@message-id': '57380', 'ok': None})
        self.assertEqual(xmlns, {netconf_namespace: utils.NETCONF_NAMESPACE})

        # dont have reply
        xml = """
            <rpc message-id="57380">
                <ok/>
            </rpc>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(xmlns, netconf_namespace, xml)

        # error in reply
        xml = """
            <rpc-reply message-id="57380">
                <rpc-error/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(xmlns, netconf_namespace, xml)

        # error in reply with namespace
        xml = """
            <rpc-reply
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
                message-id="57380">
                <rpc-error/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(xmlns, netconf_namespace, xml)
def run(**kwargs):
    """main entry point for all operations"""

    xmls = kwargs.get('xmls', [])
    if not xmls:
        ctx.logger.info("No xmls for translate")
        return

    xmlns = kwargs.get('xmlns', {})
    netconf_namespace, xmlns = utils.update_xmlns(
        xmlns
    )

    for xml_struct in xmls:
        raw_xml = xml_struct.get("raw")
        if not raw_xml:
            ctx.logger.info("Empty raw xml?")
            continue
        ctx.logger.info("Parsing %s..." % (raw_xml[:60]))
        xml_node = etree.XML(raw_xml)
        xml_dict = {}
        utils.generate_dict_node(
            xml_dict, xml_node,
            xmlns
        )
        # save results to runtime properties
        save_to = xml_struct.get('save_to')
        if save_to:
            ctx.instance.runtime_properties[save_to] = xml_dict
            ctx.instance.runtime_properties[save_to + "_ns"] = xmlns
 def test_rpc_gen(self):
     """check rpc_gen"""
     xmlns = {
         'r': utils.NETCONF_NAMESPACE,
         'n': "someaction"
     }
     netconf_namespace, xmlns = utils.update_xmlns(
         xmlns
     )
     self.assertEqual(netconf_namespace, "r")
     data = {
         "b": "b"
     }
     # dont have namespace in action
     parent = utils.rpc_gen(
         "some_id", 'run', netconf_namespace, data, xmlns
     )
     rpc_string = etree.tostring(parent)
     example_string = (
         """<r:rpc xmlns:r="urn:ietf:params:xml:ns:netconf:base:""" +
         """1.0" xmlns:n="someaction" message-id="some_id"><r:ru""" +
         """n><r:b>b</r:b></r:run></r:rpc>"""
     )
     self.assertEqual(rpc_string, example_string)
     # have namespace in action
     parent = utils.rpc_gen(
         "some_id", 'n@run', netconf_namespace, data, xmlns
     )
     rpc_string = etree.tostring(parent)
     example_string = (
         """<r:rpc xmlns:r="urn:ietf:params:xml:ns:netconf:base:""" +
         """1.0" xmlns:n="someaction" message-id="some_id"><n:ru""" +
         """n><n:b>b</n:b></n:run></r:rpc>"""
     )
     self.assertEqual(rpc_string, example_string)
 def test_rpc_gen(self):
     """check rpc_gen"""
     xmlns = {
         'r': utils.NETCONF_NAMESPACE,
         'n': "someaction"
     }
     netconf_namespace, xmlns = utils.update_xmlns(
         xmlns
     )
     self.assertEqual(netconf_namespace, "r")
     data = {
         "b": "b"
     }
     # dont have namespace in action
     parent = utils.rpc_gen(
         "some_id", 'run', netconf_namespace, data, xmlns
     )
     rpc_string = etree.tostring(parent)
     example_string = (
         """<r:rpc xmlns:n="someaction" xmlns:r="urn:ietf:""" +
         """params:xml:ns:netconf:base:1.0" r:message-id""" +
         """="some_id"><r:run><r:b>b</r:b></r:run></r:rpc>"""
     )
     self.assertEqual(rpc_string, example_string)
     # have namespace in action
     parent = utils.rpc_gen(
         "some_id", 'n@run', netconf_namespace, data, xmlns
     )
     rpc_string = etree.tostring(parent)
     example_string = (
         """<r:rpc xmlns:n="someaction" xmlns:r="urn:ietf:""" +
         """params:xml:ns:netconf:base:1.0" r:message-id""" +
         """="some_id"><n:run><n:b>b</n:b></n:run></r:rpc>"""
     )
     self.assertEqual(rpc_string, example_string)
Beispiel #5
0
 def test_server_support_1_1(self):
     """check support 1.1 response from server"""
     netconf_namespace, xmlns = utils.update_xmlns({})
     self.assertFalse(
         rpc._server_support_1_1(xmlns, netconf_namespace,
                                 self.CORRECT_HELLO_REPLY))
     self.assertTrue(
         rpc._server_support_1_1(xmlns, netconf_namespace,
                                 self.CORRECT_HELLO_1_1_REPLY))
 def test_update_xmlns(self):
     """check add default namespace"""
     namespace, xmlns = utils.update_xmlns({})
     self.assertEqual(
         namespace, utils.DEFAULT_NCNS
     )
     self.assertEqual(
         xmlns, {
             utils.DEFAULT_NCNS: utils.NETCONF_NAMESPACE
         }
     )
 def test_update_xmlns(self):
     """check add default namespace"""
     namespace, xmlns = utils.update_xmlns({})
     self.assertEqual(
         namespace, utils.DEFAULT_NCNS
     )
     self.assertEqual(
         xmlns, {
             utils.DEFAULT_NCNS: utils.NETCONF_NAMESPACE
         }
     )
Beispiel #8
0
 def test_generate_goodbye(self):
     """check goodbye message"""
     goodbye_message = (
         """<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<rfc6020""" +
         """:rpc xmlns:rfc6020="urn:ietf:params:xml:ns:netconf:b""" +
         """ase:1.0" message-id="last_message">\n  <rfc6020:clos""" +
         """e-session/>\n</rfc6020:rpc>\n""")
     netconf_namespace, xmlns = utils.update_xmlns({})
     goodbye_string = rpc._generate_goodbye(xmlns, netconf_namespace,
                                            "last_message")
     self.assertEqual(goodbye_string, goodbye_message)
 def test_server_support_1_1(self):
     """check support 1.1 response from server"""
     netconf_namespace, xmlns = utils.update_xmlns({})
     self.assertFalse(
         rpc._server_support_1_1(
             xmlns, netconf_namespace, self.CORRECT_HELLO_REPLY
         )
     )
     self.assertTrue(
         rpc._server_support_1_1(
             xmlns, netconf_namespace, self.CORRECT_HELLO_1_1_REPLY
         )
     )
Beispiel #10
0
 def test_generate_hello(self):
     """check hello message"""
     hello_message = (
         """<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<rfc6020""" +
         """:hello xmlns:rfc6020="urn:ietf:params:xml:ns:netconf""" +
         """:base:1.0">\n  <rfc6020:capabilities>\n    <rfc6020:""" +
         """capability>urn:ietf:params:netconf:base:1.0</rfc6020""" +
         """:capability>\n    <rfc6020:capability>urn:ietf:param""" +
         """s:netconf:base:1.1</rfc6020:capability>\n  </rfc6020""" +
         """:capabilities>\n</rfc6020:hello>\n""")
     netconf_namespace, xmlns = utils.update_xmlns({})
     hello_string = rpc._generate_hello(xmlns, netconf_namespace, {})
     self.assertEqual(hello_string, hello_message)
 def test_generate_goodbye(self):
     """check goodbye message"""
     goodbye_message = (
         """<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<rfc6020""" +
         """:rpc xmlns:rfc6020="urn:ietf:params:xml:ns:netconf:b""" +
         """ase:1.0" message-id="last_message">\n  <rfc6020:clos""" +
         """e-session/>\n</rfc6020:rpc>\n"""
     )
     netconf_namespace, xmlns = utils.update_xmlns({})
     goodbye_string = rpc._generate_goodbye(
         xmlns, netconf_namespace, "last_message"
     )
     self.assertEqual(goodbye_string, goodbye_message)
 def test_generate_hello(self):
     """check hello message"""
     hello_message = (
         """<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n<rfc6020""" +
         """:hello xmlns:rfc6020="urn:ietf:params:xml:ns:netconf""" +
         """:base:1.0">\n  <rfc6020:capabilities>\n    <rfc6020:""" +
         """capability>urn:ietf:params:netconf:base:1.0</rfc6020""" +
         """:capability>\n    <rfc6020:capability>urn:ietf:param""" +
         """s:netconf:base:1.1</rfc6020:capability>\n  </rfc6020""" +
         """:capabilities>\n</rfc6020:hello>\n"""
     )
     netconf_namespace, xmlns = utils.update_xmlns({})
     hello_string = rpc._generate_hello(xmlns, netconf_namespace, {})
     self.assertEqual(hello_string, hello_message)
  source:
    running: {}
  filter:
    _@@type: subtree
    turing@turing-machine:
      turing@transition-function: {}
-------------------
"""
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(help_message)
    else:
        yaml_rpc = open(sys.argv[1], 'rb')
        with yaml_rpc:
            yaml_text = yaml_rpc.read()
            yaml_dict = yaml.load(yaml_text)
            data = yaml_dict.get('payload', {})
            xmlns = yaml_dict.get('ns', {})
            operation = yaml_dict.get('action', 'get')
            netconf_namespace, xmlns = utils.update_xmlns(
                xmlns
            )
            parent = utils.rpc_gen(
                "some_id", operation, netconf_namespace, data, xmlns
            )
            rpc_string = etree.tostring(
                parent, pretty_print=True, xml_declaration=True,
                encoding='UTF-8'
            )
            print(rpc_string)
Beispiel #14
0
action: get

payload:
  source:
    running: {}
  filter:
    _@@type: subtree
    turing@turing-machine:
      turing@transition-function: {}
-------------------
"""
if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(help_message)
    else:
        yaml_rpc = open(sys.argv[1], 'rb')
        with yaml_rpc:
            yaml_text = yaml_rpc.read()
            yaml_dict = yaml.load(yaml_text)
            data = yaml_dict.get('payload', {})
            xmlns = yaml_dict.get('ns', {})
            operation = yaml_dict.get('action', 'get')
            netconf_namespace, xmlns = utils.update_xmlns(xmlns)
            parent = utils.rpc_gen("some_id", operation, netconf_namespace,
                                   data, xmlns)
            rpc_string = etree.tostring(parent,
                                        pretty_print=True,
                                        xml_declaration=True,
                                        encoding='UTF-8')
            print(rpc_string)
Beispiel #15
0
    def test_parse_response(self):
        """check parse response code"""
        xml = self.CORRECT_REPLY
        fake_ctx = cfy_mocks.MockCloudifyContext()
        current_ctx.set(fake_ctx)
        netconf_namespace, xmlns = utils.update_xmlns({})
        response = rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml,
                                       True)
        self.assertEqual(response, {
            '_@rfc6020@message-id': '57380',
            'rfc6020@ok': None
        })
        self.assertEqual(xmlns, {netconf_namespace: utils.NETCONF_NAMESPACE})

        # no namespace in reply
        xml = """
            <rpc-reply message-id="57380">
                <ok/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        response = rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml,
                                       True)
        self.assertEqual(response, {'_@@message-id': '57380', 'ok': None})
        self.assertEqual(xmlns, {netconf_namespace: utils.NETCONF_NAMESPACE})

        # dont have reply
        xml = """
            <rpc message-id="57380">
                <ok/>
            </rpc>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True)

        # error in reply
        xml = """
            <rpc-reply message-id="57380">
                <rpc-error/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.RecoverableError):
            rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True)

        # warning in reply
        xml = """
            <rpc-reply message-id="57380">
                <rpc-error>
                    <error-severity>warning</error-severity>
                </rpc-error>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True)

        # error in reply
        xml = """
            <rpc-reply message-id="57380">
                <rpc-error>
                    <error-severity>error</error-severity>
                </rpc-error>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.RecoverableError):
            rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True)

        # error in reply in uncommon place
        xml = """
            <rpc-reply message-id="57380">
                <uncommon>
                    <rpc-error>
                        <error-severity>error</error-severity>
                    </rpc-error>
                </uncommon>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.RecoverableError):
            rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True,
                                True)

        # error in reply with namespace
        xml = """
            <rpc-reply
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
                message-id="57380">
                <rpc-error/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.RecoverableError):
            rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True)

        # warning in reply with namespace
        xml = """
            <rpc-reply
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
                message-id="57380">
                <rpc-error>
                    <error-severity>warning</error-severity>
                </rpc-error>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True)

        # error in reply in uncommon place with namespace
        xml = """
            <rpc-reply
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
                message-id="57380">
                <uncommon>
                    <rpc-error>
                        <error-severity>error</error-severity>
                    </rpc-error>
                </uncommon>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.RecoverableError):
            rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True,
                                True)

        # check issues with xml
        xml = """
            <rpc-reply
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
                xmlns:junos="http://xml.juniper.net/junos/12.1X46/junos"
                xmlns:junos="http://xml.juniper.net/junos/12.1X46/junos"
                xmlns:rfc6020="urn:ietf:params:xml:ns:netconf:base:1.0"
                xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm"
                rfc6020:message-id="229">
                    <ok/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        response = rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml,
                                       False)
        self.assertEqual(response, {
            'rfc6020@ok': None,
            '_@rfc6020@message-id': '229'
        })

        # raise execption for uncorrect xml
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(fake_ctx, xmlns, netconf_namespace, xml, True)
def run(ctx, **kwargs):
    """main entry point for all calls"""

    calls = kwargs.get('calls', [])

    templates_locs = kwargs.get('templates', [])
    template = kwargs.get('template')

    templates = []
    for tmpl_loc in templates_locs:
        templates.append(_get_template(ctx, tmpl_loc))

    if template:
        templates.extend(_get_template(ctx, template).split("]]>]]>"))

    if not calls and not templates:
        ctx.logger.info("Please provide calls or template")
        return

    # credentials
    properties = ctx.node.properties
    netconf_auth = properties.get('netconf_auth', {})
    netconf_auth.update(kwargs.get('netconf_auth', {}))
    user = netconf_auth.get('user')
    password = netconf_auth.get('password')
    key_content = netconf_auth.get('key_content')
    port = int(netconf_auth.get('port', 830))
    ip_list = netconf_auth.get('ip')
    if isinstance(ip_list, basestring):
        ip_list = [ip_list]
    # save logs to debug file
    log_file_name = None
    if netconf_auth.get('store_logs'):
        log_file_name = (
            "/tmp/netconf-{execution_id}_{instance_id}_{workflow_id}.log".
            format(execution_id=str(ctx.execution_id),
                   instance_id=str(ctx.instance.id),
                   workflow_id=str(ctx.workflow_id)))
        ctx.logger.info(
            "Communication logs will be saved to {log_file_name}".format(
                log_file_name=log_file_name))

    strict_check = kwargs.get('strict_check', True)

    # if node contained in some other node, try to overwrite ip
    if not ip_list:
        ip_list = [ctx.instance.host_ip]
        ctx.logger.info("Used host from container: {ip_list}".format(
            ip_list=filters.shorted_text(ip_list)))
    # check minimal amout of credentials
    if not port or not ip_list or not user or (not password
                                               and not key_content):
        raise cfy_exc.NonRecoverableError("please check your credentials")

    # some random initial message id, for have different between calls
    message_id = int((time.time() * 100) % 100 * 1000)

    # xml namespaces and capabilities
    xmlns = properties.get('metadata', {}).get('xmlns', {})

    # override by system namespaces
    xmlns = _merge_ns(xmlns, properties.get('base_xmlns', {}))

    netconf_namespace, xmlns = utils.update_xmlns(xmlns)
    capabilities = properties.get('metadata', {}).get('capabilities')

    # connect
    ctx.logger.info("use {user}@{ip_list}:{port} for login".format(
        user=user, ip_list=ip_list, port=port))
    hello_string = _generate_hello(xmlns, netconf_namespace, capabilities)
    ctx.logger.debug(
        "Sent: {message}".format(message=filters.shorted_text(hello_string)))

    netconf = netconf_connection.NetConfConnection(logger=ctx.logger,
                                                   log_file_name=log_file_name)
    for ip in ip_list:
        try:
            capabilities = netconf.connect(ip, user, hello_string, password,
                                           key_content, port)
            ctx.logger.info("Will be used: {ip}".format(ip=ip))
            break
        except Exception as ex:
            ctx.logger.info("Can't connect to {ip} with {ex}".format(
                ip=repr(ip), ex=str(ex)))
    else:
        raise cfy_exc.NonRecoverableError("please check your ip list")

    ctx.logger.debug("Recieved: {capabilities}".format(
        capabilities=filters.shorted_text(capabilities)))

    if _server_support_1_1(xmlns, netconf_namespace, capabilities):
        ctx.logger.info("use version 1.1 of netconf protocol")
        netconf.current_level = netconf_connection.NETCONF_1_1_CAPABILITY
    else:
        ctx.logger.info("use version 1.0 of netconf protocol")

    try:
        message_id = _run_in_locked(ctx=ctx,
                                    netconf=netconf,
                                    message_id=message_id,
                                    netconf_namespace=netconf_namespace,
                                    xmlns=xmlns,
                                    calls=calls,
                                    templates=templates,
                                    kwargs=kwargs,
                                    strict_check=strict_check)
    finally:
        # goodbye
        ctx.logger.info("Connection close")
        message_id += 1
        goodbye_string = _generate_goodbye(xmlns, netconf_namespace,
                                           message_id)
        ctx.logger.debug("Sent: {message}".format(
            message=filters.shorted_text(goodbye_string)))

        response = netconf.close(goodbye_string)
        ctx.logger.debug("Recieved: {message} ".format(
            message=filters.shorted_text(response)))
def run(**kwargs):
    """main entry point for all calls"""

    calls = kwargs.get('calls', [])

    template = kwargs.get('template')
    templates = []
    if template:
        templates = ctx.get_resource(template).split("]]>]]>")

    if not calls and not templates:
        ctx.logger.info("Please provide calls or template")
        return

    # credentials
    properties = ctx.node.properties
    netconf_auth = properties.get('netconf_auth', {})
    netconf_auth.update(kwargs.get('netconf_auth', {}))
    user = netconf_auth.get('user')
    password = netconf_auth.get('password')
    key_content = netconf_auth.get('key_content')
    port = int(netconf_auth.get('port', 830))
    ip_list = netconf_auth.get('ip')
    if isinstance(ip_list, basestring):
        ip_list = [ip_list]
    # save logs to debug file
    log_file_name = None
    if netconf_auth.get('store_logs'):
        log_file_name = "/tmp/netconf-%s_%s_%s.log" % (str(
            ctx.execution_id), str(ctx.instance.id), str(ctx.workflow_id))
        ctx.logger.info("Communication logs will be saved to %s" %
                        log_file_name)

    # if node contained in some other node, try to overwrite ip
    if not ip_list:
        ip_list = [ctx.instance.host_ip]
        ctx.logger.info("Used host from container: %s" % str(ip_list))
    # check minimal amout of credentials
    if not port or not ip_list or not user or (not password
                                               and not key_content):
        raise cfy_exc.NonRecoverableError("please check your credentials")

    # some random initial message id, for have different between calls
    message_id = int((time.time() * 100) % 100 * 1000)

    # xml namespaces and capabilities
    xmlns = properties.get('metadata', {}).get('xmlns', {})

    # override by system namespaces
    xmlns = _merge_ns(xmlns, properties.get('base_xmlns', {}))

    netconf_namespace, xmlns = utils.update_xmlns(xmlns)
    capabilities = properties.get('metadata', {}).get('capabilities')

    # connect
    ctx.logger.info("use %s@%s:%s for login" % (user, ip_list, port))
    hello_string = _generate_hello(xmlns, netconf_namespace, capabilities)
    ctx.logger.info("i sent: " + hello_string)
    _write_to_log(log_file_name, hello_string)

    netconf = netconf_connection.connection()
    for ip in ip_list:
        try:
            capabilities = netconf.connect(ip, user, hello_string, password,
                                           key_content, port)
            ctx.logger.info("Will be used: " + ip)
            break
        except Exception as ex:
            ctx.logger.info("Can't connect to %s with %s" %
                            (repr(ip), str(ex)))
    else:
        raise cfy_exc.NonRecoverableError("please check your ip list")

    ctx.logger.info("i recieved: " + capabilities)
    _write_to_log(log_file_name, capabilities)

    if _server_support_1_1(xmlns, netconf_namespace, capabilities):
        ctx.logger.info("i will use version 1.1 of netconf protocol")
        netconf.current_level = netconf_connection.NETCONF_1_1_CAPABILITY
    else:
        ctx.logger.info("i will use version 1.0 of netconf protocol")

    strict_check = kwargs.get('strict_check', True)
    if 'lock' in kwargs:
        message_id = message_id + 1
        for name in kwargs['lock']:
            _lock(name, True, netconf, message_id, netconf_namespace, xmlns,
                  strict_check, log_file_name)

    if 'back_database' in kwargs and 'front_database' in kwargs:
        message_id = message_id + 1
        _copy(kwargs['front_database'],
              kwargs['back_database'],
              netconf,
              message_id,
              netconf_namespace,
              xmlns,
              strict_check,
              log_file_name=log_file_name)

    if calls:
        dsdl = properties.get('metadata', {}).get('dsdl')
        _run_calls(netconf,
                   message_id,
                   netconf_namespace,
                   xmlns,
                   calls,
                   kwargs.get('back_database'),
                   dsdl,
                   strict_check,
                   log_file_name=log_file_name)
    elif templates:
        template_params = kwargs.get('params')
        deep_error_check = kwargs.get('deep_error_check')
        ctx.logger.info("Params for template %s" % str(template_params))
        _run_templates(netconf,
                       templates,
                       template_params,
                       netconf_namespace,
                       xmlns,
                       strict_check,
                       deep_error_check,
                       log_file_name=log_file_name)

    if 'back_database' in kwargs and 'front_database' in kwargs:
        message_id = message_id + 1
        _copy(kwargs['back_database'],
              kwargs['front_database'],
              netconf,
              message_id,
              netconf_namespace,
              xmlns,
              strict_check,
              log_file_name=log_file_name)

    if 'lock' in kwargs:
        message_id = message_id + 1
        for name in kwargs['lock']:
            _lock(name,
                  False,
                  netconf,
                  message_id,
                  netconf_namespace,
                  xmlns,
                  strict_check,
                  log_file_name=log_file_name)

    # goodbye
    ctx.logger.info("connection close")
    message_id = message_id + 1
    goodbye_string = _generate_goodbye(xmlns, netconf_namespace, message_id)
    ctx.logger.info("i sent: " + goodbye_string)

    response = netconf.close(goodbye_string)
    ctx.logger.info("i recieved: " + response)
    def test_parse_response(self):
        """check parse response code"""
        xml = self.CORRECT_REPLY
        netconf_namespace, xmlns = utils.update_xmlns({})
        response = rpc._parse_response(xmlns, netconf_namespace, xml)
        self.assertEqual(
            response, {
                '_@rfc6020@message-id': '57380',
                'rfc6020@ok': None
            }
        )
        self.assertEqual(
            xmlns, {
                netconf_namespace: utils.NETCONF_NAMESPACE
            }
        )

        # no namespace in reply
        xml = """
            <rpc-reply message-id="57380">
                <ok/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        response = rpc._parse_response(xmlns, netconf_namespace, xml)
        self.assertEqual(
            response, {
                '_@@message-id': '57380',
                'ok': None
            }
        )
        self.assertEqual(
            xmlns, {
                netconf_namespace: utils.NETCONF_NAMESPACE
            }
        )

        # dont have reply
        xml = """
            <rpc message-id="57380">
                <ok/>
            </rpc>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(xmlns, netconf_namespace, xml)

        # error in reply
        xml = """
            <rpc-reply message-id="57380">
                <rpc-error/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(xmlns, netconf_namespace, xml)

        # error in reply with namespace
        xml = """
            <rpc-reply
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
                message-id="57380">
                <rpc-error/>
            </rpc-reply>
        """
        netconf_namespace, xmlns = utils.update_xmlns({})
        with self.assertRaises(cfy_exc.NonRecoverableError):
            rpc._parse_response(xmlns, netconf_namespace, xml)