From a5df219e502be3dd866b2d81e9b48444bbe5e47b Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 25 May 2025 23:32:39 +0530 Subject: [PATCH 001/102] Making changes to workflow pipeline --- .gitea/workflows/test_image_build_push.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index f5805cb..fac82f9 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -20,8 +20,6 @@ jobs: java-version: '17' - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - - name: Check secrets - run: echo "my secret is ${{ secrets.TOKEN }}" - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: @@ -29,6 +27,6 @@ jobs: username: hitanshu password: ${{ secrets.TOKEN }} - name: Gradle build - run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:latest + run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:test - name: Push to Gitea Registry - run: docker push 192.168.0.100:8928/hithomelabs/cftunnels:latest + run: docker push 192.168.0.100:8928/hithomelabs/cftunnels:test From d3f0797e333542e81493dfbd8b92244e33806e51 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 27 May 2025 01:08:07 +0530 Subject: [PATCH 002/102] Adding field path to ingress --- .../java/com/hithomelabs/CFTunnels/Models/Ingress.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java index 8adcc89..7c6c7be 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java @@ -8,6 +8,16 @@ public class Ingress { private String service; private String hostname; private Map originRequest; + private String path; + + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } public static boolean deleteByHostName(List ingressList, String toBeDeleted){ return ingressList.removeIf(ingress -> ingress.getHostname() != null && ingress.getHostname().equals(toBeDeleted)); From 585dd26a7be3fa5c5b7378a0ca583bfe47727b9d Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 28 May 2025 18:55:38 +0530 Subject: [PATCH 003/102] Workflow to only build on PR and building an image only on push to test --- .gitea/workflows/test_build.yml | 20 ++++++++++++++++++++ .gitea/workflows/test_image_build_push.yml | 3 --- 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 .gitea/workflows/test_build.yml diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml new file mode 100644 index 0000000..0a4e7d0 --- /dev/null +++ b/.gitea/workflows/test_build.yml @@ -0,0 +1,20 @@ +name: sample gradle build and test +run-name: Build started by $ {{gitea.actor}} +on: + pull_request: + branches: [test] +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: JDK setup + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + - name: Validate Gradle Wrapper + uses: gradle/actions/wrapper-validation@v3 + - name: Gradle build + run: /gradlew build --debug \ No newline at end of file diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index fac82f9..f45a5a8 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -3,9 +3,6 @@ run-name: Build started by $ {{gitea.actor}} on: push: branches: [test] - pull_request: - branches: [test] -jobs: build: runs-on: ubuntu-latest container: From 882b12781832c50ea57d0fbcb582f689606949d5 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 28 May 2025 19:01:11 +0530 Subject: [PATCH 004/102] Fixing issue related to not beaing able to execute gradlew --- .gitea/workflows/test_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index 0a4e7d0..05e8adb 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -17,4 +17,4 @@ jobs: - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - name: Gradle build - run: /gradlew build --debug \ No newline at end of file + run: ./gradlew build --debug \ No newline at end of file From 4483bf5a1b359c4b104b05fe912cf6f878d78ffd Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 28 May 2025 19:15:50 +0530 Subject: [PATCH 005/102] Adding env agnostic docker compose file --- .env.example | 4 ++++ docker-compose.yaml | 12 ++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 .env.example create mode 100644 docker-compose.yaml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..08c0845 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +CLOUDFLARE_ACCOUNT_ID="" +CLOUDFLARE_API_KEY="" +CLOUDFLARE_EMAIL="" +ENV="" \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..1c03e48 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,12 @@ +services: + app: + image: gitea.hithomelabs.com/hithomelabs/cftunnels:${ENV} + container_name: cftunnels_${ENV} + environment: + - CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID} + - CLOUDFLARE_API_KEY=${CLOUDFLARE_API_KEY} + - CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL} + - ENV=${ENV} + ports: + - 5002:8080 + restart: unless-stopped \ No newline at end of file From 87f779450dcc78647f4f3170a19301a36c13f294 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 28 May 2025 20:39:53 +0530 Subject: [PATCH 006/102] Changing open api springdoc version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 663b328..467f49e 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ repositories { } dependencies { - implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.0.3' + implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.8.8' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' From 8bc84a3202845347753892dfcb20cbec1a2a3d67 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 28 May 2025 23:54:27 +0530 Subject: [PATCH 007/102] Changing some bruno env variables --- CFTunnels/Get tunnels.bru | 2 +- CFTunnels/Tunnel.bru | 2 +- CFTunnels/Write ingress.bru | 2 +- CFTunnels/delete mapping.bru | 2 +- CFTunnels/environments/CFTunnels Local.bru | 2 +- CFTunnels/environments/CFTunnels.bru | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CFTunnels/Get tunnels.bru b/CFTunnels/Get tunnels.bru index b3cb95a..231ee08 100644 --- a/CFTunnels/Get tunnels.bru +++ b/CFTunnels/Get tunnels.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{base_url}}cloudflare/tunnels + url: {{base_url}}/cloudflare/tunnels body: none auth: none } diff --git a/CFTunnels/Tunnel.bru b/CFTunnels/Tunnel.bru index d19374e..826b583 100644 --- a/CFTunnels/Tunnel.bru +++ b/CFTunnels/Tunnel.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{base_url}}cloudflare/tunnel/{{tunnel_id}} + url: {{base_url}}/cloudflare/tunnel/{{tunnel_id}} body: none auth: none } diff --git a/CFTunnels/Write ingress.bru b/CFTunnels/Write ingress.bru index 61f4ebc..9930a0b 100644 --- a/CFTunnels/Write ingress.bru +++ b/CFTunnels/Write ingress.bru @@ -5,7 +5,7 @@ meta { } put { - url: {{base_url}}cloudflare/tunnel/{{tunnel_id}}/add + url: {{base_url}}/cloudflare/tunnel/{{tunnel_id}}/add body: json auth: none } diff --git a/CFTunnels/delete mapping.bru b/CFTunnels/delete mapping.bru index 857a43e..c9e3dbb 100644 --- a/CFTunnels/delete mapping.bru +++ b/CFTunnels/delete mapping.bru @@ -5,7 +5,7 @@ meta { } put { - url: {{base_url}}cloudflare/tunnel/{{tunnel_id}}/delete + url: {{base_url}}/cloudflare/tunnel/{{tunnel_id}}/delete body: json auth: none } diff --git a/CFTunnels/environments/CFTunnels Local.bru b/CFTunnels/environments/CFTunnels Local.bru index 9e83a22..6d2b6b0 100644 --- a/CFTunnels/environments/CFTunnels Local.bru +++ b/CFTunnels/environments/CFTunnels Local.bru @@ -1,4 +1,4 @@ vars { tunnel_id: 50df9101-f625-4618-b7c5-100338a57124 - base_url: http://localhost:8080/ + base_url: http://localhost:8080 } diff --git a/CFTunnels/environments/CFTunnels.bru b/CFTunnels/environments/CFTunnels.bru index 1c61ef6..d8219ab 100644 --- a/CFTunnels/environments/CFTunnels.bru +++ b/CFTunnels/environments/CFTunnels.bru @@ -1,4 +1,4 @@ vars { tunnel_id: 50df9101-f625-4618-b7c5-100338a57124 - base_url: https://testcf.hithomelabs.com/ + base_url: https://testcf.hithomelabs.com } From 6cd3524ca0b67344004dee16c27a8e5d167d0b54 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 29 May 2025 00:13:49 +0530 Subject: [PATCH 008/102] Fixing broken image creation --- .gitea/workflows/test_image_build_push.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index f45a5a8..e4cdd2f 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -3,6 +3,7 @@ run-name: Build started by $ {{gitea.actor}} on: push: branches: [test] +jobs: build: runs-on: ubuntu-latest container: From ec7d3299dfc2fd646f4fbe0aae57021611b72c29 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 1 Jun 2025 17:29:24 +0530 Subject: [PATCH 009/102] Changes derver in OpenAPI Config to avoid CORS --- build.gradle | 2 +- .../CFTunnels/Config/OpenApiConfig.java | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java diff --git a/build.gradle b/build.gradle index 467f49e..aaa90d3 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ repositories { } dependencies { - implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.8.8' + implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.8.5' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java new file mode 100644 index 0000000..0b2aa4b --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java @@ -0,0 +1,22 @@ +package com.hithomelabs.CFTunnels.Config; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.servers.Server; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; + +@Configuration +public class OpenApiConfig { + + @Bean + public OpenAPI openAPI(){ + Server httpsServer = new Server().url("https://testcf.hithomelabs.com"); + OpenAPI openApi = new OpenAPI(); + ArrayList servers = new ArrayList<>(); + servers.add(httpsServer); + openApi.setServers(servers); + return openApi; + } +} From c5d01ece01327baa7dbc47f09882d0225b57e50d Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 4 Jun 2025 01:27:34 +0530 Subject: [PATCH 010/102] Adding profiles for different OpenAPI server URLS in different environments --- .../com/hithomelabs/CFTunnels/Config/OpenApiConfig.java | 6 +++++- src/main/resources/application-local.properties | 1 + src/main/resources/application-prod.properties | 1 + src/main/resources/application-test.properties | 1 + src/main/resources/application.properties | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/application-local.properties create mode 100644 src/main/resources/application-prod.properties create mode 100644 src/main/resources/application-test.properties diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java index 0b2aa4b..e24e6f5 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java @@ -2,6 +2,7 @@ package com.hithomelabs.CFTunnels.Config; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.servers.Server; +import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,9 +11,12 @@ import java.util.ArrayList; @Configuration public class OpenApiConfig { + @Value("${api.baseUrl}") + private String baseUrl; + @Bean public OpenAPI openAPI(){ - Server httpsServer = new Server().url("https://testcf.hithomelabs.com"); + Server httpsServer = new Server().url(baseUrl); OpenAPI openApi = new OpenAPI(); ArrayList servers = new ArrayList<>(); servers.add(httpsServer); diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties new file mode 100644 index 0000000..fdb25ce --- /dev/null +++ b/src/main/resources/application-local.properties @@ -0,0 +1 @@ +api.baseUrl=http://localhost:8080 \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties new file mode 100644 index 0000000..dec0f4b --- /dev/null +++ b/src/main/resources/application-prod.properties @@ -0,0 +1 @@ +api.baseUrl=https://cftunnels.hithomelabs.com \ No newline at end of file diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties new file mode 100644 index 0000000..e5c014b --- /dev/null +++ b/src/main/resources/application-test.properties @@ -0,0 +1 @@ +api.baseUrl=https://testcf.hithomelabs.com \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2c265e1..9b04cc9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,3 +2,4 @@ spring.application.name=CFTunnels cloudflare.accountId=${CLOUDFLARE_ACCOUNT_ID} cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} +spring.profiles.active=${ENV} From ebd65ccbbe655b99731b5b9bc6c6262f394974a0 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 4 Jun 2025 01:34:19 +0530 Subject: [PATCH 011/102] Changing verbosity of gradle logs --- .gitea/workflows/test_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index 05e8adb..ae070cd 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -17,4 +17,4 @@ jobs: - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - name: Gradle build - run: ./gradlew build --debug \ No newline at end of file + run: ./gradlew build --info \ No newline at end of file From 196cf74a722683dba0d608aaff6b2416afed509d Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Wed, 4 Jun 2025 01:50:41 +0530 Subject: [PATCH 012/102] Adding default profile test for gradle build test task --- build.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle b/build.gradle index aaa90d3..49a3976 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,10 @@ java { } } +test { + systemProperty 'spring.profiles.active', 'test' +} + repositories { mavenCentral() } From 5fb59032cb8c88aa50f7808a6a380a5a4ccc9e94 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 01:52:45 +0530 Subject: [PATCH 013/102] Adding tags to release and images --- .gitea/workflows/test_image_build_push.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index e4cdd2f..96b71d2 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -18,6 +18,16 @@ jobs: java-version: '17' - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 + - name: Get latest tag + run: echo "VERSION=$(git describe --tags --abbrev=0)" + - name: Increment version + run: echo "NEW_VERSION=$(echo $VERSION | awk -F'v' '{print $2}' | awk -F. '{print "v"$1"."$2"."$3+1}')" + - name: Extract commit message + run: echo "COMMIT_MESSAGE=$((git log -1 --pretty=%B)" + - name: Create and push tag + run: | + git tag -a ${NEW_VERSION} -m "${COMMIT_MESSAGE}" + git push origin ${NEW_VERSION} - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: @@ -25,6 +35,10 @@ jobs: username: hitanshu password: ${{ secrets.TOKEN }} - name: Gradle build - run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:test + run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} + - name: Tag image as test + run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} 192.168.0.100:8928/hithomelabs/cftunnels:test - name: Push to Gitea Registry - run: docker push 192.168.0.100:8928/hithomelabs/cftunnels:test + run: | + docker push 192.168.0.100:8928/hithomelabs/cftunnels:test + docker push 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} From 8f1f6e4f99dd0ceda6fe0c56ad0ca1abcfad6c06 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 01:59:40 +0530 Subject: [PATCH 014/102] Minor bugfix --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 96b71d2..6abc8a3 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -23,7 +23,7 @@ jobs: - name: Increment version run: echo "NEW_VERSION=$(echo $VERSION | awk -F'v' '{print $2}' | awk -F. '{print "v"$1"."$2"."$3+1}')" - name: Extract commit message - run: echo "COMMIT_MESSAGE=$((git log -1 --pretty=%B)" + run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag run: | git tag -a ${NEW_VERSION} -m "${COMMIT_MESSAGE}" From b66ba60028795bf0b15821efd589e7a9e62558ab Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 02:19:59 +0530 Subject: [PATCH 015/102] Fetching tags explicitly --- .gitea/workflows/test_image_build_push.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 6abc8a3..4bcfafc 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -26,6 +26,7 @@ jobs: run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag run: | + git fetch --tags git tag -a ${NEW_VERSION} -m "${COMMIT_MESSAGE}" git push origin ${NEW_VERSION} - name: Log in to Gitea Docker Registry From f6bd7573a6a85283067a5f0e429dec2b22a47598 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 02:29:02 +0530 Subject: [PATCH 016/102] using fetch-depth 0 as specified in https://github.com/actions/checkout/issues/1781 --- .gitea/workflows/test_image_build_push.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 4bcfafc..4130c59 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -11,6 +11,8 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: JDK setup uses: actions/setup-java@v4 with: @@ -26,7 +28,6 @@ jobs: run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag run: | - git fetch --tags git tag -a ${NEW_VERSION} -m "${COMMIT_MESSAGE}" git push origin ${NEW_VERSION} - name: Log in to Gitea Docker Registry From 1cd63d6d3d48a6489152f8628b54a96f49ce5a0a Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 02:36:19 +0530 Subject: [PATCH 017/102] Adding awk --- .gitea/workflows/test_image_build_push.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 4130c59..f74f74f 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -18,6 +18,8 @@ jobs: with: distribution: 'zulu' java-version: '17' + - name: Install AWK + run: sudo apt-get update && sudo apt-get install -y gawk - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - name: Get latest tag From 005863c9988a90a9c79f07c2e982e868de736251 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 21:45:30 +0530 Subject: [PATCH 018/102] Using cut to increment version --- .gitea/workflows/test_image_build_push.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index f74f74f..18792f0 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -18,14 +18,18 @@ jobs: with: distribution: 'zulu' java-version: '17' - - name: Install AWK - run: sudo apt-get update && sudo apt-get install -y gawk - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - name: Get latest tag - run: echo "VERSION=$(git describe --tags --abbrev=0)" + run: | + echo "VERSION=$(git describe --tags --abbrev=0)" + MAJOR=$(echo $VERSION | cut -d "." -f 1) + MINOR=$(echo $VERSION | cut -d "." -f 2) + PATCH=$(echo $VERSION | cut -d "." -f 3) - name: Increment version - run: echo "NEW_VERSION=$(echo $VERSION | awk -F'v' '{print $2}' | awk -F. '{print "v"$1"."$2"."$3+1}')" + run: | + PATCH=$((PATCH + 1)) + echo "NEW_VERSION=$(echo $MAJOR.$MINOR.$PATCH)" - name: Extract commit message run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag From 3bf981ac05c21965a193a730fdbba8074b5ee3a2 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 22:05:51 +0530 Subject: [PATCH 019/102] Checking if cut is installed on gitea runner --- .gitea/workflows/test_image_build_push.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 18792f0..b035c3b 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -20,12 +20,14 @@ jobs: java-version: '17' - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 + - name: Check if cut is installed + run: echo $(which cut) - name: Get latest tag run: | echo "VERSION=$(git describe --tags --abbrev=0)" - MAJOR=$(echo $VERSION | cut -d "." -f 1) - MINOR=$(echo $VERSION | cut -d "." -f 2) - PATCH=$(echo $VERSION | cut -d "." -f 3) + echo "MAJOR=$(echo $VERSION | cut -d "." -f 1)" + echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" + echo "PATCH=$(echo $VERSION | cut -d "." -f 3)" - name: Increment version run: | PATCH=$((PATCH + 1)) From 3742fb53af916a9e43eaa5d6d05f70c101ee5a9b Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 23:13:27 +0530 Subject: [PATCH 020/102] Trying a different base image --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index b035c3b..aa75baf 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -7,7 +7,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: catthehacker/ubuntu:act-latest + image: catthehacker/ubuntu:runner-latest steps: - name: Check out repository code uses: actions/checkout@v4 From ccc65aef8d9b4828e1aeebfc3dd81e845e2d0d0f Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 23:23:44 +0530 Subject: [PATCH 021/102] Trying to figure out RCA --- .gitea/workflows/test_build.yml | 7 +++++++ .gitea/workflows/test_image_build_push.yml | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index ae070cd..a546543 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -15,6 +15,13 @@ jobs: distribution: 'zulu' java-version: '17' - name: Validate Gradle Wrapper + - name: Get latest tag dry run + run: | + echo "VERSION=$(git describe --tags --abbrev=0)" + echo $VERSION + echo "MAJOR=$(echo $VERSION | cut -d "." -f 1)" + echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" + echo "PATCH=$(echo $VERSION | cut -d "." -f 3)" uses: gradle/actions/wrapper-validation@v3 - name: Gradle build run: ./gradlew build --info \ No newline at end of file diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index aa75baf..3feddd2 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -7,7 +7,7 @@ jobs: build: runs-on: ubuntu-latest container: - image: catthehacker/ubuntu:runner-latest + image: catthehacker/ubuntu:act-latest steps: - name: Check out repository code uses: actions/checkout@v4 @@ -25,6 +25,7 @@ jobs: - name: Get latest tag run: | echo "VERSION=$(git describe --tags --abbrev=0)" + echo $VERSION echo "MAJOR=$(echo $VERSION | cut -d "." -f 1)" echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" echo "PATCH=$(echo $VERSION | cut -d "." -f 3)" From 36050aec95f171f1ce26149fbab6396e7e8c1de2 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 23:26:25 +0530 Subject: [PATCH 022/102] Trying to figure out RCA --- .gitea/workflows/test_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index a546543..85e9353 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -15,6 +15,7 @@ jobs: distribution: 'zulu' java-version: '17' - name: Validate Gradle Wrapper + uses: gradle/actions/wrapper-validation@v3 - name: Get latest tag dry run run: | echo "VERSION=$(git describe --tags --abbrev=0)" @@ -22,6 +23,5 @@ jobs: echo "MAJOR=$(echo $VERSION | cut -d "." -f 1)" echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" echo "PATCH=$(echo $VERSION | cut -d "." -f 3)" - uses: gradle/actions/wrapper-validation@v3 - name: Gradle build run: ./gradlew build --info \ No newline at end of file From c6ded4a74d5de69c6e122571f80eb8c2062a1700 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Thu, 5 Jun 2025 23:43:57 +0530 Subject: [PATCH 023/102] Trying to figure out RCA --- .gitea/workflows/test_build.yml | 7 ------- .gitea/workflows/test_image_build_push.yml | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index 85e9353..ae070cd 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -16,12 +16,5 @@ jobs: java-version: '17' - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - - name: Get latest tag dry run - run: | - echo "VERSION=$(git describe --tags --abbrev=0)" - echo $VERSION - echo "MAJOR=$(echo $VERSION | cut -d "." -f 1)" - echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" - echo "PATCH=$(echo $VERSION | cut -d "." -f 3)" - name: Gradle build run: ./gradlew build --info \ No newline at end of file diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 3feddd2..c6f314b 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -26,8 +26,8 @@ jobs: run: | echo "VERSION=$(git describe --tags --abbrev=0)" echo $VERSION - echo "MAJOR=$(echo $VERSION | cut -d "." -f 1)" - echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" + echo "MAJOR=$(echo $VERSION | /usr/bin/cut -d "." -f 1)" + sudo echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" echo "PATCH=$(echo $VERSION | cut -d "." -f 3)" - name: Increment version run: | From df2a50d356fb055e8de7b83c0510fabbe97f4273 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 00:02:30 +0530 Subject: [PATCH 024/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index c6f314b..492ed6e 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -25,10 +25,10 @@ jobs: - name: Get latest tag run: | echo "VERSION=$(git describe --tags --abbrev=0)" - echo $VERSION - echo "MAJOR=$(echo $VERSION | /usr/bin/cut -d "." -f 1)" - sudo echo "MINOR=$(echo $VERSION | cut -d "." -f 2)" - echo "PATCH=$(echo $VERSION | cut -d "." -f 3)" + echo "${VERSION}" + echo "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" + sudo echo "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" + echo "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" - name: Increment version run: | PATCH=$((PATCH + 1)) From cc64b7c74872c33c1e5538c7f9705a1f1a71a33b Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 00:30:25 +0530 Subject: [PATCH 025/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 27 +++++++--------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 492ed6e..250d553 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -18,27 +18,16 @@ jobs: with: distribution: 'zulu' java-version: '17' - - name: Validate Gradle Wrapper - uses: gradle/actions/wrapper-validation@v3 - - name: Check if cut is installed - run: echo $(which cut) - - name: Get latest tag - run: | - echo "VERSION=$(git describe --tags --abbrev=0)" - echo "${VERSION}" - echo "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" - sudo echo "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" - echo "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" - - name: Increment version - run: | - PATCH=$((PATCH + 1)) - echo "NEW_VERSION=$(echo $MAJOR.$MINOR.$PATCH)" - - name: Extract commit message - run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" + - name: Get Next Patch Version + id: version + uses: reecetech/version-increment@v2024.10.1 + with: + scheme: semver + increment: patch - name: Create and push tag run: | - git tag -a ${NEW_VERSION} -m "${COMMIT_MESSAGE}" - git push origin ${NEW_VERSION} + git tag -a ${{ steps.version.outputs.version }} -m "Tagging with ${{ steps.version.outputs.version }}" + git push origin ${{ steps.version.outputs.version }} - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: From 61df434e0da719efd10a2dc886544b3db8d20ff8 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 00:31:06 +0530 Subject: [PATCH 026/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 250d553..5693c1b 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -35,10 +35,10 @@ jobs: username: hitanshu password: ${{ secrets.TOKEN }} - name: Gradle build - run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} + run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.version.outputs.version }} - name: Tag image as test - run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} 192.168.0.100:8928/hithomelabs/cftunnels:test + run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.version.outputs.version }} 192.168.0.100:8928/hithomelabs/cftunnels:test - name: Push to Gitea Registry run: | docker push 192.168.0.100:8928/hithomelabs/cftunnels:test - docker push 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} + docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.version.outputs.version }} From 80b55fd993139bf38662c40854b8ee5a8175c335 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 00:48:35 +0530 Subject: [PATCH 027/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 5693c1b..a7f80aa 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -18,16 +18,25 @@ jobs: with: distribution: 'zulu' java-version: '17' - - name: Get Next Patch Version - id: version - uses: reecetech/version-increment@v2024.10.1 - with: - scheme: semver - increment: patch + - name: Check if cut is installed + run: echo $(which cut) + - name: Get latest tag + run: | + export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_OUTPUT + echo "${GITEA_OUTPUT}" + echo "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" + sudo echo "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" + echo "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" + - name: Increment version + run: | + PATCH=$((PATCH + 1)) + echo "NEW_VERSION=$(echo $MAJOR.$MINOR.$PATCH)" + - name: Extract commit message + run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag run: | - git tag -a ${{ steps.version.outputs.version }} -m "Tagging with ${{ steps.version.outputs.version }}" - git push origin ${{ steps.version.outputs.version }} + git tag -a ${NEW_VERSION} -m "${COMMIT_MESSAGE}" + git push origin ${NEW_VERSION} - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: @@ -35,10 +44,10 @@ jobs: username: hitanshu password: ${{ secrets.TOKEN }} - name: Gradle build - run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.version.outputs.version }} + run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} - name: Tag image as test - run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.version.outputs.version }} 192.168.0.100:8928/hithomelabs/cftunnels:test + run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} 192.168.0.100:8928/hithomelabs/cftunnels:test - name: Push to Gitea Registry run: | docker push 192.168.0.100:8928/hithomelabs/cftunnels:test - docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.version.outputs.version }} + docker push 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} From 0bc90d5d773a94baec457b13f6bcd08056a9a74d Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 01:07:33 +0530 Subject: [PATCH 028/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index a7f80aa..217374d 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -24,9 +24,12 @@ jobs: run: | export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_OUTPUT echo "${GITEA_OUTPUT}" - echo "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" - sudo echo "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" - echo "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" + export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" + echo "${MAJOR}" + export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" + echo "${MINOR}" + export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" + echo "${PATCH} - name: Increment version run: | PATCH=$((PATCH + 1)) From 4afeb9f6b2249ec50e081d064220661147df9ec0 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 01:11:09 +0530 Subject: [PATCH 029/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 217374d..dace717 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -22,14 +22,14 @@ jobs: run: echo $(which cut) - name: Get latest tag run: | - export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_OUTPUT - echo "${GITEA_OUTPUT}" + export "VERSION=$(git describe --tags --abbrev=0)" + echo "${VERSION}" export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" echo "${MAJOR}" export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" echo "${MINOR}" export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" - echo "${PATCH} + echo "${PATCH}" - name: Increment version run: | PATCH=$((PATCH + 1)) From c045dae894cb82e3a8d4c8b1f2fb5812586e2f66 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 01:33:41 +0530 Subject: [PATCH 030/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index dace717..317c324 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -18,22 +18,21 @@ jobs: with: distribution: 'zulu' java-version: '17' - - name: Check if cut is installed - run: echo $(which cut) - name: Get latest tag + id: get_tag run: | export "VERSION=$(git describe --tags --abbrev=0)" echo "${VERSION}" export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" - echo "${MAJOR}" + echo "MAJOR=${MAJOR}" export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" - echo "${MINOR}" + echo "MINOR=${MINOR}" export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" - echo "${PATCH}" + echo "PATCH=${PATCH}" - name: Increment version run: | - PATCH=$((PATCH + 1)) - echo "NEW_VERSION=$(echo $MAJOR.$MINOR.$PATCH)" + export "NEW_VERSION=$(echo ${{ steps.get_tag.outputs.MAJOR }}.${{ steps.get_tag.outputs.MINOR }}.$( ${{ steps.get_tag.outputs.PATCH }} + 1) ) + echo "NEW_VERSION=${NEW_VERSION}" - name: Extract commit message run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag From 27576d6023096f34173f83a47a2b3bde7c1d172b Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 01:36:57 +0530 Subject: [PATCH 031/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 317c324..6bc41d8 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - export "NEW_VERSION=$(echo ${{ steps.get_tag.outputs.MAJOR }}.${{ steps.get_tag.outputs.MINOR }}.$( ${{ steps.get_tag.outputs.PATCH }} + 1) ) + export "NEW_VERSION=$(echo ${{ steps.get_tag.outputs.MAJOR }}.${{ steps.get_tag.outputs.MINOR }}.$( ${{ steps.get_tag.outputs.PATCH }} + 1) )" echo "NEW_VERSION=${NEW_VERSION}" - name: Extract commit message run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" From 7203877b27771111800ea39e21b221ac304e19be Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 01:41:34 +0530 Subject: [PATCH 032/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 6bc41d8..998c7c7 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - export "NEW_VERSION=$(echo ${{ steps.get_tag.outputs.MAJOR }}.${{ steps.get_tag.outputs.MINOR }}.$( ${{ steps.get_tag.outputs.PATCH }} + 1) )" + export "NEW_VERSION=$(echo ${{ steps.get_tag.outputs.MAJOR }}.${{ steps.get_tag.outputs.MINOR }}.${{ steps.get_tag.outputs.PATCH }})" echo "NEW_VERSION=${NEW_VERSION}" - name: Extract commit message run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" From 856748edb77ce1d249c12bcc342a0b87b1e03437 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 01:46:54 +0530 Subject: [PATCH 033/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 998c7c7..30b431a 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - export "NEW_VERSION=$(echo ${{ steps.get_tag.outputs.MAJOR }}.${{ steps.get_tag.outputs.MINOR }}.${{ steps.get_tag.outputs.PATCH }})" + export "NEW_VERSION=${{ steps.get_tag.outputs.MAJOR }}" echo "NEW_VERSION=${NEW_VERSION}" - name: Extract commit message run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" From c24abc76be63cd58189ae03ddfc1480976bde93e Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 01:54:20 +0530 Subject: [PATCH 034/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 30b431a..99f6a46 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -21,7 +21,7 @@ jobs: - name: Get latest tag id: get_tag run: | - export "VERSION=$(git describe --tags --abbrev=0)" + export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_ENV echo "${VERSION}" export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" echo "MAJOR=${MAJOR}" @@ -31,8 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - export "NEW_VERSION=${{ steps.get_tag.outputs.MAJOR }}" - echo "NEW_VERSION=${NEW_VERSION}" + cat $GITEA_ENV - name: Extract commit message run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag From 05214000af88a83507ffc65e7fab79a65032205e Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 02:02:19 +0530 Subject: [PATCH 035/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 99f6a46..51d6af2 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -23,15 +23,17 @@ jobs: run: | export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_ENV echo "${VERSION}" - export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" + export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" >> $GITEA_ENV echo "MAJOR=${MAJOR}" - export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" + export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" >> $GITEA_ENV echo "MINOR=${MINOR}" - export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" + export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" >> $GITEA_ENV echo "PATCH=${PATCH}" - name: Increment version run: | - cat $GITEA_ENV + export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV + export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV + echo "NEW_VERSION=${NEW_VERSION}" - name: Extract commit message run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" - name: Create and push tag From 5760f9e7141f85c9b8a777b7fe9d3569f349bcda Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 02:06:12 +0530 Subject: [PATCH 036/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 51d6af2..b302553 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,6 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | + echo "MAJOR=${MAJOR}" export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV echo "NEW_VERSION=${NEW_VERSION}" From d7cda65f2110dce372b77341e8620e7678c85178 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 02:11:28 +0530 Subject: [PATCH 037/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index b302553..641a094 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - echo "MAJOR=${MAJOR}" + echo $GITEA_ENV export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV echo "NEW_VERSION=${NEW_VERSION}" From 2b0e0eb9c4318fe793eabcee073ce5bed7c88591 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 02:14:30 +0530 Subject: [PATCH 038/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 641a094..ebc6e00 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - echo $GITEA_ENV + cat /var/run/act/workflow/envs.txt export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV echo "NEW_VERSION=${NEW_VERSION}" From 40a536ddcfd16bb23bc900ac751b7ca1bd64d97e Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 02:19:18 +0530 Subject: [PATCH 039/102] Trying to figure out RCA --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index ebc6e00..a07f84a 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - cat /var/run/act/workflow/envs.txt + source $GITEA_ENV export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV echo "NEW_VERSION=${NEW_VERSION}" From 38753791d71069952988a74672e6fe75765eaf81 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 02:20:03 +0530 Subject: [PATCH 040/102] Trying to figure out RCA --- .gitea/workflows/test_build.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index ae070cd..b991e53 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -16,5 +16,22 @@ jobs: java-version: '17' - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 + - name: Get latest tag + id: get_tag + run: | + export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_ENV + echo "${VERSION}" + export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" >> $GITEA_ENV + echo "MAJOR=${MAJOR}" + export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" >> $GITEA_ENV + echo "MINOR=${MINOR}" + export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" >> $GITEA_ENV + echo "PATCH=${PATCH}" + - name: Increment version + run: | + source $GITEA_ENV + export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV + export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV + echo "NEW_VERSION=${NEW_VERSION}" - name: Gradle build run: ./gradlew build --info \ No newline at end of file From 1980b49272f9435fa57f90f85e8c5de3f17c93ae Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 6 Jun 2025 02:24:53 +0530 Subject: [PATCH 041/102] Trying to figure out RCA --- .gitea/workflows/test_build.yml | 4 +++- .gitea/workflows/test_image_build_push.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index b991e53..3817663 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -6,6 +6,8 @@ on: jobs: build: runs-on: ubuntu-latest + container: + image: catthehacker/ubuntu:act-latest steps: - name: Check out repository code uses: actions/checkout@v4 @@ -29,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - source $GITEA_ENV + . $GITEA_ENV export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV echo "NEW_VERSION=${NEW_VERSION}" diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index a07f84a..d96fd01 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -31,7 +31,7 @@ jobs: echo "PATCH=${PATCH}" - name: Increment version run: | - source $GITEA_ENV + . $GITEA_ENV export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV echo "NEW_VERSION=${NEW_VERSION}" From cd4b2ae2d86de6dac2635941d374cea641252b11 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 21:21:39 +0530 Subject: [PATCH 042/102] Trying to pass variables between steps using outputs --- .gitea/workflows/test_build.yml | 19 ----------- .gitea/workflows/test_image_build_push.yml | 37 +++++++++++----------- 2 files changed, 18 insertions(+), 38 deletions(-) diff --git a/.gitea/workflows/test_build.yml b/.gitea/workflows/test_build.yml index 3817663..ae070cd 100644 --- a/.gitea/workflows/test_build.yml +++ b/.gitea/workflows/test_build.yml @@ -6,8 +6,6 @@ on: jobs: build: runs-on: ubuntu-latest - container: - image: catthehacker/ubuntu:act-latest steps: - name: Check out repository code uses: actions/checkout@v4 @@ -18,22 +16,5 @@ jobs: java-version: '17' - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - - name: Get latest tag - id: get_tag - run: | - export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_ENV - echo "${VERSION}" - export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" >> $GITEA_ENV - echo "MAJOR=${MAJOR}" - export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" >> $GITEA_ENV - echo "MINOR=${MINOR}" - export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" >> $GITEA_ENV - echo "PATCH=${PATCH}" - - name: Increment version - run: | - . $GITEA_ENV - export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV - export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV - echo "NEW_VERSION=${NEW_VERSION}" - name: Gradle build run: ./gradlew build --info \ No newline at end of file diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index d96fd01..425a819 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -18,29 +18,28 @@ jobs: with: distribution: 'zulu' java-version: '17' + - name: Validate Gradle Wrapper + uses: gradle/actions/wrapper-validation@v3 - name: Get latest tag id: get_tag run: | - export "VERSION=$(git describe --tags --abbrev=0)" >> $GITEA_ENV - echo "${VERSION}" - export "MAJOR=$(echo ${VERSION} | /usr/bin/cut -d "." -f 1)" >> $GITEA_ENV - echo "MAJOR=${MAJOR}" - export "MINOR=$(echo ${VERSION} | cut -d "." -f 2)" >> $GITEA_ENV - echo "MINOR=${MINOR}" - export "PATCH=$(echo ${VERSION} | cut -d "." -f 3)" >> $GITEA_ENV - echo "PATCH=${PATCH}" + VERSION=$(git describe --tags --abbrev=0) + echo "VERSION=${VERSION}" >> $GITEA_OUTPUT + MAJOR=$(echo ${VERSION} | cut -d "." -f 1) + echo "MAJOR=${MAJOR}" >> $GITEA_OUTPUT + MINOR=$(echo ${VERSION} | cut -d "." -f 2) + echo "MINOR=${MINOR}" >> $GITEA_OUTPUT + PATCH=$(echo ${VERSION} | cut -d "." -f 3) + echo "PATCH=${PATCH}" >> $GITEA_OUTPUT - name: Increment version + id: calc_new_tag run: | - . $GITEA_ENV - export "PATCH=$((${PATCH} + 1))" >> $GITEA_ENV - export "NEW_VERSION=$(echo ${MAJOR}.${MINOR}.${PATCH})" >> $GITEA_ENV - echo "NEW_VERSION=${NEW_VERSION}" - - name: Extract commit message - run: echo "COMMIT_MESSAGE=$(git log -1 --pretty=%B)" + echo "NEW_PATCH=$((${{ steps.get_id.outputs.PATCH }} + 1))" >> $GITEA_OUTPUT + echo "NEW_VERSION=$( ${{ steps.get_id.outputs.MAJOR }}.${{ steps.get_id.outputs.MINOR }}.${{ steps.get_id.outputs.NEW_PATCH }})" >> $GITEA_OUTPUT - name: Create and push tag run: | - git tag -a ${NEW_VERSION} -m "${COMMIT_MESSAGE}" - git push origin ${NEW_VERSION} + git tag -a ${{ steps.calc_new_tag.outputs.NEW_VERSION }} -m "Pushing new version ${{ steps.calc_new_tag.outputs.NEW_VERSION }}" + git push origin ${{ steps.calc_new_tag.outputs.NEW_VERSION }} - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: @@ -48,10 +47,10 @@ jobs: username: hitanshu password: ${{ secrets.TOKEN }} - name: Gradle build - run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} + run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.calc_new_tag.outputs.NEW_VERSION }} - name: Tag image as test - run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} 192.168.0.100:8928/hithomelabs/cftunnels:test + run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.calc_new_tag.outputs.NEW_VERSION }} 192.168.0.100:8928/hithomelabs/cftunnels:test - name: Push to Gitea Registry run: | docker push 192.168.0.100:8928/hithomelabs/cftunnels:test - docker push 192.168.0.100:8928/hithomelabs/cftunnels:${NEW_VERSION} + docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.calc_new_tag.outputs.NEW_VERSION }} From 66fbfc5d69e69b30c39b9f47cabc7f4ddbef5aee Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 21:29:54 +0530 Subject: [PATCH 043/102] Trying to pass variables between steps using outputs --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 425a819..f4b42f1 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -35,7 +35,7 @@ jobs: id: calc_new_tag run: | echo "NEW_PATCH=$((${{ steps.get_id.outputs.PATCH }} + 1))" >> $GITEA_OUTPUT - echo "NEW_VERSION=$( ${{ steps.get_id.outputs.MAJOR }}.${{ steps.get_id.outputs.MINOR }}.${{ steps.get_id.outputs.NEW_PATCH }})" >> $GITEA_OUTPUT + echo "NEW_VERSION=$( ${{ steps.get_id.outputs.MAJOR }}.${{ steps.get_id.outputs.MINOR }}.${NEW_PATCH})" >> $GITEA_OUTPUT - name: Create and push tag run: | git tag -a ${{ steps.calc_new_tag.outputs.NEW_VERSION }} -m "Pushing new version ${{ steps.calc_new_tag.outputs.NEW_VERSION }}" From 8720810c46b5fb58aaecc1b5bd6dae2f3227467d Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 21:39:17 +0530 Subject: [PATCH 044/102] Trying to pass variables between steps using outputs --- .gitea/workflows/test_image_build_push.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index f4b42f1..b44a6f1 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -34,7 +34,8 @@ jobs: - name: Increment version id: calc_new_tag run: | - echo "NEW_PATCH=$((${{ steps.get_id.outputs.PATCH }} + 1))" >> $GITEA_OUTPUT + echo "${{ steps.get_id.outputs.PATCH }}" + echo "NEW_PATCH=$(( ${{ steps.get_id.outputs.PATCH }} + 1))" >> $GITEA_OUTPUT echo "NEW_VERSION=$( ${{ steps.get_id.outputs.MAJOR }}.${{ steps.get_id.outputs.MINOR }}.${NEW_PATCH})" >> $GITEA_OUTPUT - name: Create and push tag run: | From 6262c84535174dd1e6b7fdb132fd104715dbe26a Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 21:46:10 +0530 Subject: [PATCH 045/102] Trying to use --- .gitea/workflows/test_image_build_push.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index b44a6f1..1295a5f 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -24,19 +24,19 @@ jobs: id: get_tag run: | VERSION=$(git describe --tags --abbrev=0) - echo "VERSION=${VERSION}" >> $GITEA_OUTPUT + echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT MAJOR=$(echo ${VERSION} | cut -d "." -f 1) - echo "MAJOR=${MAJOR}" >> $GITEA_OUTPUT + echo "MAJOR=${MAJOR}" >> $GITHUB_OUTPUT MINOR=$(echo ${VERSION} | cut -d "." -f 2) - echo "MINOR=${MINOR}" >> $GITEA_OUTPUT + echo "MINOR=${MINOR}" >> $GITHUB_OUTPUT PATCH=$(echo ${VERSION} | cut -d "." -f 3) - echo "PATCH=${PATCH}" >> $GITEA_OUTPUT + echo "PATCH=${PATCH}" >> $GITHUB_OUTPUT - name: Increment version id: calc_new_tag run: | echo "${{ steps.get_id.outputs.PATCH }}" - echo "NEW_PATCH=$(( ${{ steps.get_id.outputs.PATCH }} + 1))" >> $GITEA_OUTPUT - echo "NEW_VERSION=$( ${{ steps.get_id.outputs.MAJOR }}.${{ steps.get_id.outputs.MINOR }}.${NEW_PATCH})" >> $GITEA_OUTPUT + echo "NEW_PATCH=$(( ${{ steps.get_id.outputs.PATCH }} + 1))" >> $GITHUB_OUTPUT + echo "NEW_VERSION=$( ${{ steps.get_id.outputs.MAJOR }}.${{ steps.get_id.outputs.MINOR }}.${NEW_PATCH})" >> $GITHUB_OUTPUT - name: Create and push tag run: | git tag -a ${{ steps.calc_new_tag.outputs.NEW_VERSION }} -m "Pushing new version ${{ steps.calc_new_tag.outputs.NEW_VERSION }}" From 5307ba0307169d96d6125d5759b7f7faec0f0385 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 23:14:11 +0530 Subject: [PATCH 046/102] Trying to use --- .gitea/workflows/test_image_build_push.yml | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 1295a5f..dec2b35 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -4,8 +4,25 @@ on: push: branches: [test] jobs: + tag: + runs-on: ubuntu-latest + outputs: + new_version: ${{ steps.new_version.outputs.new_version }} + steps: + id: new_version + run: | + VERSION=$(git describe --tags --abbrev=0) + echo ${VERSION} + MAJOR=$(echo ${VERSION} | cut -d "." -f 1) + MINOR=$(echo ${VERSION} | cut -d "." -f 2) + PATCH=$(echo ${VERSION} | cut -d "." -f 3) + NEW_PATCH=$(( ${PATCH} + 1)) + echo ${NEW_PATCH} + echo "new_version=$($MAJOR.$MINOR.$NEW_PATCH)" >> $GITHUB_OUTPUT + echo ${new_version} build: runs-on: ubuntu-latest + needs: tag container: image: catthehacker/ubuntu:act-latest steps: @@ -20,27 +37,10 @@ jobs: java-version: '17' - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - - name: Get latest tag - id: get_tag - run: | - VERSION=$(git describe --tags --abbrev=0) - echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT - MAJOR=$(echo ${VERSION} | cut -d "." -f 1) - echo "MAJOR=${MAJOR}" >> $GITHUB_OUTPUT - MINOR=$(echo ${VERSION} | cut -d "." -f 2) - echo "MINOR=${MINOR}" >> $GITHUB_OUTPUT - PATCH=$(echo ${VERSION} | cut -d "." -f 3) - echo "PATCH=${PATCH}" >> $GITHUB_OUTPUT - - name: Increment version - id: calc_new_tag - run: | - echo "${{ steps.get_id.outputs.PATCH }}" - echo "NEW_PATCH=$(( ${{ steps.get_id.outputs.PATCH }} + 1))" >> $GITHUB_OUTPUT - echo "NEW_VERSION=$( ${{ steps.get_id.outputs.MAJOR }}.${{ steps.get_id.outputs.MINOR }}.${NEW_PATCH})" >> $GITHUB_OUTPUT - name: Create and push tag run: | - git tag -a ${{ steps.calc_new_tag.outputs.NEW_VERSION }} -m "Pushing new version ${{ steps.calc_new_tag.outputs.NEW_VERSION }}" - git push origin ${{ steps.calc_new_tag.outputs.NEW_VERSION }} + git tag -a ${{ needs.tag.outputs.new_version }} -m "Pushing new version ${{ needs.tag.outputs.new_version }}" + git push origin ${{ needs.tag.outputs.new_version }} - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: @@ -48,10 +48,10 @@ jobs: username: hitanshu password: ${{ secrets.TOKEN }} - name: Gradle build - run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.calc_new_tag.outputs.NEW_VERSION }} + run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} - name: Tag image as test - run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.calc_new_tag.outputs.NEW_VERSION }} 192.168.0.100:8928/hithomelabs/cftunnels:test + run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} 192.168.0.100:8928/hithomelabs/cftunnels:test - name: Push to Gitea Registry run: | docker push 192.168.0.100:8928/hithomelabs/cftunnels:test - docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ steps.calc_new_tag.outputs.NEW_VERSION }} + docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} From bdb4c77ac30cebb080c512359a315b509fdac48e Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 23:15:19 +0530 Subject: [PATCH 047/102] Trying to multiple jobs --- .gitea/workflows/test_image_build_push.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index dec2b35..749327a 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -9,6 +9,10 @@ jobs: outputs: new_version: ${{ steps.new_version.outputs.new_version }} steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 id: new_version run: | VERSION=$(git describe --tags --abbrev=0) From b7c6149fb79721db3e0b5f5cf6c935b85d3fb2e0 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 23:24:03 +0530 Subject: [PATCH 048/102] Correcting syntax --- .gitea/workflows/test_image_build_push.yml | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 749327a..26b78f7 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -9,21 +9,22 @@ jobs: outputs: new_version: ${{ steps.new_version.outputs.new_version }} steps: - - name: Check out repository code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - id: new_version - run: | - VERSION=$(git describe --tags --abbrev=0) - echo ${VERSION} - MAJOR=$(echo ${VERSION} | cut -d "." -f 1) - MINOR=$(echo ${VERSION} | cut -d "." -f 2) - PATCH=$(echo ${VERSION} | cut -d "." -f 3) - NEW_PATCH=$(( ${PATCH} + 1)) - echo ${NEW_PATCH} - echo "new_version=$($MAJOR.$MINOR.$NEW_PATCH)" >> $GITHUB_OUTPUT - echo ${new_version} + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Get new version + id: new_version + run: | + VERSION=$(git describe --tags --abbrev=0) + echo ${VERSION} + MAJOR=$(echo ${VERSION} | cut -d "." -f 1) + MINOR=$(echo ${VERSION} | cut -d "." -f 2) + PATCH=$(echo ${VERSION} | cut -d "." -f 3) + NEW_PATCH=$(( ${PATCH} + 1)) + echo ${NEW_PATCH} + echo "new_version=$($MAJOR.$MINOR.$NEW_PATCH)" >> $GITHUB_OUTPUT + echo ${new_version} build: runs-on: ubuntu-latest needs: tag From fe591b8af09c22ffb31dd9a750ba937233057e97 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 23:32:54 +0530 Subject: [PATCH 049/102] Minor bugfix --- .gitea/workflows/test_image_build_push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 26b78f7..213fa22 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -23,7 +23,7 @@ jobs: PATCH=$(echo ${VERSION} | cut -d "." -f 3) NEW_PATCH=$(( ${PATCH} + 1)) echo ${NEW_PATCH} - echo "new_version=$($MAJOR.$MINOR.$NEW_PATCH)" >> $GITHUB_OUTPUT + echo "new_version=$MAJOR.$MINOR.$NEW_PATCH" >> $GITHUB_OUTPUT echo ${new_version} build: runs-on: ubuntu-latest From 5b8735bf58f8adc0e1f109b3f6b60992d7f45c82 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 23:44:55 +0530 Subject: [PATCH 050/102] Adding git config --- .gitea/workflows/test_image_build_push.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 213fa22..f97fdc9 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -23,7 +23,7 @@ jobs: PATCH=$(echo ${VERSION} | cut -d "." -f 3) NEW_PATCH=$(( ${PATCH} + 1)) echo ${NEW_PATCH} - echo "new_version=$MAJOR.$MINOR.$NEW_PATCH" >> $GITHUB_OUTPUT + echo "new_version=$(echo "${MAJOR}.${MINOR}.${NEW_PATCH}")" >> $GITHUB_OUTPUT echo ${new_version} build: runs-on: ubuntu-latest @@ -44,6 +44,8 @@ jobs: uses: gradle/actions/wrapper-validation@v3 - name: Create and push tag run: | + git config --global user.name "${{gitea.actor}}" + git config --global user.email "${{ gitea.actor }}@users.noreply.github.com" git tag -a ${{ needs.tag.outputs.new_version }} -m "Pushing new version ${{ needs.tag.outputs.new_version }}" git push origin ${{ needs.tag.outputs.new_version }} - name: Log in to Gitea Docker Registry From 33682a4425e8c9584f6d0b4c06e65e187a295ae6 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 23:45:42 +0530 Subject: [PATCH 051/102] Adding git config --- .gitea/workflows/test_image_build_push.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index f97fdc9..a933b76 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -44,6 +44,7 @@ jobs: uses: gradle/actions/wrapper-validation@v3 - name: Create and push tag run: | + echo "NEW_VERSION=${{ needs.tag.outputs.new_version }}" git config --global user.name "${{gitea.actor}}" git config --global user.email "${{ gitea.actor }}@users.noreply.github.com" git tag -a ${{ needs.tag.outputs.new_version }} -m "Pushing new version ${{ needs.tag.outputs.new_version }}" From 5fe2d96f42d7b6a70eeacdd5ee95b8fa83fa482b Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 10 Jun 2025 23:55:45 +0530 Subject: [PATCH 052/102] Add semantic versioning, when pushing to test PATH is incremented by 1 --- .gitea/workflows/test_image_build_push.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index a933b76..f53e140 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -24,8 +24,7 @@ jobs: NEW_PATCH=$(( ${PATCH} + 1)) echo ${NEW_PATCH} echo "new_version=$(echo "${MAJOR}.${MINOR}.${NEW_PATCH}")" >> $GITHUB_OUTPUT - echo ${new_version} - build: + build_tag_push: runs-on: ubuntu-latest needs: tag container: From e960c5cfa595b0e91d1cae6452c84796192e3045 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Mon, 15 Sep 2025 00:21:49 +0530 Subject: [PATCH 053/102] Final cahnges to add OIDC, setting groups and authorities --- build.gradle | 1 + docker-compose.yaml | 2 + .../Config/AuthoritiesToGroupMapping.java | 28 ++++++++++++ .../Config/CustomOidcUserConfiguration.java | 45 +++++++++++++++++++ .../Config/Security/SecuirtyConfig.java | 39 ++++++++++++++++ .../Controllers/TunnelController.java | 27 +++++++++-- .../CFTunnels/Models/Authorities.java | 10 +++++ .../hithomelabs/CFTunnels/Models/Groups.java | 10 +++++ src/main/resources/application.properties | 12 +++++ 9 files changed, 171 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Config/AuthoritiesToGroupMapping.java create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Config/CustomOidcUserConfiguration.java create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Models/Authorities.java create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Models/Groups.java diff --git a/build.gradle b/build.gradle index 49a3976..bfc0540 100644 --- a/build.gradle +++ b/build.gradle @@ -23,6 +23,7 @@ repositories { dependencies { implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.8.5' + implementation group: 'org.springframework.boot', name:'spring-boot-starter-oauth2-client', version: '3.5.5' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/docker-compose.yaml b/docker-compose.yaml index 1c03e48..7cac007 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -7,6 +7,8 @@ services: - CLOUDFLARE_API_KEY=${CLOUDFLARE_API_KEY} - CLOUDFLARE_EMAIL=${CLOUDFLARE_EMAIL} - ENV=${ENV} + - OAUTH_CLIENT_ID=${OAUTH_CLIENT_ID} + - OAUTH_CLIENT_SECRET=${OAUTH_CLIENT_SECRET} ports: - 5002:8080 restart: unless-stopped \ No newline at end of file diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/AuthoritiesToGroupMapping.java b/src/main/java/com/hithomelabs/CFTunnels/Config/AuthoritiesToGroupMapping.java new file mode 100644 index 0000000..b323700 --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/AuthoritiesToGroupMapping.java @@ -0,0 +1,28 @@ +package com.hithomelabs.CFTunnels.Config; + +import com.hithomelabs.CFTunnels.Models.Authorities; +import com.hithomelabs.CFTunnels.Models.Groups; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@Configuration +public class AuthoritiesToGroupMapping { + + public Map> getAuthorityForGroup(){ + HashMap> mappings = new HashMap<>(); + mappings.put(Groups.GITEA_USER, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_USER)))); + mappings.put(Groups.POWER_USER, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_USER)))); + mappings.put(Groups.HOMELAB_DEVELOPER, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_DEVELOPER)))); + mappings.put(Groups.SYSTEM_ADMIN, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_APPROVER), new SimpleGrantedAuthority(Authorities.ROLE_ADMIN)))); + return mappings; + } + + + +} diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/CustomOidcUserConfiguration.java b/src/main/java/com/hithomelabs/CFTunnels/Config/CustomOidcUserConfiguration.java new file mode 100644 index 0000000..22a4e64 --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/CustomOidcUserConfiguration.java @@ -0,0 +1,45 @@ +package com.hithomelabs.CFTunnels.Config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; +import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserService; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.security.oauth2.core.oidc.user.OidcUser; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Configuration +public class CustomOidcUserConfiguration extends OidcUserService { + + @Autowired + AuthoritiesToGroupMapping authoritiesToGroupMapping; + + @Override + public OidcUser loadUser(OidcUserRequest userRequest) { + // * * Delegate to the default implementation for loading user and claims + OidcUser oidcUser = super.loadUser(userRequest); + + // * * Copy existing authorities (e.g. scopes → authorities) + Set mappedAuthorities = new HashSet<>(); + + // * * Extract your custom claim (change "roles" to your claim name) + List groups = oidcUser.getClaimAsStringList("groups"); + if (groups != null) { + groups.forEach(group -> + mappedAuthorities.addAll(authoritiesToGroupMapping.getAuthorityForGroup().get(group)) + ); + } + + // * * Return a new DefaultOidcUser with merged authorities + return new DefaultOidcUser( + mappedAuthorities, + oidcUser.getIdToken(), + oidcUser.getUserInfo() + ); + } + } + diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java b/src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java new file mode 100644 index 0000000..7bd9c1e --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java @@ -0,0 +1,39 @@ +package com.hithomelabs.CFTunnels.Config.Security; + +import com.hithomelabs.CFTunnels.Config.CustomOidcUserConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer; +import org.springframework.security.web.SecurityFilterChain; + + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity( + prePostEnabled = true, + securedEnabled = true, + jsr250Enabled = true +) +public class SecuirtyConfig { + + @Autowired + private CustomOidcUserConfiguration customOidcUserConfiguration; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .authorizeHttpRequests(auth -> auth + .anyRequest().authenticated() + ) + .with(new OAuth2LoginConfigurer<>(), oauth2 -> oauth2.userInfoEndpoint(u -> u.oidcUserService(customOidcUserConfiguration))); + + + return http.build(); + } + +} diff --git a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java index 9e8ad9c..fc8819f 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java @@ -1,8 +1,7 @@ package com.hithomelabs.CFTunnels.Controllers; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; +import com.hithomelabs.CFTunnels.Config.AuthoritiesToGroupMapping; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Config.RestTemplateConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; @@ -11,7 +10,10 @@ import com.hithomelabs.CFTunnels.Models.Ingress; import com.hithomelabs.CFTunnels.Models.TunnelResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.*; -import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.web.bind.annotation.*; import org.springframework.web.client.RestTemplate; @@ -25,6 +27,8 @@ public class TunnelController { private final RestTemplate restTemplate = new RestTemplate(); + @Autowired + private AuthoritiesToGroupMapping authoritiesToGroupMapping; @Autowired private CloudflareConfig cloudflareConfig; @@ -34,6 +38,20 @@ public class TunnelController { @Autowired private RestTemplateConfig restTemplateConfig; + @PreAuthorize("hasAnyRole('USER')") + @GetMapping("/whoami") + public Map whoAmI(@AuthenticationPrincipal OidcUser oidcUser) { + + List authorities = oidcUser.getAuthorities().stream() + .map(GrantedAuthority::getAuthority) + .toList(); + return Map.of( + "username", oidcUser.getPreferredUsername(), + "roles", authorities + ); + } + + @PreAuthorize("hasAnyRole('USER')") @GetMapping("/tunnels") public ResponseEntity> getTunnels(){ @@ -50,6 +68,7 @@ public class TunnelController { return ResponseEntity.ok(jsonResponse); } + @PreAuthorize("hasAnyRole('DEVELOPER')") @GetMapping("/tunnel/{tunnelId}") public ResponseEntity> getTunnelConfigurations(@PathVariable String tunnelId) throws JsonProcessingException { @@ -67,6 +86,7 @@ public class TunnelController { } // 50df9101-f625-4618-b7c5-100338a57124 + @PreAuthorize("hasAnyRole('ADMIN')") @PutMapping("/tunnel/{tunnelId}/add") public ResponseEntity> addTunnelconfiguration(@PathVariable String tunnelId, @RequestBody Ingress ingress) throws JsonProcessingException { @@ -95,6 +115,7 @@ public class TunnelController { return ResponseEntity.ok(jsonResponse); } + @PreAuthorize("hasAnyRole('DEVELOPER')") @PutMapping("/tunnel/{tunnelId}/delete") public ResponseEntity> deleteTunnelConfiguration(@PathVariable String tunnelId, @RequestBody Ingress ingress) throws JsonProcessingException { diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/Authorities.java b/src/main/java/com/hithomelabs/CFTunnels/Models/Authorities.java new file mode 100644 index 0000000..f26a17b --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Models/Authorities.java @@ -0,0 +1,10 @@ +package com.hithomelabs.CFTunnels.Models; + +public class Authorities { + + public static final String ROLE_ADMIN = "ROLE_ADMIN"; + public static final String ROLE_DEVELOPER = "ROLE_DEVELOPER"; + public static final String ROLE_USER = "ROLE_USER"; + public static final String ROLE_APPROVER = "ROLE_APPROVER"; + +} diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/Groups.java b/src/main/java/com/hithomelabs/CFTunnels/Models/Groups.java new file mode 100644 index 0000000..f7c213d --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Models/Groups.java @@ -0,0 +1,10 @@ +package com.hithomelabs.CFTunnels.Models; + +public class Groups { + + public static final String HOMELAB_DEVELOPER = "homelab developer"; + public static final String SYSTEM_ADMIN = "authentik Admins"; + public static final String POWER_USER = "arr premium"; + public static final String GITEA_USER = "gitrestricted"; + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9b04cc9..3ba3827 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -3,3 +3,15 @@ cloudflare.accountId=${CLOUDFLARE_ACCOUNT_ID} cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} spring.profiles.active=${ENV} + +spring.security.oauth2.client.registration.cftunnels.client-id=${OAUTH_CLIENT_ID} +spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIENT_SECRET} +spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code +spring.security.oauth2.client.registration.cftunnels.redirect-uri={baseUrl}/login/oauth2/code/cftunnels +spring.security.oauth2.client.registration.cftunnels.scope=openid,profile,email,offline_access,cftunnels + +spring.security.oauth2.client.provider.cftunnels.authorization-uri=https://auth.hithomelabs.com/application/o/authorize/ +spring.security.oauth2.client.provider.cftunnels.token-uri=https://auth.hithomelabs.com/application/o/token/ +spring.security.oauth2.client.provider.cftunnels.user-info-uri=https://auth.hithomelabs.com/application/o/userinfo/ +spring.security.oauth2.client.provider.cftunnels.jwk-set-uri=https://auth.hithomelabs.com/application/o/cftunnels/jwks/ +spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ \ No newline at end of file From 674d541d7848519b421217649ce46641ada95799 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Mon, 15 Sep 2025 00:59:13 +0530 Subject: [PATCH 054/102] Trying to address the issue of redirect_uri --- src/main/resources/application-test.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index e5c014b..9f52712 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -1 +1 @@ -api.baseUrl=https://testcf.hithomelabs.com \ No newline at end of file +api.baseUrl=http://192.168.0.100:5002 \ No newline at end of file From f1ec120715c93f9c82bd4230fea3acd7b811b799 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Mon, 15 Sep 2025 01:17:29 +0530 Subject: [PATCH 055/102] Tinkering with redirect-uri --- src/main/resources/application-test.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index 9f52712..e5c014b 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -1 +1 @@ -api.baseUrl=http://192.168.0.100:5002 \ No newline at end of file +api.baseUrl=https://testcf.hithomelabs.com \ No newline at end of file From 37a57279fdd8c31730d896e359ab816439a2a8d8 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Mon, 15 Sep 2025 01:43:31 +0530 Subject: [PATCH 056/102] Trying something seeing if it works --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3ba3827..1b13697 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,7 +7,7 @@ spring.profiles.active=${ENV} spring.security.oauth2.client.registration.cftunnels.client-id=${OAUTH_CLIENT_ID} spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIENT_SECRET} spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code -spring.security.oauth2.client.registration.cftunnels.redirect-uri={baseUrl}/login/oauth2/code/cftunnels +spring.security.oauth2.client.registration.cftunnels.redirect-uri=http://localhost:8080/login/oauth2/code/cftunnels spring.security.oauth2.client.registration.cftunnels.scope=openid,profile,email,offline_access,cftunnels spring.security.oauth2.client.provider.cftunnels.authorization-uri=https://auth.hithomelabs.com/application/o/authorize/ From e46974870a00aa41022ade71a76811636186bd39 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Mon, 15 Sep 2025 01:57:34 +0530 Subject: [PATCH 057/102] Trying to avoid clash with baseUrl variable --- .../com/hithomelabs/CFTunnels/Config/OpenApiConfig.java | 6 +++--- src/main/resources/application-local.properties | 2 +- src/main/resources/application-prod.properties | 2 +- src/main/resources/application-test.properties | 2 +- src/main/resources/application.properties | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java index e24e6f5..ef3b098 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java @@ -11,12 +11,12 @@ import java.util.ArrayList; @Configuration public class OpenApiConfig { - @Value("${api.baseUrl}") - private String baseUrl; + @Value("${api.corsResolveUrl}") + private String corsResolveUrl; @Bean public OpenAPI openAPI(){ - Server httpsServer = new Server().url(baseUrl); + Server httpsServer = new Server().url(corsResolveUrl); OpenAPI openApi = new OpenAPI(); ArrayList servers = new ArrayList<>(); servers.add(httpsServer); diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index fdb25ce..9001ed2 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1 +1 @@ -api.baseUrl=http://localhost:8080 \ No newline at end of file +api.corsResolveUrl=http://localhost:8080 \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index dec0f4b..5126249 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1 +1 @@ -api.baseUrl=https://cftunnels.hithomelabs.com \ No newline at end of file +api.corsResolveUrl=https://cftunnels.hithomelabs.com \ No newline at end of file diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index e5c014b..1ea328b 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -1 +1 @@ -api.baseUrl=https://testcf.hithomelabs.com \ No newline at end of file +api.corsResolveUrl=https://testcf.hithomelabs.com \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1b13697..3ba3827 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,7 +7,7 @@ spring.profiles.active=${ENV} spring.security.oauth2.client.registration.cftunnels.client-id=${OAUTH_CLIENT_ID} spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIENT_SECRET} spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code -spring.security.oauth2.client.registration.cftunnels.redirect-uri=http://localhost:8080/login/oauth2/code/cftunnels +spring.security.oauth2.client.registration.cftunnels.redirect-uri={baseUrl}/login/oauth2/code/cftunnels spring.security.oauth2.client.registration.cftunnels.scope=openid,profile,email,offline_access,cftunnels spring.security.oauth2.client.provider.cftunnels.authorization-uri=https://auth.hithomelabs.com/application/o/authorize/ From e04ac4b73d8889c59c926652af94fd364ab5b6fb Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 16 Sep 2025 00:27:12 +0530 Subject: [PATCH 058/102] Adding config to make sping boot return an https redirect URI --- src/main/resources/application.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3ba3827..c3fb4db 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,6 +4,8 @@ cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} spring.profiles.active=${ENV} +server.forward-headers-strategy=framework + spring.security.oauth2.client.registration.cftunnels.client-id=${OAUTH_CLIENT_ID} spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIENT_SECRET} spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code From 30ec013002f19d63eec69f5302e502ae5bf5e10f Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Tue, 16 Sep 2025 01:30:02 +0530 Subject: [PATCH 059/102] Trying to do everythng via http --- src/main/resources/application-test.properties | 3 ++- src/main/resources/application.properties | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index 1ea328b..fb3cd9e 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -1 +1,2 @@ -api.corsResolveUrl=https://testcf.hithomelabs.com \ No newline at end of file +api.corsResolveUrl=https://testcf.hithomelabs.com +spring.security.oauth2.client.registration.cftunnels.redirect-uri=http://192.168.0.100:5002/login/oauth2/code/cftunnels \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c3fb4db..3ba3827 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,8 +4,6 @@ cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} spring.profiles.active=${ENV} -server.forward-headers-strategy=framework - spring.security.oauth2.client.registration.cftunnels.client-id=${OAUTH_CLIENT_ID} spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIENT_SECRET} spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code From b3b3d4a441052f91724faca8deed41b6405eff47 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 20 Sep 2025 20:29:48 +0530 Subject: [PATCH 060/102] Trying to fix OIDC configuration with TLS termination behind reverse proxy --- src/main/resources/application-test.properties | 3 +-- src/main/resources/application.properties | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index fb3cd9e..1ea328b 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -1,2 +1 @@ -api.corsResolveUrl=https://testcf.hithomelabs.com -spring.security.oauth2.client.registration.cftunnels.redirect-uri=http://192.168.0.100:5002/login/oauth2/code/cftunnels \ No newline at end of file +api.corsResolveUrl=https://testcf.hithomelabs.com \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 3ba3827..03b15a5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,14 +4,10 @@ cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} spring.profiles.active=${ENV} +server.forward-headers-strategy=framework spring.security.oauth2.client.registration.cftunnels.client-id=${OAUTH_CLIENT_ID} spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIENT_SECRET} spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code spring.security.oauth2.client.registration.cftunnels.redirect-uri={baseUrl}/login/oauth2/code/cftunnels spring.security.oauth2.client.registration.cftunnels.scope=openid,profile,email,offline_access,cftunnels - -spring.security.oauth2.client.provider.cftunnels.authorization-uri=https://auth.hithomelabs.com/application/o/authorize/ -spring.security.oauth2.client.provider.cftunnels.token-uri=https://auth.hithomelabs.com/application/o/token/ -spring.security.oauth2.client.provider.cftunnels.user-info-uri=https://auth.hithomelabs.com/application/o/userinfo/ -spring.security.oauth2.client.provider.cftunnels.jwk-set-uri=https://auth.hithomelabs.com/application/o/cftunnels/jwks/ -spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ \ No newline at end of file +spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels \ No newline at end of file From 84b2b5aead9df6e7664ff1753ffc58a8786223fb Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 20 Sep 2025 20:40:19 +0530 Subject: [PATCH 061/102] Fixing breaking build --- src/main/resources/application.properties | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 03b15a5..b95f4d1 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,4 +10,8 @@ spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIEN spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code spring.security.oauth2.client.registration.cftunnels.redirect-uri={baseUrl}/login/oauth2/code/cftunnels spring.security.oauth2.client.registration.cftunnels.scope=openid,profile,email,offline_access,cftunnels -spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels \ No newline at end of file +spring.security.oauth2.client.provider.cftunnels.authorization-uri=https://auth.hithomelabs.com/application/o/authorize/ +spring.security.oauth2.client.provider.cftunnels.token-uri=https://auth.hithomelabs.com/application/o/token/ +spring.security.oauth2.client.provider.cftunnels.user-info-uri=https://auth.hithomelabs.com/application/o/userinfo/ +spring.security.oauth2.client.provider.cftunnels.jwk-set-uri=https://auth.hithomelabs.com/application/o/cftunnels/jwks/ +spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ \ No newline at end of file From 77a43bfde89ae2758a6720f60c3a50a812160eb9 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 20 Sep 2025 21:00:58 +0530 Subject: [PATCH 062/102] Adding new URL mapping that redirects / to swagger UI --- .../hithomelabs/CFTunnels/Controllers/TunnelController.java | 5 +++++ src/main/resources/application.properties | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java index fc8819f..8c9d145 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java @@ -38,6 +38,11 @@ public class TunnelController { @Autowired private RestTemplateConfig restTemplateConfig; + @GetMapping("/") + public String redirectToSwagger() { + return "redirect:/swagger-ui/index.html"; + } + @PreAuthorize("hasAnyRole('USER')") @GetMapping("/whoami") public Map whoAmI(@AuthenticationPrincipal OidcUser oidcUser) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b95f4d1..4774989 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,7 +4,9 @@ cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} spring.profiles.active=${ENV} +/ * * Masking sure app works behind a reverse proxy server.forward-headers-strategy=framework + spring.security.oauth2.client.registration.cftunnels.client-id=${OAUTH_CLIENT_ID} spring.security.oauth2.client.registration.cftunnels.client-secret=${OAUTH_CLIENT_SECRET} spring.security.oauth2.client.registration.cftunnels.authorization-grant-type=authorization_code From 40168545148990ba216f2e94b67e7d26ea1a8abb Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 20 Sep 2025 21:29:53 +0530 Subject: [PATCH 063/102] Adding a new HomeController to redirect to swagger UI --- .../CFTunnels/Controllers/HomeController.java | 32 +++++++++++++++++++ .../Controllers/TunnelController.java | 9 ++---- 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Controllers/HomeController.java diff --git a/src/main/java/com/hithomelabs/CFTunnels/Controllers/HomeController.java b/src/main/java/com/hithomelabs/CFTunnels/Controllers/HomeController.java new file mode 100644 index 0000000..43ea57a --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Controllers/HomeController.java @@ -0,0 +1,32 @@ +package com.hithomelabs.CFTunnels.Controllers; + + +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +@Controller +public class HomeController implements ErrorController { + + private static final String ERROR_PATH = "/error"; + + /** + * Redirects the root (including any query params like ?continue=…) + * straight into Swagger UI. + */ + @GetMapping("/") + public String rootRedirect() { + return "redirect:/swagger-ui/index.html"; + } + + /** + * Catches any errors (404s, unhandled paths) and punts them + * into the same Swagger UI page. + */ + @RequestMapping(ERROR_PATH) + public String onError() { + return "redirect:/swagger-ui/index.html"; + } + +} diff --git a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java index 8c9d145..612fc78 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java @@ -9,6 +9,7 @@ import com.hithomelabs.CFTunnels.Models.Config; import com.hithomelabs.CFTunnels.Models.Ingress; import com.hithomelabs.CFTunnels.Models.TunnelResponse; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.*; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.GrantedAuthority; @@ -23,9 +24,10 @@ import java.util.Map; @RestController @RequestMapping("/cloudflare") -public class TunnelController { +public class TunnelController implements ErrorController { private final RestTemplate restTemplate = new RestTemplate(); + private static final String ERROR_PATH = "/error"; @Autowired private AuthoritiesToGroupMapping authoritiesToGroupMapping; @@ -38,11 +40,6 @@ public class TunnelController { @Autowired private RestTemplateConfig restTemplateConfig; - @GetMapping("/") - public String redirectToSwagger() { - return "redirect:/swagger-ui/index.html"; - } - @PreAuthorize("hasAnyRole('USER')") @GetMapping("/whoami") public Map whoAmI(@AuthenticationPrincipal OidcUser oidcUser) { From c8ba9ef6a965091567d02464b6b46f189c7afd21 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 20 Sep 2025 23:31:18 +0530 Subject: [PATCH 064/102] Incrementing minor version and building an PROD image when PR merged to main --- .gitea/workflows/prod_image_build_push.yaml | 64 +++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .gitea/workflows/prod_image_build_push.yaml diff --git a/.gitea/workflows/prod_image_build_push.yaml b/.gitea/workflows/prod_image_build_push.yaml new file mode 100644 index 0000000..ec31a2c --- /dev/null +++ b/.gitea/workflows/prod_image_build_push.yaml @@ -0,0 +1,64 @@ +name: Promote image with tag test to prod +run-name: Build started by $ {{gitea.actor}} +on: + push: + branches: [main] +jobs: + tag: + runs-on: ubuntu-latest + outputs: + new_version: ${{ steps.new_version.outputs.new_version }} + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Get new version + id: new_version + run: | + VERSION=$(git describe --tags --abbrev=0) + echo ${VERSION} + MAJOR=$(echo ${VERSION} | cut -d "." -f 1) + MINOR=$(echo ${VERSION} | cut -d "." -f 2) + PATCH=0 + NEW_MINOR=$(( ${MINOR} + 1)) + echo ${NEW_MINOR} + echo "new_version=$(echo "${MAJOR}.${NEW_MINOR}.${PATCH}")" >> $GITHUB_OUTPUT + build_tag_push: + runs-on: ubuntu-latest + needs: tag + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: JDK setup + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + - name: Validate Gradle Wrapper + uses: gradle/actions/wrapper-validation@v3 + - name: Create and push tag + run: | + echo "NEW_VERSION=${{ needs.tag.outputs.new_version }}" + git config --global user.name "${{gitea.actor}}" + git config --global user.email "${{ gitea.actor }}@users.noreply.github.com" + git tag -a ${{ needs.tag.outputs.new_version }} -m "Pushing new version ${{ needs.tag.outputs.new_version }}" + git push origin ${{ needs.tag.outputs.new_version }} + - name: Log in to Gitea Docker Registry + uses: docker/login-action@v3 + with: + registry: 'http://192.168.0.100:8928' + username: hitanshu + password: ${{ secrets.TOKEN }} + - name: Gradle build + run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} + - name: Tag image as test + run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} 192.168.0.100:8928/hithomelabs/cftunnels:prod + - name: Push to Gitea Registry + run: | + docker push 192.168.0.100:8928/hithomelabs/cftunnels:prod + docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} From 831aaa41ebdaf6a87a589f1352e47d6c627d33e9 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 21 Sep 2025 00:34:20 +0530 Subject: [PATCH 065/102] Adding port config based on environment variables, removing gradle build for prod deployment --- ..._image_build_push.yaml => prod_image_tag_promote.yaml} | 8 ++++---- docker-compose.yaml | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) rename .gitea/workflows/{prod_image_build_push.yaml => prod_image_tag_promote.yaml} (86%) diff --git a/.gitea/workflows/prod_image_build_push.yaml b/.gitea/workflows/prod_image_tag_promote.yaml similarity index 86% rename from .gitea/workflows/prod_image_build_push.yaml rename to .gitea/workflows/prod_image_tag_promote.yaml index ec31a2c..fcef6f0 100644 --- a/.gitea/workflows/prod_image_build_push.yaml +++ b/.gitea/workflows/prod_image_tag_promote.yaml @@ -54,10 +54,10 @@ jobs: registry: 'http://192.168.0.100:8928' username: hitanshu password: ${{ secrets.TOKEN }} - - name: Gradle build - run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} - - name: Tag image as test - run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} 192.168.0.100:8928/hithomelabs/cftunnels:prod + - name: Tag prod image + run: | + docker tag 192.168.0.100:8928/hithomelabs/cftunnels:test 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} + docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} 192.168.0.100:8928/hithomelabs/cftunnels:prod - name: Push to Gitea Registry run: | docker push 192.168.0.100:8928/hithomelabs/cftunnels:prod diff --git a/docker-compose.yaml b/docker-compose.yaml index 7cac007..29e1529 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -2,6 +2,8 @@ services: app: image: gitea.hithomelabs.com/hithomelabs/cftunnels:${ENV} container_name: cftunnels_${ENV} + ports: + - "${HOST_PORT:-5002}:8080 environment: - CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID} - CLOUDFLARE_API_KEY=${CLOUDFLARE_API_KEY} @@ -9,6 +11,5 @@ services: - ENV=${ENV} - OAUTH_CLIENT_ID=${OAUTH_CLIENT_ID} - OAUTH_CLIENT_SECRET=${OAUTH_CLIENT_SECRET} - ports: - - 5002:8080 + - HOST_PORT=${HOST_PORT} restart: unless-stopped \ No newline at end of file From b98dad9c4b7090bb2b64be873402e51c4aa6e1dc Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 21 Sep 2025 00:47:23 +0530 Subject: [PATCH 066/102] removing JDK seup and gradle wrapper validation as not needed --- .gitea/workflows/test_image_build_push.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index f53e140..ab3e539 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -34,13 +34,6 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - - name: JDK setup - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '17' - - name: Validate Gradle Wrapper - uses: gradle/actions/wrapper-validation@v3 - name: Create and push tag run: | echo "NEW_VERSION=${{ needs.tag.outputs.new_version }}" From 0f04461a928552fba3bbcecee9f728efc7139f44 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 21 Sep 2025 00:48:58 +0530 Subject: [PATCH 067/102] Restoring and making changes to the correct workflow --- .gitea/workflows/prod_image_tag_promote.yaml | 7 ------- .gitea/workflows/test_image_build_push.yml | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitea/workflows/prod_image_tag_promote.yaml b/.gitea/workflows/prod_image_tag_promote.yaml index fcef6f0..a2a2a16 100644 --- a/.gitea/workflows/prod_image_tag_promote.yaml +++ b/.gitea/workflows/prod_image_tag_promote.yaml @@ -34,13 +34,6 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - - name: JDK setup - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '17' - - name: Validate Gradle Wrapper - uses: gradle/actions/wrapper-validation@v3 - name: Create and push tag run: | echo "NEW_VERSION=${{ needs.tag.outputs.new_version }}" diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index ab3e539..f53e140 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -34,6 +34,13 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: JDK setup + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + - name: Validate Gradle Wrapper + uses: gradle/actions/wrapper-validation@v3 - name: Create and push tag run: | echo "NEW_VERSION=${{ needs.tag.outputs.new_version }}" From 6b6ef23108ed33c7a9647a95700930c6bcbb7805 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 21 Sep 2025 01:00:18 +0530 Subject: [PATCH 068/102] Fixing faulty docker-compose --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 29e1529..ce91374 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -3,7 +3,7 @@ services: image: gitea.hithomelabs.com/hithomelabs/cftunnels:${ENV} container_name: cftunnels_${ENV} ports: - - "${HOST_PORT:-5002}:8080 + - ${HOST_PORT}:8080 environment: - CLOUDFLARE_ACCOUNT_ID=${CLOUDFLARE_ACCOUNT_ID} - CLOUDFLARE_API_KEY=${CLOUDFLARE_API_KEY} From fb4ff607299f337d6c911a8f94f8844f26c725f6 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 21 Sep 2025 12:29:30 +0530 Subject: [PATCH 069/102] Adding env file placeholder is manddatory for portainer env variables workflow --- docker-compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index ce91374..b014137 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,4 +12,6 @@ services: - OAUTH_CLIENT_ID=${OAUTH_CLIENT_ID} - OAUTH_CLIENT_SECRET=${OAUTH_CLIENT_SECRET} - HOST_PORT=${HOST_PORT} + env_file: + - stack.env restart: unless-stopped \ No newline at end of file From c567cf766d34e163b75e66ab1686aaaeb299911e Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 21:59:55 +0530 Subject: [PATCH 070/102] Postgres integration --- build.gradle | 4 ++ docker-compose.yaml | 21 ++++++++++- .../resources/application-local.properties | 9 ++++- src/main/resources/application.properties | 13 ++++++- src/main/resources/schema.sql | 37 +++++++++++++++++++ 5 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/schema.sql diff --git a/build.gradle b/build.gradle index bfc0540..2c09e0d 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'org.postgresql:postgresql' + implementation 'org.hibernate.validator:hibernate-validator' } tasks.named('test') { diff --git a/docker-compose.yaml b/docker-compose.yaml index b014137..772008b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,6 +12,23 @@ services: - OAUTH_CLIENT_ID=${OAUTH_CLIENT_ID} - OAUTH_CLIENT_SECRET=${OAUTH_CLIENT_SECRET} - HOST_PORT=${HOST_PORT} + - POSTGRES_USER=${POSTGRES_USERNAME} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} env_file: - - stack.env - restart: unless-stopped \ No newline at end of file + - .env + restart: unless-stopped + postgres: + image: postgres:15 + container_name: cftunnel-db + environment: + POSTGRES_DB: cftunnel + POSTGRES_USER: ${POSTGRES_USERNAME} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + restart: unless-stopped + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + +volumes: + pgdata: {} \ No newline at end of file diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 9001ed2..556b2d1 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1 +1,8 @@ -api.corsResolveUrl=http://localhost:8080 \ No newline at end of file +api.corsResolveUrl=http://localhost:8080 + +management.health.db.enabled=true +management.endpoints.web.exposure.include=health +management.endpoint.health.show-details=always + +logging.level.org.hibernate.SQL=DEBUG +debug=true diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4774989..e6d31e7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -16,4 +16,15 @@ spring.security.oauth2.client.provider.cftunnels.authorization-uri=https://auth. spring.security.oauth2.client.provider.cftunnels.token-uri=https://auth.hithomelabs.com/application/o/token/ spring.security.oauth2.client.provider.cftunnels.user-info-uri=https://auth.hithomelabs.com/application/o/userinfo/ spring.security.oauth2.client.provider.cftunnels.jwk-set-uri=https://auth.hithomelabs.com/application/o/cftunnels/jwks/ -spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ \ No newline at end of file +spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ + +spring.datasource.url=jdbc:postgresql://localhost:5432/cftunnel +spring.datasource.username=${POSTGRES_USERNAME} +spring.datasource.password=${POSTGRES_PASSWORD} +spring.datasource.driver-class-name=org.postgresql.Driver +spring.sql.init.mode=always + +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000..1fa876d --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,37 @@ +-- schema.sql + +-- Roles table +CREATE TABLE IF NOT EXISTS roles ( + role_id SERIAL PRIMARY KEY, + role_name VARCHAR(50) UNIQUE NOT NULL +); + +-- Users table +CREATE TABLE IF NOT EXISTS users ( + user_id SERIAL PRIMARY KEY, + user_name VARCHAR(100) NOT NULL, + password VARCHAR(255) NOT NULL +); + +-- User-Role Mapping table (many-to-many relationship) +CREATE TABLE IF NOT EXISTS user_role_mapping ( + mapping_id SERIAL PRIMARY KEY, + user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE, + role_id INTEGER NOT NULL REFERENCES roles(role_id) ON DELETE CASCADE +); + +-- Tunnels table +CREATE TABLE IF NOT EXISTS tunnels ( + tunnel_id SERIAL PRIMARY KEY, + tunnel_name VARCHAR(100) NOT NULL, + tunnel_type VARCHAR(50) NOT NULL +); + +-- Mapping Requests table +CREATE TABLE IF NOT EXISTS mapping_requests ( + request_id SERIAL PRIMARY KEY, + request_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(20) NOT NULL, + user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL, + tunnel_id INTEGER REFERENCES tunnels(tunnel_id) ON DELETE SET NULL +); From bbadd41ec482aa2bdff2ee4f8d48d97e4d1e7fd9 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 22:55:05 +0530 Subject: [PATCH 071/102] bug fixes --- build.gradle | 1 - docker-compose.yaml | 9 +++------ src/main/resources/application-local.properties | 2 ++ src/main/resources/application.properties | 5 +++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 2c09e0d..4340fce 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'org.postgresql:postgresql' implementation 'org.hibernate.validator:hibernate-validator' diff --git a/docker-compose.yaml b/docker-compose.yaml index 772008b..f33b9fe 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,10 +15,10 @@ services: - POSTGRES_USER=${POSTGRES_USERNAME} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} env_file: - - .env + - stack.env restart: unless-stopped postgres: - image: postgres:15 + image: postgres:15-alpine container_name: cftunnel-db environment: POSTGRES_DB: cftunnel @@ -28,7 +28,4 @@ services: ports: - "5432:5432" volumes: - - pgdata:/var/lib/postgresql/data - -volumes: - pgdata: {} \ No newline at end of file + - ${DB_PATH}:/var/lib/postgresql/data \ No newline at end of file diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 556b2d1..c355d6f 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -6,3 +6,5 @@ management.endpoint.health.show-details=always logging.level.org.hibernate.SQL=DEBUG debug=true + +spring.datasource.url=jdbc:postgresql://localhost:5432/cftunnel diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e6d31e7..c241382 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -18,7 +18,7 @@ spring.security.oauth2.client.provider.cftunnels.user-info-uri=https://auth.hith spring.security.oauth2.client.provider.cftunnels.jwk-set-uri=https://auth.hithomelabs.com/application/o/cftunnels/jwks/ spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ -spring.datasource.url=jdbc:postgresql://localhost:5432/cftunnel +spring.datasource.url=jdbc:postgresql://192.168.0.100:5432/cftunnel spring.datasource.username=${POSTGRES_USERNAME} spring.datasource.password=${POSTGRES_PASSWORD} spring.datasource.driver-class-name=org.postgresql.Driver @@ -26,5 +26,6 @@ spring.sql.init.mode=always spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + +spring.jpa.open-in-view=false \ No newline at end of file From 729d0ddcfc366a2c931a55bf2a4fd7ce85e8b924 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 23:28:24 +0530 Subject: [PATCH 072/102] sql init set to never --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c241382..72edec8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -22,7 +22,7 @@ spring.datasource.url=jdbc:postgresql://192.168.0.100:5432/cftunnel spring.datasource.username=${POSTGRES_USERNAME} spring.datasource.password=${POSTGRES_PASSWORD} spring.datasource.driver-class-name=org.postgresql.Driver -spring.sql.init.mode=always +spring.sql.init.mode=never spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true From b804cc978fc428dec16c089e547f36ed62201beb Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 23:38:40 +0530 Subject: [PATCH 073/102] dialect readded --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 72edec8..a0264d2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -26,6 +26,6 @@ spring.sql.init.mode=never spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true - +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.open-in-view=false \ No newline at end of file From 057d0120b7ab22802d57754c5aa982da9f0a1ad4 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 23:58:14 +0530 Subject: [PATCH 074/102] db port variable added --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index f33b9fe..f8cb6ed 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,6 +26,6 @@ services: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} restart: unless-stopped ports: - - "5432:5432" + - "${DB_PORT}:5432" volumes: - ${DB_PATH}:/var/lib/postgresql/data \ No newline at end of file From c8e8817e257ccf3c977717a109df8b063cdad21f Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 18 Oct 2025 16:35:23 +0530 Subject: [PATCH 075/102] ISSUE-43: Attempting to fix Hithomelabs/HomeLabDocker#43 disbling server side csrf check --- .../com/hithomelabs/CFTunnels/Config/OpenApiConfig.java | 6 +++--- .../CFTunnels/Config/Security/SecuirtyConfig.java | 9 +++++---- .../CFTunnels/Controllers/TunnelController.java | 2 +- src/main/resources/application-local.properties | 2 +- src/main/resources/application-prod.properties | 2 +- src/main/resources/application-test.properties | 2 +- src/main/resources/application.properties | 6 ++++++ 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java index ef3b098..e24e6f5 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java @@ -11,12 +11,12 @@ import java.util.ArrayList; @Configuration public class OpenApiConfig { - @Value("${api.corsResolveUrl}") - private String corsResolveUrl; + @Value("${api.baseUrl}") + private String baseUrl; @Bean public OpenAPI openAPI(){ - Server httpsServer = new Server().url(corsResolveUrl); + Server httpsServer = new Server().url(baseUrl); OpenAPI openApi = new OpenAPI(); ArrayList servers = new ArrayList<>(); servers.add(httpsServer); diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java b/src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java index 7bd9c1e..81def11 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/Security/SecuirtyConfig.java @@ -16,8 +16,8 @@ import org.springframework.security.web.SecurityFilterChain; @EnableWebSecurity @EnableMethodSecurity( prePostEnabled = true, - securedEnabled = true, - jsr250Enabled = true + securedEnabled = true, + jsr250Enabled = true ) public class SecuirtyConfig { @@ -29,8 +29,9 @@ public class SecuirtyConfig { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() - ) - .with(new OAuth2LoginConfigurer<>(), oauth2 -> oauth2.userInfoEndpoint(u -> u.oidcUserService(customOidcUserConfiguration))); + ).csrf(csrf -> csrf.disable()) + .with(new OAuth2LoginConfigurer<>(), + oauth2 -> oauth2.userInfoEndpoint(u -> u.oidcUserService(customOidcUserConfiguration))); return http.build(); diff --git a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java index 612fc78..902cb55 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java @@ -87,7 +87,7 @@ public class TunnelController implements ErrorController { return ResponseEntity.ok(jsonResponse); } -// 50df9101-f625-4618-b7c5-100338a57124 + // 50df9101-f625-4618-b7c5-100338a57124 @PreAuthorize("hasAnyRole('ADMIN')") @PutMapping("/tunnel/{tunnelId}/add") public ResponseEntity> addTunnelconfiguration(@PathVariable String tunnelId, @RequestBody Ingress ingress) throws JsonProcessingException { diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 9001ed2..fdb25ce 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1 +1 @@ -api.corsResolveUrl=http://localhost:8080 \ No newline at end of file +api.baseUrl=http://localhost:8080 \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 5126249..dec0f4b 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1 +1 @@ -api.corsResolveUrl=https://cftunnels.hithomelabs.com \ No newline at end of file +api.baseUrl=https://cftunnels.hithomelabs.com \ No newline at end of file diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties index 1ea328b..e5c014b 100644 --- a/src/main/resources/application-test.properties +++ b/src/main/resources/application-test.properties @@ -1 +1 @@ -api.corsResolveUrl=https://testcf.hithomelabs.com \ No newline at end of file +api.baseUrl=https://testcf.hithomelabs.com \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4774989..5f1c452 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,6 +4,12 @@ cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} spring.profiles.active=${ENV} +# set root level +logging.level.root=INFO +# package-specific +logging.level.org.springframework=TRACE +logging.level.com.myapp=INFO + / * * Masking sure app works behind a reverse proxy server.forward-headers-strategy=framework From e9e6bd69f9afa5a5eefe8b89341658aa28629ff6 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 21:59:55 +0530 Subject: [PATCH 076/102] Adding Postgres integration --- build.gradle | 4 ++ docker-compose.yaml | 21 ++++++++++- .../resources/application-local.properties | 9 ++++- src/main/resources/application.properties | 13 ++++++- src/main/resources/schema.sql | 37 +++++++++++++++++++ 5 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/schema.sql diff --git a/build.gradle b/build.gradle index bfc0540..2c09e0d 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'org.postgresql:postgresql' + implementation 'org.hibernate.validator:hibernate-validator' } tasks.named('test') { diff --git a/docker-compose.yaml b/docker-compose.yaml index b014137..772008b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -12,6 +12,23 @@ services: - OAUTH_CLIENT_ID=${OAUTH_CLIENT_ID} - OAUTH_CLIENT_SECRET=${OAUTH_CLIENT_SECRET} - HOST_PORT=${HOST_PORT} + - POSTGRES_USER=${POSTGRES_USERNAME} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} env_file: - - stack.env - restart: unless-stopped \ No newline at end of file + - .env + restart: unless-stopped + postgres: + image: postgres:15 + container_name: cftunnel-db + environment: + POSTGRES_DB: cftunnel + POSTGRES_USER: ${POSTGRES_USERNAME} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + restart: unless-stopped + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + +volumes: + pgdata: {} \ No newline at end of file diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index fdb25ce..21709da 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -1 +1,8 @@ -api.baseUrl=http://localhost:8080 \ No newline at end of file +api.baseUrl=http://localhost:8080 + +management.health.db.enabled=true +management.endpoints.web.exposure.include=health +management.endpoint.health.show-details=always + +logging.level.org.hibernate.SQL=DEBUG +debug=true diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5f1c452..16bd18b 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -22,4 +22,15 @@ spring.security.oauth2.client.provider.cftunnels.authorization-uri=https://auth. spring.security.oauth2.client.provider.cftunnels.token-uri=https://auth.hithomelabs.com/application/o/token/ spring.security.oauth2.client.provider.cftunnels.user-info-uri=https://auth.hithomelabs.com/application/o/userinfo/ spring.security.oauth2.client.provider.cftunnels.jwk-set-uri=https://auth.hithomelabs.com/application/o/cftunnels/jwks/ -spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ \ No newline at end of file +spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ + +spring.datasource.url=jdbc:postgresql://localhost:5432/cftunnel +spring.datasource.username=${POSTGRES_USERNAME} +spring.datasource.password=${POSTGRES_PASSWORD} +spring.datasource.driver-class-name=org.postgresql.Driver +spring.sql.init.mode=always + +spring.jpa.hibernate.ddl-auto=update +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql new file mode 100644 index 0000000..1fa876d --- /dev/null +++ b/src/main/resources/schema.sql @@ -0,0 +1,37 @@ +-- schema.sql + +-- Roles table +CREATE TABLE IF NOT EXISTS roles ( + role_id SERIAL PRIMARY KEY, + role_name VARCHAR(50) UNIQUE NOT NULL +); + +-- Users table +CREATE TABLE IF NOT EXISTS users ( + user_id SERIAL PRIMARY KEY, + user_name VARCHAR(100) NOT NULL, + password VARCHAR(255) NOT NULL +); + +-- User-Role Mapping table (many-to-many relationship) +CREATE TABLE IF NOT EXISTS user_role_mapping ( + mapping_id SERIAL PRIMARY KEY, + user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE, + role_id INTEGER NOT NULL REFERENCES roles(role_id) ON DELETE CASCADE +); + +-- Tunnels table +CREATE TABLE IF NOT EXISTS tunnels ( + tunnel_id SERIAL PRIMARY KEY, + tunnel_name VARCHAR(100) NOT NULL, + tunnel_type VARCHAR(50) NOT NULL +); + +-- Mapping Requests table +CREATE TABLE IF NOT EXISTS mapping_requests ( + request_id SERIAL PRIMARY KEY, + request_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + status VARCHAR(20) NOT NULL, + user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL, + tunnel_id INTEGER REFERENCES tunnels(tunnel_id) ON DELETE SET NULL +); From 4d63eb2e2cbe81c2da4f1eef0d9646e12529b3a9 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 22:55:05 +0530 Subject: [PATCH 077/102] bug fixes --- build.gradle | 1 - docker-compose.yaml | 9 +++------ src/main/resources/application-local.properties | 2 ++ src/main/resources/application.properties | 5 +++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 2c09e0d..4340fce 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,6 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'org.postgresql:postgresql' implementation 'org.hibernate.validator:hibernate-validator' diff --git a/docker-compose.yaml b/docker-compose.yaml index 772008b..f33b9fe 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,10 +15,10 @@ services: - POSTGRES_USER=${POSTGRES_USERNAME} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} env_file: - - .env + - stack.env restart: unless-stopped postgres: - image: postgres:15 + image: postgres:15-alpine container_name: cftunnel-db environment: POSTGRES_DB: cftunnel @@ -28,7 +28,4 @@ services: ports: - "5432:5432" volumes: - - pgdata:/var/lib/postgresql/data - -volumes: - pgdata: {} \ No newline at end of file + - ${DB_PATH}:/var/lib/postgresql/data \ No newline at end of file diff --git a/src/main/resources/application-local.properties b/src/main/resources/application-local.properties index 21709da..febde77 100644 --- a/src/main/resources/application-local.properties +++ b/src/main/resources/application-local.properties @@ -6,3 +6,5 @@ management.endpoint.health.show-details=always logging.level.org.hibernate.SQL=DEBUG debug=true + +spring.datasource.url=jdbc:postgresql://localhost:5432/cftunnel diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 16bd18b..28915d5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -24,7 +24,7 @@ spring.security.oauth2.client.provider.cftunnels.user-info-uri=https://auth.hith spring.security.oauth2.client.provider.cftunnels.jwk-set-uri=https://auth.hithomelabs.com/application/o/cftunnels/jwks/ spring.security.oauth2.client.provider.cftunnels.issuer-uri=https://auth.hithomelabs.com/application/o/cftunnels/ -spring.datasource.url=jdbc:postgresql://localhost:5432/cftunnel +spring.datasource.url=jdbc:postgresql://192.168.0.100:5432/cftunnel spring.datasource.username=${POSTGRES_USERNAME} spring.datasource.password=${POSTGRES_PASSWORD} spring.datasource.driver-class-name=org.postgresql.Driver @@ -32,5 +32,6 @@ spring.sql.init.mode=always spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true -spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect + +spring.jpa.open-in-view=false \ No newline at end of file From 18e3535a575da837e5d247f3d032ab46c6f86532 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 23:28:24 +0530 Subject: [PATCH 078/102] sql init set to never --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 28915d5..94b9238 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -28,7 +28,7 @@ spring.datasource.url=jdbc:postgresql://192.168.0.100:5432/cftunnel spring.datasource.username=${POSTGRES_USERNAME} spring.datasource.password=${POSTGRES_PASSWORD} spring.datasource.driver-class-name=org.postgresql.Driver -spring.sql.init.mode=always +spring.sql.init.mode=never spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true From f99ed01a54c24f39aaba3d958916a4dbf42fd0ed Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 23:38:40 +0530 Subject: [PATCH 079/102] dialect readded --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 94b9238..89201b8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -32,6 +32,6 @@ spring.sql.init.mode=never spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true - +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect spring.jpa.open-in-view=false \ No newline at end of file From 0d576eb9a7f6b557a88d72e8d3e728139d9bea25 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sun, 12 Oct 2025 23:58:14 +0530 Subject: [PATCH 080/102] db port variable added --- docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index f33b9fe..f8cb6ed 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -26,6 +26,6 @@ services: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} restart: unless-stopped ports: - - "5432:5432" + - "${DB_PORT}:5432" volumes: - ${DB_PATH}:/var/lib/postgresql/data \ No newline at end of file From 25ef5660fa6e21e220185a39a161dac59aaf67b5 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sat, 18 Oct 2025 17:30:25 +0530 Subject: [PATCH 081/102] Env name added in container name --- docker-compose.yaml | 2 +- postgres-docker-compose.yaml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 postgres-docker-compose.yaml diff --git a/docker-compose.yaml b/docker-compose.yaml index f8cb6ed..9eb1198 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -19,7 +19,7 @@ services: restart: unless-stopped postgres: image: postgres:15-alpine - container_name: cftunnel-db + container_name: cftunnel-db-${ENV} environment: POSTGRES_DB: cftunnel POSTGRES_USER: ${POSTGRES_USERNAME} diff --git a/postgres-docker-compose.yaml b/postgres-docker-compose.yaml new file mode 100644 index 0000000..b72cc0d --- /dev/null +++ b/postgres-docker-compose.yaml @@ -0,0 +1,16 @@ +services: + postgres: + image: postgres + container_name: cftunnel-db + restart: always + environment: + POSTGRES_DB: cftunnel + POSTGRES_USER: root + POSTGRES_PASSWORD: password + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data + +volumes: + pgdata: \ No newline at end of file From 6794e567481163bf04c9b87b281e2b9661031461 Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Sat, 18 Oct 2025 17:33:06 +0530 Subject: [PATCH 082/102] postgres docker compose file deleted --- postgres-docker-compose.yaml | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 postgres-docker-compose.yaml diff --git a/postgres-docker-compose.yaml b/postgres-docker-compose.yaml deleted file mode 100644 index b72cc0d..0000000 --- a/postgres-docker-compose.yaml +++ /dev/null @@ -1,16 +0,0 @@ -services: - postgres: - image: postgres - container_name: cftunnel-db - restart: always - environment: - POSTGRES_DB: cftunnel - POSTGRES_USER: root - POSTGRES_PASSWORD: password - ports: - - "5432:5432" - volumes: - - pgdata:/var/lib/postgresql/data - -volumes: - pgdata: \ No newline at end of file From 316dd6b01e3061b7d1223e9b25c0ccf7e49a2676 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 26 Oct 2025 18:37:41 +0530 Subject: [PATCH 083/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Decoupling the controller and the service layer --- .../Services/CloudflareAPIService.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java diff --git a/src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java b/src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java new file mode 100644 index 0000000..2e0d71c --- /dev/null +++ b/src/main/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIService.java @@ -0,0 +1,61 @@ +package com.hithomelabs.CFTunnels.Services; + +import com.hithomelabs.CFTunnels.Config.CloudflareConfig; +import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Models.Config; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.Map; + +@Service +public class CloudflareAPIService { + + @Autowired + CloudflareConfig cloudflareConfig; + + @Autowired + AuthKeyEmailHeader authKeyEmailHeader; + + @Autowired + RestTemplate restTemplate; + + public ResponseEntity getCloudflareTunnels() { + + // * * Resource URL to hit get request at + String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel"; + + HttpEntity httpEntity = new HttpEntity<>("", authKeyEmailHeader.getHttpHeaders()); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class); + return responseEntity; + } + + public ResponseEntity getCloudflareTunnelConfigurations(String tunnelId, RestTemplate restTemplate, Class responseType) { + + // * * Resource URL to hit get request at + String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel/" + tunnelId + "/configurations"; + + HttpEntity httpEntity = new HttpEntity<>("",authKeyEmailHeader.getHttpHeaders()); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, responseType); + return responseEntity; + } + + public ResponseEntity putCloudflareTunnelConfigurations(String tunnelId, RestTemplate restTemplate, Class responseType, Config config) { + + // * * Resource URL to hit get request at + String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel/" + tunnelId + "/configurations"; + + HttpHeaders httpHeaders = authKeyEmailHeader.getHttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + HttpEntity entity = new HttpEntity<>(config, httpHeaders); + ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.PUT, entity, responseType); + return responseEntity; + } + + + + + +} From 68792e2cbf1a0dfedf164c77fa72b4bbf59b6a56 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 26 Oct 2025 18:49:18 +0530 Subject: [PATCH 084/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Adding mockMvc tests for web tier --- .gitignore | 2 + build.gradle | 3 + .../Controllers/TunnelController.java | 42 +-- .../CFTunnels/Models/TunnelResponse.java | 50 +--- .../Controllers/TunnelControllerTest.java | 271 ++++++++++++++++++ .../Services/CloudflareAPIServiceTest.java | 55 ++++ src/test/resources/docker-compose.yaml | 13 + 7 files changed, 364 insertions(+), 72 deletions(-) create mode 100644 src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java create mode 100644 src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java create mode 100644 src/test/resources/docker-compose.yaml diff --git a/.gitignore b/.gitignore index c2065bc..c47508c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ HELP.md .gradle +.run build/ +.env* !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ !**/src/test/**/build/ diff --git a/build.gradle b/build.gradle index 4340fce..4328386 100644 --- a/build.gradle +++ b/build.gradle @@ -24,8 +24,11 @@ repositories { dependencies { implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.8.5' implementation group: 'org.springframework.boot', name:'spring-boot-starter-oauth2-client', version: '3.5.5' + compileOnly 'org.projectlombok:lombok:1.18.30' + annotationProcessor 'org.projectlombok:lombok:1.18.30' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'org.postgresql:postgresql' diff --git a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java index 902cb55..3362a83 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Controllers/TunnelController.java @@ -8,6 +8,7 @@ import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; import com.hithomelabs.CFTunnels.Models.Config; import com.hithomelabs.CFTunnels.Models.Ingress; import com.hithomelabs.CFTunnels.Models.TunnelResponse; +import com.hithomelabs.CFTunnels.Services.CloudflareAPIService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.http.*; @@ -40,6 +41,9 @@ public class TunnelController implements ErrorController { @Autowired private RestTemplateConfig restTemplateConfig; + @Autowired + CloudflareAPIService cloudflareAPIService; + @PreAuthorize("hasAnyRole('USER')") @GetMapping("/whoami") public Map whoAmI(@AuthenticationPrincipal OidcUser oidcUser) { @@ -57,12 +61,7 @@ public class TunnelController implements ErrorController { @GetMapping("/tunnels") public ResponseEntity> getTunnels(){ - // * * Resource URL to hit get request at - String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel"; - - HttpEntity httpEntity = new HttpEntity<>("",authKeyEmailHeader.getHttpHeaders()); - ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class); - + ResponseEntity responseEntity = cloudflareAPIService.getCloudflareTunnels(); Map jsonResponse = new HashMap<>(); jsonResponse.put("status", "success"); jsonResponse.put("data", responseEntity.getBody()); @@ -72,14 +71,9 @@ public class TunnelController implements ErrorController { @PreAuthorize("hasAnyRole('DEVELOPER')") @GetMapping("/tunnel/{tunnelId}") - public ResponseEntity> getTunnelConfigurations(@PathVariable String tunnelId) throws JsonProcessingException { - - // * * Resource URL to hit get request at - String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel/" + tunnelId + "/configurations"; - - HttpEntity httpEntity = new HttpEntity<>("",authKeyEmailHeader.getHttpHeaders()); - ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class); + public ResponseEntity> getTunnelConfigurations(@PathVariable String tunnelId) { + ResponseEntity responseEntity = cloudflareAPIService.getCloudflareTunnelConfigurations(tunnelId, restTemplate, Map.class); Map jsonResponse = new HashMap<>(); jsonResponse.put("status", "success"); jsonResponse.put("data", responseEntity.getBody()); @@ -92,12 +86,7 @@ public class TunnelController implements ErrorController { @PutMapping("/tunnel/{tunnelId}/add") public ResponseEntity> addTunnelconfiguration(@PathVariable String tunnelId, @RequestBody Ingress ingress) throws JsonProcessingException { - String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel/" + tunnelId + "/configurations"; - - // * * Getting existing public hostname mappings - HttpHeaders httpHeaders = authKeyEmailHeader.getHttpHeaders(); - HttpEntity httpEntity = new HttpEntity<>("",httpHeaders); - ResponseEntity responseEntity = restTemplateConfig.restTemplate().exchange(url, HttpMethod.GET, httpEntity, TunnelResponse.class); + ResponseEntity responseEntity = cloudflareAPIService.getCloudflareTunnelConfigurations(tunnelId, restTemplateConfig.restTemplate(), TunnelResponse.class); // * * Inserting new ingress value at second-to last position in list Config config = responseEntity.getBody().getResult().getConfig(); @@ -105,9 +94,7 @@ public class TunnelController implements ErrorController { response_ingress.add(response_ingress.size()-1, ingress); // * * Hitting put endpoint - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - HttpEntity entity = new HttpEntity<>(config, httpHeaders); - ResponseEntity response = restTemplateConfig.restTemplate().exchange(url, HttpMethod.PUT, entity, Map.class); + ResponseEntity response = cloudflareAPIService.putCloudflareTunnelConfigurations(tunnelId, restTemplateConfig.restTemplate(), TunnelResponse.class, config); // * * Displaying response Map jsonResponse = new HashMap<>(); @@ -121,12 +108,7 @@ public class TunnelController implements ErrorController { @PutMapping("/tunnel/{tunnelId}/delete") public ResponseEntity> deleteTunnelConfiguration(@PathVariable String tunnelId, @RequestBody Ingress ingress) throws JsonProcessingException { - String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel/" + tunnelId + "/configurations"; - - // * * Getting existing public hostname mappings - HttpHeaders httpHeaders = authKeyEmailHeader.getHttpHeaders(); - HttpEntity httpEntity = new HttpEntity<>("",httpHeaders); - ResponseEntity responseEntity = restTemplateConfig.restTemplate().exchange(url, HttpMethod.GET, httpEntity, TunnelResponse.class); + ResponseEntity responseEntity = cloudflareAPIService.getCloudflareTunnelConfigurations(tunnelId, restTemplateConfig.restTemplate(), TunnelResponse.class); // * * Deleting the selected ingress value Config config = responseEntity.getBody().getResult().getConfig(); @@ -134,9 +116,7 @@ public class TunnelController implements ErrorController { Boolean result = Ingress.deleteByHostName(response_ingress, ingress.getHostname()); // * * Hitting put endpoint - httpHeaders.setContentType(MediaType.APPLICATION_JSON); - HttpEntity entity = new HttpEntity<>(config, httpHeaders); - ResponseEntity response = restTemplateConfig.restTemplate().exchange(url, HttpMethod.PUT, entity, Map.class); + ResponseEntity response = cloudflareAPIService.putCloudflareTunnelConfigurations(tunnelId, restTemplateConfig.restTemplate(), TunnelResponse.class, config); // * * Displaying response Map jsonResponse = new HashMap<>(); diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/TunnelResponse.java b/src/main/java/com/hithomelabs/CFTunnels/Models/TunnelResponse.java index e51a3d5..f5a4fb4 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Models/TunnelResponse.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Models/TunnelResponse.java @@ -1,8 +1,17 @@ package com.hithomelabs.CFTunnels.Models; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + import java.util.List; import java.util.Map; +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor public class TunnelResponse { private List> errors; @@ -12,45 +21,4 @@ public class TunnelResponse { private Boolean success; private Result result; - - public Result getResult() { - return result; - } - - public void setResult(Result result) { - this.result = result; - } - - public List> getErrors() { - return errors; - } - - public void setErrors(List> errors) { - this.errors = errors; - } - - public List> getMessages() { - return messages; - } - - public void setMessages(List> messages) { - this.messages = messages; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public Boolean getSuccess() { - return success; - } - - public void setSuccess(Boolean success) { - this.success = success; - } - } diff --git a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java new file mode 100644 index 0000000..ac85244 --- /dev/null +++ b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java @@ -0,0 +1,271 @@ +package com.hithomelabs.CFTunnels.Controllers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hithomelabs.CFTunnels.Config.AuthoritiesToGroupMapping; +import com.hithomelabs.CFTunnels.Config.CloudflareConfig; +import com.hithomelabs.CFTunnels.Config.RestTemplateConfig; +import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Models.Authorities; +import com.hithomelabs.CFTunnels.Models.Config; +import com.hithomelabs.CFTunnels.Models.Groups; +import com.hithomelabs.CFTunnels.Models.TunnelResponse; +import com.hithomelabs.CFTunnels.Services.CloudflareAPIService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.http.*; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.core.oidc.OidcIdToken; +import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; +import org.springframework.test.context.bean.override.mockito.MockitoBean; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.web.client.RestTemplate; + +import java.time.Instant; +import java.util.*; + +import static org.hamcrest.core.IsIterableContaining.hasItem; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Login; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; +import static org.hamcrest.Matchers.not; + + +@WebMvcTest(TunnelController.class) +class TunnelControllerTest { + + @Autowired + MockMvc mockMvc; + + @MockitoBean + AuthoritiesToGroupMapping authoritiesToGroupMapping; + + @MockitoBean + CloudflareConfig cloudflareConfig; + + @MockitoBean + AuthKeyEmailHeader authKeyEmailHeader; + + @MockitoBean + RestTemplate restTemplate; + + @MockitoBean + CloudflareAPIService cloudflareAPIService; + + @MockitoBean + RestTemplateConfig restTemplateConfig; + + private static String withAdditionalIngress = """ + { + "success": true, + "errors": [], + "messages": [], + "result": { + "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", + "version": 63, + "config": { + "ingress": [ + { + "service": "http://192.168.0.100:8928", + "hostname": "giteabkp.hithomelabs.com", + "originRequest": {} + }, + { + "service": "https://192.168.0.100:9442", + "hostname": "devdocker.hithomelabs.com", + "originRequest": { + "noTLSVerify": true + } + }, + { + "service": "http://192.168.0.100:3457", + "hostname": "random.hithomelabs.com", + "originRequest": {} + }, + { + "service": "http_status:404" + } + ], + "warp-routing": { + "enabled": false + } + }, + "source": "cloudflare", + "created_at": "2025-10-24T18:17:26.914217Z" + } + } + """; + + private static final String withoutAdditionalIngress = """ + { + "success": true, + "errors": [], + "messages": [], + "result": { + "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", + "version": 63, + "config": { + "ingress": [ + { + "service": "http://192.168.0.100:8928", + "hostname": "giteabkp.hithomelabs.com", + "originRequest": {} + }, + { + "service": "https://192.168.0.100:9442", + "hostname": "devdocker.hithomelabs.com", + "originRequest": { + "noTLSVerify": true + } + }, + { + "service": "http_status:404" + } + ], + "warp-routing": { + "enabled": false + } + }, + "source": "cloudflare", + "created_at": "2025-10-24T18:17:26.914217Z" + } + } + """; + + private static final String ingressJson = """ + { + "service": "http://192.168.0.100:3457", + "hostname": "random.hithomelabs.com", + "originRequest": {} + } + """; + + private DefaultOidcUser buildOidcUser(String username, String role) { + + when(authoritiesToGroupMapping.getAuthorityForGroup()).thenReturn(Map.of(Groups.GITEA_USER, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_USER))), + Groups.POWER_USER, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_USER))), + Groups.HOMELAB_DEVELOPER, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_DEVELOPER))), + Groups.SYSTEM_ADMIN, new HashSet<>(Set.of(new SimpleGrantedAuthority(Authorities.ROLE_APPROVER), new SimpleGrantedAuthority(Authorities.ROLE_ADMIN))))); + + Map> roleAuthorityMapping = authoritiesToGroupMapping.getAuthorityForGroup(); + List authorities = roleAuthorityMapping.get(role).stream().toList(); + + OidcIdToken idToken = new OidcIdToken( + "mock-token", + Instant.now(), + Instant.now().plusSeconds(3600), + Map.of("preferred_username", username, "sub", username) + ); + + return new DefaultOidcUser(authorities, idToken, "preferred_username"); + } + + @Test + @DisplayName("should return appropriate user roles when use belongs to group GITEA_USER") + public void testWhoAmI_user() throws Exception { + mockMvc.perform(get("/cloudflare/whoami") + .with(oauth2Login().oauth2User(buildOidcUser("username", Groups.GITEA_USER)))) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.username").value("username")) + .andExpect(jsonPath("$.roles", hasItem("ROLE_USER"))); + } + + @Test + @DisplayName("should hit tunnels endpoint successfully with ROLE_USER") + public void testGetTunnelsForRoleUser() throws Exception { + + when(cloudflareConfig.getAccountId()).thenReturn("abc123"); + HttpHeaders headers = new HttpHeaders(); + headers.set("X-Auth-Email", "me@example.com"); + when(authKeyEmailHeader.getHttpHeaders()).thenReturn(headers); + + Map tunnelData = Map.of("tunnels", List.of(Map.of("id", "50df9101-f625-4618-b7c5-100338a57124"))); + ResponseEntity mockResponse = new ResponseEntity<>(tunnelData, HttpStatus.OK); + + when(cloudflareAPIService.getCloudflareTunnels()).thenReturn(mockResponse); + + mockMvc.perform(get("/cloudflare/tunnels") + .with(oauth2Login().oauth2User(buildOidcUser("username", Groups.GITEA_USER)))) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.data.tunnels[0].id").value("50df9101-f625-4618-b7c5-100338a57124")); + + } + + @Test + void getTunnelConfigurations() throws Exception { + + Map tunnelData = Map.of("config", Map.of("result", "success", "ingress", "sample ingress object")); + ResponseEntity mockResponse = new ResponseEntity<>(tunnelData, HttpStatus.OK); + + when(cloudflareAPIService.getCloudflareTunnelConfigurations(eq("sampleTunnelId"), any(RestTemplate.class), eq(Map.class))).thenReturn(mockResponse); + + mockMvc.perform(get("/cloudflare/tunnel/{tunnelId}", "sampleTunnelId") + .with(oauth2Login().oauth2User(buildOidcUser("username", Groups.HOMELAB_DEVELOPER)))) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.data.config.ingress").value("sample ingress object")); + } + + @Test + void addTunnelconfiguration() throws Exception { + + when(restTemplateConfig.restTemplate()).thenReturn(new RestTemplate()); + + ObjectMapper mapper = new ObjectMapper(); + TunnelResponse tunnelStateBefore = mapper.readValue(withoutAdditionalIngress, TunnelResponse.class); + ResponseEntity tunnelResponseBefore = new ResponseEntity<>(tunnelStateBefore, HttpStatus.OK); + + when(cloudflareAPIService.getCloudflareTunnelConfigurations(eq("sampleTunnelId"), any(RestTemplate.class), eq(TunnelResponse.class))).thenReturn(tunnelResponseBefore); + + TunnelResponse expectedTunnelConfig = mapper.readValue(withAdditionalIngress, TunnelResponse.class); + ResponseEntity expectedHttpTunnelResponse = new ResponseEntity<>(expectedTunnelConfig, HttpStatus.OK); + when(cloudflareAPIService.putCloudflareTunnelConfigurations(eq("sampleTunnelId"), any(RestTemplate.class), eq(TunnelResponse.class), any(Config.class))).thenReturn(expectedHttpTunnelResponse); + + mockMvc.perform(put("/cloudflare/tunnel/{tunnelId}/add", "sampleTunnelId") + .with(oauth2Login().oauth2User(buildOidcUser("admin", Groups.SYSTEM_ADMIN))) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(ingressJson)) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.data.result.config.ingress[*].hostname", hasItem("random.hithomelabs.com"))); + } + + @Test + void deleteTunnelConfiguration() throws Exception { + + when(restTemplateConfig.restTemplate()).thenReturn(new RestTemplate()); + + ObjectMapper mapper = new ObjectMapper(); + TunnelResponse tunnelStateBefore = mapper.readValue(withAdditionalIngress, TunnelResponse.class); + ResponseEntity tunnelResponseBefore = new ResponseEntity<>(tunnelStateBefore, HttpStatus.OK); + + when(cloudflareAPIService.getCloudflareTunnelConfigurations(eq("sampleTunnelId"), any(RestTemplate.class), eq(TunnelResponse.class))).thenReturn(tunnelResponseBefore); + + TunnelResponse expectedTunnelConfig = mapper.readValue(withoutAdditionalIngress, TunnelResponse.class); + ResponseEntity expectedHttpTunnelResponse = new ResponseEntity<>(expectedTunnelConfig, HttpStatus.OK); + when(cloudflareAPIService.putCloudflareTunnelConfigurations(eq("sampleTunnelId"), any(RestTemplate.class), eq(TunnelResponse.class), any(Config.class))).thenReturn(expectedHttpTunnelResponse); + + mockMvc.perform(put("/cloudflare/tunnel/{tunnelId}/delete", "sampleTunnelId") + .with(oauth2Login().oauth2User(buildOidcUser("admin", Groups.SYSTEM_ADMIN))) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(ingressJson)) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.data.result.config.ingress[*].hostname", not(hasItem("random.hithomelabs.com")))); + } + + +} diff --git a/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java b/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java new file mode 100644 index 0000000..dbafc60 --- /dev/null +++ b/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java @@ -0,0 +1,55 @@ +package com.hithomelabs.CFTunnels.Services; + +import com.hithomelabs.CFTunnels.Config.CloudflareConfig; +import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.*; +import org.springframework.web.client.RestTemplate; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class CloudflareAPIServiceTest { + + @InjectMocks + private CloudflareAPIService cloudflareAPIService; + + @Mock + AuthKeyEmailHeader authKeyEmailHeader; + + @Mock + private RestTemplate restTemplate; + + @Mock + CloudflareConfig cloudflareConfig; + + @Test + void testGetCloudflareTunnels() { + + when(cloudflareConfig.getAccountId()).thenReturn("account-123"); + when(authKeyEmailHeader.getHttpHeaders()).thenReturn(new HttpHeaders()); + Map mockBody = Map.of("tunnels", List.of(Map.of("id", "t1"))); + ResponseEntity mockResponse = new ResponseEntity<>(mockBody, HttpStatus.OK); + + when(restTemplate.exchange( + any(String.class), + eq(HttpMethod.GET), + any(HttpEntity.class), + eq(Map.class) + )).thenReturn(mockResponse); + + ResponseEntity response = cloudflareAPIService.getCloudflareTunnels(); + assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + + } \ No newline at end of file diff --git a/src/test/resources/docker-compose.yaml b/src/test/resources/docker-compose.yaml new file mode 100644 index 0000000..27068c8 --- /dev/null +++ b/src/test/resources/docker-compose.yaml @@ -0,0 +1,13 @@ +services: + postgres: + image: postgres:15-alpine + container_name: cftunnel-db-${ENV} + environment: + POSTGRES_DB: cftunnel + POSTGRES_USER: ${POSTGRES_USERNAME} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + restart: unless-stopped + ports: + - "${DB_PORT}:5432" + volumes: + - ${DB_PATH}:/var/lib/postgresql/data \ No newline at end of file From 4075eb78c8e2d20b6a24029249284cf02d1368b3 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 26 Oct 2025 20:30:01 +0530 Subject: [PATCH 085/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Adding unit tests for service layer --- .../Controllers/TunnelControllerTest.java | 98 +++++-------------- .../Services/CloudflareAPIServiceTest.java | 64 +++++++++++- .../hithomelabs/CFTunnels/TestUtils/Util.java | 17 ++++ .../data/tunnelResponseLargeIngress.json | 38 +++++++ .../data/tunnelResponseSmallIngress.json | 33 +++++++ 5 files changed, 174 insertions(+), 76 deletions(-) create mode 100644 src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java create mode 100644 src/test/resources/data/tunnelResponseLargeIngress.json create mode 100644 src/test/resources/data/tunnelResponseSmallIngress.json diff --git a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java index ac85244..644288e 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Controllers/TunnelControllerTest.java @@ -24,9 +24,11 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.web.client.RestTemplate; +import java.io.IOException; import java.time.Instant; import java.util.*; +import static com.hithomelabs.CFTunnels.TestUtils.Util.getClassPathDataResource; import static org.hamcrest.core.IsIterableContaining.hasItem; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -64,82 +66,28 @@ class TunnelControllerTest { @MockitoBean RestTemplateConfig restTemplateConfig; - private static String withAdditionalIngress = """ - { - "success": true, - "errors": [], - "messages": [], - "result": { - "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", - "version": 63, - "config": { - "ingress": [ - { - "service": "http://192.168.0.100:8928", - "hostname": "giteabkp.hithomelabs.com", - "originRequest": {} - }, - { - "service": "https://192.168.0.100:9442", - "hostname": "devdocker.hithomelabs.com", - "originRequest": { - "noTLSVerify": true - } - }, - { - "service": "http://192.168.0.100:3457", - "hostname": "random.hithomelabs.com", - "originRequest": {} - }, - { - "service": "http_status:404" - } - ], - "warp-routing": { - "enabled": false - } - }, - "source": "cloudflare", - "created_at": "2025-10-24T18:17:26.914217Z" - } - } - """; + private static final String tunnelResponseSmallIngressFile = "tunnelResponseSmallIngress.json"; - private static final String withoutAdditionalIngress = """ - { - "success": true, - "errors": [], - "messages": [], - "result": { - "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", - "version": 63, - "config": { - "ingress": [ - { - "service": "http://192.168.0.100:8928", - "hostname": "giteabkp.hithomelabs.com", - "originRequest": {} - }, - { - "service": "https://192.168.0.100:9442", - "hostname": "devdocker.hithomelabs.com", - "originRequest": { - "noTLSVerify": true - } - }, - { - "service": "http_status:404" - } - ], - "warp-routing": { - "enabled": false - } - }, - "source": "cloudflare", - "created_at": "2025-10-24T18:17:26.914217Z" - } - } - """; + private static final String tunnelResponseLargeIngressFile = "tunnelResponseLargeIngress.json"; + + private static final String withAdditionalIngress; + + static { + try { + withAdditionalIngress = getClassPathDataResource(tunnelResponseLargeIngressFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static final String withoutAdditionalIngress; + static { + try { + withoutAdditionalIngress = getClassPathDataResource(tunnelResponseSmallIngressFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } private static final String ingressJson = """ { diff --git a/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java b/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java index dbafc60..03374e5 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Services/CloudflareAPIServiceTest.java @@ -1,7 +1,11 @@ package com.hithomelabs.CFTunnels.Services; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Models.Config; +import com.hithomelabs.CFTunnels.Models.TunnelResponse; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; @@ -9,9 +13,12 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; + +import java.io.IOException; import java.util.List; import java.util.Map; +import static com.hithomelabs.CFTunnels.TestUtils.Util.getClassPathDataResource; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -32,6 +39,18 @@ class CloudflareAPIServiceTest { @Mock CloudflareConfig cloudflareConfig; + private static final String tunnelResponseLargeIngressFile = "tunnelResponseLargeIngress.json"; + + private static final String bigTunnelResponse; + + static { + try { + bigTunnelResponse = getClassPathDataResource(tunnelResponseLargeIngressFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Test void testGetCloudflareTunnels() { @@ -52,4 +71,47 @@ class CloudflareAPIServiceTest { } - } \ No newline at end of file + @Test + void getCloudflareTunnelConfigurations() throws JsonProcessingException { + + when(cloudflareConfig.getAccountId()).thenReturn("account-123"); + when(authKeyEmailHeader.getHttpHeaders()).thenReturn(new HttpHeaders()); + + TunnelResponse tunnelResponse = new ObjectMapper().readValue(bigTunnelResponse, TunnelResponse.class); + ResponseEntity tunnelResponseResponseEntity = new ResponseEntity<>(tunnelResponse, HttpStatus.OK); + + when(restTemplate.exchange( + any(String.class), + eq(HttpMethod.GET), + any(HttpEntity.class), + eq(TunnelResponse.class) + )).thenReturn(tunnelResponseResponseEntity); + + ResponseEntity response = cloudflareAPIService.getCloudflareTunnelConfigurations("sampleTunnelID", restTemplate, TunnelResponse.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(response.getBody().getResult().getConfig().getIngress().get(0).getHostname(), "giteabkp.hithomelabs.com"); + } + + @Test + void putCloudflareTunnelConfigurations() throws JsonProcessingException { + + when(cloudflareConfig.getAccountId()).thenReturn("account-123"); + when(authKeyEmailHeader.getHttpHeaders()).thenReturn(new HttpHeaders()); + + TunnelResponse tunnelResponse = new ObjectMapper().readValue(bigTunnelResponse, TunnelResponse.class); + ResponseEntity tunnelResponseResponseEntity = new ResponseEntity<>(tunnelResponse, HttpStatus.OK); + + Config config = tunnelResponse.getResult().getConfig(); + + when(restTemplate.exchange( + any(String.class), + eq(HttpMethod.PUT), + any(HttpEntity.class), + eq(TunnelResponse.class) + )).thenReturn(tunnelResponseResponseEntity); + + ResponseEntity response = cloudflareAPIService.putCloudflareTunnelConfigurations("sampleTunnelID", restTemplate, TunnelResponse.class, config); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertEquals(response.getBody().getResult().getConfig().getIngress().get(2).getHostname(), "random.hithomelabs.com"); + } +} \ No newline at end of file diff --git a/src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java b/src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java new file mode 100644 index 0000000..a5f8c36 --- /dev/null +++ b/src/test/java/com/hithomelabs/CFTunnels/TestUtils/Util.java @@ -0,0 +1,17 @@ +package com.hithomelabs.CFTunnels.TestUtils; + +import org.springframework.core.io.ClassPathResource; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +public class Util { + + public static String getClassPathDataResource(String filename) throws IOException { + return Files.readString( + new ClassPathResource(String.format("data/%s", filename)).getFile().toPath(), + StandardCharsets.UTF_8); + } + +} diff --git a/src/test/resources/data/tunnelResponseLargeIngress.json b/src/test/resources/data/tunnelResponseLargeIngress.json new file mode 100644 index 0000000..e24b930 --- /dev/null +++ b/src/test/resources/data/tunnelResponseLargeIngress.json @@ -0,0 +1,38 @@ +{ + "success": true, + "errors": [], + "messages": [], + "result": { + "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", + "version": 63, + "config": { + "ingress": [ + { + "service": "http://192.168.0.100:8928", + "hostname": "giteabkp.hithomelabs.com", + "originRequest": {} + }, + { + "service": "https://192.168.0.100:9442", + "hostname": "devdocker.hithomelabs.com", + "originRequest": { + "noTLSVerify": true + } + }, + { + "service": "http://192.168.0.100:3457", + "hostname": "random.hithomelabs.com", + "originRequest": {} + }, + { + "service": "http_status:404" + } + ], + "warp-routing": { + "enabled": false + } + }, + "source": "cloudflare", + "created_at": "2025-10-24T18:17:26.914217Z" + } +} \ No newline at end of file diff --git a/src/test/resources/data/tunnelResponseSmallIngress.json b/src/test/resources/data/tunnelResponseSmallIngress.json new file mode 100644 index 0000000..9e840f0 --- /dev/null +++ b/src/test/resources/data/tunnelResponseSmallIngress.json @@ -0,0 +1,33 @@ +{ + "success": true, + "errors": [], + "messages": [], + "result": { + "tunnel_id": "50df9101-f625-4618-b7c5-100338a57124", + "version": 63, + "config": { + "ingress": [ + { + "service": "http://192.168.0.100:8928", + "hostname": "giteabkp.hithomelabs.com", + "originRequest": {} + }, + { + "service": "https://192.168.0.100:9442", + "hostname": "devdocker.hithomelabs.com", + "originRequest": { + "noTLSVerify": true + } + }, + { + "service": "http_status:404" + } + ], + "warp-routing": { + "enabled": false + } + }, + "source": "cloudflare", + "created_at": "2025-10-24T18:17:26.914217Z" + } +} \ No newline at end of file From 665361a4e38d2bb6f6e84384878a94fed0c10ccb Mon Sep 17 00:00:00 2001 From: Shikhar Pandya Date: Tue, 28 Oct 2025 00:05:47 +0530 Subject: [PATCH 086/102] [Added a script for auto syncing forks of parent repository] Beta #1 --- .gitea/workflows/test_image_build_push.yml | 71 +++++++++++++++++++--- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index f53e140..edda211 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -1,8 +1,10 @@ name: sample gradle build and test -run-name: Build started by $ {{gitea.actor}} +run-name: Build started by ${{ gitea.actor }} + on: push: branches: [test] + jobs: tag: runs-on: ubuntu-latest @@ -13,17 +15,20 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Get new version id: new_version run: | VERSION=$(git describe --tags --abbrev=0) - echo ${VERSION} + echo "Current version: ${VERSION}" MAJOR=$(echo ${VERSION} | cut -d "." -f 1) MINOR=$(echo ${VERSION} | cut -d "." -f 2) PATCH=$(echo ${VERSION} | cut -d "." -f 3) - NEW_PATCH=$(( ${PATCH} + 1)) - echo ${NEW_PATCH} - echo "new_version=$(echo "${MAJOR}.${MINOR}.${NEW_PATCH}")" >> $GITHUB_OUTPUT + NEW_PATCH=$((PATCH + 1)) + NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}" + echo "New version: ${NEW_VERSION}" + echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT + build_tag_push: runs-on: ubuntu-latest needs: tag @@ -34,31 +39,79 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 + - name: JDK setup uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: '17' + - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 + - name: Create and push tag run: | - echo "NEW_VERSION=${{ needs.tag.outputs.new_version }}" - git config --global user.name "${{gitea.actor}}" + echo "New version: ${{ needs.tag.outputs.new_version }}" + git config --global user.name "${{ gitea.actor }}" git config --global user.email "${{ gitea.actor }}@users.noreply.github.com" - git tag -a ${{ needs.tag.outputs.new_version }} -m "Pushing new version ${{ needs.tag.outputs.new_version }}" - git push origin ${{ needs.tag.outputs.new_version }} + git tag -a "${{ needs.tag.outputs.new_version }}" -m "Pushing new version ${{ needs.tag.outputs.new_version }}" + git push origin "${{ needs.tag.outputs.new_version }}" + - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: registry: 'http://192.168.0.100:8928' username: hitanshu password: ${{ secrets.TOKEN }} + - name: Gradle build run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} + - name: Tag image as test run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} 192.168.0.100:8928/hithomelabs/cftunnels:test + - name: Push to Gitea Registry run: | docker push 192.168.0.100:8928/hithomelabs/cftunnels:test docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} + + sync_forks: + name: Sync All Forks + runs-on: ubuntu-latest + needs: build_tag_push + steps: + - name: Check out repository code + uses: actions/checkout@v4 + + - name: Sync all forks via Gitea API + env: + TOKEN: ${{ secrets.TOKEN }} + BASE_URL: "https://gitea.hithomelabs.com/api/v1" + OWNER: "Hithomelabs" + REPO: "CFTunnels" + run: | + set -e + set -o pipefail + + echo "Fetching forks for $OWNER/$REPO..." + response=$(curl -s -X GET "$BASE_URL/repos/$OWNER/$REPO/forks" -H "Authorization: token $TOKEN") + + # Extract clone URLs of forked repos (excluding the parent repo) + filtered=$(echo "$response" | grep -o '"clone_url":"[^"]*"' | sed 's/"clone_url":"\([^"]*\)"/\1/' | grep -v "/$OWNER") + + echo "Detected forks:" + echo "$filtered" + + readarray -t forks <<< "$filtered" + + for fork_url in "${forks[@]}"; do + echo "🔄 Syncing fork: $fork_url" + git remote add fork "$fork_url" 2>/dev/null || git remote set-url fork "$fork_url" + if git push fork main --force >/dev/null 2>&1; then + echo "✅ Synced $fork_url successfully" + else + echo "❌ Failed to sync $fork_url" + fi + echo + done + From ef7b6545db6de6147135ccfa69fa0db066a598b6 Mon Sep 17 00:00:00 2001 From: Shikhar Pandya Date: Tue, 28 Oct 2025 00:46:32 +0530 Subject: [PATCH 087/102] [Added a script for auto syncing forks of parent repository] Beta #2 --- .gitea/workflows/test_image_build_push.yml | 27 ++++------------------ 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index edda211..546f0d5 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -84,34 +84,15 @@ jobs: uses: actions/checkout@v4 - name: Sync all forks via Gitea API - env: - TOKEN: ${{ secrets.TOKEN }} - BASE_URL: "https://gitea.hithomelabs.com/api/v1" - OWNER: "Hithomelabs" - REPO: "CFTunnels" run: | - set -e - set -o pipefail - - echo "Fetching forks for $OWNER/$REPO..." - response=$(curl -s -X GET "$BASE_URL/repos/$OWNER/$REPO/forks" -H "Authorization: token $TOKEN") - - # Extract clone URLs of forked repos (excluding the parent repo) - filtered=$(echo "$response" | grep -o '"clone_url":"[^"]*"' | sed 's/"clone_url":"\([^"]*\)"/\1/' | grep -v "/$OWNER") - + echo "Fetching forks for Hithomelabs/CFTunnels..." + response=$(curl -s -X GET "https://gitea.hithomelabs.com/api/v1/repos/Hithomelabs/CFTunnels/forks" -H "Authorization: token ${{secrets.TOKEN}}") + filtered=$(echo "$response" | grep -o '"clone_url":"[^"]*"' | sed 's/"clone_url":"\([^"]*\)"/\1/' | grep -v "/Hithomelabs") echo "Detected forks:" echo "$filtered" - readarray -t forks <<< "$filtered" - for fork_url in "${forks[@]}"; do echo "🔄 Syncing fork: $fork_url" - git remote add fork "$fork_url" 2>/dev/null || git remote set-url fork "$fork_url" - if git push fork main --force >/dev/null 2>&1; then - echo "✅ Synced $fork_url successfully" - else - echo "❌ Failed to sync $fork_url" - fi - echo + git push "$fork_url" test & done From 46e8f614a0f192ddc3bd0dea142c0db78b710a90 Mon Sep 17 00:00:00 2001 From: Shikhar Pandya Date: Tue, 28 Oct 2025 01:12:58 +0530 Subject: [PATCH 088/102] [Added a script for auto syncing forks of parent repository] Beta #3 --- .gitea/workflows/test_image_build_push.yml | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/.gitea/workflows/test_image_build_push.yml b/.gitea/workflows/test_image_build_push.yml index 546f0d5..a4ed4ea 100644 --- a/.gitea/workflows/test_image_build_push.yml +++ b/.gitea/workflows/test_image_build_push.yml @@ -1,10 +1,8 @@ name: sample gradle build and test run-name: Build started by ${{ gitea.actor }} - on: push: branches: [test] - jobs: tag: runs-on: ubuntu-latest @@ -28,7 +26,6 @@ jobs: NEW_VERSION="${MAJOR}.${MINOR}.${NEW_PATCH}" echo "New version: ${NEW_VERSION}" echo "new_version=${NEW_VERSION}" >> $GITHUB_OUTPUT - build_tag_push: runs-on: ubuntu-latest needs: tag @@ -39,16 +36,13 @@ jobs: uses: actions/checkout@v4 with: fetch-depth: 0 - - name: JDK setup uses: actions/setup-java@v4 with: distribution: 'zulu' java-version: '17' - - name: Validate Gradle Wrapper uses: gradle/actions/wrapper-validation@v3 - - name: Create and push tag run: | echo "New version: ${{ needs.tag.outputs.new_version }}" @@ -56,25 +50,20 @@ jobs: git config --global user.email "${{ gitea.actor }}@users.noreply.github.com" git tag -a "${{ needs.tag.outputs.new_version }}" -m "Pushing new version ${{ needs.tag.outputs.new_version }}" git push origin "${{ needs.tag.outputs.new_version }}" - - name: Log in to Gitea Docker Registry uses: docker/login-action@v3 with: registry: 'http://192.168.0.100:8928' username: hitanshu password: ${{ secrets.TOKEN }} - - name: Gradle build run: ./gradlew bootBuildImage --imageName=192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} - - name: Tag image as test run: docker tag 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} 192.168.0.100:8928/hithomelabs/cftunnels:test - - name: Push to Gitea Registry run: | docker push 192.168.0.100:8928/hithomelabs/cftunnels:test docker push 192.168.0.100:8928/hithomelabs/cftunnels:${{ needs.tag.outputs.new_version }} - sync_forks: name: Sync All Forks runs-on: ubuntu-latest @@ -82,7 +71,6 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v4 - - name: Sync all forks via Gitea API run: | echo "Fetching forks for Hithomelabs/CFTunnels..." @@ -93,6 +81,6 @@ jobs: readarray -t forks <<< "$filtered" for fork_url in "${forks[@]}"; do echo "🔄 Syncing fork: $fork_url" - git push "$fork_url" test & + authed_url=$(echo "$fork_url" | sed "s#https://#https://${{secrets.TOKEN}}@#") + git push "$authed_url" test & done - From 487539227190e1a126184b0a2f3ea04c60edc2ed Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 14 Nov 2025 23:07:10 +0530 Subject: [PATCH 089/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Adding an integration test --- .../java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java index e24e6f5..1f2af4a 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Config/OpenApiConfig.java @@ -5,10 +5,12 @@ import io.swagger.v3.oas.models.servers.Server; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; import java.util.ArrayList; @Configuration +@Profile("!integration") public class OpenApiConfig { @Value("${api.baseUrl}") From ffb33a49e40e9dbd3f4daf57f4953a4068b8ffa0 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 14 Nov 2025 23:10:36 +0530 Subject: [PATCH 090/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Setting up workflow to run integration tests --- .gitea/workflows/integration_test.yaml | 26 +++++++++ .../application-integration.properties | 5 ++ .../CoudflareApiIntegrationTest.java | 53 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 .gitea/workflows/integration_test.yaml create mode 100644 src/main/resources/application-integration.properties create mode 100644 src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java diff --git a/.gitea/workflows/integration_test.yaml b/.gitea/workflows/integration_test.yaml new file mode 100644 index 0000000..2a46a19 --- /dev/null +++ b/.gitea/workflows/integration_test.yaml @@ -0,0 +1,26 @@ +name: Daily cloudflare API integration test +on: + push: + branches: [ test ] +# schedule: +# - cron: '0 * * * *' # Every hour +# workflow_dispatch: + +jobs: + cloudflare-api-test: + runs-on: ubuntu-latest + steps: + - name: Check out repository code + uses: actions/checkout@v4 + - name: JDK setup + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + - name: Run integration tests with Cloudflare API + env: + SPRING_PROFILES_ACTIVE: integration + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }} + CLOUDFLARE_EMAIL: hitanshu98@gmail.com + run: ./gradlew test --tests "com.hithomelabs.CFTunnels.Integration.CoudflareApiIntegrationTest" \ No newline at end of file diff --git a/src/main/resources/application-integration.properties b/src/main/resources/application-integration.properties new file mode 100644 index 0000000..d2ec183 --- /dev/null +++ b/src/main/resources/application-integration.properties @@ -0,0 +1,5 @@ +cloudflare.accountId=${CLOUDFLARE_ACCOUNT_ID} +cloudflare.apiKey=${CLOUDFLARE_API_KEY} +cloudflare.email=${CLOUDFLARE_EMAIL} + +api.baseUrl \ No newline at end of file diff --git a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java new file mode 100644 index 0000000..94c3076 --- /dev/null +++ b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java @@ -0,0 +1,53 @@ +package com.hithomelabs.CFTunnels.Integration; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.hithomelabs.CFTunnels.Config.CloudflareConfig; +import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ActiveProfiles; + +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ActiveProfiles("integration") +public class CoudflareApiIntegrationTest { + + @Autowired + TestRestTemplate restTemplate; + + @Autowired + AuthKeyEmailHeader authKeyEmailHeader; + + @Autowired + CloudflareConfig cloudflareConfig; + + private static ObjectMapper mapper = new ObjectMapper(); + + @Test + @DisplayName("Calls cloudflare cfd tunnels API and checks that dev tunnel should be a part of the response") + public void getTunnelsTest(){ + + // * * Resource URL to hit get request at + String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel"; + HttpEntity httpEntity = new HttpEntity<>("", authKeyEmailHeader.getHttpHeaders()); + ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + List> tunnelList = (List>) response.getBody().get("result"); + boolean hasName = tunnelList.stream() + .anyMatch(tunnel -> "devtunnel".equals(tunnel.get("name"))); + assertTrue(hasName); + } + +} From 8039945f2a4d0e6f7270ecf44eabec20df737f68 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 14 Nov 2025 23:11:57 +0530 Subject: [PATCH 091/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Minor bug fix --- src/main/resources/application-integration.properties | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/resources/application-integration.properties b/src/main/resources/application-integration.properties index d2ec183..055765b 100644 --- a/src/main/resources/application-integration.properties +++ b/src/main/resources/application-integration.properties @@ -1,5 +1,3 @@ cloudflare.accountId=${CLOUDFLARE_ACCOUNT_ID} cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} - -api.baseUrl \ No newline at end of file From b2d58d6a6155a4bb3e53669b302d5d85388dc31e Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 14 Nov 2025 23:24:42 +0530 Subject: [PATCH 092/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Reducing logging verbiage, excuding integration test from test profile --- src/main/resources/application.properties | 6 ------ .../CFTunnels/Integration/CoudflareApiIntegrationTest.java | 2 ++ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 89201b8..a0264d2 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -4,12 +4,6 @@ cloudflare.apiKey=${CLOUDFLARE_API_KEY} cloudflare.email=${CLOUDFLARE_EMAIL} spring.profiles.active=${ENV} -# set root level -logging.level.root=INFO -# package-specific -logging.level.org.springframework=TRACE -logging.level.com.myapp=INFO - / * * Masking sure app works behind a reverse proxy server.forward-headers-strategy=framework diff --git a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java index 94c3076..124d246 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.annotation.Profile; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -22,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("integration") +@Profile("!test") public class CoudflareApiIntegrationTest { @Autowired From b8bf2e8c671e3af1339884cf2ee6fcdbf214f7eb Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Fri, 14 Nov 2025 23:38:32 +0530 Subject: [PATCH 093/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Fixes bug reaated to integration test running during gradle build --- build.gradle | 3 +++ .../CFTunnels/Integration/CoudflareApiIntegrationTest.java | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4328386..5fd8ad1 100644 --- a/build.gradle +++ b/build.gradle @@ -15,6 +15,9 @@ java { test { systemProperty 'spring.profiles.active', 'test' + useJUnitPlatform { + excludeTags 'integration' + } } repositories { diff --git a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java index 124d246..939e001 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -23,7 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("integration") -@Profile("!test") +@Tag("integration") public class CoudflareApiIntegrationTest { @Autowired From e87fb6d153a64b563f89eab517285ad7793831b3 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 15 Nov 2025 01:14:11 +0530 Subject: [PATCH 094/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Excluding integration tests from gradle build and runs them separately in integration tests --- .gitea/workflows/integration_test.yaml | 2 +- build.gradle | 8 ++++++++ settings.gradle | 1 - .../Integration/CoudflareApiIntegrationTest.java | 1 - 4 files changed, 9 insertions(+), 3 deletions(-) delete mode 100644 settings.gradle diff --git a/.gitea/workflows/integration_test.yaml b/.gitea/workflows/integration_test.yaml index 2a46a19..3a4697c 100644 --- a/.gitea/workflows/integration_test.yaml +++ b/.gitea/workflows/integration_test.yaml @@ -23,4 +23,4 @@ jobs: CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} CLOUDFLARE_API_KEY: ${{ secrets.CLOUDFLARE_API_KEY }} CLOUDFLARE_EMAIL: hitanshu98@gmail.com - run: ./gradlew test --tests "com.hithomelabs.CFTunnels.Integration.CoudflareApiIntegrationTest" \ No newline at end of file + run: ./gradlew integrationTestOnly \ No newline at end of file diff --git a/build.gradle b/build.gradle index 5fd8ad1..c85d1f3 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,14 @@ test { } } +tasks.register('integrationTestOnly', Test) { + useJUnitPlatform { + includeTags 'integration' + } + description = 'Runs only integration tests tagged with @Tag("integration")' + group = 'verification' +} + repositories { mavenCentral() } diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 3561707..0000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'CFTunnels' diff --git a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java index 939e001..0ce0bc0 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java @@ -9,7 +9,6 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.context.annotation.Profile; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; From d194828c4411453f2f84344fdfe3c1474bb05ff1 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 15 Nov 2025 01:22:29 +0530 Subject: [PATCH 095/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Executing integration test every 6 hours --- .gitea/workflows/integration_test.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/integration_test.yaml b/.gitea/workflows/integration_test.yaml index 3a4697c..688f37b 100644 --- a/.gitea/workflows/integration_test.yaml +++ b/.gitea/workflows/integration_test.yaml @@ -1,10 +1,8 @@ name: Daily cloudflare API integration test on: - push: - branches: [ test ] -# schedule: -# - cron: '0 * * * *' # Every hour -# workflow_dispatch: + schedule: + - cron: '0 */6 * * *' # Every hour + workflow_dispatch: jobs: cloudflare-api-test: From 95ec64630a84950f5c7091880bcc00452e1de232 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 15 Nov 2025 01:27:32 +0530 Subject: [PATCH 096/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 making tests more verbose --- build.gradle | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build.gradle b/build.gradle index c85d1f3..0800341 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,11 @@ test { useJUnitPlatform { excludeTags 'integration' } + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + exceptionFormat "full" // shows full stack trace + showStandardStreams = true // shows println/log output + } } tasks.register('integrationTestOnly', Test) { @@ -26,6 +31,11 @@ tasks.register('integrationTestOnly', Test) { } description = 'Runs only integration tests tagged with @Tag("integration")' group = 'verification' + testLogging { + events "passed", "skipped", "failed" + exceptionFormat "full" + showStandardStreams = true + } } repositories { From 8b220640404e89cb53ed9a5318a0e294a7a44275 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 15 Nov 2025 01:22:29 +0530 Subject: [PATCH 097/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 Executing integration test every 6 hours --- .gitea/workflows/integration_test.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/integration_test.yaml b/.gitea/workflows/integration_test.yaml index 3a4697c..688f37b 100644 --- a/.gitea/workflows/integration_test.yaml +++ b/.gitea/workflows/integration_test.yaml @@ -1,10 +1,8 @@ name: Daily cloudflare API integration test on: - push: - branches: [ test ] -# schedule: -# - cron: '0 * * * *' # Every hour -# workflow_dispatch: + schedule: + - cron: '0 */6 * * *' # Every hour + workflow_dispatch: jobs: cloudflare-api-test: From f36d8077314a7831b5acb0877f22138e73749852 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sat, 15 Nov 2025 01:27:32 +0530 Subject: [PATCH 098/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 making tests more verbose --- build.gradle | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build.gradle b/build.gradle index c85d1f3..0800341 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,11 @@ test { useJUnitPlatform { excludeTags 'integration' } + testLogging { + events "passed", "skipped", "failed", "standardOut", "standardError" + exceptionFormat "full" // shows full stack trace + showStandardStreams = true // shows println/log output + } } tasks.register('integrationTestOnly', Test) { @@ -26,6 +31,11 @@ tasks.register('integrationTestOnly', Test) { } description = 'Runs only integration tests tagged with @Tag("integration")' group = 'verification' + testLogging { + events "passed", "skipped", "failed" + exceptionFormat "full" + showStandardStreams = true + } } repositories { From b30ae7cdbff9748487c242f7c7b0b4dcc3d0c180 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 16 Nov 2025 18:59:06 +0530 Subject: [PATCH 099/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 adding more tests --- .../hithomelabs/CFTunnels/Models/Ingress.java | 41 +++------- .../CoudflareApiIntegrationTest.java | 78 +++++++++++++++---- 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java index 7c6c7be..005a02b 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java @@ -1,8 +1,17 @@ package com.hithomelabs.CFTunnels.Models; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + import java.util.List; import java.util.Map; +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter public class Ingress { private String service; @@ -10,40 +19,8 @@ public class Ingress { private Map originRequest; private String path; - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - public static boolean deleteByHostName(List ingressList, String toBeDeleted){ return ingressList.removeIf(ingress -> ingress.getHostname() != null && ingress.getHostname().equals(toBeDeleted)); } - public String getService() { - return service; - } - - public void setService(String service) { - this.service = service; - } - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public Map getOriginRequest() { - return originRequest; - } - - public void setOriginRequest(Map originRequest) { - this.originRequest = originRequest; - } } diff --git a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java index 0ce0bc0..9553db1 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java @@ -1,25 +1,25 @@ package com.hithomelabs.CFTunnels.Integration; -import com.fasterxml.jackson.databind.ObjectMapper; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Models.Config; +import com.hithomelabs.CFTunnels.Models.Ingress; +import com.hithomelabs.CFTunnels.Models.TunnelResponse; +import com.hithomelabs.CFTunnels.Services.CloudflareAPIService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; +import org.springframework.web.client.RestTemplate; import java.util.List; import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("integration") @@ -27,7 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class CoudflareApiIntegrationTest { @Autowired - TestRestTemplate restTemplate; + RestTemplate restTemplate; @Autowired AuthKeyEmailHeader authKeyEmailHeader; @@ -35,21 +35,73 @@ public class CoudflareApiIntegrationTest { @Autowired CloudflareConfig cloudflareConfig; - private static ObjectMapper mapper = new ObjectMapper(); + @Autowired + CloudflareAPIService cloudflareAPIService; + + private static final String DEV_TUNNEL_ID = "50df9101-f625-4618-b7c5-100338a57124"; @Test @DisplayName("Calls cloudflare cfd tunnels API and checks that dev tunnel should be a part of the response") - public void getTunnelsTest(){ + public void testGetTunnelsTest() { + + ResponseEntity response = cloudflareAPIService.getCloudflareTunnels(); - // * * Resource URL to hit get request at - String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel"; - HttpEntity httpEntity = new HttpEntity<>("", authKeyEmailHeader.getHttpHeaders()); - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class); assertEquals(HttpStatus.OK, response.getStatusCode()); + List> tunnelList = (List>) response.getBody().get("result"); boolean hasName = tunnelList.stream() .anyMatch(tunnel -> "devtunnel".equals(tunnel.get("name"))); + assertTrue(hasName); } + @Test + @DisplayName("Calls cloudflare API to get mappings for devtunnel tunnel") + public void testTunnelConfigurations() { + + ResponseEntity responseEntity = cloudflareAPIService.getCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class); + + // * * Check if status code is 200 + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + + // * * Checking if mapping for devdocker exists + TunnelResponse tunnelResponse = responseEntity.getBody(); + boolean hasMatch = tunnelResponse.getResult().getConfig().getIngress().stream() + .anyMatch(ingress -> "devdocker.hithomelabs.com".equals(ingress.getHostname())); + assertTrue(hasMatch); + } + + @Test + @DisplayName("Inserts and deletes a mapping using Cloudflare API") + public void testAddAndDeleteMapping() { + + ResponseEntity beforeMapping = cloudflareAPIService.getCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class); + + assertEquals(HttpStatus.OK, beforeMapping.getStatusCode()); + + Ingress ingress = new Ingress(); + ingress.setHostname("random.hithomelabs.com"); + ingress.setService("http://192.168.0.100:3457"); + + Config beforeInsertConfig = beforeMapping.getBody().getResult().getConfig(); + List beforeInsert = beforeInsertConfig.getIngress(); + beforeInsert.add(beforeInsert.size() - 1, ingress); + + ResponseEntity afterInsert = cloudflareAPIService.putCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class, beforeInsertConfig); + + assertEquals(HttpStatus.OK, afterInsert.getStatusCode()); + Config afterInsertConfig = afterInsert.getBody().getResult().getConfig(); + List ingressList = afterInsertConfig.getIngress(); + + boolean hasIngress = ingressList.get(ingressList.size() - 2 ).getHostname().equals("random.hithomelabs.com"); + assertTrue(hasIngress); + + Boolean deleteSuccess = Ingress.deleteByHostName(ingressList, ingress.getHostname()); + assertTrue(deleteSuccess); + + ResponseEntity afterDelete = cloudflareAPIService.putCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class, afterInsertConfig); + assertEquals(HttpStatus.OK, afterDelete.getStatusCode()); + assertFalse(afterDelete.getBody().getResult().getConfig().getIngress().stream().anyMatch(anyIngress -> "random.hithomelabs.com".equals(anyIngress.getHostname()))); + } + } From 43416d4bc74b36bb3506eba860e746c2bcc5bc87 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 16 Nov 2025 18:59:06 +0530 Subject: [PATCH 100/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 adding more tests --- .../hithomelabs/CFTunnels/Models/Ingress.java | 41 +++------- .../CoudflareApiIntegrationTest.java | 78 +++++++++++++++---- 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java index 7c6c7be..005a02b 100644 --- a/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java +++ b/src/main/java/com/hithomelabs/CFTunnels/Models/Ingress.java @@ -1,8 +1,17 @@ package com.hithomelabs.CFTunnels.Models; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + import java.util.List; import java.util.Map; +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter public class Ingress { private String service; @@ -10,40 +19,8 @@ public class Ingress { private Map originRequest; private String path; - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - public static boolean deleteByHostName(List ingressList, String toBeDeleted){ return ingressList.removeIf(ingress -> ingress.getHostname() != null && ingress.getHostname().equals(toBeDeleted)); } - public String getService() { - return service; - } - - public void setService(String service) { - this.service = service; - } - - public String getHostname() { - return hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - public Map getOriginRequest() { - return originRequest; - } - - public void setOriginRequest(Map originRequest) { - this.originRequest = originRequest; - } } diff --git a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java index 0ce0bc0..9553db1 100644 --- a/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java +++ b/src/test/java/com/hithomelabs/CFTunnels/Integration/CoudflareApiIntegrationTest.java @@ -1,25 +1,25 @@ package com.hithomelabs.CFTunnels.Integration; -import com.fasterxml.jackson.databind.ObjectMapper; import com.hithomelabs.CFTunnels.Config.CloudflareConfig; import com.hithomelabs.CFTunnels.Headers.AuthKeyEmailHeader; +import com.hithomelabs.CFTunnels.Models.Config; +import com.hithomelabs.CFTunnels.Models.Ingress; +import com.hithomelabs.CFTunnels.Models.TunnelResponse; +import com.hithomelabs.CFTunnels.Services.CloudflareAPIService; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; +import org.springframework.web.client.RestTemplate; import java.util.List; import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles("integration") @@ -27,7 +27,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; public class CoudflareApiIntegrationTest { @Autowired - TestRestTemplate restTemplate; + RestTemplate restTemplate; @Autowired AuthKeyEmailHeader authKeyEmailHeader; @@ -35,21 +35,73 @@ public class CoudflareApiIntegrationTest { @Autowired CloudflareConfig cloudflareConfig; - private static ObjectMapper mapper = new ObjectMapper(); + @Autowired + CloudflareAPIService cloudflareAPIService; + + private static final String DEV_TUNNEL_ID = "50df9101-f625-4618-b7c5-100338a57124"; @Test @DisplayName("Calls cloudflare cfd tunnels API and checks that dev tunnel should be a part of the response") - public void getTunnelsTest(){ + public void testGetTunnelsTest() { + + ResponseEntity response = cloudflareAPIService.getCloudflareTunnels(); - // * * Resource URL to hit get request at - String url = "https://api.cloudflare.com/client/v4/accounts/" + cloudflareConfig.getAccountId() + "/cfd_tunnel"; - HttpEntity httpEntity = new HttpEntity<>("", authKeyEmailHeader.getHttpHeaders()); - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class); assertEquals(HttpStatus.OK, response.getStatusCode()); + List> tunnelList = (List>) response.getBody().get("result"); boolean hasName = tunnelList.stream() .anyMatch(tunnel -> "devtunnel".equals(tunnel.get("name"))); + assertTrue(hasName); } + @Test + @DisplayName("Calls cloudflare API to get mappings for devtunnel tunnel") + public void testTunnelConfigurations() { + + ResponseEntity responseEntity = cloudflareAPIService.getCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class); + + // * * Check if status code is 200 + assertEquals(HttpStatus.OK, responseEntity.getStatusCode()); + + // * * Checking if mapping for devdocker exists + TunnelResponse tunnelResponse = responseEntity.getBody(); + boolean hasMatch = tunnelResponse.getResult().getConfig().getIngress().stream() + .anyMatch(ingress -> "devdocker.hithomelabs.com".equals(ingress.getHostname())); + assertTrue(hasMatch); + } + + @Test + @DisplayName("Inserts and deletes a mapping using Cloudflare API") + public void testAddAndDeleteMapping() { + + ResponseEntity beforeMapping = cloudflareAPIService.getCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class); + + assertEquals(HttpStatus.OK, beforeMapping.getStatusCode()); + + Ingress ingress = new Ingress(); + ingress.setHostname("random.hithomelabs.com"); + ingress.setService("http://192.168.0.100:3457"); + + Config beforeInsertConfig = beforeMapping.getBody().getResult().getConfig(); + List beforeInsert = beforeInsertConfig.getIngress(); + beforeInsert.add(beforeInsert.size() - 1, ingress); + + ResponseEntity afterInsert = cloudflareAPIService.putCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class, beforeInsertConfig); + + assertEquals(HttpStatus.OK, afterInsert.getStatusCode()); + Config afterInsertConfig = afterInsert.getBody().getResult().getConfig(); + List ingressList = afterInsertConfig.getIngress(); + + boolean hasIngress = ingressList.get(ingressList.size() - 2 ).getHostname().equals("random.hithomelabs.com"); + assertTrue(hasIngress); + + Boolean deleteSuccess = Ingress.deleteByHostName(ingressList, ingress.getHostname()); + assertTrue(deleteSuccess); + + ResponseEntity afterDelete = cloudflareAPIService.putCloudflareTunnelConfigurations(DEV_TUNNEL_ID, restTemplate, TunnelResponse.class, afterInsertConfig); + assertEquals(HttpStatus.OK, afterDelete.getStatusCode()); + assertFalse(afterDelete.getBody().getResult().getConfig().getIngress().stream().anyMatch(anyIngress -> "random.hithomelabs.com".equals(anyIngress.getHostname()))); + } + } From 6db68ad36f8275b68f77aabdead8ef120753a078 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 16 Nov 2025 19:47:08 +0530 Subject: [PATCH 101/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 run integration tests on push to main and changing interval to 12 hours --- .gitea/workflows/integration_test.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/integration_test.yaml b/.gitea/workflows/integration_test.yaml index 688f37b..4c4ee37 100644 --- a/.gitea/workflows/integration_test.yaml +++ b/.gitea/workflows/integration_test.yaml @@ -1,7 +1,9 @@ name: Daily cloudflare API integration test on: + push: + branches: [ main ] schedule: - - cron: '0 */6 * * *' # Every hour + - cron: '0 */12 * * *' # Every hour workflow_dispatch: jobs: From f469ff33a7a0d6441fbf803f5aaa705744759a93 Mon Sep 17 00:00:00 2001 From: hitanshu310 Date: Sun, 16 Nov 2025 19:49:58 +0530 Subject: [PATCH 102/102] ISSUE-44: Hithomelabs/HomeLabDocker#44 bug-fix --- .gitea/workflows/integration_test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/integration_test.yaml b/.gitea/workflows/integration_test.yaml index 4c4ee37..4ccbebf 100644 --- a/.gitea/workflows/integration_test.yaml +++ b/.gitea/workflows/integration_test.yaml @@ -3,7 +3,7 @@ on: push: branches: [ main ] schedule: - - cron: '0 */12 * * *' # Every hour + - cron: '0 */2 * * *' # Every hour workflow_dispatch: jobs: