Passing optional parameters to rundeck script

5.8k views Asked by At

I have a python script that I would like to run using rundeck that is invoked as follows:

createInstance.py [-n <name>] <env> <version>

Where name is optional and env and version are required.

e.g. if I want to call the script with a name I would call:

createInstance.py -n test staging 1.2.3.4

If I want to default the name, I would call:

createInstance.py staging 1.2.3.4

The problem i have is that I dont know how to specify the script arguments string in rundeck. I have a job, with 3 options, one for env, version and name and if I define the arguments string as:

-n ${option.name} ${option.env} ${option.version}

Whenever the name is unset, rundeck calls:

createInstance.py -n staging 1.2.3.4

Instead I would like it to omit the -n. Is there any way of doing this? Right now my only option is to change the script to be more forgiving in how it handles the -n, and to always ensure its at the end, e.g.:

createInstance.py staging 1.2.3.4 -n 
createInstance.py staging 1.2.3.4 -n test

I would like to avoid making this change though, as I want to be able to use the scripts standalone as well.

4

There are 4 answers

0
Aaron Tobias On

I tried the shell optional argument expansion but it didn't work.

For python I recommend to use argparse with inline script rundeck variables which optionally can take in an argument list:

# Create an ArgumentParser object
parser = argparse.ArgumentParser()
 
# Add optional keyword argument
parser.add_argument('-n', type=str)
# ...add the other positional arguments ...

# Allow args to work inside or outside rundeck
args = [
   "-n",
   "@option.RD_OPTION_NAME@"
   ...
] is len(sys.argv) < 2 else sys.argv[1:]
 
# Parse the command-line arguments
processed_args = parser.parse_args(args)

args = processed_args.__dict__

process(**args)
0
tr3w On

Use an inline script and use conditional variable expansion feature from bash.

createInstance.py ${RD_OPTION_NAME:+-n $RD_OPTION_NAME} $RD_OPTION_ENV $RD_OPTION_VERSION

This will omit the first option altogether if it is empty ("").

0
Alex-SF On

Rather than use a command step, try an inline script step. Your inline script can count the number of arguments and if they are set. Then with that logic you can choose how to set the creteInstance.py args.

0
gaddman On

As @Alex-SF suggests, I've also used an inline script for this, along with a Key Value Data log filter. The script is:

#!/bin/bash
# Parse optional parameters
# https://stackoverflow.com/questions/41233996/passing-optional-parameters-to-rundeck-script
# Arguments to this script should be in the format "flag" "value", eg "-p" ${option.name}
# If value is not missing then return will be "flag value", otherwise blank

echo -n "RUNDECK:DATA:"
while (( "$#" )); do
    flag="$1"
    value="$2"
    if [[ -z "$value" ]] || [[ $value =~ ^\- ]]; then
        # no value for this parameter (empty or picking up the next flag)
        echo -n ""
        shift
    else
        # value provided for this parameter
        echo -n "$flag $value "
        shift
        shift
    fi
done

And the key value data filter uses the pattern ^RUNDECK:DATA:(.*)$ and the name data args. Then I use ${data.args*} as the input for the real command.

It's all rather messy, and I can't find any open issue requesting this as a feature (yet).