diff --git a/.github/workflows/cd-pipeline.yml b/.github/workflows/cd-pipeline.yml
index e925733df0..a8ed80cadf 100644
--- a/.github/workflows/cd-pipeline.yml
+++ b/.github/workflows/cd-pipeline.yml
@@ -34,6 +34,7 @@ on: # rebuild any PRs and main branch changes
- 'bitnami/kafka/**'
- 'bitnami/keycloak/**'
- 'bitnami/kibana/**'
+ - 'bitnami/kong/**'
- 'bitnami/logstash/**'
- 'bitnami/magento/**'
- 'bitnami/mariadb-galera/**'
diff --git a/.vib/kong/cypress/cypress.json b/.vib/kong/cypress/cypress.json
new file mode 100644
index 0000000000..ac2d78f0b5
--- /dev/null
+++ b/.vib/kong/cypress/cypress.json
@@ -0,0 +1,10 @@
+{
+ "baseUrl": "http://localhost",
+ "env": {
+ "apikey": "ComplicatedPassword123!4",
+ "ingressHost": "www.example.com",
+ "ingressPath": "/nginx",
+ "externalIp": "{{ TARGET_IP }}",
+ "adminHttpPort": "443"
+ }
+}
diff --git a/.vib/kong/cypress/cypress/fixtures/routes.json b/.vib/kong/cypress/cypress/fixtures/routes.json
new file mode 100644
index 0000000000..dad3d621bb
--- /dev/null
+++ b/.vib/kong/cypress/cypress/fixtures/routes.json
@@ -0,0 +1,5 @@
+{
+ "newRoute": {
+ "path": "/chestnut"
+ }
+}
diff --git a/.vib/kong/cypress/cypress/fixtures/services.json b/.vib/kong/cypress/cypress/fixtures/services.json
new file mode 100644
index 0000000000..fe4612ab36
--- /dev/null
+++ b/.vib/kong/cypress/cypress/fixtures/services.json
@@ -0,0 +1,7 @@
+{
+ "newService": {
+ "name": "cypress-service",
+ "upstreamURL": "https://bitnami.com",
+ "upstreamContent": "Loved by Developers"
+ }
+}
diff --git a/.vib/kong/cypress/cypress/integration/kong_spec.js b/.vib/kong/cypress/cypress/integration/kong_spec.js
new file mode 100644
index 0000000000..0252517315
--- /dev/null
+++ b/.vib/kong/cypress/cypress/integration/kong_spec.js
@@ -0,0 +1,73 @@
+///
+
+import { random } from '../support/utils';
+
+it('allows accessing a restricted service (CRD) when API key is presented', () => {
+ const ROUTE_PATH = Cypress.env('ingressPath');
+
+ cy.request({
+ method: 'GET',
+ url: ROUTE_PATH,
+ headers: { Host: Cypress.env('ingressHost') },
+ failOnStatusCode: false,
+ }).then((response) => {
+ // No API Key presented
+ expect(response.status).to.eq(401);
+ });
+
+ cy.request({
+ method: 'GET',
+ url: ROUTE_PATH,
+ headers: {
+ apikey: Cypress.env('apikey'),
+ Host: Cypress.env('ingressHost'),
+ },
+ }).then((response) => {
+ expect(response.status).to.eq(200);
+ expect(response.body).to.contain('Welcome to nginx');
+ });
+});
+
+it('allows adding a new service and route through admin API', () => {
+ // As adminAPI is exposed in another port, we need to use the external IP to access it
+ const BASE_URL = `http://${Cypress.env('externalIp')}:${Cypress.env(
+ 'adminHttpPort'
+ )}`;
+
+ cy.fixture('services').then((services) => {
+ cy.request({
+ method: 'POST',
+ url: `${BASE_URL}/services`,
+ body: {
+ name: `${services.newService.name}-${random}`,
+ url: services.newService.upstreamURL,
+ },
+ }).then((response) => {
+ expect(response.status).to.eq(201);
+ });
+
+ cy.fixture('routes').then((routes) => {
+ cy.request({
+ method: 'POST',
+ url: `${BASE_URL}/services/${services.newService.name}-${random}/routes`,
+ body: {
+ paths: [
+ `${routes.newRoute.path}${random}`
+ ],
+ },
+ }).then((response) => {
+ expect(response.status).to.eq(201);
+ });
+
+ // Changes takes some seconds to apply
+ cy.wait(7000);
+ cy.request({
+ method: 'GET',
+ url: `${routes.newRoute.path}${random}`,
+ }).then((response) => {
+ expect(response.status).to.eq(200);
+ expect(response.body).to.contain(services.newService.upstreamContent);
+ });
+ });
+ });
+});
diff --git a/.vib/kong/cypress/cypress/support/utils.js b/.vib/kong/cypress/cypress/support/utils.js
new file mode 100644
index 0000000000..f0217c9773
--- /dev/null
+++ b/.vib/kong/cypress/cypress/support/utils.js
@@ -0,0 +1,3 @@
+///
+
+export let random = (Math.random() + 1).toString(36).substring(7);
diff --git a/.vib/kong/goss/goss.yaml b/.vib/kong/goss/goss.yaml
new file mode 100644
index 0000000000..0582e25c21
--- /dev/null
+++ b/.vib/kong/goss/goss.yaml
@@ -0,0 +1,33 @@
+http:
+ https://kong:{{ .Vars.service.ports.proxyHttps }}:
+ # The proxy does respond but the route is not registered
+ status: 404
+ allow-insecure: true
+ https://kong:{{ .Vars.service.ports.adminHttps }}:
+ status: 200
+ allow-insecure: true
+file:
+ /opt/bitnami/kong/conf/kong.conf:
+ exists: true
+ filetype: file
+ mode: '0644'
+ owner: root
+ contains:
+ - /pg_user.*{{ .Vars.postgresql.auth.username }}/
+ - /pg_database.*{{ .Vars.postgresql.auth.database }}/
+ - /pg_password.*{{ .Vars.postgresql.auth.password }}/
+ /opt/bitnami/kong/server/nginx-kong.conf:
+ exists: true
+ filetype: file
+ mode: '0644'
+ contains:
+ - /listen.*{{ .Vars.kong.containerPorts.proxyHttp }}/
+ - /listen.*{{ .Vars.kong.containerPorts.adminHttp }}/
+ - /listen.*{{ .Vars.kong.containerPorts.proxyHttps }}.*ssl/
+ - /listen.*{{ .Vars.kong.containerPorts.adminHttps }}.*ssl/
+command:
+ check-user-info:
+ exec: id
+ exit-status: 0
+ stdout:
+ - uid={{ .Vars.containerSecurityContext.runAsUser }}
\ No newline at end of file
diff --git a/.vib/kong/goss/vars.yaml b/.vib/kong/goss/vars.yaml
new file mode 100644
index 0000000000..f964271c37
--- /dev/null
+++ b/.vib/kong/goss/vars.yaml
@@ -0,0 +1,17 @@
+containerSecurityContext:
+ runAsUser: 1002
+kong:
+ containerPorts:
+ proxyHttp: 8000
+ proxyHttps: 8443
+ adminHttp: 8001
+ adminHttps: 8444
+service:
+ ports:
+ proxyHttps: 8443
+ adminHttps: 8444
+postgresql:
+ auth:
+ username: kong
+ password: ""
+ database: kong
\ No newline at end of file
diff --git a/.vib/kong/vib-action.config b/.vib/kong/vib-action.config
new file mode 100644
index 0000000000..98dc98a97e
--- /dev/null
+++ b/.vib/kong/vib-action.config
@@ -0,0 +1 @@
+verification-mode=SERIAL
\ No newline at end of file
diff --git a/.vib/kong/vib-publish.json b/.vib/kong/vib-publish.json
index 9cd48b4f53..0cf9013a10 100644
--- a/.vib/kong/vib-publish.json
+++ b/.vib/kong/vib-publish.json
@@ -22,7 +22,7 @@
"url": "{SHA_ARCHIVE}",
"path": "/bitnami/kong"
},
- "runtime_parameters": "InBvZEFmZmluaXR5UHJlc2V0IjogImhhcmQiCiJwb2RBbnRpQWZmaW5pdHlQcmVzZXQiOiAiIgoicG9zdGdyZXNxbCI6CiAgInBvc3RncmVzcWxQYXNzd29yZCI6ICI3ZE14TGZjcXhOIgoicmVwbGljYUNvdW50IjogMQoic2VydmljZSI6CiAgInByb3h5SHR0cFBvcnQiOiA4MAogICJ0eXBlIjogIkxvYWRCYWxhbmNlciI=",
+ "runtime_parameters": "cmVwbGljYUNvdW50OiAxCmRhdGFiYXNlOiBwb3N0Z3Jlc3FsCmNvbnRhaW5lclNlY3VyaXR5Q29udGV4dDoKICBlbmFibGVkOiB0cnVlCiAgcnVuQXNVc2VyOiAxMDAyCmtvbmc6CiAgY29udGFpbmVyUG9ydHM6IAogICAgcHJveHlIdHRwOiA4MDAwCiAgICBwcm94eUh0dHBzOiA4NDQzCiAgICBhZG1pbkh0dHA6IDgwMDEKICAgIGFkbWluSHR0cHM6IDg0NDQKc2VydmljZToKICB0eXBlOiBMb2FkQmFsYW5jZXIKICBleHBvc2VBZG1pbjogdHJ1ZQogIGRpc2FibGVIdHRwUG9ydDogZmFsc2UKICBwb3J0czoKICAgIHByb3h5SHR0cDogODAKICAgIHByb3h5SHR0cHM6IDg0NDMKICAgIGFkbWluSHR0cDogNDQzCiAgICBhZG1pbkh0dHBzOiA4NDQ0CmluZ3Jlc3NDb250cm9sbGVyOgogIGVuYWJsZWQ6IHRydWUKICBpbmdyZXNzQ2xhc3M6IGtvbmcKcG9zdGdyZXNxbDoKICBlbmFibGVkOiB0cnVlCiAgYXV0aDoKICAgIHVzZXJuYW1lOiBrb25nCiAgICBwYXNzd29yZDogIiIKICAgIGRhdGFiYXNlOiBrb25nCmV4dHJhRGVwbG95OgotIGFwaVZlcnNpb246IGFwcHMvdjEKICBraW5kOiBEZXBsb3ltZW50CiAgbWV0YWRhdGE6CiAgICBuYW1lOiBuZ2lueC12aWItdGVzdHMKICBzcGVjOgogICAgcmVwbGljYXM6IDEKICAgIHNlbGVjdG9yOgogICAgICBtYXRjaExhYmVsczoKICAgICAgICBhcHA6IG5naW54CiAgICB0ZW1wbGF0ZToKICAgICAgbWV0YWRhdGE6CiAgICAgICAgbGFiZWxzOgogICAgICAgICAgYXBwOiBuZ2lueAogICAgICBzcGVjOgogICAgICAgIGNvbnRhaW5lcnM6CiAgICAgICAgLSBuYW1lOiBuZ2lueAogICAgICAgICAgaW1hZ2U6IGJpdG5hbWkvbmdpbngKICAgICAgICAgIHBvcnRzOgogICAgICAgICAgLSBjb250YWluZXJQb3J0OiA4MDgwCi0gYXBpVmVyc2lvbjogdjEKICBraW5kOiBTZXJ2aWNlCiAgbWV0YWRhdGE6CiAgICBuYW1lOiBuZ2lueC12aWItdGVzdHMKICAgIGxhYmVsczoKICAgICAgYXBwOiBuZ2lueAogIHNwZWM6CiAgICBzZWxlY3RvcjoKICAgICAgYXBwOiBuZ2lueAogICAgcG9ydHM6CiAgICAtIHBvcnQ6IDgwODAKICAgICAgbmFtZTogaHR0cAogICAgICB0YXJnZXRQb3J0OiA4MDgwCi0gYXBpVmVyc2lvbjogdjEKICBraW5kOiBTZWNyZXQKICBtZXRhZGF0YToKICAgIG5hbWU6IGFwaWtleS12aWItdGVzdHMKICBkYXRhOgogICAga29uZ0NyZWRUeXBlOiBhMlY1TFdGMWRHZz0KICAgIGtleTogUTI5dGNHeHBZMkYwWldSUVlYTnpkMjl5WkRFeU15RTAKLSBhcGlWZXJzaW9uOiBjb25maWd1cmF0aW9uLmtvbmdocS5jb20vdjEKICBraW5kOiBLb25nQ29uc3VtZXIKICBtZXRhZGF0YToKICAgIG5hbWU6IHZpYi10ZXN0cwogICAgYW5ub3RhdGlvbnM6CiAgICAgIGt1YmVybmV0ZXMuaW8vaW5ncmVzcy5jbGFzczoga29uZwogIHVzZXJuYW1lOiAidmliLXRlc3RzIgogIGNyZWRlbnRpYWxzOgogIC0gYXBpa2V5LXZpYi10ZXN0cwotIGFwaVZlcnNpb246IGNvbmZpZ3VyYXRpb24ua29uZ2hxLmNvbS92MQogIGtpbmQ6IEtvbmdQbHVnaW4KICBtZXRhZGF0YToKICAgIG5hbWU6IGF1dGgtdmliLXRlc3RzCiAgcGx1Z2luOiBrZXktYXV0aAotIGFwaVZlcnNpb246IG5ldHdvcmtpbmcuazhzLmlvL3YxCiAga2luZDogSW5ncmVzcwogIG1ldGFkYXRhOgogICAgbmFtZTogdmliLXRlc3RzCiAgICBhbm5vdGF0aW9uczoKICAgICAga29uZ2hxLmNvbS9zdHJpcC1wYXRoOiAidHJ1ZSIKICAgICAga29uZ2hxLmNvbS9wbHVnaW5zOiBhdXRoLXZpYi10ZXN0cwogIHNwZWM6CiAgICBpbmdyZXNzQ2xhc3NOYW1lOiBrb25nCiAgICBydWxlczoKICAgIC0gaG9zdDogd3d3LmV4YW1wbGUuY29tCiAgICAgIGh0dHA6CiAgICAgICAgcGF0aHM6CiAgICAgICAgLSBwYXRoOiAvbmdpbngKICAgICAgICAgIHBhdGhUeXBlOiBJbXBsZW1lbnRhdGlvblNwZWNpZmljCiAgICAgICAgICBiYWNrZW5kOgogICAgICAgICAgICBzZXJ2aWNlOgogICAgICAgICAgICAgIG5hbWU6IG5naW54LXZpYi10ZXN0cwogICAgICAgICAgICAgIHBvcnQ6CiAgICAgICAgICAgICAgICBudW1iZXI6IDgwODA=",
"target_platform": {
"target_platform_id": "{VIB_ENV_ALTERNATIVE_TARGET_PLATFORM}",
"size": {
@@ -36,6 +36,35 @@
"params": {
"endpoint": "lb-kong-http-proxy"
}
+ },
+ {
+ "action_id": "goss",
+ "params": {
+ "resources": {
+ "path": "/.vib/kong/goss"
+ },
+ "remote": {
+ "workload": "deploy-kong"
+ },
+ "vars_file": "vars.yaml"
+ }
+ },
+ {
+ "action_id": "cypress",
+ "params": {
+ "resources": {
+ "path": "/.vib/kong/cypress"
+ },
+ "endpoint": "lb-kong-http-proxy",
+ "app_protocol": "HTTP",
+ "env": {
+ "apikey": "ComplicatedPassword123!4",
+ "ingressHost": "www.example.com",
+ "ingressPath": "/nginx",
+ "externalIp": "{{ TARGET_IP }}",
+ "adminHttpPort": "443"
+ }
+ }
}
]
},
diff --git a/.vib/kong/vib-verify.json b/.vib/kong/vib-verify.json
index faff44c0d1..e6d4815873 100644
--- a/.vib/kong/vib-verify.json
+++ b/.vib/kong/vib-verify.json
@@ -22,7 +22,7 @@
"url": "{SHA_ARCHIVE}",
"path": "/bitnami/kong"
},
- "runtime_parameters": "InBvZEFmZmluaXR5UHJlc2V0IjogImhhcmQiCiJwb2RBbnRpQWZmaW5pdHlQcmVzZXQiOiAiIgoicG9zdGdyZXNxbCI6CiAgInBvc3RncmVzcWxQYXNzd29yZCI6ICI3ZE14TGZjcXhOIgoicmVwbGljYUNvdW50IjogMQoic2VydmljZSI6CiAgInByb3h5SHR0cFBvcnQiOiA4MAogICJ0eXBlIjogIkxvYWRCYWxhbmNlciI=",
+ "runtime_parameters": "cmVwbGljYUNvdW50OiAxCmRhdGFiYXNlOiBwb3N0Z3Jlc3FsCmNvbnRhaW5lclNlY3VyaXR5Q29udGV4dDoKICBlbmFibGVkOiB0cnVlCiAgcnVuQXNVc2VyOiAxMDAyCmtvbmc6CiAgY29udGFpbmVyUG9ydHM6IAogICAgcHJveHlIdHRwOiA4MDAwCiAgICBwcm94eUh0dHBzOiA4NDQzCiAgICBhZG1pbkh0dHA6IDgwMDEKICAgIGFkbWluSHR0cHM6IDg0NDQKc2VydmljZToKICB0eXBlOiBMb2FkQmFsYW5jZXIKICBleHBvc2VBZG1pbjogdHJ1ZQogIGRpc2FibGVIdHRwUG9ydDogZmFsc2UKICBwb3J0czoKICAgIHByb3h5SHR0cDogODAKICAgIHByb3h5SHR0cHM6IDg0NDMKICAgIGFkbWluSHR0cDogNDQzCiAgICBhZG1pbkh0dHBzOiA4NDQ0CmluZ3Jlc3NDb250cm9sbGVyOgogIGVuYWJsZWQ6IHRydWUKICBpbmdyZXNzQ2xhc3M6IGtvbmcKcG9zdGdyZXNxbDoKICBlbmFibGVkOiB0cnVlCiAgYXV0aDoKICAgIHVzZXJuYW1lOiBrb25nCiAgICBwYXNzd29yZDogIiIKICAgIGRhdGFiYXNlOiBrb25nCmV4dHJhRGVwbG95OgotIGFwaVZlcnNpb246IGFwcHMvdjEKICBraW5kOiBEZXBsb3ltZW50CiAgbWV0YWRhdGE6CiAgICBuYW1lOiBuZ2lueC12aWItdGVzdHMKICBzcGVjOgogICAgcmVwbGljYXM6IDEKICAgIHNlbGVjdG9yOgogICAgICBtYXRjaExhYmVsczoKICAgICAgICBhcHA6IG5naW54CiAgICB0ZW1wbGF0ZToKICAgICAgbWV0YWRhdGE6CiAgICAgICAgbGFiZWxzOgogICAgICAgICAgYXBwOiBuZ2lueAogICAgICBzcGVjOgogICAgICAgIGNvbnRhaW5lcnM6CiAgICAgICAgLSBuYW1lOiBuZ2lueAogICAgICAgICAgaW1hZ2U6IGJpdG5hbWkvbmdpbngKICAgICAgICAgIHBvcnRzOgogICAgICAgICAgLSBjb250YWluZXJQb3J0OiA4MDgwCi0gYXBpVmVyc2lvbjogdjEKICBraW5kOiBTZXJ2aWNlCiAgbWV0YWRhdGE6CiAgICBuYW1lOiBuZ2lueC12aWItdGVzdHMKICAgIGxhYmVsczoKICAgICAgYXBwOiBuZ2lueAogIHNwZWM6CiAgICBzZWxlY3RvcjoKICAgICAgYXBwOiBuZ2lueAogICAgcG9ydHM6CiAgICAtIHBvcnQ6IDgwODAKICAgICAgbmFtZTogaHR0cAogICAgICB0YXJnZXRQb3J0OiA4MDgwCi0gYXBpVmVyc2lvbjogdjEKICBraW5kOiBTZWNyZXQKICBtZXRhZGF0YToKICAgIG5hbWU6IGFwaWtleS12aWItdGVzdHMKICBkYXRhOgogICAga29uZ0NyZWRUeXBlOiBhMlY1TFdGMWRHZz0KICAgIGtleTogUTI5dGNHeHBZMkYwWldSUVlYTnpkMjl5WkRFeU15RTAKLSBhcGlWZXJzaW9uOiBjb25maWd1cmF0aW9uLmtvbmdocS5jb20vdjEKICBraW5kOiBLb25nQ29uc3VtZXIKICBtZXRhZGF0YToKICAgIG5hbWU6IHZpYi10ZXN0cwogICAgYW5ub3RhdGlvbnM6CiAgICAgIGt1YmVybmV0ZXMuaW8vaW5ncmVzcy5jbGFzczoga29uZwogIHVzZXJuYW1lOiAidmliLXRlc3RzIgogIGNyZWRlbnRpYWxzOgogIC0gYXBpa2V5LXZpYi10ZXN0cwotIGFwaVZlcnNpb246IGNvbmZpZ3VyYXRpb24ua29uZ2hxLmNvbS92MQogIGtpbmQ6IEtvbmdQbHVnaW4KICBtZXRhZGF0YToKICAgIG5hbWU6IGF1dGgtdmliLXRlc3RzCiAgcGx1Z2luOiBrZXktYXV0aAotIGFwaVZlcnNpb246IG5ldHdvcmtpbmcuazhzLmlvL3YxCiAga2luZDogSW5ncmVzcwogIG1ldGFkYXRhOgogICAgbmFtZTogdmliLXRlc3RzCiAgICBhbm5vdGF0aW9uczoKICAgICAga29uZ2hxLmNvbS9zdHJpcC1wYXRoOiAidHJ1ZSIKICAgICAga29uZ2hxLmNvbS9wbHVnaW5zOiBhdXRoLXZpYi10ZXN0cwogIHNwZWM6CiAgICBpbmdyZXNzQ2xhc3NOYW1lOiBrb25nCiAgICBydWxlczoKICAgIC0gaG9zdDogd3d3LmV4YW1wbGUuY29tCiAgICAgIGh0dHA6CiAgICAgICAgcGF0aHM6CiAgICAgICAgLSBwYXRoOiAvbmdpbngKICAgICAgICAgIHBhdGhUeXBlOiBJbXBsZW1lbnRhdGlvblNwZWNpZmljCiAgICAgICAgICBiYWNrZW5kOgogICAgICAgICAgICBzZXJ2aWNlOgogICAgICAgICAgICAgIG5hbWU6IG5naW54LXZpYi10ZXN0cwogICAgICAgICAgICAgIHBvcnQ6CiAgICAgICAgICAgICAgICBudW1iZXI6IDgwODA=",
"target_platform": {
"target_platform_id": "{VIB_ENV_ALTERNATIVE_TARGET_PLATFORM}",
"size": {
@@ -36,6 +36,35 @@
"params": {
"endpoint": "lb-kong-http-proxy"
}
+ },
+ {
+ "action_id": "goss",
+ "params": {
+ "resources": {
+ "path": "/.vib/kong/goss"
+ },
+ "remote": {
+ "workload": "deploy-kong"
+ },
+ "vars_file": "vars.yaml"
+ }
+ },
+ {
+ "action_id": "cypress",
+ "params": {
+ "resources": {
+ "path": "/.vib/kong/cypress"
+ },
+ "endpoint": "lb-kong-http-proxy",
+ "app_protocol": "HTTP",
+ "env": {
+ "apikey": "ComplicatedPassword123!4",
+ "ingressHost": "www.example.com",
+ "ingressPath": "/nginx",
+ "externalIp": "{{ TARGET_IP }}",
+ "adminHttpPort": "443"
+ }
+ }
}
]
}