Skip to content
Closed
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
9 changes: 8 additions & 1 deletion cmd/operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,18 @@ package main
import (
"knative.dev/operator/pkg/reconciler/knativeeventing"
"knative.dev/operator/pkg/reconciler/knativeserving"
kubefilteredfactory "knative.dev/pkg/client/injection/kube/informers/factory/filtered"
"knative.dev/pkg/injection/sharedmain"
"knative.dev/pkg/signals"
)

func main() {
sharedmain.Main("knative-operator",
ctx := signals.NewContext()
ctx = kubefilteredfactory.WithSelectors(ctx,
knativeserving.Selector,
knativeeventing.Selector,
)
sharedmain.MainWithContext(ctx, "knative-operator",
knativeserving.NewController,
knativeeventing.NewController,
)
Expand Down
13 changes: 13 additions & 0 deletions pkg/reconciler/common/transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,16 @@ func InjectNamespace(manifest *mf.Manifest, instance base.KComponent, extra ...m
*manifest = m
return nil
}

// InjectLabel adds the given key and value as label.
func InjectLabel(key, value string) mf.Transformer {
return func(u *unstructured.Unstructured) error {
curr := u.GetLabels()
if curr == nil {
curr = map[string]string{}
}
curr[key] = value
u.SetLabels(curr)
return nil
}
}
19 changes: 17 additions & 2 deletions pkg/reconciler/knativeeventing/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,23 @@ import (
knereconciler "knative.dev/operator/pkg/client/injection/reconciler/operator/v1beta1/knativeeventing"
"knative.dev/operator/pkg/reconciler/common"
kubeclient "knative.dev/pkg/client/injection/kube/client"
deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment"
deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment/filtered"
configmapinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/configmap/filtered"
"knative.dev/pkg/configmap"
"knative.dev/pkg/controller"
"knative.dev/pkg/injection"
"knative.dev/pkg/logging"
)

const (
// SelectorKey is the key of the selector for the KnativeEventing resources.
SelectorKey = "app.kubernetes.io/name"
// SelectorValue is the value of the selector for the KnativeEventing resources.
SelectorValue = "knative-eventing"
// Selector is the selector for the KnativeEventing resources.
Selector = SelectorKey + "=" + SelectorValue
)

// NewController initializes the controller and is called by the generated code
// Registers eventhandlers to enqueue events
func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
Expand All @@ -45,7 +55,8 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl
func NewExtendedController(generator common.ExtensionGenerator) injection.ControllerConstructor {
return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
knativeEventingInformer := knativeEventinginformer.Get(ctx)
deploymentInformer := deploymentinformer.Get(ctx)
deploymentInformer := deploymentinformer.Get(ctx, Selector)
configMapInformer := configmapinformer.Get(ctx, Selector)
kubeClient := kubeclient.Get(ctx)
logger := logging.FromContext(ctx)

Expand All @@ -72,6 +83,10 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
FilterFunc: controller.FilterControllerGVK(v1beta1.SchemeGroupVersion.WithKind("KnativeEventing")),
Handler: controller.HandleAll(impl.EnqueueControllerOf),
})
configMapInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: controller.FilterControllerGVK(v1beta1.SchemeGroupVersion.WithKind("KnativeEventing")),
Handler: controller.HandleAll(impl.EnqueueControllerOf),
})

return impl
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/reconciler/knativeeventing/knativeeventing.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ func (r *Reconciler) transform(ctx context.Context, manifest *mf.Manifest, comp
kec.DefaultBrokerConfigMapTransform(instance, logger),
kec.SinkBindingSelectionModeTransform(instance, logger),
kec.ReplicasEnvVarsTransform(manifest.Client),
// Ensure all resources have the selector applied so that the controller re-queues applied resources when they change.
common.InjectLabel(SelectorKey, SelectorValue),
}
extra = append(extra, r.extension.Transformers(instance)...)
return common.Transform(ctx, manifest, instance, extra...)
Expand Down
19 changes: 17 additions & 2 deletions pkg/reconciler/knativeserving/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import (
knsreconciler "knative.dev/operator/pkg/client/injection/reconciler/operator/v1beta1/knativeserving"
"knative.dev/operator/pkg/reconciler/common"
kubeclient "knative.dev/pkg/client/injection/kube/client"
deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment"
deploymentinformer "knative.dev/pkg/client/injection/kube/informers/apps/v1/deployment/filtered"
configmapinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/configmap/filtered"
"knative.dev/pkg/configmap"
"knative.dev/pkg/controller"
"knative.dev/pkg/injection"
Expand All @@ -41,11 +42,21 @@ func NewController(ctx context.Context, cmw configmap.Watcher) *controller.Impl
return NewExtendedController(common.NoExtension)(ctx, cmw)
}

