Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the configuration for labels and annotations #1899

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions config/crd/bases/operator.knative.dev_knativeeventings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,20 @@ spec:
type: object
type: object
type: array
namespace:
description: A field of namespace name to override the labels and annotations
type: object
properties:
labels:
additionalProperties:
type: string
description: Labels overrides labels for the namespace and its template.
type: object
annotations:
additionalProperties:
type: string
description: Annotations overrides labels for the namespace and its template.
type: object
deployments:
description: A mapping of deployment name to override
type: array
Expand Down
14 changes: 14 additions & 0 deletions config/crd/bases/operator.knative.dev_knativeservings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,20 @@ spec:
type: object
type: object
type: array
namespace:
description: A field of namespace name to override the labels and annotations
type: object
properties:
labels:
additionalProperties:
type: string
description: Labels overrides labels for the namespace and its template.
type: object
annotations:
additionalProperties:
type: string
description: Annotations overrides labels for the namespace and its template.
type: object
deployments:
description: A mapping of deployment name to override
type: array
Expand Down
23 changes: 23 additions & 0 deletions pkg/apis/operator/base/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ type KComponentSpec interface {
// GetAdditionalManifests gets the list of additional manifests, which should be installed
GetAdditionalManifests() []Manifest

// GetNamespaceConfiguration gets the labels and annotations for the namespace
GetNamespaceConfiguration() *NamespaceConfiguration

// GetHighAvailability returns means to set the number of desired replicas
GetHighAvailability() *HighAvailability

Expand Down Expand Up @@ -142,6 +145,10 @@ type CommonSpec struct {
// +optional
DeploymentOverride []WorkloadOverride `json:"deployments,omitempty"`

// NamespaceConfiguration overrides namespace configurations such as labels and annotations.
// +optional
NamespaceConfiguration *NamespaceConfiguration `json:"namespace,omitempty"`

// Workloads overrides workloads configurations such as resources and replicas.
// +optional
Workloads []WorkloadOverride `json:"workloads,omitempty"`
Expand Down Expand Up @@ -191,6 +198,11 @@ func (c *CommonSpec) GetVersion() string {
return c.Version
}

// GetNamespaceConfiguration implements KComponentSpec.
func (c *CommonSpec) GetNamespaceConfiguration() *NamespaceConfiguration {
return c.NamespaceConfiguration
}

// GetManifests implements KComponentSpec.
func (c *CommonSpec) GetManifests() []Manifest {
return c.Manifests
Expand Down Expand Up @@ -247,6 +259,17 @@ type Registry struct {
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
}

// NamespaceConfiguration defines the configurations of namespaces to override.
type NamespaceConfiguration struct {
// Labels overrides labels for the namespace and its template.
// +optional
Labels map[string]string `json:"labels,omitempty"`

// Annotations overrides labels for the namespace and its template.
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
}

// WorkloadOverride defines the configurations of deployments to override.
type WorkloadOverride struct {
// Name is the name of the deployment to override.
Expand Down
65 changes: 65 additions & 0 deletions pkg/reconciler/common/namespace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
Copyright 2024 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package common

import (
mf "github.com/manifestival/manifestival"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/kubernetes/scheme"

"knative.dev/operator/pkg/apis/operator/base"
)

// NamespaceConfigurationTransform mutates the only namespace available for knative serving or eventing
// by changing the labels and annotations.
func NamespaceConfigurationTransform(namespaceConfiguration *base.NamespaceConfiguration) mf.Transformer {
return func(u *unstructured.Unstructured) error {
if u.GetKind() != "Namespace" || namespaceConfiguration == nil {
return nil
}
namespace := &corev1.Namespace{}
err := scheme.Scheme.Convert(u, namespace, nil)
if err != nil {
return err
}

// Override the labels for the namespace
if namespace.GetLabels() == nil {
namespace.Labels = map[string]string{}
}

for key, val := range namespaceConfiguration.Labels {
namespace.Labels[key] = val
}

// Override the annotations for the namespace
if namespace.GetAnnotations() == nil {
namespace.Annotations = map[string]string{}
}

for key, val := range namespaceConfiguration.Annotations {
namespace.Annotations[key] = val
}

err = scheme.Scheme.Convert(namespace, u, nil)
if err != nil {
return err
}
return nil
}
}
121 changes: 121 additions & 0 deletions pkg/reconciler/common/namespace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
Copyright 2024 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package common

import (
"testing"

"github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/kubernetes/scheme"

"knative.dev/operator/pkg/apis/operator/base"
)

func TestNamespaceConfigurationTransform(t *testing.T) {
tests := []struct {
name string
namespace *corev1.Namespace
override *base.NamespaceConfiguration
expLabels map[string]string
expAnnotations map[string]string
}{{
name: "Label override",
namespace: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "knative-serving",
Labels: map[string]string{
"istio-injection": "enabled",
"serving.knative.dev/release": "v0.13.0",
},
},
},
override: &base.NamespaceConfiguration{
Labels: map[string]string{"a": "b"},
},
expLabels: map[string]string{"a": "b", "istio-injection": "enabled", "serving.knative.dev/release": "v0.13.0"},
expAnnotations: nil,
}, {
name: "Annotation override",
namespace: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "knative-serving",
Labels: map[string]string{
"istio-injection": "enabled",
"serving.knative.dev/release": "v0.13.0",
},
},
},
override: &base.NamespaceConfiguration{
Annotations: map[string]string{"c": "d"},
},
expLabels: map[string]string{"istio-injection": "enabled", "serving.knative.dev/release": "v0.13.0"},
expAnnotations: map[string]string{"c": "d"},
}, {
name: "No override",
namespace: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "knative-serving",
Labels: map[string]string{
"istio-injection": "enabled",
"serving.knative.dev/release": "v0.13.0",
},
},
},
override: nil,
expLabels: map[string]string{"serving.knative.dev/release": "v0.13.0", "istio-injection": "enabled"},
expAnnotations: nil,
}, {
name: "Override both labels and annotations",
namespace: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "knative-serving",
},
},
override: &base.NamespaceConfiguration{
Labels: map[string]string{"c1": "d1", "j": "k"},
Annotations: map[string]string{"c": "d", "x": "y"},
},
expLabels: map[string]string{"j": "k", "c1": "d1"},
expAnnotations: map[string]string{"x": "y", "c": "d"},
}}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
u := &unstructured.Unstructured{}
err := scheme.Scheme.Convert(test.namespace, u, nil)
if err != nil {
t.Fatalf("Failed to convert namespace to unstructured: %v", err)
}
NamespaceConfigurationTransform(test.override)(u)
got := &corev1.Namespace{}
if err = scheme.Scheme.Convert(u, got, nil); err != nil {
t.Fatalf("Failed to convert unstructured to namespace: %v", err)
}

if diff := cmp.Diff(got.GetLabels(), test.expLabels); diff != "" {
t.Fatalf("Unexpected labels: %v", diff)
}

if diff := cmp.Diff(got.GetAnnotations(), test.expAnnotations); diff != "" {
t.Fatalf("Unexpected annotations: %v", diff)
}
})
}
}
1 change: 1 addition & 0 deletions pkg/reconciler/common/transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func transformers(ctx context.Context, obj base.KComponent) []mf.Transformer {
return []mf.Transformer{
injectOwner(obj),
mf.InjectNamespace(obj.GetNamespace()),
NamespaceConfigurationTransform(obj.GetSpec().GetNamespaceConfiguration()),
HighAvailabilityTransform(obj),
ImageTransform(obj.GetSpec().GetRegistry(), logger),
JobTransform(obj),
Expand Down
Loading