Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip #23

Closed
wants to merge 1 commit into from
Closed

wip #23

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
Binary file added .DS_Store
Binary file not shown.
34 changes: 34 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# .env

# Variables de la cuenta de Sysdig
INSTRUQT_SYSDIG_ACCOUNT=training
INSTRUQT_SYSDIG_ACCOUNT_REGION_URL=fasdf
INSTRUQT_SYSDIG_ACCOUNT_USERNAME=asdf
INSTRUQT_SYSDIG_ACCOUNT_PASSWORD=asdf
INSTRUQT_SYSDIG_ACCOUNT_SYSDIG_SECURE_API_TOKEN=asdfasdf
INSTRUQT_SYSDIG_ACCOUNT_SYSDIG_MONITOR_API_TOKEN=asdf

# Cuentas de AWS
INSTRUQT_AWS_ACCOUNTS=
INSTRUQT_AWS_ACCOUNT_%s_ACCOUNT_NAME=
INSTRUQT_AWS_ACCOUNT_%s_ACCOUNT_ID=
INSTRUQT_AWS_ACCOUNT_%s_USERNAME=
INSTRUQT_AWS_ACCOUNT_%s_PASSWORD=
INSTRUQT_AWS_ACCOUNT_%s_AWS_ACCESS_KEY_ID=
INSTRUQT_AWS_ACCOUNT_%s_AWS_SECRET_ACCESS_KEY=

# Proyectos de GCP
INSTRUQT_GCP_PROJECTS=
INSTRUQT_GCP_PROJECT_%s_PROJECT_NAME=
INSTRUQT_GCP_PROJECT_%s_PROJECT_ID=
INSTRUQT_GCP_PROJECT_%s_USER_EMAIL=
INSTRUQT_GCP_PROJECT_%s_USER_PASSWORD=
INSTRUQT_GCP_PROJECT_%s_SERVICE_ACCOUNT_EMAIL=
INSTRUQT_GCP_PROJECT_%s_SERVICE_ACCOUNT_KEY=

# Variables adicionales de Sysdig
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_AGENT_ACCESS_KEY=
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_MONITOR_API_TOKEN=
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_SECURE_API_TOKEN=
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_API_URL=
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_REGION=
15 changes: 9 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM python:3.8

RUN apt-get update && \
RUN apt-get update && apt-get upgrade -y && \
apt-get install --no-install-recommends -y curl lsb-release gnupg apt-utils && \
curl -sS --fail -L https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
echo "deb http://packages.cloud.google.com/apt cloud-sdk-$(lsb_release -c -s) main" > /etc/apt/sources.list.d/google-cloud-sdk.list && \
Expand All @@ -17,21 +17,24 @@ RUN apt-get update && \
RUN echo "source /usr/lib/google-cloud-sdk/completion.bash.inc" >> /etc/bash.bashrc && \
echo "complete -C $(which aws_completer) aws" >> /etc/bash.bashrc && \
echo "source /etc/bash_completion.d/azure-cli" >> /etc/bash.bashrc && \
mkdir -p $HOME/.vim/pack/tpope/start && \
git clone https://tpope.io/vim/sensible.git $HOME/.vim/pack/tpope/start/sensible && \
vim -u NONE -c "helptags sensible/doc" -c q && \
mkdir -p $HOME/.vim/colors && \
curl -sS --fail -L -o $HOME/.vim/colors/basic-dark.vim https://raw.githubusercontent.com/zcodes/vim-colors-basic/master/colors/basic-dark.vim && \
echo "include /usr/share/nano/*" > $HOME/.nanorc

RUN wget https://github.com/cdr/code-server/releases/download/2.1692-vsc1.39.2/code-server2.1692-vsc1.39.2-linux-x86_64.tar.gz -O /tmp/code-server.tar.gz --no-check-certificate && \
tar -xzf /tmp/code-server.tar.gz --strip 1 -C /usr/bin && \
rm /tmp/code-server.tar.gz

RUN curl -LO https://raw.github.com/robertpeteuil/terraform-installer/master/terraform-install.sh && \
chmod +x terraform-install.sh && \
./terraform-install.sh && \
rm terraform-install.sh

ENV PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ENTRYPOINT [ "/opt/instruqt/docker-entrypoint.sh" ]
COPY docker-entrypoint.sh /opt/instruqt/

COPY assets/ /var/www/html/assets/
COPY index.html.tmpl /opt/instruqt/

RUN mkdir -p /opt/sysdig
COPY sysdig/ /opt/sysdig/
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
build:
docker build --pull -t gcr.io/instruqt/cloud-client .
docker build -t pablopez/cloud-client .

