I've been working on OpsMop push mode this week and things have been going GREAT.
As I noted previously, OpsMop no longer has a bin/opsmop and bin/opsmop-push script, the policy files are now executable.
You execute a local policy like this:
foo.py --local --apply
You execute a remote policy in push (SSH) mode like this:
foo.py --push --apply
Now, the best example for push mode is here right now:
To run this, you just do:
cd opsmop-demo/content/ vim inventory/inventory.toml python3 push_demo.py --push --apply
I've written some docs which I haven't pushed yet that explain this a lot:
But there are a few things that aren't really even documented there yet.
There's a new UserDefaults class:
This allows loading a VERY wide variety of SSH, sudo, tuning, and logging preferences from an optional file in ~/.opsmop/defaults.toml or /etc/opsmop/defaults.toml, whichever is found first.
Here is where you would set your default login name if it wasn't going to be defined in the policy file.
In the Role, there are several new methods that are not used when executing it locally, but it's important to remember any role that is remoteable CAN still be executed locally:
def serial() - returns an integer of how many hosts in a role to complete as a group. The default right now is 80. You could set it to 5. We don't yet do anything like progressive canary deployments, but it's quite possible to add later.
def inventory(self) - returns a subset of an inventory. As explained in https://github.com/opsmop/opsmop/blob/master/docs/source/push.rst the only inventory we have in the tree right now is a basic TOML inventory - though I suspect the first contribution (this can happen NOW btw, nothing is holding it back) to be one for AWS using boto3. Inventory classes are super easy to write and only require returning a nested dictionary structure.
def ssh_as(self) - returns a tuple of (username, pass) where pass may be None - this says what to login as. I am a strong believer in not using passwords, ever, so I will probably make this so that if you return just a string (username) it doesn't need you to return (username, None)
def sudo_as(self) - similarly, returns a list of accounts to sudo to, and the sudo password required (if required).
def sudo(self) - return True if you need to sudo at all.
For users familiar with ansible, these above concepts should be pretty familiar, but they are consolidated and made a bit more programatical. You can easily see here how something like getting a password could come from ANY external data source, because it's a program.
Now, these set the settings for the whole role.
Any value that is None - like a password, or a login user, doesn't have to come from the role. A common use cases is that multiple members of a team share the same config management content and need to connect as them before sudoing.
To do this, each should create a ~/.opsmop/defaults.toml
Easy enough, that machine will login as Bob.
I didn't do any automation to assume the current username as a deafult, but I suppose we COULD add that.
There are also a lot of magic variables, which I've mostly documented in the https://github.com/opsmop/opsmop/blob/master/docs/source/push.rst file, which will appear in docs when I am ready to share this more widely.
This is a LOT to take in and a lot of new stuff, so please ask any questions you may have, or share any ideas/wants...