Skip to content

Commit

Permalink
OSSM-5410 Add update strategy to Istio resource (#1544)
Browse files Browse the repository at this point in the history
* OSSM-5410 Add update strategy to Istio resource

* Add comment that Istio.spec.updateStrategy.updateWorkloads is false by default
  • Loading branch information
luksa authored Dec 18, 2023
1 parent 623755e commit 91545e3
Show file tree
Hide file tree
Showing 10 changed files with 326 additions and 58 deletions.
38 changes: 37 additions & 1 deletion api/v1alpha1/istio_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ import (

const IstioKind = "Istio"

type UpdateStrategyType string

const (
UpdateStrategyTypeInPlace UpdateStrategyType = "InPlace"
UpdateStrategyTypeRevisionBased UpdateStrategyType = "RevisionBased"
)

// IstioSpec defines the desired state of Istio
type IstioSpec struct {
// +sail:version
Expand All @@ -35,6 +42,10 @@ type IstioSpec struct {
// +kubebuilder:validation:Enum=v1.20.1;v1.20.0;v1.19.5;latest
Version string `json:"version"`

// Defines the update strategy to use when the version in the Istio CR is updated.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Update Strategy"
UpdateStrategy *IstioUpdateStrategy `json:"updateStrategy,omitempty"`

// +sail:profile
// The built-in installation configuration profile to use.
// The 'default' profile is always applied. On OpenShift, the 'openshift' profile is also applied on top of 'default'.
Expand All @@ -57,7 +68,7 @@ type IstioSpec struct {
// Defines the non-validated values to be passed to the Helm charts when installing Istio.
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Schemaless
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Helm RawValues"
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Raw Helm Values"
RawValues json.RawMessage `json:"rawValues,omitempty"`
}

Expand All @@ -78,6 +89,31 @@ func (s *IstioSpec) SetValues(values helm.HelmValues) error {
return nil
}

// IstioUpdateStrategy defines how the control plane should be updated when the version in
// the Istio CR is updated.
type IstioUpdateStrategy struct {
// Type of strategy to use. Can be "InPlace" or "RevisionBased". When the "InPlace" strategy
// is used, the existing Istio control plane is updated in-place. The workloads therefore
// don't need to be moved from one control plane instance to another. When the "RevisionBased"
// strategy is used, a new Istio control plane instance is created for every change to the
// Istio.spec.version field. The old control plane remains in place until all workloads have
// been moved to the new control plane instance.
//
// The "InPlace" strategy is the default. TODO: change default to "RevisionBased"
// +operator-sdk:csv:customresourcedefinitions:type=spec,order=1,displayName="Type",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:select:InPlace", "urn:alm:descriptor:com.tectonic.ui:select:RevisionBased"}
// +kubebuilder:validation:Enum=InPlace;RevisionBased
Type UpdateStrategyType `json:"type,omitempty"`

// Defines whether the workloads should be moved from one control plane instance to another
// automatically. If updateWorkloads is true, the operator moves the workloads from the old
// control plane instance to the new one after the new control plane is ready.
// If updateWorkloads is false, the user must move the workloads manually by updating the
// istio.io/rev labels on the namespace and/or the pods.
// Defaults to false.
// +operator-sdk:csv:customresourcedefinitions:type=spec,order=2,displayName="Update Workloads Automatically",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"}
UpdateWorkloads bool `json:"updateWorkloads,omitempty"`
}

// IstioStatus defines the observed state of Istio
type IstioStatus struct {
// ObservedGeneration is the most recent generation observed for this
Expand Down
20 changes: 20 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

28 changes: 28 additions & 0 deletions bundle/manifests/operator.istio.io_istios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,34 @@ spec:
description: Defines the non-validated values to be passed to the
Helm charts when installing Istio.
x-kubernetes-preserve-unknown-fields: true
updateStrategy:
description: Defines the update strategy to use when the version in
the Istio CR is updated.
properties:
type:
description: "Type of strategy to use. Can be \"InPlace\" or \"RevisionBased\".
When the \"InPlace\" strategy is used, the existing Istio control
plane is updated in-place. The workloads therefore don't need
to be moved from one control plane instance to another. When
the \"RevisionBased\" strategy is used, a new Istio control
plane instance is created for every change to the Istio.spec.version
field. The old control plane remains in place until all workloads
have been moved to the new control plane instance. \n The \"InPlace\"
strategy is the default.\tTODO: change default to \"RevisionBased\""
enum:
- InPlace
- RevisionBased
type: string
updateWorkloads:
description: Defines whether the workloads should be moved from
one control plane instance to another automatically. If updateWorkloads
is true, the operator moves the workloads from the old control
plane instance to the new one after the new control plane is
ready. If updateWorkloads is false, the user must move the workloads
manually by updating the istio.io/rev labels on the namespace
and/or the pods. Defaults to false.
type: boolean
type: object
values:
description: Defines the values to be passed to the Helm charts when
installing Istio.
Expand Down
34 changes: 32 additions & 2 deletions bundle/manifests/sailoperator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@ metadata:
},
"spec": {
"namespace": "istio-system",
"updateStrategy": {
"type": "InPlace"
},
"version": "v1.20.1"
}
}
]
capabilities: Seamless Upgrades
categories: OpenShift Optional, Integration & Delivery, Networking, Security
containerImage: quay.io/maistra-dev/istio-operator:3.0-latest
createdAt: "2023-12-17T03:24:36Z"
createdAt: "2023-12-18T14:35:58Z"
operators.operatorframework.io/builder: operator-sdk-v1.32.0
operators.operatorframework.io/internal-objects: '["wasmplugins.extensions.istio.io","destinationrules.networking.istio.io","envoyfilters.networking.istio.io","gateways.networking.istio.io","proxyconfigs.networking.istio.io","serviceentries.networking.istio.io","sidecars.networking.istio.io","virtualservices.networking.istio.io","workloadentries.networking.istio.io","workloadgroups.networking.istio.io","authorizationpolicies.security.istio.io","peerauthentications.security.istio.io","requestauthentications.security.istio.io","telemetries.telemetry.istio.io"]'
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
Expand Down Expand Up @@ -89,6 +92,19 @@ spec:
kind: Istio
name: istios.operator.istio.io
specDescriptors:
- description: "Type of strategy to use. Can be \"InPlace\" or \"RevisionBased\".
When the \"InPlace\" strategy is used, the existing Istio control plane
is updated in-place. The workloads therefore don't need to be moved from
one control plane instance to another. When the \"RevisionBased\" strategy
is used, a new Istio control plane instance is created for every change
to the Istio.spec.version field. The old control plane remains in place
until all workloads have been moved to the new control plane instance. \n
The \"InPlace\" strategy is the default.\tTODO: change default to \"RevisionBased\""
displayName: Type
path: updateStrategy.type
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:select:InPlace
- urn:alm:descriptor:com.tectonic.ui:select:RevisionBased
- description: 'Defines the version of Istio to install. Must be one of: v1.20.1,
v1.20.0, v1.19.5, latest.'
displayName: Istio Version
Expand All @@ -99,6 +115,16 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:select:v1.20.0
- urn:alm:descriptor:com.tectonic.ui:select:v1.19.5
- urn:alm:descriptor:com.tectonic.ui:select:latest
- description: Defines whether the workloads should be moved from one control
plane instance to another automatically. If updateWorkloads is true, the
operator moves the workloads from the old control plane instance to the
new one after the new control plane is ready. If updateWorkloads is false,
the user must move the workloads manually by updating the istio.io/rev labels
on the namespace and/or the pods. Defaults to false.
displayName: Update Workloads Automatically
path: updateStrategy.updateWorkloads
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- description: Namespace to which the Istio components should be installed.
displayName: Namespace
path: namespace
Expand All @@ -114,8 +140,12 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Defines the non-validated values to be passed to the Helm charts
when installing Istio.
displayName: Helm RawValues
displayName: Raw Helm Values
path: rawValues
- description: Defines the update strategy to use when the version in the Istio
CR is updated.
displayName: Update Strategy
path: updateStrategy
- description: Defines the values to be passed to the Helm charts when installing
Istio.
displayName: Helm Values
Expand Down
13 changes: 13 additions & 0 deletions config/crd/bases/operator.istio.io_istios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@ spec:
rawValues:
description: Defines the non-validated values to be passed to the Helm charts when installing Istio.
x-kubernetes-preserve-unknown-fields: true
updateStrategy:
description: Defines the update strategy to use when the version in the Istio CR is updated.
properties:
type:
description: "Type of strategy to use. Can be \"InPlace\" or \"RevisionBased\". When the \"InPlace\" strategy is used, the existing Istio control plane is updated in-place. The workloads therefore don't need to be moved from one control plane instance to another. When the \"RevisionBased\" strategy is used, a new Istio control plane instance is created for every change to the Istio.spec.version field. The old control plane remains in place until all workloads have been moved to the new control plane instance. \n The \"InPlace\" strategy is the default.\tTODO: change default to \"RevisionBased\""
enum:
- InPlace
- RevisionBased
type: string
updateWorkloads:
description: Defines whether the workloads should be moved from one control plane instance to another automatically. If updateWorkloads is true, the operator moves the workloads from the old control plane instance to the new one after the new control plane is ready. If updateWorkloads is false, the user must move the workloads manually by updating the istio.io/rev labels on the namespace and/or the pods. Defaults to false.
type: boolean
type: object
values:
description: Defines the values to be passed to the Helm charts when installing Istio.
properties:
Expand Down
29 changes: 28 additions & 1 deletion config/manifests/bases/sailoperator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,19 @@ spec:
kind: Istio
name: istios.operator.istio.io
specDescriptors:
- description: "Type of strategy to use. Can be \"InPlace\" or \"RevisionBased\".
When the \"InPlace\" strategy is used, the existing Istio control plane
is updated in-place. The workloads therefore don't need to be moved from
one control plane instance to another. When the \"RevisionBased\" strategy
is used, a new Istio control plane instance is created for every change
to the Istio.spec.version field. The old control plane remains in place
until all workloads have been moved to the new control plane instance. \n
The \"InPlace\" strategy is the default.\tTODO: change default to \"RevisionBased\""
displayName: Type
path: updateStrategy.type
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:select:InPlace
- urn:alm:descriptor:com.tectonic.ui:select:RevisionBased
- description: 'Defines the version of Istio to install. Must be one of: v1.20.1,
v1.20.0, v1.19.5, latest.'
displayName: Istio Version
Expand All @@ -62,6 +75,16 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:select:v1.20.0
- urn:alm:descriptor:com.tectonic.ui:select:v1.19.5
- urn:alm:descriptor:com.tectonic.ui:select:latest
- description: Defines whether the workloads should be moved from one control
plane instance to another automatically. If updateWorkloads is true, the
operator moves the workloads from the old control plane instance to the
new one after the new control plane is ready. If updateWorkloads is false,
the user must move the workloads manually by updating the istio.io/rev labels
on the namespace and/or the pods. Defaults to false.
displayName: Update Workloads Automatically
path: updateStrategy.updateWorkloads
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:booleanSwitch
- description: Namespace to which the Istio components should be installed.
displayName: Namespace
path: namespace
Expand All @@ -77,8 +100,12 @@ spec:
- urn:alm:descriptor:com.tectonic.ui:hidden
- description: Defines the non-validated values to be passed to the Helm charts
when installing Istio.
displayName: Helm RawValues
displayName: Raw Helm Values
path: rawValues
- description: Defines the update strategy to use when the version in the Istio
CR is updated.
displayName: Update Strategy
path: updateStrategy
- description: Defines the values to be passed to the Helm charts when installing
Istio.
displayName: Helm Values
Expand Down
2 changes: 2 additions & 0 deletions config/samples/istio-sample-kubernetes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ metadata:
spec:
version: v1.20.1
namespace: istio-system
updateStrategy:
type: InPlace
rawValues:
pilot:
resources:
Expand Down
2 changes: 2 additions & 0 deletions config/samples/istio-sample-openshift.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ metadata:
spec:
version: v1.20.1
namespace: istio-system
updateStrategy:
type: InPlace
27 changes: 23 additions & 4 deletions controllers/istio/istio_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"os"
"path"
"reflect"
"strings"

"gopkg.in/yaml.v3"
"k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -107,10 +108,10 @@ func (r *IstioReconciler) doReconcile(ctx context.Context, istio v1alpha1.Istio)
return err
}

return r.createOrUpdateIstioRevision(ctx, &istio, values)
return r.reconcileActiveRevision(ctx, &istio, values)
}