push: build
docker push pablopez/cloud-client

test: build
docker run -it --rm \
-e INSTRUQT_SYSDIG_ACCOUNT="true" \
-e INSTRUQT_AWS_ACCOUNTS="AWS1,AWS2" \
-e INSTRUQT_AWS_ACCOUNT_AWS1_ACCOUNT_NAME="AWS 1" \
-e INSTRUQT_AWS_ACCOUNT_AWS1_ACCOUNT_ID="1234567890" \
Expand Down Expand Up @@ -45,4 +49,4 @@ test: build
-e INSTRUQT_AZURE_SUBSCRIPTION_AZURE2_SPN_PASSWORD="spnpass2!@%^" \
-e INSTRUQT_AZURE_SUBSCRIPTION_AZURE2_TENANT_ID="22222222-e1e2-4639-a706-6556470e4046" \
-p 8080:80 \
gcr.io/instruqt/cloud-client
pablopez/cloud-client
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This is the `cloud-client` container, that can be used on the Instruqt platform to interact with the different supported cloud accounts.

Test localy with:

```
make
docker run --env-file .env pablopez/cloud-client:latest
```

## What this does

Expand Down
Binary file added assets/.DS_Store
Binary file not shown.
Binary file added assets/sysdig.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/sysdig.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
223 changes: 223 additions & 0 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
#!/bin/bash

set -euxo pipefail

# Available env vars:

# INSTRUQT_SYSDIG_ACCOUNT
# INSTRUQT_SYSDIG_ACCOUNT_REGION_URL
# INSTRUQT_SYSDIG_ACCOUNT_USERNAME
# INSTRUQT_SYSDIG_ACCOUNT_PASSWORD
# INSTRUQT_SYSDIG_ACCOUNT_SYSDIG_SECURE_API_TOKEN
# INSTRUQT_SYSDIG_ACCOUNT_SYSDIG_MONITOR_API_TOKEN

# INSTRUQT_AWS_ACCOUNTS
# INSTRUQT_AWS_ACCOUNT_%s_ACCOUNT_NAME
# INSTRUQT_AWS_ACCOUNT_%s_ACCOUNT_ID
Expand Down Expand Up @@ -79,6 +89,219 @@ EOF
fi
}

function provision_monitor_user(){

json_file="$WORK_DIR/monitor-operations-team.json"
tmp_file="$WORK_DIR/monitor-operations-team.json.tmp"

MONITOR_OPS_TEAM_ID=$(curl -s -k -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCOUNT_PROVISIONER_SECURE_API_TOKEN}" \
${ACCOUNT_PROVISIONER_SECURE_API_URL}/api/teams \
| jq -r '.[][] | select(.immutable) | select(.products[] | contains("SDC"))| .id')

# get monitor operations team info
curl -s -k -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCOUNT_PROVISIONER_SECURE_API_TOKEN}" \
${ACCOUNT_PROVISIONER_SECURE_API_URL}/api/teams/${MONITOR_OPS_TEAM_ID} \
| jq > "$json_file"

# edits
# remove team, get all other info
jq '.team' "$json_file" > "$tmp_file"
cp "$tmp_file" "$json_file"; rm "$tmp_file"

# remove all users that are role ROLE_TEAM_MANAGER
jq '.userRoles[] |= del(. | select(.role == "ROLE_TEAM_MANAGER"))' "$json_file" > "$tmp_file"
cp "$tmp_file" "$json_file"; rm "$tmp_file"

# clean nulls in .userRoles[]
# del(.[][] | nulls)
jq '.userRoles |= del(.[] | nulls)' "$json_file" > "$tmp_file"
cp "$tmp_file" "$json_file"; rm "$tmp_file"

# remove fields
fields=("properties" "customerId" "dateCreated" "lastUpdated" "userCount")
for field in "${fields[@]}"; do
jq ". |= del(.$field)" "$json_file" > "$tmp_file"
cp "$tmp_file" "$json_file"
done
rm "$tmp_file"

# add fields "searchFilter" "filter"
jq --argjson var null '. + {searchFilter: $var}' "$json_file" > "$tmp_file"
cp "$tmp_file" "$json_file"; rm "$tmp_file"

jq --argjson var null '. + {filter: $var}' "$json_file" > "$tmp_file"
cp "$tmp_file" "$json_file"; rm "$tmp_file"

