diff --git a/Makefile b/Makefile index fdabdc74..c63455fc 100644 --- a/Makefile +++ b/Makefile @@ -127,6 +127,10 @@ inventory-up-sso: inventory-up-kafka: ./scripts/start-inventory-kafka.sh +.PHONY: inventory-up-kind +inventory-up-kind: + ./scripts/start-inventory-kind.sh + .PHONY: get-token get-token: ./scripts/get-token.sh @@ -143,6 +147,10 @@ inventory-down-sso: inventory-down-kafka: ./scripts/stop-inventory-kafka.sh +.PHONY: inventory-down-kind +inventory-down-kind: + ./scripts/stop-inventory-kind.sh + .PHONY: run # run api locally run: build diff --git a/deploy/kessel-inventory.yaml b/deploy/kessel-inventory.yaml index 60846dbd..57719d60 100644 --- a/deploy/kessel-inventory.yaml +++ b/deploy/kessel-inventory.yaml @@ -18,11 +18,11 @@ objects: replicas: ${{REPLICAS}} podSpec: initContainers: - - name: migration - image: ${INVENTORY_IMAGE}:${IMAGE_TAG} - command: ["inventory-api"] - args: ["migrate"] - inheritEnv: true + - name: migration + image: ${INVENTORY_IMAGE}:${IMAGE_TAG} + command: ["inventory-api"] + args: ["migrate"] + inheritEnv: true image: ${INVENTORY_IMAGE}:${IMAGE_TAG} command: ["inventory-api"] args: ["serve"] @@ -35,15 +35,15 @@ objects: path: /api/inventory/v1/readyz port: 8000 env: - - name: CLOWDER_ENABLED - value: "true" - - name: INVENTORY_API_CONFIG - value: "/inventory/inventory-api-config.yaml" - - name: PGDATA - value: /temp/data + - name: CLOWDER_ENABLED + value: "true" + - name: INVENTORY_API_CONFIG + value: "/inventory/inventory-api-config.yaml" + - name: PGDATA + value: /temp/data volumeMounts: - - name: config-volume - mountPath: "/inventory" + - name: config-volume + mountPath: "/inventory" volumes: - name: config-volume secret: diff --git a/deploy/kind/e2e/e2e-batch.yaml b/deploy/kind/e2e/e2e-batch.yaml new file mode 100644 index 00000000..a6224974 --- /dev/null +++ b/deploy/kind/e2e/e2e-batch.yaml @@ -0,0 +1,31 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: e2e-inventory-http-tests +spec: + template: + spec: + initContainers: + - name: wait-for-inventory + image: curlimages/curl:latest + command: + - /bin/sh + - "-c" + - | + echo "Waiting for kessel-inventory-service to be ready..." + while ! curl -s http://kessel-inventory-service/api/inventory/v1/readyz; do + echo "Inventory service not ready yet. Sleeping for 5 seconds..." + sleep 5 + done + echo "Inventory service is ready!" + containers: + - name: e2e-http-tests + image: localhost/inventory-e2e-tests:e2e-test + env: + - name: INV_HTTP_URL + value: "kessel-inventory-service:80" + - name: KAFKA_BOOTSTRAP_SERVERS + value: "localhost:9092" + command: ["/usr/local/bin/e2e-inventory-tests", "-test.v"] + restartPolicy: Never + backoffLimit: 4 diff --git a/deploy/kind/inventory/invdatabase.yaml b/deploy/kind/inventory/invdatabase.yaml new file mode 100644 index 00000000..1bbdbb45 --- /dev/null +++ b/deploy/kind/inventory/invdatabase.yaml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: invdatabase + labels: + app: invdatabase +spec: + replicas: 1 + selector: + matchLabels: + app: invdatabase + template: + metadata: + labels: + app: invdatabase + spec: + containers: + - name: postgres + image: postgres:latest + env: + - name: POSTGRES_DB + value: spicedb + - name: POSTGRES_USER + value: postgres + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: inventory-api-config + key: db_password + ports: + - containerPort: 5432 +--- +apiVersion: v1 +kind: Service +metadata: + name: invdatabase + labels: + app: invdatabase +spec: + ports: + - port: 5433 + targetPort: 5432 + selector: + app: invdatabase + type: ClusterIP diff --git a/deploy/kind/inventory/kessel-inventory.yaml b/deploy/kind/inventory/kessel-inventory.yaml new file mode 100644 index 00000000..91c5a9c4 --- /dev/null +++ b/deploy/kind/inventory/kessel-inventory.yaml @@ -0,0 +1,163 @@ +# Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kessel-inventory + labels: + app: kessel-inventory +spec: + replicas: 1 + selector: + matchLabels: + app: kessel-inventory + template: + metadata: + labels: + app: kessel-inventory + spec: + initContainers: + - name: migration + image: quay.io/redhat-services-prod/project-kessel-tenant/kessel-inventory/inventory-api:latest + command: + - /bin/sh + - "-c" + - | + echo "Waiting for PostgreSQL to be ready..." + sleep 20 + + inventory-api migrate + env: + - name: CLOWDER_ENABLED + value: "true" + - name: INVENTORY_API_CONFIG + value: "/inventory/inventory-api-config.yaml" + - name: PGDATA + value: /temp/data + - name: POSTGRES_HOST + value: "invdatabase" + - name: POSTGRES_PORT + value: "5433" + - name: POSTGRES_USER + value: "postgres" + - name: POSTGRES_DB + value: "spicedb" + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: inventory-api-config + key: db_password + volumeMounts: + - name: config-volume + mountPath: "/inventory" + containers: + - name: api + image: quay.io/redhat-services-prod/project-kessel-tenant/kessel-inventory/inventory-api:latest + command: ["inventory-api"] + args: ["serve"] + env: + - name: CLOWDER_ENABLED + value: "true" + - name: INVENTORY_API_CONFIG + value: "/inventory/inventory-api-config.yaml" + - name: PGDATA + value: /temp/data + - name: POSTGRES_HOST + value: "invdatabase" + - name: POSTGRES_PORT + value: "5433" + - name: POSTGRES_USER + value: "postgres" + - name: POSTGRES_DB + value: "spicedb" + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: inventory-api-config + key: db_password + livenessProbe: + httpGet: + path: /api/inventory/v1/livez + port: 8081 + readinessProbe: + httpGet: + path: /api/inventory/v1/readyz + port: 8081 + volumeMounts: + - name: psks-volume + mountPath: "/psks.yaml" + subPath: psks.yaml + - name: config-volume + mountPath: "/inventory" + volumes: + - name: config-volume + secret: + secretName: inventory-api-config + - name: psks-volume + configMap: + name: inventory-api-psks +--- +# Services +apiVersion: v1 +kind: Service +metadata: + name: kessel-inventory-service + labels: + app: kessel-inventory +spec: + selector: + app: kessel-inventory + ports: + - protocol: TCP + port: 80 + targetPort: 8081 +--- +# PodDisruptionBudget +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: kessel-inventory-api-pdb + labels: + app: kessel-inventory +spec: + minAvailable: 1 + selector: + matchLabels: + app: kessel-inventory +--- +# Secret +apiVersion: v1 +kind: Secret +metadata: + name: inventory-api-config +type: Opaque +stringData: + inventory-api-config.yaml: | + server: + http: + address: 0.0.0.0:8081 + grpc: + address: 0.0.0.0:9081 + authn: + psk: + pre-shared-key-file: /psks.yaml + authz: + impl: allow-all + eventing: + eventer: stdout + kafka: + storage: + database: postgres + sqlite3: + dsn: inventory.db + postgres: + host: "invdatabase" + port: "5433" + user: "postgres" + password: "yPsw5e6ab4bvAGe5H" + dbname: "spicedb" + log: + level: "debug" + livez: true + readyz: true + db_password: "yPsw5e6ab4bvAGe5H" + diff --git a/deploy/kind/inventory/strimzi.yaml b/deploy/kind/inventory/strimzi.yaml new file mode 100644 index 00000000..e3de6219 --- /dev/null +++ b/deploy/kind/inventory/strimzi.yaml @@ -0,0 +1,35 @@ +# Taken from: https://github.com/strimzi/strimzi-kafka-operator/blob/main/examples/kafka/kafka-ephemeral.yaml +apiVersion: kafka.strimzi.io/v1beta2 +kind: Kafka +metadata: + name: my-cluster +spec: + kafka: + version: 3.8.0 + replicas: 1 + listeners: + - name: plain + port: 9092 + type: internal + tls: false + - name: tls + port: 9093 + type: internal + tls: true + config: + offsets.topic.replication.factor: 3 + transaction.state.log.replication.factor: 3 + transaction.state.log.min.isr: 2 + default.replication.factor: 3 + min.insync.replicas: 2 + inter.broker.protocol.version: "3.8" + storage: + type: ephemeral + zookeeper: + replicas: 1 + storage: + type: ephemeral + entityOperator: + topicOperator: {} + userOperator: {} + diff --git a/scripts/start-inventory-kind.sh b/scripts/start-inventory-kind.sh new file mode 100755 index 00000000..936a62c9 --- /dev/null +++ b/scripts/start-inventory-kind.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -e + +source ./scripts/check_docker_podman.sh + +kind create cluster --name inventory-cluster + +kubectl create secret docker-registry redhat-registry-secret \ + --docker-server=$DOCKER_SERVER \ + --docker-username=$QUAY_USERNAME \ + --docker-password=$QUAY_PASSWORD \ + --docker-email=$QUAY_EMAIL + +kubectl create serviceaccount default +kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "redhat-registry-secret"}]}' + +# build/tag image +${DOCKER} build -t localhost/inventory-api:latest -f Dockerfile . +${DOCKER} build -t localhost/inventory-e2e-tests:latest -f Dockerfile-e2e . + +${DOCKER} tag localhost/inventory-api:latest localhost/inventory-api:e2e-test +${DOCKER} tag localhost/inventory-e2e-tests:latest localhost/inventory-e2e-tests:e2e-test + +rm -rf inventory-api.tar +rm -rf inventory-e2e-tests.tar + +${DOCKER} save -o inventory-api.tar localhost/inventory-api:e2e-test +${DOCKER} save -o inventory-e2e-tests.tar localhost/inventory-e2e-tests:e2e-test + +kind load image-archive inventory-api.tar --name inventory-cluster +kind load image-archive inventory-e2e-tests.tar --name inventory-cluster + +kubectl create configmap inventory-api-psks --from-file=config/psks.yaml + +kubectl apply -f https://strimzi.io/install/latest\?namespace\=default +kubectl apply -f deploy/kind/inventory/kessel-inventory.yaml +kubectl apply -f deploy/kind/inventory/invdatabase.yaml +kubectl apply -f deploy/kind/e2e/e2e-batch.yaml +kubectl apply -f deploy/kind/inventory/strimzi.yaml diff --git a/scripts/stop-inventory-kind.sh b/scripts/stop-inventory-kind.sh new file mode 100755 index 00000000..44c49666 --- /dev/null +++ b/scripts/stop-inventory-kind.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -oe errexit + +if ! command -v kind &> /dev/null +then + echo "kind could not be found" + exit +fi + +echo "Deleting kind inventory-cluster" +kind delete clusters inventory-cluster diff --git a/test/e2e/inventory_http_test.go b/test/e2e/inventory_http_test.go index 8df15665..d9253c2c 100644 --- a/test/e2e/inventory_http_test.go +++ b/test/e2e/inventory_http_test.go @@ -113,7 +113,7 @@ func TestInventoryAPIHTTP_Readyz(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, resp) - expectedStatus := "Storage type sqlite" + expectedStatus := "Storage type postgres" expectedCode := uint32(200) assert.Equal(t, expectedStatus, resp.Status) @@ -121,7 +121,7 @@ func TestInventoryAPIHTTP_Readyz(t *testing.T) { } func TestInventoryAPIHTTP_Metrics(t *testing.T) { - resp, err := nethttp.Get("http://localhost:8081/metrics") + resp, err := nethttp.Get("http://" + inventoryapi_http_url + "/metrics") if err != nil { t.Fatal("Failed to send request: ", err) }