Categorygithub.com/rhpds/sandbox
repository
1.0.2
Repository: https://github.com/rhpds/sandbox.git
Documentation: pkg.go.dev

# Packages

No description provided by the author

# README

= Sandbox = :toc:

This repository is a consolidated codebase for everything related to sandboxes for the Red Hat Demo Platform. It contains:

  • sandbox-api: The Backend API for all things sandbox.
  • sandbox-issue-jwt: CLI to generate a new signed JWT login token
  • sandbox-list: Interact with the AWS Sandbox DB in a read-only way.
  • sandbox-metrics: Prometheus Endpoint exposing metrics.
  • sandbox-replicate: AWS Lambda function to replicate changes from DynamoDB to a Postgres database.
  • sandbox-rotate-vault: Program to reencrypt the IAM keys using a new secret key (ansible-vault, AES256)

== Build ==

.Build all binaries

You will need to have 'go' setup on your machine. Please use version 1.22 onwards

make

.Build separately

make sandbox-api make sandbox-list make sandbox-metrics make sandbox-replicate make sandbox-issue-jwt make sandbox-rotate-vault

== sandbox-api ==

=== Installation ===

Create a secret file and run helm.

.secrets.yaml

sandbox_api_secrets: database: url: postgres://... dynamodb_aws_access_key_id: ... dynamodb_aws_secret_access_key: ...

Secret to generate and validate JWT tokens

auth: jwt_auth_secret: ...

ansible-vault (AES256) key to encrypt the secret in the DB

vault: vault_secret: ...

AWS usser that can assume role into the accounts

aws: assume_aws_access_key_id: ... assume_aws_secret_access_key: ...

.Install chart

helm install -f secrets.yaml sandbox-api deploy/helm-api/

.Upgrade chart

helm upgrade -f secrets.yaml sandbox-api deploy/helm-api/

To initialize or update the postgresql schema, use the following:

.Run the DB migration

oc run admin-$$
--image=quay.io/rhpds/sandbox-admin:latest -i -t
--restart=Never --rm -- /bin/bash <1>

DATABASE_URL=postgres://postgres:PASSWORD@RDS_ADDRESS.us-west-2.rds.amazonaws.com:5432/sandbox_api_dev?sslmode=require

git clone https://github.com/rhpds/sandbox.git

cd sandbox

migrate github://rhpds/sandbox/db/migrations#VERSION -database $DATABASE_URL up

For example

migrate
-source github://rhpds/sandbox/db/migrations#main
-database $DATABASE_URL up

<1> Use the rhpds/sandbox-admin image which contains all the necessary binaries and tools.

.Bootstrap an admin login token

oc run admin-$$ --image=quay.io/rhpds/sandbox-admin:latest -i -t --restart=Never --rm -- /bin/bash

export DATABASE_URL=postgres://postgres:PASSWORD@RDS_ADDRESS.us-west-2.rds.amazonaws.com:5432/sandbox_api_dev?sslmode=require

./sandbox-issue-jwt [root@admin sandbox]# ./sandbox-issue-jwt JWT Auth secret: Enter Claims in the JSON format: for example: {"kind": "login", "name": "gucore", "role": "admin"} {"kind": "login", "name": "gucore", "role": "admin"} token: [TOKEN HERE]

.Create an access token

oc run admin-$$ --image=quay.io/rhpds/sandbox-admin:latest -i -t --restart=Never --rm -- /bin/bash

logintoken=[TOKEN]

curl -H "Authorization: Bearer ${logintoken}" sandbox-api:8080/api/v1/login

[ACCESS TOKEN]

token=[ACCESS TOKEN]

check access

curl -H "Authorization: Bearer ${token}" sandbox-api:8080/api/v1/health

=== Setup local development environment ===

All filed used for the local development environment are prefixed by .dev and are ignored by Git, see link:.gitignore[.gitignore]

[source,shell]

make run-local-pg # run postgresql locally in a Container make migrate # Run the DB migrations to setup the db schema

Set the following secrets, notice the heading space ' ' to avoid shell history

IAM secrets to access AWS sandboxes

export ASSUMEROLE_AWS_SECRET_ACCESS_KEY=... export ASSUMEROLE_AWS_ACCESS_KEY_ID=...

IAM secrets to access dynamodb table that contains info of the AWS sandboxes

export AWS_ACCESS_KEY_ID=... export AWS_SECRET_ACCESS_KEY=...