# add new user to group
# this is not working:
# we should remove existing users (account managers) and push only the new ones.
# the get is returning account_managers
jq '.userRoles[.userRoles| length] |= . + {
"teamId": '${MONITOR_OPS_TEAM_ID}',
"teamName": "Monitor Operations",
"teamTheme": "#7BB0B2",
"userId": '${SPA_USER_ID}',
"userName": "'${SPA_USER}'",
"role": "ROLE_TEAM_STANDARD"
}' "$json_file" > "$tmp_file"
cp "$tmp_file" "$json_file"; rm "$tmp_file"

# update Monitor Operations team with new user assigned
curl -s -k -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCOUNT_PROVISIONER_MONITOR_API_TOKEN}" \
-d @$json_file \
${ACCOUNT_PROVISIONER_MONITOR_API_URL}/api/teams/${MONITOR_OPS_TEAM_ID} \
| jq > /dev/null

}

function provision_secure_user(){

curl -s -k -X POST \
-D headers.txt \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCOUNT_PROVISIONER_SECURE_API_TOKEN}" \
--data-binary '{
"username": "'${SPA_USER}'",
"password": "'${SPA_PASS}'",
"firstName": "Training",
"lastName": "Student",
"systemRole": "ROLE_USER"
}' \
${ACCOUNT_PROVISIONER_SECURE_API_URL}/api/user/provisioning/ \
| jq > $WORK_DIR/account.json

if [ TODO ] # creation succeded
then
touch $WORK_DIR/user_provisioned_COMPLETED

SPA_USER_ID=$(cat $WORK_DIR/account.json | jq .user.id)
SPA_USER_API_TOKEN=$(cat $WORK_DIR/account.json | jq -r .token.key)

curl -s -k -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${SPA_USER_API_TOKEN}" \
--data-binary '[
{
"id": "additionalEnvironments",
"displayQuestion": "What are all the environments your company has?",
"choices": []
},
{
"id": "iacManifests",
"displayQuestion": "Where do you store your Infrastructure as Code manifests?",
"choices": []
},
{
"id": "cicdTool",
"displayQuestion": "What are your CI/CD tools?",
"choices": []
},
{
"id": "notificationChannels",
"displayQuestion": "How do you want to be notified outside of Sysdig?",
"choices": []
}
]' ${ACCOUNT_PROVISIONER_SECURE_API_URL}/api/secure/onboarding/v2/userProfile/questionnaire \
| jq > /dev/null

else
echo "provision_secure_user: failed"
exit 1
fi

}

