diff --git a/.woodpecker.yml b/.woodpecker.yml index 89996ac..e5ca18b 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -6,7 +6,7 @@ steps: image: alpine commands: - apk add --no-cache git bash curl yq - - bash automation/main.sh + - bash cloudflared-sync.sh environment: GIT_TOKEN: from_secret: GIT_TOKEN diff --git a/automation/clone_repos.sh b/automation/clone_repos.sh deleted file mode 100644 index 078181c..0000000 --- a/automation/clone_repos.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -echo "Cloning from $INFRA_REPO_URL" - - -echo "đŸ“Ļ Cloning sandbox-apps..." -git clone --depth=1 "$SANDBOX_REPO_URL" "$SANDBOX_CLONE" - -echo "đŸ“Ļ Cloning infra..." -git clone --depth=1 "$INFRA_REPO_URL" "$INFRA_CLONE" diff --git a/automation/commit_and_push.sh b/automation/commit_and_push.sh deleted file mode 100644 index f04f779..0000000 --- a/automation/commit_and_push.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -cd "$INFRA_CLONE" -git config user.name "woodpecker-bot" -git config user.email "ci@dvirlabs.com" -git remote set-url origin "$INFRA_REPO_URL" - -if ! git diff --quiet manifests/cloudflared/values.yaml; then - git add manifests/cloudflared/values.yaml - git commit -m "chore(cloudflared): auto-merge CNAME entries from sandbox" - git push origin HEAD - echo "✅ Changes pushed successfully." -else - echo "â„šī¸ No changes to commit." -fi diff --git a/automation/config.sh b/automation/config.sh deleted file mode 100644 index d96aaf1..0000000 --- a/automation/config.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -# ✋ Do NOT install tools here — do that in the pipeline or main.sh - -# ❗ Fail if required env vars are not set -: "${GIT_TOKEN:?GIT_TOKEN is not set}" -: "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN is not set}" -: "${CLOUDFLARE_ZONE_ID:?CLOUDFLARE_ZONE_ID is not set}" - -# Repos -SANDBOX_REPO_URL="https://git.dvirlabs.com/dvirlabs/sandbox.git" -INFRA_REPO_URL="https://${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/infra.git" - -# Paths -SANDBOX_CLONE=".tmp-repos/sandbox" -INFRA_CLONE=".tmp-repos/infra" - -# Generated files -GENERATED_FILE="$(pwd)/generated-values/cloudflared-values.yaml" -ORIGINAL_FILE="$INFRA_CLONE/manifests/cloudflared/values.yaml" -MERGED_FILE="$INFRA_CLONE/manifests/cloudflared/values.yaml" - -# Cloudflare API -CLOUDFLARE_API="https://api.cloudflare.com/client/v4" -TARGET="b50bbf48-0a2f-47ce-b73e-336b6718318b.cfargotunnel.com" diff --git a/automation/create_cnames.sh b/automation/create_cnames.sh deleted file mode 100644 index e7018bc..0000000 --- a/automation/create_cnames.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -echo "🌐 Creating CNAME records in Cloudflare..." - -: "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN not set}" -: "${CLOUDFLARE_ZONE_ID:?CLOUDFLARE_ZONE_ID not set}" - -yq eval '.ingress' "$GENERATED_FILE" | yq -o=json '.' | jq -c '.[]' | while read -r record; do - name=$(echo "$record" | jq -r '.hostname' | sed 's/\.dvirlabs\.com//') - - exists=$(curl -s -X GET "$CLOUDFLARE_API/zones/$CLOUDFLARE_ZONE_ID/dns_records?type=CNAME&name=$name.dvirlabs.com" \ - -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" -H "Content-Type: application/json" | jq '.result | length') - - if [ "$exists" -eq 0 ]; then - echo "➕ Creating CNAME: $name.dvirlabs.com → $TARGET" - curl -s -X POST "$CLOUDFLARE_API/zones/$CLOUDFLARE_ZONE_ID/dns_records" \ - -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ - -H "Content-Type: application/json" \ - --data "{ - \"type\": \"CNAME\", - \"name\": \"$name\", - \"content\": \"$TARGET\", - \"ttl\": 1, - \"proxied\": true - }" > /dev/null - else - echo "âš ī¸ CNAME for $name.dvirlabs.com already exists, skipping" - fi -done diff --git a/automation/generate_ingress.sh b/automation/generate_ingress.sh deleted file mode 100644 index 05fbc97..0000000 --- a/automation/generate_ingress.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -echo "âš™ī¸ Generating sandbox ingress list..." -mkdir -p generated-values -cat < "$GENERATED_FILE" -ingress: [] -EOF - -find "$SANDBOX_CLONE/manifests" -name cname.yaml | while read -r cname_file; do - app_name=$(basename "$(dirname "$cname_file")") - enabled=$(yq '.enabled' "$cname_file") - if [[ "$enabled" == "true" ]]; then - hostname=$(yq '.hostname' "$cname_file") - service="http://${app_name}.sandbox.svc.cluster.local:80" - echo "✅ Found $hostname → $service" - yq eval ".ingress += [{\"hostname\": \"$hostname\", \"service\": \"$service\"}]" -i "$GENERATED_FILE" - fi -done diff --git a/automation/main.sh b/automation/main.sh deleted file mode 100644 index a953c04..0000000 --- a/automation/main.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e - -# Install dependencies (done once here) -apk add --no-cache git bash curl yq jq - -# Load config AFTER env is present (from Woodpecker or exported manually) -source automation/config.sh - -rm -rf .tmp-repos -mkdir -p .tmp-repos -chmod +x automation/*.sh - -automation/clone_repos.sh -automation/generate_ingress.sh -automation/merge_values.sh -automation/commit_and_push.sh -automation/create_cnames.sh diff --git a/automation/merge_values.sh b/automation/merge_values.sh deleted file mode 100644 index 8810ecc..0000000 --- a/automation/merge_values.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -echo "🔁 Merging new entries into: $ORIGINAL_FILE" -TEMP_FILE=$(mktemp) -cp "$ORIGINAL_FILE" "$TEMP_FILE" - -yq eval '.ingress' "$GENERATED_FILE" | yq -o=json | jq -c '.[]' | while read -r new_entry; do - hostname=$(echo "$new_entry" | jq -r '.hostname') - service=$(echo "$new_entry" | jq -r '.service') - exists=$(yq e ".cloudflare.ingress[] | select(.hostname == \"$hostname\")" "$TEMP_FILE") - if [ -z "$exists" ]; then - echo "➕ Adding $hostname → $service" - yq eval ".cloudflare.ingress += [{\"hostname\": \"$hostname\", \"service\": \"$service\"}]" -i "$TEMP_FILE" - else - echo "âš ī¸ $hostname already exists, skipping" - fi -done - -cp "$TEMP_FILE" "$MERGED_FILE" diff --git a/cloudflared-sync.sh b/cloudflared-sync.sh new file mode 100644 index 0000000..c1254c5 --- /dev/null +++ b/cloudflared-sync.sh @@ -0,0 +1,134 @@ +#!/bin/bash +set -e + +# đŸ“Ļ Ensure apk installs: yq, jq, git, bash, curl +# Required for pipeline: alpine image + apk add --no-cache git bash curl yq jq + +apk add --no-cache git bash curl yq jq + +echo "🔍 Scanning for apps with cname.yaml..." + +mkdir -p generated-values +rm -rf .tmp-repos +mkdir -p .tmp-repos + +# === REPO CONFIG === +SANDBOX_REPO_URL="https://git.dvirlabs.com/dvirlabs/sandbox.git" +INFRA_REPO_URL="https://${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/infra.git" +SANDBOX_CLONE=".tmp-repos/sandbox" +INFRA_CLONE=".tmp-repos/infra" +GENERATED_FILE="$(pwd)/generated-values/cloudflared-values.yaml" +ORIGINAL_FILE="$INFRA_CLONE/manifests/cloudflared/values.yaml" +MERGED_FILE="$INFRA_CLONE/manifests/cloudflared/values.yaml" + +# === STEP 1: Clone Repos === +echo "đŸ“Ļ Cloning sandbox-apps..." +git clone --depth=1 "$SANDBOX_REPO_URL" "$SANDBOX_CLONE" + +echo "đŸ“Ļ Cloning infra..." +git clone --depth=1 "$INFRA_REPO_URL" "$INFRA_CLONE" + +ls -l .tmp-repos/ + +# === STEP 2: Extract Generated CNAMEs from sandbox === +echo "âš™ī¸ Generating sandbox ingress list..." +cat < "$GENERATED_FILE" +ingress: [] +EOF + +find "$SANDBOX_CLONE/manifests" -name cname.yaml | while read -r cname_file; do + app_name=$(basename "$(dirname "$cname_file")") + enabled=$(yq '.enabled' "$cname_file") + + if [[ "$enabled" == "true" ]]; then + hostname=$(yq '.hostname' "$cname_file") + service="http://${app_name}.sandbox.svc.cluster.local:80" + + echo "✅ Found $hostname → $service" + + yq eval ".ingress += [{\"hostname\": \"$hostname\", \"service\": \"$service\"}]" -i "$GENERATED_FILE" + fi +done + +echo "📄 Generated Ingress:" +cat "$GENERATED_FILE" + +# === STEP 3: Merge with existing cloudflared values === +echo "🔁 Merging new entries into: $ORIGINAL_FILE" + +TEMP_FILE=$(mktemp) +cp "$ORIGINAL_FILE" "$TEMP_FILE" + +# Loop through new entries and append only if hostname not exists +yq eval '.ingress' "$GENERATED_FILE" | yq -o=json | jq -c '.[]' | while read -r new_entry; do + hostname=$(echo "$new_entry" | jq -r '.hostname') + service=$(echo "$new_entry" | jq -r '.service') + + exists=$(yq e ".cloudflare.ingress[] | select(.hostname == \"$hostname\")" "$TEMP_FILE") + + if [ -z "$exists" ]; then + echo "➕ Adding $hostname → $service" + yq eval ".cloudflare.ingress += [{\"hostname\": \"$hostname\", \"service\": \"$service\"}]" -i "$TEMP_FILE" + else + echo "âš ī¸ $hostname already exists, skipping" + fi +done + +# === STEP 4: Overwrite only ingress list and preserve all other fields === +echo "📝 Writing final merged values.yaml" +cp "$TEMP_FILE" "$MERGED_FILE" + +echo "✅ Final merged values.yaml:" +cat "$MERGED_FILE" + +# === STEP 5: Optional push to Git === +cd "$INFRA_CLONE" +git config user.name "woodpecker-bot" +git config user.email "ci@dvirlabs.com" +git remote set-url origin "https://${GIT_TOKEN}@git.dvirlabs.com/dvirlabs/infra.git" + +if ! git diff --quiet manifests/cloudflared/values.yaml; then + git add manifests/cloudflared/values.yaml + git commit -m "chore(cloudflared): auto-merge CNAME entries from sandbox" + git push origin HEAD + echo "✅ Changes pushed successfully." +else + echo "â„šī¸ No changes to commit." +fi + +# === STEP 5: Create CNAME records in Cloudflare === +ls -l +pwd +ls -l "$GENERATED_FILE" +echo "🌐 Creating CNAME records in Cloudflare..." +CLOUDFLARE_API="https://api.cloudflare.com/client/v4" +TARGET="b50bbf48-0a2f-47ce-b73e-336b6718318b.cfargotunnel.com" + +# Load required secrets +: "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN not set}" +: "${CLOUDFLARE_ZONE_ID:?CLOUDFLARE_ZONE_ID not set}" + +# Check and create each CNAME +yq eval '.ingress' "$GENERATED_FILE" | yq eval -o=json '.' - | jq -c '.[]' | while read -r record; do + name=$(echo "$record" | jq -r '.hostname' | sed 's/\.dvirlabs\.com//') + + # Check if already exists + exists=$(curl -s -X GET "$CLOUDFLARE_API/zones/$CLOUDFLARE_ZONE_ID/dns_records?type=CNAME&name=$name.dvirlabs.com" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" -H "Content-Type: application/json" | jq '.result | length') + + if [ "$exists" -eq 0 ]; then + echo "➕ Creating CNAME: $name.dvirlabs.com → $TARGET" + curl -s -X POST "$CLOUDFLARE_API/zones/$CLOUDFLARE_ZONE_ID/dns_records" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ + -H "Content-Type: application/json" \ + --data "{ + \"type\": \"CNAME\", + \"name\": \"$name\", + \"content\": \"$TARGET\", + \"ttl\": 1, + \"proxied\": true + }" > /dev/null + else + echo "âš ī¸ CNAME for $name.dvirlabs.com already exists, skipping" + fi +done