From 6f2bcc189c48a589099fe40eaeea8a0e32486093 Mon Sep 17 00:00:00 2001 From: jinal--shah Date: Sat, 24 Nov 2018 16:07:01 +0000 Subject: [PATCH 1/3] preserve before generating docco --- bash/habitual/secrets.functions | 92 +++++++++++++++++++++++++++++++++ bash/habitual/secrets/ssm | 0 bash/habitual/std.functions | 70 +++++++++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 bash/habitual/secrets.functions create mode 100644 bash/habitual/secrets/ssm diff --git a/bash/habitual/secrets.functions b/bash/habitual/secrets.functions new file mode 100644 index 0000000..5939617 --- /dev/null +++ b/bash/habitual/secrets.functions @@ -0,0 +1,92 @@ +# vim: et sr sw=4 ts=4 smartindent syntax=sh: +# +# @overview +# > +# > agnostic public interface for pluggable secrets management functions. +# > + +# ... defines user-defined provider e.g. ssm - see [known_providers()](#known_providers) +SECRETS_PROVIDER="${SECRETS_PROVIDER,,}" + +__SECRETS_HANDLERS_DIR="$(cd $(dirname $BASH_SOURCE) && pwd)/secrets" + +# @desc Configures secrets management functions to use the expected provider. +# +# Pass a valid secrets provider. See [known_providers()](#known_providers) for getting the list. +# Sets `$SECRETS_PROVIDER` for the user. +set_secrets_provider() { + local p="$1" + __valid_provider "$p" || return 1 + export SECRETS_PROVIDER="$p" + return 0 +} + +__valid_provider() { + local p="$1" # ... provider name + local handler_file="$__SECRETS_HANDLERS_DIR/$p" + + [[ -z "$p" ]] && red_e "expects a provider name for secrets management." && return 1 + + if ! known_providers | grep -Po "(\b$p\b)" >/dev/null + then + red_e "valid provider names are:\n$(known_providers)" + return 1 + fi + + # check file exists for sourcing + if [[ ! -r "$handler_file" ]]; then + red_e "readable handler file not found at $handler_file." + return 1 + fi + + ! . $handler_file && red_e "unable to source $handler_file" && return 1 + + __imported_required_funcs "$p" || return 1 + + return 0 +} + +# @desc Prints supported secrets providers to STDOUT. +# +# We expect a file named after this provider that contains [required functions](#required_funcs). +# +# This is verified when [set_secrets_provider()](#set_secrets_provider) is run. +# +known_providers() { + cat << EOF | sort | uniq + credstash + ssm +EOF +} + +__imported_required_funcs() { + local p="$1" # provider + local func="" failed="" rc=0 + + for func in $(required_funcs) ; do + if ! declare -f ${func} &>/dev/null + then + failed="${failed}function missing: ${func}\n" + rc=1 + fi + done + + if [[ $rc -eq 1 ]]; then + red_e "provider $p not implemented correctly:\n$failed" + fi + + return $rc +} + +# @desc Prints names of functions that must be defined. +# We expect them to be defined in the provider's handler file - +# the file that [set_secrets_provider()](#set_secrets_provider) sources. +# +required_funcs() { + cat < Date: Sat, 24 Nov 2018 16:57:19 +0000 Subject: [PATCH 2/3] added secrets public api functions, more habitual string functions and related docco --- bash/habitual/secrets.functions | 2 +- bash/habitual/secrets.functions.md | 56 ++++++++++++++++++++++ bash/habitual/std.functions.md | 77 ++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 bash/habitual/secrets.functions.md diff --git a/bash/habitual/secrets.functions b/bash/habitual/secrets.functions index 5939617..08073f7 100644 --- a/bash/habitual/secrets.functions +++ b/bash/habitual/secrets.functions @@ -23,7 +23,7 @@ set_secrets_provider() { __valid_provider() { local p="$1" # ... provider name - local handler_file="$__SECRETS_HANDLERS_DIR/$p" + local handler_file="$__SECRETS_HANDLERS_DIR/${p}.functions" [[ -z "$p" ]] && red_e "expects a provider name for secrets management." && return 1 diff --git a/bash/habitual/secrets.functions.md b/bash/habitual/secrets.functions.md new file mode 100644 index 0000000..f6b8997 --- /dev/null +++ b/bash/habitual/secrets.functions.md @@ -0,0 +1,56 @@ +# habitual/secrets.functions + +> +> agnostic public interface for pluggable secrets management functions. +> + +* [GLOBALS](#globals) + +* [FUNCTIONS](#functions) + +--- + +# GLOBALS + +* `$SECRETS_PROVIDER`: _... defines user-defined provider e.g. ssm - see [known\_providers()](#known\_providers)_ + * reads env var `$SECRETS_PROVIDER,,` + + + +# FUNCTIONS + +* [set\_secrets\_provider()](#set_secrets_provider) +* [known\_providers()](#known_providers) +* [required\_funcs()](#required_funcs) + +--- + +### set\_secrets\_provider() + +Configures secrets management functions to use the expected provider. + +Pass a valid secrets provider. See [known_providers()](#known_providers) for getting the list. +Sets `$SECRETS_PROVIDER` for the user. + +--- + +### known\_providers() + +Prints supported secrets providers to STDOUT. + +We expect a file named after this provider that contains [required functions](#required_funcs). + +This is verified when [set_secrets_provider()](#set_secrets_provider) is run. + + +--- + +### required\_funcs() + +Prints names of functions that must be defined. +We expect them to be defined in the provider's handler file - +the file that [set_secrets_provider()](#set_secrets_provider) sources. + + +--- + diff --git a/bash/habitual/std.functions.md b/bash/habitual/std.functions.md index dc2ec7b..32bcaa8 100644 --- a/bash/habitual/std.functions.md +++ b/bash/habitual/std.functions.md @@ -35,6 +35,10 @@ * [envsubst\_tokens\_list()](#envsubst_tokens_list) * [random\_str()](#random_str) * [semver\_a\_ge\_b()](#semver_a_ge_b) +* [multiline\_to\_single()](#multiline_to_single) +* [single\_to\_multiline()](#single_to_multiline) +* [base64\_encode()](#base64_encode) +* [base64\_decode()](#base64_decode) * [export\_build\_url()](#export_build_url) ## LOG MESSAGE FUNCTIONS --- @@ -222,6 +226,79 @@ semver_a_ge_b 0.99.0-beta V0.99.0-alpha # true (as beta beats alpha) ``` +--- + +### multiline\_to\_single() + +Concatenates a multiline string, converting newlines to \n + +STDOUT: concatenated line +*NOTE: the argument is double quoted if a variable, to preserve real newlines.* + +#### Example + +```bash +my_str="This is +a multiline string" +multiline_to_single "$my_str" + +# ... would print something like: +# This is\na multiline string + +``` + + +--- + +### single\_to\_multiline() + +Splits a string on '\n' to multiple lines with real newlines. + +STDOUT: Multiple lines + +These are an alternative to the `base64_encode` and +`base64_decode` functions, for example, when base64 produces +too long a string. Try storing an ssh key in AWS parameter store +and see what I mean ... + +#### Example + +```bash +my_str="This will be\na multiline string" +single_to_multiline "$my_str" + +# ... would print something like: +# This will be +# a multiline string + +``` + + +--- + +### base64\_encode() + +Encodes a string (or mulitline string) as Base64 + +You can use this and `base64_decode` when you need to pass +or store multiline strings as a single line. + +These are an alternative to the `single_to_multiline` and +`multiline_to_single` functions when you wish to preserve existing +'\n' instances in your strings, and not convert them to newlines +or vice-versa. + + +--- + +### base64\_decode() + +Decodes a base64 string + +You can use this and `base64_decode` when you need to pass +or store multiline strings as a single line. + + --- ### export\_build\_url() From 4ce6ad60be2e66927421b1411ed81bbdc2efe6d7 Mon Sep 17 00:00:00 2001 From: jinal--shah Date: Sat, 24 Nov 2018 17:34:28 +0000 Subject: [PATCH 3/3] added an example secrets handler --- bash/habitual/secrets.functions | 12 ++++++++- bash/habitual/secrets/ssm | 0 bash/habitual/secrets/ssm.functions | 24 +++++++++++++++++ bash/habitual/secrets/ssm.functions.md | 36 ++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) delete mode 100644 bash/habitual/secrets/ssm create mode 100644 bash/habitual/secrets/ssm.functions create mode 100644 bash/habitual/secrets/ssm.functions.md diff --git a/bash/habitual/secrets.functions b/bash/habitual/secrets.functions index 08073f7..9a57fd4 100644 --- a/bash/habitual/secrets.functions +++ b/bash/habitual/secrets.functions @@ -17,10 +17,21 @@ __SECRETS_HANDLERS_DIR="$(cd $(dirname $BASH_SOURCE) && pwd)/secrets" set_secrets_provider() { local p="$1" __valid_provider "$p" || return 1 + __run_init "$p" || return 1 export SECRETS_PROVIDER="$p" return 0 } +__run_init() { + if declare -f "${p}_init" &>/dev/null + then + d "running init function ${p}_init()" + ${p}_init || return 1 + fi + + return 0 +} + __valid_provider() { local p="$1" # ... provider name local handler_file="$__SECRETS_HANDLERS_DIR/${p}.functions" @@ -85,7 +96,6 @@ __imported_required_funcs() { required_funcs() { cat < +# > Functions for interacting with AWS SSM parameter store secret values. + +# @desc TODO ... we must check that the aws libs have been sourced. +# This function gets loaded automatically when +# [set_secrets_provider()](../secrets.functions.md#set_secrets_provider) is run. +ssm_init() { + # ... check that AWS libs are loaded + # ... check that aws cli exists on path + : +} + +# @desc TODO ... for a given param name, get the secret +get_secret() { + : +} + +# @desc TODO ... set a value for a given param name +put_secret() { + : +} diff --git a/bash/habitual/secrets/ssm.functions.md b/bash/habitual/secrets/ssm.functions.md new file mode 100644 index 0000000..8decb2c --- /dev/null +++ b/bash/habitual/secrets/ssm.functions.md @@ -0,0 +1,36 @@ +# habitual/secrets/ssm.functions + +> +> Functions for interacting with AWS SSM parameter store secret values. + +--- + + +# FUNCTIONS + +* [ssm\_init()](#ssm_init) +* [get\_secret()](#get_secret) +* [put\_secret()](#put_secret) + +--- + +### ssm\_init() + +TODO ... we must check that the aws libs have been sourced. +This function gets loaded automatically when +[set_secrets_provider()](../secrets.functions.md#set_secrets_provider) is run. + +--- + +### get\_secret() + +TODO ... for a given param name, get the secret + +--- + +### put\_secret() + +TODO ... set a value for a given param name + +--- +