Create multi-layered json in bash

时间:2019-01-09 21:54:39

标签: json bash

I have a script that puts AWS access keys into secrets manager in AWS.

This is a key rotation script. So the script may encounter either one or two keys that need to be rotated, depending on the user.

The script produces valid json if it prints out only one key:

printf '{"Access Key1":"%s","Secret Key1":"%s"}\n' "$new_access_key1" "$new_secret_key1" > "$ofile"

However, the JSON breaks if you print the second key. If that happens what you end up with is this non-working JSON:

{"Access Key1":"AKIAI7TJSSQMHSAD5UWQ","Secret Key1":"secret-key-contents"}
{"Access Key2":"AKIAJ3ZSNMIVGMVHYEQQ","Secret Key2":"secret-key-contents"}

I want the resulting json to look like this if there's one key:

{
    "Access Keys": {
        "Access Keys 1": {
            "Access Key1": "AKIAI4I2T3ZASJN762KQ",
            "Secret Key1": "secret-key-contents"
        }
    }
}

Or this if it has to print out two keys:

{
    "Access Keys": {
        "Access Keys 1": {
            "Access Key1": "AKIAI4I2T3ZASJN762KQ",
            "Secret Key1": "secret-key-contents"
        },
        "Access Keys 2": {
            "Access Key2": "AKIAI6BAYZQEBA6TTKCQ",
            "Secret Key2": "secret-key-contents"
        }
    }
}

I'm using a variable to store the directory I'm printing out to:

output_dir="../output_files/aws_secrets"

And I'm putting the json into a file that I define with this variable:

ofile="$output_dir"/aws-"$aws_user_name"-"$aws_account"-access-keys.json

I'm creating or updating the aws secret with this function:

store_secret() {
  secret_exists=$(aws secretsmanager list-secrets --max-results 100  --profile company-nonprod  | jq -r '.SecretList[].Name' | grep aws-"$aws_user_name"-"$aws_account"-keys)
  if [[ -z  "$secret_exists" ]]; then
    printf "Creating New AWS Secret:\\n"
    aws secretsmanager create-secret --name aws-"$aws_user_name"-"$aws_account"-keys --description "$aws_user_name's $aws_account Access Keys" --secret-string file://"$ofile" --profile company-nonprod
  else
    printf "Updating AWS Secret:\\n"
    aws secretsmanager update-secret --secret-id aws-"$aws_user_name"-"$aws_account"-keys --secret-string file://"$ofile" --profile company-nonprod
  fi
}

I create the AWS keys with this command that uses jq:

  readarray  -t new_keys < <(aws iam create-access-key --user-name "$aws_user_name" --profile "$aws_account" |  jq -r '.AccessKey | (.AccessKeyId, .SecretAccessKey)')
  new_access_key1="${new_keys[0]}"
  new_secret_key1="${new_keys[1]}"

How can I use print statements to output correctly formatted JSON to the file if the script encounters:

  • One key that needs to be printed out
  • Or two keys that need to be printed out

1 个答案:

答案 0 :(得分:-1)

我需要用完30个字符,但它们全部归结为以下两个字符:jq