Using cdist to configure non-SSH/non-shell targets #118

Closed
opened 2021-11-20 13:24:12 +00:00 by ungleich-gitea · 6 comments

Created by: adam-dej

I want to use cdist to configure targets without SSH connectivity (or without usable shell), that
can be configured using a locally-run utility (for example SNMP-enabled network gear/printers,
Google Cloud Platform projects or Kubernetes clusters).

Why do I want to use cdist for this? I want to combine configuration of non-ssh-enabled devices
with configuration of my servers without launching multiple different configuration tools. For
example, I want to have a type which creates SMB shares on a server, and configures relevant
multi-function printers (over SNMP) to use them as scanning targets. Or I want to write a type
__server_link which configures VLANs and link aggregation on a server and on an SNMP switch,
depending on the $__target_host. Arguments of that type are a single source of truth for both
machines (and for my documentation, since I generate it from my manifests).

Currently possible ways to do it? One option is to use a "config gateway" machine (VM, container or
even localhost), but that adds the necessity to maintain one more thing and introduces one more
point of failure. The other option is to use gencode-local, but then I can't run explorers locally
and have to always generate code. My current workaround is to use gencode-local, HOST is IP of the
SNMP device I want to configure, and I prevent cdist from attempting to connect over SSH with args
--remote-exec true and --remote-copy true. Downsides are no explorers, and the fact that it is
an ugly hack.

I'm willing to implement this feature and submit a PR, but first I would like to know whether you
even want such feature in cdist, and if so, in what way should it be implemented.

My initial proposal consists of two parts:

  • Add support for explorer-local in types. Same thing as explorer, just executed locally.
  • Add support for marking some hosts as "nonshell". If a "nonshell" host is being configured, no SSH
    connection is attempted and execution of all global explorers and type explorers will be skipped.
    Moreover, if any remote code is generated, the configuration should fail (manifests/types that
    expect to be executed against "nonshell" targets will know not to generate any remote code, so
    if some code was generated the config is not intended to be used with "nonshell" targets,
    and unexpected things may happen). In addition to existing __target_* variables, a new
    variable, __target_without_shell would be set when configuring a "nonshell" target.

I'm not really sure what would be the best way to mark a target as "nonshell". One possibility would
be to use the built-in inventory, and define a special tag .nonshell. Special tags are bad, and
somebody may want to use an external inventory. Another possibility is to use a non-standard URI
scheme nonshell://host (ssh-enabled hosts are either without scheme or with
ssh://[user@]hostname, both accepted by ssh(1)). But then cdist would have to parse URIs and
remove schemes, not just pass them through.

What are your thoughts on this feature or on the proposed way of implementing it?

*Created by: adam-dej* I want to use cdist to configure targets without SSH connectivity (or without usable shell), that can be configured using a locally-run utility (for example SNMP-enabled network gear/printers, Google Cloud Platform projects or Kubernetes clusters). Why do I want to use `cdist` for this? I want to combine configuration of non-ssh-enabled devices with configuration of my servers without launching multiple different configuration tools. For example, I want to have a type which creates SMB shares on a server, and configures relevant multi-function printers (over SNMP) to use them as scanning targets. Or I want to write a type `__server_link` which configures VLANs and link aggregation on a server and on an SNMP switch, depending on the `$__target_host`. Arguments of that type are a single source of truth for both machines (and for my documentation, since I generate it from my manifests). Currently possible ways to do it? One option is to use a "config gateway" machine (VM, container or even localhost), but that adds the necessity to maintain one more thing and introduces one more point of failure. The other option is to use `gencode-local`, but then I can't run explorers locally and have to always generate code. My current workaround is to use `gencode-local`, HOST is IP of the SNMP device I want to configure, and I prevent cdist from attempting to connect over SSH with args `--remote-exec true` and `--remote-copy true`. Downsides are no explorers, and the fact that it is an ugly hack. I'm willing to implement this feature and submit a PR, but first I would like to know whether you even want such feature in cdist, and if so, in what way should it be implemented. My initial proposal consists of two parts: - Add support for `explorer-local` in types. Same thing as `explorer`, just executed locally. - Add support for marking some hosts as "nonshell". If a "nonshell" host is being configured, no SSH connection is attempted and execution of all global explorers and type explorers will be skipped. Moreover, if any remote code is generated, the configuration should fail (manifests/types that expect to be executed against "nonshell" targets will know not to generate any remote code, so if some code was generated the config is not intended to be used with "nonshell" targets, and unexpected things may happen). In addition to existing `__target_*` variables, a new variable, `__target_without_shell` would be set when configuring a "nonshell" target. I'm not really sure what would be the best way to mark a target as "nonshell". One possibility would be to use the built-in inventory, and define a special tag `.nonshell`. Special tags are bad, and somebody may want to use an external inventory. Another possibility is to use a non-standard URI scheme `nonshell://host` (ssh-enabled hosts are either without scheme or with `ssh://[user@]hostname`, both accepted by ssh(1)). But then `cdist` would have to parse URIs and remove schemes, not just pass them through. What are your thoughts on this feature or on the proposed way of implementing it?
ungleich-gitea added the
Stale
label 2021-11-20 13:24:12 +00:00
Author
Owner

