StackStorm / st2

StackStorm (aka "IFTTT for Ops") is event-driven automation for auto-remediation, incident responses, troubleshooting, deployments, and more for DevOps and SREs. Includes rules engine, workflow, 160 integration packs with 6000+ actions (see https://exchange.stackstorm.org) and ChatOps. Installer at https://docs.stackstorm.com/install/index.html
https://stackstorm.com/
Apache License 2.0
6.06k stars 745 forks source link

st2client config manager #5294

Open minsis opened 3 years ago

minsis commented 3 years ago

It would be a cool feature to have the ability to switch between config files in a muti-environment setup. An example is similar to how knife block might work.

Multiple config files inside ~/.st2 folder which are named however you need. Could be prefixed with something like st2client-config. Filename might look something like ~/.st2/st2client-config-<env-name>.ini. Then switching between the configs would just be doing a symlink like knife block does.

Switching configs e.g.

$ st2 config use <env-name>
> Now using <env-name>

Listing the configs e.g.

$ st2 config list
> The available StackStorm servers are
>  <env-name> [ Currently Selected ]
>  <env-name1>
>  <env-name2>
>  <env-name3>

There could even maybe be the option to create/edit them with the cli as well which would drop you into whatever configured editor is.

st2 config {create,edit} <env-name1>
minsis commented 3 years ago

I'd like to take a crack at this but I'd like to get some input on the idea before I put any time into it.

blag commented 3 years ago

I'm not a huge fan of the statefulness of which config to choose, but saving that state in a symlink is not a bad idea. The question then becomes: what do you call the default config file? default.ini?

I'm more of a fan of a stateless approach, where the config file is selected by an argument to a --config option (st2client might already do this, I've been away from that code for too long, if so, please disregard this). That way, if users want a stateful/efficient approach, they can set shell aliases for themselves for different configs:

alias st2-prod="st2 --config prod "
alias st2-staging="st2 --config staging "
alias st2-dev="st2 --config dev "

Either way, if you go with your original idea, please make sure to create the config files as only readable by the user (not their group, and not world readable like we do now).

Is there a particular reason you want st2client config to be stateful instead of using aliases?

blag commented 3 years ago

And to be clear: I wouldn't reject this solution. I even have a use case for it. I'm just questioning if we need to do this on behalf of users, or if using existing tools are good enough. Please don't take my (hopefully mild) skepticism as negativity! 😁

minsis commented 3 years ago

You could use alias but I'm not sure its practical in larger environments. Maybe this just only really applies to my use case, but we have several environments with several clusters. This is what makes something like knife block useful since we probably have about 7 or so Chef servers. Our st2 foot print might grow this large as we grow or migrate; at the moment we're at 5 StackStorm environments and we maybe looking at others when stackstorm-ha comes out of beta, or we have to work in SOX or PCI compliant networks.

So at 5 environments it doesn't feel very practical to have 5 different aliases and needing to remember/use 5 separate commands to execute the same functions.

The st2client package does have a --config option, but again I dont feel like this is very practical in larger environments when you're usually only working in one environment at a time.

In any case I thought it would be a nice feature to have. Plus there could be options for managing the config files this way instead of having users need to create them manually. Something like st2 config set api-url https://someserver.com or st2 config set api-key <somekey>. It gives control to the application and there's no guess work for end users in what needs/can be configured.

Like I said I'm willing to give the development of it a shot if people think its a useful enough feature to have. Otherwise I just stick to something home made like I've done in the past.

nzlosh commented 3 years ago

Taking @blag's idea further, you can have the behaviour you're asking for by adding this to your shell rc file (tested with bash but should work on other shells with small changes):

TEMPLATE_PATH=~/.st2/st2client-config-__ST2ENV__.ini
ST2ENV=""
ST2ENVS=(dev preprod staging prod)

set_st2env() {
    echo "Setting st2env to $1"
    export ST2ENV="$1"
    export ST2CONF="$(echo \"${TEMPLATE_PATH}\" | sed s/__ST2ENV__/$1/g)"
    alias st2="st2 --config $ST2CONF "
}

st2env ()
{
    if [[ -z "$1" ]]; then
        echo $ST2ENV
        return 0
    fi

    if [[ "$1" = "list" ]]; then
        echo "Available environments for st2env (* = current environment)"
        for e in ${ST2ENVS[@]}; do
            local T=""
            if [[ "$e" = "$ST2ENV" ]]; then
                T="*"
            fi
            echo -e "\t${T}${e}"
        done
        return 0
    fi

    for e in ${ST2ENVS[@]}; do
        if [[ "$1" = "$e" ]]; then
            set_st2env "$e"
        fi
    done
    if [[ "$1" != "$ST2ENV" ]]; then
        echo Unsupported environment $1
        return 1
    fi
}

To demonstrate the usage, setting prod and switching to dev:

st2client $ st2env prod
Setting st2env to prod
st2client $ st2env
prod
st2client $ alias st2
alias st2='st2 --config ~/.st2/st2client-config-prod.ini '
st2client $ st2env dev
Setting st2env to dev
st2client $ st2env
dev
st2client $ alias st2
alias st2='st2 --config ~/.st2/st2client-config-dev.ini '
st2client $ st2env list
Available environments for st2env (* = current environment)
    *dev
    preprod
    staging
    prod

You'd update TEMPLATE_PATH to change the configuration location and ST2ENVS when you want to add a new environment.

minsis commented 3 years ago

There's 100 ways to skin this cat. I do this for other tools myself with customized shell or python scripts to do the work. The entire point is to have everything contained in a single command without the thought or need to know anything extra outside of whats provided. It gives control to the app and allows users to change the config as they need to within the parameters of what the st2client app knows.

If no one sees value in this proposal its all good we can just close it.

blag commented 3 years ago

I see the value in this proposal, and I would review and merge it if we had a PR, so I don't think it should be closed yet. Having this supported in st2client would be a nice, user friendly feature, and would ease some of the burden of managing ST2 in multiple environments. I've pinged the ST2 TSC to see if there is anybody else who has opinions on it, but otherwise I would say go for it.

minsis commented 3 years ago

https://github.com/minsis/st2/tree/config-mgr

I started something wanted to see if I was going in the right direction. I didn't want to create a PR since its a WIP and I didn't see a way to set the PR as WIP for some reason. If you want a PR while this is WIP let me know.

Some notes:

Here's a sample of the list command:

(st2client)  [ st2client ] (config-mgr) $ st2 config list       
+----------+------------+-----------------------------------------------+
| selected | name       | filepath                                      |
+----------+------------+-----------------------------------------------+
| yes      | nonprod    | /Users/dwhitney/.st2/st2config-nonprod.ini    |
|          | production | /Users/dwhitney/.st2/st2config-production.ini |
|          | test       | /Users/dwhitney/.st2/st2config-test.ini       |
+----------+------------+-----------------------------------------------+