def test_dispatch(session, fake_id): session.replies.append((RPC_REPLY_DATA, etree.fromstring(RPC_REPLY_DATA))) with LogSentry(True), Manager(session, timeout=1) as mgr: reply = mgr.dispatch("<data>pie test</data>") assert session.sent[0] == uglify( """ <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <data>pie test</data> </rpc> """ ) assert uglify(reply.xml) == uglify( """ <rpc-reply message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <data>bar</data> </rpc-reply> """ ) assert log_recorder.check_content( "dispatch", [ ["NC Request:\n", "<rpc xmlns", "<data>pie test</data>", "</rpc>"], [ r"NC Response \(\d\.\d+ sec\):\n", "<rpc-reply", "<data>bar</data>", "</rpc-reply>", ], ], )
def connect(): global manager session = connect_ssh(host=host, port=port, username=username, password=password) manager = Manager(session, timeout=timeout)
def test_edit_config(session, fake_id, log_enabled, log_id, log_funcname, log_content): session.replies.append(None) with LogSentry(log_enabled), Manager(session, timeout=1, log_id=log_id) as mgr: mgr.edit_config( config="<config>foo</config>", target="candidate", default_operation="merge", test_option="set-only", error_option="rollback-on-error", ) assert session.sent[0] == uglify( """ <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <edit-config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <target> <candidate/> </target> <default-operation>merge</default-operation> <test-option>set-only</test-option> <error-option>rollback-on-error</error-option> <config>foo</config> </edit-config> </rpc> """ ) assert log_recorder.check_content(log_funcname, log_content)
def test_manager_lifecycle_with_id(session): session.set_session_id(4712) with Manager(session, log_id="Raspberry Pi 3") as mgr: assert mgr.timeout == 120 # default timeout assert mgr.log_id == "Raspberry Pi 3" assert mgr.session_id() == 4712 assert session.closed
def test_take_notification_default(session): session.set_notifications(msg="message", ele="element") with Manager(session) as mgr: notification = mgr.take_notification() assert notification.notification_ele == "element" assert notification.notification_xml == "message" assert session.notifications.block is True assert session.notifications.timeout is None
def test_take_notification(session): session.set_notifications(msg="message", ele="element") with Manager(session) as mgr: notification = mgr.take_notification(block=False, timeout=1.23) assert notification.notification_ele == "element" assert notification.notification_xml == "message" assert session.notifications.block is False assert session.notifications.timeout == 1.23
def test_close_session(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.close_session() assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <close-session/> </rpc> """)
def test_discard_changes(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.discard_changes() assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <discard-changes/> </rpc> """)
def test_kill_session(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.kill_session(session_id=7) assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <kill-session> <session-id>7</session-id> </kill-session> </rpc> """)
def test_validate_config(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.validate(source=etree.fromstring("<config>foo</config>")) assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <validate> <source> <config>foo</config> </source> </validate> </rpc> """)
def test_validate_datastore(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.validate(source="running") assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <validate> <source> <running/> </source> </validate> </rpc> """)
def test_unlock(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.unlock(target="startup") assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <unlock> <target> <startup/> </target> </unlock> </rpc> """)
def test_delete_config(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.delete_config(target="running") assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <delete-config> <target> <running/> </target> </delete-config> </rpc> """)
def test_exceptions(fake_id, log_enabled, session_exception, log_content): with LogSentry(log_enabled), MockSession( [], ) as session, Manager(session, timeout=10, log_id="bad device") as mgr: session.replies.append((RPC_REPLY_DATA, etree.fromstring(RPC_REPLY_DATA))) session.set_exception(session_exception()) caught = None try: mgr.get(filter="<filter>foo</filter>", with_defaults="explicit") except Exception as e: caught = e assert isinstance(caught, session_exception) assert log_recorder.check_content("get", log_content)
def test_get(session, fake_id): session.replies.append((RPC_REPLY_DATA, etree.fromstring(RPC_REPLY_DATA))) with Manager(session, timeout=1) as mgr: r = mgr.get(filter="<filter>foo</filter>", with_defaults="explicit") assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <filter>foo</filter> <with-defaults xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults"> explicit </with-defaults> </get> </rpc> """) assert r.data_ele.text == "bar"
def test_xml_error(fake_id): with LogSentry(True), MockSession([]) as session, Manager( session, timeout=1 ) as mgr: session.replies.append((RPC_REPLY_DATA, etree.fromstring(RPC_REPLY_DATA))) # namespace prefix for "adtn-lag:lag" missing bad_filter = """ <filter> <if:interfaces xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"> <if:interface> <if:name>ethernet 0/1:1</if:name> <adtn-lag:lag/> </if:interface> </if:interfaces> </filter>""" r = mgr.get(filter=bad_filter) # NC request was sent nevertheless (and a response was received) assert uglify(session.sent[0].decode("utf-8")) == uglify( """ <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> {} </get> </rpc> """.format( bad_filter ) ) assert r.data_ele.text == "bar" log_content = [ [ "NC Request:\n", "\nError: Cannot format XML message: ", "Namespace prefix adtn-lag on lag is not defined", "\nPlain message is:", bad_filter, ], [ r"NC Response \(\d\.\d+ sec\):\n", "<rpc-reply ", "<data>bar</data>", "</rpc-reply>", ], ] assert log_recorder.check_content("get", log_content)
def test_commit(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.commit(confirmed=True, confirm_timeout=7, persist="foo", persist_id="bar") assert session.sent[0] == uglify( """ <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <commit> <confirmed/> <confirm-timeout>7</confirm-timeout> <persist>foo</persist> <persist-id>bar</persist-id> </commit> </rpc> """ )
def test_create_subscription(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.create_subscription( stream="NETCONF", filter="<filter>foo</filter>", start_time="noon", stop_time="midnight", ) assert session.sent[0] == uglify(""" <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <create-subscription xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0"> <stream>NETCONF</stream> <filter>foo</filter> <startTime>noon</startTime> <stopTime>midnight</stopTime> </create-subscription> </rpc> """)
def test_get(fake_id, log_id, log_local_ip, log_peer_ip, log_content): with LogSentry(True), MockSession( [], log_local_ip, log_peer_ip ) as session, Manager(session, timeout=1, log_id=log_id) as mgr: session.replies.append((RPC_REPLY_DATA, etree.fromstring(RPC_REPLY_DATA))) r = mgr.get(filter="<filter>foo</filter>", with_defaults="explicit") assert session.sent[0] == uglify( """ <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <get xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <filter>foo</filter> <with-defaults xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults"> explicit </with-defaults> </get> </rpc> """ ) assert r.data_ele.text == "bar" assert log_recorder.check_content("get", log_content)
def test_copy_config(session, fake_id): session.replies.append(None) with Manager(session, timeout=1) as mgr: mgr.copy_config(source="running", target="startup", with_defaults="explicit") assert session.sent[0] == uglify( """ <rpc message-id="fake-id" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> <copy-config> <target> <startup/> </target> <source> <running/> </source> <with-defaults xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults"> explicit </with-defaults> </copy-config> </rpc> """ )
def test_take_notification_empty(session): with Manager(session) as mgr: notification = mgr.take_notification() assert notification is None
from netconf_client.connect import connect_ssh from netconf_client.ncclient import Manager HOST = "10.55.1.2" PORT = 31830 # cuup-1 PORT = 31833 # cuup-2 PORT = 31832 # cucp-1 session = connect_ssh(host=HOST, port=PORT, username="******", password="******") mgr = Manager(session, timeout=1200000000) print(mgr.get().data_xml)
from netconf_client.connect import connect_ssh from netconf_client.ncclient import Manager HOST = "10.55.1.2" PORT = 31833 session = connect_ssh(host=HOST, port=PORT, username="******", password="******") mgr = Manager(session, timeout=12000000) rpc = """ <config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"> <gnb-cu-up xmlns="http://accelleran.com/ns/yang/accelleran-gnb-cu-up" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0" xc:operation="replace"> <admin-state>locked</admin-state> </gnb-cu-up> </config>""" print(mgr.edit_config(config=rpc, target='running', default_operation=None))
def __init__(self, log_enabled): log_recorder.clear() Manager.logger().setLevel(logging.DEBUG if log_enabled else logging.NOTSET) assert Manager.logger().isEnabledFor(logging.DEBUG) == log_enabled
def test_manager_lifecycle(session): with Manager(session, timeout=1) as mgr: assert mgr.timeout == 1 assert mgr.log_id is None assert mgr.session_id() == 4711 assert session.closed
def __exit__(self, a, b, c): log_recorder.clear() Manager.logger().setLevel(logging.NOTSET)
entry = record.__dict__ msg = entry.get("msg") args = entry.get("args") if msg and args: # store fully formatted log message entry["formatted_message"] = msg % (args) except AttributeError: pass self.records.append(entry) return False # don't really log anything, recording only # install a log recorder log_recorder = LogRecorder() Manager.logger().addFilter(log_recorder) class LogSentry: def __init__(self, log_enabled): log_recorder.clear() Manager.logger().setLevel(logging.DEBUG if log_enabled else logging.NOTSET) assert Manager.logger().isEnabledFor(logging.DEBUG) == log_enabled def __enter__(self): return self def __exit__(self, a, b, c): log_recorder.clear() Manager.logger().setLevel(logging.NOTSET)
from netconf_client.connect import connect_ssh from netconf_client.ncclient import Manager HOST = "10.55.1.2" PORT = 31833 session = connect_ssh(host=HOST, port=PORT, username="******", password="******") mgr = Manager(session, timeout=120) defPathCuUp = """<config> <gnb-cu-up xmlns="http://accelleran.com/ns/yang/accelleran-gnb-cu-up" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0" xc:operation="create"> <gnb-cu-up-name>accelleran-cu-up-2</gnb-cu-up-name> <gnb-cu-up-id>2</gnb-cu-up-id> <admin-state>unlocked</admin-state> <up-integrity-protection-enabled>false</up-integrity-protection-enabled> <up-ciphering-enabled>true</up-ciphering-enabled> <e1-link-policy xc:operation="create"> <sctp-policy xc:operation="create"> <in-streams>1</in-streams> <out-streams>1</out-streams> </sctp-policy> </e1-link-policy> <e1-link xc:operation="create"> <dest-address>acc-5g-cu-cp-cucp-1-sctp-e1</dest-address> </e1-link> <supported-plmn-slices xc:operation="create"> <plmn-id>00202</plmn-id> <s-nssai xc:operation="create"> <sst>embb</sst>
def test_manager_lifecycle(session): with Manager(session, timeout=1): pass assert session.closed