func (r *IstioReconciler) createOrUpdateIstioRevision(ctx context.Context, istio *v1alpha1.Istio, values helm.HelmValues) error {
func (r *IstioReconciler) reconcileActiveRevision(ctx context.Context, istio *v1alpha1.Istio, values helm.HelmValues) error {
logger := log.FromContext(ctx).WithName("reconciler")

valuesRawMessage, err := json.Marshal(values)
Expand All @@ -129,7 +130,7 @@ func (r *IstioReconciler) createOrUpdateIstioRevision(ctx context.Context, istio
// create new
rev = v1alpha1.IstioRevision{
ObjectMeta: metav1.ObjectMeta{
Name: istio.Name,
Name: r.getActiveRevisionName(istio),
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: v1alpha1.GroupVersion.String(),
Expand Down Expand Up @@ -160,7 +161,25 @@ func (r *IstioReconciler) getActiveRevision(ctx context.Context, istio *v1alpha1
}

func (r *IstioReconciler) getActiveRevisionKey(istio *v1alpha1.Istio) types.NamespacedName {
return types.NamespacedName{Name: istio.Name}
return types.NamespacedName{
Name: r.getActiveRevisionName(istio),
}
}

func (r *IstioReconciler) getActiveRevisionName(istio *v1alpha1.Istio) string {
var strategy v1alpha1.UpdateStrategyType
if istio.Spec.UpdateStrategy != nil {
strategy = istio.Spec.UpdateStrategy.Type
}

switch strategy {
default:
fallthrough
case v1alpha1.UpdateStrategyTypeInPlace:
return istio.Name
case v1alpha1.UpdateStrategyTypeRevisionBased:
return istio.Name + "-" + strings.ReplaceAll(istio.Spec.Version, ".", "-")
}
}

func getAggregatedValues(istio v1alpha1.Istio, defaultProfiles []string, resourceDir string) (helm.HelmValues, error) {
Expand Down
Loading

0 comments on commit 91545e3

Please sign in to comment.