Skip to content

Commit

Permalink
Set Istio CR to warning on version update that is not allowed (#855)
Browse files Browse the repository at this point in the history
* Return warning instead of error when Istio version update is not allowed.

* Move code to separate files to improve readability

* Add condition for Istio version update

* Reformat docs to have version on new line

* Add PR link to release notes

* Remove unnecessary function

* Replace context.TODO() with context.Background()

* Apply suggestions from code review

Co-authored-by: Natalia Sitko <80401180+nataliasitko@users.noreply.github.com>

---------

Co-authored-by: Marek Kołodziejczak <69915024+kolodziejczak@users.noreply.github.com>
Co-authored-by: Natalia Sitko <80401180+nataliasitko@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 11, 2024
1 parent 2482918 commit d190d85
Show file tree
Hide file tree
Showing 13 changed files with 423 additions and 411 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Istio is an open-source service mesh that provides a uniform way to manage, conn

Kyma Istio Operator is a component of the Kyma runtime that handles the management and configuration of the Istio service mesh. Within Kyma Istio Operator, [Istio Controller](/docs/user/00-10-overview-istio-controller.md) is responsible for installing, uninstalling, and upgrading Istio.

The latest release includes the following versions of Istio and Envoy:
The latest release includes the following versions of Istio and Envoy:
**Istio version:** 1.21.2
**Envoy version:** 1.29.4

Expand Down
13 changes: 7 additions & 6 deletions api/v1alpha2/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ var conditionReasons = map[ConditionReason]conditionMeta{
ConditionReasonValidationFailed: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonValidationFailedMessage},
ConditionReasonOlderCRExists: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonOlderCRExistsMessage},

ConditionReasonIstioInstallNotNeeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioInstallNotNeededMessage},
ConditionReasonIstioInstallSucceeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioInstallSucceededMessage},
ConditionReasonIstioUninstallSucceeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioUninstallSucceededMessage},
ConditionReasonIstioInstallUninstallFailed: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioInstallUninstallFailedMessage},
ConditionReasonCustomResourceMisconfigured: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonCustomResourceMisconfiguredMessage},
ConditionReasonIstioCRsDangling: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioCRsDanglingMessage},
ConditionReasonIstioInstallNotNeeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioInstallNotNeededMessage},
ConditionReasonIstioInstallSucceeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioInstallSucceededMessage},
ConditionReasonIstioUninstallSucceeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioUninstallSucceededMessage},
ConditionReasonIstioInstallUninstallFailed: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioInstallUninstallFailedMessage},
ConditionReasonCustomResourceMisconfigured: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonCustomResourceMisconfiguredMessage},
ConditionReasonIstioCRsDangling: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioCRsDanglingMessage},
ConditionReasonIstioVersionUpdateNotAllowed: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIstioVersionUpdateNotAllowedMessage},

ConditionReasonCRsReconcileSucceeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonCRsReconcileSucceededMessage},
ConditionReasonCRsReconcileFailed: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonCRsReconcileFailedMessage},
Expand Down
26 changes: 14 additions & 12 deletions api/v1alpha2/istio_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,20 @@ const (
ConditionReasonOlderCRExistsMessage = "This Istio custom resource is not the oldest one and does not represent the module state"

// install / uninstall
ConditionReasonIstioInstallNotNeeded ConditionReason = "IstioInstallNotNeeded"
ConditionReasonIstioInstallNotNeededMessage = "Istio installation is not needed"
ConditionReasonIstioInstallSucceeded ConditionReason = "IstioInstallSucceeded"
ConditionReasonIstioInstallSucceededMessage = "Istio installation succeeded"
ConditionReasonIstioUninstallSucceeded ConditionReason = "IstioUninstallSucceeded"
ConditionReasonIstioUninstallSucceededMessage = "Istio uninstallation succeded"
ConditionReasonIstioInstallUninstallFailed ConditionReason = "IstioInstallUninstallFailed"
ConditionReasonIstioInstallUninstallFailedMessage = "Istio install or uninstall failed"
ConditionReasonCustomResourceMisconfigured ConditionReason = "IstioCustomResourceMisconfigured"
ConditionReasonCustomResourceMisconfiguredMessage = "Istio custom resource has invalid configuration"
ConditionReasonIstioCRsDangling ConditionReason = "IstioCustomResourcesDangling"
ConditionReasonIstioCRsDanglingMessage = "Istio deletion blocked because of existing Istio custom resources"
ConditionReasonIstioInstallNotNeeded ConditionReason = "IstioInstallNotNeeded"
ConditionReasonIstioInstallNotNeededMessage = "Istio installation is not needed"
ConditionReasonIstioInstallSucceeded ConditionReason = "IstioInstallSucceeded"
ConditionReasonIstioInstallSucceededMessage = "Istio installation succeeded"
ConditionReasonIstioUninstallSucceeded ConditionReason = "IstioUninstallSucceeded"
ConditionReasonIstioUninstallSucceededMessage = "Istio uninstallation succeded"
ConditionReasonIstioInstallUninstallFailed ConditionReason = "IstioInstallUninstallFailed"
ConditionReasonIstioInstallUninstallFailedMessage = "Istio install or uninstall failed"
ConditionReasonCustomResourceMisconfigured ConditionReason = "IstioCustomResourceMisconfigured"
ConditionReasonCustomResourceMisconfiguredMessage = "Istio custom resource has invalid configuration"
ConditionReasonIstioCRsDangling ConditionReason = "IstioCustomResourcesDangling"
ConditionReasonIstioCRsDanglingMessage = "Istio deletion blocked because of existing Istio custom resources"
ConditionReasonIstioVersionUpdateNotAllowed ConditionReason = "IstioVersionUpdateNotAllowed"
ConditionReasonIstioVersionUpdateNotAllowedMessage = "Update to the new Istio version is not allowed"

// Istio CRs
ConditionReasonCRsReconcileSucceeded ConditionReason = "CustomResourcesReconcileSucceeded"
Expand Down
1 change: 1 addition & 0 deletions docs/release-notes/1.7.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
- Now, Istio Operator does not restart Pods with Istio Sidecar, which contain custom image annotations. See the issue [#698](https://github.com/kyma-project/istio/issues/698) and [Istio Resource Annotations](https://istio.io/latest/docs/reference/config/annotations/#SidecarProxyImage) for more details.
- Change Istio Ingress Gateway's scaling to be based only on CPU utilization. This adjustment ensures that the scaling is more responsive to traffic changes, as the Istio Ingress Gateway memory utilization is not a good indicator of the traffic load.
- Set the default number of Istio Ingress Gateway replicas in smaller clusters to `1`.
- Set Istio CR status to `Warning` instead of `Error` when the Istio version update is not allowed [#855](https://github.com/kyma-project/istio/pull/855).
40 changes: 21 additions & 19 deletions docs/user/00-10-overview-istio-controller.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ The version of Istio is dependent on the version of Istio Controller that you us

You can only skip a version of Kyma Istio Operator if the difference between the minor version of Istio it contains and the minor version of Istio you're using is not greater than one (for example, 1.2.3 -> 1.3.0).
If the difference is greater than one minor version (for example, 1.2.3 -> 1.4.0), the reconciliation fails.
The same happens if you try to update the major version (for example, 1.2.3 -> 2.0.0) or downgrade the version. Such scenarios are not supported.
The same happens if you try to update the major version (for example, 1.2.3 -> 2.0.0) or downgrade the version.
Such scenarios are not supported and cause the Istio CR to be in the `Warning` state with the `Ready` condition set to `false` and the reason being `IstioVersionUpdateNotAllowed`.

## Istio Custom Resource

Expand All @@ -38,24 +39,25 @@ Istio Operator does not restart an Istio sidecar proxy, if it has a custom image

Conditions:

| CR state | Type | Status | Reason | Message |
|------------|------------------------------|--------|-----------------------------------|------------------------------------------------------------------------------------------|
| Ready | Ready | True | ReconcileSucceeded | Reconciliation succeeded |
| Error | Ready | False | ReconcileFailed | Reconciliation failed |
| Warning | Ready | False | OlderCRExists | This Istio custom resource is not the oldest one and does not represent the module state |
| Processing | Ready | False | IstioInstallNotNeeded | Istio installation is not needed |
| Processing | Ready | False | IstioInstallSucceeded | Istio installation succeeded |
| Processing | Ready | False | IstioUninstallSucceeded | Istio uninstallation succeded |
| Error | Ready | False | IstioInstallUninstallFailed | Istio install or uninstall failed |
| Error | Ready | False | IstioCustomResourceMisconfigured | Istio custom resource has invalid configuration |
| Warning | Ready | False | IstioCustomResourcesDangling | Istio deletion blocked because of existing Istio custom resources |
| Processing | Ready | False | CustomResourcesReconcileSucceeded | Custom resources reconciliation succeeded |
| Error | Ready | False | CustomResourcesReconcileFailed | Custom resources reconciliation failed |
| Processing | ProxySidecarRestartSucceeded | True | ProxySidecarRestartSucceeded | Proxy sidecar restart succeeded |
| Error | ProxySidecarRestartSucceeded | False | ProxySidecarRestartFailed | Proxy sidecar restart failed |
| Warning | ProxySidecarRestartSucceeded | False | ProxySidecarManualRestartRequired | Proxy sidecar manual restart is required for some workloads |
| Processing | Ready | False | IngressGatewayReconcileSucceeded | Istio Ingress Gateway reconciliation succeeded |
| Error | Ready | False | IngressGatewayReconcileFailed | Istio Ingress Gateway reconciliation failed |
| CR state | Type | Status | Reason | Message |
|------------|------------------------------|--------|------------------------------------|------------------------------------------------------------------------------------------|
| Ready | Ready | True | ReconcileSucceeded | Reconciliation succeeded |
| Error | Ready | False | ReconcileFailed | Reconciliation failed |
| Warning | Ready | False | OlderCRExists | This Istio custom resource is not the oldest one and does not represent the module state |
| Processing | Ready | False | IstioInstallNotNeeded | Istio installation is not needed |
| Processing | Ready | False | IstioInstallSucceeded | Istio installation succeeded |
| Processing | Ready | False | IstioUninstallSucceeded | Istio uninstallation succeded |
| Error | Ready | False | IstioInstallUninstallFailed | Istio install or uninstall failed |
| Error | Ready | False | IstioCustomResourceMisconfigured | Istio custom resource has invalid configuration |
| Warning | Ready | False | IstioCustomResourcesDangling | Istio deletion blocked because of existing Istio custom resources |
| Processing | Ready | False | CustomResourcesReconcileSucceeded | Custom resources reconciliation succeeded |
| Error | Ready | False | CustomResourcesReconcileFailed | Custom resources reconciliation failed |
| Processing | ProxySidecarRestartSucceeded | True | ProxySidecarRestartSucceeded | Proxy sidecar restart succeeded |
| Error | ProxySidecarRestartSucceeded | False | ProxySidecarRestartFailed | Proxy sidecar restart failed |
| Warning | ProxySidecarRestartSucceeded | False | ProxySidecarManualRestartRequired | Proxy sidecar manual restart is required for some workloads |
| Processing | Ready | False | IngressGatewayReconcileSucceeded | Istio Ingress Gateway reconciliation succeeded |
| Error | Ready | False | IngressGatewayReconcileFailed | Istio Ingress Gateway reconciliation failed |
| Warning | Ready | False | IstioVersionUpdateNotAllowed | Update to the new Istio version is not allowed |

## X-Forwarded-For HTTP Header

Expand Down
2 changes: 1 addition & 1 deletion docs/user/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Istio is an open-source service mesh that provides a uniform way to manage, conn

Kyma Istio Operator is an essential part of the Istio module that handles the management and configuration of the Istio service mesh. It contains [Istio Controller](./00-10-overview-istio-controller.md) that is responsible for installing, uninstalling, and upgrading Istio.

The latest release includes the following versions of Istio and Envoy:
The latest release includes the following versions of Istio and Envoy:
**Istio version:** 1.21.2
**Envoy version:** 1.29.4

Expand Down
31 changes: 1 addition & 30 deletions internal/reconciliations/istio/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,13 @@ import (

"github.com/coreos/go-semver/semver"
operatorv1alpha2 "github.com/kyma-project/istio/operator/api/v1alpha2"
"github.com/kyma-project/istio/operator/internal/istiooperator"
)

type appliedConfig struct {
operatorv1alpha2.IstioSpec
IstioTag string
}

// shouldDelete returns true when Istio should be deleted
func shouldDelete(istio *operatorv1alpha2.Istio) bool {
return !istio.DeletionTimestamp.IsZero()
}

// shouldInstall returns true when Istio should be installed
func shouldInstall(istio *operatorv1alpha2.Istio, istioImageVersion istiooperator.IstioImageVersion) (shouldInstall bool, err error) {
if shouldDelete(istio) {
return false, nil
}

lastAppliedConfigAnnotation, ok := istio.Annotations[labels.LastAppliedConfiguration]
if !ok {
return true, nil
}

var lastAppliedConfig appliedConfig
if err := json.Unmarshal([]byte(lastAppliedConfigAnnotation), &lastAppliedConfig); err != nil {
return false, err
}

if err := checkIstioVersion(lastAppliedConfig.IstioTag, istioImageVersion.Tag()); err != nil {
return false, err
}

return true, nil
}

// UpdateLastAppliedConfiguration annotates the passed CR with LastAppliedConfiguration, which holds information about last applied
// IstioCR spec and IstioTag (IstioVersion-IstioImageBase)
func UpdateLastAppliedConfiguration(istioCR *operatorv1alpha2.Istio, istioTag string) error {
Expand Down Expand Up @@ -80,7 +51,7 @@ func getLastAppliedConfiguration(istioCR *operatorv1alpha2.Istio) (appliedConfig
return lastAppliedConfig, nil
}

func checkIstioVersion(currentIstioVersionString, targetIstioVersionString string) error {
func checkIstioVersionUpdate(currentIstioVersionString, targetIstioVersionString string) error {
currentIstioVersion, err := semver.NewVersion(currentIstioVersionString)
if err != nil {
return err
Expand Down
55 changes: 55 additions & 0 deletions internal/reconciliations/istio/finalizer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package istio

import (
"context"
"k8s.io/client-go/util/retry"

operatorv1alpha2 "github.com/kyma-project/istio/operator/api/v1alpha2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

const (
installationFinalizer string = "istios.operator.kyma-project.io/istio-installation"
)

func hasInstallationFinalizer(istioCR *operatorv1alpha2.Istio) bool {
return controllerutil.ContainsFinalizer(istioCR, installationFinalizer)
}

func addInstallationFinalizer(ctx context.Context, apiClient client.Client, istioCR *operatorv1alpha2.Istio) error {
ctrl.Log.Info("Adding Istio installation finalizer")
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
finalizerCR := operatorv1alpha2.Istio{}
if err := apiClient.Get(ctx, client.ObjectKeyFromObject(istioCR), &finalizerCR); err != nil {
return err
}
if controllerutil.AddFinalizer(&finalizerCR, installationFinalizer) {
if err := apiClient.Update(ctx, &finalizerCR); err != nil {
return err
}
}
istioCR.Finalizers = finalizerCR.Finalizers
ctrl.Log.Info("Successfully added Istio installation finalizer")
return nil
})
}

func removeInstallationFinalizer(ctx context.Context, apiClient client.Client, istioCR *operatorv1alpha2.Istio) error {
ctrl.Log.Info("Removing Istio installation finalizer")
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
finalizerCR := operatorv1alpha2.Istio{}
if err := apiClient.Get(ctx, client.ObjectKeyFromObject(istioCR), &finalizerCR); err != nil {
return err
}
if controllerutil.RemoveFinalizer(&finalizerCR, installationFinalizer) {
if err := apiClient.Update(ctx, &finalizerCR); err != nil {
return err
}
}
istioCR.Finalizers = finalizerCR.Finalizers
ctrl.Log.Info("Successfully removed Istio installation finalizer")
return nil
})
}
Loading

0 comments on commit d190d85

Please sign in to comment.