pyinfra-dev / pyinfra

pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands.
https://pyinfra.com
MIT License
3.82k stars 372 forks source link

It is possible to write custom connectors, but not to use them #977

Open KACAH opened 1 year ago

KACAH commented 1 year ago

There is more or less documented way to write your own connectors: https://docs.pyinfra.com/en/2.x/api/connectors.html

However, connectors lookup is pretty much hardcoded to pyinfra.connectors package right here: https://github.com/Fizzadar/pyinfra/blob/51c48de09adcc7b8e9ee5da7b56b44f230cc30a0/pyinfra/api/connectors.py#L33

and there: https://github.com/Fizzadar/pyinfra/blob/51c48de09adcc7b8e9ee5da7b56b44f230cc30a0/pyinfra/api/inventory.py#L92

So, it's not possible to use connectors outside the official pyinfra release without monkey patching.

Is it designed to be like that? And if so, what is the purpose of the mentioned documentation page?

mvgijssel commented 1 year ago

I've managed to create a basic teleport connector here https://github.com/mvgijssel/setup/pull/262/files with the following monkey patch in the inventory.py

import pyinfra.api.connectors
import provisioner.connectors.teleport

from pyinfra.api.connectors import get_all_connectors
import pyinfra.api.inventory

original_get_all_connectors = pyinfra.api.connectors.get_all_connectors

def patched_get_all_connectors():
    data = original_get_all_connectors()
    data["teleport"] = provisioner.connectors.teleport
    return data

pyinfra.api.connectors.get_all_connectors = patched_get_all_connectors
pyinfra.api.inventory.get_all_connectors = patched_get_all_connectors

It's not pretty but it works!

Fizzadar commented 1 year ago

The move to use entrypoints should facilitate exactly this kind of situation! I don't have time to pull an example together right now but essentially you need to define a package that adds to the pyinfra.connectors entry point (https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata).

I will try to get an example of this up somewhere!