diff --git a/.gitignore b/.gitignore index 145d9f6..132f979 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,6 @@ dmypy.json .pyre/ data.json -sg.json \ No newline at end of file +sg.json + +*paylod.json \ No newline at end of file diff --git a/shell/README.md b/shell/README.md index 1307db6..52da2a6 100644 --- a/shell/README.md +++ b/shell/README.md @@ -127,7 +127,7 @@ Example 5: (add new key) ``` ./sg-cli stack create --org demo-org --workflow-group integration-wfgrp --patch-payload '{"custom_key": "custom_value"}' -- payload.json ``` -Payload will look like the follwing: +Payload will look like the following: > new key/value will be added to payload ``` { @@ -137,45 +137,111 @@ Payload will look like the follwing: } ``` -Example 6: Bulk onboard cloud accounts +Example 6: Bulk onboard Cloud/VCS accounts + +Integrating Cloud/VCS Accounts: + ``` -./sg-cli aws integrate --org demo-org -- payload.json +./sg-cli integrations create --org org-name -- payload.json ``` -Payload will look like the follwing: -> It should contain an array of AWS account objects under the key `awsAccounts` +Payload will look like the following for integrating accounts: +> It should contain an array of account objects under the key `Integrations` ``` { - "awsAccounts": [ - { - "ResourceName": "Dummy123", - "Description": "dummy account", - "Settings": { - "kind": "AWS_STATIC", - "config": [ - { - "awsAccessKeyId": "hi-its-me-a-dummy-account", - "awsSecretAccessKey": "keep-your-secrets-safe", - "awsDefaultRegion": "us-east-1" - } - ] - } - }, - { - "ResourceName": "Dummy11345", - "Description": "dummy account", - "Settings": { - "kind": "AWS_STATIC", - "config": [ - { - "awsAccessKeyId": "hi-its-me-a-dummy-account", - "awsSecretAccessKey": "keep-your-secrets-safe", - "awsDefaultRegion": "us-east-1" - } - ] - } - } - ] + "Integrations": [ + { + "ResourceName": "gitlab-sgcli", + "Settings": { + "kind": "GITLAB_COM", + "config": [ + { + "gitlabCreds": "secretUsername:secretAccessToken" + } + ] + } + }, + { + "ResourceName": "azuredevops-sgcli", + "Settings": { + "kind": "AZURE_DEVOPS", + "config": [ + { + "azureCreds": "personalAccessToken" + } + ] + } + }, + { + "ResourceName": "bitbucket-sgcli", + "Settings": { + "kind": "BITBUCKET_ORG", + "config": [ + { + "bitbucketCreds": "userName:appPassword" + } + ] + } + }, + { + "ResourceName": "AWS-STATIC-101", + "Description": "Dummy AWS Account integration using Access Key.", + "Settings": { + "kind": "AWS_STATIC", + "config": [ + { + "awsAccessKeyId": "dummy-accesskey-id", + "awsSecretAccessKey":"keep-your-secret-safe", + "awsDefaultRegion":"us-east-1" + } + ] + }, + "Tags": [ + "aws", + "sg-cli", + "STATIC" + ] + }, + { + "ResourceName": "AWS-RBAC-101", + "Description": "Dummy AWS Account integration using RBAC.", + "Settings": { + "kind": "AWS_RBAC", + "config": [ + { + "externalId": "demo-org:1234567890", + "durationSeconds":"3600", + "roleArn":"arn:aws:iam::account-id:role/role-name" + } + ] + }, + "Tags": [ + "aws", + "sg-cli", + "RBAC" + ] + }, + { + "ResourceName": "AZURE-DUMMY-101", + "Description": "Dummy Azure Account.", + "Settings": { + "kind": "AZURE_STATIC", + "config": [ + { + "armClientSecret": "SECRET-101", + "armClientId":"cscsdcsdcsdcscs101", + "armSubscriptionId":"sdcscdscsdc101", + "armTenantId": "cscsdcsdcsdcscs101" + } + ] + }, + "Tags": [ + "azure", + "sg-cli", + "integration" + ] + } + ] } ``` diff --git a/shell/sg-cli b/shell/sg-cli index c50287d..0283d25 100755 --- a/shell/sg-cli +++ b/shell/sg-cli @@ -119,7 +119,7 @@ Available commands: stack Manage stack resources workflow Manage workflow resources artifacts Manage artifacts - aws Manage aws integration + integrations Manage cloud/vcs provider integration Usage: ./$(basename "$0") [options] -- [payload] @@ -313,23 +313,24 @@ EOF } #}}} -aws_help() { #{{{ +integrations_help() { #{{{ cat < --org org-name -- payload + ./$(basename "$0") integrations --org org-name -- payload Use "./$(basename "$0") options" for a list of global command-line options (appiles to all commands). EOF @@ -361,6 +362,7 @@ parse_response() { #{{{ # get first status code from response status_code="$(echo "$response" \ | awk '/^HTTP/ {print $2; exit}')" + echo $status_code # actual response data response="$(echo "$response" \ @@ -1214,7 +1216,7 @@ list_artifacts() { #{{{ #}}} ####################################### -# AWS Integrate +# Cloud / VCS Integrate # Arguments: # org_id # payload @@ -1222,28 +1224,29 @@ list_artifacts() { #{{{ # Write to STDIN/STDERR # if successfull/error. ####################################### -integrate_aws() { #{{{ - return_response= +create_integrations() { + return_response= if [ -z "${payload}" ] || [ -z "${org_id}" ]; then err "Parameters --org and payload must be provided" exit 1 fi - array_length="$(echo "${payload}" | jq 'if type == "object" then . else empty end | if has("awsAccounts") then .awsAccounts else empty end | length')" + array_length="$(echo "${payload}" | jq 'if type == "object" then . else empty end | if has("Integrations") then .Integrations else empty end | length')" ! exists_or_notnull \ "array_length" \ - "Invalid payload. \`awsAccounts\` key missing in global object." && \ + "Invalid payload. \`Integrations\` key missing in global object." && \ exit 1 i=0 while [ ${i} -lt "${array_length}" ]; do object_payload=$(echo "${payload}" | jq ".[][$i]") - url="${API_URL}/orgs/${org_id}/integrations" + url="${API_URL}/orgs/${org_id}/integrations/" response=$(curl -i -s --http1.1 -X POST \ -H 'PrincipalId: "cli"' \ -H "Authorization: apikey ${API_TOKEN}" \ -H "Content-Type: application/json" \ --data-raw "${object_payload}" "${url}") + echo $response if parse_response; then exists_or_notnull \ "response" && \ @@ -1255,7 +1258,6 @@ integrate_aws() { #{{{ i=$(( $i + 1 )) done } -#}}} get_workflow_outputs() { #{{{ url="${API_URL}/orgs/${org_id}/wfgrps/${wfgrp_id}/wfs/${wf_id}/outputs" @@ -1766,11 +1768,9 @@ list_artifacts_parse_response() { #{{{ } #}}} -integrate_aws_parse_response() { #{{{ - # echo "${response}" | jq +create_integrations_parse_response() { exit 0 } -#}}} ####################################### # Other support functions @@ -1840,7 +1840,8 @@ init() { #{{{ exists_or_notnull() { #{{{ var=$1 - if [ -z "${!var}" ] || [ "${!var}" = "null" ]; then + value=$(eval echo \$$var) + if [ -z "$value" ] || [ "$value" = "null" ]; then if [ "$2" != "" ] || [ -n "$2" ]; then err "$2" fi @@ -1885,7 +1886,7 @@ main() { #{{{ #}}} #{{{ Check Inputs -if [ -z "${API_TOKEN}" ] || [ "sgu_" != "${API_TOKEN:0:4}" ]; then +if [ -z "${API_TOKEN}" ] || [ "sgu_" != "$(echo ${API_TOKEN} | cut -c1-4)" ]; then err "Invalid or no API Token provided. Expecting it in \"SG_API_TOKEN\" environment variable. Navigate to StackGuardian platform to get your api token: ${DASHBOARD_URL}/orgs/${org}/settings?tab=api_key" exit 1 fi @@ -1962,15 +1963,15 @@ case "$1" in exit 1 esac ;; - aws) + integrations) service="$1" case "$2" in - integrate) + create) service_option="$2" shift 2 ;; help | --help | -h) - aws_help + integrations_help exit 0 ;; *) @@ -2098,4 +2099,4 @@ cleanup() { #{{{ trap cleanup INT -main "$@" +main "$@" \ No newline at end of file