Adding a new connection plugin

Hi,

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.

Thank you very much for your help!

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.

nxos_vlan → load_config → connection.edit_config → ansible-connection → network_cli → nxos cliconf

------ module side code --------------------------------------| |--------------- controller code -----------------------------|

[0] http://www.jsonrpc.org/specification
[1] https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/connection.py#L158
[2] https://github.com/ansible/ansible/blob/devel/lib/ansible/executor/task_executor.py#L917
[3] https://github.com/ansible/ansible/blob/devel/bin/ansible-connection#L123
[4] https://github.com/ansible/ansible/blob/devel/bin/ansible-connection#L89
[5] https://github.com/ansible/ansible/blob/devel/lib/ansible/utils/jsonrpc.py#L25
[6] https://github.com/ansible/ansible/blob/devel/bin/ansible-connection#L87
[7] https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/network_cli.py#L287
[8] https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/network_cli.py#L318
[9] https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/network_cli.py#L225

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

Hope this helps.

Regards,
Ganesh