Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,6 @@ dmypy.json
.pyre/

data.json
sg.json
sg.json

*paylod.json
136 changes: 101 additions & 35 deletions shell/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
{
Expand All @@ -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"
]
}
]
}
```

Expand Down
45 changes: 23 additions & 22 deletions shell/sg-cli
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -313,23 +313,24 @@ EOF
}
#}}}

aws_help() { #{{{
integrations_help() { #{{{
cat <<EOF

Configure AWS integration for Stackguardian platform.
Configure Cloud integration for Stackguardian platform.

Examples:
./$(basename "$0") aws integrate --org demo-org -- payload.json
[Integrate Cloud Accounts]
./$(basename "$0") integrations create --org org-name -- payload.json

Sub-commands:
integrate Create AWS integration
create Create Cloud/VCS integration

Options:
--org '': (required)
The organization name on Stackguardian platform for which integration is created.

Usage:
./$(basename "$0") aws <sub-command> --org org-name -- payload
./$(basename "$0") integrations <sub-command> --org org-name -- payload

Use "./$(basename "$0") options" for a list of global command-line options (appiles to all commands).
EOF
Expand Down Expand Up @@ -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" \
Expand Down Expand Up @@ -1214,36 +1216,37 @@ list_artifacts() { #{{{
#}}}

#######################################
# AWS Integrate
# Cloud / VCS Integrate
# Arguments:
# org_id
# payload
# Outputs:
# 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" && \
Expand All @@ -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"
Expand Down Expand Up @@ -1766,11 +1768,9 @@ list_artifacts_parse_response() { #{{{
}
#}}}

integrate_aws_parse_response() { #{{{
# echo "${response}" | jq
create_integrations_parse_response() {
exit 0
}
#}}}

#######################################
# Other support functions
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
;;
*)
Expand Down Expand Up @@ -2098,4 +2099,4 @@ cleanup() { #{{{

trap cleanup INT

main "$@"
main "$@"