diff --git a/internal/controller/dashboard/factory.go b/internal/controller/dashboard/factory.go index c23bac4a..4e18ff09 100644 --- a/internal/controller/dashboard/factory.go +++ b/internal/controller/dashboard/factory.go @@ -221,7 +221,7 @@ func workloadsTab(kind string) map[string]any { "baseprefix": "/openapi-ui", "customizationId": "factory-details-v1alpha1.cozystack.io.workloadmonitors", "pathToItems": []any{"items"}, - "labelsSelector": map[string]any{ + "labelSelector": map[string]any{ "apps.cozystack.io/application.group": "apps.cozystack.io", "apps.cozystack.io/application.kind": kind, "apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}", @@ -246,7 +246,7 @@ func servicesTab(kind string) map[string]any { "baseprefix": "/openapi-ui", "customizationId": "factory-details-v1.services", "pathToItems": []any{"items"}, - "labelsSelector": map[string]any{ + "labelSelector": map[string]any{ "apps.cozystack.io/application.group": "apps.cozystack.io", "apps.cozystack.io/application.kind": kind, "apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}", @@ -272,7 +272,7 @@ func ingressesTab(kind string) map[string]any { "baseprefix": "/openapi-ui", "customizationId": "factory-details-networking.k8s.io.v1.ingresses", "pathToItems": []any{"items"}, - "labelsSelector": map[string]any{ + "labelSelector": map[string]any{ "apps.cozystack.io/application.group": "apps.cozystack.io", "apps.cozystack.io/application.kind": kind, "apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}", @@ -298,7 +298,7 @@ func secretsTab(kind string) map[string]any { "baseprefix": "/openapi-ui", "customizationId": "factory-details-v1alpha1.core.cozystack.io.tenantsecrets", "pathToItems": []any{"items"}, - "labelsSelector": map[string]any{ + "labelSelector": map[string]any{ "apps.cozystack.io/application.group": "apps.cozystack.io", "apps.cozystack.io/application.kind": kind, "apps.cozystack.io/application.name": "{reqs[0]['metadata','name']}", diff --git a/internal/controller/dashboard/static_refactored.go b/internal/controller/dashboard/static_refactored.go index 31db0377..b52ea3cc 100644 --- a/internal/controller/dashboard/static_refactored.go +++ b/internal/controller/dashboard/static_refactored.go @@ -1056,7 +1056,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory { "clusterNamePartOfUrl": "{2}", "customizationId": "factory-kube-service-details-endpointslice", "fetchUrl": "/api/clusters/{2}/k8s/apis/discovery.k8s.io/v1/namespaces/{3}/endpointslices", - "labelsSelector": map[string]any{ + "labelSelector": map[string]any{ "kubernetes.io/service-name": "{reqsJsonPath[0]['.metadata.name']['-']}", }, "pathToItems": ".items[*].endpoints", @@ -1397,7 +1397,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory { "clusterNamePartOfUrl": "{2}", "customizationId": "factory-details-v1alpha1.cozystack.io.workloads", "fetchUrl": "/api/clusters/{2}/k8s/apis/cozystack.io/v1alpha1/namespaces/{3}/workloads", - "labelsSelector": map[string]any{ + "labelSelector": map[string]any{ "workloads.cozystack.io/monitor": "{reqs[0]['metadata','name']}", }, "pathToItems": []any{"items"}, diff --git a/pkg/registry/core/tenantsecret/rest.go b/pkg/registry/core/tenantsecret/rest.go index a13426e6..b1667c45 100644 --- a/pkg/registry/core/tenantsecret/rest.go +++ b/pkg/registry/core/tenantsecret/rest.go @@ -9,7 +9,7 @@ import ( "encoding/base64" "fmt" "net/http" - "sort" + "slices" "time" corev1 "k8s.io/api/core/v1" @@ -226,6 +226,9 @@ func (r *REST) Get( if err != nil { return nil, err } + if sec.Labels == nil || sec.Labels[tsLabelKey] != tsLabelValue { + return nil, apierrors.NewNotFound(r.gvr.GroupResource(), name) + } return secretToTenant(sec), nil } @@ -253,11 +256,13 @@ func (r *REST) List(ctx context.Context, opts *metainternal.ListOptions) (runtim list := &corev1.SecretList{} err = r.c.List(ctx, list, &client.ListOptions{ - Namespace: ns, + Namespace: ns, + LabelSelector: ls, Raw: &metav1.ListOptions{ LabelSelector: ls.String(), FieldSelector: fieldSel, - }}) + }, + }) if err != nil { return nil, err } @@ -273,7 +278,17 @@ func (r *REST) List(ctx context.Context, opts *metainternal.ListOptions) (runtim for i := range list.Items { out.Items = append(out.Items, *secretToTenant(&list.Items[i])) } - sort.Slice(out.Items, func(i, j int) bool { return out.Items[i].Name < out.Items[j].Name }) + slices.SortFunc(out.Items, func(a, b corev1alpha1.TenantSecret) int { + aKey := fmt.Sprintf("%s/%s", a.Namespace, a.Name) + bKey := fmt.Sprintf("%s/%s", b.Namespace, b.Name) + switch { + case aKey < bKey: + return -1 + case aKey > bKey: + return 1 + } + return 0 + }) return out, nil } @@ -291,10 +306,17 @@ func (r *REST) Update( return nil, false, err } - cur := &corev1.Secret{} - err = r.c.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, cur, &client.GetOptions{Raw: &metav1.GetOptions{}}) - if err != nil && !apierrors.IsNotFound(err) { - return nil, false, err + var cur *corev1.Secret + previous := &corev1.Secret{} + if err := r.c.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, previous, &client.GetOptions{Raw: &metav1.GetOptions{}}); err != nil { + if !apierrors.IsNotFound(err) { + return nil, false, err + } + } else { + if previous.Labels == nil || previous.Labels[tsLabelKey] != tsLabelValue { + return nil, false, apierrors.NewNotFound(r.gvr.GroupResource(), name) + } + cur = previous } newObj, err := objInfo.UpdatedObject(ctx, nil) @@ -306,7 +328,7 @@ func (r *REST) Update( newSec := tenantToSecret(in, cur) newSec.Namespace = ns if cur == nil { - if !forceCreate && err == nil { + if !forceCreate { return nil, false, apierrors.NewNotFound(r.gvr.GroupResource(), name) } err := r.c.Create(ctx, newSec, &client.CreateOptions{Raw: &metav1.CreateOptions{}}) @@ -328,6 +350,13 @@ func (r *REST) Delete( if err != nil { return nil, false, err } + current := &corev1.Secret{} + if err := r.c.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, current, &client.GetOptions{Raw: &metav1.GetOptions{}}); err != nil { + return nil, false, err + } + if current.Labels == nil || current.Labels[tsLabelKey] != tsLabelValue { + return nil, false, apierrors.NewNotFound(r.gvr.GroupResource(), name) + } err = r.c.Delete(ctx, &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: name}}, &client.DeleteOptions{Raw: opts}) return nil, err == nil, err } @@ -347,6 +376,13 @@ func (r *REST) Patch( if err != nil { return nil, err } + current := &corev1.Secret{} + if err := r.c.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, current, &client.GetOptions{Raw: &metav1.GetOptions{}}); err != nil { + return nil, err + } + if current.Labels == nil || current.Labels[tsLabelKey] != tsLabelValue { + return nil, apierrors.NewNotFound(r.gvr.GroupResource(), name) + } out := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Namespace: ns, @@ -383,12 +419,16 @@ func (r *REST) Watch(ctx context.Context, opts *metainternal.ListOptions) (watch } secList := &corev1.SecretList{} - ls := labels.Set{tsLabelKey: tsLabelValue}.AsSelector().String() - base, err := r.w.Watch(ctx, secList, &client.ListOptions{Namespace: ns, Raw: &metav1.ListOptions{ - Watch: true, - LabelSelector: ls, - ResourceVersion: opts.ResourceVersion, - }}) + ls := labels.Set{tsLabelKey: tsLabelValue}.AsSelector() + base, err := r.w.Watch(ctx, secList, &client.ListOptions{ + Namespace: ns, + LabelSelector: ls, + Raw: &metav1.ListOptions{ + Watch: true, + LabelSelector: ls.String(), + ResourceVersion: opts.ResourceVersion, + }, + }) if err != nil { return nil, err }