From de8dd2bb00cc0ff42e214458150208a56af272aa Mon Sep 17 00:00:00 2001 From: nxtcoder17 Date: Mon, 8 May 2023 17:00:46 +0530 Subject: [PATCH] status-watcher controller updates, namespaced CRs updates - status watcher controller now communicates with message office api, and also has automatically reconnect to message office, whenever connection drops. - from namespace scoped resources, removes `accountName` and `clusterName` from spec, as they would automatically be added as labels via their respective controllers - project controller now adds labels related to accountName, and clusterName on the target namespace --- .tools/nvim/dap/go.lua | 2 +- agent/main.go | 30 +++++--- apis/clusters/v1/byoc_types.go | 9 ++- apis/crds/v1/config_types.go | 6 +- apis/redpanda.msvc/v1/topic_types.go | 2 +- config/crd/bases/_.yaml | 20 ----- .../bases/clusters.kloudlite.io_byocs.yaml | 3 + .../crd/bases/crds.kloudlite.io_configs.yaml | 9 --- .../redpanda.msvc.kloudlite.io_topics.yaml | 2 - .../byoc-client-operator/internal/env/env.go | 10 +-- .../internal/controller/controller.go | 48 ++++-------- .../internal/controllers/topic/controller.go | 6 +- .../controllers/project/controller.go | 2 +- .../controllers/status-watcher/controller.go | 76 +++++++++++++------ operators/status-n-billing/main.go | 29 ------- pkg/operator/request.go | 13 +++- 16 files changed, 120 insertions(+), 147 deletions(-) delete mode 100644 config/crd/bases/_.yaml diff --git a/.tools/nvim/dap/go.lua b/.tools/nvim/dap/go.lua index ebe59eda..de7860be 100644 --- a/.tools/nvim/dap/go.lua +++ b/.tools/nvim/dap/go.lua @@ -54,7 +54,7 @@ dap.configurations.go = { name = "Debug status-n-billing", request = "launch", program = vim.g.root_dir .. "/operators/status-n-billing", - args = { "--dev" }, + args = { "--dev", "--serverHost", "localhost:8081" }, -- console = "externalTerminal", -- externalTerminal = true, envFile = { diff --git a/agent/main.go b/agent/main.go index 59629263..3f507d0d 100644 --- a/agent/main.go +++ b/agent/main.go @@ -70,17 +70,17 @@ func (g *grpcHandler) handleMessage(msg t.AgentMessage) error { obj := unstructured.Unstructured{Object: msg.Object} mLogger := g.logger.WithKV("gvk", obj.GetObjectKind().GroupVersionKind().String()).WithKV("clusterName", msg.ClusterName).WithKV("accountName", msg.AccountName).WithKV("action", msg.Action) - mLogger.Infof("received message [%d]", g.inMemCounter) - defer func() { - mLogger.Infof("processed message [%d]", g.inMemCounter) - }() + mLogger.Infof("[%d] received message", g.inMemCounter) + // defer func() { + // mLogger.Infof("processed message [%d]", g.inMemCounter) + // }() if len(strings.TrimSpace(msg.AccountName)) == 0 { return g.handleErrorOnApply(ctx, fmt.Errorf("field 'accountName' must be defined in message"), msg) } switch msg.Action { - case "apply", "delete", "create": + case "apply", "delete": { b, err := yaml.Marshal(msg.Object) if err != nil { @@ -90,23 +90,31 @@ func (g *grpcHandler) handleMessage(msg t.AgentMessage) error { if msg.Action == "apply" { _, err := g.yamlClient.ApplyYAML(ctx, b) if err != nil { + mLogger.Infof("[%d] [error-on-apply]: %s", g.inMemCounter, err.Error()) + mLogger.Infof("[%d] failed to process message", g.inMemCounter) return g.handleErrorOnApply(ctx, err, msg) } + mLogger.Infof("[%d] processed message", g.inMemCounter) return nil } if msg.Action == "delete" { err := g.yamlClient.DeleteYAML(ctx, b) if err != nil { + mLogger.Infof("[%d] [error-on-delete]: %s", err.Error()) return g.handleErrorOnApply(ctx, err, msg) } + mLogger.Infof("[%d] processed message", g.inMemCounter) return nil } return nil } default: { - return g.handleErrorOnApply(ctx, fmt.Errorf("invalid action (%s)", msg.Action), msg) + err := fmt.Errorf("invalid action (%s)", msg.Action) + mLogger.Infof("[%d] [error]: %s", err.Error()) + mLogger.Infof("[%d] failed to process message", g.inMemCounter) + return g.handleErrorOnApply(ctx, err, msg) } } } @@ -215,9 +223,9 @@ func main() { for { cc, err := func() (*grpc.ClientConn, error) { - if isDev { - return libGrpc.Connect(ev.GrpcAddr) - } + // if isDev { + // return libGrpc.Connect(ev.GrpcAddr) + // } return libGrpc.ConnectSecure(ev.GrpcAddr) }() @@ -228,7 +236,9 @@ func main() { logger.Infof("GRPC connection successful") g.msgDispatchCli = messages.NewMessageDispatchServiceClient(cc) - g.run(cc) + if err := g.run(cc); err != nil { + logger.Errorf(err, "running grpc sendActions") + } connState := cc.GetState() for connState != connectivity.Ready && connState != connectivity.Shutdown { diff --git a/apis/clusters/v1/byoc_types.go b/apis/clusters/v1/byoc_types.go index 93c72516..e44636a7 100644 --- a/apis/clusters/v1/byoc_types.go +++ b/apis/clusters/v1/byoc_types.go @@ -6,11 +6,12 @@ import ( ) type BYOCSpec struct { - Region string `json:"region"` - Provider string `json:"provider"` - AccountName string `json:"accountName"` + Region string `json:"region"` + Provider string `json:"provider"` + AccountName string `json:"accountName"` + IncomingKafkaTopic string `json:"incomingKafkaTopic"` - DisplayName string `json:"displayName,omitempty"` + DisplayName string `json:"displayName,omitempty"` StorageClasses []string `json:"storageClasses,omitempty"` IngressClasses []string `json:"ingressClasses,omitempty"` PublicIPs []string `json:"publicIps,omitempty"` diff --git a/apis/crds/v1/config_types.go b/apis/crds/v1/config_types.go index 49eaa861..4f7e9770 100644 --- a/apis/crds/v1/config_types.go +++ b/apis/crds/v1/config_types.go @@ -16,11 +16,7 @@ type Config struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - AccountName string `json:"accountName"` - ClusterName string `json:"clusterName"` - - ProjectName string `json:"projectName,omitempty"` - Data map[string]string `json:"data,omitempty"` + Data map[string]string `json:"data,omitempty"` // +kubebuilder:default=true Enabled bool `json:"enabled,omitempty"` diff --git a/apis/redpanda.msvc/v1/topic_types.go b/apis/redpanda.msvc/v1/topic_types.go index 42ac4e8d..5eb1f1de 100644 --- a/apis/redpanda.msvc/v1/topic_types.go +++ b/apis/redpanda.msvc/v1/topic_types.go @@ -7,7 +7,7 @@ import ( ) type TopicSpec struct { - RedpandaAdmin string `json:"redpandaAdmin"` + RedpandaAdmin string `json:"redpandaAdmin,omitempty"` // +kubebuilder:default=3 PartitionCount int `json:"partitionCount,omitempty"` diff --git a/config/crd/bases/_.yaml b/config/crd/bases/_.yaml deleted file mode 100644 index a8e941a4..00000000 --- a/config/crd/bases/_.yaml +++ /dev/null @@ -1,20 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null -spec: - group: "" - names: - kind: "" - plural: "" - scope: "" - versions: null -status: - acceptedNames: - kind: "" - plural: "" - conditions: null - storedVersions: null diff --git a/config/crd/bases/clusters.kloudlite.io_byocs.yaml b/config/crd/bases/clusters.kloudlite.io_byocs.yaml index 793f78a7..0a8ec3de 100644 --- a/config/crd/bases/clusters.kloudlite.io_byocs.yaml +++ b/config/crd/bases/clusters.kloudlite.io_byocs.yaml @@ -54,6 +54,8 @@ spec: type: string displayName: type: string + incomingKafkaTopic: + type: string ingressClasses: items: type: string @@ -72,6 +74,7 @@ spec: type: array required: - accountName + - incomingKafkaTopic - provider - region type: object diff --git a/config/crd/bases/crds.kloudlite.io_configs.yaml b/config/crd/bases/crds.kloudlite.io_configs.yaml index 1067690b..213f2319 100644 --- a/config/crd/bases/crds.kloudlite.io_configs.yaml +++ b/config/crd/bases/crds.kloudlite.io_configs.yaml @@ -27,15 +27,11 @@ spec: openAPIV3Schema: description: Config is the Schema for the configs API properties: - accountName: - type: string apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string - clusterName: - type: string data: additionalProperties: type: string @@ -69,8 +65,6 @@ spec: type: object type: array type: object - projectName: - type: string status: properties: checks: @@ -348,9 +342,6 @@ spec: type: object type: array type: object - required: - - accountName - - clusterName type: object served: true storage: true diff --git a/config/crd/bases/redpanda.msvc.kloudlite.io_topics.yaml b/config/crd/bases/redpanda.msvc.kloudlite.io_topics.yaml index aad034a1..5c1a31a6 100644 --- a/config/crd/bases/redpanda.msvc.kloudlite.io_topics.yaml +++ b/config/crd/bases/redpanda.msvc.kloudlite.io_topics.yaml @@ -46,8 +46,6 @@ spec: type: integer redpandaAdmin: type: string - required: - - redpandaAdmin type: object status: properties: diff --git a/operators/byoc-client-operator/internal/env/env.go b/operators/byoc-client-operator/internal/env/env.go index 348e1431..3d243671 100644 --- a/operators/byoc-client-operator/internal/env/env.go +++ b/operators/byoc-client-operator/internal/env/env.go @@ -12,11 +12,11 @@ type Env struct { // HelmReleaseName string `env:"HELM_RELEASE_NAME" required:"true"` HelmReleaseNamespace string `env:"HELM_RELEASE_NAMESPACE" required:"true"` - KafkaTopicBYOCClientUpdates string `env:"KAFKA_TOPIC_BYOC_CLIENT_UPDATES" required:"true"` - - KafkaBrokers string `env:"KAFKA_BROKERS" required:"true"` - KafkaSASLUsername string `env:"KAFKA_SASL_USERNAME" required:"true"` - KafkaSASLPassword string `env:"KAFKA_SASL_PASSWORD" required:"true"` + // KafkaTopicBYOCClientUpdates string `env:"KAFKA_TOPIC_BYOC_CLIENT_UPDATES" required:"true"` + // + // KafkaBrokers string `env:"KAFKA_BROKERS" required:"true"` + // KafkaSASLUsername string `env:"KAFKA_SASL_USERNAME" required:"true"` + // KafkaSASLPassword string `env:"KAFKA_SASL_PASSWORD" required:"true"` } func LoadEnv() (*Env, error) { diff --git a/operators/byoc-operator/internal/controller/controller.go b/operators/byoc-operator/internal/controller/controller.go index 815e6a45..bf9f2763 100644 --- a/operators/byoc-operator/internal/controller/controller.go +++ b/operators/byoc-operator/internal/controller/controller.go @@ -19,12 +19,10 @@ import ( fn "github.com/kloudlite/operator/pkg/functions" stepResult "github.com/kloudlite/operator/pkg/operator/step-result" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/controller" redpandaMsvcv1 "github.com/kloudlite/operator/apis/redpanda.msvc/v1" - apiErrors "k8s.io/apimachinery/pkg/api/errors" ) type Reconciler struct { @@ -85,48 +83,22 @@ func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl. req.Object.Status.IsReady = true req.Object.Status.LastReconcileTime = &metav1.Time{Time: time.Now()} - req.Object.Status.Resources = req.GetOwnedResources() - if err := r.Status().Update(ctx, req.Object); err != nil { - return ctrl.Result{}, err - } - return ctrl.Result{RequeueAfter: r.Env.ReconcilePeriod}, nil + return ctrl.Result{RequeueAfter: r.Env.ReconcilePeriod}, r.Status().Update(ctx, req.Object) } func (r *Reconciler) finalize(req *rApi.Request[*clusterv1.BYOC]) stepResult.Result { - ctx, obj := req.Context(), req.Object - check := rApi.Check{Generation: obj.Generation} - finalizing := "finalizing" req.LogPreCheck(finalizing) defer req.LogPostCheck(finalizing) - rr := req.GetOwnedResources() - for i := range rr { - res := &unstructured.Unstructured{Object: map[string]any{"apiVersion": rr[i].APIVersion, "kind": rr[i].Kind}} - - if err := r.Get(ctx, fn.NN(rr[i].Namespace, rr[i].Name), res); err != nil { - if !apiErrors.IsNotFound(err) { - if res.GetDeletionTimestamp() != nil { - if err := r.Delete(ctx, res); err != nil { - return req.CheckFailed(finalizing, check, err.Error()) - } - } - req.Logger.Infof("waiting for child resource '[%s, %s] %s/%s' to be deleted", rr[i].APIVersion, rr[i].Kind, rr[i].Namespace, rr[i].Name) - return req.CheckFailed(finalizing, check, err.Error()) - } - } + if step := req.CleanupOwnedResources(); !step.ShouldProceed() { + return step } - // ---> - controllerutil.RemoveFinalizer(obj, constants.CommonFinalizer) - if err := r.Update(ctx, obj); err != nil { - return req.CheckFailed(finalizing, check, err.Error()) - } - - return req.Next() + return req.Finalize() } func (r *Reconciler) ensureKafkaTopic(req *rApi.Request[*clusterv1.BYOC]) stepResult.Result { @@ -136,7 +108,16 @@ func (r *Reconciler) ensureKafkaTopic(req *rApi.Request[*clusterv1.BYOC]) stepRe req.LogPreCheck(KafkaTopicExists) defer req.LogPostCheck(KafkaTopicExists) - kt := &redpandaMsvcv1.Topic{ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("kl-%s-%s-incoming", obj.Spec.AccountName, obj.Name), Namespace: r.Env.KafkaTopicNamespace}} + var rpAdminList redpandaMsvcv1.AdminList + if err := r.List(ctx, &rpAdminList); err != nil { + return req.CheckFailed(KafkaTopicExists, check, err.Error()).Err(nil) + } + + if len(rpAdminList.Items) != 1 { + return req.CheckFailed(KafkaTopicExists, check, "multiple redpanda admin found, should be only one").Err(nil) + } + + kt := &redpandaMsvcv1.Topic{ObjectMeta: metav1.ObjectMeta{Name: obj.Spec.IncomingKafkaTopic, Namespace: r.Env.KafkaTopicNamespace}} if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, kt, func() error { if !fn.IsOwner(kt, fn.AsOwner(obj)) { kt.SetOwnerReferences([]metav1.OwnerReference{fn.AsOwner(obj, true)}) @@ -145,6 +126,7 @@ func (r *Reconciler) ensureKafkaTopic(req *rApi.Request[*clusterv1.BYOC]) stepRe } kt.Labels["kloudlite.io/byoc.name"] = obj.Name } + kt.Spec.RedpandaAdmin = rpAdminList.Items[0].Name return nil }); err != nil { return req.CheckFailed(KafkaTopicExists, check, err.Error()).Err(nil) diff --git a/operators/msvc-redpanda/internal/controllers/topic/controller.go b/operators/msvc-redpanda/internal/controllers/topic/controller.go index d2ea1a06..5541fb65 100644 --- a/operators/msvc-redpanda/internal/controllers/topic/controller.go +++ b/operators/msvc-redpanda/internal/controllers/topic/controller.go @@ -15,6 +15,7 @@ import ( stepResult "github.com/kloudlite/operator/pkg/operator/step-result" "github.com/kloudlite/operator/pkg/redpanda" corev1 "k8s.io/api/core/v1" + apiErrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" @@ -89,7 +90,10 @@ func (r *Reconciler) finalize(req *rApi.Request[*redpandaMsvcv1.Topic]) stepResu adminCli, err := r.getAdminClient(req) if err != nil { - return req.CheckFailed(topicDeleted, check, err.Error()) + if !apiErrors.IsNotFound(err) { + return req.CheckFailed(topicDeleted, check, err.Error()) + } + return req.Finalize() } if err := adminCli.DeleteTopic(obj.Name); err != nil { diff --git a/operators/project/internal/controllers/project/controller.go b/operators/project/internal/controllers/project/controller.go index 6dd309ce..c0261ff9 100644 --- a/operators/project/internal/controllers/project/controller.go +++ b/operators/project/internal/controllers/project/controller.go @@ -149,7 +149,7 @@ func (r *Reconciler) ensureNamespacedRBACs(req *rApi.Request[*v1.Project]) stepR b, err := templates.Parse( templates.ProjectRBAC, map[string]any{ - "namespace": obj.Name, + "namespace": obj.Spec.TargetNamespace, "role-name": r.Env.AdminRoleName, "role-binding-name": r.Env.AdminRoleName + "-rb", "svc-account-name": r.Env.SvcAccountName, diff --git a/operators/status-n-billing/internal/controllers/status-watcher/controller.go b/operators/status-n-billing/internal/controllers/status-watcher/controller.go index dcdcf60b..03197ef2 100644 --- a/operators/status-n-billing/internal/controllers/status-watcher/controller.go +++ b/operators/status-n-billing/internal/controllers/status-watcher/controller.go @@ -52,15 +52,17 @@ func (r *Reconciler) GetName() string { } func (r *Reconciler) SendStatusEvents(ctx context.Context, obj client.Object, logger logging.Logger) (ctrl.Result, error) { + obj.SetManagedFields(nil) + b, err := json.Marshal(obj) if err != nil { return ctrl.Result{}, nil } var j struct { - Spec struct { - AccountName string `json:"accountName"` - } `json:"spec"` + // Spec struct { + // AccountName string `json:"accountName"` + // } `json:"spec"` Status rApi.Status `json:"status"` } @@ -68,21 +70,40 @@ func (r *Reconciler) SendStatusEvents(ctx context.Context, obj client.Object, lo return ctrl.Result{}, nil } - obj.SetManagedFields(nil) - var m map[string]any if err := json.Unmarshal(b, &m); err != nil { return ctrl.Result{}, err } - if strings.HasSuffix(obj.GetObjectKind().GroupVersionKind().Group, "infra.kloudlite.io") { - if err := r.dispatchStatusMsg(ctx, statusType.StatusUpdate{ - ClusterName: r.Env.ClusterName, - AccountName: j.Spec.AccountName, - Object: m, - Status: j.Status, - }); err != nil { - return ctrl.Result{}, err + switch { + case strings.HasSuffix(obj.GetObjectKind().GroupVersionKind().Group, "infra.kloudlite.io"): + { + if err := r.dispatchInfraMsg(ctx, statusType.StatusUpdate{ + // ClusterName: r.Env.ClusterName, + ClusterName: obj.GetLabels()[constants.ClusterNameKey], + AccountName: obj.GetLabels()[constants.AccountNameKey], + Object: m, + Status: j.Status, + }); err != nil { + return ctrl.Result{}, err + } + } + case strings.HasSuffix(obj.GetObjectKind().GroupVersionKind().Group, "kloudlite.io"): + { + if err := r.dispatchStatusMsg(ctx, statusType.StatusUpdate{ + // ClusterName: r.Env.ClusterName, + ClusterName: obj.GetLabels()[constants.ClusterNameKey], + AccountName: obj.GetLabels()[constants.AccountNameKey], + Object: m, + Status: j.Status, + }); err != nil { + return ctrl.Result{}, err + } + } + default: + { + logger.Infof("ignoring resource status update, as it does not belong to group kloudlite.io") + return ctrl.Result{}, nil } } @@ -133,6 +154,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, oReq ctrl.Request) (ctrl.Res if err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) } + return r.SendStatusEvents(ctx, obj, logger) } @@ -143,6 +165,7 @@ func (r *Reconciler) AddWatcherFinalizer(ctx context.Context, obj client.Object) func (r *Reconciler) RemoveWatcherFinalizer(ctx context.Context, obj client.Object) (ctrl.Result, error) { controllerutil.RemoveFinalizer(obj, constants.StatusWatcherFinalizer) + return ctrl.Result{}, r.Update(ctx, obj) } @@ -179,12 +202,16 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, logger logging.Logger) e if err != nil { return err } - return mds.Send(&messages.StatusData{ + if err = mds.Send(&messages.StatusData{ AccessToken: r.Env.AccessToken, ClusterName: r.Env.ClusterName, AccountName: r.Env.AccountName, StatusUpdateMessage: b, - }) + }); err != nil { + handlerCh <- err + return err + } + return nil } infraMessagesCli, err := msgDispatchCli.ReceiveInfraUpdates(context.Background()) @@ -198,25 +225,28 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager, logger logging.Logger) e return err } - return infraMessagesCli.Send(&messages.InfraStatusData{ + if err = infraMessagesCli.Send(&messages.InfraStatusData{ AccessToken: r.Env.AccessToken, ClusterName: r.Env.ClusterName, AccountName: r.Env.AccountName, InfraUpdateMessage: b, - }) + }); err != nil { + handlerCh <- err + return err + } + return nil } - // g.run(cc) - - go func() { - connState := cc.GetState() - for connState != connectivity.Ready && connState != connectivity.Shutdown { + connState := cc.GetState() + go func(cs connectivity.State) { + fmt.Println("here ----------") + for cs != connectivity.Ready && connState != connectivity.Shutdown { handlerCh <- fmt.Errorf("connection lost") // log.Printf("Connection lost, trying to reconnect...") // time.Sleep(2 * time.Second // connState = cc.GetState() } - }() + }(connState) <-handlerCh cc.Close() } diff --git a/operators/status-n-billing/main.go b/operators/status-n-billing/main.go index 952d2739..8e6aaa04 100644 --- a/operators/status-n-billing/main.go +++ b/operators/status-n-billing/main.go @@ -30,35 +30,6 @@ type grpcHandler struct { func main() { ev := env.GetEnvOrDie() - // g := grpcHandler{ - // inMemCounter: 0, - // // yamlClient: yamlClient, - // // logger: logger, - // ev: ev, - // } - - - // producer, err := redpanda.NewProducer( - // ev.KafkaBrokers, redpanda.ProducerOpts{ - // SASLAuth: &redpanda.KafkaSASLAuth{ - // // SASLMechanism: redpanda.ScramSHA256, - // User: ev.KafkaSASLUsername, - // Password: ev.KafkaSASLPassword, - // }, - // }, - // ) - // - // if err != nil { - // panic(errors.NewEf(err, "creating redpanda producer")) - // } - // defer producer.Close() - - // timeout, cancelFn := context.WithTimeout(context.Background(), 5*time.Second) - // defer cancelFn() - // if err := producer.Ping(timeout); err != nil { - // panic(fmt.Errorf("failed to ping kafka producer as %s", err.Error())) - // } - mgr := operator.New("status-n-billing-watcher") getGrpcConnection := func() (*grpc.ClientConn, error) { diff --git a/pkg/operator/request.go b/pkg/operator/request.go index 5b8756c8..3928150b 100644 --- a/pkg/operator/request.go +++ b/pkg/operator/request.go @@ -11,6 +11,7 @@ import ( "github.com/kloudlite/operator/pkg/conditions" "github.com/kloudlite/operator/pkg/constants" + "github.com/kloudlite/operator/pkg/errors" fn "github.com/kloudlite/operator/pkg/functions" "github.com/kloudlite/operator/pkg/logging" stepResult "github.com/kloudlite/operator/pkg/operator/step-result" @@ -105,10 +106,16 @@ func (r *Request[T]) EnsureLabelsAndAnnotations() stepResult.Result { if r.Object.GetNamespace() != "" { var ns corev1.Namespace if err := r.client.Get(r.Context(), fn.NN("", r.Object.GetNamespace()), &ns); err != nil { - for k, v := range ns.GetLabels() { + return stepResult.New().Err(errors.NewEf(err, "could not get namespace %q", r.Object.GetNamespace())) + } + + for k, v := range ns.GetLabels() { + if strings.HasPrefix(k, "kloudlite.io/") { labels[k] = v } - for k, v := range ns.GetAnnotations() { + } + for k, v := range ns.GetAnnotations() { + if strings.HasPrefix(k, "kloudlite.io/") { annotations[k] = v } } @@ -454,7 +461,7 @@ func (r *Request[T]) CleanupOwnedResources() stepResult.Result { return r.CheckFailed("CleanupResource", check, err.Error()).Err(nil) } return r.CheckFailed("CleanupResource", check, - fmt.Sprintf("waiting for deletion of resource gvk=%s, nn=%s", res.GetObjectKind().GroupVersionKind().String(), fn.NN(res.GetNamespace(), res.GetName())), + fmt.Sprintf("waiting for deletion of owned resource gvk=%s, nn=%s", res.GetObjectKind().GroupVersionKind().String(), fn.NN(res.GetNamespace(), res.GetName())), ).Err(nil) }