From 09277e96871bba8834561100b4bff23ca057c256 Mon Sep 17 00:00:00 2001 From: Miciah Masters Date: Wed, 22 Mar 2023 10:49:24 -0400 Subject: [PATCH] gatewayclass: Update for OSSM 2.4 API change Update for an API change in ServiceMeshControlPlane in OSSM 2.4. https://github.com/maistra/istio-operator/commit/ecd25d550dba4ee4d6477fda4c7889329b4ad1d6 replaced the spec.techPreview.controlPlaneMode field with a new spec.mode field. Specifying spec.techPreview.controlPlaneMode now elicits the following error message: failed to create ServiceMeshControlPlane openshift-ingress/openshift-gateway: admission webhook "smcp.validation.maistra.io" denied the request: the spec.techPreview.controlPlaneMode field is not supported in version 2.4+; use spec.mode To resolve this issue, this commit bumps the vendored Maistra API version and changes the gatewayclass controller to use the new spec.mode field in the ServiceMeshControlPlane CR. This commit fixes OCPBUGS-10714. https://issues.redhat.com/browse/OCPBUGS-10714 * go.mod: Bump github.com/maistra/istio-operator to v0.0.0-20230322122339-793794762e67. * go.sum: * vendor/*: Regenerate. * pkg/operator/controller/gatewayclass/servicemeshcontrolplane.go (desiredServiceMeshControlPlane): Update to use the new spec.mode field instead of spec.techPreview.controlPlanemode. --- go.mod | 2 +- go.sum | 4 +- .../gatewayclass/servicemeshcontrolplane.go | 4 +- .../maistra/v1/servicemeshmemberroll_types.go | 85 ++++++++++++++++++- .../apis/maistra/v1/zz_generated.deepcopy.go | 6 ++ .../apis/maistra/v2/extension_providers.go | 10 +++ .../v2/servicemeshcontrolplane_types.go | 38 ++++++--- .../apis/maistra/v2/zz_generated.deepcopy.go | 48 +++++++++++ vendor/modules.txt | 2 +- 9 files changed, 177 insertions(+), 22 deletions(-) create mode 100644 vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/extension_providers.go diff --git a/go.mod b/go.mod index 8c45b4e823..0d52c181f1 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/google/go-cmp v0.5.9 github.com/jongio/azidext/go/azidext v0.4.0 github.com/kevinburke/go-bindata v3.11.0+incompatible - github.com/maistra/istio-operator v0.0.0-20230213165116-3138f8d64e59 + github.com/maistra/istio-operator v0.0.0-20230322122339-793794762e67 github.com/openshift/api v3.9.1-0.20190924102528-32369d4db2ad+incompatible github.com/openshift/client-go v0.0.0-20230120202327-72f107311084 github.com/openshift/library-go v0.0.0-20230209193239-2e9167362f31 diff --git a/go.sum b/go.sum index 22477a6967..9a847b39f2 100644 --- a/go.sum +++ b/go.sum @@ -837,8 +837,8 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/maistra/istio-operator v0.0.0-20230213165116-3138f8d64e59 h1:JI/0TPDapa9gBljIcFwb66+xNtp+uh0iihROQJ7gQHM= -github.com/maistra/istio-operator v0.0.0-20230213165116-3138f8d64e59/go.mod h1:Ls3+Sa4I7ZFjKm6myTbYYLsodrEKLiB3hi831fTbCk8= +github.com/maistra/istio-operator v0.0.0-20230322122339-793794762e67 h1:MKacYZbpog8jM+uN3/TQS/FUO+Emz/qdAhma63x1pCk= +github.com/maistra/istio-operator v0.0.0-20230322122339-793794762e67/go.mod h1:OTwsAjzSt6870+UXseGMkEPwiyif2xr8A6xyTUrGXVg= github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= diff --git a/pkg/operator/controller/gatewayclass/servicemeshcontrolplane.go b/pkg/operator/controller/gatewayclass/servicemeshcontrolplane.go index c32ace3c83..7d94cc12f5 100644 --- a/pkg/operator/controller/gatewayclass/servicemeshcontrolplane.go +++ b/pkg/operator/controller/gatewayclass/servicemeshcontrolplane.go @@ -120,6 +120,7 @@ func desiredServiceMeshControlPlane(name types.NamespacedName, ownerRef metav1.O }, }, }, + Mode: maistrav2.ClusterWideMode, Policy: &maistrav2.PolicyConfig{ Type: maistrav2.PolicyTypeIstiod, }, @@ -148,9 +149,6 @@ func desiredServiceMeshControlPlane(name types.NamespacedName, ownerRef metav1.O Security: &maistrav2.SecurityConfig{ ManageNetworkPolicy: &f, }, - TechPreview: maistrav1.NewHelmValues(map[string]interface{}{ - "controlPlaneMode": "ClusterScoped", - }), Tracing: &maistrav2.TracingConfig{ Type: maistrav2.TracerTypeNone, }, diff --git a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/servicemeshmemberroll_types.go b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/servicemeshmemberroll_types.go index fa245f3d97..1aaed831fe 100644 --- a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/servicemeshmemberroll_types.go +++ b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/servicemeshmemberroll_types.go @@ -1,8 +1,11 @@ package v1 import ( + "strings" + core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" "github.com/maistra/istio-operator/pkg/apis/maistra/status" ) @@ -58,15 +61,89 @@ type ServiceMeshMemberRollSpec struct { // +optional // +nullable Members []string `json:"members,omitempty"` + + // Include namespaces with label keys and values matching this selector. + // +optional + MemberSelector *metav1.LabelSelector `json:"memberSelector,omitempty"` } -func (s *ServiceMeshMemberRollSpec) IsClusterScoped() bool { - for _, ns := range s.Members { - if ns == "*" { +func (smmr *ServiceMeshMemberRoll) IsMember(ns *core.Namespace) bool { + return smmr.isIncluded(ns) && !smmr.isExcluded(ns) +} + +func (smmr *ServiceMeshMemberRoll) isIncluded(ns *core.Namespace) bool { + // include namespace if spec.members=["*"] + if hasAsterisk(smmr.Spec.Members) { + return true + } + + // check if ns is in spec.members + for _, m := range smmr.Spec.Members { + if ns.Name == m { return true } } - return false + + // check if namespace labels match the label selector + return selectorMatches(smmr.Spec.MemberSelector, ns.Labels) +} + +func hasAsterisk(members []string) bool { + return len(members) == 1 && members[0] == "*" +} + +func (smmr *ServiceMeshMemberRoll) isExcluded(ns *core.Namespace) bool { + return ns.Name == smmr.Namespace || + ns.Name == "kube" || + ns.Name == "openshift" || + strings.HasPrefix(ns.Name, "kube-") || + strings.HasPrefix(ns.Name, "openshift-") || + strings.HasPrefix(ns.Name, "ibm-") +} + +// MatchesNamespacesDynamically returns true if the SMMR contains wildcards in +// spec.members or defines a member selector. In either case, the list of members +// is dynamic, as the member namespace list can change with no change to the SMMR. +func (smmr *ServiceMeshMemberRoll) MatchesNamespacesDynamically() bool { + return hasAsterisk(smmr.Spec.Members) || smmr.Spec.MemberSelector != nil +} + +func selectorMatches(selector *metav1.LabelSelector, labels map[string]string) bool { + if selector == nil { + return false + } + + for k, v := range selector.MatchLabels { + if labels[k] != v { + return false + } + } + + for _, requirement := range selector.MatchExpressions { + value, exists := labels[requirement.Key] + switch requirement.Operator { + case metav1.LabelSelectorOpIn: + values := sets.NewString(requirement.Values...) + if !values.Has(value) { + return false + } + case metav1.LabelSelectorOpNotIn: + for _, v := range requirement.Values { + if value == v { + return false + } + } + case metav1.LabelSelectorOpExists: + if !exists { + return false + } + case metav1.LabelSelectorOpDoesNotExist: + if exists { + return false + } + } + } + return true } // ServiceMeshMemberRollStatus represents the current state of a ServiceMeshMemberRoll. diff --git a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/zz_generated.deepcopy.go b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/zz_generated.deepcopy.go index 5c125d2dd3..7bcf6b6b11 100644 --- a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v1/zz_generated.deepcopy.go @@ -6,6 +6,7 @@ package v1 import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -309,6 +310,11 @@ func (in *ServiceMeshMemberRollSpec) DeepCopyInto(out *ServiceMeshMemberRollSpec *out = make([]string, len(*in)) copy(*out, *in) } + if in.MemberSelector != nil { + in, out := &in.MemberSelector, &out.MemberSelector + *out = new(metav1.LabelSelector) + (*in).DeepCopyInto(*out) + } return } diff --git a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/extension_providers.go b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/extension_providers.go new file mode 100644 index 0000000000..80c828a001 --- /dev/null +++ b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/extension_providers.go @@ -0,0 +1,10 @@ +package v2 + +type ExtensionProviderConfig struct { + // A unique name identifying the extension provider. + Name string `json:"name"` + Prometheus *ExtensionProviderPrometheusConfig `json:"prometheus,omitempty"` +} + +// ExtensionProviderPrometheusConfig configures a Prometheus metrics provider. +type ExtensionProviderPrometheusConfig struct{} diff --git a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/servicemeshcontrolplane_types.go b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/servicemeshcontrolplane_types.go index e451a7898b..4843ad0bf6 100644 --- a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/servicemeshcontrolplane_types.go +++ b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/servicemeshcontrolplane_types.go @@ -8,9 +8,17 @@ import ( ) const ( - ControlPlaneModeKey = "controlPlaneMode" - ControlPlaneModeValueClusterScoped = "ClusterScoped" - ControlPlaneModeValueMultiTenant = "MultiTenant" + // controlPlaneMode in v2.3 + TechPreviewControlPlaneModeKey = "controlPlaneMode" + TechPreviewControlPlaneModeValueClusterScoped = "ClusterScoped" + TechPreviewControlPlaneModeValueMultiTenant = "MultiTenant" +) + +type ControlPlaneMode string + +const ( + ClusterWideMode ControlPlaneMode = "ClusterWide" + MultiTenantMode ControlPlaneMode = "MultiTenant" ) func init() { @@ -125,10 +133,26 @@ type ControlPlaneSpec struct { // admission webhook sets the version to the current version. // +optional Version string `json:"version,omitempty"` + // Mode specifies whether the control plane operates in + // ClusterWide or MultiTenant mode. With ClusterWide mode the control + // plane components get cluster-scoped privileges and can watch + // OSSM-related API resources across the entire cluster, whereas with + // MultiTenant mode, the components only get privileges to watch resources + // in the namespaces listed in the ServiceMeshMemberRoll. This mode requires + // Istiod to create many more watch connections to the API server, since + // it must open a watch for each resource type for each member namespace. + // The default Mode is MultiTenant. + // +optional + // +kubebuilder:validation:Enum=MultiTenant;ClusterWide + Mode ControlPlaneMode `json:"mode,omitempty"` // Cluster is the general configuration of the cluster (cluster name, // network name, multi-cluster, mesh expansion, etc.) // +optional Cluster *ControlPlaneClusterConfig `json:"cluster,omitempty"` + // ExtensionProviders defines a list of extension providers that extend Istio's functionality. For example, + // the AuthorizationPolicy can be used with an extension provider to delegate the authorization decision + // to a custom authorization system. + ExtensionProviders []*ExtensionProviderConfig `json:"extensionProviders,omitempty"` // General represents general control plane configuration that does not // logically fit in another area. // +optional @@ -194,11 +218,3 @@ func (s ControlPlaneSpec) IsGrafanaEnabled() bool { func (s ControlPlaneSpec) IsJaegerEnabled() bool { return s.Tracing != nil && s.Tracing.Type == TracerTypeJaeger } - -func (s ControlPlaneSpec) IsClusterScoped() (bool, error) { - controlPlaneMode, _, err := s.TechPreview.GetString(ControlPlaneModeKey) - if err != nil { - return false, err - } - return controlPlaneMode == ControlPlaneModeValueClusterScoped, nil -} diff --git a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/zz_generated.deepcopy.go b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/zz_generated.deepcopy.go index 855e76b358..4f351df43e 100644 --- a/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/zz_generated.deepcopy.go +++ b/vendor/github.com/maistra/istio-operator/pkg/apis/maistra/v2/zz_generated.deepcopy.go @@ -538,6 +538,17 @@ func (in *ControlPlaneSpec) DeepCopyInto(out *ControlPlaneSpec) { *out = new(ControlPlaneClusterConfig) (*in).DeepCopyInto(*out) } + if in.ExtensionProviders != nil { + in, out := &in.ExtensionProviders, &out.ExtensionProviders + *out = make([]*ExtensionProviderConfig, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(ExtensionProviderConfig) + (*in).DeepCopyInto(*out) + } + } + } if in.General != nil { in, out := &in.General, &out.General *out = new(GeneralConfig) @@ -848,6 +859,43 @@ func (in *EnvoyServiceTCPKeepalive) DeepCopy() *EnvoyServiceTCPKeepalive { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExtensionProviderConfig) DeepCopyInto(out *ExtensionProviderConfig) { + *out = *in + if in.Prometheus != nil { + in, out := &in.Prometheus, &out.Prometheus + *out = new(ExtensionProviderPrometheusConfig) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderConfig. +func (in *ExtensionProviderConfig) DeepCopy() *ExtensionProviderConfig { + if in == nil { + return nil + } + out := new(ExtensionProviderConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExtensionProviderPrometheusConfig) DeepCopyInto(out *ExtensionProviderPrometheusConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderPrometheusConfig. +func (in *ExtensionProviderPrometheusConfig) DeepCopy() *ExtensionProviderPrometheusConfig { + if in == nil { + return nil + } + out := new(ExtensionProviderPrometheusConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GatewayConfig) DeepCopyInto(out *GatewayConfig) { *out = *in diff --git a/vendor/modules.txt b/vendor/modules.txt index 997eade664..0081593b0b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -306,7 +306,7 @@ github.com/leodido/go-urn github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter -# github.com/maistra/istio-operator v0.0.0-20230213165116-3138f8d64e59 +# github.com/maistra/istio-operator v0.0.0-20230322122339-793794762e67 ## explicit; go 1.15 github.com/maistra/istio-operator/pkg/apis/maistra/status github.com/maistra/istio-operator/pkg/apis/maistra/v1