I am trying to write a connection plugin for enabling REST connections, and to that end,
I looked at the existing connection plugins. One of the plugins that caught my attention is the network_cli connection plugin. To understand the code better, I tried to trace the control flow from the nxos vlan module back to the network_cli connection plugin. Here’s what I have gathered so far:
nxos_vlan (modules/network/nxos/nxos_vlan)
load_config (module_utils/network/nxos/nxos)
connection.edit_config
Here connection is an object of the Connection class, imported from module_utils/connection. However, edit_config is found in the cliconf plugin (plugins/cliconf/nxos), which gets loaded from within the network_cli connection_plugin. Thus, it is unclear to me that edit_config gets invoked on an object of the Connection class (different from the network_cli Connection class), when the class does not even have this function defined in the first place.
In view of the above, I would be very thankful if anyone could clear my above confusion and also provide some pointers towards writing a fresh connection plugin for rest connections.
There are multiple moving parts in this code flow.
To start with network_cli connection plugin is applicable for network platforms that support persistent
connection with the remote host across task.
The method called on connection object (connection.edit_config) is serialised in json string as per jsonrpc 2.0 spec [0]
and is send over to socket [1]. The receiving end of the socket is a daemon process called “ansible-connection”
which is spawned from task_executor [2] at the time of connection creation to the remote host.
“ansible-connection” receives the json string and calls handle_request method [3] on the object of JsonRpcServer class
In the initialization steps, “ansible-connection” loads the connection plugin (“network-cli” plugin in this case based on the value of “ansible_connection”)
and registers it with object JsonRpcServer class [4].
handle_request() in turn decodes the json string to fetch the method name, arguments and invokes it on the object of Connection class defined in network_cli [5]
network_cli _connect() method which is called at the time of connection initialization [6] & [7] handles the
connection with the remote host and also loads the cliconf and terminal plugins within the Connection object
based on the value of “network_os” [8] (nxos in this case)
So the call connection.edit_config ends up in Connection class defined in network_cli as and “edit_config” method isnot directly defined in this class it searches for the method with the same name in nxos cliconf and terminal plugin.
Since edit_config is defined in nxos cliconf plugin [9] it gets invoked.
You can refer the httpapi proposal here which deals with a similar requirement as yours.
FYI httpapi connection support is present in devel branch and will be available with Ansible 2.6 version onwards