Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jayonthenet committed Aug 20, 2024
0 parents commit 46f0633
Show file tree
Hide file tree
Showing 26 changed files with 1,168 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.github
setup/terraform/.terraform*
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
53 changes: 53 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: ci
on:
push:

jobs:
run:
runs-on: ubuntu-latest
steps:

# Prepare

- name: Checkout
uses: actions/checkout@v4
- name: Setup Humanitec CLI
uses: humanitec/setup-cli-action@v1
with:
version: "0.21.1"
- name: Setup tflit
uses: terraform-linters/setup-tflint@v4
with:
tflint_version: v0.49.0
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Validate

- name: Lint
run: make lint
- name: Simulate a humctl login
run: |
yq e -n '.token = "'"${HUMANITEC_TOKEN}"'"' > ~/.humctl
env:
HUMANITEC_TOKEN: ${{ secrets.HUMANITEC_TOKEN }}
- name: Test
run: make test
env:
HUMANITEC_ORG: ${{ secrets.HUMANITEC_ORG }}

# Push

- if: github.ref == 'refs/heads/main'
name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- if: github.ref == 'refs/heads/main'
name: Push image
run: make push
94 changes: 94 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
kube/*

# Created by https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,terraform
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,visualstudiocode,terraform

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud

### Terraform ###
# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files, which are likely to contain sensitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
*.tfvars
*.tfvars.json

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide

# End of https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode,terraform
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"yaml.schemas": {
"https://raw.githubusercontent.com/score-spec/schema/main/score-v1b1.json": "score.yaml",
"https://json.schemastore.org/yamllint.json": "setup/kind/cluster.yaml"
}
}
170 changes: 170 additions & 0 deletions 0_install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/usr/bin/env bash
set -eo pipefail

mkdir -p /state/kube

# 1. Create registry container unless it already exists
reg_name='kind-registry'
reg_port='5001'
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
docker run \
-d --restart=always -p "127.0.0.1:${reg_port}:5000" --network bridge --name "${reg_name}" \
registry:2
fi

# 2. Create Kind cluster
if [ ! -f /state/kube/config.yaml ]; then
kind create cluster -n 5min-idp --kubeconfig /state/kube/config.yaml --config ./setup/kind/cluster.yaml
fi

# connect current container to the kind network
container_name="5min-idp"
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${container_name}")" = 'null' ]; then
docker network connect "kind" "${container_name}"
fi

# used by humanitec-agent / inside docker to reach the cluster
kubeconfig_docker=/state/kube/config-internal.yaml
kind export kubeconfig --internal -n 5min-idp --kubeconfig "$kubeconfig_docker"

### Export needed env-vars for terraform
export TF_VAR_humanitec_org=$HUMANITEC_ORG
# Aim for service user if present, otherwise use current user token (max 24h validity)
if [ -z "$HUMANITEC_SERVICE_USER" ]; then
export TF_VAR_humanitec_token=$HUMANITEC_SERVICE_USER
else
export TF_VAR_humanitec_token=$(yq -r '.token' ~/.humctl)
fi
# Variables for TLS in Terraform
export TF_VAR_tls_ca_cert=$TLS_CA_CERT
export TF_VAR_tls_cert_string=$TLS_CERT_STRING
export TF_VAR_tls_key_string=$TLS_KEY_STRING
# Kubeconfig for Terraform
export TF_VAR_kubeconfig=$kubeconfig_docker

terraform -chdir=setup/terraform init -upgrade
terraform -chdir=setup/terraform apply -auto-approve

# Create Gitea Runner for Actions CI
RUNNER_TOKEN=""
while [[ -z $RUNNER_TOKEN ]]; do
response=$(curl -k -s -X 'GET' 'https://5min-idp-control-plane/api/v1/admin/runners/registration-token' -H 'accept: application/json' -H 'authorization: Basic NW1pbmFkbWluOjVtaW5hZG1pbg==')
if [[ $response == *"token"* ]]; then
RUNNER_TOKEN=$(echo $response | jq -r '.token')
fi
sleep 1
done

# Start Gitea Runner
docker volume create gitea_runner_data
docker create \
--name gitea_runner \
-v gitea_runner_data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
-e CONFIG_FILE=/config.yaml \
-e GITEA_INSTANCE_URL=https://5min-idp-control-plane \
-e GITEA_RUNNER_REGISTRATION_TOKEN=$RUNNER_TOKEN \
-e GITEA_RUNNER_NAME=local \
-e GITEA_RUNNER_LABELS=local \
--network kind \
gitea/act_runner:latest
sed 's|###ca-certficates.crt###|'"$TLS_CA_CERT"'|' setup/gitea/config.yaml > setup/gitea/config.done.yaml
docker cp setup/gitea/config.done.yaml gitea_runner:/config.yaml
docker start gitea_runner

# Create Gitea org and Backstage clone with configuration
curl -k -X 'POST' \
'https://5min-idp-control-plane/api/v1/orgs' \
-H 'accept: application/json' \
-H 'authorization: Basic NW1pbmFkbWluOjVtaW5hZG1pbg==' \
-H 'Content-Type: application/json' \
-d '{
"repo_admin_change_team_access": true,
"username": "5minorg",
"visibility": "public"
}'
curl -k -X 'POST' \
'https://5min-idp-control-plane/api/v1/repos/migrate' \
-H 'accept: application/json' \
-H 'authorization: Basic NW1pbmFkbWluOjVtaW5hZG1pbg==' \
-H 'Content-Type: application/json' \
-d '{
"clone_addr": "https://github.com/humanitec-architecture/backstage.git",
"mirror": false,
"private": false,
"repo_name": "backstage",
"repo_owner": "5minorg"
}'
curl -k -X 'POST' \
'https://5min-idp-control-plane/api/v1/orgs/5minorg/actions/variables/CLOUD_PROVIDER' \
-H 'accept: application/json' \
-H 'authorization: Basic NW1pbmFkbWluOjVtaW5hZG1pbg==' \
-H 'Content-Type: application/json' \
-d '{
"value": "5min"
}'
curl -k -X 'POST' \
'https://5min-idp-control-plane/api/v1/orgs/5minorg/actions/variables/HUMANITEC_ORG_ID' \
-H 'accept: application/json' \
-H 'authorization: Basic NW1pbmFkbWluOjVtaW5hZG1pbg==' \
-H 'Content-Type: application/json' \
-d '{
"value": "'$HUMANITEC_ORG'"
}'
humanitec_app_backstage=$(terraform -chdir=setup/terraform output -raw humanitec_app_backstage)
curl -k -X 'POST' \
'https://5min-idp-control-plane/api/v1/orgs/5minorg/actions/variables/HUMANITEC_APP_ID' \
-H 'accept: application/json' \
-H 'authorization: Basic NW1pbmFkbWluOjVtaW5hZG1pbg==' \
-H 'Content-Type: application/json' \
-d '{
"value": "'$humanitec_app_backstage'"
}'
### TODO -> Use from env if present instead of extracting
curl -k -X 'PUT' \
'https://5min-idp-control-plane/api/v1/orgs/5minorg/actions/secrets/HUMANITEC_TOKEN' \
-H 'accept: application/json' \
-H 'authorization: Basic NW1pbmFkbWluOjVtaW5hZG1pbg==' \
-H 'Content-Type: application/json' \
-d '{
"data": "'$TF_VAR_humanitec_token'"
}'

# 3. Add the registry config to the nodes
#
# This is necessary because localhost resolves to loopback addresses that are
# network-namespace local.
# In other words: localhost in the container is not localhost on the host.
#
# We want a consistent name that works from both ends, so we tell containerd to
# alias localhost:${reg_port} to the registry container when pulling images
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
for node in $(kind get nodes -n 5min-idp); do
docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
[host."http://${reg_name}:5000"]
EOF
done

# 4. Connect the registry to the cluster network if not already connected
# This allows kind to bootstrap the network but ensures they're on the same network
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
docker network connect "kind" "${reg_name}"
fi

# 5. Document the local registry
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: local-registry-hosting
namespace: kube-public
data:
localRegistryHosting.v1: |
host: "localhost:${reg_port}"
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF

echo ""
echo ">>>> Everything prepared, ready to deploy application."
24 changes: 24 additions & 0 deletions 1_demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -eo pipefail

echo "Deploying workload"

humanitec_app=$(terraform -chdir=setup/terraform output -raw humanitec_app)

humctl score deploy --app "$humanitec_app" --env 5min-local -f ./score.yaml --wait

workload_host=$(humctl get active-resources --app "$humanitec_app" --env 5min-local -o yaml | yq '.[] | select(.metadata.type == "route") | .status.resource.host')

echo "Waiting for workload to be available"

# manually change the host here as the workload host resolves to localhost, which is not reachable from the container
if curl -I --retry 30 --retry-delay 3 --retry-all-errors --fail \
--connect-to "$workload_host:30080:5min-idp-control-plane:30080" \
"http://$workload_host:30080"; then
echo "Workload available at: http://$workload_host:30080"
else
echo "Workload not available"
kubectl get pods --all-namespaces
kubectl -n "$humanitec_app-development" logs deployment/hello-world
exit 1
fi
27 changes: 27 additions & 0 deletions 2_cleanup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -eo pipefail

# connect current container to the kind network
container_name="5min-idp"
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${container_name}")" = 'null' ]; then
docker network connect "kind" "${container_name}"
fi

kubeconfig_docker=/state/kube/config-internal.yaml

export TF_VAR_humanitec_org=$HUMANITEC_ORG
export TF_VAR_kubeconfig=$kubeconfig_docker

terraform -chdir=setup/terraform init -upgrade
terraform -chdir=setup/terraform destroy -auto-approve

kind delete cluster -n 5min-idp

docker stop gitea_runner
docker rm gitea_runner
docker volume rm gitea_runner_data

docker stop kind-registry
docker rm kind-registry

rm -rf /state/kube
Loading

0 comments on commit 46f0633

Please sign in to comment.