From 25debe967476ec06cb010caa2347ce07613c92d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Luk=C5=A1a?= Date: Fri, 19 Apr 2024 14:35:43 +0200 Subject: [PATCH 1/3] Use INFO level to log missing namespace in IstioRevision/IstioCNI (#64) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marko Lukša --- controllers/istiocni/istiocni_controller.go | 27 ++++++++++++++----- .../istiorevision/istiorevision_controller.go | 26 +++++++++++++----- go.mod | 1 + 3 files changed, 40 insertions(+), 14 deletions(-) diff --git a/controllers/istiocni/istiocni_controller.go b/controllers/istiocni/istiocni_controller.go index 747b33ea8..8ca919ac1 100644 --- a/controllers/istiocni/istiocni_controller.go +++ b/controllers/istiocni/istiocni_controller.go @@ -36,6 +36,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" @@ -43,6 +44,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" + "istio.io/istio/pkg/log" "istio.io/istio/pkg/ptr" ) @@ -92,12 +94,7 @@ func NewReconciler( func (r *Reconciler) Reconcile(ctx context.Context, cni *v1alpha1.IstioCNI) (ctrl.Result, error) { log := logf.FromContext(ctx) - if err := validateIstioCNI(cni); err != nil { - return ctrl.Result{}, err - } - - log.Info("Installing components") - reconcileErr := r.installHelmChart(ctx, cni) + reconcileErr := r.doReconcile(ctx, cni) log.Info("Reconciliation done. Updating status.") statusErr := r.updateStatus(ctx, cni, reconcileErr) @@ -109,13 +106,29 @@ func (r *Reconciler) Finalize(ctx context.Context, cni *v1alpha1.IstioCNI) error return r.uninstallHelmChart(ctx, cni) } -func validateIstioCNI(cni *v1alpha1.IstioCNI) error { +func (r *Reconciler) doReconcile(ctx context.Context, cni *v1alpha1.IstioCNI) error { + if err := r.validateIstioCNI(ctx, cni); err != nil { + return err + } + + log.Info("Installing Helm chart") + return r.installHelmChart(ctx, cni) +} + +func (r *Reconciler) validateIstioCNI(ctx context.Context, cni *v1alpha1.IstioCNI) error { if cni.Spec.Version == "" { return reconciler.NewValidationError("spec.version not set") } if cni.Spec.Namespace == "" { return reconciler.NewValidationError("spec.namespace not set") } + + if err := r.Client.Get(ctx, types.NamespacedName{Name: cni.Spec.Namespace}, &corev1.Namespace{}); err != nil { + if apierrors.IsNotFound(err) { + return reconciler.NewValidationError(fmt.Sprintf("namespace %q doesn't exist", cni.Spec.Namespace)) + } + return err + } return nil } diff --git a/controllers/istiorevision/istiorevision_controller.go b/controllers/istiorevision/istiorevision_controller.go index bbb2a2e50..203af0670 100644 --- a/controllers/istiorevision/istiorevision_controller.go +++ b/controllers/istiorevision/istiorevision_controller.go @@ -50,6 +50,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" + "istio.io/istio/pkg/log" "istio.io/istio/pkg/ptr" ) @@ -100,12 +101,7 @@ func NewReconciler(client client.Client, scheme *runtime.Scheme, resourceDir str func (r *Reconciler) Reconcile(ctx context.Context, rev *v1alpha1.IstioRevision) (ctrl.Result, error) { log := logf.FromContext(ctx) - if err := validateIstioRevision(rev); err != nil { - return ctrl.Result{}, err - } - - log.Info("Installing components") - reconcileErr := r.installHelmCharts(ctx, rev) + reconcileErr := r.doReconcile(ctx, rev) log.Info("Reconciliation done. Updating status.") statusErr := r.updateStatus(ctx, rev, reconcileErr) @@ -113,17 +109,33 @@ func (r *Reconciler) Reconcile(ctx context.Context, rev *v1alpha1.IstioRevision) return ctrl.Result{}, errors.Join(reconcileErr, statusErr) } +func (r *Reconciler) doReconcile(ctx context.Context, rev *v1alpha1.IstioRevision) error { + if err := r.validateIstioRevision(ctx, rev); err != nil { + return err + } + + log.Info("Installing Helm chart") + return r.installHelmCharts(ctx, rev) +} + func (r *Reconciler) Finalize(ctx context.Context, rev *v1alpha1.IstioRevision) error { return r.uninstallHelmCharts(ctx, rev) } -func validateIstioRevision(rev *v1alpha1.IstioRevision) error { +func (r *Reconciler) validateIstioRevision(ctx context.Context, rev *v1alpha1.IstioRevision) error { if rev.Spec.Version == "" { return reconciler.NewValidationError("spec.version not set") } if rev.Spec.Namespace == "" { return reconciler.NewValidationError("spec.namespace not set") } + if err := r.Client.Get(ctx, types.NamespacedName{Name: rev.Spec.Namespace}, &corev1.Namespace{}); err != nil { + if apierrors.IsNotFound(err) { + return reconciler.NewValidationError(fmt.Sprintf("namespace %q doesn't exist", rev.Spec.Namespace)) + } + return err + } + if rev.Spec.Values == nil { return reconciler.NewValidationError("spec.values not set") } diff --git a/go.mod b/go.mod index f0fb968d0..9cb1e3c6e 100644 --- a/go.mod +++ b/go.mod @@ -156,6 +156,7 @@ require ( google.golang.org/grpc v1.61.0 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.5.1 // indirect istio.io/api v1.19.0-alpha.1.0.20240224002031-63dcee0970de // indirect From 3067e15f73f7675b04674f9e345387added1d7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Luk=C5=A1a?= Date: Fri, 19 Apr 2024 15:31:42 +0200 Subject: [PATCH 2/3] Ensure control plane is deployed immediately when the target namespace is created (#65) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marko Lukša --- controllers/istiocni/istiocni_controller.go | 2 +- .../istiorevision/istiorevision_controller.go | 30 +++++++-- pkg/kube/key.go | 27 ++++++++ tests/e2e/controlplane/control_plane_test.go | 27 ++++---- tests/e2e/operator/operator_install_test.go | 7 +- tests/e2e/util/client/client.go | 6 +- tests/e2e/util/common/e2e_utils.go | 10 --- tests/integration/api/istiorevision_test.go | 66 +++++++++++++++++++ 8 files changed, 138 insertions(+), 37 deletions(-) create mode 100644 pkg/kube/key.go diff --git a/controllers/istiocni/istiocni_controller.go b/controllers/istiocni/istiocni_controller.go index 8ca919ac1..cc48772cb 100644 --- a/controllers/istiocni/istiocni_controller.go +++ b/controllers/istiocni/istiocni_controller.go @@ -44,7 +44,6 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "istio.io/istio/pkg/log" "istio.io/istio/pkg/ptr" ) @@ -107,6 +106,7 @@ func (r *Reconciler) Finalize(ctx context.Context, cni *v1alpha1.IstioCNI) error } func (r *Reconciler) doReconcile(ctx context.Context, cni *v1alpha1.IstioCNI) error { + log := logf.FromContext(ctx) if err := r.validateIstioCNI(ctx, cni); err != nil { return err } diff --git a/controllers/istiorevision/istiorevision_controller.go b/controllers/istiorevision/istiorevision_controller.go index 203af0670..e66b20614 100644 --- a/controllers/istiorevision/istiorevision_controller.go +++ b/controllers/istiorevision/istiorevision_controller.go @@ -50,7 +50,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" - "istio.io/istio/pkg/log" "istio.io/istio/pkg/ptr" ) @@ -110,6 +109,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, rev *v1alpha1.IstioRevision) } func (r *Reconciler) doReconcile(ctx context.Context, rev *v1alpha1.IstioRevision) error { + log := logf.FromContext(ctx) if err := r.validateIstioRevision(ctx, rev); err != nil { return err } @@ -187,8 +187,12 @@ func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error { // ownedResourceHandler handles resources that are owned by the IstioRevision CR ownedResourceHandler := handler.EnqueueRequestForOwner(r.Scheme, r.RESTMapper(), &v1alpha1.IstioRevision{}, handler.OnlyControllerOwner()) - // nsHandler handles namespaces that reference the IstioRevision CR via the istio.io/rev or istio-injection labels. - // The handler triggers the reconciliation of the referenced IstioRevision CR so that its InUse condition is updated. + // nsHandler triggers reconciliation in two cases: + // - when a namespace that is referenced in IstioRevision.spec.namespace is + // created, so that the control plane is installed immediately. + // - when a namespace that references the IstioRevision CR via the istio.io/rev + // or istio-injection labels is updated, so that the InUse condition of + // the IstioRevision CR is updated. nsHandler := handler.EnqueueRequestsFromMapFunc(r.mapNamespaceToReconcileRequest) // podHandler handles pods that reference the IstioRevision CR via the istio.io/rev or sidecar.istio.io/inject labels. @@ -433,11 +437,27 @@ func istiodDeploymentKey(rev *v1alpha1.IstioRevision) client.ObjectKey { } func (r *Reconciler) mapNamespaceToReconcileRequest(ctx context.Context, ns client.Object) []reconcile.Request { + log := logf.FromContext(ctx) + var requests []reconcile.Request + + // Check if any IstioRevision references this namespace in .spec.namespace + revList := v1alpha1.IstioRevisionList{} + if err := r.Client.List(ctx, &revList); err != nil { + log.Error(err, "failed to list IstioRevisions") + return nil + } + for _, rev := range revList.Items { + if rev.Spec.Namespace == ns.GetName() { + requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{Name: rev.Name}}) + } + } + + // Check if the namespace references an IstioRevision in its labels revision := getReferencedRevisionFromNamespace(ns.GetLabels()) if revision != "" { - return []reconcile.Request{{NamespacedName: types.NamespacedName{Name: revision}}} + requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{Name: revision}}) } - return nil + return requests } func (r *Reconciler) mapPodToReconcileRequest(ctx context.Context, pod client.Object) []reconcile.Request { diff --git a/pkg/kube/key.go b/pkg/kube/key.go new file mode 100644 index 000000000..116359fd3 --- /dev/null +++ b/pkg/kube/key.go @@ -0,0 +1,27 @@ +// Copyright Istio 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 kube + +import "sigs.k8s.io/controller-runtime/pkg/client" + +// key returns the client.ObjectKey for the given name and namespace. If no namespace is provided, it returns a key cluster scoped +func Key(name string, namespace ...string) client.ObjectKey { + if len(namespace) > 1 { + panic("you can only provide one namespace") + } else if len(namespace) == 1 { + return client.ObjectKey{Name: name, Namespace: namespace[0]} + } + return client.ObjectKey{Name: name} +} diff --git a/tests/e2e/controlplane/control_plane_test.go b/tests/e2e/controlplane/control_plane_test.go index 06ad9915b..2a90acbbf 100644 --- a/tests/e2e/controlplane/control_plane_test.go +++ b/tests/e2e/controlplane/control_plane_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/istio-ecosystem/sail-operator/api/v1alpha1" + "github.com/istio-ecosystem/sail-operator/pkg/kube" . "github.com/istio-ecosystem/sail-operator/pkg/test/util/ginkgo" "github.com/istio-ecosystem/sail-operator/pkg/test/util/supportedversion" common "github.com/istio-ecosystem/sail-operator/tests/e2e/util/common" @@ -58,7 +59,7 @@ var _ = Describe("Control Plane Installation", Ordered, func() { Expect(helm.Install("sail-operator", filepath.Join(baseDir, "chart"), "--namespace "+namespace, "--set=image="+image, extraArg)). To(Succeed(), "Operator failed to be deployed") - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key(deploymentName, namespace), &appsv1.Deployment{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key(deploymentName, namespace), &appsv1.Deployment{}). Should(HaveCondition(appsv1.DeploymentAvailable, metav1.ConditionTrue), "Error getting Istio CRD") Success("Operator is deployed in the namespace and Running") }) @@ -78,12 +79,12 @@ metadata: Success("IstioCNI created") cni := &v1alpha1.IstioCNI{} - Expect(cl.Get(ctx, common.Key("default"), cni)).To(Succeed()) + Expect(cl.Get(ctx, kube.Key("default"), cni)).To(Succeed()) Expect(cni.Spec.Version).To(Equal(supportedversion.Default)) Expect(cni.Spec.Namespace).To(Equal("istio-cni")) Expect(cl.Delete(ctx, cni)).To(Succeed()) - Eventually(cl.Get).WithArguments(ctx, common.Key("default"), cni).Should(ReturnNotFoundError()) + Eventually(cl.Get).WithArguments(ctx, kube.Key("default"), cni).Should(ReturnNotFoundError()) }, ) @@ -102,14 +103,14 @@ metadata: Success("Istio created") istio := &v1alpha1.Istio{} - Expect(cl.Get(ctx, common.Key("default"), istio)).To(Succeed()) + Expect(cl.Get(ctx, kube.Key("default"), istio)).To(Succeed()) Expect(istio.Spec.Version).To(Equal(supportedversion.Default)) Expect(istio.Spec.Namespace).To(Equal("istio-system")) Expect(istio.Spec.UpdateStrategy).ToNot(BeNil()) Expect(istio.Spec.UpdateStrategy.Type).To(Equal(v1alpha1.UpdateStrategyTypeInPlace)) Expect(cl.Delete(ctx, istio)).To(Succeed()) - Eventually(cl.Get).WithArguments(ctx, common.Key("default"), istio).Should(ReturnNotFoundError()) + Eventually(cl.Get).WithArguments(ctx, kube.Key("default"), istio).Should(ReturnNotFoundError()) }, ) }) @@ -144,7 +145,7 @@ spec: It("deploys the CNI DaemonSet", func(ctx SpecContext) { Eventually(func(g Gomega) { daemonset := &appsv1.DaemonSet{} - g.Expect(cl.Get(ctx, common.Key("istio-cni-node", istioCniNamespace), daemonset)).To(Succeed(), "Error getting IstioCNI DaemonSet") + g.Expect(cl.Get(ctx, kube.Key("istio-cni-node", istioCniNamespace), daemonset)).To(Succeed(), "Error getting IstioCNI DaemonSet") g.Expect(daemonset.Status.NumberAvailable). To(Equal(daemonset.Status.CurrentNumberScheduled), "CNI DaemonSet Pods not Available; expected numberAvailable to be equal to currentNumberScheduled") }).Should(Succeed(), "CNI DaemonSet Pods are not Available") @@ -152,13 +153,13 @@ spec: }) It("updates the status to Reconciled", func(ctx SpecContext) { - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key(istioCniName), &v1alpha1.IstioCNI{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key(istioCniName), &v1alpha1.IstioCNI{}). Should(HaveCondition(v1alpha1.IstioCNIConditionReconciled, metav1.ConditionTrue), "IstioCNI is not Reconciled; unexpected Condition") Success("IstioCNI is Reconciled") }) It("updates the status to Ready", func(ctx SpecContext) { - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key(istioCniName), &v1alpha1.IstioCNI{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key(istioCniName), &v1alpha1.IstioCNI{}). Should(HaveCondition(v1alpha1.IstioCNIConditionReady, metav1.ConditionTrue), "IstioCNI is not Ready; unexpected Condition") Success("IstioCNI is Ready") }) @@ -188,19 +189,19 @@ spec: }) It("updates the Istio CR status to Reconciled", func(ctx SpecContext) { - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key(istioName), &v1alpha1.Istio{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key(istioName), &v1alpha1.Istio{}). Should(HaveCondition(v1alpha1.IstioConditionReconciled, metav1.ConditionTrue), "Istio is not Reconciled; unexpected Condition") Success("Istio CR is Reconciled") }) It("updates the Istio CR status to Ready", func(ctx SpecContext) { - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key(istioName), &v1alpha1.Istio{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key(istioName), &v1alpha1.Istio{}). Should(HaveCondition(v1alpha1.IstioConditionReady, metav1.ConditionTrue), "Istio is not Ready; unexpected Condition") Success("Istio CR is Ready") }) It("deploys istiod", func(ctx SpecContext) { - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key("istiod", controlPlaneNamespace), &appsv1.Deployment{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key("istiod", controlPlaneNamespace), &appsv1.Deployment{}). Should(HaveCondition(appsv1.DeploymentAvailable, metav1.ConditionTrue), "Istiod is not Available; unexpected Condition") Expect(getVersionFromIstiod()).To(Equal(version.Version), "Unexpected istiod version") Success("Istiod is deployed in the namespace and Running") @@ -220,7 +221,7 @@ spec: }) It("removes everything from the namespace", func(ctx SpecContext) { - Eventually(cl.Get).WithArguments(ctx, common.Key("istiod", controlPlaneNamespace), &appsv1.Deployment{}). + Eventually(cl.Get).WithArguments(ctx, kube.Key("istiod", controlPlaneNamespace), &appsv1.Deployment{}). Should(ReturnNotFoundError(), "Istiod should not exist anymore") common.CheckNamespaceEmpty(ctx, cl, controlPlaneNamespace) Success("Namespace is empty") @@ -235,7 +236,7 @@ spec: It("removes everything from the CNI namespace", func(ctx SpecContext) { daemonset := &appsv1.DaemonSet{} - Eventually(cl.Get).WithArguments(ctx, common.Key("istio-cni-node", istioCniNamespace), daemonset). + Eventually(cl.Get).WithArguments(ctx, kube.Key("istio-cni-node", istioCniNamespace), daemonset). Should(ReturnNotFoundError(), "IstioCNI DaemonSet should not exist anymore") common.CheckNamespaceEmpty(ctx, cl, istioCniNamespace) Success("CNI namespace is empty") diff --git a/tests/e2e/operator/operator_install_test.go b/tests/e2e/operator/operator_install_test.go index 0dfdd96ce..102198917 100644 --- a/tests/e2e/operator/operator_install_test.go +++ b/tests/e2e/operator/operator_install_test.go @@ -20,6 +20,7 @@ import ( "path/filepath" "time" + "github.com/istio-ecosystem/sail-operator/pkg/kube" . "github.com/istio-ecosystem/sail-operator/pkg/test/util/ginkgo" common "github.com/istio-ecosystem/sail-operator/tests/e2e/util/common" . "github.com/istio-ecosystem/sail-operator/tests/e2e/util/gomega" @@ -84,7 +85,7 @@ var _ = Describe("Operator", Ordered, func() { It("updates the CRDs status to Established", func(ctx SpecContext) { for _, crdName := range sailCRDs { - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key(crdName), &apiextensionsv1.CustomResourceDefinition{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key(crdName), &apiextensionsv1.CustomResourceDefinition{}). Should(HaveCondition(apiextensionsv1.Established, metav1.ConditionTrue), "Error getting Istio CRD") } Success("CRDs are Established") @@ -92,13 +93,13 @@ var _ = Describe("Operator", Ordered, func() { Specify("istio crd is present", func(ctx SpecContext) { // When the operator runs in OCP cluster, the CRD is created but not available at the moment - Eventually(cl.Get).WithArguments(ctx, common.Key("istios.operator.istio.io"), &apiextensionsv1.CustomResourceDefinition{}). + Eventually(cl.Get).WithArguments(ctx, kube.Key("istios.operator.istio.io"), &apiextensionsv1.CustomResourceDefinition{}). Should(Succeed(), "Error getting Istio CRD") Success("Istio CRD is present") }) It("starts successfully", func(ctx SpecContext) { - Eventually(common.GetObject).WithArguments(ctx, cl, common.Key(deploymentName, namespace), &appsv1.Deployment{}). + Eventually(common.GetObject).WithArguments(ctx, cl, kube.Key(deploymentName, namespace), &appsv1.Deployment{}). Should(HaveCondition(appsv1.DeploymentAvailable, metav1.ConditionTrue), "Error getting Istio CRD") }) diff --git a/tests/e2e/util/client/client.go b/tests/e2e/util/client/client.go index 70243c83b..9ab45ee74 100644 --- a/tests/e2e/util/client/client.go +++ b/tests/e2e/util/client/client.go @@ -15,7 +15,6 @@ package client import ( - "flag" "fmt" "log" "os" @@ -29,11 +28,8 @@ import ( // getConfig returns the configuration of the kubernetes go-client func getConfig() (*rest.Config, error) { - kubeconfig := flag.String("kubeconfig", os.Getenv("KUBECONFIG"), "(optional) absolute path to the kubeconfig file") - flag.Parse() - // use the current context in kubeconfig - config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) + config, err := clientcmd.BuildConfigFromFlags("", os.Getenv("KUBECONFIG")) if err != nil { return nil, fmt.Errorf("error building config: %w", err) } diff --git a/tests/e2e/util/common/e2e_utils.go b/tests/e2e/util/common/e2e_utils.go index efa4976fc..49b4c6f62 100644 --- a/tests/e2e/util/common/e2e_utils.go +++ b/tests/e2e/util/common/e2e_utils.go @@ -41,16 +41,6 @@ var ( istioCniNamespace = env.Get("ISTIOCNI_NAMESPACE", "istio-cni") ) -// key returns the client.ObjectKey for the given name and namespace. If no namespace is provided, it returns a key cluster scoped -func Key(name string, namespace ...string) client.ObjectKey { - if len(namespace) > 1 { - panic("you can only provide one namespace") - } else if len(namespace) == 1 { - return client.ObjectKey{Name: name, Namespace: namespace[0]} - } - return client.ObjectKey{Name: name} -} - // getObject returns the object with the given key func GetObject(ctx context.Context, cl client.Client, key client.ObjectKey, obj client.Object) (client.Object, error) { err := cl.Get(ctx, key, obj) diff --git a/tests/integration/api/istiorevision_test.go b/tests/integration/api/istiorevision_test.go index 4d5c88794..46d75dae9 100644 --- a/tests/integration/api/istiorevision_test.go +++ b/tests/integration/api/istiorevision_test.go @@ -21,6 +21,7 @@ import ( "time" "github.com/istio-ecosystem/sail-operator/api/v1alpha1" + "github.com/istio-ecosystem/sail-operator/pkg/kube" . "github.com/istio-ecosystem/sail-operator/pkg/test/util/ginkgo" "github.com/istio-ecosystem/sail-operator/pkg/test/util/supportedversion" . "github.com/onsi/ginkgo/v2" @@ -158,6 +159,71 @@ var _ = Describe("IstioRevision resource", Ordered, func() { }) }) + Describe("reconciles immediately after target namespace is created", func() { + BeforeAll(func() { + Step("Creating the IstioRevision resource without the namespace") + rev = &v1alpha1.IstioRevision{ + ObjectMeta: metav1.ObjectMeta{ + Name: revName, + }, + Spec: v1alpha1.IstioRevisionSpec{ + Version: supportedversion.Default, + Namespace: "nonexistent-namespace", + Values: &v1alpha1.Values{ + Revision: revName, + Global: &v1alpha1.GlobalConfig{ + IstioNamespace: "nonexistent-namespace", + }, + }, + }, + } + Expect(k8sClient.Create(ctx, rev)).To(Succeed()) + }) + + AfterAll(func() { + Expect(k8sClient.Delete(ctx, rev)).To(Succeed()) + Eventually(k8sClient.Get).WithArguments(ctx, kube.Key(revName), rev).Should(ReturnNotFoundError()) + }) + + It("indicates in the status that the namespace doesn't exist", func() { + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, revKey, rev)).To(Succeed()) + g.Expect(rev.Status.ObservedGeneration).To(Equal(rev.ObjectMeta.Generation)) + + reconciled := rev.Status.GetCondition(v1alpha1.IstioRevisionConditionReconciled) + g.Expect(reconciled.Status).To(Equal(metav1.ConditionFalse)) + g.Expect(reconciled.Reason).To(Equal(v1alpha1.IstioRevisionReasonReconcileError)) + g.Expect(reconciled.Message).To(ContainSubstring(`namespace "nonexistent-namespace" doesn't exist`)) + }).Should(Succeed()) + }) + + When("the namespace is created", func() { + BeforeAll(func() { + ns := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "nonexistent-namespace", + }, + } + Expect(k8sClient.Create(ctx, ns)).To(Succeed()) + }) + + It("reconciles immediately", func() { + Step("Checking if istiod is deployed immediately") + istiod := &appsv1.Deployment{} + istiodKey := client.ObjectKey{Name: "istiod-" + revName, Namespace: "nonexistent-namespace"} + Eventually(k8sClient.Get).WithArguments(ctx, istiodKey, istiod).WithTimeout(10 * time.Second).Should(Succeed()) + + Step("Checking if the status is updated") + Eventually(func(g Gomega) { + g.Expect(k8sClient.Get(ctx, revKey, rev)).To(Succeed()) + g.Expect(rev.Status.ObservedGeneration).To(Equal(rev.ObjectMeta.Generation)) + reconciled := rev.Status.GetCondition(v1alpha1.IstioRevisionConditionReconciled) + g.Expect(reconciled.Status).To(Equal(metav1.ConditionTrue)) + }).Should(Succeed()) + }) + }) + }) + It("successfully reconciles the resource", func() { Step("Creating the custom resource") rev = &v1alpha1.IstioRevision{ From 823ef1f2039ebef044218da8babfea4170d21fc8 Mon Sep 17 00:00:00 2001 From: Istio Automation Date: Fri, 19 Apr 2024 16:07:52 -0700 Subject: [PATCH 3/3] Automator: Update dependencies in istio-ecosystem/sail-operator@main (#66) Signed-off-by: istio-testing --- .../sailoperator.clusterserviceversion.yaml | 4 ++-- chart/values.yaml | 2 +- go.mod | 1 - resources/latest/charts/base/Chart.yaml | 4 ++-- resources/latest/charts/cni/Chart.yaml | 4 ++-- resources/latest/charts/cni/values.yaml | 2 +- resources/latest/charts/gateway/Chart.yaml | 4 ++-- resources/latest/charts/istiod/Chart.yaml | 4 ++-- .../latest/charts/istiod/files/kube-gateway.yaml | 2 +- resources/latest/charts/istiod/values.yaml | 2 +- resources/latest/charts/ztunnel/Chart.yaml | 4 ++-- resources/latest/charts/ztunnel/values.yaml | 2 +- versions.yaml | 12 ++++++------ 13 files changed, 23 insertions(+), 24 deletions(-) diff --git a/bundle/manifests/sailoperator.clusterserviceversion.yaml b/bundle/manifests/sailoperator.clusterserviceversion.yaml index 25d19dd50..71bd34280 100644 --- a/bundle/manifests/sailoperator.clusterserviceversion.yaml +++ b/bundle/manifests/sailoperator.clusterserviceversion.yaml @@ -34,7 +34,7 @@ metadata: capabilities: Seamless Upgrades categories: OpenShift Optional, Integration & Delivery, Networking, Security containerImage: quay.io/maistra-dev/sail-operator:3.0-latest - createdAt: "2024-04-18T23:02:03Z" + createdAt: "2024-04-19T23:01:33Z" description: Experimental operator for installing Istio service mesh features.operators.openshift.io/cnf: "false" features.operators.openshift.io/cni: "true" @@ -288,7 +288,7 @@ spec: This version of the operator supports the following Istio versions: - v1.21.0 - - latest (bf9fd612) + - latest (3112392b) [See this page](https://github.com/istio-ecosystem/sail-operator/blob/pre-main/bundle/README.md) for instructions on how to use it. displayName: Sail Operator diff --git a/chart/values.yaml b/chart/values.yaml index 2fa051c0b..ade97a306 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -17,7 +17,7 @@ csv: This version of the operator supports the following Istio versions: - v1.21.0 - - latest (bf9fd612) + - latest (3112392b) [See this page](https://github.com/istio-ecosystem/sail-operator/blob/pre-main/bundle/README.md) for instructions on how to use it. support: Community based diff --git a/go.mod b/go.mod index 9cb1e3c6e..f0fb968d0 100644 --- a/go.mod +++ b/go.mod @@ -156,7 +156,6 @@ require ( google.golang.org/grpc v1.61.0 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gotest.tools/v3 v3.5.1 // indirect istio.io/api v1.19.0-alpha.1.0.20240224002031-63dcee0970de // indirect diff --git a/resources/latest/charts/base/Chart.yaml b/resources/latest/charts/base/Chart.yaml index 05701b759..ec7ae3bad 100644 --- a/resources/latest/charts/base/Chart.yaml +++ b/resources/latest/charts/base/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +appVersion: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d description: Helm chart for deploying Istio cluster resources and CRDs icon: https://istio.io/latest/favicons/android-192x192.png keywords: @@ -7,4 +7,4 @@ keywords: name: base sources: - https://github.com/istio/istio -version: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +version: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d diff --git a/resources/latest/charts/cni/Chart.yaml b/resources/latest/charts/cni/Chart.yaml index 5b2ee9711..5caa528ed 100644 --- a/resources/latest/charts/cni/Chart.yaml +++ b/resources/latest/charts/cni/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +appVersion: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d description: Helm chart for istio-cni components icon: https://istio.io/latest/favicons/android-192x192.png keywords: @@ -8,4 +8,4 @@ keywords: name: cni sources: - https://github.com/istio/istio/tree/master/cni -version: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +version: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d diff --git a/resources/latest/charts/cni/values.yaml b/resources/latest/charts/cni/values.yaml index fbbde7c79..7209c9411 100644 --- a/resources/latest/charts/cni/values.yaml +++ b/resources/latest/charts/cni/values.yaml @@ -110,7 +110,7 @@ defaults: hub: gcr.io/istio-testing # Default tag for Istio images. - tag: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 + tag: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d # Variant of the image to use. # Currently supported are: [debug, distroless] diff --git a/resources/latest/charts/gateway/Chart.yaml b/resources/latest/charts/gateway/Chart.yaml index b258a91c5..6241b3071 100644 --- a/resources/latest/charts/gateway/Chart.yaml +++ b/resources/latest/charts/gateway/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -appVersion: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +appVersion: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d description: Helm chart for deploying Istio gateways icon: https://istio.io/latest/favicons/android-192x192.png keywords: @@ -9,4 +9,4 @@ name: gateway sources: - https://github.com/istio/istio type: application -version: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +version: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d diff --git a/resources/latest/charts/istiod/Chart.yaml b/resources/latest/charts/istiod/Chart.yaml index f34043bf7..60dd5a678 100644 --- a/resources/latest/charts/istiod/Chart.yaml +++ b/resources/latest/charts/istiod/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +appVersion: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d description: Helm chart for istio control plane icon: https://istio.io/latest/favicons/android-192x192.png keywords: @@ -9,4 +9,4 @@ keywords: name: istiod sources: - https://github.com/istio/istio -version: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +version: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d diff --git a/resources/latest/charts/istiod/files/kube-gateway.yaml b/resources/latest/charts/istiod/files/kube-gateway.yaml index 512859b04..8d1dc5de9 100644 --- a/resources/latest/charts/istiod/files/kube-gateway.yaml +++ b/resources/latest/charts/istiod/files/kube-gateway.yaml @@ -138,7 +138,7 @@ spec: {{- end }} {{- if .Values.global.proxy.lifecycle }} lifecycle: - {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} + {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} {{- end }} env: - name: PILOT_CERT_PROVIDER diff --git a/resources/latest/charts/istiod/values.yaml b/resources/latest/charts/istiod/values.yaml index a4ddd3643..bbc802294 100644 --- a/resources/latest/charts/istiod/values.yaml +++ b/resources/latest/charts/istiod/values.yaml @@ -231,7 +231,7 @@ defaults: # Dev builds from prow are on gcr.io hub: gcr.io/istio-testing # Default tag for Istio images. - tag: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 + tag: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d # Variant of the image to use. # Currently supported are: [debug, distroless] variant: "" diff --git a/resources/latest/charts/ztunnel/Chart.yaml b/resources/latest/charts/ztunnel/Chart.yaml index dca74af72..aaa68dae5 100644 --- a/resources/latest/charts/ztunnel/Chart.yaml +++ b/resources/latest/charts/ztunnel/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +appVersion: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d description: Helm chart for istio ztunnel components icon: https://istio.io/latest/favicons/android-192x192.png keywords: @@ -8,4 +8,4 @@ keywords: name: ztunnel sources: - https://github.com/istio/istio -version: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 +version: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d diff --git a/resources/latest/charts/ztunnel/values.yaml b/resources/latest/charts/ztunnel/values.yaml index dd58a35a0..1668ed15c 100644 --- a/resources/latest/charts/ztunnel/values.yaml +++ b/resources/latest/charts/ztunnel/values.yaml @@ -2,7 +2,7 @@ defaults: # Hub to pull from. Image will be `Hub/Image:Tag-Variant` hub: gcr.io/istio-testing # Tag to pull from. Image will be `Hub/Image:Tag-Variant` - tag: 1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749 + tag: 1.22-alpha.3112392b96748f15315150044244f0052a2f730d # Variant to pull. Options are "debug" or "distroless". Unset will use the default for the given version. variant: "" diff --git a/versions.yaml b/versions.yaml index 7dd909cf8..1750fb0a1 100644 --- a/versions.yaml +++ b/versions.yaml @@ -24,10 +24,10 @@ versions: version: 1.22-alpha repo: https://github.com/istio/istio branch: master - commit: bf9fd6127f5bebf2f0024362f3c687849f390749 + commit: 3112392b96748f15315150044244f0052a2f730d charts: - - https://storage.googleapis.com/istio-build/dev/1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749/helm/base-1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749.tgz - - https://storage.googleapis.com/istio-build/dev/1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749/helm/cni-1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749.tgz - - https://storage.googleapis.com/istio-build/dev/1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749/helm/gateway-1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749.tgz - - https://storage.googleapis.com/istio-build/dev/1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749/helm/istiod-1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749.tgz - - https://storage.googleapis.com/istio-build/dev/1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749/helm/ztunnel-1.22-alpha.bf9fd6127f5bebf2f0024362f3c687849f390749.tgz + - https://storage.googleapis.com/istio-build/dev/1.22-alpha.3112392b96748f15315150044244f0052a2f730d/helm/base-1.22-alpha.3112392b96748f15315150044244f0052a2f730d.tgz + - https://storage.googleapis.com/istio-build/dev/1.22-alpha.3112392b96748f15315150044244f0052a2f730d/helm/cni-1.22-alpha.3112392b96748f15315150044244f0052a2f730d.tgz + - https://storage.googleapis.com/istio-build/dev/1.22-alpha.3112392b96748f15315150044244f0052a2f730d/helm/gateway-1.22-alpha.3112392b96748f15315150044244f0052a2f730d.tgz + - https://storage.googleapis.com/istio-build/dev/1.22-alpha.3112392b96748f15315150044244f0052a2f730d/helm/istiod-1.22-alpha.3112392b96748f15315150044244f0052a2f730d.tgz + - https://storage.googleapis.com/istio-build/dev/1.22-alpha.3112392b96748f15315150044244f0052a2f730d/helm/ztunnel-1.22-alpha.3112392b96748f15315150044244f0052a2f730d.tgz