diff --git a/.github/workflows/pull-integration-cluster-k3d.yml b/.github/workflows/pull-integration-cluster-k3d.yml index eae5c6fd1a..3bb328c41c 100644 --- a/.github/workflows/pull-integration-cluster-k3d.yml +++ b/.github/workflows/pull-integration-cluster-k3d.yml @@ -44,18 +44,12 @@ jobs: run: | set -e npm ci - npm run build - npm i -g serve + npm run start > busola.log & - name: run_tests shell: bash run: | k3d kubeconfig get k3dCluster > tests/integration/fixtures/kubeconfig.yaml - export CYPRESS_DOMAIN=http://localhost:3000 - serve -s build > busola.log & - - pushd backend - npm start > backend.log & - popd + export CYPRESS_DOMAIN=http://localhost:8080 echo "waiting for server to be up..." while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' "$CYPRESS_DOMAIN")" != "200" ]]; do sleep 5; done @@ -76,6 +70,5 @@ jobs: with: name: busola-logs-${{ github.job }} path: | - backend/backend.log busola.log retention-days: 90 diff --git a/.github/workflows/pull-integration-namespace-k3d.yml b/.github/workflows/pull-integration-namespace-k3d.yml index 1acd4901c4..073151997c 100644 --- a/.github/workflows/pull-integration-namespace-k3d.yml +++ b/.github/workflows/pull-integration-namespace-k3d.yml @@ -44,19 +44,13 @@ jobs: run: | set -e npm ci - npm run build - npm i -g serve + npm run start > busola.log & - name: run_tests shell: bash run: | k3d kubeconfig get k3dCluster > tests/integration/fixtures/kubeconfig.yaml - export CYPRESS_DOMAIN=http://localhost:3000 - serve -s build > busola.log & + export CYPRESS_DOMAIN=http://localhost:8080 - pushd backend - npm start > backend.log & - popd - echo "waiting for server to be up..." while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' "$CYPRESS_DOMAIN")" != "200" ]]; do sleep 5; done sleep 10 @@ -76,6 +70,5 @@ jobs: with: name: busola-logs-${{ github.job }} path: | - backend/backend.log busola.log retention-days: 90 diff --git a/.github/workflows/pull-lighthouse.yml b/.github/workflows/pull-lighthouse.yml index 011d3dc150..7095573eaf 100644 --- a/.github/workflows/pull-lighthouse.yml +++ b/.github/workflows/pull-lighthouse.yml @@ -37,18 +37,12 @@ jobs: run: | set -e npm ci - npm run build - npm i -g serve + npm run start > busola.log & - name: run_tests shell: bash run: | k3d kubeconfig get k3dCluster > tests/lighthouse/fixtures/kubeconfig.yaml - export DOMAIN=http://localhost:3000 - serve -s build > busola.log & - - pushd backend - npm start > backend.log & - popd + export DOMAIN=http://localhost:8080 echo "waiting for server to be up..." while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' "$DOMAIN")" != "200" ]]; do sleep 5; done @@ -62,6 +56,5 @@ jobs: with: name: busola-logs-${{ github.job }} path: | - backend/backend.log busola.log retention-days: 90 diff --git a/Makefile b/Makefile index bb245f942f..a9dedf5b27 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,9 @@ -IMG_NAME = busola-web -LOCAL_IMG_NAME = busola -IMG = $(DOCKER_PUSH_REPOSITORY)$(DOCKER_PUSH_DIRECTORY)/$(IMG_NAME) -LOCAL_IMG = $(DOCKER_PUSH_REPOSITORY)$(DOCKER_PUSH_DIRECTORY)/$(LOCAL_IMG_NAME) -KYMA_DASHBOARD_IMG = $(DOCKER_PUSH_REPOSITORY)$(DOCKER_PUSH_DIRECTORY)/$(KYMA_DASHBOARD_IMG_NAME) -TAG = $(DOCKER_TAG) +APP_NAME = busola +.DEFAULT_GOAL=help + +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + .PHONY: resolve resolve: @@ -21,30 +21,12 @@ release: build-image push-image release-local: build-image-local push-image-local -build-image: - docker build -t $(IMG_NAME) -f Dockerfile . - -build-image-local: - docker build -t $(LOCAL_IMG_NAME) -f Dockerfile.local . - -push-image: - docker tag $(IMG_NAME) $(IMG):$(TAG) - docker push $(IMG):$(TAG) -ifeq ($(JOB_TYPE), postsubmit) - @echo "Sign image with Cosign" - cosign version - cosign sign -key ${KMS_KEY_URL} $(REPO)$(IMG):$(TAG) -else - @echo "Image signing skipped" -endif - -push-image-local: - docker tag $(LOCAL_IMG_NAME) $(LOCAL_IMG):$(TAG) - docker push $(LOCAL_IMG):$(TAG) -ifeq ($(JOB_TYPE), postsubmit) - @echo "Tag image with latest" - docker tag $(LOCAL_IMG_NAME) $(LOCAL_IMG):latest - docker push $(LOCAL_IMG):latest -else - @echo "Image tagging with latest skipped" -endif +build-image: ## Build busola backend image + docker build -t $(APP_NAME) -f Dockerfile . + +install-busola-k3d: build-image ## Build busola web image and install it on local k3d cluster + $(eval HASH_TAG=$(shell docker images $(APP_NAME):latest --quiet)) + docker tag $(APP_NAME) $(APP_NAME):$(HASH_TAG) + + k3d image import $(APP_NAME):$(HASH_TAG) -c kyma + kubectl set image deployment busola busola=$(APP_NAME):$(HASH_TAG) diff --git a/README.md b/README.md index cd398ab3de..7e1a6e5259 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ For the information on how to run tests and configure them, go to the [`tests`]( docker run --rm -it -p 3001:3001 -v :/app/core-ui/kubeconfig/ --pid=host --name busola europe-docker.pkg.dev/kyma-project/prod/busola:latest ``` -2. When you open Busola in your browser, go to `http://localhost:3001?kubeconfigID={YOUR_KUBECONFIG_FILE_NAME}`. Busola will try to download that file and add it for your Busola instance. +2. When you open Busola in your browser, visit `http://localhost:3001?kubeconfigID={YOUR_KUBECONFIG_FILE_NAME}`. Busola will try to download that file and add it for your Busola instance. ### Set active environment @@ -178,6 +178,84 @@ For the information on how to run tests and configure them, go to the [`tests`]( docker run --rm -it -p 3001:3001 -v :/app/core-ui/environments/ --env ENVIRONMENT={your-env} --pid=host --name busola europe-docker.pkg.dev/kyma-project/prod/busola:latest ``` +## Deploy Busola in the Kubernetes Cluster + +To install Busola in the Kubernetes cluster, run: + +```shell +(cd resources && kustomize build base/ | kubectl apply -f- ) +``` + +To install Busola using a specific environment configuration, set the `ENVIRONMENT` shell environment variable and run: + +```shell +(cd resources && kustomize build environments/${ENVIRONMENT} | kubectl apply -f- ) +``` + +## Access Busola Installed on Kubernetes + +### kubectl + +The simplest method that always works is to use the capabilities of kubectl. + +```shell +kubectl port-forward services/busola 3001:3001 +``` + +### k3d + +Prerequisites: + +- K3d with exposed loadbalancer on port 80. + > **TIP:** To create K3d with exposed load balancer run: `k3d cluster create -p "80:80@loadbalancer"`. + > See [Exposing Services](https://k3d.io/v5.6.3/usage/exposing_services/) for more details. + +1. Install Ingress resources: + +```shell +(cd resources && kubectl apply -f ingress/ingress.yaml) +``` + +2. Visit `localhost` + +#### Connect to the k3d Cluster With Busola Installed. + +To connect to the same k3d cluster with Busola installed, download kubeconfig and change the cluster server address to `https://kubernetes.default.svc:443`. + +Use shell to quickly process the file. + +Prerequisites: + +- [yq](https://mikefarah.gitbook.io/yq) + +Set the `K3D_CLUSTER_NAME` shell environment variable to the name of your cluster and run: + +```shell +k3d kubeconfig get ${K3D_CLUSTER_NAME} > k3d-kubeconfig.yaml +yq --inplace '.clusters[].cluster.server = "https://kubernetes.default.svc:443"' k3d-kubeconfig.yaml +``` + +### Kubernetes Cluster with Istio Installed + +Prerequisites: + +- Sidecar Proxy injection enabled, see [Enable Istio Sidecar Proxy Injection](https://kyma-project.io/#/istio/user/tutorials/01-40-enable-sidecar-injection?id=enable-istio-sidecar-proxy-injection). +- The API Gateway module installed, see [Quick Install](https://kyma-project.io/#/02-get-started/01-quick-install) + +1. Install the Istio required resources: + +```shell +(cd resources && kubectl apply -k istio) +``` + +2. To get the Busola address, run: + +```shell +kubectl get virtualservices.networking.istio.io +``` + +and find the `busola-***` virtual service. Under `HOSTS,` there is an address where you can access the Busola page. + ## Troubleshooting > **TIP:** To solve most of the problems with Busola development, clear the browser cache or do a hard refresh of the website. diff --git a/backend/Makefile b/backend/Makefile index fe9ee86c7f..28e836f2e5 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -1,12 +1,6 @@ -APP_NAME = busola-backend -IMG_NAME := $(DOCKER_PUSH_REPOSITORY)$(DOCKER_PUSH_DIRECTORY)/$(APP_NAME) -TAG := $(DOCKER_TAG) - - -build-image: - docker build -t $(APP_NAME) -f Dockerfile . -push-image: - docker tag $(APP_NAME):latest $(IMG_NAME):$(TAG) - docker push $(IMG_NAME):$(TAG) - -release: build-image push-image +##@ General +.DEFAULT_GOAL=help +.PHONY: help +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) diff --git a/busola.log b/busola.log new file mode 100644 index 0000000000..dbb509fe37 --- /dev/null +++ b/busola.log @@ -0,0 +1,53 @@ + +> @kyma-project/busola@0.0.1-rc.8 start +> concurrently -c cyan,green npm:busola npm:backend + +[busola] +[busola] > @kyma-project/busola@0.0.1-rc.8 busola +[busola] > npm run copy-themes; BROWSER=none GENERATE_SOURCEMAP=false vite +[busola] +[backend] +[backend] > @kyma-project/busola@0.0.1-rc.8 backend +[backend] > cd backend && npm run start +[backend] +[busola] +[busola] > @kyma-project/busola@0.0.1-rc.8 copy-themes +[busola] > cp node_modules/@sap-theming/theming-base-content/content/Base/baseLib/sap_horizon/css_variables.css public/themes/@sap-theming/default.css; for theme in hcb dark hcw ; do cp node_modules/@sap-theming/theming-base-content/content/Base/baseLib/sap_horizon_$theme/css_variables.css public/themes/@sap-theming/$theme.css ; done +[busola] +[backend] +[backend] > backend@1.0.0 start +[backend] > SSL_CERT_FILE=certs.pem NODE_ENV=development nodemon --exec babel-node index.js +[backend] +[backend] [nodemon] 2.0.22 +[backend] [nodemon] to restart at any time, enter `rs` +[backend] [nodemon] watching path(s): *.* +[backend] [nodemon] watching extensions: js,mjs,json +[backend] [nodemon] starting `babel-node index.js` +[busola] Forced re-optimization of dependencies +[busola] [vite-plugin-static-copy] Collected 1 items. +[busola] +[busola] VITE v5.4.3 ready in 1274 ms +[busola] +[busola] ➜ Local: http://localhost:8080/ +[busola] ➜ Network: use --host to expose +[backend] node:events:496 +[backend] throw er; // Unhandled 'error' event +[backend] ^ +[backend] +[backend] Error: listen EADDRINUSE: address already in use 0.0.0.0:3001 +[backend] at Server.setupListenHandle [as _listen2] (node:net:1897:16) +[backend] at listenInCluster (node:net:1945:12) +[backend] at doListen (node:net:2109:7) +[backend] at processTicksAndRejections (node:internal/process/task_queues:83:21) +[backend] Emitted 'error' event on Server instance at: +[backend] at emitErrorNT (node:net:1924:8) +[backend] at processTicksAndRejections (node:internal/process/task_queues:82:21) { +[backend] code: 'EADDRINUSE', +[backend] errno: -98, +[backend] syscall: 'listen', +[backend] address: '0.0.0.0', +[backend] port: 3001 +[backend] } +[backend] +[backend] Node.js v20.12.1 +[backend] [nodemon] app crashed - waiting for file changes before starting... diff --git a/examples/custom-extension/script.js b/examples/custom-extension/script.js index bc3c6bd601..841aeacbc8 100644 --- a/examples/custom-extension/script.js +++ b/examples/custom-extension/script.js @@ -6,9 +6,7 @@ function fetchWrapper(url, options = {}) { } function proxyFetch(url, options = {}) { - const baseUrl = window.location.hostname.startsWith('localhost') - ? 'http://localhost:3001/proxy' - : '/proxy'; + const baseUrl = '/proxy'; const encodedUrl = encodeURIComponent(url); const proxyUrl = `${baseUrl}?url=${encodedUrl}`; return fetch(proxyUrl, options); diff --git a/resources/base/resource-validation/rule-sets/datree/rules.yaml b/resource-validation/rule-sets/datree/rules.yaml similarity index 100% rename from resources/base/resource-validation/rule-sets/datree/rules.yaml rename to resource-validation/rule-sets/datree/rules.yaml diff --git a/resources/base/resource-validation/rule-sets/default/policies.yaml b/resource-validation/rule-sets/default/policies.yaml similarity index 100% rename from resources/base/resource-validation/rule-sets/default/policies.yaml rename to resource-validation/rule-sets/default/policies.yaml diff --git a/resources/base/resource-validation/rule-sets/kubernetes-pod-security-standards/policies.yaml b/resource-validation/rule-sets/kubernetes-pod-security-standards/policies.yaml similarity index 100% rename from resources/base/resource-validation/rule-sets/kubernetes-pod-security-standards/policies.yaml rename to resource-validation/rule-sets/kubernetes-pod-security-standards/policies.yaml diff --git a/resources/base/resource-validation/rule-sets/kubernetes-pod-security-standards/rules.yaml b/resource-validation/rule-sets/kubernetes-pod-security-standards/rules.yaml similarity index 100% rename from resources/base/resource-validation/rule-sets/kubernetes-pod-security-standards/rules.yaml rename to resource-validation/rule-sets/kubernetes-pod-security-standards/rules.yaml diff --git a/resources/base/resource-validation/rulesetSchema.json b/resource-validation/rulesetSchema.json similarity index 100% rename from resources/base/resource-validation/rulesetSchema.json rename to resource-validation/rulesetSchema.json diff --git a/resources/apply-resources-istio.sh b/resources/apply-resources-istio.sh deleted file mode 100755 index f1c10eade5..0000000000 --- a/resources/apply-resources-istio.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -e - -if [ -z "$1" ] ; then - echo "No domain passed as first argument, aborting." - exit 1 -fi - -export DOMAIN=$1 -export NAMESPACE=${2:-busola} -export ENVIRONMENT=$3 -TMP_DIR="../temp/resources" - -./apply-resources.sh "$@" - -envsubst < "${TMP_DIR}"/istio/virtualservice-busola.tpl.yaml > "${TMP_DIR}"/istio/virtualservice-busola.yaml - -kubectl apply -k "${TMP_DIR}"/istio --namespace=$NAMESPACE diff --git a/resources/apply-resources.sh b/resources/apply-resources.sh deleted file mode 100755 index 14739fa646..0000000000 --- a/resources/apply-resources.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -set -e - -if [ -z "$1" ] ; then - echo "No domain passed as first argument, aborting." - exit 1 -fi - -export DOMAIN=$1 -NAMESPACE=${2:-busola} -export ENVIRONMENT=$3 -TMP_DIR="../temp/resources" - - -mkdir -p "${TMP_DIR}" -cp -rf . "${TMP_DIR}" - -kubectl create namespace "${NAMESPACE}" || true -kubectl apply -k "${TMP_DIR}/environments/${ENVIRONMENT}" --namespace="${NAMESPACE}" - -envsubst < "${TMP_DIR}"/ingress/ingress.tpl.yaml > "${TMP_DIR}"/ingress/ingress.yaml -kubectl apply -k "${TMP_DIR}"/ingress --namespace=$NAMESPACE diff --git a/resources/base/backend/deployment.yaml b/resources/base/backend/deployment.yaml deleted file mode 100644 index a017c42574..0000000000 --- a/resources/base/backend/deployment.yaml +++ /dev/null @@ -1,53 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: backend - labels: - app: backend -spec: - replicas: 1 - selector: - matchLabels: - app: backend - strategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 0 - template: - metadata: - labels: - app: backend - spec: - containers: - - name: backend - image: busola-backend - imagePullPolicy: Always - resources: - limits: - cpu: 1 - memory: 1Gi - requests: - cpu: 200m - memory: 128M - securityContext: - allowPrivilegeEscalation: false - privileged: false - ports: - - containerPort: 3001 - name: http-backend - protocol: TCP - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - env: - - name: ADDRESS - value: 0.0.0.0 - volumeMounts: - - name: config - mountPath: /app/config - volumes: - - name: config - configMap: - name: busola-config - items: - - key: config - path: config.yaml diff --git a/resources/base/backend/hpa.yaml b/resources/base/backend/hpa.yaml deleted file mode 100644 index 6b010cd9e1..0000000000 --- a/resources/base/backend/hpa.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: backend - labels: - app: busola -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: backend - minReplicas: 1 - maxReplicas: 11 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 125 - - type: Resource - resource: - name: memory - target: - type: Utilization - averageUtilization: 125 diff --git a/resources/base/backend/service.yaml b/resources/base/backend/service.yaml deleted file mode 100644 index 41b9205d85..0000000000 --- a/resources/base/backend/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: backend - labels: - app: backend -spec: - ports: - - port: 3001 - targetPort: 3001 - protocol: TCP - name: http - selector: - app: backend diff --git a/resources/base/web/deployment.yaml b/resources/base/busola/deployment.yaml similarity index 85% rename from resources/base/web/deployment.yaml rename to resources/base/busola/deployment.yaml index a8a8b1eb5e..2450819668 100644 --- a/resources/base/web/deployment.yaml +++ b/resources/base/busola/deployment.yaml @@ -1,7 +1,7 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: web + name: busola labels: app: busola spec: @@ -16,8 +16,8 @@ spec: spec: containers: - name: busola - image: busola-web - imagePullPolicy: Always + image: busola + imagePullPolicy: IfNotPresent env: - name: ENVIRONMENT valueFrom: @@ -25,18 +25,19 @@ spec: optional: true key: ENVIRONMENT name: environment + volumeMounts: + - name: config + mountPath: /app/core-ui/config resources: requests: cpu: 100m memory: 21Mi ports: - - containerPort: 8080 - volumeMounts: - - name: config - mountPath: /app/core-ui/config + - containerPort: 3001 volumes: - name: config configMap: + optional: true name: busola-config items: - key: config diff --git a/resources/base/web/hpa.yaml b/resources/base/busola/hpa.yaml similarity index 93% rename from resources/base/web/hpa.yaml rename to resources/base/busola/hpa.yaml index d65e500215..9fbdb37d2c 100644 --- a/resources/base/web/hpa.yaml +++ b/resources/base/busola/hpa.yaml @@ -1,14 +1,14 @@ apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: - name: web + name: busola labels: app: busola spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment - name: web + name: busola minReplicas: 1 maxReplicas: 11 metrics: diff --git a/resources/base/backend/kustomization.yaml b/resources/base/busola/kustomization.yaml similarity index 100% rename from resources/base/backend/kustomization.yaml rename to resources/base/busola/kustomization.yaml diff --git a/resources/base/web/service.yaml b/resources/base/busola/service.yaml similarity index 57% rename from resources/base/web/service.yaml rename to resources/base/busola/service.yaml index 95fcfd898e..0168f1c4a2 100644 --- a/resources/base/web/service.yaml +++ b/resources/base/busola/service.yaml @@ -1,13 +1,13 @@ apiVersion: v1 kind: Service metadata: - name: web + name: busola labels: app: busola spec: ports: - - port: 8080 - name: http-web - targetPort: 8080 + - port: 3001 + name: http-busola + targetPort: 3001 selector: app: busola diff --git a/resources/base/extensions-patch/builtin-resource-extensions.configmap.yaml b/resources/base/extensions-patch/builtin-resource-extensions.configmap.yaml deleted file mode 100644 index 7058c48da1..0000000000 --- a/resources/base/extensions-patch/builtin-resource-extensions.configmap.yaml +++ /dev/null @@ -1,9 +0,0 @@ -kind: ConfigMap -apiVersion: v1 -metadata: - name: busola-builtin-resource-extensions - labels: - app.kubernetes.io/name: busola-builtin-resource-extensions - busola.io/extension: builtin-resources -data: - extensions.yaml: [] diff --git a/resources/base/extensions-patch/kustomization.yaml b/resources/base/extensions-patch/kustomization.yaml deleted file mode 100644 index 3a5d82821b..0000000000 --- a/resources/base/extensions-patch/kustomization.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - builtin-resource-extensions.configmap.yaml -patchesJson6902: - - target: - group: apps - version: v1 - kind: Deployment - name: web - path: web-deployment.patch.yaml - -bases: - - ../web diff --git a/resources/base/extensions-patch/web-deployment.patch.yaml b/resources/base/extensions-patch/web-deployment.patch.yaml deleted file mode 100644 index e90f94506b..0000000000 --- a/resources/base/extensions-patch/web-deployment.patch.yaml +++ /dev/null @@ -1,14 +0,0 @@ -- op: add - path: /spec/template/spec/containers/0/volumeMounts/1 - value: - name: extensions - mountPath: /app/core/assets/extensions -- op: add - path: /spec/template/spec/volumes/1 - value: - name: extensions - configMap: - name: busola-builtin-resource-extensions - items: - - key: extensions.yaml - path: extensions.yaml diff --git a/resources/base/kustomization.yaml b/resources/base/kustomization.yaml index 446976a60d..c325f63b5c 100644 --- a/resources/base/kustomization.yaml +++ b/resources/base/kustomization.yaml @@ -1,12 +1,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - backend - - web + - busola images: - - name: busola-web - newName: europe-docker.pkg.dev/kyma-project/prod/busola-web - newTag: latest - - name: busola-backend - newName: europe-docker.pkg.dev/kyma-project/prod/busola-backend + - name: busola + newName: europe-docker.pkg.dev/kyma-project/prod/busola newTag: latest diff --git a/resources/base/web/configmap.yaml b/resources/base/web/configmap.yaml deleted file mode 100644 index 94677f8b59..0000000000 --- a/resources/base/web/configmap.yaml +++ /dev/null @@ -1,61 +0,0 @@ -kind: ConfigMap -apiVersion: v1 -metadata: - name: busola-config -data: - config: > - { - "config": { - "storage": "localStorage", - "features": { - "LEGAL_LINKS": { - "config": { - "legal-disclosure": { - "default": "https://www.sap.com/corporate/en/legal/impressum.html", - "de": "https://www.sap.com/corporate/de/legal/impressum.html" - }, - "privacy": { - "default": - "https://help.sap.com/viewer/82bdf2271c6041f79387c122147cf774/Cloud/en-US" - }, - "copyright": { - "default": "https://www.sap.com/corporate/en/legal/copyright.html", - "de": "https://www.sap.com/corporate/de/legal/copyright.html" - }, - "trademark": { - "default": "https://www.sap.com/corporate/en/legal/trademark.html", - "de": "https://www.sap.com/corporate/de/legal/trademark.html" - } - } - }, - "GET_HELP_LINKS": { - "config": { - "kyma-project-io": { - "default": "https://kyma-project.io" - }, - "help-sap-com": { - "default": "https://help.sap.com" - } - } - }, - "SENTRY": { - "isEnabled": true, - "selectors": [], - "config": { - "dsn": "" - } - }, - "KUBECONFIG_ID": { - "config": { - "kubeconfigUrl": "/kubeconfig" - } - }, - "GZIP": { - "isEnabled": true - }, - "VISUAL_RESOURCES": { - "isEnabled": true - } - } - } - } diff --git a/resources/base/web/kustomization.yaml b/resources/base/web/kustomization.yaml deleted file mode 100644 index 8c9f6e654b..0000000000 --- a/resources/base/web/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - configmap.yaml - - deployment.yaml - - hpa.yaml - - service.yaml diff --git a/resources/ingress/ingress.tpl.yaml b/resources/ingress/ingress.tpl.yaml deleted file mode 100644 index afda2cee0a..0000000000 --- a/resources/ingress/ingress.tpl.yaml +++ /dev/null @@ -1,29 +0,0 @@ -kind: Ingress -apiVersion: networking.k8s.io/v1 -metadata: - name: ingress-busola - annotations: - nginx.ingress.kubernetes.io/rewrite-target: /$1 - nginx.ingress.kubernetes.io/force-ssl-redirect: 'true' - nginx.ingress.kubernetes.io/server-snippet: 'server_tokens off;' # hide nginx version - nginx.ingress.kubernetes.io/enable-cors: 'false' -spec: - ingressClassName: nginx - rules: - - host: $DOMAIN - http: - paths: - - backend: - service: - name: web - port: - number: 8080 - path: /(.*) - pathType: Prefix - - backend: - service: - name: backend - port: - number: 3001 - path: /backend(?:/|$)(.*) - pathType: Prefix diff --git a/resources/ingress/ingress.yaml b/resources/ingress/ingress.yaml new file mode 100644 index 0000000000..c3f74defff --- /dev/null +++ b/resources/ingress/ingress.yaml @@ -0,0 +1,15 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1 +metadata: + name: busola +spec: + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: busola + port: + number: 3001 diff --git a/resources/ingress/ingressClass.yaml b/resources/ingress/ingressClass.yaml deleted file mode 100644 index a5feb7a495..0000000000 --- a/resources/ingress/ingressClass.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: IngressClass -metadata: - labels: - app.kubernetes.io/component: controller - name: nginx - annotations: - ingressclass.kubernetes.io/is-default-class: 'true' -spec: - controller: k8s.io/ingress-nginx diff --git a/resources/istio/apirule.yaml b/resources/istio/apirule.yaml new file mode 100644 index 0000000000..203e3a74d7 --- /dev/null +++ b/resources/istio/apirule.yaml @@ -0,0 +1,15 @@ +apiVersion: gateway.kyma-project.io/v2alpha1 +kind: APIRule +metadata: + name: busola +spec: + gateway: kyma-system/kyma-gateway + hosts: + - busola + service: + name: busola + port: 3001 + rules: + - path: /{**} + methods: ['GET'] + noAuth: true diff --git a/resources/istio/destinationrule-busola-backend.yaml b/resources/istio/destinationrule-busola-backend.yaml deleted file mode 100644 index 2314cf3e16..0000000000 --- a/resources/istio/destinationrule-busola-backend.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: backend -spec: - host: backend - trafficPolicy: - tls: - mode: SIMPLE diff --git a/resources/istio/kustomization.yaml b/resources/istio/kustomization.yaml index ff3b2d8a2b..579346e571 100644 --- a/resources/istio/kustomization.yaml +++ b/resources/istio/kustomization.yaml @@ -1,8 +1,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - virtualservice-busola.yaml - # Add the destinationrule for TLS into the backend pod. - # This will tell the istio sidecar to use TLS to connect to the backend service. - # For this to work, you need to enable TLS in the backend. See docs/install-kyma-dashboard-manually.md for more information. - # - destinationrule-busola-backend.yaml + - apirule.yaml diff --git a/resources/istio/virtualservice-busola.tpl.yaml b/resources/istio/virtualservice-busola.tpl.yaml deleted file mode 100644 index f771f2e728..0000000000 --- a/resources/istio/virtualservice-busola.tpl.yaml +++ /dev/null @@ -1,21 +0,0 @@ -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: busola -spec: - hosts: - - $DOMAIN - gateways: - - kyma-system/kyma-gateway - http: - - name: 'backend-route' - match: - - uri: - prefix: '/backend' - route: - - destination: - host: backend.$NAMESPACE.svc.cluster.local - - name: 'web-route' - route: - - destination: - host: web.$NAMESPACE.svc.cluster.local diff --git a/src/components/Gardener/useGardenerLoginFunction.tsx b/src/components/Gardener/useGardenerLoginFunction.tsx index e7a18cff84..5ba0bc7fe1 100644 --- a/src/components/Gardener/useGardenerLoginFunction.tsx +++ b/src/components/Gardener/useGardenerLoginFunction.tsx @@ -21,12 +21,12 @@ async function failFastFetch( } export function useGardenerLogin(setReport: (report: string) => void) { - const { backendAddress } = getClusterConfig(); const clustersInfo = useClustersInfo(); const getAvailableProjects = async ( fetchHeaders: HeadersInit, ): Promise => { + const { backendAddress } = getClusterConfig(); type SSRResult = { status: { resourceRules: PermissionSet[] }; }; @@ -63,6 +63,8 @@ export function useGardenerLogin(setReport: (report: string) => void) { fetchHeaders: HeadersInit, availableProjects: string[], ) => { + const { backendAddress } = getClusterConfig(); + type ShootsResult = { items: K8sResource[]; }; diff --git a/src/shared/hooks/BackendAPI/useFetch.ts b/src/shared/hooks/BackendAPI/useFetch.ts index 5acc7f7e9a..bbf102fd1c 100644 --- a/src/shared/hooks/BackendAPI/useFetch.ts +++ b/src/shared/hooks/BackendAPI/useFetch.ts @@ -5,7 +5,7 @@ import { throwHttpError } from 'shared/hooks/BackendAPI/config'; import { authDataState, AuthDataState } from '../../../state/authDataAtom'; import { getClusterConfig } from '../../../state/utils/getBackendInfo'; -import { clusterState, ActiveClusterState } from '../../../state/clusterAtom'; +import { ActiveClusterState, clusterState } from '../../../state/clusterAtom'; export type FetchFn = ({ relativeUrl, diff --git a/src/shared/utils/env.ts b/src/shared/utils/env.ts index 55bbe3fc38..ced6aaf9cc 100644 --- a/src/shared/utils/env.ts +++ b/src/shared/utils/env.ts @@ -1,15 +1,36 @@ import joinPaths from './path'; -export default async function getConfigDir(): Promise { +export enum Envs { + ENVIRONMENT = 'ENVIRONMENT', +} + +async function getEnv(env: Envs): Promise { const input = await fetchActiveEnv(); - const envVar = input.trim().split('='); - if (envVar?.length === 2 && envVar[1]) { - const envDir = envVar[1].trim(); - return joinPaths('environments', envDir); + const envs = readEnv(input); + const desiredEnv = envs.get(env); + return desiredEnv ? desiredEnv : ''; +} + +export async function getConfigDir(): Promise { + const environment = await getEnv(Envs.ENVIRONMENT); + if (environment) { + return joinPaths('environments', environment); } return ''; } +function readEnv(input: string): Map { + return new Map( + input.split('\n').map(value => { + const envVar = value.trim().split('='); + if (envVar?.length === 2 && envVar[1]) { + return [envVar[0], envVar[1]]; + } + return ['', '']; + }), + ); +} + async function fetchActiveEnv(): Promise { const envResponse = await fetch('/active.env'); return envResponse.text(); diff --git a/src/shared/utils/getClusterConfig.js b/src/shared/utils/getClusterConfig.js deleted file mode 100644 index c4bf6398fa..0000000000 --- a/src/shared/utils/getClusterConfig.js +++ /dev/null @@ -1,15 +0,0 @@ -const domain = window.location.hostname; - -function getBackendAddress() { - // dev busola - if (window.location.hostname.startsWith('localhost')) { - return 'http://localhost:3001/backend'; - // on cluster - } else { - return '/backend'; - } -} -export const getClusterConfig = () => ({ - domain, - backendAddress: getBackendAddress(), -}); diff --git a/src/state/configuration/configurationAtom.ts b/src/state/configuration/configurationAtom.ts index c36844b15c..bc4cfbc0c6 100644 --- a/src/state/configuration/configurationAtom.ts +++ b/src/state/configuration/configurationAtom.ts @@ -10,7 +10,7 @@ import { ConfigFeatureList } from '../types'; import { apiGroupState } from '../discoverability/apiGroupsSelector'; import { getFeatures } from './getFeatures'; import { FetchFn } from 'shared/hooks/BackendAPI/useFetch'; -import getConfigDir from 'shared/utils/env'; +import { getConfigDir } from 'shared/utils/env'; type Configuration = { features?: ConfigFeatureList; diff --git a/src/state/navigation/extensionsAtom.ts b/src/state/navigation/extensionsAtom.ts index 426102e79e..c79f55b093 100644 --- a/src/state/navigation/extensionsAtom.ts +++ b/src/state/navigation/extensionsAtom.ts @@ -26,7 +26,7 @@ import pluralize from 'pluralize'; import { useGet } from 'shared/hooks/BackendAPI/useGet'; import { CustomResourceDefinition } from 'command-pallette/CommandPalletteUI/handlers/crHandler'; import { createPostFn } from 'shared/hooks/BackendAPI/usePost'; -import getConfigDir from 'shared/utils/env'; +import { getConfigDir } from 'shared/utils/env'; /* the order of the overwrting extensions @@ -435,7 +435,10 @@ export const useGetExtensions = () => { relativeUrl: url, init: options, abortController: options?.signal - ? { signal: options?.signal, abort: () => {} } + ? { + signal: options?.signal, + abort: () => {}, + } : undefined, }); } diff --git a/src/state/utils/getBackendInfo.ts b/src/state/utils/getBackendInfo.ts index d5ee6e5fec..d295ce51e2 100644 --- a/src/state/utils/getBackendInfo.ts +++ b/src/state/utils/getBackendInfo.ts @@ -1,22 +1,6 @@ const domain = window.location.hostname; -const getBackendAddress = () => { - // local busola - needed for e2e tests to work locally - if ( - window.location.hostname.startsWith('localhost') && - window.location.port === '8080' && - !process.env.IS_DOCKER - ) { - return 'http://127.0.0.1:3001/backend'; - // dev busola - } else if (window.location.hostname.startsWith('localhost')) { - return 'http://localhost:3001/backend'; - // on cluster - } else { - return '/backend'; - } -}; export const getClusterConfig = () => ({ domain, - backendAddress: getBackendAddress(), + backendAddress: '/backend', }); diff --git a/tests/lighthouse/lighthouse.spec.js b/tests/lighthouse/lighthouse.spec.js index b0716c54b4..ad70ba3459 100644 --- a/tests/lighthouse/lighthouse.spec.js +++ b/tests/lighthouse/lighthouse.spec.js @@ -3,9 +3,7 @@ import { playAudit } from 'playwright-lighthouse'; import { chromium } from 'playwright'; import { tmpdir } from 'os'; -const ADDRESS = process.env.LOCAL - ? 'http://localhost:8080' - : 'http://localhost:3000'; +const ADDRESS = 'http://localhost:8080'; test('Busola Lighthouse audit', async () => { const context = await chromium.launchPersistentContext(tmpdir(), { diff --git a/vite.config.mts b/vite.config.mts index 0e88a8863e..d056603ede 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -15,6 +15,13 @@ export default defineConfig({ }, server: { port: 8080, + proxy: { + // with options + '^/backend/.*': { + target: 'http://localhost:3001', + changeOrigin: true, + }, + }, }, plugins: [ { @@ -38,11 +45,11 @@ export default defineConfig({ viteStaticCopy({ targets: [ { - src: 'resources/base/resource-validation/rule-sets/**/*.yaml', + src: 'resource-validation/rule-sets/**/*.yaml', dest: 'resource-validation', rename: 'rule-set.yaml', transform() { - return mergeYamlFiles('resources/base/resource-validation/rule-sets/**/*.yaml'); + return mergeYamlFiles('resource-validation/rule-sets/**/*.yaml'); }, }, ], @@ -60,7 +67,7 @@ export default defineConfig({ }, }, include: [ - '@openapi-contrib/openapi-schema-to-json-schema', + '@openapi-contrib/openapi-schema-to-json-schema', '@stoplight/json-ref-resolver', 'monaco-yaml/yaml.worker.js' ]