const (
// SelectorKey is the key of the selector for the KnativeServing resources.
SelectorKey = "app.kubernetes.io/name"
// SelectorValue is the value of the selector for the KnativeServing resources.
SelectorValue = "knative-serving"
// Selector is the selector for the KnativeServing resources.
Selector = SelectorKey + "=" + SelectorValue
)

// NewExtendedController returns a controller extended to a specific platform
func NewExtendedController(generator common.ExtensionGenerator) injection.ControllerConstructor {
return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
knativeServingInformer := knativeServinginformer.Get(ctx)
deploymentInformer := deploymentinformer.Get(ctx)
deploymentInformer := deploymentinformer.Get(ctx, Selector)
configMapInformer := configmapinformer.Get(ctx, Selector)
kubeClient := kubeclient.Get(ctx)
logger := logging.FromContext(ctx)

Expand All @@ -72,6 +83,10 @@ func NewExtendedController(generator common.ExtensionGenerator) injection.Contro
FilterFunc: controller.FilterControllerGVK(v1beta1.SchemeGroupVersion.WithKind("KnativeServing")),
Handler: controller.HandleAll(impl.EnqueueControllerOf),
})
configMapInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{
FilterFunc: controller.FilterControllerGVK(v1beta1.SchemeGroupVersion.WithKind("KnativeServing")),
Handler: controller.HandleAll(impl.EnqueueControllerOf),
})