closed

closed
Author
Owner

Created by: darko-poljak

@adam-dej

My current workaround is to use gencode-local, HOST is IP of the
SNMP device I want to configure, and I prevent cdist from attempting to connect over SSH with args
--remote-exec true and --remote-copy true. Downsides are no explorers, and the fact that it is
an ugly hack.

You can do it better. remote-exec and remote-copy can be paths to your exec and copy scripts.
And in those shell scripts you can do the desired behavior.
In cdist-ng transports are actually shell scripts. see https://github.com/asteven/cdist-ng/tree/master/conf/transport and for chroot example see https://github.com/asteven/cdist-ng/blob/master/conf/transport/chroot/exec and https://github.com/asteven/cdist-ng/blob/master/conf/transport/chroot/copy. Following the same principle you can write scripts for your needs.

*Created by: darko-poljak* @adam-dej > My current workaround is to use gencode-local, HOST is IP of the SNMP device I want to configure, and I prevent cdist from attempting to connect over SSH with args --remote-exec true and --remote-copy true. Downsides are no explorers, and the fact that it is an ugly hack. You can do it better. remote-exec and remote-copy can be paths to your exec and copy scripts. And in those shell scripts you can do the desired behavior. In cdist-ng transports are actually shell scripts. see https://github.com/asteven/cdist-ng/tree/master/conf/transport and for chroot example see https://github.com/asteven/cdist-ng/blob/master/conf/transport/chroot/exec and https://github.com/asteven/cdist-ng/blob/master/conf/transport/chroot/copy. Following the same principle you can write scripts for your needs.
Author
Owner

Created by: darko-poljak

@adam-dej Are you starting to port this to cdist?

*Created by: darko-poljak* @adam-dej Are you starting to port this to cdist?
Author
Owner

Created by: telmich

I like @asteven 's URL based way. Porting it to cdist from cdist-ng is a good idea.

*Created by: telmich* I like @asteven 's URL based way. Porting it to cdist from cdist-ng is a good idea.
Author
Owner

Created by: lubo

@darko-poljak @telmich Your thoughts would be highly appreciated.

*Created by: lubo* @darko-poljak @telmich Your thoughts would be highly appreciated.
Author
Owner

Created by: asteven

While experimenting with cdist-ng I implemented target host as always being a URI. Then used the scheme in the URI to select the apropriate transport.

This allowed me to do things like:

cdist config test.example.com
# same as
cdist config ssh://test.example.com
# or stacked transports
cdist config ssh+sudo+chroot://sudo-user@test.example.com/path/to/chroot

Guess what I want to say is: I like the idea of using URI's for this kind of stuff.
Not sure if I would call it 'noshell', but that depends on how generic you can make it.

I believe @telmich mentioned he would also like this feature, e.g. to configure his switches, so will let him comment.

*Created by: asteven* While experimenting with [cdist-ng](https://github.com/asteven/cdist-ng/) I implemented target host as always being a URI. Then used the scheme in the URI to select the apropriate transport. This allowed me to do things like: ``` cdist config test.example.com # same as cdist config ssh://test.example.com # or stacked transports cdist config ssh+sudo+chroot://sudo-user@test.example.com/path/to/chroot ``` Guess what I want to say is: I like the idea of using URI's for this kind of stuff. Not sure if I would call it 'noshell', but that depends on how generic you can make it. I believe @telmich mentioned he would also like this feature, e.g. to configure his switches, so will let him comment.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: ungleich-public/cdist#118
No description provided.