AES key to encrypt sensible data in the different databases

If you're using the dynamoDB dev database for AWS sandboxes (which you probably are)

Then this needs to match the one in use on the DEV environment

export VAULT_SECRET=...

make tokens # issue some JWT token for access make run-api # <1> air # <2>


<1> When iterating, you will be stopping and relaunching this step <2> You can use link:https://github.com/cosmtrek/air[cosmtrek/air] instead. That will watch local files and rebuild + launch the API automatically if any changes are made.

== sandbox-replicate ==

The role of the lambda function is to replicate any changes made to the dynamoDB table into a postgresql database.

=== Push lambda ===


export AWS_PROFILE=infra-dev make push-lambda

That will:

. Create a role, a policy and a lambda function . Attach the policy to the role and the role to the lambda function . Push the updated 'build/sandbox-replicate' binary to the lambda function

== sandbox-metrics ==

=== Deploy Metrics Prometheus ===

. clone this repository +

git clone --depth 1 https://github.com/rhpds/sandbox sandbox

. If it doesn't exist yet, create an IAM user in AWS to read-only access to dynamoDB . Create the secret file containing the key for the IAM user that has read-only access to DynamoDB + [source,yaml] .aws_sandbox_readonly.yaml

aws_sandbox_metrics_secrets: readonly: aws_access_key_id: ... aws_secret_access_key: ...

. Install the helm chart +

helm install sandbox-metrics sandbox/deploy/helm-metrics/ -f aws_sandbox_readonly.yaml

Output should look like: +

NAME: sandbox-metrics LAST DEPLOYED: Thu Jun 17 09:30:04 2021 NAMESPACE: user-gucore-redhat-com STATUS: deployed REVISION: 1 TEST SUITE: None

== Create AWS sandboxes ==

Use link:playbooks[ansible playbooks].

== Conan - Sandbox Cleanup Daemon ==

See link:conan[conan].

== Add a new OCP shared cluster for OcpSandbox

In order for the sandbox API to be able to talk to the OCP shared cluster, you need to create a new OcpSharedClusterConfiguration.

That configuration holds the information needed to authenticate to the cluster and the additional variables that will be passed to the deployer when a sandbox is scheduled on that cluster.

There is 2 ways to authenticate to the cluster: . Using a service Bearer Token . Using a kubeconfig file

Here we'll be describing the first method.

On the cluster, create an admin service account


oc create serviceaccount sandbox-api-admin -n kube-system oc create clusterrolebinding sandbox-api-admin -n kube-system --clusterrole=cluster-admin --serviceaccount=kube-system:sandbox-api-admin oc create token sandbox-api-admin -n kube-system --duration=4294967296s

Then create a JSON file describing the OcpSharedClusterConfiguration. For example:

[source,text] .clustername.json

{ "name": "clustername", <1> "api_url": "https://api...:6443", <2> "ingress_domain": "apps...", "additional_vars": { ... <3> }, "annotations": { "virt":"no", "cloud":"aws", "purpose":"dev" }, <4> "token":"..." <5> }

<1> The name of the cluster as it will be saved in the database <2> The API URL of the cluster <3> Additional variables that will be passed to the deployer if that cluster is elected when scheduling a sandbox <4> Annotations are used to filter the clusters when ordering. For example, if you want to deploy a sandbox on a cluster that is not in production, you can use the purpose annotation to filter out the production clusters. That is done in agnosticV using the __meta__.sandboxes[].cloud_selector key <5> The token is the token created in the previous step. It is used to authenticate the Sandbox API to the cluster.

Then use hurl and ./tools/ocp_shared_cluster_configuration_create.hurl


hurl --variable login_token_admin=$admintoken
--file-root .
--variable host=SANDBOX_API_ADRESS \ <1> --variable ocp_cluster_def=clustername.json
./tools/ocp_shared_cluster_configuration_create.hurl

or with curl directly

accesstoken=$(curl -s --header "Authorization: Bearer $admintoken" --header 'Content-Type: application/json' 'https://SANDBOX_API_ADDRESS/api/v1/login'|jq -r .access_token)

curl --header "Authorization: Bearer $accesstoken"
--header 'Content-Type: application/json'
--data-binary '@./clustername.json'
'https://SANDBOX_API_ADDRESS/api/v1/ocp-shared-cluster-configurations'

<1> Replace SANDBOX_API_ADDRESS with the address of the Sandbox API