From f278c09089ab0f37cdeb529839e5805f96655ac4 Mon Sep 17 00:00:00 2001 From: leoporoli Date: Mon, 14 Oct 2024 17:09:46 -0300 Subject: [PATCH] fix: fix unsupported resources deployment (#278) --- ci/obd-demo.yaml | 85 ++++++++++++-------- ci/template.yaml | 65 ++++++++------- kardinal-cli/cmd/root.go | 2 +- kardinal-cli/deployment/deployment.go | 10 ++- kardinal-cli/kubernetes/kubernetes_client.go | 45 ++++++++++- 5 files changed, 142 insertions(+), 65 deletions(-) diff --git a/ci/obd-demo.yaml b/ci/obd-demo.yaml index 36bfbbf2..197ef8f3 100644 --- a/ci/obd-demo.yaml +++ b/ci/obd-demo.yaml @@ -126,8 +126,8 @@ spec: env: - name: ADDRESS value: ":8080" - - name: FREECURRENCYAPIKEY - value: "fca_live_nFVVF8CvfxqJhzMHB4N2x1NH7ffVVPwZr9hg3iNl" + - name: JSDELIVRAPIKEY + value: "prod" - name: CARTSERVICEHOST value: cartservice - name: PRODUCTCATALOGSERVICEHOST @@ -143,12 +143,7 @@ metadata: version: v1 annotations: kardinal.dev.service/dependencies: "productcatalogservice:http,cartservice:http" - kardinal.dev.service/plugins: | - - name: https://github.com/kurtosis-tech/free-currency-api-plugin.git - type: external - servicename: free-currency-api - args: - api_key: fca_live_VKZlykCWEiFcpBHnw74pzd4vLi04q1h9JySbVHDF + kardinal.dev.service/plugins: "jsdelivr-api" spec: type: ClusterIP selector: @@ -210,32 +205,7 @@ metadata: version: v1 annotations: kardinal.dev.service/stateful: "true" - kardinal.dev.service/plugins: | - - name: github.com/kurtosis-tech/postgres-seed-plugin - args: - seed_script: | - -- create the table - CREATE TABLE IF NOT EXISTS public.items( - id bigserial PRIMARY KEY, - created_at TIMESTAMP WITH TIME ZONE, - updated_at TIMESTAMP WITH TIME ZONE, - deleted_at TIMESTAMP WITH TIME ZONE, - user_id TEXT, - product_id TEXT, - quantity INTEGER - ); - - INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) - VALUES (1, '2024-08-02 13:02:07.656104 +00:00', '2024-08-02 13:02:07.656104 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '66VCHSJNUP', 1); - - INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) - VALUES (2, '2024-08-02 13:02:10.891407 +00:00', '2024-08-02 13:02:10.891407 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '2ZYFJ3GM2N', 1); - - -- Set the sequence to the correct value after inserting records - SELECT setval('public.items_id_seq', (SELECT MAX(id) FROM public.items)); - db_name: "cart" - db_user: "postgresuser" - db_password: "postgrespass" + kardinal.dev.service/plugins: "postgres-seed-plugin" spec: type: ClusterIP @@ -332,3 +302,50 @@ spec: name: frontend port: number: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: jsdelivr-api + annotations: + kardinal.dev.service/plugin-definition: | + - name: github.com/kurtosis-tech/jsdelivr-api-plugin + type: external + servicename: jsdelivr-api + args: + api_key: "dev" + +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres-seed-plugin + annotations: + kardinal.dev.service/plugin-definition: | + - name: github.com/kurtosis-tech/postgres-seed-plugin + type: stateful + servicename: postgres-seed-plugin + args: + seed_script: | + -- create the table + CREATE TABLE IF NOT EXISTS public.items( + id bigserial PRIMARY KEY, + created_at TIMESTAMP WITH TIME ZONE, + updated_at TIMESTAMP WITH TIME ZONE, + deleted_at TIMESTAMP WITH TIME ZONE, + user_id TEXT, + product_id TEXT, + quantity INTEGER + ); + + INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) + VALUES (1, '2024-08-02 13:02:07.656104 +00:00', '2024-08-02 13:02:07.656104 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '66VCHSJNUP', 1); + + INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) + VALUES (2, '2024-08-02 13:02:10.891407 +00:00', '2024-08-02 13:02:10.891407 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '2ZYFJ3GM2N', 1); + + -- Set the sequence to the correct value after inserting records + SELECT setval('public.items_id_seq', (SELECT MAX(id) FROM public.items)); + db_name: "cart" + db_user: "postgresuser" + db_password: "postgrespass" \ No newline at end of file diff --git a/ci/template.yaml b/ci/template.yaml index 24bc9fac..9693c37c 100644 --- a/ci/template.yaml +++ b/ci/template.yaml @@ -4,32 +4,43 @@ metadata: name: postgres annotations: kardinal.dev.service/shared: "true" - kardinal.dev.service/plugins: | - - name: github.com/kurtosis-tech/postgres-seed-plugin - args: - seed_script: | - -- create the table - CREATE TABLE IF NOT EXISTS public.items( - id bigserial PRIMARY KEY, - created_at TIMESTAMP WITH TIME ZONE, - updated_at TIMESTAMP WITH TIME ZONE, - deleted_at TIMESTAMP WITH TIME ZONE, - user_id TEXT, - product_id TEXT, - quantity INTEGER - ); - - INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) - VALUES (1, '2024-08-02 13:02:07.656104 +00:00', '2024-08-02 13:02:07.656104 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '66VCHSJNUP', 1); + kardinal.dev.service/plugins: "postgres-seed-plugin" - INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) - VALUES (2, '2024-08-02 13:02:10.891407 +00:00', '2024-08-02 13:02:10.891407 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '2ZYFJ3GM2N', 1); - INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) - VALUES (3, '2024-08-02 13:03:10.891407 +00:00', '2024-08-02 13:02:10.891407 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '2ZYFJ3GM2N', ${last_insert_quantity:-1}); - - -- Set the sequence to the correct value after inserting records - SELECT setval('public.items_id_seq', (SELECT MAX(id) FROM public.items)); - db_name: "cart" - db_user: "postgresuser" - db_password: "postgrespass" \ No newline at end of file +--- +apiVersion: v1 +kind: Service +metadata: + name: postgres-seed-plugin + annotations: + kardinal.dev.service/plugin-definition: | + - name: github.com/kurtosis-tech/postgres-seed-plugin + type: stateful + servicename: postgres-seed-plugin + args: + seed_script: | + -- create the table + CREATE TABLE IF NOT EXISTS public.items( + id bigserial PRIMARY KEY, + created_at TIMESTAMP WITH TIME ZONE, + updated_at TIMESTAMP WITH TIME ZONE, + deleted_at TIMESTAMP WITH TIME ZONE, + user_id TEXT, + product_id TEXT, + quantity INTEGER + ); + + INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) + VALUES (1, '2024-08-02 13:02:07.656104 +00:00', '2024-08-02 13:02:07.656104 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '66VCHSJNUP', 1); + + INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) + VALUES (2, '2024-08-02 13:02:10.891407 +00:00', '2024-08-02 13:02:10.891407 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '2ZYFJ3GM2N', 1); + + INSERT INTO public.items (id, created_at, updated_at, deleted_at, user_id, product_id, quantity) + VALUES (3, '2024-08-02 13:03:10.891407 +00:00', '2024-08-02 13:02:10.891407 +00:00', null, '0494c5e0-dde0-48fa-a6d8-f7962f5476bf', '2ZYFJ3GM2N', ${last_insert_quantity:-1}); + + -- Set the sequence to the correct value after inserting records + SELECT setval('public.items_id_seq', (SELECT MAX(id) FROM public.items)); + db_name: "cart" + db_user: "postgresuser" + db_password: "postgrespass" \ No newline at end of file diff --git a/kardinal-cli/cmd/root.go b/kardinal-cli/cmd/root.go index 9d15ab5e..df524706 100644 --- a/kardinal-cli/cmd/root.go +++ b/kardinal-cli/cmd/root.go @@ -914,7 +914,7 @@ func deploy( namespace string, ) error { - if err := deployment.DeployResourceSpecs(ctx, noSupportedResourcesSpecs); err != nil { + if err := deployment.DeployResourceSpecs(ctx, namespace, noSupportedResourcesSpecs); err != nil { return stacktrace.Propagate(err, "an error occurred deploying not supported resources") } diff --git a/kardinal-cli/deployment/deployment.go b/kardinal-cli/deployment/deployment.go index b344caa5..3ccc1208 100644 --- a/kardinal-cli/deployment/deployment.go +++ b/kardinal-cli/deployment/deployment.go @@ -261,7 +261,11 @@ type k8sResourceKindAndMetadata struct { } } -func DeployResourceSpecs(ctx context.Context, resourceSpecs []string) error { +func DeployResourceSpecs(ctx context.Context, namespace string, resourceSpecs []string) error { + if len(resourceSpecs) == 0 { + return nil + } + k8sConfig, err := kubernetes.GetConfig() if err != nil { return stacktrace.Propagate(err, "An error occurred while creating the Kubernetes client") @@ -271,6 +275,10 @@ func DeployResourceSpecs(ctx context.Context, resourceSpecs []string) error { return stacktrace.Propagate(err, "An error occurred while creating the Kubernetes client") } + if err := kubernetesClientObj.EnsureNamespace(ctx, namespace); err != nil { + return stacktrace.Propagate(err, "An error occurred while ensuring the namespace '%s'", namespace) + } + for _, resourceSpec := range resourceSpecs { resourceSpecBytes := []byte(resourceSpec) diff --git a/kardinal-cli/kubernetes/kubernetes_client.go b/kardinal-cli/kubernetes/kubernetes_client.go index 9c0058fc..a0fba858 100644 --- a/kardinal-cli/kubernetes/kubernetes_client.go +++ b/kardinal-cli/kubernetes/kubernetes_client.go @@ -4,12 +4,12 @@ import ( "bytes" "context" "errors" - "io" - "github.com/kurtosis-tech/stacktrace" "gopkg.in/yaml.v3" + "io" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + k8s_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/labels" @@ -24,6 +24,20 @@ const ( listOptionsTimeoutSeconds int64 = 10 deleteOptionsGracePeriodSeconds int64 = 0 + istioSystemNamespace = "istio-system" +) + +var ( + globalCreateOptions = metav1.CreateOptions{ + TypeMeta: metav1.TypeMeta{ + Kind: "", + APIVersion: "", + }, + DryRun: nil, + // We need every object to have this field manager so that the Kurtosis objects can all seamlessly modify Kubernetes resources + FieldManager: fieldManager, + FieldValidation: "", + } ) type KubernetesClient struct { @@ -198,6 +212,33 @@ func (client *KubernetesClient) GetNamespacesByLabels(ctx context.Context, names return &namespacesNotMarkedForDeletionnamespaceList, nil } +func (client *KubernetesClient) EnsureNamespace(ctx context.Context, name string) error { + if name == "" || name == istioSystemNamespace { + // Some resources might be under the istio system namespace, but we don't want to alter + // this namespace because it is managed by Istio + return nil + } + + _, err := client.clientSet.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if k8s_errors.IsNotFound(err) { + newNamespace := corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + } + _, err = client.clientSet.CoreV1().Namespaces().Create(ctx, &newNamespace, globalCreateOptions) + if err != nil { + return stacktrace.Propagate(err, "Failed to create Namespace: %s", name) + } + return nil + } + return stacktrace.Propagate(err, "An error occurred getting '%s'", name) + } + + return nil +} + func buildListOptionsFromLabels(labelsMap map[string]string) metav1.ListOptions { return metav1.ListOptions{ TypeMeta: metav1.TypeMeta{