function generate_random_id () {

if [ ! -f $WORK_DIR/random_string_OK ] # random_id not set
then

mapfile nouns < /opt/sysdig/lab_random_string_id_nouns
mapfile adjectives < /opt/sysdig/lab_random_string_id_adjectives

nounIndex=$RANDOM%$((${#nouns[@]}-1))
adjectiveIndex=$RANDOM%$((${#adjectives[@]}-1))

adjective="$(echo -e "${adjectives[$adjectiveIndex]}" | tr -d '[:space:]')"
noun="$(echo -e "${nouns[$nounIndex]}" | tr -d '[:space:]')"
salt="$(shuf -i 1-99999 -n 1)"
random_id="$adjective"_"$noun"_"$salt"

echo "${random_id}[email protected]" > $WORK_DIR/ACCOUNT_PROVISIONED_USER
#create flag
echo "$random_id" > $WORK_DIR/random_string_OK
agent variable set RANDOM_ID ${random_id}

fi
echo "Random user string from dictionary: $random_id"

# generate random password
# set user/pass
SPA_PASS=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 9 ; echo '')
echo "${SPA_PASS}" > $WORK_DIR/ACCOUNT_PROVISIONED_PASS
agent variable set SPA_PASS ${SPA_PASS}
SPA_USER=$(cat $WORK_DIR/ACCOUNT_PROVISIONED_USER)
agent variable set SPA_USER ${SPA_USER}
agent variable set SPA_SECURE_API_TOKEN ${ACCOUNT_PROVISIONER_SECURE_API_TOKEN}

}

function sysdig_init() {
if [[ -n $INSTRUQT_SYSDIG_ACCOUNT ]]; then
# INPUTs
# TODO, this might not work for those regions
# where no equivalence between Monitor & Secure exists
# testing
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_AGENT_ACCESS_KEY=9f1c06cf-f7ee-45b8-943f-73740472e978
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_MONITOR_API_TOKEN=970a55f3-889e-4c80-9f73-3dba104ccb53
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_SECURE_API_TOKEN=cce028ab-d10b-48e2-92d6-389317d9d92e
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_API_URL=https://us2.app.sysdig.com
INSTRUQT_SECRET_ACCOUNT_PROVISIONER_REGION=2

if [[ -z $INSTRUQT_SECRET_ACCOUNT_PROVISIONER_AGENT_ACCESS_KEY \
|| -z $INSTRUQT_SECRET_ACCOUNT_PROVISIONER_MONITOR_API_TOKEN \
|| -z $INSTRUQT_SECRET_ACCOUNT_PROVISIONER_SECURE_API_TOKEN \
|| -z $INSTRUQT_SECRET_ACCOUNT_PROVISIONER_API_URL \
|| -z $INSTRUQT_SECRET_ACCOUNT_PROVISIONER_REGION \
]]; then
echo 'One or more required variables to provision for this lab are undefined'
exit 1
else
ACCOUNT_PROVISIONER_MONITOR_API_TOKEN=$INSTRUQT_SECRET_ACCOUNT_PROVISIONER_MONITOR_API_TOKEN
ACCOUNT_PROVISIONER_MONITOR_API_URL=$INSTRUQT_SECRET_ACCOUNT_PROVISIONER_API_URL
ACCOUNT_PROVISIONER_SECURE_API_TOKEN=$INSTRUQT_SECRET_ACCOUNT_PROVISIONER_SECURE_API_TOKEN
ACCOUNT_PROVISIONER_SECURE_API_URL=$INSTRUQT_SECRET_ACCOUNT_PROVISIONER_API_URL
ACCOUNT_PROVISIONER_AGENT_ACCESS_KEY=$INSTRUQT_SECRET_ACCOUNT_PROVISIONER_AGENT_ACCESS_KEY
ACCOUNT_PROVISIONER_REGION_NUMBER=$INSTRUQT_SECRET_ACCOUNT_PROVISIONER_REGION_NUMBER
fi

WORK_DIR=/opt/sysdig
WORK_DIR=/tmp/sysdig
TRACK_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd -P )
mkdir -p $WORK_DIR
mkdir -p $TRACK_DIR

# provision user
generate_random_id
provision_secure_user
provision_monitor_user

#set values to present to student in the UI -> OUT
INSTRUQT_SYSDIG_ACCOUNT_USERNAME=${SPA_USER}
INSTRUQT_SYSDIG_ACCOUNT_PASSWORD=${SPA_PASS}
INSTRUQT_SYSDIG_ACCOUNT_REGION_URL=${ACCOUNT_PROVISIONER_SECURE_API_URL}/
INSTRUQT_SYSDIG_ACCOUNT_SECURE_API_TOKEN=${SPA_USER_API_TOKEN}
INSTRUQT_SYSDIG_ACCOUNT_MONITOR_API_TOKEN=${SPA_USER}
fi
}

sysdig_init
aws_init
gcloud_init &
azure_init &
Expand Down
39 changes: 38 additions & 1 deletion index.html.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,51 @@
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Instruqt Cloud Accounts</title>
<title>Training Accounts</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="/assets/main.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/assets/fontawesome/css/all.min.css" />
</head>

<body>
<div class="accountList">


<div class="account sysdigAccount">
<div class="card">
<div class="header">
<div class="logo">
<img alt="icon" src="/assets/sysdig.svg">
</div>
<div class="title">
<h2>Sysdig</h2>
<p>Temporary Training Account</p>
</div>
</div>
<div class="properties">
<div class="key">Account Region:</div>
<div class="value">
<a href="{{ getenv (print "INSTRUQT_SYSDIG_ACCOUNT_REGION_URL") }}" target="_blank">
{{ getenv (print "INSTRUQT_SYSDIG_ACCOUNT_REGION_URL") }}
</a>
</div>
<div class="key">Username:</div>
<div class="value" data-copyable>{{ getenv (print "INSTRUQT_SYSDIG_ACCOUNT_USERNAME") }}</div>

<div class="key">Password:</div>
<div class="value" data-copyable>{{ getenv (print "INSTRUQT_SYSDIG_ACCOUNT_PASSWORD") }}</div>

<div class="key">Sysdig Secure API Token:</div>
<div class="value" data-copyable>{{ getenv (print "INSTRUQT_SYSDIG_ACCOUNT_SECURE_API_TOKEN") }}</div>

<div class="key">Sysdig Monitor API Token:</div>
<div class="value" data-copyable>{{ getenv (print "INSTRUQT_SYSDIG_ACCOUNT_MONITOR_API_TOKEN") }}</div>
</div>
</div>
</div>



{{ if ne (getenv "INSTRUQT_AWS_ACCOUNTS") "" }}
{{ range $i, $a := (.Env.INSTRUQT_AWS_ACCOUNTS | strings.Split ",") }}
<div class="account awsAccount">
Expand Down
Loading