return impl
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/reconciler/knativeserving/knativeserving.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ func (r *Reconciler) transform(ctx context.Context, manifest *mf.Manifest, comp
extra := []mf.Transformer{
ksc.CustomCertsTransform(instance, logger),
ksc.AggregationRuleTransform(manifest.Client),
// Ensure all resources have the selector applied so that the controller re-queues applied resources when they change.
common.InjectLabel(SelectorKey, SelectorValue),
}
extra = append(extra, r.extension.Transformers(instance)...)
extra = append(extra, ingress.Transformers(ctx, instance)...)
Expand Down
1 change: 1 addition & 0 deletions test/e2e/knativeeventingdeployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func TestKnativeEventingDeployment(t *testing.T) {
t.Run("restore", func(t *testing.T) {
resources.AssertKEOperatorCRReadyStatus(t, clients, names)
resources.DeleteAndVerifyEventingDeployments(t, clients, names)
resources.DeleteAndVerifyEventingConfigMaps(t, clients, names)
})

// Delete the KnativeEventing to see if all resources will be removed
Expand Down
1 change: 1 addition & 0 deletions test/e2e/knativeservingdeployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func TestKnativeServingDeployment(t *testing.T) {
t.Run("restore", func(t *testing.T) {
resources.AssertKSOperatorCRReadyStatus(t, clients, names)
resources.DeleteAndVerifyDeployments(t, clients, names)
resources.DeleteAndVerifyConfigMaps(t, clients, names)
})

// Delete the KnativeServing to see if all resources will be removed
Expand Down
81 changes: 81 additions & 0 deletions test/resources/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,47 @@ func DeleteAndVerifyDeployments(t *testing.T, clients *test.Clients, names test.
t.Logf("The deployment %s/%s reached the desired state.", deployment.Namespace, deployment.Name)
}

// DeleteAndVerifyConfigMaps verify whether all the ConfigMaps for knative serving are able to recreate, when they are deleted.
func DeleteAndVerifyConfigMaps(t *testing.T, clients *test.Clients, names test.ResourceNames) {
cmList, err := clients.KubeClient.CoreV1().ConfigMaps(names.Namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
t.Fatalf("Failed to get any ConfigMap under the namespace %q: %v",
test.ServingOperatorNamespace, err)
}
if len(cmList.Items) == 0 {
t.Fatalf("No ConfigMap under the namespace %q was found",
test.ServingOperatorNamespace)
}
// Delete the first ConfigMap and verify the operator recreates it
configMap := cmList.Items[0]
if err := clients.KubeClient.CoreV1().ConfigMaps(configMap.Namespace).Delete(context.TODO(), configMap.Name, metav1.DeleteOptions{}); err != nil {
t.Fatalf("Failed to delete ConfigMap %s/%s: %v", configMap.Namespace, configMap.Name, err)
}

waitErr := wait.PollUntilContextTimeout(context.TODO(), Interval, Timeout, true, func(context.Context) (bool, error) {
_, err := clients.KubeClient.CoreV1().ConfigMaps(configMap.Namespace).Get(context.TODO(), configMap.Name, metav1.GetOptions{})
if err != nil {
// If the ConfigMap is not found, we continue to wait for the availability.
if apierrs.IsNotFound(err) {
return false, nil
}
return false, err
}
// For ConfigMaps, we consider it recreated as soon as it reappears.
return true, nil
})

if waitErr != nil {
t.Fatalf("The ConfigMap %s/%s failed to be recreated: %v", configMap.Namespace, configMap.Name, err)
}

if _, err := WaitForKnativeServingState(clients.KnativeServing(), test.OperatorName,
IsKnativeServingReady); err != nil {
t.Fatalf("KnativeService %q failed to reach the desired state: %v", test.OperatorName, err)
}
t.Logf("The ConfigMap %s/%s was successfully recreated.", configMap.Namespace, configMap.Name)
}

// KSOperatorCRDelete deletes tha KnativeServing to see if all resources will be deleted
func KSOperatorCRDelete(t *testing.T, clients *test.Clients, names test.ResourceNames) {
if err := clients.KnativeServing().Delete(context.TODO(), names.KnativeServing, metav1.DeleteOptions{}); err != nil {
Expand Down Expand Up @@ -399,6 +440,46 @@ func DeleteAndVerifyEventingDeployments(t *testing.T, clients *test.Clients, nam
t.Logf("The deployment %s/%s reached the desired state.", deployment.Namespace, deployment.Name)
}

// DeleteAndVerifyEventingConfigMaps verify whether all the ConfigMaps for knative eventing are able to recreate, when they are deleted.
func DeleteAndVerifyEventingConfigMaps(t *testing.T, clients *test.Clients, names test.ResourceNames) {
cmList, err := clients.KubeClient.CoreV1().ConfigMaps(names.Namespace).List(context.TODO(), metav1.ListOptions{})
if err != nil {
t.Fatalf("Failed to get any ConfigMap under the namespace %q: %v",
test.EventingOperatorNamespace, err)
}
if len(cmList.Items) == 0 {
t.Fatalf("No ConfigMap under the namespace %q was found",
test.EventingOperatorNamespace)
}
// Delete the first ConfigMap and verify the operator recreates it
configMap := cmList.Items[0]
if err := clients.KubeClient.CoreV1().ConfigMaps(configMap.Namespace).Delete(context.TODO(), configMap.Name, metav1.DeleteOptions{}); err != nil {
t.Fatalf("Failed to delete ConfigMap %s/%s: %v", configMap.Namespace, configMap.Name, err)
}

waitErr := wait.PollUntilContextTimeout(context.TODO(), Interval, Timeout, true, func(context.Context) (bool, error) {
_, err := clients.KubeClient.CoreV1().ConfigMaps(configMap.Namespace).Get(context.TODO(), configMap.Name, metav1.GetOptions{})
if err != nil {
// If the ConfigMap is not found, we continue to wait for the availability.
if apierrs.IsNotFound(err) {
return false, nil
}
return false, err
}
return true, nil
})

if waitErr != nil {
t.Fatalf("The ConfigMap %s/%s failed to reach the desired state: %v", configMap.Namespace, configMap.Name, err)
}

if _, err := WaitForKnativeEventingState(clients.KnativeEventing(), test.OperatorName,
IsKnativeEventingReady); err != nil {
t.Fatalf("KnativeService %q failed to reach the desired state: %v", test.OperatorName, err)
}
t.Logf("The ConfigMap %s/%s reached the desired state.", configMap.Namespace, configMap.Name)
}

// KEOperatorCRDelete deletes tha KnativeEventing to see if all resources will be deleted
func KEOperatorCRDelete(t *testing.T, clients *test.Clients, names test.ResourceNames) {
if err := clients.KnativeEventing().Delete(context.TODO(), names.KnativeEventing, metav1.DeleteOptions{}); err != nil {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading