diff --git a/api/external/maistra/addtoscheme_maistra_v1.go b/api/external/maistra/addtoscheme_maistra_v1.go deleted file mode 100644 index 569765298..000000000 --- a/api/external/maistra/addtoscheme_maistra_v1.go +++ /dev/null @@ -1,12 +0,0 @@ -package apis - -import ( - v1 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v1" -) - -func init() { - // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back - AddToSchemes = append(AddToSchemes, - v1.SchemeBuilder.AddToScheme, - ) -} diff --git a/api/external/maistra/addtoscheme_maistra_v2.go b/api/external/maistra/addtoscheme_maistra_v2.go deleted file mode 100644 index 4e2897f4b..000000000 --- a/api/external/maistra/addtoscheme_maistra_v2.go +++ /dev/null @@ -1,12 +0,0 @@ -package apis - -import ( - v2 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v2" -) - -func init() { - // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back - AddToSchemes = append(AddToSchemes, - v2.SchemeBuilder.AddToScheme, - ) -} diff --git a/api/external/maistra/apis.go b/api/external/maistra/apis.go deleted file mode 100644 index 07dc96164..000000000 --- a/api/external/maistra/apis.go +++ /dev/null @@ -1,13 +0,0 @@ -package apis - -import ( - "k8s.io/apimachinery/pkg/runtime" -) - -// AddToSchemes may be used to add all resources defined in the project to a Scheme -var AddToSchemes runtime.SchemeBuilder - -// AddToScheme adds all Resources to the Scheme -func AddToScheme(s *runtime.Scheme) error { - return AddToSchemes.AddToScheme(s) -} diff --git a/api/external/maistra/status/doc.go b/api/external/maistra/status/doc.go deleted file mode 100644 index edbaf0f5c..000000000 --- a/api/external/maistra/status/doc.go +++ /dev/null @@ -1,3 +0,0 @@ -// Package status contains common status types used in maistra API -// +k8s:deepcopy-gen=package -package status diff --git a/api/external/maistra/status/status.go b/api/external/maistra/status/status.go deleted file mode 100644 index 8b5a253ef..000000000 --- a/api/external/maistra/status/status.go +++ /dev/null @@ -1,280 +0,0 @@ -// nolint -package status - -import ( - "fmt" - "strings" - "time" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/kuadrant/kuadrant-operator/api/external/maistra/version" -) - -type StatusBase struct { - // Annotations is an unstructured key value map used to store additional, - // usually redundant status information, such as the number of components - // deployed by the ServiceMeshControlPlane (number is redundant because - // you could just as easily count the elements in the ComponentStatus - // array). The reason to add this redundant information is to make it - // available to kubectl, which does not yet allow counting objects in - // JSONPath expressions. - // +optional - Annotations map[string]string `json:"annotations,omitempty"` -} - -func (s *StatusBase) GetAnnotation(name string) string { - if s.Annotations == nil { - return "" - } - return s.Annotations[name] -} - -func (s *StatusBase) SetAnnotation(name string, value string) { - if s.Annotations == nil { - s.Annotations = map[string]string{} - } - s.Annotations[name] = value -} - -func (s *StatusBase) RemoveAnnotation(name string) { - if s.Annotations != nil { - delete(s.Annotations, name) - } -} - -// StatusType represents the status for a control plane, component, or resource -type StatusType struct { - // Represents the latest available observations of the object's current state. - Conditions []Condition `json:"conditions,omitempty"` -} - -// NewStatus returns a new StatusType object -func NewStatus() StatusType { - return StatusType{Conditions: make([]Condition, 0, 3)} -} - -type ComponentStatusList struct { - // +optional - ComponentStatus []ComponentStatus `json:"components,omitempty"` -} - -// FindComponentByName returns the status for a specific component -func (s *ComponentStatusList) FindComponentByName(name string) *ComponentStatus { - for i, status := range s.ComponentStatus { - if status.Resource == name { - return &s.ComponentStatus[i] - } - } - return nil -} - -// NewComponentStatus returns a new ComponentStatus object -func NewComponentStatus() *ComponentStatus { - return &ComponentStatus{StatusType: NewStatus()} -} - -// ComponentStatus represents the status of an object with children -type ComponentStatus struct { - StatusType `json:",inline"` - - // The name of the component this status pertains to. - Resource string `json:"resource,omitempty"` - - // TODO: can we remove this? it's not used anywhere - // The status of each resource that comprises this component. - Resources []*StatusType `json:"children,omitempty"` -} - -// ConditionType represents the type of the condition. Condition stages are: -// Installed, Reconciled, Ready -type ConditionType string - -const ( - // ConditionTypeInstalled signifies the whether or not the controller has - // installed the resources defined through the CR. - ConditionTypeInstalled ConditionType = "Installed" - // ConditionTypeReconciled signifies the whether or not the controller has - // reconciled the resources defined through the CR. - ConditionTypeReconciled ConditionType = "Reconciled" - // ConditionTypeReady signifies the whether or not any Deployment, StatefulSet, - // etc. resources are Ready. - ConditionTypeReady ConditionType = "Ready" -) - -// ConditionStatus represents the status of the condition -type ConditionStatus string - -const ( - // ConditionStatusTrue represents completion of the condition, e.g. - // Initialized=True signifies that initialization has occurred. - ConditionStatusTrue ConditionStatus = "True" - // ConditionStatusFalse represents incomplete status of the condition, e.g. - // Initialized=False signifies that initialization has not occurred or has - // failed. - ConditionStatusFalse ConditionStatus = "False" - // ConditionStatusUnknown represents unknown completion of the condition, e.g. - // Initialized=Unknown signifies that initialization may or may not have been - // completed. - ConditionStatusUnknown ConditionStatus = "Unknown" -) - -// ConditionReason represents a short message indicating how the condition came -// to be in its present state. -type ConditionReason string - -const ( - // ConditionReasonDeletionError ... - ConditionReasonDeletionError ConditionReason = "DeletionError" - // ConditionReasonInstallSuccessful ... - ConditionReasonInstallSuccessful ConditionReason = "InstallSuccessful" - // ConditionReasonInstallError ... - ConditionReasonInstallError ConditionReason = "InstallError" - // ConditionReasonReconcileSuccessful ... - ConditionReasonReconcileSuccessful ConditionReason = "ReconcileSuccessful" - // ConditionReasonValidationError ... - ConditionReasonValidationError ConditionReason = "ValidationError" - // ConditionReasonValidationError ... - ConditionReasonMultipleSMCPs ConditionReason = "ErrMultipleSMCPs" - // ConditionReasonDependencyMissingError ... - ConditionReasonDependencyMissingError ConditionReason = "DependencyMissingError" - // ConditionReasonReconcileError ... - ConditionReasonReconcileError ConditionReason = "ReconcileError" - // ConditionReasonResourceCreated ... - ConditionReasonResourceCreated ConditionReason = "ResourceCreated" - // ConditionReasonSpecUpdated ... - ConditionReasonSpecUpdated ConditionReason = "SpecUpdated" - // ConditionReasonOperatorUpdated indicates that the SMCP is being reconciled - // because the operator was upgraded - ConditionReasonOperatorUpdated ConditionReason = "OperatorUpdated" - // ConditionReasonUpdateSuccessful ... - ConditionReasonUpdateSuccessful ConditionReason = "UpdateSuccessful" - // ConditionReasonComponentsReady ... - ConditionReasonComponentsReady ConditionReason = "ComponentsReady" - // ConditionReasonComponentsNotReady ... - ConditionReasonComponentsNotReady ConditionReason = "ComponentsNotReady" - // ConditionReasonProbeError ... - ConditionReasonProbeError ConditionReason = "ProbeError" - // ConditionReasonPausingInstall ... - ConditionReasonPausingInstall ConditionReason = "PausingInstall" - // ConditionReasonPausingUpdate ... - ConditionReasonPausingUpdate ConditionReason = "PausingUpdate" - // ConditionReasonDeleting ... - ConditionReasonDeleting ConditionReason = "Deleting" - // ConditionReasonDeleted ... - ConditionReasonDeleted ConditionReason = "Deleted" -) - -// A Condition represents a specific observation of the object's state. -type Condition struct { - // The type of this condition. - Type ConditionType `json:"type,omitempty"` - - // The status of this condition. Can be True, False or Unknown. - Status ConditionStatus `json:"status,omitempty"` - - // Unique, single-word, CamelCase reason for the condition's last transition. - Reason ConditionReason `json:"reason,omitempty"` - - // Human-readable message indicating details about the last transition. - Message string `json:"message,omitempty"` - - // Last time the condition transitioned from one status to another. - LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` -} - -func (c *Condition) Matches(status ConditionStatus, reason ConditionReason, message string) bool { - return c.Status == status && c.Reason == reason && c.Message == message -} - -// CurrentReconciledVersion returns a ReconciledVersion for this release of the operator -func CurrentReconciledVersion(generation int64) string { - return ComposeReconciledVersion(version.Info.Version, generation) -} - -// ComposeReconciledVersion returns a string for use in ReconciledVersion fields -func ComposeReconciledVersion(operatorVersion string, generation int64) string { - return fmt.Sprintf("%s-%d", operatorVersion, generation) -} - -// GetCondition removes a condition for the list of conditions -func (s *StatusType) GetCondition(conditionType ConditionType) Condition { - if s == nil { - return Condition{Type: conditionType, Status: ConditionStatusUnknown} - } - for i := range s.Conditions { - if s.Conditions[i].Type == conditionType { - return s.Conditions[i] - } - } - return Condition{Type: conditionType, Status: ConditionStatusUnknown} -} - -// SetCondition sets a specific condition in the list of conditions -func (s *StatusType) SetCondition(condition Condition) *StatusType { - if s == nil { - return nil - } - // These only get serialized out to the second. This can break update - // skipping, as the time in the resource returned from the client may not - // match the time in our cached status during a reconcile. We truncate here - // to save any problems down the line. - now := metav1.NewTime(time.Now().Truncate(time.Second)) - for i, prevCondition := range s.Conditions { - if prevCondition.Type == condition.Type { - if prevCondition.Status != condition.Status { - condition.LastTransitionTime = now - } else { - condition.LastTransitionTime = prevCondition.LastTransitionTime - } - s.Conditions[i] = condition - return s - } - } - - // If the condition does not exist, - // initialize the lastTransitionTime - condition.LastTransitionTime = now - s.Conditions = append(s.Conditions, condition) - return s -} - -// RemoveCondition removes a condition for the list of conditions -func (s *StatusType) RemoveCondition(conditionType ConditionType) *StatusType { - if s == nil { - return nil - } - for i := range s.Conditions { - if s.Conditions[i].Type == conditionType { - s.Conditions = append(s.Conditions[:i], s.Conditions[i+1:]...) - return s - } - } - return s -} - -// ResourceKey is a typedef for key used in ManagedGenerations. It is a string -// with the format: namespace/name=group/version,kind -type ResourceKey string - -// NewResourceKey for the object and type -func NewResourceKey(o metav1.Object, t metav1.Type) ResourceKey { - return ResourceKey(fmt.Sprintf("%s/%s=%s,Kind=%s", o.GetNamespace(), o.GetName(), t.GetAPIVersion(), t.GetKind())) -} - -// ToUnstructured returns a an Unstructured object initialized with Namespace, -// Name, APIVersion, and Kind fields from the ResourceKey -func (key ResourceKey) ToUnstructured() *unstructured.Unstructured { - // ResourceKey is guaranteed to be at least "/=," meaning we are guaranteed - // to get two elements in all of the splits - retval := &unstructured.Unstructured{} - parts := strings.SplitN(string(key), "=", 2) - nn := strings.SplitN(parts[0], "/", 2) - gvk := strings.SplitN(parts[1], ",Kind=", 2) - retval.SetNamespace(nn[0]) - retval.SetName(nn[1]) - retval.SetAPIVersion(gvk[0]) - retval.SetKind(gvk[1]) - return retval -} diff --git a/api/external/maistra/status/zz_generated.deepcopy.go b/api/external/maistra/status/zz_generated.deepcopy.go deleted file mode 100644 index 1b1a7922d..000000000 --- a/api/external/maistra/status/zz_generated.deepcopy.go +++ /dev/null @@ -1,132 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2021. - -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package status - -import () - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentStatus) DeepCopyInto(out *ComponentStatus) { - *out = *in - in.StatusType.DeepCopyInto(&out.StatusType) - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]*StatusType, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(StatusType) - (*in).DeepCopyInto(*out) - } - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentStatus. -func (in *ComponentStatus) DeepCopy() *ComponentStatus { - if in == nil { - return nil - } - out := new(ComponentStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentStatusList) DeepCopyInto(out *ComponentStatusList) { - *out = *in - if in.ComponentStatus != nil { - in, out := &in.ComponentStatus, &out.ComponentStatus - *out = make([]ComponentStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentStatusList. -func (in *ComponentStatusList) DeepCopy() *ComponentStatusList { - if in == nil { - return nil - } - out := new(ComponentStatusList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Condition) DeepCopyInto(out *Condition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. -func (in *Condition) DeepCopy() *Condition { - if in == nil { - return nil - } - out := new(Condition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StatusBase) DeepCopyInto(out *StatusBase) { - *out = *in - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusBase. -func (in *StatusBase) DeepCopy() *StatusBase { - if in == nil { - return nil - } - out := new(StatusBase) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StatusType) DeepCopyInto(out *StatusType) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusType. -func (in *StatusType) DeepCopy() *StatusType { - if in == nil { - return nil - } - out := new(StatusType) - in.DeepCopyInto(out) - return out -} diff --git a/api/external/maistra/v1/conversion.go b/api/external/maistra/v1/conversion.go deleted file mode 100644 index 01d39480e..000000000 --- a/api/external/maistra/v1/conversion.go +++ /dev/null @@ -1,25 +0,0 @@ -package v1 - -import ( - "k8s.io/apimachinery/pkg/runtime" - "sigs.k8s.io/controller-runtime/pkg/conversion" -) - -var _ conversion.Convertible = (*ServiceMeshControlPlane)(nil) - -// ConverterV1V2 and ConverterV2V1 functions are really hacky, but allow us to avoid circular imports. -// The alternative is to move the entire conversion package into here. -var ( - ConverterV1V2 func(src, dst runtime.Object) error - ConverterV2V1 func(src, dst runtime.Object) error -) - -// ConvertTo v2 SMCP resource -func (smcp *ServiceMeshControlPlane) ConvertTo(dst conversion.Hub) error { - return ConverterV1V2(smcp, dst) -} - -// ConvertFrom v2 SMCP resource -func (smcp *ServiceMeshControlPlane) ConvertFrom(src conversion.Hub) error { - return ConverterV2V1(src, smcp) -} diff --git a/api/external/maistra/v1/doc.go b/api/external/maistra/v1/doc.go deleted file mode 100644 index dd899f3e5..000000000 --- a/api/external/maistra/v1/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package v1 contains API Schema definitions for the maistra v1 API group -// +k8s:deepcopy-gen=package,register -// +groupName=maistra.io -package v1 diff --git a/api/external/maistra/v1/helmvalues.go b/api/external/maistra/v1/helmvalues.go deleted file mode 100644 index b77abf867..000000000 --- a/api/external/maistra/v1/helmvalues.go +++ /dev/null @@ -1,353 +0,0 @@ -// nolint -package v1 - -import ( - "fmt" - "strconv" - "strings" - - "github.com/goccy/go-yaml" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/util/json" -) - -// HelmValues is typedef for Helm .Values -// +kubebuilder:validation:Type=object -// +kubebuilder:validation:XPreserveUnknownFields -type HelmValues struct { - data map[string]interface{} `json:"-"` -} - -func NewHelmValues(values map[string]interface{}) *HelmValues { - if values == nil { - values = make(map[string]interface{}) - } - return &HelmValues{data: values} -} - -func (h *HelmValues) GetContent() map[string]interface{} { - if h == nil { - return nil - } - return h.data -} - -func (h *HelmValues) GetFieldNoCopy(path string) (interface{}, bool, error) { - if h == nil || h.data == nil { - return nil, false, nil - } - return unstructured.NestedFieldNoCopy(h.data, strings.Split(path, ".")...) -} - -func (h *HelmValues) GetBool(path string) (bool, bool, error) { - if h == nil || h.data == nil { - return false, false, nil - } - val, found, err := unstructured.NestedFieldNoCopy(h.data, strings.Split(path, ".")...) - if !found || err != nil { - return false, found, err - } - b, ok := val.(bool) - if !ok { - if val == nil { - return false, false, nil - } - return false, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected bool", path, val, val) - } - return b, true, nil -} - -func (h *HelmValues) GetAndRemoveBool(path string) (bool, bool, error) { - value, ok, err := h.GetBool(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetString(path string) (string, bool, error) { - if h == nil || h.data == nil { - return "", false, nil - } - val, found, err := unstructured.NestedFieldNoCopy(h.data, strings.Split(path, ".")...) - if !found || err != nil { - return "", found, err - } - s, ok := val.(string) - if !ok { - if val == nil { - return "", false, nil - } - return "", false, fmt.Errorf("%v accessor error: %v is of the type %T, expected string", path, val, val) - } - return s, true, nil -} - -func (h *HelmValues) GetForceNumberToString(path string) (string, bool, error) { - if h == nil || h.data == nil { - return "", false, nil - } - value, ok, err := unstructured.NestedFieldNoCopy(h.data, strings.Split(path, ".")...) - if err != nil { - return "", false, err - } else if !ok { - return "", false, nil - } - switch typeValue := value.(type) { - case int64: - return strconv.FormatInt(typeValue, 10), ok, nil - case float64: - return strconv.FormatFloat(typeValue, 'f', -1, 64), ok, nil - case string: - return typeValue, ok, nil - case nil: - return "", false, nil - } - return "", false, fmt.Errorf("could not convert type to string: %T=%s", value, value) -} - -func (h *HelmValues) GetAndRemoveString(path string) (string, bool, error) { - value, ok, err := h.GetString(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetAndRemoveForceNumberToString(path string) (string, bool, error) { - value, ok, err := h.GetForceNumberToString(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetInt64(path string) (int64, bool, error) { - if h == nil || h.data == nil { - return 0, false, nil - } - val, found, err := unstructured.NestedFieldNoCopy(h.data, strings.Split(path, ".")...) - if !found || err != nil { - return 0, found, err - } - i, ok := val.(int64) - if !ok { - if val == nil { - return 0, false, nil - } - return 0, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected int64", path, val, val) - } - return i, true, nil -} - -func (h *HelmValues) GetAndRemoveInt64(path string) (int64, bool, error) { - value, ok, err := h.GetInt64(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetFloat64(path string) (float64, bool, error) { - if h == nil || h.data == nil { - return 0, false, nil - } - val, found, err := unstructured.NestedFieldNoCopy(h.data, strings.Split(path, ".")...) - if !found || err != nil { - return 0, found, err - } - f, ok := val.(float64) - if !ok { - if val == nil { - return 0, false, nil - } - return 0, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected float64", path, val, val) - } - return f, true, nil -} - -func (h *HelmValues) GetAndRemoveFloat64(path string) (float64, bool, error) { - value, ok, err := h.GetFloat64(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetStringSlice(path string) ([]string, bool, error) { - if h == nil || h.data == nil { - return nil, false, nil - } - slice, ok, err := unstructured.NestedStringSlice(h.data, strings.Split(path, ".")...) - if err != nil { - if val, _, _ := h.GetFieldNoCopy(path); val == nil { - return nil, false, nil - } - } - return slice, ok, err -} - -func (h *HelmValues) GetAndRemoveStringSlice(path string) ([]string, bool, error) { - value, ok, err := h.GetStringSlice(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetSlice(path string) ([]interface{}, bool, error) { - if h == nil || h.data == nil { - return nil, false, nil - } - slice, ok, err := unstructured.NestedSlice(h.data, strings.Split(path, ".")...) - if err != nil { - if val, _, _ := h.GetFieldNoCopy(path); val == nil { - return nil, false, nil - } - } - return slice, ok, err -} - -func (h *HelmValues) GetAndRemoveSlice(path string) ([]interface{}, bool, error) { - value, ok, err := h.GetSlice(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetAndRemoveStringToStringMap(path string) (map[string]string, bool, error) { - var stringToStringMap map[string]string - var found bool - if rawValues, ok, err := h.GetMap(path); ok { - if len(rawValues) > 0 { - stringToStringMap = make(map[string]string) - for name, rawValue := range rawValues { - if rawValue == nil { - continue - } - switch value := rawValue.(type) { - case string: - stringToStringMap[name] = value - default: - return nil, false, fmt.Errorf("unknown type for %s.%s value, expected string: %T", path, name, rawValue) - } - } - if len(stringToStringMap) == 0 { - // this can happen if there are nil values - stringToStringMap = nil - } else { - found = true - } - } - } else if err != nil { - return nil, false, err - } - h.RemoveField(path) - return stringToStringMap, found, nil -} - -func (h *HelmValues) GetMap(path string) (map[string]interface{}, bool, error) { - if h == nil || h.data == nil { - return nil, false, nil - } - rawval, ok, err := unstructured.NestedFieldCopy(h.data, strings.Split(path, ".")...) - if ok { - if rawval == nil { - return nil, ok, err - } - if mapval, ok := rawval.(map[string]interface{}); ok { - return mapval, ok, err - } - return nil, false, fmt.Errorf("%v accessor error: %v is of the type %T, expected map[string]interface{}", path, rawval, rawval) - } - return nil, ok, err -} - -func (h *HelmValues) GetAndRemoveMap(path string) (map[string]interface{}, bool, error) { - value, ok, err := h.GetMap(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) GetStringMap(path string) (map[string]string, bool, error) { - if h == nil || h.data == nil { - return nil, false, nil - } - mapval, ok, err := unstructured.NestedStringMap(h.data, strings.Split(path, ".")...) - if ok { - return mapval, ok, err - } - return nil, ok, err -} - -func (h *HelmValues) GetAndRemoveStringMap(path string) (map[string]string, bool, error) { - value, ok, err := h.GetStringMap(path) - if err == nil { - h.RemoveField(path) - } - return value, ok, err -} - -func (h *HelmValues) SetField(path string, value interface{}) error { - if h == nil { - panic("Tried to invoke SetField on nil *HelmValues") - } - if h.data == nil { - h.data = map[string]interface{}{} - } - return unstructured.SetNestedField(h.data, value, strings.Split(path, ".")...) -} - -func (h *HelmValues) SetStringSlice(path string, value []string) error { - if h == nil { - panic("Tried to invoke SetField on nil *HelmValues") - } - if h.data == nil { - h.data = map[string]interface{}{} - } - return unstructured.SetNestedStringSlice(h.data, value, strings.Split(path, ".")...) -} - -func (h *HelmValues) RemoveField(path string) { - if h == nil || h.data == nil { - return - } - unstructured.RemoveNestedField(h.data, strings.Split(path, ".")...) -} - -func (h *HelmValues) UnmarshalJSON(in []byte) error { - err := json.Unmarshal(in, &h.data) - if err != nil { - return err - } - return nil -} - -func (h *HelmValues) UnmarshalYAML(in []byte) error { - if err := yaml.Unmarshal(in, &h.data); err != nil { - return err - } - return nil -} - -func (h *HelmValues) MarshalJSON() ([]byte, error) { - return json.Marshal(h.data) -} - -func (h *HelmValues) DeepCopyInto(out *HelmValues) { - *out = HelmValues{} - - data, err := json.Marshal(h) - if err != nil { - // panic ??? - return - } - err = json.Unmarshal(data, out) - if err != nil { - // panic ??? - return - } -} diff --git a/api/external/maistra/v1/register.go b/api/external/maistra/v1/register.go deleted file mode 100644 index 458024ced..000000000 --- a/api/external/maistra/v1/register.go +++ /dev/null @@ -1,24 +0,0 @@ -// NOTE: Boilerplate only. Ignore this file. - -// Package v1 contains API Schema definitions for the maistra v1 API group -// +k8s:deepcopy-gen=package,register -// +groupName=maistra.io -package v1 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -const ( - APIGroup = "maistra.io" - APIVersion = "v1" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: APIGroup, Version: APIVersion} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} -) diff --git a/api/external/maistra/v1/servicemeshcontrolplane_deepcopy.go b/api/external/maistra/v1/servicemeshcontrolplane_deepcopy.go deleted file mode 100644 index b7b1f993d..000000000 --- a/api/external/maistra/v1/servicemeshcontrolplane_deepcopy.go +++ /dev/null @@ -1 +0,0 @@ -package v1 diff --git a/api/external/maistra/v1/servicemeshcontrolplane_types.go b/api/external/maistra/v1/servicemeshcontrolplane_types.go deleted file mode 100644 index 769532776..000000000 --- a/api/external/maistra/v1/servicemeshcontrolplane_types.go +++ /dev/null @@ -1,149 +0,0 @@ -package v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kuadrant/kuadrant-operator/api/external/maistra/status" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -func init() { - SchemeBuilder.Register(&ServiceMeshControlPlane{}, &ServiceMeshControlPlaneList{}) -} - -const DefaultTemplate = "default" - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ServiceMeshControlPlane represents a deployment of the service mesh control -// plane. The control plane components are deployed in the namespace in which -// the ServiceMeshControlPlane resides. The configuration options for the -// components that comprise the control plane are specified in this object. -// +k8s:openapi-gen=true -// +kubebuilder:resource:shortName=smcp,categories=maistra-io -// +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.annotations.readyComponentCount",description="How many of the total number of components are ready" -// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Reconciled\")].reason",description="Whether or not the control plane installation is up to date." -// +kubebuilder:printcolumn:name="Template",type="string",JSONPath=".status.lastAppliedConfiguration.template",description="The configuration template to use as the base." -// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.lastAppliedConfiguration.version",description="The actual current version of the control plane installation." -// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the object" -// +kubebuilder:printcolumn:name="Image HUB",type="string",JSONPath=".status.lastAppliedConfiguration.istio.global.hub",description="The image hub used as the base for all component images.",priority=1 -type ServiceMeshControlPlane struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // The specification of the desired state of this ServiceMeshControlPlane. - // This includes the configuration options for all components that comprise - // the control plane. - // +kubebuilder:validation:Required - Spec ControlPlaneSpec `json:"spec"` - - // The current status of this ServiceMeshControlPlane and the components - // that comprise the control plane. This data may be out of date by some - // window of time. - Status ControlPlaneStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ServiceMeshControlPlaneList contains a list of ServiceMeshControlPlane -type ServiceMeshControlPlaneList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ServiceMeshControlPlane `json:"items"` -} - -// ControlPlaneStatus represents the current state of a ServiceMeshControlPlane. -type ControlPlaneStatus struct { - status.StatusBase `json:",inline"` - - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file - status.StatusType `json:",inline"` - - // The generation observed by the controller during the most recent - // reconciliation. The information in the status pertains to this particular - // generation of the object. - ObservedGeneration int64 `json:"observedGeneration,omitempty"` - - // The last version that was reconciled. - ReconciledVersion string `json:"reconciledVersion,omitempty"` - - // The list of components comprising the control plane and their statuses. - // +nullable - status.ComponentStatusList `json:",inline"` - - // The full specification of the configuration options that were applied - // to the components of the control plane during the most recent reconciliation. - // +optional - LastAppliedConfiguration ControlPlaneSpec `json:"lastAppliedConfiguration"` -} - -// GetReconciledVersion returns the reconciled version, or a default for older resources -func (s *ControlPlaneStatus) GetReconciledVersion() string { - if s == nil { - return status.ComposeReconciledVersion("0.0.0", 0) - } - if s.ReconciledVersion == "" { - return status.ComposeReconciledVersion("1.0.0", s.ObservedGeneration) - } - return s.ReconciledVersion -} - -// ControlPlaneSpec represents the configuration for installing a control plane. -type ControlPlaneSpec struct { - // Template selects the template to use for default values. Defaults to - // "default" when not set. - // DEPRECATED - use Profiles instead - // +optional - Template string `json:"template,omitempty"` - - // Profiles selects the profile to use for default values. Defaults to - // "default" when not set. Takes precedence over Template. - // +optional - Profiles []string `json:"profiles,omitempty"` - - // Version specifies what Maistra version of the control plane to install. - // When creating a new ServiceMeshControlPlane with an empty version, the - // admission webhook sets the version to the latest version supported by - // the operator. - // +optional - Version string `json:"version,omitempty"` - - // Deprecated: No longer used anywhere. - // Previously used to specify the NetworkType of the cluster. Defaults to "subnet". - // +optional - NetworkType NetworkType `json:"networkType,omitempty"` - - // Specifies the Istio configuration options that are passed to Helm when the - // Istio charts are rendered. These options are usually populated from the - // template specified in the spec.template field, but individual values can - // be overridden here. - // More info: https://maistra.io/docs/installation/installation-options/ - // +optional - // +kubebuilder:validation:Optional - Istio *HelmValues `json:"istio,omitempty"` - - // Specifies the 3Scale configuration options that are passed to Helm when the - // 3Scale charts are rendered. These values are usually populated from the - // template specified in the spec.template field, but individual values can - // be overridden here. - // More info: https://maistra.io/docs/installation/installation-options/#_3scale - // +optional - // +kubebuilder:validation:Optional - ThreeScale *HelmValues `json:"threeScale,omitempty"` -} - -// NetworkType is type definition representing the network type of the cluster -type NetworkType string - -const ( - // NetworkTypeSubnet when using ovs-subnet - NetworkTypeSubnet NetworkType = "subnet" - // NetworkTypeMultitenant when using ovs-multitenant - NetworkTypeMultitenant NetworkType = "multitenant" - // NetworkTypeNetworkPolicy when using ovs-networkpolicy - NetworkTypeNetworkPolicy NetworkType = "networkpolicy" -) diff --git a/api/external/maistra/v1/servicemeshmember_types.go b/api/external/maistra/v1/servicemeshmember_types.go deleted file mode 100644 index 16d989244..000000000 --- a/api/external/maistra/v1/servicemeshmember_types.go +++ /dev/null @@ -1,177 +0,0 @@ -package v1 - -import ( - "fmt" - - core "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kuadrant/kuadrant-operator/api/external/maistra/status" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -func init() { - SchemeBuilder.Register(&ServiceMeshMember{}, &ServiceMeshMemberList{}) -} - -// A ServiceMeshMember object marks the namespace in which it lives as a member -// of the Service Mesh Control Plane referenced in the object. -// The ServiceMeshMember object should be created in each application namespace -// that must be part of the service mesh and must be named "default". -// -// When the ServiceMeshMember object is created, it causes the namespace to be -// added to the ServiceMeshMemberRoll within the namespace of the -// ServiceMeshControlPlane object the ServiceMeshMember references. -// -// To reference a ServiceMeshControlPlane, the user creating the ServiceMeshMember -// object must have the "use" permission on the referenced ServiceMeshControlPlane -// object. This permission is given via the mesh-users RoleBinding (and mesh-user -// Role) in the namespace of the referenced ServiceMeshControlPlane object. -// +k8s:openapi-gen=true -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +kubebuilder:storageversion -// +kubebuilder:resource:shortName=smm,categories=maistra-io -// +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Control Plane",type="string",JSONPath=".status.annotations.controlPlaneRef",description="The ServiceMeshControlPlane this namespace belongs to" -// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="Whether or not namespace is configured as a member of the mesh." -// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the object" -type ServiceMeshMember struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // The desired state of this ServiceMeshMember. - // +kubebuilder:validation:Required - Spec ServiceMeshMemberSpec `json:"spec"` - - // The current status of this ServiceMeshMember. This data may be out of - // date by some window of time. - // +optional - Status ServiceMeshMemberStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ServiceMeshMemberList contains a list of ServiceMeshMember objects -type ServiceMeshMemberList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ServiceMeshMember `json:"items"` -} - -// ServiceMeshMemberSpec defines the member of the mesh -type ServiceMeshMemberSpec struct { - // A reference to the ServiceMeshControlPlane object. - ControlPlaneRef ServiceMeshControlPlaneRef `json:"controlPlaneRef"` -} - -// ServiceMeshControlPlaneRef is a reference to a ServiceMeshControlPlane object -type ServiceMeshControlPlaneRef struct { - // The name of the referenced ServiceMeshControlPlane object. - Name string `json:"name"` - - // The namespace of the referenced ServiceMeshControlPlane object. - Namespace string `json:"namespace"` -} - -func (s ServiceMeshControlPlaneRef) String() string { - return fmt.Sprintf("%s%c%s", s.Namespace, '/', s.Name) -} - -// ServiceMeshMemberStatus represents the current state of a ServiceMeshMember. -type ServiceMeshMemberStatus struct { - status.StatusBase `json:",inline"` - - // The generation observed by the controller during the most recent - // reconciliation. The information in the status pertains to this particular - // generation of the object. - ObservedGeneration int64 `json:"observedGeneration"` - - // The generation of the ServiceMeshControlPlane object observed by the - // controller during the most recent reconciliation of this - // ServiceMeshMember. - ServiceMeshGeneration int64 `json:"meshGeneration,omitempty"` // TODO: do we need this field at all? - - // The reconciled version of the ServiceMeshControlPlane object observed by - // the controller during the most recent reconciliation of this - // ServiceMeshMember. - ServiceMeshReconciledVersion string `json:"meshReconciledVersion,omitempty"` // TODO: do we need this field at all? - - // Represents the latest available observations of a ServiceMeshMember's - // current state. - Conditions []ServiceMeshMemberCondition `json:"conditions"` -} - -// ServiceMeshMemberConditionType represents the type of the condition. Condition types are: -// Reconciled, NamespaceConfigured -type ServiceMeshMemberConditionType string - -const ( - // ConditionTypeReconciled signifies whether or not the controller has - // updated the ServiceMeshMemberRoll object based on this ServiceMeshMember. - ConditionTypeMemberReconciled ServiceMeshMemberConditionType = "Reconciled" - // ConditionTypeReady signifies whether the namespace has been configured - // to use the mesh - ConditionTypeMemberReady ServiceMeshMemberConditionType = "Ready" // TODO: remove the Ready condition in v2 -) - -type ServiceMeshMemberConditionReason string - -const ( - // ConditionReasonDeletionError ... - ConditionReasonMemberCannotCreateMemberRoll ServiceMeshMemberConditionReason = "CreateMemberRollFailed" - ConditionReasonMemberCannotUpdateMemberRoll ServiceMeshMemberConditionReason = "UpdateMemberRollFailed" - ConditionReasonMemberCannotDeleteMemberRoll ServiceMeshMemberConditionReason = "DeleteMemberRollFailed" - ConditionReasonMemberNamespaceNotExists ServiceMeshMemberConditionReason = "NamespaceNotExists" - ConditionReasonMemberReferencesDifferentControlPlane ServiceMeshMemberConditionReason = "ReferencesDifferentControlPlane" - ConditionReasonMemberTerminating ServiceMeshMemberConditionReason = "Terminating" - ConditionReasonMemberNameInvalid ServiceMeshMemberConditionReason = "InvalidName" -) - -// Condition represents a specific condition on a resource -type ServiceMeshMemberCondition struct { - Type ServiceMeshMemberConditionType `json:"type,omitempty"` - Status core.ConditionStatus `json:"status,omitempty"` - LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` - Reason ServiceMeshMemberConditionReason `json:"reason,omitempty"` - Message string `json:"message,omitempty"` -} - -// GetCondition removes a condition for the list of conditions -func (s *ServiceMeshMemberStatus) GetCondition(conditionType ServiceMeshMemberConditionType) ServiceMeshMemberCondition { - if s == nil { - return ServiceMeshMemberCondition{Type: conditionType, Status: core.ConditionUnknown} - } - for i := range s.Conditions { - if s.Conditions[i].Type == conditionType { - return s.Conditions[i] - } - } - return ServiceMeshMemberCondition{Type: conditionType, Status: core.ConditionUnknown} -} - -// SetCondition sets a specific condition in the list of conditions -func (s *ServiceMeshMemberStatus) SetCondition(condition ServiceMeshMemberCondition) *ServiceMeshMemberStatus { - if s == nil { - return nil - } - now := metav1.Now() - for i := range s.Conditions { - if s.Conditions[i].Type == condition.Type { - if s.Conditions[i].Status != condition.Status { - condition.LastTransitionTime = now - } else { - condition.LastTransitionTime = s.Conditions[i].LastTransitionTime - } - s.Conditions[i] = condition - return s - } - } - - // If the condition does not exist, - // initialize the lastTransitionTime - condition.LastTransitionTime = now - s.Conditions = append(s.Conditions, condition) - return s -} diff --git a/api/external/maistra/v1/servicemeshmemberroll_types.go b/api/external/maistra/v1/servicemeshmemberroll_types.go deleted file mode 100644 index 70869c108..000000000 --- a/api/external/maistra/v1/servicemeshmemberroll_types.go +++ /dev/null @@ -1,284 +0,0 @@ -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/kuadrant/kuadrant-operator/api/external/maistra/status" -) - -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - -func init() { - SchemeBuilder.Register(&ServiceMeshMemberRoll{}, &ServiceMeshMemberRollList{}) -} - -// The ServiceMeshMemberRoll object configures which namespaces belong to a -// service mesh. Only namespaces listed in the ServiceMeshMemberRoll will be -// affected by the control plane. Any number of namespaces can be added, but a -// namespace may not exist in more than one service mesh. The -// ServiceMeshMemberRoll object must be created in the same namespace as -// the ServiceMeshControlPlane object and must be named "default". -// +k8s:openapi-gen=true -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// +kubebuilder:storageversion -// +kubebuilder:resource:shortName=smmr,categories=maistra-io -// +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.annotations.configuredMemberCount",description="How many of the total number of member namespaces are configured" -// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].reason",description="Whether all member namespaces have been configured or why that's not the case" -// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the object" -// +kubebuilder:printcolumn:name="Members",type="string",JSONPath=".status.members",description="Namespaces that are members of this Control Plane",priority=1 -type ServiceMeshMemberRoll struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Specification of the desired list of members of the service mesh. - // +kubebuilder:validation:Required - Spec ServiceMeshMemberRollSpec `json:"spec"` - - // The current status of this ServiceMeshMemberRoll. This data may be out - // of date by some window of time. - Status ServiceMeshMemberRollStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ServiceMeshMemberRollList contains a list of ServiceMeshMemberRoll -type ServiceMeshMemberRollList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ServiceMeshMemberRoll `json:"items"` -} - -// ServiceMeshMemberRollSpec is the specification of the desired list of -// members of the service mesh. -type ServiceMeshMemberRollSpec struct { - // List of namespaces that should be members of the service mesh. - // +optional - // +nullable - Members []string `json:"members,omitempty"` - - // Include namespaces whose labels match any of the specified selectors. - // +optional - MemberSelectors []metav1.LabelSelector `json:"memberSelectors,omitempty"` -} - -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 - } - } - - // check if namespace labels match any label selector - for _, selector := range smmr.Spec.MemberSelectors { - if selectorMatches(selector, ns.Labels) { - return true - } - } - return false -} - -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) || len(smmr.Spec.MemberSelectors) > 0 -} - -func selectorMatches(selector metav1.LabelSelector, labels map[string]string) bool { - 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. -type ServiceMeshMemberRollStatus struct { - status.StatusBase `json:",inline"` - - // The generation observed by the controller during the most recent - // reconciliation. The information in the status pertains to this particular - // generation of the object. - ObservedGeneration int64 `json:"observedGeneration,omitempty"` - - // The generation of the ServiceMeshControlPlane object observed by the - // controller during the most recent reconciliation of this - // ServiceMeshMemberRoll. - ServiceMeshGeneration int64 `json:"meshGeneration,omitempty"` - - // The reconciled version of the ServiceMeshControlPlane object observed by - // the controller during the most recent reconciliation of this - // ServiceMeshMemberRoll. - ServiceMeshReconciledVersion string `json:"meshReconciledVersion,omitempty"` - - // Complete list of namespaces that are configured as members of the service - // mesh - this includes namespaces specified in spec.members and those that - // contain a ServiceMeshMember object - // +optional - // +nullable - Members []string `json:"members"` - - // List of namespaces that are configured as members of the service mesh. - // +optional - // +nullable - ConfiguredMembers []string `json:"configuredMembers"` - - // List of namespaces that haven't been configured as members of the service - // mesh yet. - // +optional - // +nullable - PendingMembers []string `json:"pendingMembers"` - - // List of namespaces that are being removed as members of the service - // mesh. - // +optional - // +nullable - TerminatingMembers []string `json:"terminatingMembers"` - - // Represents the latest available observations of this ServiceMeshMemberRoll's - // current state. - // +optional - // +nullable - Conditions []ServiceMeshMemberRollCondition `json:"conditions"` - - // Represents the latest available observations of each member's - // current state. - // +optional - // +nullable - MemberStatuses []ServiceMeshMemberStatusSummary `json:"memberStatuses"` -} - -// ServiceMeshMemberStatusSummary represents a summary status of a ServiceMeshMember. -type ServiceMeshMemberStatusSummary struct { - Namespace string `json:"namespace"` - Conditions []ServiceMeshMemberCondition `json:"conditions"` -} - -// ServiceMeshMemberRollConditionType represents the type of the condition. Condition types are: -// Reconciled, NamespaceConfigured -type ServiceMeshMemberRollConditionType string - -const ( - // ConditionTypeMemberRollReady signifies whether the namespace has been configured - // to use the mesh - ConditionTypeMemberRollReady ServiceMeshMemberRollConditionType = "Ready" -) - -type ServiceMeshMemberRollConditionReason string - -const ( - // ConditionReasonConfigured indicates that all namespaces were configured - ConditionReasonConfigured ServiceMeshMemberRollConditionReason = "Configured" - // ConditionReasonReconcileError indicates that one of the namespaces to configure could not be configured - ConditionReasonReconcileError ServiceMeshMemberRollConditionReason = "ReconcileError" - // ConditionReasonSMCPMissing indicates that the ServiceMeshControlPlane resource does not exist - ConditionReasonSMCPMissing ServiceMeshMemberRollConditionReason = "ErrSMCPMissing" - // ConditionReasonMultipleSMCP indicates that multiple ServiceMeshControlPlane resources exist in the namespace - ConditionReasonMultipleSMCP ServiceMeshMemberRollConditionReason = "ErrMultipleSMCPs" - // ConditionReasonInvalidName indicates that the ServiceMeshMemberRoll name is invalid (only "default" is allowed) - ConditionReasonInvalidName ServiceMeshMemberRollConditionReason = "ErrInvalidName" - // ConditionReasonSMCPNotReconciled indicates that reconciliation of the SMMR was skipped because the SMCP has not been reconciled - ConditionReasonSMCPNotReconciled ServiceMeshMemberRollConditionReason = "SMCPReconciling" -) - -// Condition represents a specific condition on a resource -type ServiceMeshMemberRollCondition struct { - Type ServiceMeshMemberRollConditionType `json:"type,omitempty"` - Status core.ConditionStatus `json:"status,omitempty"` - LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` - Reason ServiceMeshMemberRollConditionReason `json:"reason,omitempty"` - Message string `json:"message,omitempty"` -} - -// GetCondition removes a condition for the list of conditions -func (s *ServiceMeshMemberRollStatus) GetCondition(conditionType ServiceMeshMemberRollConditionType) ServiceMeshMemberRollCondition { - if s == nil { - return ServiceMeshMemberRollCondition{Type: conditionType, Status: core.ConditionUnknown} - } - for i := range s.Conditions { - if s.Conditions[i].Type == conditionType { - return s.Conditions[i] - } - } - return ServiceMeshMemberRollCondition{Type: conditionType, Status: core.ConditionUnknown} -} - -// SetCondition sets a specific condition in the list of conditions -func (s *ServiceMeshMemberRollStatus) SetCondition(condition ServiceMeshMemberRollCondition) *ServiceMeshMemberRollStatus { - if s == nil { - return nil - } - now := metav1.Now() - for i := range s.Conditions { - if s.Conditions[i].Type == condition.Type { - if s.Conditions[i].Status != condition.Status { - condition.LastTransitionTime = now - } else { - condition.LastTransitionTime = s.Conditions[i].LastTransitionTime - } - s.Conditions[i] = condition - return s - } - } - - // If the condition does not exist, - // initialize the lastTransitionTime - condition.LastTransitionTime = now - s.Conditions = append(s.Conditions, condition) - return s -} diff --git a/api/external/maistra/v1/zz_generated.deepcopy.go b/api/external/maistra/v1/zz_generated.deepcopy.go deleted file mode 100644 index 6610dc2aa..000000000 --- a/api/external/maistra/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,445 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2021. - -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v1 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneSpec) DeepCopyInto(out *ControlPlaneSpec) { - *out = *in - if in.Profiles != nil { - in, out := &in.Profiles, &out.Profiles - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Istio != nil { - in, out := &in.Istio, &out.Istio - *out = (*in).DeepCopy() - } - if in.ThreeScale != nil { - in, out := &in.ThreeScale, &out.ThreeScale - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneSpec. -func (in *ControlPlaneSpec) DeepCopy() *ControlPlaneSpec { - if in == nil { - return nil - } - out := new(ControlPlaneSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneStatus) DeepCopyInto(out *ControlPlaneStatus) { - *out = *in - in.StatusBase.DeepCopyInto(&out.StatusBase) - in.StatusType.DeepCopyInto(&out.StatusType) - in.ComponentStatusList.DeepCopyInto(&out.ComponentStatusList) - in.LastAppliedConfiguration.DeepCopyInto(&out.LastAppliedConfiguration) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneStatus. -func (in *ControlPlaneStatus) DeepCopy() *ControlPlaneStatus { - if in == nil { - return nil - } - out := new(ControlPlaneStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HelmValues. -func (in *HelmValues) DeepCopy() *HelmValues { - if in == nil { - return nil - } - out := new(HelmValues) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshControlPlane) DeepCopyInto(out *ServiceMeshControlPlane) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshControlPlane. -func (in *ServiceMeshControlPlane) DeepCopy() *ServiceMeshControlPlane { - if in == nil { - return nil - } - out := new(ServiceMeshControlPlane) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshControlPlane) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshControlPlaneList) DeepCopyInto(out *ServiceMeshControlPlaneList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ServiceMeshControlPlane, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshControlPlaneList. -func (in *ServiceMeshControlPlaneList) DeepCopy() *ServiceMeshControlPlaneList { - if in == nil { - return nil - } - out := new(ServiceMeshControlPlaneList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshControlPlaneList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshControlPlaneRef) DeepCopyInto(out *ServiceMeshControlPlaneRef) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshControlPlaneRef. -func (in *ServiceMeshControlPlaneRef) DeepCopy() *ServiceMeshControlPlaneRef { - if in == nil { - return nil - } - out := new(ServiceMeshControlPlaneRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMember) DeepCopyInto(out *ServiceMeshMember) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMember. -func (in *ServiceMeshMember) DeepCopy() *ServiceMeshMember { - if in == nil { - return nil - } - out := new(ServiceMeshMember) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshMember) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberCondition) DeepCopyInto(out *ServiceMeshMemberCondition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberCondition. -func (in *ServiceMeshMemberCondition) DeepCopy() *ServiceMeshMemberCondition { - if in == nil { - return nil - } - out := new(ServiceMeshMemberCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberList) DeepCopyInto(out *ServiceMeshMemberList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ServiceMeshMember, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberList. -func (in *ServiceMeshMemberList) DeepCopy() *ServiceMeshMemberList { - if in == nil { - return nil - } - out := new(ServiceMeshMemberList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshMemberList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberRoll) DeepCopyInto(out *ServiceMeshMemberRoll) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberRoll. -func (in *ServiceMeshMemberRoll) DeepCopy() *ServiceMeshMemberRoll { - if in == nil { - return nil - } - out := new(ServiceMeshMemberRoll) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshMemberRoll) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberRollCondition) DeepCopyInto(out *ServiceMeshMemberRollCondition) { - *out = *in - in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberRollCondition. -func (in *ServiceMeshMemberRollCondition) DeepCopy() *ServiceMeshMemberRollCondition { - if in == nil { - return nil - } - out := new(ServiceMeshMemberRollCondition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberRollList) DeepCopyInto(out *ServiceMeshMemberRollList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ServiceMeshMemberRoll, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberRollList. -func (in *ServiceMeshMemberRollList) DeepCopy() *ServiceMeshMemberRollList { - if in == nil { - return nil - } - out := new(ServiceMeshMemberRollList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshMemberRollList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberRollSpec) DeepCopyInto(out *ServiceMeshMemberRollSpec) { - *out = *in - if in.Members != nil { - in, out := &in.Members, &out.Members - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.MemberSelectors != nil { - in, out := &in.MemberSelectors, &out.MemberSelectors - *out = make([]metav1.LabelSelector, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberRollSpec. -func (in *ServiceMeshMemberRollSpec) DeepCopy() *ServiceMeshMemberRollSpec { - if in == nil { - return nil - } - out := new(ServiceMeshMemberRollSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberRollStatus) DeepCopyInto(out *ServiceMeshMemberRollStatus) { - *out = *in - in.StatusBase.DeepCopyInto(&out.StatusBase) - if in.Members != nil { - in, out := &in.Members, &out.Members - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ConfiguredMembers != nil { - in, out := &in.ConfiguredMembers, &out.ConfiguredMembers - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.PendingMembers != nil { - in, out := &in.PendingMembers, &out.PendingMembers - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.TerminatingMembers != nil { - in, out := &in.TerminatingMembers, &out.TerminatingMembers - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]ServiceMeshMemberRollCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.MemberStatuses != nil { - in, out := &in.MemberStatuses, &out.MemberStatuses - *out = make([]ServiceMeshMemberStatusSummary, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberRollStatus. -func (in *ServiceMeshMemberRollStatus) DeepCopy() *ServiceMeshMemberRollStatus { - if in == nil { - return nil - } - out := new(ServiceMeshMemberRollStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberSpec) DeepCopyInto(out *ServiceMeshMemberSpec) { - *out = *in - out.ControlPlaneRef = in.ControlPlaneRef -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberSpec. -func (in *ServiceMeshMemberSpec) DeepCopy() *ServiceMeshMemberSpec { - if in == nil { - return nil - } - out := new(ServiceMeshMemberSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberStatus) DeepCopyInto(out *ServiceMeshMemberStatus) { - *out = *in - in.StatusBase.DeepCopyInto(&out.StatusBase) - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]ServiceMeshMemberCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberStatus. -func (in *ServiceMeshMemberStatus) DeepCopy() *ServiceMeshMemberStatus { - if in == nil { - return nil - } - out := new(ServiceMeshMemberStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshMemberStatusSummary) DeepCopyInto(out *ServiceMeshMemberStatusSummary) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]ServiceMeshMemberCondition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshMemberStatusSummary. -func (in *ServiceMeshMemberStatusSummary) DeepCopy() *ServiceMeshMemberStatusSummary { - if in == nil { - return nil - } - out := new(ServiceMeshMemberStatusSummary) - in.DeepCopyInto(out) - return out -} diff --git a/api/external/maistra/v2/addons.go b/api/external/maistra/v2/addons.go deleted file mode 100644 index 2fec5a6fa..000000000 --- a/api/external/maistra/v2/addons.go +++ /dev/null @@ -1,22 +0,0 @@ -package v2 - -// AddonsConfig configures additional features for use with the mesh -type AddonsConfig struct { - // Prometheus configures Prometheus specific addon capabilities - Prometheus *PrometheusAddonConfig `json:"prometheus,omitempty"` - // Stackdriver configures Stackdriver specific addon capabilities - Stackdriver *StackdriverAddonConfig `json:"stackdriver,omitempty"` - // Jaeger configures Jaeger specific addon capabilities - Jaeger *JaegerAddonConfig `json:"jaeger,omitempty"` - // Grafana configures a grafana instance to use with the mesh - // .Values.grafana.enabled, true if not null - // +optional - Grafana *GrafanaAddonConfig `json:"grafana,omitempty"` - // Kiali configures a kiali instance to use with the mesh - // .Values.kiali.enabled, true if not null - // +optional - Kiali *KialiAddonConfig `json:"kiali,omitempty"` - // ThreeScale configures the 3scale adapter - // +optional - ThreeScale *ThreeScaleAddonConfig `json:"3scale,omitempty"` -} diff --git a/api/external/maistra/v2/cluster.go b/api/external/maistra/v2/cluster.go deleted file mode 100644 index d8a9c31e1..000000000 --- a/api/external/maistra/v2/cluster.go +++ /dev/null @@ -1,76 +0,0 @@ -package v2 - -// ControlPlaneClusterConfig configures aspects related to clustering. -type ControlPlaneClusterConfig struct { - // .Values.global.multiCluster.clusterName, defaults to Kubernetes - // +optional - Name string `json:"name,omitempty"` - // .Values.global.network - // XXX: not sure what the difference is between this and cluster name - // +optional - Network string `json:"network,omitempty"` - // .Values.global.multiCluster.enabled, if not null - // +optional - MultiCluster *MultiClusterConfig `json:"multiCluster,omitempty"` - // .Values.global.meshExpansion.enabled, if not null - // XXX: it's not clear whether or not there is any overlap with MultiCluster, - // i.e. does MultiCluster require mesh expansion ports to be configured on - // the ingress gateway? - // +optional - MeshExpansion *MeshExpansionConfig `json:"meshExpansion,omitempty"` -} - -// MultiClusterConfig configures aspects related to multi-cluster. -// implies the following: -// adds external to RequestedNetworkView (ISTIO_META_REQUESTED_NETWORK_VIEW) for egress gateway -// adds "global" and "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global" to pod dns search suffixes -type MultiClusterConfig struct { - Enablement `json:",inline"` - // .Values.global.meshNetworks - // XXX: if non-empty, local cluster network should be configured as: - // : - // endpoints: - // - fromRegistry: - // gateways: - // - service: - // port: 443 # mtls port - // +optional - MeshNetworks map[string]MeshNetworkConfig `json:"meshNetworks,omitempty"` -} - -// MeshExpansionConfig configures aspects related to mesh expansion -type MeshExpansionConfig struct { - Enablement `json:",inline"` - // .Values.global.meshExpansion.useILB, true if not null, otherwise uses ingress gateway - // +optional - ILBGateway *GatewayConfig `json:"ilbGateway,omitempty"` -} - -// MeshNetworkConfig configures mesh networks for a multi-cluster mesh. -type MeshNetworkConfig struct { - Endpoints []MeshEndpointConfig `json:"endpoints,omitempty"` - Gateways []MeshGatewayConfig `json:"gateways,omitempty"` -} - -// MeshEndpointConfig specifies the endpoint of a mesh network. Only one of -// FromRegistry or FromCIDR may be specified -type MeshEndpointConfig struct { - // +optional - FromRegistry string `json:"fromRegistry,omitempty"` - // +optional - FromCIDR string `json:"fromCIDR,omitempty"` -} - -// MeshGatewayConfig specifies the gateway which should be used for accessing -// the network -type MeshGatewayConfig struct { - // +optional - // +deprecated - Service string `json:"service,omitempty"` - // +optional - RegistryServiceName string `json:"registryServiceName,omitempty"` - // +optional - Address string `json:"address,omitempty"` - // +optional - Port int32 `json:"port,omitempty"` -} diff --git a/api/external/maistra/v2/conversion.go b/api/external/maistra/v2/conversion.go deleted file mode 100644 index 18da38646..000000000 --- a/api/external/maistra/v2/conversion.go +++ /dev/null @@ -1,10 +0,0 @@ -package v2 - -import ( - "sigs.k8s.io/controller-runtime/pkg/conversion" -) - -var _ conversion.Hub = (*ServiceMeshControlPlane)(nil) - -// Hub marks v2 SMCP resource as the storage version -func (smcp *ServiceMeshControlPlane) Hub() {} diff --git a/api/external/maistra/v2/datadog.go b/api/external/maistra/v2/datadog.go deleted file mode 100644 index 7d0565432..000000000 --- a/api/external/maistra/v2/datadog.go +++ /dev/null @@ -1,6 +0,0 @@ -package v2 - -// DatadogTracerConfig configures a Datadog tracer for use with the mesh -type DatadogTracerConfig struct { - // TODO.... -} diff --git a/api/external/maistra/v2/doc.go b/api/external/maistra/v2/doc.go deleted file mode 100644 index dcd2663b9..000000000 --- a/api/external/maistra/v2/doc.go +++ /dev/null @@ -1,4 +0,0 @@ -// Package v2 contains API Schema definitions for the maistra v2 API group -// +k8s:deepcopy-gen=package,register -// +groupName=maistra.io -package v2 diff --git a/api/external/maistra/v2/extension_providers.go b/api/external/maistra/v2/extension_providers.go deleted file mode 100644 index 2a9e286df..000000000 --- a/api/external/maistra/v2/extension_providers.go +++ /dev/null @@ -1,183 +0,0 @@ -package v2 - -type ExtensionProviderConfig struct { - // A unique name identifying the extension provider. - Name string `json:"name"` - // Prometheus configures a Prometheus metrics provider. - Prometheus *ExtensionProviderPrometheusConfig `json:"prometheus,omitempty"` - // Zipkin configures a tracing provider that uses the Zipkin API. - Zipkin *ExtensionProviderZipkinTracingConfig `json:"zipkin,omitempty"` - // Opentelemetry configures an OpenTelemetry tracing provider. - Opentelemetry *ExtensionProviderOtelTracingConfig `json:"opentelemetry,omitempty"` - // EnvoyOtelAls configures an Envoy Open Telemetry Access Logging Service provider. - EnvoyOtelAls *ExtensionProviderEnvoyOtelLogConfig `json:"envoyOtelAls,omitempty"` - // EnvoyExtAuthzHTTP configures an external authorizer that implements - // the Envoy ext_authz filter authorization check service using the HTTP API. - EnvoyExtAuthzHTTP *ExtensionProviderEnvoyExternalAuthorizationHTTPConfig `json:"envoyExtAuthzHttp,omitempty"` - // EnvoyExtAuthzGRPC configures an external authorizer that implements - // the Envoy ext_authz filter authorization check service using the GRPC API. - EnvoyExtAuthzGRPC *ExtensionProviderEnvoyExternalAuthorizationGRPCConfig `json:"envoyExtAuthzGrpc,omitempty"` -} - -type ExtensionProviderPrometheusConfig struct{} - -type ExtensionProviderZipkinTracingConfig struct { - // REQUIRED. Specifies the service that the Zipkin API. - // Example: “zipkin.default.svc.cluster.local” or “bar/zipkin.example.com”. - Service string `json:"service"` - // REQUIRED. Specifies the port of the service. - Port int64 `json:"port"` - // Optional. Controls the overall path length allowed in a reported span. - // NOTE: currently only controls max length of the path tag. - MaxTagLength *int64 `json:"maxTagLength,omitempty"` - // Optional. A 128 bit trace id will be used in Istio. - // If true, will result in a 64 bit trace id being used. - Enable64bitTraceID *bool `json:"enable64bitTraceId,omitempty"` -} - -type ExtensionProviderOtelTracingConfig struct { - // REQUIRED. Specifies the OpenTelemetry endpoint that will receive OTLP traces. - // Example: “otlp.default.svc.cluster.local” or “bar/otlp.example.com”. - Service string `json:"service"` - // REQUIRED. Specifies the port of the service. - Port int64 `json:"port"` - // Optional. Controls the overall path length allowed in a reported span. - // NOTE: currently only controls max length of the path tag. - MaxTagLength *int64 `json:"maxTagLength,omitempty"` -} - -type ExtensionProviderEnvoyOtelLogConfig struct { - // REQUIRED. Specifies the service that implements the Envoy ALS gRPC authorization service. - // Example: “envoy-als.foo.svc.cluster.local” or “bar/envoy-als.example.com”. - Service string `json:"service"` - // REQUIRED. Specifies the port of the service. - Port int64 `json:"port"` - // Optional. The friendly name of the access log. Defaults: "otel_envoy_accesslog" - LogName *string `json:"logName,omitempty"` -} - -type ExtensionProviderEnvoyExternalAuthorizationHTTPConfig struct { - // REQUIRED. Specifies the service that implements the Envoy ext_authz HTTP authorization service. - // The format is `[/]`. The specification of `` is required only when it is insufficient - // to unambiguously resolve a service in the service registry. The `` is a fully qualified host name of a - // service defined by the Kubernetes service or ServiceEntry. - // - // Example: "my-ext-authz.foo.svc.cluster.local" or "bar/my-ext-authz.example.com". - Service string `json:"service"` - // REQUIRED. Specifies the port of the service. - Port int64 `json:"port"` - // The maximum duration that the proxy will wait for a response from the provider (default timeout: 600s). - // When this timeout condition is met, the proxy marks the communication to the authorization service as failure. - // In this situation, the response sent back to the client will depend on the configured `failOpen` field. - Timeout *string `json:"timeout,omitempty"` - // Sets a prefix to the value of authorization request header *Path*. - // For example, setting this to "/check" for an original user request at path "/admin" will cause the - // authorization check request to be sent to the authorization service at the path "/check/admin" instead of "/admin". - PathPrefix *string `json:"pathPrefix,omitempty"` - // If true, the user request will be allowed even if the communication with the authorization service has failed, - // or if the authorization service has returned a HTTP 5xx error. - // Default is false and the request will be rejected with "Forbidden" response. - FailOpen *bool `json:"failOpen,omitempty"` - // Sets the HTTP status that is returned to the client when there is a network error to the authorization service. - // The default status is "403" (HTTP Forbidden). - StatusOnError *string `json:"statusOnError,omitempty"` - // List of client request headers that should be included in the authorization request sent to the authorization service. - // Note that in addition to the headers specified here following headers are included by default: - // 1. *Host*, *Method*, *Path* and *Content-Length* are automatically sent. - // 2. *Content-Length* will be set to 0 and the request will not have a message body. However, the authorization - // request can include the buffered client request body (controlled by includeRequestBodyInCheck setting), - // consequently the value of Content-Length of the authorization request reflects the size of its payload size. - // - // Exact, prefix and suffix matches are supported (similar to the authorization policy rule syntax except the presence match - // https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule): - // - Exact match: "abc" will match on value "abc". - // - Prefix match: "abc*" will match on value "abc" and "abcd". - // - Suffix match: "*abc" will match on value "abc" and "xabc". - IncludeRequestHeadersInCheck []string `json:"includeRequestHeadersInCheck,omitempty"` - // Set of additional fixed headers that should be included in the authorization request sent to the authorization service. - // Key is the header name and value is the header value. - // Note that client request of the same key or headers specified in includeRequestHeadersInCheck will be overridden. - IncludeAdditionalHeadersInCheck map[string]string `json:"includeAdditionalHeadersInCheck,omitempty"` - // If set, the client request body will be included in the authorization request sent to the authorization service. - IncludeRequestBodyInCheck *ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig `json:"includeRequestBodyInCheck,omitempty"` - // List of headers from the authorization service that should be added or overridden in the original request and - // forwarded to the upstream when the authorization check result is allowed (HTTP code 200). - // If not specified, the original request will not be modified and forwarded to backend as-is. - // Note, any existing headers will be overridden. - // - // Exact, prefix and suffix matches are supported (similar to the authorization policy rule syntax except the presence match - // https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule): - // - Exact match: "abc" will match on value "abc". - // - Prefix match: "abc*" will match on value "abc" and "abcd". - // - Suffix match: "*abc" will match on value "abc" and "xabc". - HeadersToUpstreamOnAllow []string `json:"headersToUpstreamOnAllow,omitempty"` - // List of headers from the authorization service that should be forwarded to downstream when the authorization - // check result is not allowed (HTTP code other than 200). - // If not specified, all the authorization response headers, except *Authority (Host)* will be in the response to - // the downstream. - // When a header is included in this list, *Path*, *Status*, *Content-Length*, *WWWAuthenticate* and *Location* are - // automatically added. - // Note, the body from the authorization service is always included in the response to downstream. - // - // Exact, prefix and suffix matches are supported (similar to the authorization policy rule syntax except the presence match - // https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule): - // - Exact match: "abc" will match on value "abc". - // - Prefix match: "abc*" will match on value "abc" and "abcd". - // - Suffix match: "*abc" will match on value "abc" and "xabc". - HeadersToDownstreamOnDeny []string `json:"headersToDownstreamOnDeny,omitempty"` - // List of headers from the authorization service that should be forwarded to downstream when the authorization - // check result is allowed (HTTP code 200). - // If not specified, the original response will not be modified and forwarded to downstream as-is. - // Note, any existing headers will be overridden. - // - // Exact, prefix and suffix matches are supported (similar to the authorization policy rule syntax except the presence match - // https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule): - // - Exact match: "abc" will match on value "abc". - // - Prefix match: "abc*" will match on value "abc" and "abcd". - // - Suffix match: "*abc" will match on value "abc" and "xabc". - HeadersToDownstreamOnAllow []string `json:"headersToDownstreamOnAllow,omitempty"` -} -type ExtensionProviderEnvoyExternalAuthorizationGRPCConfig struct { - // REQUIRED. Specifies the service that implements the Envoy ext_authz gRPC authorization service. - // The format is `[/]`. The specification of `` is required only when it is insufficient - // to unambiguously resolve a service in the service registry. The `` is a fully qualified host name of a - // service defined by the Kubernetes service or ServiceEntry. - // - // Example: "my-ext-authz.foo.svc.cluster.local" or "bar/my-ext-authz.example.com". - Service string `json:"service"` - // REQUIRED. Specifies the port of the service. - Port int64 `json:"port"` - // The maximum duration that the proxy will wait for a response from the provider, this is the timeout for a specific request (default timeout: 600s). - // When this timeout condition is met, the proxy marks the communication to the authorization service as failure. - // In this situation, the response sent back to the client will depend on the configured `failOpen` field. - Timeout *string `json:"timeout,omitempty"` - // If true, the HTTP request or TCP connection will be allowed even if the communication with the authorization service has failed, - // or if the authorization service has returned a HTTP 5xx error. - // Default is false. For HTTP request, it will be rejected with 403 (HTTP Forbidden). For TCP connection, it will be closed immediately. - FailOpen *bool `json:"failOpen,omitempty"` - // Sets the HTTP status that is returned to the client when there is a network error to the authorization service. - // The default status is "403" (HTTP Forbidden). - StatusOnError *string `json:"statusOnError,omitempty"` - // If set, the client request body will be included in the authorization request sent to the authorization service. - IncludeRequestBodyInCheck *ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig `json:"includeRequestBodyInCheck,omitempty"` -} - -type ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig struct { - // Sets the maximum size of a message body that the ext-authz filter will hold in memory. - // If max_request_bytes is reached, and allow_partial_message is false, Envoy will return a 413 (Payload Too Large). - // Otherwise the request will be sent to the provider with a partial message. - // Note that this setting will have precedence over the failOpen field, the 413 will be returned even when the - // fail_open is set to true. - MaxRequestBytes *int64 `json:"maxRequestBytes,omitempty"` - // When this field is true, ext-authz filter will buffer the message until maxRequestBytes is reached. - // The authorization request will be dispatched and no 413 HTTP error will be returned by the filter. - // A "x-envoy-auth-partial-body: false|true" metadata header will be added to the authorization request message - // indicating if the body data is partial. - AllowPartialMessage *bool `json:"allowPartialMessage,omitempty"` - // nolint:lll - // If true, the body sent to the external authorization service in the gRPC authorization request is set with raw bytes - // in the raw_body field (https://github.com/envoyproxy/envoy/blame/cffb095d59d7935abda12b9509bcd136808367bb/api/envoy/service/auth/v3/attribute_context.proto#L153). - // Otherwise, it will be filled with UTF-8 string in the body field (https://github.com/envoyproxy/envoy/blame/cffb095d59d7935abda12b9509bcd136808367bb/api/envoy/service/auth/v3/attribute_context.proto#L147). - // This field only works with the envoyExtAuthzGrpc provider and has no effect for the envoyExtAuthzHttp provider. - PackAsBytes *bool `json:"packAsBytes,omitempty"` -} diff --git a/api/external/maistra/v2/gateways.go b/api/external/maistra/v2/gateways.go deleted file mode 100644 index 044d481a6..000000000 --- a/api/external/maistra/v2/gateways.go +++ /dev/null @@ -1,165 +0,0 @@ -package v2 - -import ( - corev1 "k8s.io/api/core/v1" -) - -// GatewaysConfig configures gateways for the mesh -type GatewaysConfig struct { - Enablement `json:",inline"` - // ClusterIngress configures the istio-ingressgateway for the mesh - // works in conjunction with cluster.meshExpansion.ingress configuration - // (for enabling ILB gateway and mesh expansion ports) - // .Values.gateways.istio-ingressgateway - // +optional - ClusterIngress *ClusterIngressGatewayConfig `json:"ingress,omitempty"` - // ClusterEgress configures the istio-egressgateway for the mesh. - // .Values.gateways.istio-egressgateway - // +optional - ClusterEgress *EgressGatewayConfig `json:"egress,omitempty"` - // Other user defined ingress gateways - // .Values.gateways. - // +optional - IngressGateways map[string]*IngressGatewayConfig `json:"additionalIngress,omitempty"` - // Other user defined egress gateways - // .Values.gateways. - // +optional - EgressGateways map[string]*EgressGatewayConfig `json:"additionalEgress,omitempty"` - // Route configures the Gateway ↔ OpenShift Route integration - OpenShiftRoute *OpenShiftRouteConfig `json:"openshiftRoute,omitempty"` -} - -// OpenShiftRouteConfig represents the Gateway ↔ OpenShift Route integration -type OpenShiftRouteConfig struct { - Enablement `json:",inline"` -} - -// GatewayConfig represents the configuration for a gateway -// XXX: should standard istio secrets be configured automatically, i.e. should -// the user be forced to add these manually? -type GatewayConfig struct { - Enablement `json:",inline"` - // Namespace is the namespace within which the gateway will be installed, - // defaults to control plane namespace. - // .Values.gateways..namespace - // XXX: for the standard gateways, it might be possible that related - // resources could be installed in control plane namespace instead of the - // gateway namespace. not sure if this is a problem or not. - // +optional - Namespace string `json:"namespace,omitempty"` - // Service configures the service associated with the gateway, e.g. port - // mappings, service type, annotations/labels, etc. - // .Values.gateways..ports, .Values.gateways..type, - // .Values.gateways..loadBalancerIP, - // .Values.gateways..serviceAnnotations, - // .Values.gateways..serviceLabels - // XXX: currently there is no distinction between labels and serviceLabels - // +optional - Service GatewayServiceConfig `json:"service,omitempty"` - // The router mode to be used by the gateway. - // .Values.gateways..env.ISTIO_META_ROUTER_MODE, defaults to sni-dnat - // +optional - RouterMode RouterModeType `json:"routerMode,omitempty"` - // Volumes is used to configure additional Secret and ConfigMap volumes that - // should be mounted for the gateway's pod. - // .Values.gateways..secretVolumes, .Values.gateways..configMapVolumes - // +optional - Volumes []VolumeConfig `json:"volumes,omitempty"` - // Runtime is used to configure execution parameters for the pod/containers - // e.g. resources, replicas, etc. - // +optional - Runtime *ComponentRuntimeConfig `json:"runtime,omitempty"` - // XXX: do we need to support additionalContainers??? -} - -// EgressGatewayConfig represents gateway configuration for egress -type EgressGatewayConfig struct { - GatewayConfig `json:",inline"` - // RequestedNetworkView is a list of networks whose services should be made - // available to the gateway. This is used primarily for mesh expansion/multi-cluster. - // .Values.gateways..env.ISTIO_META_REQUESTED_NETWORK_VIEW env, defaults to empty list - // XXX: I think this is only applicable to egress gateways - // +optional - RequestedNetworkView []string `json:"requestedNetworkView,omitempty"` -} - -// IngressGatewayConfig represents gateway configuration for ingress -type IngressGatewayConfig struct { - GatewayConfig `json:",inline"` - // EnableSDS for the gateway. - // .Values.gateways..sds.enabled - // +optional - SDS *SecretDiscoveryService `json:"sds,omitempty"` - // RouteConfig specifies whether to create an OpenShift Route for the ingress gateway deployment - // +optional - RouteConfig *Enablement `json:"routeConfig,omitempty"` -} - -// SecretDiscoveryService configures whether or not SDS is configured for the gateway -type SecretDiscoveryService struct { - Enablement `json:",inline"` - // Runtime configuration for sds sidecar - Runtime *ContainerConfig `json:"runtime,omitempty"` -} - -// ClusterIngressGatewayConfig represents gateway configuration for cluster ingress -type ClusterIngressGatewayConfig struct { - IngressGatewayConfig `json:",inline"` - // .Values.global.k8sIngress.enabled - // implies the following: - // .Values.global.k8sIngress.gatewayName will match the ingress gateway - // .Values.global.k8sIngress.enableHttps will be true if gateway service exposes port 443 - // XXX: not sure whether or not this is specific to multicluster, mesh expansion, or both - // +optional - IngressEnabled *bool `json:"ingress,omitempty"` - // MeshExpansionPorts define the port set used with multi-cluster/mesh expansion - // +optional - MeshExpansionPorts []corev1.ServicePort `json:"meshExpansionPorts,omitempty"` -} - -// RouterModeType represents the router modes available. -type RouterModeType string - -const ( - // RouterModeTypeSNIDNAT represents sni-dnat router mode - RouterModeTypeSNIDNAT RouterModeType = "sni-dnat" - // RouterModeTypeStandard represents standard router mode - RouterModeTypeStandard RouterModeType = "standard" -) - -// GatewayServiceConfig configures the k8s Service associated with the gateway -type GatewayServiceConfig struct { - // XXX: selector is ignored - // Service details used to configure the gateway's Service resource - // +optional - corev1.ServiceSpec `json:",inline"` - // metadata to be applied to the gateway's service (annotations and labels) - // +optional - Metadata *MetadataConfig `json:"metadata,omitempty"` -} - -// VolumeConfig is used to specify volumes that should be mounted on the pod. -type VolumeConfig struct { - // Volume.Name maps to .Values.gateways... (type-name is configMapName or secretName) - // .configVolumes -> .configMapName = volume.name - // .secretVolumes -> .secretName = volume.name - // Only ConfigMap and Secret fields are supported - Volume GatewayVolume `json:"volume,omitempty"` - // Mount.Name maps to .Values.gateways...name - // .configVolumes -> .name = mount.name, .mountPath = mount.mountPath - // .secretVolumes -> .name = mount.name, .mountPath = mount.mountPath - // Only Name and MountPath fields are supported - Mount corev1.VolumeMount `json:"volumeMount,omitempty"` -} - -// GatewayVolume is a pared down version of corev1.Volume, which only supports -// specifying ConfigMap and Secret volume types. -type GatewayVolume struct { - // ConfigMap represents a configMap that should populate this volume - // +optional - ConfigMap *corev1.ConfigMapVolumeSource `json:"configMap,omitempty"` - // Secret represents a secret that should populate this volume. - // More info: https://kubernetes.io/docs/concepts/storage/volumes#secret - // +optional - Secret *corev1.SecretVolumeSource `json:"secret,omitempty"` -} diff --git a/api/external/maistra/v2/general.go b/api/external/maistra/v2/general.go deleted file mode 100644 index ff3838a58..000000000 --- a/api/external/maistra/v2/general.go +++ /dev/null @@ -1,16 +0,0 @@ -package v2 - -// GeneralConfig for control plane -type GeneralConfig struct { - // Logging represents the logging configuration for the control plane components - // XXX: Should this be separate from Proxy.Logging? - // +optional - Logging *LoggingConfig `json:"logging,omitempty"` - - // ValidationMessages configures the control plane to add validationMessages - // to the status fields of istio.io resources. This can be usefule for - // detecting configuration errors in resources. - // .Values.galley.enableAnalysis (=v2.0) - ValidationMessages *bool `json:"validationMessages,omitempty"` -} diff --git a/api/external/maistra/v2/grafana.go b/api/external/maistra/v2/grafana.go deleted file mode 100644 index 4d783db69..000000000 --- a/api/external/maistra/v2/grafana.go +++ /dev/null @@ -1,68 +0,0 @@ -package v2 - -// GrafanaAddonConfig configures a grafana instance for use with the mesh. Only -// one of install or address may be specified -type GrafanaAddonConfig struct { - Enablement `json:",inline"` - // Install a new grafana instance and manage with control plane - // +optional - Install *GrafanaInstallConfig `json:"install,omitempty"` - // Address is the address of an existing grafana installation - // implies .Values.kiali.dashboard.grafanaURL - // +optional - Address *string `json:"address,omitempty"` -} - -// GrafanaInstallConfig is used to configure a new installation of grafana. -type GrafanaInstallConfig struct { - // SelfManaged, true if the entire install should be managed by Maistra, false if using grafana CR (not supported) - // +optional - SelfManaged bool `json:"selfManaged,omitempty"` - // Config configures the behavior of the grafana installation - // +optional - Config *GrafanaConfig `json:"config,omitempty"` - // Service configures the k8s Service associated with the grafana installation - // XXX: grafana service config does not follow other addon components' structure - // +optional - Service *ComponentServiceConfig `json:"service,omitempty"` - // Persistence configures a PersistentVolume associated with the grafana installation - // .Values.grafana.persist, true if not null - // +optional - Persistence *ComponentPersistenceConfig `json:"persistence,omitempty"` - // Security is used to secure the grafana service. - // .Values.grafana.security.enabled, true if not null - // XXX: unused for maistra, as we use oauth-proxy - // +optional - Security *GrafanaSecurityConfig `json:"security,omitempty"` -} - -// GrafanaConfig configures the behavior of the grafana installation -type GrafanaConfig struct { - // Env allows specification of various grafana environment variables to be - // configured on the grafana container. - // .Values.grafana.env - // XXX: This is pretty cheesy... - // +optional - Env map[string]string `json:"env,omitempty"` - // EnvSecrets allows specification of secret fields into grafana environment - // variables to be configured on the grafana container - // .Values.grafana.envSecrets - // XXX: This is pretty cheesy... - // +optional - EnvSecrets map[string]string `json:"envSecrets,omitempty"` -} - -// GrafanaSecurityConfig is used to secure access to grafana -type GrafanaSecurityConfig struct { - Enablement `json:",inline"` - // SecretName is the name of a secret containing the username/password that - // should be used to access grafana. - // +optional - SecretName string `json:"secretName,omitempty"` - // UsernameKey is the name of the key within the secret identifying the username. - // +optional - UsernameKey string `json:"usernameKey,omitempty"` - // PassphraseKey is the name of the key within the secret identifying the password. - // +optional - PassphraseKey string `json:"passphraseKey,omitempty"` -} diff --git a/api/external/maistra/v2/jaeger.go b/api/external/maistra/v2/jaeger.go deleted file mode 100644 index 61b5d3590..000000000 --- a/api/external/maistra/v2/jaeger.go +++ /dev/null @@ -1,98 +0,0 @@ -package v2 - -import v1 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v1" - -// JaegerAddonConfig configuration specific to Jaeger integration. -// XXX: this currently deviates from upstream, which creates a jaeger all-in-one deployment manually -type JaegerAddonConfig struct { - // Name of Jaeger CR, Namespace must match control plane namespace - Name string `json:"name,omitempty"` - // Install configures a Jaeger installation, which will be created if the - // named Jaeger resource is not present. If null, the named Jaeger resource - // must exist. - // +optional - Install *JaegerInstallConfig `json:"install,omitempty"` -} - -// JaegerInstallConfig configures a Jaeger installation. -type JaegerInstallConfig struct { - // Config represents the configuration of Jaeger behavior. - // +optional - Storage *JaegerStorageConfig `json:"storage,omitempty"` - // Ingress configures k8s Ingress or OpenShift Route for Jaeger services - // .Values.tracing.jaeger.ingress.enabled, false if null - // +optional - Ingress *JaegerIngressConfig `json:"ingress,omitempty"` -} - -// JaegerStorageConfig configures the storage used by the Jaeger installation. -type JaegerStorageConfig struct { - // Type of storage to use - Type JaegerStorageType `json:"type,omitempty"` - // Memory represents configuration of in-memory storage - // implies .Values.tracing.jaeger.template=all-in-one - // +optional - Memory *JaegerMemoryStorageConfig `json:"memory,omitempty"` - // Elasticsearch represents configuration of elasticsearch storage - // implies .Values.tracing.jaeger.template=production-elasticsearch - // +optional - Elasticsearch *JaegerElasticsearchStorageConfig `json:"elasticsearch,omitempty"` -} - -// JaegerStorageType represents the type of storage configured for Jaeger -type JaegerStorageType string - -const ( - // JaegerStorageTypeMemory represents in-memory storage - JaegerStorageTypeMemory JaegerStorageType = "Memory" - // JaegerStorageTypeElasticsearch represents Elasticsearch storage - JaegerStorageTypeElasticsearch JaegerStorageType = "Elasticsearch" -) - -// JaegerMemoryStorageConfig configures in-memory storage parameters for Jaeger -type JaegerMemoryStorageConfig struct { - // MaxTraces to store - // .Values.tracing.jaeger.memory.max_traces, defaults to 100000 - // +optional - MaxTraces *int64 `json:"maxTraces,omitempty"` -} - -// JaegerElasticsearchStorageConfig configures elasticsearch storage parameters for Jaeger -type JaegerElasticsearchStorageConfig struct { - // NodeCount represents the number of elasticsearch nodes to create. - // .Values.tracing.jaeger.elasticsearch.nodeCount, defaults to 3 - // +optional - NodeCount *int32 `json:"nodeCount,omitempty"` - // Storage represents storage configuration for elasticsearch. - // .Values.tracing.jaeger.elasticsearch.storage, raw yaml - // XXX: RawExtension? - // +optional - Storage *v1.HelmValues `json:"storage,omitempty"` - // RedundancyPolicy configures the redundancy policy for elasticsearch - // .Values.tracing.jaeger.elasticsearch.redundancyPolicy, raw yaml - // +optional - RedundancyPolicy string `json:"redundancyPolicy,omitempty"` - // IndexCleaner represents the configuration for the elasticsearch index cleaner - // .Values.tracing.jaeger.elasticsearch.esIndexCleaner, raw yaml - // XXX: RawExtension? - // +optional - IndexCleaner *v1.HelmValues `json:"indexCleaner,omitempty"` -} - -// JaegerIngressConfig configures k8s Ingress or OpenShift Route for exposing -// Jaeger services. -type JaegerIngressConfig struct { - Enablement `json:",inline"` - // Metadata represents additional annotations/labels to be applied to the ingress/route. - // +optional - Metadata *MetadataConfig `json:"metadata,omitempty"` -} - -// ResourceName returns the resource name for the Jaeger resource, returning a -// sensible default if the Name field is not set ("jaeger"). -func (c JaegerAddonConfig) ResourceName() string { - if c.Name == "" { - return "jaeger" - } - return c.Name -} diff --git a/api/external/maistra/v2/kiali.go b/api/external/maistra/v2/kiali.go deleted file mode 100644 index 41027aca4..000000000 --- a/api/external/maistra/v2/kiali.go +++ /dev/null @@ -1,80 +0,0 @@ -package v2 - -import corev1 "k8s.io/api/core/v1" - -// KialiAddonConfig is used to configure a kiali instance for use with the mesh -type KialiAddonConfig struct { - Enablement `json:",inline"` - // Name of Kiali CR, Namespace must match control plane namespace - Name string `json:"name,omitempty"` - // Install a Kiali resource if the named Kiali resource is not present. - // +optional - Install *KialiInstallConfig `json:"install,omitempty"` -} - -// KialiInstallConfig is used to configure a kiali installation -type KialiInstallConfig struct { - // Dashboard configures the behavior of the kiali dashboard. - // +optional - Dashboard *KialiDashboardConfig `json:"dashboard,omitempty"` - // Service is used to configure the k8s Service associated with the kiali - // installation. - // XXX: provided for upstream support, only ingress is used, and then only - // for enablement and contextPath - // +optional - Service *ComponentServiceConfig `json:"service,omitempty"` - - // Deployment configures the kiali deployment. - // +optional - // +deprecated - Deployment *KialiDeploymentConfig `json:"deployment,omitempty"` -} - -// KialiDashboardConfig configures the behavior of the kiali dashboard -type KialiDashboardConfig struct { - // ViewOnly configures view_only_mode for the dashboard - // .Values.kiali.dashboard.viewOnlyMode - // +optional - ViewOnly *bool `json:"viewOnly,omitempty"` - // XXX: should the user have a choice here, or should these be configured - // automatically if they are enabled for the control plane installation? - // Grafana endpoint will be configured based on Grafana configuration - // +optional - EnableGrafana *bool `json:"enableGrafana,omitempty"` - // Prometheus endpoint will be configured based on Prometheus configuration - // +optional - EnablePrometheus *bool `json:"enablePrometheus,omitempty"` - // Tracing endpoint will be configured based on Tracing configuration - // +optional - EnableTracing *bool `json:"enableTracing,omitempty"` -} - -// KialiDeploymentConfig configures the kiali deployment -// +deprecated -// Deprecated: Use runtime.components.kiali instead. -type KialiDeploymentConfig struct { - // +optional - Resources *corev1.ResourceRequirements `json:"resources,omitempty"` - - // If specified, the pod's scheduling constraints - // +optional - Affinity *corev1.Affinity `json:"affinity,omitempty"` - - // Selector which must match a node's labels for the pod to be scheduled on that node. - // More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - // +optional - NodeSelector map[string]string `json:"nodeSelector,omitempty"` - - // If specified, the kiali pod's tolerations. - // +optional - Tolerations []corev1.Toleration `json:"tolerations,omitempty"` -} - -// ResourceName returns the resource name for the Kiali resource, returning a -// sensible default if the Name field is not set ("kiali"). -func (c KialiAddonConfig) ResourceName() string { - if c.Name == "" { - return "kiali" - } - return c.Name -} diff --git a/api/external/maistra/v2/lightstep.go b/api/external/maistra/v2/lightstep.go deleted file mode 100644 index 3494818cb..000000000 --- a/api/external/maistra/v2/lightstep.go +++ /dev/null @@ -1,6 +0,0 @@ -package v2 - -// LightstepTracerConfig configures a Lightstep tracer for use with the mesh -type LightstepTracerConfig struct { - // TODO.... -} diff --git a/api/external/maistra/v2/logging.go b/api/external/maistra/v2/logging.go deleted file mode 100644 index 4ab01174c..000000000 --- a/api/external/maistra/v2/logging.go +++ /dev/null @@ -1,97 +0,0 @@ -package v2 - -// LoggingConfig for control plane components -type LoggingConfig struct { - // ComponentLevels configures log level for specific envoy components - // .Values.global.proxy.componentLogLevel, overridden by sidecar.istio.io/componentLogLevel - // map of : - // +optional - ComponentLevels ComponentLogLevels `json:"componentLevels,omitempty"` - // LogAsJSON enables JSON logging - // .Values.global.logAsJson - // +optional - LogAsJSON *bool `json:"logAsJSON,omitempty"` -} - -// ProxyLoggingConfig configures logging for a component -type ProxyLoggingConfig struct { - // Level the log level - // .Values.global.proxy.logLevel, overridden by sidecar.istio.io/logLevel - // +optional - Level LogLevel `json:"level,omitempty"` - // ComponentLevels configures log level for specific envoy components - // .Values.global.proxy.componentLogLevel, overridden by sidecar.istio.io/componentLogLevel - // map of : - // +optional - ComponentLevels ComponentLogLevels `json:"componentLevels,omitempty"` -} - -// ComponentLogLevels represent various logging levels, e.g. trace, debug, etc. -type ComponentLogLevels map[EnvoyComponent]LogLevel - -// LogLevel represents the logging level -type LogLevel string - -const ( - // LogLevelTrace trace logging level - LogLevelTrace LogLevel = "trace" - // LogLevelDebug debug logging level - LogLevelDebug LogLevel = "debug" - // LogLevelInfo info logging level - LogLevelInfo LogLevel = "info" - // LogLevelWarning warning logging level - LogLevelWarning LogLevel = "warn" - // LogLevelWarningProxy proxy warning logging level - LogLevelWarningProxy LogLevel = "warning" - // LogLevelError error logging level - LogLevelError LogLevel = "error" - // LogLevelCritical critical logging level - LogLevelCritical LogLevel = "critical" - // LogLevelFatal critical logging level - LogLevelFatal LogLevel = "fatal" - // LogLevelNone disable logging - LogLevelNone LogLevel = "none" - // LogLevelOff disable logging - LogLevelOff LogLevel = "off" -) - -// EnvoyComponent represents an envoy component to configure logging -type EnvoyComponent string - -// not a comprehensive list -const ( - EnvoyComponentAdmin EnvoyComponent = "admin" - EnvoyComponentAssert EnvoyComponent = "assert" - EnvoyComponentBacktrace EnvoyComponent = "backtrace" - EnvoyComponentClient EnvoyComponent = "client" - EnvoyComponentConfig EnvoyComponent = "config" - EnvoyComponentConnection EnvoyComponent = "connection" - EnvoyComponentConnHandler EnvoyComponent = "conn_handler" - EnvoyComponentFile EnvoyComponent = "file" - EnvoyComponentFilter EnvoyComponent = "filter" - EnvoyComponentForwardProxy EnvoyComponent = "forward_proxy" - EnvoyComponentGRPC EnvoyComponent = "grpc" - EnvoyComponentHealth EnvoyComponent = "hc" - EnvoyComponentHealthChecker EnvoyComponent = "health_checker" - EnvoyComponentHTTP EnvoyComponent = "http" - EnvoyComponentHTTP2 EnvoyComponent = "http2" - EnvoyComponentInit EnvoyComponent = "init" - EnvoyComponentIO EnvoyComponent = "io" - EnvoyComponentJWT EnvoyComponent = "jwt" - EnvoyComponentLua EnvoyComponent = "lua" - EnvoyComponentMain EnvoyComponent = "main" - EnvoyComponentMisc EnvoyComponent = "misc" - EnvoyComponentQuic EnvoyComponent = "quic" - EnvoyComponentPool EnvoyComponent = "pool" - EnvoyComponentRBAC EnvoyComponent = "rbac" - EnvoyComponentRouter EnvoyComponent = "router" - EnvoyComponentRuntime EnvoyComponent = "runtime" - EnvoyComponentStats EnvoyComponent = "stats" - EnvoyComponentSecret EnvoyComponent = "secret" - EnvoyComponentTap EnvoyComponent = "tap" - EnvoyComponentTesting EnvoyComponent = "testing" - EnvoyComponentTracing EnvoyComponent = "tracing" - EnvoyComponentUpstream EnvoyComponent = "upstream" - EnvoyComponentUDP EnvoyComponent = "udp" - EnvoyComponentWASM EnvoyComponent = "wasm" -) diff --git a/api/external/maistra/v2/meshconfig.go b/api/external/maistra/v2/meshconfig.go deleted file mode 100644 index 10456274a..000000000 --- a/api/external/maistra/v2/meshconfig.go +++ /dev/null @@ -1,34 +0,0 @@ -package v2 - -import v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -// MeshConfig TODO: add description -type MeshConfig struct { - // 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"` - // A list of Kubernetes selectors that specify the set of namespaces that Istio considers when - // computing configuration updates for sidecars. This can be used to reduce Istio's computational load - // by limiting the number of entities (including services, pods, and endpoints) that are watched and processed. - // If omitted, Istio will use the default behavior of processing all namespaces in the cluster. - // Elements in the list are disjunctive (OR semantics), i.e. a namespace will be included if it matches any selector. - // The following example selects any namespace that matches either below: - // 1. The namespace has both of these labels: `env: prod` and `region: us-east1` - // 2. The namespace has label `app` equal to `cassandra` or `spark`. - // ```yaml - // discoverySelectors: - // - matchLabels: - // env: prod - // region: us-east1 - // - matchExpressions: - // - key: app - // operator: In - // values: - // - cassandra - // - spark - // ``` - // Refer to the [kubernetes selector docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) - // for additional detail on selector semantics. - DiscoverySelectors []*v1.LabelSelector `json:"discoverySelectors,omitempty"` -} diff --git a/api/external/maistra/v2/policy.go b/api/external/maistra/v2/policy.go deleted file mode 100644 index 16a87a218..000000000 --- a/api/external/maistra/v2/policy.go +++ /dev/null @@ -1,91 +0,0 @@ -package v2 - -// PolicyConfig configures policy aspects of the mesh. -type PolicyConfig struct { - // Required, the policy implementation - // defaults to Istiod 1.6+, Mixer pre-1.6 - Type PolicyType `json:"type,omitempty"` - // Mixer configuration (legacy, v1) - // .Values.mixer.policy.enabled - // +optional - Mixer *MixerPolicyConfig `json:"mixer,omitempty"` - // Remote mixer configuration (legacy, v1) - // .Values.global.remotePolicyAddress - // +optional - Remote *RemotePolicyConfig `json:"remote,omitempty"` -} - -// PolicyType represents the type of policy implementation used by the mesh. -type PolicyType string - -const ( - // PolicyTypeNone represents disabling of policy - // XXX: note, this doesn't appear to affect Istio 1.6, i.e. no different than Istiod setting - PolicyTypeNone PolicyType = "None" - // PolicyTypeMixer represents mixer, v1 implementation - PolicyTypeMixer PolicyType = "Mixer" - // PolicyTypeRemote represents remote mixer, v1 implementation - PolicyTypeRemote PolicyType = "Remote" - // PolicyTypeIstiod represents istio, v2 implementation - PolicyTypeIstiod PolicyType = "Istiod" -) - -// MixerPolicyConfig configures a mixer implementation for policy -// .Values.mixer.policy.enabled -type MixerPolicyConfig struct { - // EnableChecks configures whether or not policy checks should be enabled. - // .Values.global.disablePolicyChecks | default "true" (false, inverted logic) - // Set the following variable to false to disable policy checks by the Mixer. - // Note that metrics will still be reported to the Mixer. - // +optional - EnableChecks *bool `json:"enableChecks,omitempty"` - // FailOpen configures policy checks to fail if mixer cannot be reached. - // .Values.global.policyCheckFailOpen, maps to MeshConfig.policyCheckFailOpen - // policyCheckFailOpen allows traffic in cases when the mixer policy service cannot be reached. - // Default is false which means the traffic is denied when the client is unable to connect to Mixer. - // +optional - FailOpen *bool `json:"failOpen,omitempty"` - // SessionAffinity configures session affinity for sidecar policy connections. - // .Values.mixer.policy.sessionAffinityEnabled - // +optional - SessionAffinity *bool `json:"sessionAffinity,omitempty"` - // Adapters configures available adapters. - // +optional - Adapters *MixerPolicyAdaptersConfig `json:"adapters,omitempty"` -} - -// MixerPolicyAdaptersConfig configures policy adapters for mixer. -type MixerPolicyAdaptersConfig struct { - // UseAdapterCRDs configures mixer to support deprecated mixer CRDs. - // .Values.mixer.policy.adapters.useAdapterCRDs, removed in istio 1.4, defaults to false - // Only supported in v1.0, where it defaulted to true - // +optional - UseAdapterCRDs *bool `json:"useAdapterCRDs,omitempty"` - // Kubernetesenv configures the use of the kubernetesenv adapter. - // .Values.mixer.policy.adapters.kubernetesenv.enabled, defaults to true - // +optional - KubernetesEnv *bool `json:"kubernetesenv,omitempty"` -} - -// RemotePolicyConfig configures a remote mixer instance for policy -type RemotePolicyConfig struct { - // Address represents the address of the mixer server. - // .Values.global.remotePolicyAddress, maps to MeshConfig.mixerCheckServer - Address string `json:"address,omitempty"` - // CreateServices specifies whether or not a k8s Service should be created for the remote policy server. - // .Values.global.createRemoteSvcEndpoints - // +optional - CreateService *bool `json:"createService,omitempty"` - // EnableChecks configures whether or not policy checks should be enabled. - // .Values.global.disablePolicyChecks | default "true" (false, inverted logic) - // Set the following variable to false to disable policy checks by the Mixer. - // Note that metrics will still be reported to the Mixer. - // +optional - EnableChecks *bool `json:"enableChecks,omitempty"` - // FailOpen configures policy checks to fail if mixer cannot be reached. - // .Values.global.policyCheckFailOpen, maps to MeshConfig.policyCheckFailOpen - // policyCheckFailOpen allows traffic in cases when the mixer policy service cannot be reached. - // Default is false which means the traffic is denied when the client is unable to connect to Mixer. - // +optional - FailOpen *bool `json:"failOpen,omitempty"` -} diff --git a/api/external/maistra/v2/prometheus.go b/api/external/maistra/v2/prometheus.go deleted file mode 100644 index 8be51b888..000000000 --- a/api/external/maistra/v2/prometheus.go +++ /dev/null @@ -1,58 +0,0 @@ -package v2 - -// PrometheusAddonConfig configures a prometheus instance to be used by the -// control plane. Only one of Install or Address may be specified -type PrometheusAddonConfig struct { - Enablement `json:",inline"` - // MetricsExpiryDuration is the duration to hold metrics. (mixer/v1 only) - // .Values.mixer.adapters.prometheus.metricsExpiryDuration, defaults to 10m - // +optional - MetricsExpiryDuration string `json:"metricsExpiryDuration,omitempty"` - // Scrape metrics from the pod if true. (maistra-2.0+) - // defaults to true - // .Values.meshConfig.enablePrometheusMerge - // +optional - Scrape *bool `json:"scrape,omitempty"` - // Install configuration if not using an existing prometheus installation. - // .Values.prometheus.enabled, if not null - // +optional - Install *PrometheusInstallConfig `json:"install,omitempty"` - // Address of existing prometheus installation - // implies .Values.kiali.prometheusAddr - // XXX: do we need to do anything to configure credentials for accessing - // the prometheus server? - // +optional - Address *string `json:"address,omitempty"` -} - -// PrometheusInstallConfig represents the configuration to be applied when -// installing a new instance of prometheus for use with the mesh. -type PrometheusInstallConfig struct { - // SelfManaged specifies whether or not the entire install should be managed - // by Maistra (true) or the Prometheus operator (false, not supported). - // Governs use of either prometheus charts or prometheusOperator charts. - // +optional - SelfManaged bool `json:"selfManaged,omitempty"` - // Retention specifies how long metrics should be retained by prometheus. - // .Values.prometheus.retention, defaults to 6h - // +optional - Retention string `json:"retention,omitempty"` - // ScrapeInterval specifies how frequently prometheus should scrape pods for - // metrics. - // .Values.prometheus.scrapeInterval, defaults to 15s - // +optional - ScrapeInterval string `json:"scrapeInterval,omitempty"` - // Service allows for customization of the k8s Service associated with the - // prometheus installation. - // +optional - Service *ComponentServiceConfig `json:"service,omitempty"` - // UseTLS for the prometheus server - // .Values.prometheus.provisionPrometheusCert - // 1.6+ - // ProvisionCert bool - // this seems to overlap with provision cert, as this manifests something similar to the above - // .Values.prometheus.security.enabled, version < 1.6 - // EnableSecurity bool - // +optional - UseTLS *bool `json:"useTLS,omitempty"` -} diff --git a/api/external/maistra/v2/proxy.go b/api/external/maistra/v2/proxy.go deleted file mode 100644 index afb810d01..000000000 --- a/api/external/maistra/v2/proxy.go +++ /dev/null @@ -1,387 +0,0 @@ -package v2 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// ProxyConfig configures the default sidecar behavior for workloads. -type ProxyConfig struct { - // Logging configures logging for the sidecar. - // e.g. .Values.global.proxy.logLevel - // +optional - Logging *ProxyLoggingConfig `json:"logging,omitempty"` - // Networking represents network settings to be configured for the sidecars. - // +optional - Networking *ProxyNetworkingConfig `json:"networking,omitempty"` - // Runtime is used to customize runtime configuration for the sidecar container. - // +optional - Runtime *ProxyRuntimeConfig `json:"runtime,omitempty"` - // Injection is used to customize sidecar injection for the mesh. - // +optional - Injection *ProxyInjectionConfig `json:"injection,omitempty"` - // AdminPort configures the admin port exposed by the sidecar. - // maps to defaultConfig.proxyAdminPort, defaults to 15000 - // XXX: currently not configurable in charts - // +optional - AdminPort int32 `json:"adminPort,omitempty"` - // Concurrency configures the number of threads that should be run by the sidecar. - // .Values.global.proxy.concurrency, maps to defaultConfig.concurrency - // XXX: removed in 1.7 - // XXX: this is defaulted to 2 in our values.yaml, but should probably be 0 - // +optional - Concurrency *int32 `json:"concurrency,omitempty"` - // AccessLogging configures access logging for proxies. - // +optional - AccessLogging *ProxyAccessLoggingConfig `json:"accessLogging,omitempty"` - // EnvoyMetricsService configures reporting of Envoy metrics to an external - // service. - // .Values.global.proxy.envoyMetricsService - // +optional - EnvoyMetricsService *ProxyEnvoyServiceConfig `json:"envoyMetricsService,omitempty"` -} - -// ProxyNetworkingConfig is used to configure networking aspects of the sidecar. -type ProxyNetworkingConfig struct { - // ClusterDomain represents the domain for the cluster, defaults to cluster.local - // .Values.global.proxy.clusterDomain - // +optional - ClusterDomain string `json:"clusterDomain,omitempty"` - // maps to meshConfig.defaultConfig.connectionTimeout, defaults to 10s - // XXX: currently not exposed through values.yaml - // +optional - ConnectionTimeout string `json:"connectionTimeout,omitempty"` - // MaxConnectionAge limits how long a sidecar can be connected to pilot. - // This may be used to balance load across pilot instances, at the cost of - // system churn. - // .Values.pilot.keepaliveMaxServerConnectionAge - // +optional - MaxConnectionAge string `json:"maxConnectionAge,omitempty"` - // Initialization is used to specify how the pod's networking through the - // proxy is initialized. This configures the use of CNI or an init container. - // +optional - Initialization *ProxyNetworkInitConfig `json:"initialization,omitempty"` - // TrafficControl configures what network traffic is routed through the proxy. - // +optional - TrafficControl *ProxyTrafficControlConfig `json:"trafficControl,omitempty"` - // Protocol configures how the sidecar works with application protocols. - // +optional - Protocol *ProxyNetworkProtocolConfig `json:"protocol,omitempty"` - // DNS configures aspects of the sidecar's usage of DNS - // +optional - DNS *ProxyDNSConfig `json:"dns,omitempty"` -} - -// ProxyNetworkInitConfig is used to configure how the pod's networking through -// the proxy is initialized. -type ProxyNetworkInitConfig struct { - // Type of the network initialization implementation. - Type ProxyNetworkInitType `json:"type,omitempty"` - // InitContainer configures the use of a pod init container for initializing - // the pod's networking. - // istio_cni.enabled = false, if InitContainer is used - // +optional - InitContainer *ProxyInitContainerConfig `json:"initContainer,omitempty"` -} - -// ProxyNetworkInitType represents the type of initializer to use for network initialization -type ProxyNetworkInitType string - -const ( - // ProxyNetworkInitTypeCNI to use CNI for network initialization - ProxyNetworkInitTypeCNI ProxyNetworkInitType = "CNI" - // ProxyNetworkInitTypeInitContainer to use an init container for network initialization - ProxyNetworkInitTypeInitContainer ProxyNetworkInitType = "InitContainer" -) - -// ProxyInitContainerConfig configures execution aspects for the init container -type ProxyInitContainerConfig struct { - // Runtime configures customization of the init container (e.g. resources) - // +optional - Runtime *ContainerConfig `json:"runtime,omitempty"` -} - -// ProxyTrafficControlConfig configures what and how traffic is routed through -// the sidecar. -type ProxyTrafficControlConfig struct { - // Inbound configures what inbound traffic is routed through the sidecar - // traffic.sidecar.istio.io/includeInboundPorts defaults to * (all ports) - // +optional - Inbound ProxyInboundTrafficControlConfig `json:"inbound,omitempty"` - // Outbound configures what outbound traffic is routed through the sidecar. - // +optional - Outbound ProxyOutboundTrafficControlConfig `json:"outbound,omitempty"` -} - -// ProxyNetworkInterceptionMode represents the InterceptMode types. -type ProxyNetworkInterceptionMode string - -const ( - // ProxyNetworkInterceptionModeRedirect requests iptables use REDIRECT to route inbound traffic through the sidecar. - ProxyNetworkInterceptionModeRedirect ProxyNetworkInterceptionMode = "REDIRECT" - // ProxyNetworkInterceptionModeTProxy requests iptables use TPROXY to route inbound traffic through the sidecar. - ProxyNetworkInterceptionModeTProxy ProxyNetworkInterceptionMode = "TPROXY" -) - -// ProxyInboundTrafficControlConfig configures what inbound traffic is -// routed through the sidecar. -type ProxyInboundTrafficControlConfig struct { - // InterceptionMode specifies how traffic is directed through the sidecar. - // maps to meshConfig.defaultConfig.interceptionMode, overridden by sidecar.istio.io/interceptionMode - // XXX: currently not configurable through values.yaml - // +optional - InterceptionMode ProxyNetworkInterceptionMode `json:"interceptionMode,omitempty"` - // IncludedPorts to be routed through the sidecar. * or comma separated list of integers - // .Values.global.proxy.includeInboundPorts, defaults to * (all ports), overridden by traffic.sidecar.istio.io/includeInboundPorts - // +optional - IncludedPorts []string `json:"includedPorts,omitempty"` - // ExcludedPorts to be routed around the sidecar. - // .Values.global.proxy.excludeInboundPorts, defaults to empty list, overridden by traffic.sidecar.istio.io/excludeInboundPorts - // +optional - ExcludedPorts []int32 `json:"excludedPorts,omitempty"` -} - -// ProxyOutboundTrafficControlConfig configure what outbound traffic is routed -// through the sidecar -type ProxyOutboundTrafficControlConfig struct { - // IncludedIPRanges specifies which outbound IP ranges should be routed through the sidecar. - // .Values.global.proxy.includeIPRanges, overridden by traffic.sidecar.istio.io/includeOutboundIPRanges - // * or comma separated list of CIDR - // +optional - IncludedIPRanges []string `json:"includedIPRanges,omitempty"` - // ExcludedIPRanges specifies which outbound IP ranges should _not_ be routed through the sidecar. - // .Values.global.proxy.excludeIPRanges, overridden by traffic.sidecar.istio.io/excludeOutboundIPRanges - // * or comma separated list of CIDR - // +optional - ExcludedIPRanges []string `json:"excludedIPRanges,omitempty"` - // ExcludedPorts specifies which outbound ports should _not_ be routed through the sidecar. - // .Values.global.proxy.excludeOutboundPorts, overridden by traffic.sidecar.istio.io/excludeOutboundPorts - // comma separated list of integers - // +optional - ExcludedPorts []int32 `json:"excludedPorts,omitempty"` - // Policy specifies what outbound traffic is allowed through the sidecar. - // .Values.global.outboundTrafficPolicy.mode - // +optional - Policy ProxyOutboundTrafficPolicy `json:"policy,omitempty"` -} - -// ProxyOutboundTrafficPolicy represents the outbound traffic policy type. -type ProxyOutboundTrafficPolicy string - -const ( - // ProxyOutboundTrafficPolicyAllowAny allows all traffic through the sidecar. - ProxyOutboundTrafficPolicyAllowAny ProxyOutboundTrafficPolicy = "ALLOW_ANY" - // ProxyOutboundTrafficPolicyRegistryOnly only allows traffic destined for a - // service in the service registry through the sidecar. This limits outbound - // traffic to only other services in the mesh. - ProxyOutboundTrafficPolicyRegistryOnly ProxyOutboundTrafficPolicy = "REGISTRY_ONLY" -) - -// ProxyNetworkProtocolConfig configures the sidecar's protocol handling. -type ProxyNetworkProtocolConfig struct { - // AutoDetect configures automatic detection of connection protocols. - // +optional - AutoDetect *ProxyNetworkAutoProtocolDetectionConfig `json:"autoDetect,omitempty"` -} - -// ProxyNetworkAutoProtocolDetectionConfig configures automatic protocol detection for the proxies. -type ProxyNetworkAutoProtocolDetectionConfig struct { - // DetectionTimeout specifies how much time the sidecar will spend determining - // the protocol being used for the connection before reverting to raw TCP. - // .Values.global.proxy.protocolDetectionTimeout, maps to protocolDetectionTimeout - // +optional - Timeout string `json:"timeout,omitempty"` - // EnableInboundSniffing enables protocol sniffing on inbound traffic. - // .Values.pilot.enableProtocolSniffingForInbound - // only supported for v1.1 - // +optional - Inbound *bool `json:"inbound,omitempty"` - // EnableOutboundSniffing enables protocol sniffing on outbound traffic. - // .Values.pilot.enableProtocolSniffingForOutbound - // only supported for v1.1 - // +optional - Outbound *bool `json:"outbound,omitempty"` -} - -// ProxyDNSConfig is used to configure aspects of the sidecar's DNS usage. -type ProxyDNSConfig struct { - // SearchSuffixes are additional search suffixes to be used when resolving - // names. - // .Values.global.podDNSSearchNamespaces - // Custom DNS config for the pod to resolve names of services in other - // clusters. Use this to add additional search domains, and other settings. - // see - // https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#dns-config - // This does not apply to gateway pods as they typically need a different - // set of DNS settings than the normal application pods (e.g., in - // multicluster scenarios). - // NOTE: If using templates, follow the pattern in the commented example below. - // podDNSSearchNamespaces: - // - global - // - "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global" - // +optional - SearchSuffixes []string `json:"searchSuffixes,omitempty"` - // RefreshRate configures the DNS refresh rate for Envoy cluster of type STRICT_DNS - // This must be given it terms of seconds. For example, 300s is valid but 5m is invalid. - // .Values.global.proxy.dnsRefreshRate, default 300s - // +optional - RefreshRate string `json:"refreshRate,omitempty"` -} - -// ProxyRuntimeConfig customizes the runtime parameters of the sidecar container. -type ProxyRuntimeConfig struct { - // Readiness configures the readiness probe behavior for the injected pod. - // +optional - Readiness *ProxyReadinessConfig `json:"readiness,omitempty"` - // Container configures the sidecar container. - // +optional - Container *ContainerConfig `json:"container,omitempty"` -} - -// ProxyReadinessConfig configures the readiness probe for the sidecar. -type ProxyReadinessConfig struct { - // RewriteApplicationProbes specifies whether or not the injector should - // rewrite application container probes to be routed through the sidecar. - // .Values.sidecarInjectorWebhook.rewriteAppHTTPProbe, defaults to false - // rewrite probes for application pods to route through sidecar - // +optional - RewriteApplicationProbes bool `json:"rewriteApplicationProbes,omitempty"` - // StatusPort specifies the port number to be used for status. - // .Values.global.proxy.statusPort, overridden by status.sidecar.istio.io/port, defaults to 15020 - // Default port for Pilot agent health checks. A value of 0 will disable health checking. - // XXX: this has no affect on which port is actually used for status. - // +optional - StatusPort int32 `json:"statusPort,omitempty"` - // InitialDelaySeconds specifies the initial delay for the readiness probe - // .Values.global.proxy.readinessInitialDelaySeconds, overridden by readiness.status.sidecar.istio.io/initialDelaySeconds, defaults to 1 - // +optional - InitialDelaySeconds int32 `json:"initialDelaySeconds,omitempty"` - // PeriodSeconds specifies the period over which the probe is checked. - // .Values.global.proxy.readinessPeriodSeconds, overridden by readiness.status.sidecar.istio.io/periodSeconds, defaults to 2 - // +optional - PeriodSeconds int32 `json:"periodSeconds,omitempty"` - // FailureThreshold represents the number of consecutive failures before the container is marked as not ready. - // .Values.global.proxy.readinessFailureThreshold, overridden by readiness.status.sidecar.istio.io/failureThreshold, defaults to 30 - // +optional - FailureThreshold int32 `json:"failureThreshold,omitempty"` -} - -// ProxyInjectionConfig configures sidecar injection for the mesh. -type ProxyInjectionConfig struct { - // AutoInject configures automatic injection of sidecar proxies - // .Values.global.proxy.autoInject - // .Values.sidecarInjectorWebhook.enableNamespacesByDefault - // +optional - AutoInject *bool `json:"autoInject,omitempty"` - // AlwaysInjectSelector allows specification of a label selector that when - // matched will always inject a sidecar into the pod. - // .Values.sidecarInjectorWebhook.alwaysInjectSelector - // +optional - AlwaysInjectSelector []metav1.LabelSelector `json:"alwaysInjectSelector,omitempty"` - // NeverInjectSelector allows specification of a label selector that when - // matched will never inject a sidecar into the pod. This takes precedence - // over AlwaysInjectSelector. - // .Values.sidecarInjectorWebhook.neverInjectSelector - // +optional - NeverInjectSelector []metav1.LabelSelector `json:"neverInjectSelector,omitempty"` - // InjectedAnnotations allows specification of additional annotations to be - // added to pods that have sidecars injected in them. - // .Values.sidecarInjectorWebhook.injectedAnnotations - // +optional - InjectedAnnotations map[string]string `json:"injectedAnnotations,omitempty"` -} - -// ProxyAccessLoggingConfig configures access logging for proxies. Multiple -// access logs can be configured. -type ProxyAccessLoggingConfig struct { - // File configures access logging to the file system - // +optional - File *ProxyFileAccessLogConfig `json:"file,omitempty"` - // File configures access logging to an envoy service - // .Values.global.proxy.envoyAccessLogService - // +optional - EnvoyService *ProxyEnvoyServiceConfig `json:"envoyService,omitempty"` -} - -// ProxyFileAccessLogConfig configures details related to file access log -type ProxyFileAccessLogConfig struct { - // Name is the name of the file to which access log entries will be written. - // If Name is not specified, no log entries will be written to a file. - // .Values.global.proxy.accessLogFile - // +optional - Name string `json:"name,omitempty"` - // Encoding to use when writing access log entries. Currently, JSON or TEXT - // may be specified. - // .Values.global.proxy.accessLogEncoding - // +optional - Encoding string `json:"encoding,omitempty"` - // Format to use when writing access log entries. - // .Values.global.proxy.accessLogFormat - // +optional - Format string `json:"format,omitempty"` -} - -// ProxyEnvoyServiceConfig configures reporting to an external Envoy service. -type ProxyEnvoyServiceConfig struct { - // Enable sending Envoy metrics to the service. - // .Values.global.proxy.(envoyAccessLogService|envoyMetricsService).enabled - Enablement `json:",inline"` - // Address of the service specified as host:port. - // .Values.global.proxy.(envoyAccessLogService|envoyMetricsService).host - // .Values.global.proxy.(envoyAccessLogService|envoyMetricsService).port - // +optional - Address string `json:"address,omitempty"` - // TCPKeepalive configures keepalive settings to use when connecting to the - // service. - // .Values.global.proxy.(envoyAccessLogService|envoyMetricsService).tcpKeepalive - // +optional - TCPKeepalive *EnvoyServiceTCPKeepalive `json:"tcpKeepalive,omitempty"` - // TLSSettings configures TLS settings to use when connecting to the service. - // .Values.global.proxy.(envoyAccessLogService|envoyMetricsService).tlsSettings - // +optional - TLSSettings *EnvoyServiceClientTLSSettings `json:"tlsSettings,omitempty"` -} - -// EnvoyServiceTCPKeepalive configures keepalive settings for the Envoy service. -// Provides the same interface as networking.v1alpha3.istio.io, ConnectionPoolSettings_TCPSettings_TcpKeepalive -type EnvoyServiceTCPKeepalive struct { - // Probes represents the number of successive probe failures after which the - // connection should be considered "dead." - // +optional - Probes uint32 `json:"probes,omitempty"` - // Time represents the length of idle time that must elapse before a probe - // is sent. - // +optional - Time string `json:"time,omitempty"` - // Interval represents the interval between probes. - // +optional - Interval string `json:"interval,omitempty"` -} - -// EnvoyServiceClientTLSSettings configures TLS settings for the Envoy service. -// Provides the same interface as networking.v1alpha3.istio.io, ClientTLSSettings -type EnvoyServiceClientTLSSettings struct { - // Mode represents the TLS mode to apply to the connection. The following - // values are supported: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL - // +optional - Mode string `json:"mode,omitempty"` - // ClientCertificate represents the file name containing the client certificate - // to show to the Envoy service, e.g. /etc/istio/als/cert-chain.pem - // +optional - ClientCertificate string `json:"clientCertificate,omitempty"` - // PrivateKey represents the file name containing the private key used by - // the client, e.g. /etc/istio/als/key.pem - // +optional - PrivateKey string `json:"privateKey,omitempty"` - // CACertificates represents the file name containing the root certificates - // for the CA, e.g. /etc/istio/als/root-cert.pem - // +optional - CACertificates string `json:"caCertificates,omitempty"` - // SNIHost represents the host name presented to the server during TLS - // handshake, e.g. als.somedomain - // +optional - SNIHost string `json:"sni,omitempty"` - // SubjectAltNames represents the list of alternative names that may be used - // to verify the servers identity, e.g. [als.someotherdomain] - // +optional - SubjectAltNames []string `json:"subjectAltNames,omitempty"` -} diff --git a/api/external/maistra/v2/register.go b/api/external/maistra/v2/register.go deleted file mode 100644 index 5ab21faf7..000000000 --- a/api/external/maistra/v2/register.go +++ /dev/null @@ -1,26 +0,0 @@ -// NOTE: Boilerplate only. Ignore this file. - -// Package v2 contains API Schema definitions for the maistra v2 API group -// +k8s:deepcopy-gen=package,register -// +groupName=maistra.io -package v2 - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "sigs.k8s.io/controller-runtime/pkg/scheme" -) - -const ( - // APIGroup for maistr.io - APIGroup = "maistra.io" - // APIVersion for v2 - APIVersion = "v2" -) - -var ( - // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: APIGroup, Version: APIVersion} - - // SchemeBuilder is used to add go types to the GroupVersionKind scheme - SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} -) diff --git a/api/external/maistra/v2/runtime.go b/api/external/maistra/v2/runtime.go deleted file mode 100644 index 38733ef4d..000000000 --- a/api/external/maistra/v2/runtime.go +++ /dev/null @@ -1,344 +0,0 @@ -package v2 - -import ( - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/intstr" - - v1 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v1" -) - -// ControlPlaneRuntimeConfig configures execution parameters for control plane -// componets. -type ControlPlaneRuntimeConfig struct { - // Components allows specifying execution parameters for specific control plane - // componets. The key of the map is the component name to which the settings - // should be applied. - // +optional - Components map[ControlPlaneComponentName]*ComponentRuntimeConfig `json:"components,omitempty"` - // Defaults will be merged into specific component config. - // .Values.global.defaultResources, e.g. - // +optional - Defaults *DefaultRuntimeConfig `json:"defaults,omitempty"` -} - -// ControlPlaneComponentName simple type for control plane component names -type ControlPlaneComponentName string - -const ( - // ControlPlaneComponentNameSecurity - security (citadel) - ControlPlaneComponentNameSecurity ControlPlaneComponentName = "security" - // ControlPlaneComponentNameGalley - galley - ControlPlaneComponentNameGalley ControlPlaneComponentName = "galley" - // ControlPlaneComponentNamePilot - pilot - ControlPlaneComponentNamePilot ControlPlaneComponentName = "pilot" - // ControlPlaneComponentNameMixer - mixer - ControlPlaneComponentNameMixer ControlPlaneComponentName = "mixer" - // ControlPlaneComponentNameMixerPolicy - mixer.policy - ControlPlaneComponentNameMixerPolicy ControlPlaneComponentName = "mixer.policy" - // ControlPlaneComponentNameMixerTelemetry - mixer.telemetry - ControlPlaneComponentNameMixerTelemetry ControlPlaneComponentName = "mixer.telemetry" - // ControlPlaneComponentNameGlobalOauthProxy - global.oauthproxy - ControlPlaneComponentNameGlobalOauthProxy ControlPlaneComponentName = "global.oauthproxy" - // ControlPlaneComponentNameSidecarInjectoryWebhook - sidecarInjectorWebhook - ControlPlaneComponentNameSidecarInjectoryWebhook ControlPlaneComponentName = "sidecarInjectorWebhook" - // ControlPlaneComponentNameTracing - tracing - ControlPlaneComponentNameTracing ControlPlaneComponentName = "tracing" - // ControlPlaneComponentNameTracingJaeger - tracing.jaeger - ControlPlaneComponentNameTracingJaeger ControlPlaneComponentName = "tracing.jaeger" - // ControlPlaneComponentNameTracingJaegerElasticsearch - tracing.jaeger.elasticsearch - ControlPlaneComponentNameTracingJaegerElasticsearch ControlPlaneComponentName = "tracing.jaeger.elasticsearch" - // ControlPlaneComponentNameTracingJaegerAgent - tracing.jaeger.agent - ControlPlaneComponentNameTracingJaegerAgent ControlPlaneComponentName = "tracing.jaeger.agent" - // ControlPlaneComponentNameTracingJaegerAllInOne - tracing.jaeger.allInOne - ControlPlaneComponentNameTracingJaegerAllInOne ControlPlaneComponentName = "tracing.jaeger.allInOne" - // ControlPlaneComponentNameTracingJaegerCollector - tracing.jaeger.collector - ControlPlaneComponentNameTracingJaegerCollector ControlPlaneComponentName = "tracing.jaeger.collector" - // ControlPlaneComponentNameTracingJaegerQuery - tracing.jaeger.query - ControlPlaneComponentNameTracingJaegerQuery ControlPlaneComponentName = "tracing.jaeger.query" - // ControlPlaneComponentNamePrometheus - prometheus - ControlPlaneComponentNamePrometheus ControlPlaneComponentName = "prometheus" - // ControlPlaneComponentNameKiali - kiali - ControlPlaneComponentNameKiali ControlPlaneComponentName = "kiali" - // ControlPlaneComponentNameGrafana - grafana - ControlPlaneComponentNameGrafana ControlPlaneComponentName = "grafana" - // ControlPlaneComponentNameThreeScale - 3scale - ControlPlaneComponentNameThreeScale ControlPlaneComponentName = "3scale" - // ControlPlaneComponentNameWASMCacher - wasm-extensions cacher - ControlPlaneComponentNameWASMCacher ControlPlaneComponentName = "wasmExtensions.cacher" - // ControlPlaneComponentNameRateLimiting - rateLimiting - ControlPlaneComponentNameRateLimiting ControlPlaneComponentName = "rateLimiting.rls" -) - -// ControlPlaneComponentNames - supported runtime components -var ControlPlaneComponentNames = []ControlPlaneComponentName{ - ControlPlaneComponentNameSecurity, - ControlPlaneComponentNameGalley, - ControlPlaneComponentNamePilot, - ControlPlaneComponentNameMixer, - ControlPlaneComponentNameMixerPolicy, - ControlPlaneComponentNameMixerTelemetry, - ControlPlaneComponentNameGlobalOauthProxy, - ControlPlaneComponentNameSidecarInjectoryWebhook, - ControlPlaneComponentNameTracing, - ControlPlaneComponentNameTracingJaeger, - ControlPlaneComponentNameTracingJaegerElasticsearch, - ControlPlaneComponentNameTracingJaegerAgent, - ControlPlaneComponentNameTracingJaegerAllInOne, - ControlPlaneComponentNameTracingJaegerCollector, - ControlPlaneComponentNameTracingJaegerQuery, - ControlPlaneComponentNamePrometheus, - ControlPlaneComponentNameKiali, - ControlPlaneComponentNameGrafana, - ControlPlaneComponentNameThreeScale, - ControlPlaneComponentNameWASMCacher, - ControlPlaneComponentNameRateLimiting, -} - -// ComponentRuntimeConfig allows for partial customization of a component's -// runtime configuration (Deployment, PodTemplate, auto scaling, pod disruption, etc.) -type ComponentRuntimeConfig struct { - // Deployment specific overrides - // +optional - Deployment *DeploymentRuntimeConfig `json:"deployment,omitempty"` - - // Pod specific overrides - // +optional - Pod *PodRuntimeConfig `json:"pod,omitempty"` - - // .Values.*.resource, imagePullPolicy, etc. - // +optional - Container *ContainerConfig `json:"container,omitempty"` -} - -// DeploymentRuntimeConfig allow customization of a component's Deployment -// resource, including additional labels/annotations, replica count, autoscaling, -// rollout strategy, etc. -type DeploymentRuntimeConfig struct { - // Number of desired pods. This is a pointer to distinguish between explicit - // zero and not specified. Defaults to 1. - // +optional - // .Values.*.replicaCount - Replicas *int32 `json:"replicas,omitempty"` - - // The deployment strategy to use to replace existing pods with new ones. - // +optional - // +patchStrategy=retainKeys - // .Values.*.rollingMaxSurge, rollingMaxUnavailable, etc. - Strategy *appsv1.DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys"` - - // Autoscaling specifies the configuration for a HorizontalPodAutoscaler - // to be applied to this deployment. Null indicates no auto scaling. - // .Values.*.autoscale* fields - // +optional - AutoScaling *AutoScalerConfig `json:"autoScaling,omitempty"` -} - -// CommonDeploymentRuntimeConfig represents deployment settings common to both -// default and component specific settings -type CommonDeploymentRuntimeConfig struct { - // .Values.global.podDisruptionBudget.enabled, if not null - // XXX: this is currently a global setting, not per component. perhaps - // this should only be available on the defaults? - // +optional - PodDisruption *PodDisruptionBudget `json:"podDisruption,omitempty"` -} - -// AutoScalerConfig is used to configure autoscaling for a deployment -type AutoScalerConfig struct { - Enablement `json:",inline"` - // lower limit for the number of pods that can be set by the autoscaler, default 1. - // +optional - MinReplicas *int32 `json:"minReplicas,omitempty"` - // upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas. - // +optional - MaxReplicas *int32 `json:"maxReplicas,omitempty"` - // target average CPU utilization (represented as a percentage of requested CPU) over all the pods; - // if not specified the default autoscaling policy will be used. - // +optional - TargetCPUUtilizationPercentage *int32 `json:"targetCPUUtilizationPercentage,omitempty"` -} - -// PodRuntimeConfig is used to customize pod configuration for a component -type PodRuntimeConfig struct { - CommonPodRuntimeConfig `json:",inline"` - - // Metadata allows additional annotations/labels to be applied to the pod - // .Values.*.podAnnotations - // XXX: currently, additional lables are not supported - // +optional - Metadata *MetadataConfig `json:"metadata,omitempty"` - - // If specified, the pod's scheduling constraints - // +optional - // .Values.podAntiAffinityLabelSelector, podAntiAffinityTermLabelSelector, nodeSelector - // NodeAffinity is not supported at this time - // PodAffinity is not supported at this time - Affinity *Affinity `json:"affinity,omitempty"` -} - -// CommonPodRuntimeConfig represents pod settings common to both defaults and -// component specific configuration -type CommonPodRuntimeConfig struct { - // NodeSelector is a selector which must be true for the pod to fit on a node. - // Selector which must match a node's labels for the pod to be scheduled on that node. - // More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ - // +optional - // .Values.nodeSelector - NodeSelector map[string]string `json:"nodeSelector,omitempty"` - - // If specified, the pod's tolerations. - // +optional - // .Values.tolerations - Tolerations []corev1.Toleration `json:"tolerations,omitempty"` - - // .Values.global.priorityClassName - // XXX: currently, this is only a global setting. maybe only allow setting in global runtime defaults? - // +optional - PriorityClassName string `json:"priorityClassName,omitempty"` -} - -// Affinity is the structure used by Istio for specifying Pod affinity -// XXX: istio does not support full corev1.Affinity settings, hence the special -// types here. -type Affinity struct { - // +optional - NodeAffinity *corev1.NodeAffinity `json:"nodeAffinity,omitempty"` - // +optional - PodAffinity *corev1.PodAffinity `json:"podAffinity,omitempty"` - // XXX: use corev1.PodAntiAffinity instead, the only things not supported are namespaces and weighting - // +optional - PodAntiAffinity PodAntiAffinity `json:"podAntiAffinity,omitempty"` -} - -// PodAntiAffinity configures anti affinity for pod scheduling -type PodAntiAffinity struct { - *corev1.PodAntiAffinity `json:",inline"` - - // +optional - RequiredDuringScheduling []PodAntiAffinityTerm `json:"requiredDuringScheduling,omitempty"` - // +optional - PreferredDuringScheduling []PodAntiAffinityTerm `json:"preferredDuringScheduling,omitempty"` -} - -// PodAntiAffinityTerm is a simplified version of corev1.PodAntiAffinityTerm -type PodAntiAffinityTerm struct { - metav1.LabelSelectorRequirement `json:",inline"` - // This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching - // the labelSelector in the specified namespaces, where co-located is defined as running on a node - // whose value of the label with key topologyKey matches that of any node on which any of the - // selected pods is running. - // Empty topologyKey is not allowed. - // +optional - TopologyKey string `json:"topologyKey,omitempty"` -} - -// ContainerConfig to be applied to containers in a pod, in a deployment -type ContainerConfig struct { - CommonContainerConfig `json:",inline"` - // +optional - Image string `json:"imageName,omitempty"` - // +optional - Env map[string]string `json:"env,omitempty"` -} - -// CommonContainerConfig represents container settings common to both defaults -// and component specific configuration. -type CommonContainerConfig struct { - // +optional - ImageRegistry string `json:"imageRegistry,omitempty"` - // +optional - ImageTag string `json:"imageTag,omitempty"` - // +optional - ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"` - // +optional - ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"` - // +optional - Resources *corev1.ResourceRequirements `json:"resources,omitempty"` -} - -// PodDisruptionBudget details -// XXX: currently only configurable globally (i.e. no component values.yaml equivalent) -type PodDisruptionBudget struct { - Enablement `json:",inline"` - // +optional - MinAvailable *intstr.IntOrString `json:"minAvailable,omitempty"` - // +optional - MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` -} - -// DefaultRuntimeConfig specifies default execution parameters to apply to -// control plane deployments/pods when no specific component overrides have been -// specified. These settings will be merged with component specific settings. -type DefaultRuntimeConfig struct { - // Deployment defaults - // +optional - Deployment *CommonDeploymentRuntimeConfig `json:"deployment,omitempty"` - // Pod defaults - // +optional - Pod *CommonPodRuntimeConfig `json:"pod,omitempty"` - // Container overrides to be merged with component specific overrides. - // +optional - Container *CommonContainerConfig `json:"container,omitempty"` -} - -// MetadataConfig represents additional metadata to be applied to resources -type MetadataConfig struct { - // +optional - Labels map[string]string `json:"labels,omitempty"` - // +optional - Annotations map[string]string `json:"annotations,omitempty"` -} - -// ComponentServiceConfig is used to customize the service associated with a component. -type ComponentServiceConfig struct { - // Metadata represents additional annotations/labels to be applied to the - // component's service. - // +optional - Metadata *MetadataConfig `json:"metadata,omitempty"` - // NodePort specifies a NodePort for the component's Service. - // .Values..service.nodePort.port, ...enabled is true if not null - // +optional - NodePort *int32 `json:"nodePort,omitempty"` - // Ingress specifies details for accessing the component's service through - // a k8s Ingress or OpenShift Route. - // +optional - Ingress *ComponentIngressConfig `json:"ingress,omitempty"` -} - -// ComponentIngressConfig is used to customize a k8s Ingress or OpenShift Route -// for the service associated with a component. -type ComponentIngressConfig struct { - Enablement `json:",inline"` - // Metadata represents additional metadata to be applied to the ingress/route. - // +optional - Metadata *MetadataConfig `json:"metadata,omitempty"` - // Hosts represents a list of host names to configure. Note, OpenShift route - // only supports a single host name per route. An empty host name implies - // a default host name for the Route. - // XXX: is a host name required for k8s Ingress? - // +optional - Hosts []string `json:"hosts,omitempty"` - // ContextPath represents the context path to the service. - // +optional - ContextPath string `json:"contextPath,omitempty"` - // TLS is used to configure TLS for the Ingress/Route - // XXX: should this be something like RawExtension, as the configuration differs between Route and Ingress? - // +optional - TLS *v1.HelmValues `json:"tls,omitempty"` -} - -// ComponentPersistenceConfig is used to configure persistence for a component. -type ComponentPersistenceConfig struct { - Enablement `json:",inline"` - // StorageClassName for the PersistentVolumeClaim - // +optional - StorageClassName string `json:"storageClassName,omitempty"` - // AccessMode for the PersistentVolumeClaim - // +optional - AccessMode corev1.PersistentVolumeAccessMode `json:"accessMode,omitempty"` - // Resources to request for the PersistentVolumeClaim - // +optional - Resources *corev1.ResourceRequirements `json:"capacity,omitempty"` -} diff --git a/api/external/maistra/v2/security.go b/api/external/maistra/v2/security.go deleted file mode 100644 index 5b56c8b23..000000000 --- a/api/external/maistra/v2/security.go +++ /dev/null @@ -1,302 +0,0 @@ -package v2 - -// SecurityConfig specifies security aspects of the control plane. -type SecurityConfig struct { - // Trust configures trust aspects associated with mutual TLS clients. - // +optional - Trust *TrustConfig `json:"trust,omitempty"` - // CertificateAuthority configures the certificate authority used by the - // control plane to create and sign client certs and server keys. - // +optional - CertificateAuthority *CertificateAuthorityConfig `json:"certificateAuthority,omitempty"` - // Identity configures the types of user tokens used by clients. - // +optional - Identity *IdentityConfig `json:"identity,omitempty"` - // ControlPlane configures mutual TLS for control plane communication. - // +optional - ControlPlane *ControlPlaneSecurityConfig `json:"controlPlane,omitempty"` - // DataPlane configures mutual TLS for data plane communication. - // +optional - DataPlane *DataPlaneSecurityConfig `json:"dataPlane,omitempty"` - // Manages network policies that allows communication between namespace members and control plane, defaults to `true` - // If false, operator does not create any NetworkPolicy resource, and users are responsible for managing them - // .Values.global.manageNetworkPolicy - // +optional - ManageNetworkPolicy *bool `json:"manageNetworkPolicy,omitempty"` - // JwksResolverCA is the configuration for injecting a trusted CA into the JWKSResolver. - // +optional - JwksResolverCA string `json:"jwksResolverCA,omitempty"` -} - -// TrustConfig configures trust aspects associated with mutual TLS clients -type TrustConfig struct { - // Domain specifies the trust domain to be used by the mesh. - // .Values.global.trustDomain, maps to trustDomain - // The trust domain corresponds to the trust root of a system. - // Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain - // +optional - Domain string `json:"domain,omitempty"` - // AdditionalDomains are additional SPIFFE trust domains that are accepted as trusted. - // .Values.global.trustDomainAliases, maps to trustDomainAliases - // Any service with the identity "td1/ns/foo/sa/a-service-account", "td2/ns/foo/sa/a-service-account", - // or "td3/ns/foo/sa/a-service-account" will be treated the same in the Istio mesh. - // +optional - AdditionalDomains []string `json:"additionalDomains,omitempty"` -} - -// CertificateAuthorityConfig configures the certificate authority implementation -// used by the control plane. -type CertificateAuthorityConfig struct { - // Type is the certificate authority to use. - Type CertificateAuthorityType `json:"type,omitempty"` - // Istiod is the configuration for Istio's internal certificate authority implementation. - // each of these produces a CAEndpoint, i.e. CA_ADDR - // +optional - Istiod *IstiodCertificateAuthorityConfig `json:"istiod,omitempty"` - // Custom is the configuration for a custom certificate authority. - // +optional - Custom *CustomCertificateAuthorityConfig `json:"custom,omitempty"` - CertManager *CertManagerCertificateAuthorityConfig `json:"cert-manager,omitempty"` -} - -// CertificateAuthorityType represents the type of CertificateAuthority implementation. -type CertificateAuthorityType string - -const ( - // CertificateAuthorityTypeIstiod represents Istio's internal certificate authority implementation - CertificateAuthorityTypeIstiod CertificateAuthorityType = "Istiod" - // CertificateAuthorityTypeCustom represents a custom certificate authority implementation - CertificateAuthorityTypeCustom CertificateAuthorityType = "Custom" - // CertificateAuthorityTypeCertManager represents a cert-manager istio-csr certificate authority implementation - CertificateAuthorityTypeCertManager CertificateAuthorityType = "cert-manager" -) - -// IstiodCertificateAuthorityConfig is the configuration for Istio's internal -// certificate authority implementation. -type IstiodCertificateAuthorityConfig struct { - // Type of certificate signer to use. - Type IstioCertificateSignerType `json:"type,omitempty"` - // SelfSigned configures istiod to generate and use a self-signed certificate for the root. - // +optional - SelfSigned *IstioSelfSignedCertificateSignerConfig `json:"selfSigned,omitempty"` - // PrivateKey configures istiod to use a user specified private key/cert when signing certificates. - // +optional - PrivateKey *IstioPrivateKeyCertificateSignerConfig `json:"privateKey,omitempty"` - // WorkloadCertTTLDefault is the default TTL for generated workload - // certificates. Used if not specified in CSR (<= 0) - // env DEFAULT_WORKLOAD_CERT_TTL, 1.6 - // --workload-cert-ttl, citadel, pre-1.6 - // defaults to 24 hours - // +optional - WorkloadCertTTLDefault string `json:"workloadCertTTLDefault,omitempty"` - // WorkloadCertTTLMax is the maximum TTL for generated workload certificates. - // env MAX_WORKLOAD_CERT_TTL - // --max-workload-cert-ttl, citadel, pre-1.6 - // defaults to 90 days - // +optional - WorkloadCertTTLMax string `json:"workloadCertTTLMax,omitempty"` -} - -// IstioCertificateSignerType represents the certificate signer implementation used by istiod. -type IstioCertificateSignerType string - -const ( - // IstioCertificateSignerTypePrivateKey is the signer type used when signing with a user specified private key. - IstioCertificateSignerTypePrivateKey IstioCertificateSignerType = "PrivateKey" - // IstioCertificateSignerTypeSelfSigned is the signer type used when signing with a generated, self-signed certificate. - IstioCertificateSignerTypeSelfSigned IstioCertificateSignerType = "SelfSigned" -) - -// IstioSelfSignedCertificateSignerConfig is the configuration for using a -// self-signed root certificate. -type IstioSelfSignedCertificateSignerConfig struct { - // TTL for self-signed root certificate - // env CITADEL_SELF_SIGNED_CA_CERT_TTL - // default is 10 years - // +optional - TTL string `json:"ttl,omitempty"` - // GracePeriod percentile for self-signed cert - // env CITADEL_SELF_SIGNED_ROOT_CERT_GRACE_PERIOD_PERCENTILE - // default is 20% - // +optional - GracePeriod string `json:"gracePeriod,omitempty"` - // CheckPeriod is the interval with which certificate is checked for rotation - // env CITADEL_SELF_SIGNED_ROOT_CERT_CHECK_INTERVAL - // default is 1 hour, zero or negative value disables cert rotation - // +optional - CheckPeriod string `json:"checkPeriod,omitempty"` - // EnableJitter to use jitter for cert rotation - // env CITADEL_ENABLE_JITTER_FOR_ROOT_CERT_ROTATOR - // defaults to true - // +optional - EnableJitter *bool `json:"enableJitter,omitempty"` - // Org is the Org value in the certificate. - // XXX: currently uses TrustDomain. I don't think this is configurable. - // +optional - // Org string `json:"org,omitempty"` -} - -// IstioPrivateKeyCertificateSignerConfig is the configuration when using a user -// supplied private key/cert for signing. -// XXX: nothing in here is currently configurable, except RootCADir -type IstioPrivateKeyCertificateSignerConfig struct { - // hard coded to use a secret named cacerts - // +optional - // EncryptionSecret string `json:"encryptionSecret,omitempty"` - // ROOT_CA_DIR, defaults to /etc/cacerts - // Mount directory for encryption secret - // XXX: currently, not configurable in the charts - // +optional - RootCADir string `json:"rootCADir,omitempty"` - // hard coded to ca-key.pem - // +optional - // SigningKeyFile string `json:"signingKeyFile,omitempty"` - // hard coded to ca-cert.pem - // +optional - // SigningCertFile string `json:"signingCertFile,omitempty"` - // hard coded to root-cert.pem - // +optional - // RootCertFile string `json:"rootCertFile,omitempty"` - // hard coded to cert-chain.pem - // +optional - // CertChainFile string `json:"certChainFile,omitempty"` -} - -// CustomCertificateAuthorityConfig is the configuration for a custom -// certificate authority. -type CustomCertificateAuthorityConfig struct { - // Address is the grpc address for an Istio compatible certificate authority endpoint. - // .Values.global.caAddress - // XXX: assumption is this is a grpc endpoint that provides methods like istio.v1.auth.IstioCertificateService/CreateCertificate - Address string `json:"address,omitempty"` -} - -type CertManagerCertificateAuthorityConfig struct { - // Address is the grpc address for an Istio compatible certificate authority endpoint. - // .Values.global.caAddress - Address string `json:"address,omitempty"` - PilotCertSecretName string `json:"pilotSecretName,omitempty"` - RootCAConfigMapName string `json:"rootCAConfigMapName,omitempty"` -} - -func (c *CertManagerCertificateAuthorityConfig) GetRootCAConfigMapName() string { - if c.RootCAConfigMapName == "" { - return "istio-ca-root-cert" - } - return c.RootCAConfigMapName -} - -// IdentityConfig configures the types of user tokens used by clients -type IdentityConfig struct { - // Type is the type of identity tokens being used. - // .Values.global.jwtPolicy - Type IdentityConfigType `json:"type,omitempty"` - // ThirdParty configures istiod to use a third-party token provider for - // identifying users. (basically uses a custom audience, e.g. istio-ca) - // XXX: this is only supported on OCP 4.4+ - // +optional - ThirdParty *ThirdPartyIdentityConfig `json:"thirdParty,omitempty"` -} - -// IdentityConfigType represents the identity implementation being used. -type IdentityConfigType string - -const ( - // IdentityConfigTypeKubernetes specifies Kubernetes as the token provider. - IdentityConfigTypeKubernetes IdentityConfigType = "Kubernetes" // first-party-jwt - // IdentityConfigTypeThirdParty specifies a third-party token provider. - IdentityConfigTypeThirdParty IdentityConfigType = "ThirdParty" // third-party-jwt -) - -// ThirdPartyIdentityConfig configures a third-party token provider for use with -// istiod. -type ThirdPartyIdentityConfig struct { - // TokenPath is the path to the token used to identify the workload. - // default /var/run/secrets/tokens/istio-token - // XXX: projects service account token with specified audience (istio-ca) - // XXX: not configurable - // +optional - // TokenPath string `json:"tokenPath,omitempty"` - - // Issuer is the URL of the issuer. - // env TOKEN_ISSUER, defaults to iss in specified token - // only supported in 1.6+ - // +optional - Issuer string `json:"issuer,omitempty"` - // Audience is the audience for whom the token is intended. - // env AUDIENCE - // .Values.global.sds.token.aud, defaults to istio-ca - // +optional - Audience string `json:"audience,omitempty"` -} - -// ControlPlaneSecurityConfig is the mutual TLS configuration specific to the -// control plane. -type ControlPlaneSecurityConfig struct { - // Enable mutual TLS for the control plane components. - // .Values.global.controlPlaneSecurityEnabled - // +optional - MTLS *bool `json:"mtls,omitempty"` - // CertProvider is the certificate authority used to generate the serving - // certificates for the control plane components. - // .Values.global.pilotCertProvider - // Provider used to generate serving certs for istiod (pilot) - // +optional - CertProvider ControlPlaneCertProviderType `json:"certProvider,omitempty"` - - // TLS configures aspects of TLS listeners created by control plane components. - // +optional - TLS *ControlPlaneTLSConfig `json:"tls,omitempty"` -} - -// DataPlaneSecurityConfig is the mutual TLS configuration specific to the -// control plane. -type DataPlaneSecurityConfig struct { - // Enable mutual TLS by default. - // .Values.global.mtls.enabled - MTLS *bool `json:"mtls,omitempty"` - // Auto configures the mesh to automatically detect whether or not mutual - // TLS is required for a specific connection. - // .Values.global.mtls.auto - // +optional - AutoMTLS *bool `json:"automtls,omitempty"` -} - -// ControlPlaneCertProviderType represents the provider used to generate serving -// certificates for the control plane. -type ControlPlaneCertProviderType string - -const ( - // ControlPlaneCertProviderTypeIstiod identifies istiod as the provider generating the serving certifications. - ControlPlaneCertProviderTypeIstiod ControlPlaneCertProviderType = "Istiod" - // ControlPlaneCertProviderTypeKubernetes identifies Kubernetes as the provider generating the serving certificates. - ControlPlaneCertProviderTypeKubernetes ControlPlaneCertProviderType = "Kubernetes" - // ControlPlaneCertProviderTypeCustom identifies a custom provider has generated the serving certificates. - // XXX: Not quite sure what this means. Presumably, the key and cert chain have been mounted specially - ControlPlaneCertProviderTypeCustom ControlPlaneCertProviderType = "Custom" -) - -// ControlPlaneTLSConfig configures settings on TLS listeners created by -// control plane components, e.g. webhooks, grpc (if mtls is enabled), etc. -type ControlPlaneTLSConfig struct { - // CipherSuites configures the cipher suites that are available for use by - // TLS listeners. - // .Values.global.tls.cipherSuites - // +optional - CipherSuites []string `json:"cipherSuites,omitempty"` - // ECDHCurves configures the ECDH curves that are available for use by - // TLS listeners. - // .Values.global.tls.ecdhCurves - // +optional - ECDHCurves []string `json:"ecdhCurves,omitempty"` - // MinProtocolVersion the minimum TLS version that should be supported by - // the listeners. - // .Values.global.tls.minProtocolVersion - // +optional - MinProtocolVersion string `json:"minProtocolVersion,omitempty"` - // MaxProtocolVersion the maximum TLS version that should be supported by - // the listeners. - // .Values.global.tls.maxProtocolVersion - // +optional - MaxProtocolVersion string `json:"maxProtocolVersion,omitempty"` -} diff --git a/api/external/maistra/v2/servicemeshcontrolplane_types.go b/api/external/maistra/v2/servicemeshcontrolplane_types.go deleted file mode 100644 index c4dc455df..000000000 --- a/api/external/maistra/v2/servicemeshcontrolplane_types.go +++ /dev/null @@ -1,226 +0,0 @@ -package v2 - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/kuadrant/kuadrant-operator/api/external/maistra/status" - v1 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v1" -) - -const ( - // controlPlaneMode in v2.3 - TechPreviewControlPlaneModeKey = "controlPlaneMode" - TechPreviewControlPlaneModeValueClusterScoped = "ClusterScoped" - TechPreviewControlPlaneModeValueMultiTenant = "MultiTenant" -) - -type ControlPlaneMode string - -const ( - ClusterWideMode ControlPlaneMode = "ClusterWide" - MultiTenantMode ControlPlaneMode = "MultiTenant" -) - -func init() { - SchemeBuilder.Register(&ServiceMeshControlPlane{}, &ServiceMeshControlPlaneList{}) -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ServiceMeshControlPlane is the Schema for the controlplanes API -// +k8s:openapi-gen=true -// +kubebuilder:storageversion -// +kubebuilder:resource:shortName=smcp,categories=maistra-io -// +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.annotations.readyComponentCount",description="How many of the total number of components are ready" -// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].reason",description="Whether or not the control plane installation is up to date and ready to handle requests." -// +kubebuilder:printcolumn:name="Profiles",type="string",JSONPath=".status.appliedSpec.profiles",description="The configuration profiles applied to the configuration." -// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".status.chartVersion",description="The actual current version of the control plane installation." -// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the object" -// +kubebuilder:printcolumn:name="Image Registry",type="string",JSONPath=".status.appliedSpec.runtime.defaults.container.registry",description="The image registry used as the base for all component images.",priority=1 -type ServiceMeshControlPlane struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // The specification of the desired state of this ServiceMeshControlPlane. - // This includes the configuration options for all components that comprise - // the control plane. - // +kubebuilder:validation:Required - Spec ControlPlaneSpec `json:"spec"` - - // The current status of this ServiceMeshControlPlane and the components - // that comprise the control plane. This data may be out of date by some - // window of time. - // +optional - Status ControlPlaneStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// ServiceMeshControlPlaneList contains a list of ServiceMeshControlPlane -type ServiceMeshControlPlaneList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []ServiceMeshControlPlane `json:"items"` -} - -// ControlPlaneStatus defines the observed state of ServiceMeshControlPlane -// ControlPlaneStatus represents the current state of a ServiceMeshControlPlane. -type ControlPlaneStatus struct { - status.StatusBase `json:",inline"` - - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file - status.StatusType `json:",inline"` - - // The generation observed by the controller during the most recent - // reconciliation. The information in the status pertains to this particular - // generation of the object. - ObservedGeneration int64 `json:"observedGeneration,omitempty"` - - // The version of the operator that last processed this resource. - OperatorVersion string `json:"operatorVersion,omitempty"` - - // The version of the charts that were last processed for this resource. - ChartVersion string `json:"chartVersion,omitempty"` - - // The list of components comprising the control plane and their statuses. - status.ComponentStatusList `json:",inline"` - - // The readiness status of components & owned resources - Readiness ReadinessStatus `json:"readiness"` - - // The resulting specification of the configuration options after all profiles - // have been applied. - // +optional - AppliedSpec ControlPlaneSpec `json:"appliedSpec,omitempty"` - - // The resulting values.yaml used to generate the charts. - // +optional - AppliedValues v1.ControlPlaneSpec `json:"appliedValues,omitempty"` -} - -// ReadinessStatus contains readiness information for each deployed component. -type ReadinessStatus struct { - // The readiness status of components - // +optional - Components ReadinessMap `json:"components,omitempty"` -} - -type ReadinessMap map[string][]string - -// GetReconciledVersion returns the reconciled version, or a default for older resources -func (s *ControlPlaneStatus) GetReconciledVersion() string { - if s == nil { - return status.ComposeReconciledVersion("0.0.0", 0) - } - return status.ComposeReconciledVersion(s.OperatorVersion, s.ObservedGeneration) -} - -// ControlPlaneSpec represents the configuration for installing a control plane -type ControlPlaneSpec struct { - // XXX: the resource name is intended to be used as the revision name, which - // is used by istio.io/rev labels/annotations to specify which control plane - // workloads should be connecting with. - - // Profiles selects the profile to use for default values. Defaults to - // "default" when not set. - // +optional - Profiles []string `json:"profiles,omitempty"` - - // Version specifies what Maistra version of the control plane to install. - // When creating a new ServiceMeshControlPlane with an empty version, the - // 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"` - // MeshConfig TODO: add description - MeshConfig *MeshConfig `json:"meshConfig,omitempty"` - // General represents general control plane configuration that does not - // logically fit in another area. - // +optional - General *GeneralConfig `json:"general,omitempty"` - // Policy configures policy checking for the control plane. - // .Values.policy.enabled, true if not null - // +optional - Policy *PolicyConfig `json:"policy,omitempty"` - // Proxy configures the default behavior for sidecars. Many values were - // previously exposed through .Values.global.proxy - // +optional - Proxy *ProxyConfig `json:"proxy,omitempty"` - // Security configures aspects of security for the control plane. - // +optional - Security *SecurityConfig `json:"security,omitempty"` - // Telemetry configures telemetry for the mesh. - // .Values.mixer.telemetry.enabled, true if not null. 1.6, .Values.telemetry.enabled - // +optional - Telemetry *TelemetryConfig `json:"telemetry,omitempty"` - // Tracing configures tracing for the mesh. - // +optional - Tracing *TracingConfig `json:"tracing,omitempty"` - // Gateways configures gateways for the mesh - // .Values.gateways.* - // +optional - Gateways *GatewaysConfig `json:"gateways,omitempty"` - // Runtime configuration for pilot (and galley, etc., pre 2.0) - // +optional - Runtime *ControlPlaneRuntimeConfig `json:"runtime,omitempty"` - // Addons is used to configure additional features beyond core control plane - // components, e.g. visualization, metric storage, etc. - // +optional - Addons *AddonsConfig `json:"addons,omitempty"` - // TechPreview contains switches for features that are not GA yet. - // +optional - TechPreview *v1.HelmValues `json:"techPreview,omitempty"` -} - -// Enablement is a common definition for features that can be enabled -type Enablement struct { - // Enabled specifies whether or not this feature is enabled - Enabled *bool `json:"enabled,omitempty"` -} - -func (s ControlPlaneSpec) IsKialiEnabled() bool { - return s.Addons != nil && - s.Addons.Kiali != nil && - s.Addons.Kiali.Enabled != nil && - *s.Addons.Kiali.Enabled -} - -func (s ControlPlaneSpec) IsCustomKialiConfigured() bool { - return s.Addons != nil && s.Addons.Kiali != nil && s.Addons.Kiali.Name != "" -} - -func (s ControlPlaneSpec) IsPrometheusEnabled() bool { - return s.Addons != nil && - s.Addons.Prometheus != nil && - s.Addons.Prometheus.Enabled != nil && - *s.Addons.Prometheus.Enabled -} - -func (s ControlPlaneSpec) IsGrafanaEnabled() bool { - return s.Addons != nil && s.Addons.Grafana != nil && s.Addons.Grafana.Enabled != nil && *s.Addons.Grafana.Enabled -} - -func (s ControlPlaneSpec) IsJaegerEnabled() bool { - return s.Tracing != nil && s.Tracing.Type == TracerTypeJaeger -} - -func (s ControlPlaneSpec) IsStackdriverEnabled() bool { - return s.Tracing != nil && s.Tracing.Type == TracerTypeStackdriver -} diff --git a/api/external/maistra/v2/stackdriver.go b/api/external/maistra/v2/stackdriver.go deleted file mode 100644 index 16c3105be..000000000 --- a/api/external/maistra/v2/stackdriver.go +++ /dev/null @@ -1,97 +0,0 @@ -package v2 - -import ( - v1 "github.com/kuadrant/kuadrant-operator/api/external/maistra/v1" -) - -// StackdriverAddonConfig configuration specific to Stackdriver integration. -type StackdriverAddonConfig struct { - // Configuration for Stackdriver tracer. Applies when Addons.Tracer.Type=Stackdriver - Tracer *StackdriverTracerConfig `json:"tracer,omitempty"` - // Configuration for Stackdriver telemetry plugins. Applies when telemetry - // is enabled - Telemetry *StackdriverTelemetryConfig `json:"telemetry,omitempty"` -} - -// StackdriverTracerConfig configures the Stackdriver tracer -type StackdriverTracerConfig struct { - // .Values.global.tracer.stackdriver.debug - // +optional - Debug *bool `json:"debug,omitempty"` - // .Values.global.tracer.stackdriver.maxNumberOfAttributes - // +optional - MaxNumberOfAttributes *int64 `json:"maxNumberOfAttributes,omitempty"` - // .Values.global.tracer.stackdriver.maxNumberOfAnnotations - // +optional - MaxNumberOfAnnotations *int64 `json:"maxNumberOfAnnotations,omitempty"` - // .Values.global.tracer.stackdriver.maxNumberOfMessageEvents - // +optional - MaxNumberOfMessageEvents *int64 `json:"maxNumberOfMessageEvents,omitempty"` -} - -// StackdriverTelemetryConfig adds telemetry filters for Stackdriver. -type StackdriverTelemetryConfig struct { - // Enable installation of Stackdriver telemetry filters (mixer or v2/envoy). - // These will only be installed if this is enabled an telemetry is enabled. - Enablement `json:",inline"` - // Auth configuration for stackdriver adapter (mixer/v1 telemetry only) - // .Values.mixer.adapters.stackdriver.auth - // +optional - Auth *StackdriverAuthConfig `json:"auth,omitempty"` - // EnableContextGraph for stackdriver adapter (edge reporting) - // .Values.mixer.adapters.stackdriver.contextGraph.enabled, defaults to false - // .Values.telemetry.v2.stackdriver.topology, defaults to false - // +optional - EnableContextGraph *bool `json:"enableContextGraph,omitempty"` - // EnableLogging for stackdriver adapter - // .Values.mixer.adapters.stackdriver.logging.enabled, defaults to true - // .Values.telemetry.v2.stackdriver.logging, defaults to false - // +optional - EnableLogging *bool `json:"enableLogging,omitempty"` - // EnableMetrics for stackdriver adapter - // .Values.mixer.adapters.stackdriver.metrics.enabled, defaults to true - // .Values.telemetry.v2.stackdriver.monitoring??? defaults to false - // +optional - EnableMetrics *bool `json:"enableMetrics,omitempty"` - // DisableOutbound disables intallation of sidecar outbound filter - // .Values.telemetry.v2.stackdriver.disableOutbound, defaults to false - // +optional - // DisableOutbound bool `json:"disableOutbound,omitempty"` - // AccessLogging configures access logging for stackdriver - AccessLogging *StackdriverAccessLogTelemetryConfig `json:"accessLogging,omitempty"` - // ConfigOverride apply custom configuration to Stackdriver filters (v2 - // telemetry only) - // .Values.telemetry.v2.stackdriver.configOverride - // +optional - ConfigOverride *v1.HelmValues `json:"configOverride,omitempty"` -} - -// StackdriverAuthConfig is the auth config for stackdriver. Only one field may be set -type StackdriverAuthConfig struct { - // AppCredentials if true, use default app credentials. - // .Values.mixer.adapters.stackdriver.auth.appCredentials, defaults to false - // +optional - AppCredentials *bool `json:"appCredentials,omitempty"` - // APIKey use the specified key. - // .Values.mixer.adapters.stackdriver.auth.apiKey - // +optional - APIKey string `json:"apiKey,omitempty"` - // ServiceAccountPath use the path to the service account. - // .Values.mixer.adapters.stackdriver.auth.serviceAccountPath - // +optional - ServiceAccountPath string `json:"serviceAccountPath,omitempty"` -} - -// StackdriverAccessLogTelemetryConfig for v2 telemetry. -type StackdriverAccessLogTelemetryConfig struct { - // Enable installation of access log filter. - // .Values.telemetry.v2.accessLogPolicy.enabled - Enablement `json:",inline"` - // LogWindowDuration configures the log window duration for access logs. - // defaults to 43200s - // To reduce the number of successful logs, default log window duration is - // set to 12 hours. - // .Values.telemetry.v2.accessLogPolicy.logWindowDuration - // +optional - LogWindowDuration string `json:"logWindowDuration,omitempty"` -} diff --git a/api/external/maistra/v2/telemetry.go b/api/external/maistra/v2/telemetry.go deleted file mode 100644 index eaf5597cc..000000000 --- a/api/external/maistra/v2/telemetry.go +++ /dev/null @@ -1,119 +0,0 @@ -package v2 - -// TelemetryConfig for the mesh -type TelemetryConfig struct { - // Type of telemetry implementation to use. - Type TelemetryType `json:"type,omitempty"` - // Mixer represents legacy, v1 telemetry. - // implies .Values.telemetry.v1.enabled, if not null - // +optional - Mixer *MixerTelemetryConfig `json:"mixer,omitempty"` - // Remote represents a remote, legacy, v1 telemetry. - // +optional - Remote *RemoteTelemetryConfig `json:"remote,omitempty"` -} - -// TelemetryType represents the telemetry implementation used. -type TelemetryType string - -const ( - // TelemetryTypeNone disables telemetry - TelemetryTypeNone TelemetryType = "None" - // TelemetryTypeMixer represents mixer telemetry, v1 - TelemetryTypeMixer TelemetryType = "Mixer" - // TelemetryTypeRemote represents remote mixer telemetry server, v1 - TelemetryTypeRemote TelemetryType = "Remote" - // TelemetryTypeIstiod represents istio, v2 - TelemetryTypeIstiod TelemetryType = "Istiod" -) - -// MixerTelemetryConfig is the configuration for legacy, v1 mixer telemetry. -// .Values.telemetry.v1.enabled -type MixerTelemetryConfig struct { - // SessionAffinity configures session affinity for sidecar telemetry connections. - // .Values.mixer.telemetry.sessionAffinityEnabled, maps to MeshConfig.sidecarToTelemetrySessionAffinity - // +optional - SessionAffinity *bool `json:"sessionAffinity,omitempty"` - // Loadshedding configuration for telemetry - // .Values.mixer.telemetry.loadshedding - // +optional - Loadshedding *TelemetryLoadSheddingConfig `json:"loadshedding,omitempty"` - // Batching settings used when sending telemetry. - // +optional - Batching *TelemetryBatchingConfig `json:"batching,omitempty"` - // Adapters configures the adapters used by mixer telemetry. - // +optional - Adapters *MixerTelemetryAdaptersConfig `json:"adapters,omitempty"` -} - -// TelemetryLoadSheddingConfig configures how mixer telemetry loadshedding behaves -type TelemetryLoadSheddingConfig struct { - // Mode represents the loadshedding mode applied to mixer when it becomes - // overloaded. Valid values: disabled, logonly or enforce - // .Values.mixer.telemetry.loadshedding.mode - // +optional - Mode string `json:"mode,omitempty"` - // LatencyThreshold -- - // .Values.mixer.telemetry.loadshedding.latencyThreshold - // +optional - LatencyThreshold string `json:"latencyThreshold,omitempty"` -} - -// TelemetryBatchingConfig configures how telemetry data is batched. -type TelemetryBatchingConfig struct { - // MaxEntries represents the maximum number of entries to collect before sending them to mixer. - // .Values.mixer.telemetry.reportBatchMaxEntries, maps to MeshConfig.reportBatchMaxEntries - // Set reportBatchMaxEntries to 0 to use the default batching behavior (i.e., every 100 requests). - // A positive value indicates the number of requests that are batched before telemetry data - // is sent to the mixer server - // +optional - MaxEntries *int32 `json:"maxEntries,omitempty"` - // MaxTime represents the maximum amount of time to hold entries before sending them to mixer. - // .Values.mixer.telemetry.reportBatchMaxTime, maps to MeshConfig.reportBatchMaxTime - // Set reportBatchMaxTime to 0 to use the default batching behavior (i.e., every 1 second). - // A positive time value indicates the maximum wait time since the last request will telemetry data - // be batched before being sent to the mixer server - // +optional - MaxTime string `json:"maxTime,omitempty"` -} - -// MixerTelemetryAdaptersConfig is the configuration for mixer telemetry adapters. -type MixerTelemetryAdaptersConfig struct { - // UseAdapterCRDs specifies whether or not mixer should support deprecated CRDs. - // .Values.mixer.adapters.useAdapterCRDs, removed in istio 1.4, defaults to false - // XXX: i think this can be removed completely - // +optional - UseAdapterCRDs *bool `json:"useAdapterCRDs,omitempty"` - // KubernetesEnv enables support for the kubernetesenv adapter. - // .Values.mixer.adapters.kubernetesenv.enabled, defaults to true - // +optional - KubernetesEnv *bool `json:"kubernetesenv,omitempty"` - // Stdio enables and configures the stdio adapter. - // +optional - Stdio *MixerTelemetryStdioConfig `json:"stdio,omitempty"` -} - -// MixerTelemetryStdioConfig configures the stdio adapter for mixer telemetry. -type MixerTelemetryStdioConfig struct { - // .Values.mixer.adapters.stdio.enabled - Enablement `json:",inline"` - // OutputAsJSON if true. - // .Values.mixer.adapters.stdio.outputAsJson, defaults to false - // +optional - OutputAsJSON *bool `json:"outputAsJSON,omitempty"` -} - -// RemoteTelemetryConfig configures a remote, legacy, v1 mixer telemetry. -// .Values.telemetry.v1.enabled true -type RemoteTelemetryConfig struct { - // Address is the address of the remote telemetry server - // .Values.global.remoteTelemetryAddress, maps to MeshConfig.mixerReportServer - Address string `json:"address,omitempty"` - // CreateService for the remote server. - // .Values.global.createRemoteSvcEndpoints - // +optional - CreateService *bool `json:"createService,omitempty"` - // Batching settings used when sending telemetry. - // +optional - Batching *TelemetryBatchingConfig `json:"batching,omitempty"` -} diff --git a/api/external/maistra/v2/threescale.go b/api/external/maistra/v2/threescale.go deleted file mode 100644 index 890e48a95..000000000 --- a/api/external/maistra/v2/threescale.go +++ /dev/null @@ -1,130 +0,0 @@ -package v2 - -// ThreeScaleAddonConfig represents configuration options for the installation of the -// 3scale adapter. The options are structured similarly to what is defined by -// the 3scale ConfigMap. -type ThreeScaleAddonConfig struct { - Enablement `json:",inline"` - - // ListenerAddr sets the listen address for the gRPC server. - // PARAM_THREESCALE_LISTEN_ADDR - // +optional - ListenAddr *int32 `json:"listen_addr,omitempty"` - // LogGRPC controls whether the log includes gRPC info - // PARAM_THREESCALE_LOG_GRPC - // +optional - LogGRPC *bool `json:"log_grpc,omitempty"` - // LogJSON controls whether the log is formatted as JSON - // PARAM_THREESCALE_LOG_JSON - // +optional - LogJSON *bool `json:"log_json,omitempty"` - // LogLevel sets the minimum log output level. Accepted values are one of: - // debug, info, warn, error, none - // PARAM_THREESCALE_LOG_LEVEL - // +optional - LogLevel string `json:"log_level,omitempty"` - - // Metrics configures metrics specific details - // +optional - Metrics *ThreeScaleMetricsConfig `json:"metrics,omitempty"` - - // System configures system specific details - // +optional - System *ThreeScaleSystemConfig `json:"system,omitempty"` - - // Client configures client specific details - // +optional - Client *ThreeScaleClientConfig `json:"client,omitempty"` - - // GRPC configures gRPC specific details - // +optional - GRPC *ThreeScaleGRPCConfig `json:"grpc,omitempty"` - - // Backend configures backend specific details - // +optional - Backend *ThreeScaleBackendConfig `json:"backend,omitempty"` -} - -// ThreeScaleMetricsConfig represents 3scale adapter options for its 'metrics' -// section. -type ThreeScaleMetricsConfig struct { - // Port sets the port which 3scale /metrics endpoint can be scrapped from - // PARAM_THREESCALE_METRICS_PORT - // +optional - Port *int32 `json:"port,omitempty"` - // Report controls whether 3scale system and backend metrics are collected - // and reported to Prometheus - // PARAM_THREESCALE_REPORT_METRICS - // +optional - Report *bool `json:"report,omitempty"` -} - -// ThreeScaleSystemConfig represents 3scale adapter options for its 'system' -// section. -type ThreeScaleSystemConfig struct { - // CacheMaxSize is the max number of items that can be stored in the cache - // at any time. Set to 0 to disable caching - // PARAM_THREESCALE_CACHE_ENTRIES_MAX - // +optional - CacheMaxSize *int64 `json:"cache_max_size,omitempty"` - // CacheRefreshRetries sets the number of times unreachable hosts will be - // retried during a cache update loop - // PARAM_THREESCALE_CACHE_REFRESH_RETRIES - // +optional - CacheRefreshRetries *int32 `json:"cache_refresh_retries,omitempty"` - // CacheRefreshInterval is the time period in seconds, before a background - // process attempts to refresh cached entries - // PARAM_THREESCALE_CACHE_REFRESH_SECONDS - // +optional - CacheRefreshInterval *int32 `json:"cache_refresh_interval,omitempty"` - // CacheTTL is the time period, in seconds, to wait before purging expired - // items from the cache - // PARAM_THREESCALE_CACHE_TTL_SECONDS - // +optional - CacheTTL *int32 `json:"cache_ttl,omitempty"` -} - -// ThreeScaleClientConfig represents 3scale adapter options for its 'client' -// section. -type ThreeScaleClientConfig struct { - // AllowInsecureConnections skips certificate verification when calling - // 3scale API's. Enabling is not recommended - // PARAM_THREESCALE_ALLOW_INSECURE_CONN - // +optional - AllowInsecureConnections *bool `json:"allow_insecure_connections,omitempty"` - // Timeout sets the number of seconds to wait before terminating requests - // to 3scale System and Backend - // PARAM_THREESCALE_CLIENT_TIMEOUT_SECONDS - // +optional - Timeout *int32 `json:"timeout,omitempty"` -} - -// ThreeScaleGRPCConfig represents 3scale adapter options for its 'grpc' -// section. -type ThreeScaleGRPCConfig struct { - // MaxConnTimeout sets the maximum amount of seconds (+/-10% jitter) a - // connection may exist before it will be closed - // PARAM_THREESCALE_GRPC_CONN_MAX_SECONDS - // +optional - MaxConnTimeout *int32 `json:"max_conn_timeout,omitempty"` -} - -// ThreeScaleBackendConfig represents 3scale adapter options for its 'backend' -// section. -type ThreeScaleBackendConfig struct { - // EnableCache if true, attempts to create an in-memory apisonator cache for - // authorization requests - // PARAM_THREESCALE_USE_CACHED_BACKEND - // +optional - EnableCache *bool `json:"enable_cache,omitempty"` - // CacheFlushInterval sets the interval at which metrics get reported from - // the cache to 3scale - // PARAM_THREESCALE_BACKEND_CACHE_FLUSH_INTERVAL_SECONDS - // +optional - CacheFlushInterval *int32 `json:"cache_flush_interval,omitempty"` - // PolicyFailClosed if true, request will fail if 3scale Apisonator is - // unreachable - // PARAM_THREESCALE_BACKEND_CACHE_POLICY_FAIL_CLOSED - // +optional - PolicyFailClosed *bool `json:"policy_fail_closed,omitempty"` -} diff --git a/api/external/maistra/v2/tracing.go b/api/external/maistra/v2/tracing.go deleted file mode 100644 index 290bc4693..000000000 --- a/api/external/maistra/v2/tracing.go +++ /dev/null @@ -1,31 +0,0 @@ -package v2 - -// TracingConfig configures tracing solutions for the mesh. -// .Values.global.enableTracing -type TracingConfig struct { - // Type represents the type of tracer to be installed. - Type TracerType `json:"type,omitempty"` - // Sampling sets the mesh-wide trace sampling percentage. Should be between - // 0.0 - 100.0. Precision to 0.01, scaled as 0 to 10000, e.g.: 100% = 10000, - // 1% = 100 - // .Values.pilot.traceSampling - // +kubebuilder:validation:Minimum=0 - // +kubebuilder:validation:Maximum=10000 - // +optional - Sampling *int32 `json:"sampling,omitempty"` -} - -// TracerType represents the tracer type to use -type TracerType string - -const ( - // TracerTypeNone is used to represent no tracer - TracerTypeNone TracerType = "None" - // TracerTypeJaeger is used to represent Jaeger as the tracer - TracerTypeJaeger TracerType = "Jaeger" - // TracerTypeStackdriver is used to represent Stackdriver as the tracer - TracerTypeStackdriver TracerType = "Stackdriver" - // TracerTypeZipkin TracerType = "Zipkin" - // TracerTypeLightstep TracerType = "Lightstep" - // TracerTypeDatadog TracerType = "Datadog" -) diff --git a/api/external/maistra/v2/zipkin.go b/api/external/maistra/v2/zipkin.go deleted file mode 100644 index 322ad69a4..000000000 --- a/api/external/maistra/v2/zipkin.go +++ /dev/null @@ -1,6 +0,0 @@ -package v2 - -// ZipkinTracerConfig configures a Zipkin tracer for use with the mesh -type ZipkinTracerConfig struct { - // TODO.... -} diff --git a/api/external/maistra/v2/zz_generated.deepcopy.go b/api/external/maistra/v2/zz_generated.deepcopy.go deleted file mode 100644 index 3c11276bd..000000000 --- a/api/external/maistra/v2/zz_generated.deepcopy.go +++ /dev/null @@ -1,3434 +0,0 @@ -//go:build !ignore_autogenerated - -/* -Copyright 2021. - -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. -*/ - -// Code generated by controller-gen. DO NOT EDIT. - -package v2 - -import ( - appsv1 "k8s.io/api/apps/v1" - "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/intstr" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AddonsConfig) DeepCopyInto(out *AddonsConfig) { - *out = *in - if in.Prometheus != nil { - in, out := &in.Prometheus, &out.Prometheus - *out = new(PrometheusAddonConfig) - (*in).DeepCopyInto(*out) - } - if in.Stackdriver != nil { - in, out := &in.Stackdriver, &out.Stackdriver - *out = new(StackdriverAddonConfig) - (*in).DeepCopyInto(*out) - } - if in.Jaeger != nil { - in, out := &in.Jaeger, &out.Jaeger - *out = new(JaegerAddonConfig) - (*in).DeepCopyInto(*out) - } - if in.Grafana != nil { - in, out := &in.Grafana, &out.Grafana - *out = new(GrafanaAddonConfig) - (*in).DeepCopyInto(*out) - } - if in.Kiali != nil { - in, out := &in.Kiali, &out.Kiali - *out = new(KialiAddonConfig) - (*in).DeepCopyInto(*out) - } - if in.ThreeScale != nil { - in, out := &in.ThreeScale, &out.ThreeScale - *out = new(ThreeScaleAddonConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddonsConfig. -func (in *AddonsConfig) DeepCopy() *AddonsConfig { - if in == nil { - return nil - } - out := new(AddonsConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Affinity) DeepCopyInto(out *Affinity) { - *out = *in - if in.NodeAffinity != nil { - in, out := &in.NodeAffinity, &out.NodeAffinity - *out = new(v1.NodeAffinity) - (*in).DeepCopyInto(*out) - } - if in.PodAffinity != nil { - in, out := &in.PodAffinity, &out.PodAffinity - *out = new(v1.PodAffinity) - (*in).DeepCopyInto(*out) - } - in.PodAntiAffinity.DeepCopyInto(&out.PodAntiAffinity) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Affinity. -func (in *Affinity) DeepCopy() *Affinity { - if in == nil { - return nil - } - out := new(Affinity) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AutoScalerConfig) DeepCopyInto(out *AutoScalerConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.MinReplicas != nil { - in, out := &in.MinReplicas, &out.MinReplicas - *out = new(int32) - **out = **in - } - if in.MaxReplicas != nil { - in, out := &in.MaxReplicas, &out.MaxReplicas - *out = new(int32) - **out = **in - } - if in.TargetCPUUtilizationPercentage != nil { - in, out := &in.TargetCPUUtilizationPercentage, &out.TargetCPUUtilizationPercentage - *out = new(int32) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoScalerConfig. -func (in *AutoScalerConfig) DeepCopy() *AutoScalerConfig { - if in == nil { - return nil - } - out := new(AutoScalerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CertManagerCertificateAuthorityConfig) DeepCopyInto(out *CertManagerCertificateAuthorityConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CertManagerCertificateAuthorityConfig. -func (in *CertManagerCertificateAuthorityConfig) DeepCopy() *CertManagerCertificateAuthorityConfig { - if in == nil { - return nil - } - out := new(CertManagerCertificateAuthorityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CertificateAuthorityConfig) DeepCopyInto(out *CertificateAuthorityConfig) { - *out = *in - if in.Istiod != nil { - in, out := &in.Istiod, &out.Istiod - *out = new(IstiodCertificateAuthorityConfig) - (*in).DeepCopyInto(*out) - } - if in.Custom != nil { - in, out := &in.Custom, &out.Custom - *out = new(CustomCertificateAuthorityConfig) - **out = **in - } - if in.CertManager != nil { - in, out := &in.CertManager, &out.CertManager - *out = new(CertManagerCertificateAuthorityConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CertificateAuthorityConfig. -func (in *CertificateAuthorityConfig) DeepCopy() *CertificateAuthorityConfig { - if in == nil { - return nil - } - out := new(CertificateAuthorityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterIngressGatewayConfig) DeepCopyInto(out *ClusterIngressGatewayConfig) { - *out = *in - in.IngressGatewayConfig.DeepCopyInto(&out.IngressGatewayConfig) - if in.IngressEnabled != nil { - in, out := &in.IngressEnabled, &out.IngressEnabled - *out = new(bool) - **out = **in - } - if in.MeshExpansionPorts != nil { - in, out := &in.MeshExpansionPorts, &out.MeshExpansionPorts - *out = make([]v1.ServicePort, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterIngressGatewayConfig. -func (in *ClusterIngressGatewayConfig) DeepCopy() *ClusterIngressGatewayConfig { - if in == nil { - return nil - } - out := new(ClusterIngressGatewayConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CommonContainerConfig) DeepCopyInto(out *CommonContainerConfig) { - *out = *in - if in.ImagePullSecrets != nil { - in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]v1.LocalObjectReference, len(*in)) - copy(*out, *in) - } - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = new(v1.ResourceRequirements) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonContainerConfig. -func (in *CommonContainerConfig) DeepCopy() *CommonContainerConfig { - if in == nil { - return nil - } - out := new(CommonContainerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CommonDeploymentRuntimeConfig) DeepCopyInto(out *CommonDeploymentRuntimeConfig) { - *out = *in - if in.PodDisruption != nil { - in, out := &in.PodDisruption, &out.PodDisruption - *out = new(PodDisruptionBudget) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonDeploymentRuntimeConfig. -func (in *CommonDeploymentRuntimeConfig) DeepCopy() *CommonDeploymentRuntimeConfig { - if in == nil { - return nil - } - out := new(CommonDeploymentRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CommonPodRuntimeConfig) DeepCopyInto(out *CommonPodRuntimeConfig) { - *out = *in - if in.NodeSelector != nil { - in, out := &in.NodeSelector, &out.NodeSelector - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Tolerations != nil { - in, out := &in.Tolerations, &out.Tolerations - *out = make([]v1.Toleration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonPodRuntimeConfig. -func (in *CommonPodRuntimeConfig) DeepCopy() *CommonPodRuntimeConfig { - if in == nil { - return nil - } - out := new(CommonPodRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentIngressConfig) DeepCopyInto(out *ComponentIngressConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Metadata != nil { - in, out := &in.Metadata, &out.Metadata - *out = new(MetadataConfig) - (*in).DeepCopyInto(*out) - } - if in.Hosts != nil { - in, out := &in.Hosts, &out.Hosts - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.TLS != nil { - in, out := &in.TLS, &out.TLS - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentIngressConfig. -func (in *ComponentIngressConfig) DeepCopy() *ComponentIngressConfig { - if in == nil { - return nil - } - out := new(ComponentIngressConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in ComponentLogLevels) DeepCopyInto(out *ComponentLogLevels) { - { - in := &in - *out = make(ComponentLogLevels, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentLogLevels. -func (in ComponentLogLevels) DeepCopy() ComponentLogLevels { - if in == nil { - return nil - } - out := new(ComponentLogLevels) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentPersistenceConfig) DeepCopyInto(out *ComponentPersistenceConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = new(v1.ResourceRequirements) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentPersistenceConfig. -func (in *ComponentPersistenceConfig) DeepCopy() *ComponentPersistenceConfig { - if in == nil { - return nil - } - out := new(ComponentPersistenceConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentRuntimeConfig) DeepCopyInto(out *ComponentRuntimeConfig) { - *out = *in - if in.Deployment != nil { - in, out := &in.Deployment, &out.Deployment - *out = new(DeploymentRuntimeConfig) - (*in).DeepCopyInto(*out) - } - if in.Pod != nil { - in, out := &in.Pod, &out.Pod - *out = new(PodRuntimeConfig) - (*in).DeepCopyInto(*out) - } - if in.Container != nil { - in, out := &in.Container, &out.Container - *out = new(ContainerConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentRuntimeConfig. -func (in *ComponentRuntimeConfig) DeepCopy() *ComponentRuntimeConfig { - if in == nil { - return nil - } - out := new(ComponentRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentServiceConfig) DeepCopyInto(out *ComponentServiceConfig) { - *out = *in - if in.Metadata != nil { - in, out := &in.Metadata, &out.Metadata - *out = new(MetadataConfig) - (*in).DeepCopyInto(*out) - } - if in.NodePort != nil { - in, out := &in.NodePort, &out.NodePort - *out = new(int32) - **out = **in - } - if in.Ingress != nil { - in, out := &in.Ingress, &out.Ingress - *out = new(ComponentIngressConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentServiceConfig. -func (in *ComponentServiceConfig) DeepCopy() *ComponentServiceConfig { - if in == nil { - return nil - } - out := new(ComponentServiceConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ContainerConfig) DeepCopyInto(out *ContainerConfig) { - *out = *in - in.CommonContainerConfig.DeepCopyInto(&out.CommonContainerConfig) - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerConfig. -func (in *ContainerConfig) DeepCopy() *ContainerConfig { - if in == nil { - return nil - } - out := new(ContainerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneClusterConfig) DeepCopyInto(out *ControlPlaneClusterConfig) { - *out = *in - if in.MultiCluster != nil { - in, out := &in.MultiCluster, &out.MultiCluster - *out = new(MultiClusterConfig) - (*in).DeepCopyInto(*out) - } - if in.MeshExpansion != nil { - in, out := &in.MeshExpansion, &out.MeshExpansion - *out = new(MeshExpansionConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneClusterConfig. -func (in *ControlPlaneClusterConfig) DeepCopy() *ControlPlaneClusterConfig { - if in == nil { - return nil - } - out := new(ControlPlaneClusterConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneRuntimeConfig) DeepCopyInto(out *ControlPlaneRuntimeConfig) { - *out = *in - if in.Components != nil { - in, out := &in.Components, &out.Components - *out = make(map[ControlPlaneComponentName]*ComponentRuntimeConfig, len(*in)) - for key, val := range *in { - var outVal *ComponentRuntimeConfig - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = new(ComponentRuntimeConfig) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } - } - if in.Defaults != nil { - in, out := &in.Defaults, &out.Defaults - *out = new(DefaultRuntimeConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneRuntimeConfig. -func (in *ControlPlaneRuntimeConfig) DeepCopy() *ControlPlaneRuntimeConfig { - if in == nil { - return nil - } - out := new(ControlPlaneRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneSecurityConfig) DeepCopyInto(out *ControlPlaneSecurityConfig) { - *out = *in - if in.MTLS != nil { - in, out := &in.MTLS, &out.MTLS - *out = new(bool) - **out = **in - } - if in.TLS != nil { - in, out := &in.TLS, &out.TLS - *out = new(ControlPlaneTLSConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneSecurityConfig. -func (in *ControlPlaneSecurityConfig) DeepCopy() *ControlPlaneSecurityConfig { - if in == nil { - return nil - } - out := new(ControlPlaneSecurityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneSpec) DeepCopyInto(out *ControlPlaneSpec) { - *out = *in - if in.Profiles != nil { - in, out := &in.Profiles, &out.Profiles - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Cluster != nil { - in, out := &in.Cluster, &out.Cluster - *out = new(ControlPlaneClusterConfig) - (*in).DeepCopyInto(*out) - } - if in.MeshConfig != nil { - in, out := &in.MeshConfig, &out.MeshConfig - *out = new(MeshConfig) - (*in).DeepCopyInto(*out) - } - if in.General != nil { - in, out := &in.General, &out.General - *out = new(GeneralConfig) - (*in).DeepCopyInto(*out) - } - if in.Policy != nil { - in, out := &in.Policy, &out.Policy - *out = new(PolicyConfig) - (*in).DeepCopyInto(*out) - } - if in.Proxy != nil { - in, out := &in.Proxy, &out.Proxy - *out = new(ProxyConfig) - (*in).DeepCopyInto(*out) - } - if in.Security != nil { - in, out := &in.Security, &out.Security - *out = new(SecurityConfig) - (*in).DeepCopyInto(*out) - } - if in.Telemetry != nil { - in, out := &in.Telemetry, &out.Telemetry - *out = new(TelemetryConfig) - (*in).DeepCopyInto(*out) - } - if in.Tracing != nil { - in, out := &in.Tracing, &out.Tracing - *out = new(TracingConfig) - (*in).DeepCopyInto(*out) - } - if in.Gateways != nil { - in, out := &in.Gateways, &out.Gateways - *out = new(GatewaysConfig) - (*in).DeepCopyInto(*out) - } - if in.Runtime != nil { - in, out := &in.Runtime, &out.Runtime - *out = new(ControlPlaneRuntimeConfig) - (*in).DeepCopyInto(*out) - } - if in.Addons != nil { - in, out := &in.Addons, &out.Addons - *out = new(AddonsConfig) - (*in).DeepCopyInto(*out) - } - if in.TechPreview != nil { - in, out := &in.TechPreview, &out.TechPreview - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneSpec. -func (in *ControlPlaneSpec) DeepCopy() *ControlPlaneSpec { - if in == nil { - return nil - } - out := new(ControlPlaneSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneStatus) DeepCopyInto(out *ControlPlaneStatus) { - *out = *in - in.StatusBase.DeepCopyInto(&out.StatusBase) - in.StatusType.DeepCopyInto(&out.StatusType) - in.ComponentStatusList.DeepCopyInto(&out.ComponentStatusList) - in.Readiness.DeepCopyInto(&out.Readiness) - in.AppliedSpec.DeepCopyInto(&out.AppliedSpec) - in.AppliedValues.DeepCopyInto(&out.AppliedValues) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneStatus. -func (in *ControlPlaneStatus) DeepCopy() *ControlPlaneStatus { - if in == nil { - return nil - } - out := new(ControlPlaneStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ControlPlaneTLSConfig) DeepCopyInto(out *ControlPlaneTLSConfig) { - *out = *in - if in.CipherSuites != nil { - in, out := &in.CipherSuites, &out.CipherSuites - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ECDHCurves != nil { - in, out := &in.ECDHCurves, &out.ECDHCurves - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneTLSConfig. -func (in *ControlPlaneTLSConfig) DeepCopy() *ControlPlaneTLSConfig { - if in == nil { - return nil - } - out := new(ControlPlaneTLSConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CustomCertificateAuthorityConfig) DeepCopyInto(out *CustomCertificateAuthorityConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CustomCertificateAuthorityConfig. -func (in *CustomCertificateAuthorityConfig) DeepCopy() *CustomCertificateAuthorityConfig { - if in == nil { - return nil - } - out := new(CustomCertificateAuthorityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DataPlaneSecurityConfig) DeepCopyInto(out *DataPlaneSecurityConfig) { - *out = *in - if in.MTLS != nil { - in, out := &in.MTLS, &out.MTLS - *out = new(bool) - **out = **in - } - if in.AutoMTLS != nil { - in, out := &in.AutoMTLS, &out.AutoMTLS - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataPlaneSecurityConfig. -func (in *DataPlaneSecurityConfig) DeepCopy() *DataPlaneSecurityConfig { - if in == nil { - return nil - } - out := new(DataPlaneSecurityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogTracerConfig) DeepCopyInto(out *DatadogTracerConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogTracerConfig. -func (in *DatadogTracerConfig) DeepCopy() *DatadogTracerConfig { - if in == nil { - return nil - } - out := new(DatadogTracerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DefaultRuntimeConfig) DeepCopyInto(out *DefaultRuntimeConfig) { - *out = *in - if in.Deployment != nil { - in, out := &in.Deployment, &out.Deployment - *out = new(CommonDeploymentRuntimeConfig) - (*in).DeepCopyInto(*out) - } - if in.Pod != nil { - in, out := &in.Pod, &out.Pod - *out = new(CommonPodRuntimeConfig) - (*in).DeepCopyInto(*out) - } - if in.Container != nil { - in, out := &in.Container, &out.Container - *out = new(CommonContainerConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultRuntimeConfig. -func (in *DefaultRuntimeConfig) DeepCopy() *DefaultRuntimeConfig { - if in == nil { - return nil - } - out := new(DefaultRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DeploymentRuntimeConfig) DeepCopyInto(out *DeploymentRuntimeConfig) { - *out = *in - if in.Replicas != nil { - in, out := &in.Replicas, &out.Replicas - *out = new(int32) - **out = **in - } - if in.Strategy != nil { - in, out := &in.Strategy, &out.Strategy - *out = new(appsv1.DeploymentStrategy) - (*in).DeepCopyInto(*out) - } - if in.AutoScaling != nil { - in, out := &in.AutoScaling, &out.AutoScaling - *out = new(AutoScalerConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentRuntimeConfig. -func (in *DeploymentRuntimeConfig) DeepCopy() *DeploymentRuntimeConfig { - if in == nil { - return nil - } - out := new(DeploymentRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EgressGatewayConfig) DeepCopyInto(out *EgressGatewayConfig) { - *out = *in - in.GatewayConfig.DeepCopyInto(&out.GatewayConfig) - if in.RequestedNetworkView != nil { - in, out := &in.RequestedNetworkView, &out.RequestedNetworkView - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EgressGatewayConfig. -func (in *EgressGatewayConfig) DeepCopy() *EgressGatewayConfig { - if in == nil { - return nil - } - out := new(EgressGatewayConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Enablement) DeepCopyInto(out *Enablement) { - *out = *in - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Enablement. -func (in *Enablement) DeepCopy() *Enablement { - if in == nil { - return nil - } - out := new(Enablement) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvoyServiceClientTLSSettings) DeepCopyInto(out *EnvoyServiceClientTLSSettings) { - *out = *in - if in.SubjectAltNames != nil { - in, out := &in.SubjectAltNames, &out.SubjectAltNames - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyServiceClientTLSSettings. -func (in *EnvoyServiceClientTLSSettings) DeepCopy() *EnvoyServiceClientTLSSettings { - if in == nil { - return nil - } - out := new(EnvoyServiceClientTLSSettings) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EnvoyServiceTCPKeepalive) DeepCopyInto(out *EnvoyServiceTCPKeepalive) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyServiceTCPKeepalive. -func (in *EnvoyServiceTCPKeepalive) DeepCopy() *EnvoyServiceTCPKeepalive { - if in == nil { - return nil - } - out := new(EnvoyServiceTCPKeepalive) - in.DeepCopyInto(out) - 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 - } - if in.Zipkin != nil { - in, out := &in.Zipkin, &out.Zipkin - *out = new(ExtensionProviderZipkinTracingConfig) - (*in).DeepCopyInto(*out) - } - if in.Opentelemetry != nil { - in, out := &in.Opentelemetry, &out.Opentelemetry - *out = new(ExtensionProviderOtelTracingConfig) - (*in).DeepCopyInto(*out) - } - if in.EnvoyOtelAls != nil { - in, out := &in.EnvoyOtelAls, &out.EnvoyOtelAls - *out = new(ExtensionProviderEnvoyOtelLogConfig) - (*in).DeepCopyInto(*out) - } - if in.EnvoyExtAuthzHTTP != nil { - in, out := &in.EnvoyExtAuthzHTTP, &out.EnvoyExtAuthzHTTP - *out = new(ExtensionProviderEnvoyExternalAuthorizationHTTPConfig) - (*in).DeepCopyInto(*out) - } - if in.EnvoyExtAuthzGRPC != nil { - in, out := &in.EnvoyExtAuthzGRPC, &out.EnvoyExtAuthzGRPC - *out = new(ExtensionProviderEnvoyExternalAuthorizationGRPCConfig) - (*in).DeepCopyInto(*out) - } -} - -// 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 *ExtensionProviderEnvoyExternalAuthorizationGRPCConfig) DeepCopyInto(out *ExtensionProviderEnvoyExternalAuthorizationGRPCConfig) { - *out = *in - if in.Timeout != nil { - in, out := &in.Timeout, &out.Timeout - *out = new(string) - **out = **in - } - if in.FailOpen != nil { - in, out := &in.FailOpen, &out.FailOpen - *out = new(bool) - **out = **in - } - if in.StatusOnError != nil { - in, out := &in.StatusOnError, &out.StatusOnError - *out = new(string) - **out = **in - } - if in.IncludeRequestBodyInCheck != nil { - in, out := &in.IncludeRequestBodyInCheck, &out.IncludeRequestBodyInCheck - *out = new(ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderEnvoyExternalAuthorizationGRPCConfig. -func (in *ExtensionProviderEnvoyExternalAuthorizationGRPCConfig) DeepCopy() *ExtensionProviderEnvoyExternalAuthorizationGRPCConfig { - if in == nil { - return nil - } - out := new(ExtensionProviderEnvoyExternalAuthorizationGRPCConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExtensionProviderEnvoyExternalAuthorizationHTTPConfig) DeepCopyInto(out *ExtensionProviderEnvoyExternalAuthorizationHTTPConfig) { - *out = *in - if in.Timeout != nil { - in, out := &in.Timeout, &out.Timeout - *out = new(string) - **out = **in - } - if in.PathPrefix != nil { - in, out := &in.PathPrefix, &out.PathPrefix - *out = new(string) - **out = **in - } - if in.FailOpen != nil { - in, out := &in.FailOpen, &out.FailOpen - *out = new(bool) - **out = **in - } - if in.StatusOnError != nil { - in, out := &in.StatusOnError, &out.StatusOnError - *out = new(string) - **out = **in - } - if in.IncludeRequestHeadersInCheck != nil { - in, out := &in.IncludeRequestHeadersInCheck, &out.IncludeRequestHeadersInCheck - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.IncludeAdditionalHeadersInCheck != nil { - in, out := &in.IncludeAdditionalHeadersInCheck, &out.IncludeAdditionalHeadersInCheck - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.IncludeRequestBodyInCheck != nil { - in, out := &in.IncludeRequestBodyInCheck, &out.IncludeRequestBodyInCheck - *out = new(ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig) - (*in).DeepCopyInto(*out) - } - if in.HeadersToUpstreamOnAllow != nil { - in, out := &in.HeadersToUpstreamOnAllow, &out.HeadersToUpstreamOnAllow - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.HeadersToDownstreamOnDeny != nil { - in, out := &in.HeadersToDownstreamOnDeny, &out.HeadersToDownstreamOnDeny - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.HeadersToDownstreamOnAllow != nil { - in, out := &in.HeadersToDownstreamOnAllow, &out.HeadersToDownstreamOnAllow - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderEnvoyExternalAuthorizationHTTPConfig. -func (in *ExtensionProviderEnvoyExternalAuthorizationHTTPConfig) DeepCopy() *ExtensionProviderEnvoyExternalAuthorizationHTTPConfig { - if in == nil { - return nil - } - out := new(ExtensionProviderEnvoyExternalAuthorizationHTTPConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig) DeepCopyInto(out *ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig) { - *out = *in - if in.MaxRequestBytes != nil { - in, out := &in.MaxRequestBytes, &out.MaxRequestBytes - *out = new(int64) - **out = **in - } - if in.AllowPartialMessage != nil { - in, out := &in.AllowPartialMessage, &out.AllowPartialMessage - *out = new(bool) - **out = **in - } - if in.PackAsBytes != nil { - in, out := &in.PackAsBytes, &out.PackAsBytes - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig. -func (in *ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig) DeepCopy() *ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig { - if in == nil { - return nil - } - out := new(ExtensionProviderEnvoyExternalAuthorizationRequestBodyConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExtensionProviderEnvoyOtelLogConfig) DeepCopyInto(out *ExtensionProviderEnvoyOtelLogConfig) { - *out = *in - if in.LogName != nil { - in, out := &in.LogName, &out.LogName - *out = new(string) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderEnvoyOtelLogConfig. -func (in *ExtensionProviderEnvoyOtelLogConfig) DeepCopy() *ExtensionProviderEnvoyOtelLogConfig { - if in == nil { - return nil - } - out := new(ExtensionProviderEnvoyOtelLogConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExtensionProviderOtelTracingConfig) DeepCopyInto(out *ExtensionProviderOtelTracingConfig) { - *out = *in - if in.MaxTagLength != nil { - in, out := &in.MaxTagLength, &out.MaxTagLength - *out = new(int64) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderOtelTracingConfig. -func (in *ExtensionProviderOtelTracingConfig) DeepCopy() *ExtensionProviderOtelTracingConfig { - if in == nil { - return nil - } - out := new(ExtensionProviderOtelTracingConfig) - 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 -} - -// 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 *ExtensionProviderZipkinTracingConfig) DeepCopyInto(out *ExtensionProviderZipkinTracingConfig) { - *out = *in - if in.MaxTagLength != nil { - in, out := &in.MaxTagLength, &out.MaxTagLength - *out = new(int64) - **out = **in - } - if in.Enable64bitTraceID != nil { - in, out := &in.Enable64bitTraceID, &out.Enable64bitTraceID - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtensionProviderZipkinTracingConfig. -func (in *ExtensionProviderZipkinTracingConfig) DeepCopy() *ExtensionProviderZipkinTracingConfig { - if in == nil { - return nil - } - out := new(ExtensionProviderZipkinTracingConfig) - 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 - in.Enablement.DeepCopyInto(&out.Enablement) - in.Service.DeepCopyInto(&out.Service) - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]VolumeConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Runtime != nil { - in, out := &in.Runtime, &out.Runtime - *out = new(ComponentRuntimeConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayConfig. -func (in *GatewayConfig) DeepCopy() *GatewayConfig { - if in == nil { - return nil - } - out := new(GatewayConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayServiceConfig) DeepCopyInto(out *GatewayServiceConfig) { - *out = *in - in.ServiceSpec.DeepCopyInto(&out.ServiceSpec) - if in.Metadata != nil { - in, out := &in.Metadata, &out.Metadata - *out = new(MetadataConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayServiceConfig. -func (in *GatewayServiceConfig) DeepCopy() *GatewayServiceConfig { - if in == nil { - return nil - } - out := new(GatewayServiceConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayVolume) DeepCopyInto(out *GatewayVolume) { - *out = *in - if in.ConfigMap != nil { - in, out := &in.ConfigMap, &out.ConfigMap - *out = new(v1.ConfigMapVolumeSource) - (*in).DeepCopyInto(*out) - } - if in.Secret != nil { - in, out := &in.Secret, &out.Secret - *out = new(v1.SecretVolumeSource) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayVolume. -func (in *GatewayVolume) DeepCopy() *GatewayVolume { - if in == nil { - return nil - } - out := new(GatewayVolume) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewaysConfig) DeepCopyInto(out *GatewaysConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.ClusterIngress != nil { - in, out := &in.ClusterIngress, &out.ClusterIngress - *out = new(ClusterIngressGatewayConfig) - (*in).DeepCopyInto(*out) - } - if in.ClusterEgress != nil { - in, out := &in.ClusterEgress, &out.ClusterEgress - *out = new(EgressGatewayConfig) - (*in).DeepCopyInto(*out) - } - if in.IngressGateways != nil { - in, out := &in.IngressGateways, &out.IngressGateways - *out = make(map[string]*IngressGatewayConfig, len(*in)) - for key, val := range *in { - var outVal *IngressGatewayConfig - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = new(IngressGatewayConfig) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } - } - if in.EgressGateways != nil { - in, out := &in.EgressGateways, &out.EgressGateways - *out = make(map[string]*EgressGatewayConfig, len(*in)) - for key, val := range *in { - var outVal *EgressGatewayConfig - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = new(EgressGatewayConfig) - (*in).DeepCopyInto(*out) - } - (*out)[key] = outVal - } - } - if in.OpenShiftRoute != nil { - in, out := &in.OpenShiftRoute, &out.OpenShiftRoute - *out = new(OpenShiftRouteConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewaysConfig. -func (in *GatewaysConfig) DeepCopy() *GatewaysConfig { - if in == nil { - return nil - } - out := new(GatewaysConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GeneralConfig) DeepCopyInto(out *GeneralConfig) { - *out = *in - if in.Logging != nil { - in, out := &in.Logging, &out.Logging - *out = new(LoggingConfig) - (*in).DeepCopyInto(*out) - } - if in.ValidationMessages != nil { - in, out := &in.ValidationMessages, &out.ValidationMessages - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GeneralConfig. -func (in *GeneralConfig) DeepCopy() *GeneralConfig { - if in == nil { - return nil - } - out := new(GeneralConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GrafanaAddonConfig) DeepCopyInto(out *GrafanaAddonConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Install != nil { - in, out := &in.Install, &out.Install - *out = new(GrafanaInstallConfig) - (*in).DeepCopyInto(*out) - } - if in.Address != nil { - in, out := &in.Address, &out.Address - *out = new(string) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaAddonConfig. -func (in *GrafanaAddonConfig) DeepCopy() *GrafanaAddonConfig { - if in == nil { - return nil - } - out := new(GrafanaAddonConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GrafanaConfig) DeepCopyInto(out *GrafanaConfig) { - *out = *in - if in.Env != nil { - in, out := &in.Env, &out.Env - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.EnvSecrets != nil { - in, out := &in.EnvSecrets, &out.EnvSecrets - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaConfig. -func (in *GrafanaConfig) DeepCopy() *GrafanaConfig { - if in == nil { - return nil - } - out := new(GrafanaConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GrafanaInstallConfig) DeepCopyInto(out *GrafanaInstallConfig) { - *out = *in - if in.Config != nil { - in, out := &in.Config, &out.Config - *out = new(GrafanaConfig) - (*in).DeepCopyInto(*out) - } - if in.Service != nil { - in, out := &in.Service, &out.Service - *out = new(ComponentServiceConfig) - (*in).DeepCopyInto(*out) - } - if in.Persistence != nil { - in, out := &in.Persistence, &out.Persistence - *out = new(ComponentPersistenceConfig) - (*in).DeepCopyInto(*out) - } - if in.Security != nil { - in, out := &in.Security, &out.Security - *out = new(GrafanaSecurityConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaInstallConfig. -func (in *GrafanaInstallConfig) DeepCopy() *GrafanaInstallConfig { - if in == nil { - return nil - } - out := new(GrafanaInstallConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GrafanaSecurityConfig) DeepCopyInto(out *GrafanaSecurityConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GrafanaSecurityConfig. -func (in *GrafanaSecurityConfig) DeepCopy() *GrafanaSecurityConfig { - if in == nil { - return nil - } - out := new(GrafanaSecurityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IdentityConfig) DeepCopyInto(out *IdentityConfig) { - *out = *in - if in.ThirdParty != nil { - in, out := &in.ThirdParty, &out.ThirdParty - *out = new(ThirdPartyIdentityConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IdentityConfig. -func (in *IdentityConfig) DeepCopy() *IdentityConfig { - if in == nil { - return nil - } - out := new(IdentityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IngressGatewayConfig) DeepCopyInto(out *IngressGatewayConfig) { - *out = *in - in.GatewayConfig.DeepCopyInto(&out.GatewayConfig) - if in.SDS != nil { - in, out := &in.SDS, &out.SDS - *out = new(SecretDiscoveryService) - (*in).DeepCopyInto(*out) - } - if in.RouteConfig != nil { - in, out := &in.RouteConfig, &out.RouteConfig - *out = new(Enablement) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IngressGatewayConfig. -func (in *IngressGatewayConfig) DeepCopy() *IngressGatewayConfig { - if in == nil { - return nil - } - out := new(IngressGatewayConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IstioPrivateKeyCertificateSignerConfig) DeepCopyInto(out *IstioPrivateKeyCertificateSignerConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IstioPrivateKeyCertificateSignerConfig. -func (in *IstioPrivateKeyCertificateSignerConfig) DeepCopy() *IstioPrivateKeyCertificateSignerConfig { - if in == nil { - return nil - } - out := new(IstioPrivateKeyCertificateSignerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IstioSelfSignedCertificateSignerConfig) DeepCopyInto(out *IstioSelfSignedCertificateSignerConfig) { - *out = *in - if in.EnableJitter != nil { - in, out := &in.EnableJitter, &out.EnableJitter - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IstioSelfSignedCertificateSignerConfig. -func (in *IstioSelfSignedCertificateSignerConfig) DeepCopy() *IstioSelfSignedCertificateSignerConfig { - if in == nil { - return nil - } - out := new(IstioSelfSignedCertificateSignerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IstiodCertificateAuthorityConfig) DeepCopyInto(out *IstiodCertificateAuthorityConfig) { - *out = *in - if in.SelfSigned != nil { - in, out := &in.SelfSigned, &out.SelfSigned - *out = new(IstioSelfSignedCertificateSignerConfig) - (*in).DeepCopyInto(*out) - } - if in.PrivateKey != nil { - in, out := &in.PrivateKey, &out.PrivateKey - *out = new(IstioPrivateKeyCertificateSignerConfig) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IstiodCertificateAuthorityConfig. -func (in *IstiodCertificateAuthorityConfig) DeepCopy() *IstiodCertificateAuthorityConfig { - if in == nil { - return nil - } - out := new(IstiodCertificateAuthorityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JaegerAddonConfig) DeepCopyInto(out *JaegerAddonConfig) { - *out = *in - if in.Install != nil { - in, out := &in.Install, &out.Install - *out = new(JaegerInstallConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JaegerAddonConfig. -func (in *JaegerAddonConfig) DeepCopy() *JaegerAddonConfig { - if in == nil { - return nil - } - out := new(JaegerAddonConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JaegerElasticsearchStorageConfig) DeepCopyInto(out *JaegerElasticsearchStorageConfig) { - *out = *in - if in.NodeCount != nil { - in, out := &in.NodeCount, &out.NodeCount - *out = new(int32) - **out = **in - } - if in.Storage != nil { - in, out := &in.Storage, &out.Storage - *out = (*in).DeepCopy() - } - if in.IndexCleaner != nil { - in, out := &in.IndexCleaner, &out.IndexCleaner - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JaegerElasticsearchStorageConfig. -func (in *JaegerElasticsearchStorageConfig) DeepCopy() *JaegerElasticsearchStorageConfig { - if in == nil { - return nil - } - out := new(JaegerElasticsearchStorageConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JaegerIngressConfig) DeepCopyInto(out *JaegerIngressConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Metadata != nil { - in, out := &in.Metadata, &out.Metadata - *out = new(MetadataConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JaegerIngressConfig. -func (in *JaegerIngressConfig) DeepCopy() *JaegerIngressConfig { - if in == nil { - return nil - } - out := new(JaegerIngressConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JaegerInstallConfig) DeepCopyInto(out *JaegerInstallConfig) { - *out = *in - if in.Storage != nil { - in, out := &in.Storage, &out.Storage - *out = new(JaegerStorageConfig) - (*in).DeepCopyInto(*out) - } - if in.Ingress != nil { - in, out := &in.Ingress, &out.Ingress - *out = new(JaegerIngressConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JaegerInstallConfig. -func (in *JaegerInstallConfig) DeepCopy() *JaegerInstallConfig { - if in == nil { - return nil - } - out := new(JaegerInstallConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JaegerMemoryStorageConfig) DeepCopyInto(out *JaegerMemoryStorageConfig) { - *out = *in - if in.MaxTraces != nil { - in, out := &in.MaxTraces, &out.MaxTraces - *out = new(int64) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JaegerMemoryStorageConfig. -func (in *JaegerMemoryStorageConfig) DeepCopy() *JaegerMemoryStorageConfig { - if in == nil { - return nil - } - out := new(JaegerMemoryStorageConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *JaegerStorageConfig) DeepCopyInto(out *JaegerStorageConfig) { - *out = *in - if in.Memory != nil { - in, out := &in.Memory, &out.Memory - *out = new(JaegerMemoryStorageConfig) - (*in).DeepCopyInto(*out) - } - if in.Elasticsearch != nil { - in, out := &in.Elasticsearch, &out.Elasticsearch - *out = new(JaegerElasticsearchStorageConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JaegerStorageConfig. -func (in *JaegerStorageConfig) DeepCopy() *JaegerStorageConfig { - if in == nil { - return nil - } - out := new(JaegerStorageConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KialiAddonConfig) DeepCopyInto(out *KialiAddonConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Install != nil { - in, out := &in.Install, &out.Install - *out = new(KialiInstallConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KialiAddonConfig. -func (in *KialiAddonConfig) DeepCopy() *KialiAddonConfig { - if in == nil { - return nil - } - out := new(KialiAddonConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KialiDashboardConfig) DeepCopyInto(out *KialiDashboardConfig) { - *out = *in - if in.ViewOnly != nil { - in, out := &in.ViewOnly, &out.ViewOnly - *out = new(bool) - **out = **in - } - if in.EnableGrafana != nil { - in, out := &in.EnableGrafana, &out.EnableGrafana - *out = new(bool) - **out = **in - } - if in.EnablePrometheus != nil { - in, out := &in.EnablePrometheus, &out.EnablePrometheus - *out = new(bool) - **out = **in - } - if in.EnableTracing != nil { - in, out := &in.EnableTracing, &out.EnableTracing - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KialiDashboardConfig. -func (in *KialiDashboardConfig) DeepCopy() *KialiDashboardConfig { - if in == nil { - return nil - } - out := new(KialiDashboardConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KialiDeploymentConfig) DeepCopyInto(out *KialiDeploymentConfig) { - *out = *in - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = new(v1.ResourceRequirements) - (*in).DeepCopyInto(*out) - } - if in.Affinity != nil { - in, out := &in.Affinity, &out.Affinity - *out = new(v1.Affinity) - (*in).DeepCopyInto(*out) - } - if in.NodeSelector != nil { - in, out := &in.NodeSelector, &out.NodeSelector - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Tolerations != nil { - in, out := &in.Tolerations, &out.Tolerations - *out = make([]v1.Toleration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KialiDeploymentConfig. -func (in *KialiDeploymentConfig) DeepCopy() *KialiDeploymentConfig { - if in == nil { - return nil - } - out := new(KialiDeploymentConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KialiInstallConfig) DeepCopyInto(out *KialiInstallConfig) { - *out = *in - if in.Dashboard != nil { - in, out := &in.Dashboard, &out.Dashboard - *out = new(KialiDashboardConfig) - (*in).DeepCopyInto(*out) - } - if in.Service != nil { - in, out := &in.Service, &out.Service - *out = new(ComponentServiceConfig) - (*in).DeepCopyInto(*out) - } - if in.Deployment != nil { - in, out := &in.Deployment, &out.Deployment - *out = new(KialiDeploymentConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KialiInstallConfig. -func (in *KialiInstallConfig) DeepCopy() *KialiInstallConfig { - if in == nil { - return nil - } - out := new(KialiInstallConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LightstepTracerConfig) DeepCopyInto(out *LightstepTracerConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LightstepTracerConfig. -func (in *LightstepTracerConfig) DeepCopy() *LightstepTracerConfig { - if in == nil { - return nil - } - out := new(LightstepTracerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *LoggingConfig) DeepCopyInto(out *LoggingConfig) { - *out = *in - if in.ComponentLevels != nil { - in, out := &in.ComponentLevels, &out.ComponentLevels - *out = make(ComponentLogLevels, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.LogAsJSON != nil { - in, out := &in.LogAsJSON, &out.LogAsJSON - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoggingConfig. -func (in *LoggingConfig) DeepCopy() *LoggingConfig { - if in == nil { - return nil - } - out := new(LoggingConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MeshConfig) DeepCopyInto(out *MeshConfig) { - *out = *in - 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.DiscoverySelectors != nil { - in, out := &in.DiscoverySelectors, &out.DiscoverySelectors - *out = make([]*metav1.LabelSelector, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(metav1.LabelSelector) - (*in).DeepCopyInto(*out) - } - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshConfig. -func (in *MeshConfig) DeepCopy() *MeshConfig { - if in == nil { - return nil - } - out := new(MeshConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MeshEndpointConfig) DeepCopyInto(out *MeshEndpointConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshEndpointConfig. -func (in *MeshEndpointConfig) DeepCopy() *MeshEndpointConfig { - if in == nil { - return nil - } - out := new(MeshEndpointConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MeshExpansionConfig) DeepCopyInto(out *MeshExpansionConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.ILBGateway != nil { - in, out := &in.ILBGateway, &out.ILBGateway - *out = new(GatewayConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshExpansionConfig. -func (in *MeshExpansionConfig) DeepCopy() *MeshExpansionConfig { - if in == nil { - return nil - } - out := new(MeshExpansionConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MeshGatewayConfig) DeepCopyInto(out *MeshGatewayConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshGatewayConfig. -func (in *MeshGatewayConfig) DeepCopy() *MeshGatewayConfig { - if in == nil { - return nil - } - out := new(MeshGatewayConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MeshNetworkConfig) DeepCopyInto(out *MeshNetworkConfig) { - *out = *in - if in.Endpoints != nil { - in, out := &in.Endpoints, &out.Endpoints - *out = make([]MeshEndpointConfig, len(*in)) - copy(*out, *in) - } - if in.Gateways != nil { - in, out := &in.Gateways, &out.Gateways - *out = make([]MeshGatewayConfig, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshNetworkConfig. -func (in *MeshNetworkConfig) DeepCopy() *MeshNetworkConfig { - if in == nil { - return nil - } - out := new(MeshNetworkConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetadataConfig) DeepCopyInto(out *MetadataConfig) { - *out = *in - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetadataConfig. -func (in *MetadataConfig) DeepCopy() *MetadataConfig { - if in == nil { - return nil - } - out := new(MetadataConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MixerPolicyAdaptersConfig) DeepCopyInto(out *MixerPolicyAdaptersConfig) { - *out = *in - if in.UseAdapterCRDs != nil { - in, out := &in.UseAdapterCRDs, &out.UseAdapterCRDs - *out = new(bool) - **out = **in - } - if in.KubernetesEnv != nil { - in, out := &in.KubernetesEnv, &out.KubernetesEnv - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MixerPolicyAdaptersConfig. -func (in *MixerPolicyAdaptersConfig) DeepCopy() *MixerPolicyAdaptersConfig { - if in == nil { - return nil - } - out := new(MixerPolicyAdaptersConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MixerPolicyConfig) DeepCopyInto(out *MixerPolicyConfig) { - *out = *in - if in.EnableChecks != nil { - in, out := &in.EnableChecks, &out.EnableChecks - *out = new(bool) - **out = **in - } - if in.FailOpen != nil { - in, out := &in.FailOpen, &out.FailOpen - *out = new(bool) - **out = **in - } - if in.SessionAffinity != nil { - in, out := &in.SessionAffinity, &out.SessionAffinity - *out = new(bool) - **out = **in - } - if in.Adapters != nil { - in, out := &in.Adapters, &out.Adapters - *out = new(MixerPolicyAdaptersConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MixerPolicyConfig. -func (in *MixerPolicyConfig) DeepCopy() *MixerPolicyConfig { - if in == nil { - return nil - } - out := new(MixerPolicyConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MixerTelemetryAdaptersConfig) DeepCopyInto(out *MixerTelemetryAdaptersConfig) { - *out = *in - if in.UseAdapterCRDs != nil { - in, out := &in.UseAdapterCRDs, &out.UseAdapterCRDs - *out = new(bool) - **out = **in - } - if in.KubernetesEnv != nil { - in, out := &in.KubernetesEnv, &out.KubernetesEnv - *out = new(bool) - **out = **in - } - if in.Stdio != nil { - in, out := &in.Stdio, &out.Stdio - *out = new(MixerTelemetryStdioConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MixerTelemetryAdaptersConfig. -func (in *MixerTelemetryAdaptersConfig) DeepCopy() *MixerTelemetryAdaptersConfig { - if in == nil { - return nil - } - out := new(MixerTelemetryAdaptersConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MixerTelemetryConfig) DeepCopyInto(out *MixerTelemetryConfig) { - *out = *in - if in.SessionAffinity != nil { - in, out := &in.SessionAffinity, &out.SessionAffinity - *out = new(bool) - **out = **in - } - if in.Loadshedding != nil { - in, out := &in.Loadshedding, &out.Loadshedding - *out = new(TelemetryLoadSheddingConfig) - **out = **in - } - if in.Batching != nil { - in, out := &in.Batching, &out.Batching - *out = new(TelemetryBatchingConfig) - (*in).DeepCopyInto(*out) - } - if in.Adapters != nil { - in, out := &in.Adapters, &out.Adapters - *out = new(MixerTelemetryAdaptersConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MixerTelemetryConfig. -func (in *MixerTelemetryConfig) DeepCopy() *MixerTelemetryConfig { - if in == nil { - return nil - } - out := new(MixerTelemetryConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MixerTelemetryStdioConfig) DeepCopyInto(out *MixerTelemetryStdioConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.OutputAsJSON != nil { - in, out := &in.OutputAsJSON, &out.OutputAsJSON - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MixerTelemetryStdioConfig. -func (in *MixerTelemetryStdioConfig) DeepCopy() *MixerTelemetryStdioConfig { - if in == nil { - return nil - } - out := new(MixerTelemetryStdioConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MultiClusterConfig) DeepCopyInto(out *MultiClusterConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.MeshNetworks != nil { - in, out := &in.MeshNetworks, &out.MeshNetworks - *out = make(map[string]MeshNetworkConfig, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MultiClusterConfig. -func (in *MultiClusterConfig) DeepCopy() *MultiClusterConfig { - if in == nil { - return nil - } - out := new(MultiClusterConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *OpenShiftRouteConfig) DeepCopyInto(out *OpenShiftRouteConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenShiftRouteConfig. -func (in *OpenShiftRouteConfig) DeepCopy() *OpenShiftRouteConfig { - if in == nil { - return nil - } - out := new(OpenShiftRouteConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodAntiAffinity) DeepCopyInto(out *PodAntiAffinity) { - *out = *in - if in.PodAntiAffinity != nil { - in, out := &in.PodAntiAffinity, &out.PodAntiAffinity - *out = new(v1.PodAntiAffinity) - (*in).DeepCopyInto(*out) - } - if in.RequiredDuringScheduling != nil { - in, out := &in.RequiredDuringScheduling, &out.RequiredDuringScheduling - *out = make([]PodAntiAffinityTerm, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.PreferredDuringScheduling != nil { - in, out := &in.PreferredDuringScheduling, &out.PreferredDuringScheduling - *out = make([]PodAntiAffinityTerm, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodAntiAffinity. -func (in *PodAntiAffinity) DeepCopy() *PodAntiAffinity { - if in == nil { - return nil - } - out := new(PodAntiAffinity) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodAntiAffinityTerm) DeepCopyInto(out *PodAntiAffinityTerm) { - *out = *in - in.LabelSelectorRequirement.DeepCopyInto(&out.LabelSelectorRequirement) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodAntiAffinityTerm. -func (in *PodAntiAffinityTerm) DeepCopy() *PodAntiAffinityTerm { - if in == nil { - return nil - } - out := new(PodAntiAffinityTerm) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodDisruptionBudget) DeepCopyInto(out *PodDisruptionBudget) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.MinAvailable != nil { - in, out := &in.MinAvailable, &out.MinAvailable - *out = new(intstr.IntOrString) - **out = **in - } - if in.MaxUnavailable != nil { - in, out := &in.MaxUnavailable, &out.MaxUnavailable - *out = new(intstr.IntOrString) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodDisruptionBudget. -func (in *PodDisruptionBudget) DeepCopy() *PodDisruptionBudget { - if in == nil { - return nil - } - out := new(PodDisruptionBudget) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodRuntimeConfig) DeepCopyInto(out *PodRuntimeConfig) { - *out = *in - in.CommonPodRuntimeConfig.DeepCopyInto(&out.CommonPodRuntimeConfig) - if in.Metadata != nil { - in, out := &in.Metadata, &out.Metadata - *out = new(MetadataConfig) - (*in).DeepCopyInto(*out) - } - if in.Affinity != nil { - in, out := &in.Affinity, &out.Affinity - *out = new(Affinity) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodRuntimeConfig. -func (in *PodRuntimeConfig) DeepCopy() *PodRuntimeConfig { - if in == nil { - return nil - } - out := new(PodRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PolicyConfig) DeepCopyInto(out *PolicyConfig) { - *out = *in - if in.Mixer != nil { - in, out := &in.Mixer, &out.Mixer - *out = new(MixerPolicyConfig) - (*in).DeepCopyInto(*out) - } - if in.Remote != nil { - in, out := &in.Remote, &out.Remote - *out = new(RemotePolicyConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyConfig. -func (in *PolicyConfig) DeepCopy() *PolicyConfig { - if in == nil { - return nil - } - out := new(PolicyConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PrometheusAddonConfig) DeepCopyInto(out *PrometheusAddonConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Scrape != nil { - in, out := &in.Scrape, &out.Scrape - *out = new(bool) - **out = **in - } - if in.Install != nil { - in, out := &in.Install, &out.Install - *out = new(PrometheusInstallConfig) - (*in).DeepCopyInto(*out) - } - if in.Address != nil { - in, out := &in.Address, &out.Address - *out = new(string) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusAddonConfig. -func (in *PrometheusAddonConfig) DeepCopy() *PrometheusAddonConfig { - if in == nil { - return nil - } - out := new(PrometheusAddonConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PrometheusInstallConfig) DeepCopyInto(out *PrometheusInstallConfig) { - *out = *in - if in.Service != nil { - in, out := &in.Service, &out.Service - *out = new(ComponentServiceConfig) - (*in).DeepCopyInto(*out) - } - if in.UseTLS != nil { - in, out := &in.UseTLS, &out.UseTLS - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusInstallConfig. -func (in *PrometheusInstallConfig) DeepCopy() *PrometheusInstallConfig { - if in == nil { - return nil - } - out := new(PrometheusInstallConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyAccessLoggingConfig) DeepCopyInto(out *ProxyAccessLoggingConfig) { - *out = *in - if in.File != nil { - in, out := &in.File, &out.File - *out = new(ProxyFileAccessLogConfig) - **out = **in - } - if in.EnvoyService != nil { - in, out := &in.EnvoyService, &out.EnvoyService - *out = new(ProxyEnvoyServiceConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyAccessLoggingConfig. -func (in *ProxyAccessLoggingConfig) DeepCopy() *ProxyAccessLoggingConfig { - if in == nil { - return nil - } - out := new(ProxyAccessLoggingConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyConfig) DeepCopyInto(out *ProxyConfig) { - *out = *in - if in.Logging != nil { - in, out := &in.Logging, &out.Logging - *out = new(ProxyLoggingConfig) - (*in).DeepCopyInto(*out) - } - if in.Networking != nil { - in, out := &in.Networking, &out.Networking - *out = new(ProxyNetworkingConfig) - (*in).DeepCopyInto(*out) - } - if in.Runtime != nil { - in, out := &in.Runtime, &out.Runtime - *out = new(ProxyRuntimeConfig) - (*in).DeepCopyInto(*out) - } - if in.Injection != nil { - in, out := &in.Injection, &out.Injection - *out = new(ProxyInjectionConfig) - (*in).DeepCopyInto(*out) - } - if in.Concurrency != nil { - in, out := &in.Concurrency, &out.Concurrency - *out = new(int32) - **out = **in - } - if in.AccessLogging != nil { - in, out := &in.AccessLogging, &out.AccessLogging - *out = new(ProxyAccessLoggingConfig) - (*in).DeepCopyInto(*out) - } - if in.EnvoyMetricsService != nil { - in, out := &in.EnvoyMetricsService, &out.EnvoyMetricsService - *out = new(ProxyEnvoyServiceConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyConfig. -func (in *ProxyConfig) DeepCopy() *ProxyConfig { - if in == nil { - return nil - } - out := new(ProxyConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyDNSConfig) DeepCopyInto(out *ProxyDNSConfig) { - *out = *in - if in.SearchSuffixes != nil { - in, out := &in.SearchSuffixes, &out.SearchSuffixes - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyDNSConfig. -func (in *ProxyDNSConfig) DeepCopy() *ProxyDNSConfig { - if in == nil { - return nil - } - out := new(ProxyDNSConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyEnvoyServiceConfig) DeepCopyInto(out *ProxyEnvoyServiceConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.TCPKeepalive != nil { - in, out := &in.TCPKeepalive, &out.TCPKeepalive - *out = new(EnvoyServiceTCPKeepalive) - **out = **in - } - if in.TLSSettings != nil { - in, out := &in.TLSSettings, &out.TLSSettings - *out = new(EnvoyServiceClientTLSSettings) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyEnvoyServiceConfig. -func (in *ProxyEnvoyServiceConfig) DeepCopy() *ProxyEnvoyServiceConfig { - if in == nil { - return nil - } - out := new(ProxyEnvoyServiceConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyFileAccessLogConfig) DeepCopyInto(out *ProxyFileAccessLogConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyFileAccessLogConfig. -func (in *ProxyFileAccessLogConfig) DeepCopy() *ProxyFileAccessLogConfig { - if in == nil { - return nil - } - out := new(ProxyFileAccessLogConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyInboundTrafficControlConfig) DeepCopyInto(out *ProxyInboundTrafficControlConfig) { - *out = *in - if in.IncludedPorts != nil { - in, out := &in.IncludedPorts, &out.IncludedPorts - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ExcludedPorts != nil { - in, out := &in.ExcludedPorts, &out.ExcludedPorts - *out = make([]int32, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyInboundTrafficControlConfig. -func (in *ProxyInboundTrafficControlConfig) DeepCopy() *ProxyInboundTrafficControlConfig { - if in == nil { - return nil - } - out := new(ProxyInboundTrafficControlConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyInitContainerConfig) DeepCopyInto(out *ProxyInitContainerConfig) { - *out = *in - if in.Runtime != nil { - in, out := &in.Runtime, &out.Runtime - *out = new(ContainerConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyInitContainerConfig. -func (in *ProxyInitContainerConfig) DeepCopy() *ProxyInitContainerConfig { - if in == nil { - return nil - } - out := new(ProxyInitContainerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyInjectionConfig) DeepCopyInto(out *ProxyInjectionConfig) { - *out = *in - if in.AutoInject != nil { - in, out := &in.AutoInject, &out.AutoInject - *out = new(bool) - **out = **in - } - if in.AlwaysInjectSelector != nil { - in, out := &in.AlwaysInjectSelector, &out.AlwaysInjectSelector - *out = make([]metav1.LabelSelector, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.NeverInjectSelector != nil { - in, out := &in.NeverInjectSelector, &out.NeverInjectSelector - *out = make([]metav1.LabelSelector, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.InjectedAnnotations != nil { - in, out := &in.InjectedAnnotations, &out.InjectedAnnotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyInjectionConfig. -func (in *ProxyInjectionConfig) DeepCopy() *ProxyInjectionConfig { - if in == nil { - return nil - } - out := new(ProxyInjectionConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyLoggingConfig) DeepCopyInto(out *ProxyLoggingConfig) { - *out = *in - if in.ComponentLevels != nil { - in, out := &in.ComponentLevels, &out.ComponentLevels - *out = make(ComponentLogLevels, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyLoggingConfig. -func (in *ProxyLoggingConfig) DeepCopy() *ProxyLoggingConfig { - if in == nil { - return nil - } - out := new(ProxyLoggingConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyNetworkAutoProtocolDetectionConfig) DeepCopyInto(out *ProxyNetworkAutoProtocolDetectionConfig) { - *out = *in - if in.Inbound != nil { - in, out := &in.Inbound, &out.Inbound - *out = new(bool) - **out = **in - } - if in.Outbound != nil { - in, out := &in.Outbound, &out.Outbound - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyNetworkAutoProtocolDetectionConfig. -func (in *ProxyNetworkAutoProtocolDetectionConfig) DeepCopy() *ProxyNetworkAutoProtocolDetectionConfig { - if in == nil { - return nil - } - out := new(ProxyNetworkAutoProtocolDetectionConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyNetworkInitConfig) DeepCopyInto(out *ProxyNetworkInitConfig) { - *out = *in - if in.InitContainer != nil { - in, out := &in.InitContainer, &out.InitContainer - *out = new(ProxyInitContainerConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyNetworkInitConfig. -func (in *ProxyNetworkInitConfig) DeepCopy() *ProxyNetworkInitConfig { - if in == nil { - return nil - } - out := new(ProxyNetworkInitConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyNetworkProtocolConfig) DeepCopyInto(out *ProxyNetworkProtocolConfig) { - *out = *in - if in.AutoDetect != nil { - in, out := &in.AutoDetect, &out.AutoDetect - *out = new(ProxyNetworkAutoProtocolDetectionConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyNetworkProtocolConfig. -func (in *ProxyNetworkProtocolConfig) DeepCopy() *ProxyNetworkProtocolConfig { - if in == nil { - return nil - } - out := new(ProxyNetworkProtocolConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyNetworkingConfig) DeepCopyInto(out *ProxyNetworkingConfig) { - *out = *in - if in.Initialization != nil { - in, out := &in.Initialization, &out.Initialization - *out = new(ProxyNetworkInitConfig) - (*in).DeepCopyInto(*out) - } - if in.TrafficControl != nil { - in, out := &in.TrafficControl, &out.TrafficControl - *out = new(ProxyTrafficControlConfig) - (*in).DeepCopyInto(*out) - } - if in.Protocol != nil { - in, out := &in.Protocol, &out.Protocol - *out = new(ProxyNetworkProtocolConfig) - (*in).DeepCopyInto(*out) - } - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(ProxyDNSConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyNetworkingConfig. -func (in *ProxyNetworkingConfig) DeepCopy() *ProxyNetworkingConfig { - if in == nil { - return nil - } - out := new(ProxyNetworkingConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyOutboundTrafficControlConfig) DeepCopyInto(out *ProxyOutboundTrafficControlConfig) { - *out = *in - if in.IncludedIPRanges != nil { - in, out := &in.IncludedIPRanges, &out.IncludedIPRanges - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ExcludedIPRanges != nil { - in, out := &in.ExcludedIPRanges, &out.ExcludedIPRanges - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ExcludedPorts != nil { - in, out := &in.ExcludedPorts, &out.ExcludedPorts - *out = make([]int32, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyOutboundTrafficControlConfig. -func (in *ProxyOutboundTrafficControlConfig) DeepCopy() *ProxyOutboundTrafficControlConfig { - if in == nil { - return nil - } - out := new(ProxyOutboundTrafficControlConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyReadinessConfig) DeepCopyInto(out *ProxyReadinessConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyReadinessConfig. -func (in *ProxyReadinessConfig) DeepCopy() *ProxyReadinessConfig { - if in == nil { - return nil - } - out := new(ProxyReadinessConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyRuntimeConfig) DeepCopyInto(out *ProxyRuntimeConfig) { - *out = *in - if in.Readiness != nil { - in, out := &in.Readiness, &out.Readiness - *out = new(ProxyReadinessConfig) - **out = **in - } - if in.Container != nil { - in, out := &in.Container, &out.Container - *out = new(ContainerConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyRuntimeConfig. -func (in *ProxyRuntimeConfig) DeepCopy() *ProxyRuntimeConfig { - if in == nil { - return nil - } - out := new(ProxyRuntimeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProxyTrafficControlConfig) DeepCopyInto(out *ProxyTrafficControlConfig) { - *out = *in - in.Inbound.DeepCopyInto(&out.Inbound) - in.Outbound.DeepCopyInto(&out.Outbound) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyTrafficControlConfig. -func (in *ProxyTrafficControlConfig) DeepCopy() *ProxyTrafficControlConfig { - if in == nil { - return nil - } - out := new(ProxyTrafficControlConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in ReadinessMap) DeepCopyInto(out *ReadinessMap) { - { - in := &in - *out = make(ReadinessMap, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) - } - (*out)[key] = outVal - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadinessMap. -func (in ReadinessMap) DeepCopy() ReadinessMap { - if in == nil { - return nil - } - out := new(ReadinessMap) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ReadinessStatus) DeepCopyInto(out *ReadinessStatus) { - *out = *in - if in.Components != nil { - in, out := &in.Components, &out.Components - *out = make(ReadinessMap, len(*in)) - for key, val := range *in { - var outVal []string - if val == nil { - (*out)[key] = nil - } else { - inVal := (*in)[key] - in, out := &inVal, &outVal - *out = make([]string, len(*in)) - copy(*out, *in) - } - (*out)[key] = outVal - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadinessStatus. -func (in *ReadinessStatus) DeepCopy() *ReadinessStatus { - if in == nil { - return nil - } - out := new(ReadinessStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RemotePolicyConfig) DeepCopyInto(out *RemotePolicyConfig) { - *out = *in - if in.CreateService != nil { - in, out := &in.CreateService, &out.CreateService - *out = new(bool) - **out = **in - } - if in.EnableChecks != nil { - in, out := &in.EnableChecks, &out.EnableChecks - *out = new(bool) - **out = **in - } - if in.FailOpen != nil { - in, out := &in.FailOpen, &out.FailOpen - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemotePolicyConfig. -func (in *RemotePolicyConfig) DeepCopy() *RemotePolicyConfig { - if in == nil { - return nil - } - out := new(RemotePolicyConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RemoteTelemetryConfig) DeepCopyInto(out *RemoteTelemetryConfig) { - *out = *in - if in.CreateService != nil { - in, out := &in.CreateService, &out.CreateService - *out = new(bool) - **out = **in - } - if in.Batching != nil { - in, out := &in.Batching, &out.Batching - *out = new(TelemetryBatchingConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RemoteTelemetryConfig. -func (in *RemoteTelemetryConfig) DeepCopy() *RemoteTelemetryConfig { - if in == nil { - return nil - } - out := new(RemoteTelemetryConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecretDiscoveryService) DeepCopyInto(out *SecretDiscoveryService) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Runtime != nil { - in, out := &in.Runtime, &out.Runtime - *out = new(ContainerConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretDiscoveryService. -func (in *SecretDiscoveryService) DeepCopy() *SecretDiscoveryService { - if in == nil { - return nil - } - out := new(SecretDiscoveryService) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SecurityConfig) DeepCopyInto(out *SecurityConfig) { - *out = *in - if in.Trust != nil { - in, out := &in.Trust, &out.Trust - *out = new(TrustConfig) - (*in).DeepCopyInto(*out) - } - if in.CertificateAuthority != nil { - in, out := &in.CertificateAuthority, &out.CertificateAuthority - *out = new(CertificateAuthorityConfig) - (*in).DeepCopyInto(*out) - } - if in.Identity != nil { - in, out := &in.Identity, &out.Identity - *out = new(IdentityConfig) - (*in).DeepCopyInto(*out) - } - if in.ControlPlane != nil { - in, out := &in.ControlPlane, &out.ControlPlane - *out = new(ControlPlaneSecurityConfig) - (*in).DeepCopyInto(*out) - } - if in.DataPlane != nil { - in, out := &in.DataPlane, &out.DataPlane - *out = new(DataPlaneSecurityConfig) - (*in).DeepCopyInto(*out) - } - if in.ManageNetworkPolicy != nil { - in, out := &in.ManageNetworkPolicy, &out.ManageNetworkPolicy - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecurityConfig. -func (in *SecurityConfig) DeepCopy() *SecurityConfig { - if in == nil { - return nil - } - out := new(SecurityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshControlPlane) DeepCopyInto(out *ServiceMeshControlPlane) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshControlPlane. -func (in *ServiceMeshControlPlane) DeepCopy() *ServiceMeshControlPlane { - if in == nil { - return nil - } - out := new(ServiceMeshControlPlane) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshControlPlane) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceMeshControlPlaneList) DeepCopyInto(out *ServiceMeshControlPlaneList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]ServiceMeshControlPlane, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceMeshControlPlaneList. -func (in *ServiceMeshControlPlaneList) DeepCopy() *ServiceMeshControlPlaneList { - if in == nil { - return nil - } - out := new(ServiceMeshControlPlaneList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ServiceMeshControlPlaneList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackdriverAccessLogTelemetryConfig) DeepCopyInto(out *StackdriverAccessLogTelemetryConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackdriverAccessLogTelemetryConfig. -func (in *StackdriverAccessLogTelemetryConfig) DeepCopy() *StackdriverAccessLogTelemetryConfig { - if in == nil { - return nil - } - out := new(StackdriverAccessLogTelemetryConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackdriverAddonConfig) DeepCopyInto(out *StackdriverAddonConfig) { - *out = *in - if in.Tracer != nil { - in, out := &in.Tracer, &out.Tracer - *out = new(StackdriverTracerConfig) - (*in).DeepCopyInto(*out) - } - if in.Telemetry != nil { - in, out := &in.Telemetry, &out.Telemetry - *out = new(StackdriverTelemetryConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackdriverAddonConfig. -func (in *StackdriverAddonConfig) DeepCopy() *StackdriverAddonConfig { - if in == nil { - return nil - } - out := new(StackdriverAddonConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackdriverAuthConfig) DeepCopyInto(out *StackdriverAuthConfig) { - *out = *in - if in.AppCredentials != nil { - in, out := &in.AppCredentials, &out.AppCredentials - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackdriverAuthConfig. -func (in *StackdriverAuthConfig) DeepCopy() *StackdriverAuthConfig { - if in == nil { - return nil - } - out := new(StackdriverAuthConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackdriverTelemetryConfig) DeepCopyInto(out *StackdriverTelemetryConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.Auth != nil { - in, out := &in.Auth, &out.Auth - *out = new(StackdriverAuthConfig) - (*in).DeepCopyInto(*out) - } - if in.EnableContextGraph != nil { - in, out := &in.EnableContextGraph, &out.EnableContextGraph - *out = new(bool) - **out = **in - } - if in.EnableLogging != nil { - in, out := &in.EnableLogging, &out.EnableLogging - *out = new(bool) - **out = **in - } - if in.EnableMetrics != nil { - in, out := &in.EnableMetrics, &out.EnableMetrics - *out = new(bool) - **out = **in - } - if in.AccessLogging != nil { - in, out := &in.AccessLogging, &out.AccessLogging - *out = new(StackdriverAccessLogTelemetryConfig) - (*in).DeepCopyInto(*out) - } - if in.ConfigOverride != nil { - in, out := &in.ConfigOverride, &out.ConfigOverride - *out = (*in).DeepCopy() - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackdriverTelemetryConfig. -func (in *StackdriverTelemetryConfig) DeepCopy() *StackdriverTelemetryConfig { - if in == nil { - return nil - } - out := new(StackdriverTelemetryConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StackdriverTracerConfig) DeepCopyInto(out *StackdriverTracerConfig) { - *out = *in - if in.Debug != nil { - in, out := &in.Debug, &out.Debug - *out = new(bool) - **out = **in - } - if in.MaxNumberOfAttributes != nil { - in, out := &in.MaxNumberOfAttributes, &out.MaxNumberOfAttributes - *out = new(int64) - **out = **in - } - if in.MaxNumberOfAnnotations != nil { - in, out := &in.MaxNumberOfAnnotations, &out.MaxNumberOfAnnotations - *out = new(int64) - **out = **in - } - if in.MaxNumberOfMessageEvents != nil { - in, out := &in.MaxNumberOfMessageEvents, &out.MaxNumberOfMessageEvents - *out = new(int64) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StackdriverTracerConfig. -func (in *StackdriverTracerConfig) DeepCopy() *StackdriverTracerConfig { - if in == nil { - return nil - } - out := new(StackdriverTracerConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TelemetryBatchingConfig) DeepCopyInto(out *TelemetryBatchingConfig) { - *out = *in - if in.MaxEntries != nil { - in, out := &in.MaxEntries, &out.MaxEntries - *out = new(int32) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TelemetryBatchingConfig. -func (in *TelemetryBatchingConfig) DeepCopy() *TelemetryBatchingConfig { - if in == nil { - return nil - } - out := new(TelemetryBatchingConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TelemetryConfig) DeepCopyInto(out *TelemetryConfig) { - *out = *in - if in.Mixer != nil { - in, out := &in.Mixer, &out.Mixer - *out = new(MixerTelemetryConfig) - (*in).DeepCopyInto(*out) - } - if in.Remote != nil { - in, out := &in.Remote, &out.Remote - *out = new(RemoteTelemetryConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TelemetryConfig. -func (in *TelemetryConfig) DeepCopy() *TelemetryConfig { - if in == nil { - return nil - } - out := new(TelemetryConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TelemetryLoadSheddingConfig) DeepCopyInto(out *TelemetryLoadSheddingConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TelemetryLoadSheddingConfig. -func (in *TelemetryLoadSheddingConfig) DeepCopy() *TelemetryLoadSheddingConfig { - if in == nil { - return nil - } - out := new(TelemetryLoadSheddingConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ThirdPartyIdentityConfig) DeepCopyInto(out *ThirdPartyIdentityConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdPartyIdentityConfig. -func (in *ThirdPartyIdentityConfig) DeepCopy() *ThirdPartyIdentityConfig { - if in == nil { - return nil - } - out := new(ThirdPartyIdentityConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ThreeScaleAddonConfig) DeepCopyInto(out *ThreeScaleAddonConfig) { - *out = *in - in.Enablement.DeepCopyInto(&out.Enablement) - if in.ListenAddr != nil { - in, out := &in.ListenAddr, &out.ListenAddr - *out = new(int32) - **out = **in - } - if in.LogGRPC != nil { - in, out := &in.LogGRPC, &out.LogGRPC - *out = new(bool) - **out = **in - } - if in.LogJSON != nil { - in, out := &in.LogJSON, &out.LogJSON - *out = new(bool) - **out = **in - } - if in.Metrics != nil { - in, out := &in.Metrics, &out.Metrics - *out = new(ThreeScaleMetricsConfig) - (*in).DeepCopyInto(*out) - } - if in.System != nil { - in, out := &in.System, &out.System - *out = new(ThreeScaleSystemConfig) - (*in).DeepCopyInto(*out) - } - if in.Client != nil { - in, out := &in.Client, &out.Client - *out = new(ThreeScaleClientConfig) - (*in).DeepCopyInto(*out) - } - if in.GRPC != nil { - in, out := &in.GRPC, &out.GRPC - *out = new(ThreeScaleGRPCConfig) - (*in).DeepCopyInto(*out) - } - if in.Backend != nil { - in, out := &in.Backend, &out.Backend - *out = new(ThreeScaleBackendConfig) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThreeScaleAddonConfig. -func (in *ThreeScaleAddonConfig) DeepCopy() *ThreeScaleAddonConfig { - if in == nil { - return nil - } - out := new(ThreeScaleAddonConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ThreeScaleBackendConfig) DeepCopyInto(out *ThreeScaleBackendConfig) { - *out = *in - if in.EnableCache != nil { - in, out := &in.EnableCache, &out.EnableCache - *out = new(bool) - **out = **in - } - if in.CacheFlushInterval != nil { - in, out := &in.CacheFlushInterval, &out.CacheFlushInterval - *out = new(int32) - **out = **in - } - if in.PolicyFailClosed != nil { - in, out := &in.PolicyFailClosed, &out.PolicyFailClosed - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThreeScaleBackendConfig. -func (in *ThreeScaleBackendConfig) DeepCopy() *ThreeScaleBackendConfig { - if in == nil { - return nil - } - out := new(ThreeScaleBackendConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ThreeScaleClientConfig) DeepCopyInto(out *ThreeScaleClientConfig) { - *out = *in - if in.AllowInsecureConnections != nil { - in, out := &in.AllowInsecureConnections, &out.AllowInsecureConnections - *out = new(bool) - **out = **in - } - if in.Timeout != nil { - in, out := &in.Timeout, &out.Timeout - *out = new(int32) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThreeScaleClientConfig. -func (in *ThreeScaleClientConfig) DeepCopy() *ThreeScaleClientConfig { - if in == nil { - return nil - } - out := new(ThreeScaleClientConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ThreeScaleGRPCConfig) DeepCopyInto(out *ThreeScaleGRPCConfig) { - *out = *in - if in.MaxConnTimeout != nil { - in, out := &in.MaxConnTimeout, &out.MaxConnTimeout - *out = new(int32) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThreeScaleGRPCConfig. -func (in *ThreeScaleGRPCConfig) DeepCopy() *ThreeScaleGRPCConfig { - if in == nil { - return nil - } - out := new(ThreeScaleGRPCConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ThreeScaleMetricsConfig) DeepCopyInto(out *ThreeScaleMetricsConfig) { - *out = *in - if in.Port != nil { - in, out := &in.Port, &out.Port - *out = new(int32) - **out = **in - } - if in.Report != nil { - in, out := &in.Report, &out.Report - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThreeScaleMetricsConfig. -func (in *ThreeScaleMetricsConfig) DeepCopy() *ThreeScaleMetricsConfig { - if in == nil { - return nil - } - out := new(ThreeScaleMetricsConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ThreeScaleSystemConfig) DeepCopyInto(out *ThreeScaleSystemConfig) { - *out = *in - if in.CacheMaxSize != nil { - in, out := &in.CacheMaxSize, &out.CacheMaxSize - *out = new(int64) - **out = **in - } - if in.CacheRefreshRetries != nil { - in, out := &in.CacheRefreshRetries, &out.CacheRefreshRetries - *out = new(int32) - **out = **in - } - if in.CacheRefreshInterval != nil { - in, out := &in.CacheRefreshInterval, &out.CacheRefreshInterval - *out = new(int32) - **out = **in - } - if in.CacheTTL != nil { - in, out := &in.CacheTTL, &out.CacheTTL - *out = new(int32) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThreeScaleSystemConfig. -func (in *ThreeScaleSystemConfig) DeepCopy() *ThreeScaleSystemConfig { - if in == nil { - return nil - } - out := new(ThreeScaleSystemConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TracingConfig) DeepCopyInto(out *TracingConfig) { - *out = *in - if in.Sampling != nil { - in, out := &in.Sampling, &out.Sampling - *out = new(int32) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TracingConfig. -func (in *TracingConfig) DeepCopy() *TracingConfig { - if in == nil { - return nil - } - out := new(TracingConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TrustConfig) DeepCopyInto(out *TrustConfig) { - *out = *in - if in.AdditionalDomains != nil { - in, out := &in.AdditionalDomains, &out.AdditionalDomains - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrustConfig. -func (in *TrustConfig) DeepCopy() *TrustConfig { - if in == nil { - return nil - } - out := new(TrustConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VolumeConfig) DeepCopyInto(out *VolumeConfig) { - *out = *in - in.Volume.DeepCopyInto(&out.Volume) - in.Mount.DeepCopyInto(&out.Mount) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeConfig. -func (in *VolumeConfig) DeepCopy() *VolumeConfig { - if in == nil { - return nil - } - out := new(VolumeConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ZipkinTracerConfig) DeepCopyInto(out *ZipkinTracerConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZipkinTracerConfig. -func (in *ZipkinTracerConfig) DeepCopy() *ZipkinTracerConfig { - if in == nil { - return nil - } - out := new(ZipkinTracerConfig) - in.DeepCopyInto(out) - return out -} diff --git a/api/external/maistra/version/version.go b/api/external/maistra/version/version.go deleted file mode 100644 index f5c52a6ea..000000000 --- a/api/external/maistra/version/version.go +++ /dev/null @@ -1,48 +0,0 @@ -package version - -import ( - "fmt" - "runtime" -) - -var ( - buildVersion = "unknown" - buildGitRevision = "unknown" - buildStatus = "unknown" - buildTag = "unknown" - - // Minimum supported mesh version (nil (all), "v2_0", "v2_1" etc) - minimumSupportedVersion = "v2.0" - - // Info exports the build version information. - Info BuildInfo -) - -// BuildInfo describes version information about the binary build. -type BuildInfo struct { - Version string - GitRevision string - BuildStatus string - GitTag string - GoVersion string - GoArch string - OperatorSDK string - MinimumSupportedVersion string -} - -func (b BuildInfo) String() string { - return fmt.Sprintf("%#v", b) -} - -func init() { - Info = BuildInfo{ - Version: buildVersion, - GitRevision: buildGitRevision, - BuildStatus: buildStatus, - GitTag: buildTag, - GoVersion: runtime.Version(), - GoArch: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), - OperatorSDK: "v0.18.0", - MinimumSupportedVersion: minimumSupportedVersion, - } -} diff --git a/api/v1/authpolicy_types.go b/api/v1/authpolicy_types.go index c51459af9..06bd3e6fc 100644 --- a/api/v1/authpolicy_types.go +++ b/api/v1/authpolicy_types.go @@ -26,18 +26,10 @@ import ( "github.com/kuadrant/policy-machinery/machinery" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -const ( - // TODO: remove after fixing the integration tests that still depend on these - AuthPolicyBackReferenceAnnotationName = "kuadrant.io/authpolicies" - AuthPolicyDirectReferenceAnnotationName = "kuadrant.io/authpolicy" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) var ( @@ -78,12 +70,7 @@ func (p *AuthPolicy) GetLocator() string { return machinery.LocatorFromObject(p) } -// TODO: remove -func (p *AuthPolicy) IsAtomicOverride() bool { - return p.Spec.Overrides != nil && p.Spec.Overrides.Strategy == AtomicMergeStrategy -} - -// DEPRECATED: Use GetTargetRefs instead +// Deprecated: Use GetTargetRefs instead func (p *AuthPolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { return p.Spec.TargetRef.LocalPolicyTargetReference } @@ -294,46 +281,14 @@ func (p *AuthPolicy) SetRules(rules map[string]MergeableRule) { } } -// DEPRECATED. impl: kuadrant.Policy func (p *AuthPolicy) GetStatus() kuadrantgatewayapi.PolicyStatus { return &p.Status } -// DEPRECATED. impl: kuadrant.Policy -func (p *AuthPolicy) PolicyClass() kuadrantgatewayapi.PolicyClass { - return kuadrantgatewayapi.InheritedPolicy -} - -// DEPRECATED. impl: kuadrant.Policy -func (p *AuthPolicy) GetWrappedNamespace() gatewayapiv1.Namespace { - return gatewayapiv1.Namespace(p.GetNamespace()) -} - -// DEPRECATED. impl: kuadrant.Policy -func (p *AuthPolicy) GetRulesHostnames() []string { - return []string{} -} - -// DEPRECATED. impl: kuadrant.Policy func (p *AuthPolicy) Kind() string { return AuthPolicyGroupKind.Kind } -// TODO: remove -func (p *AuthPolicy) BackReferenceAnnotationName() string { - return AuthPolicyBackReferenceAnnotationName -} - -// TODO: remove -func (p *AuthPolicy) DirectReferenceAnnotationName() string { - return AuthPolicyDirectReferenceAnnotationName -} - -// TODO: remove -func (p *AuthPolicy) TargetProgrammedGatewaysOnly() bool { - return true -} - // +kubebuilder:validation:XValidation:rule="!(has(self.defaults) && (has(self.patterns) || has(self.when) || has(self.rules)))",message="Implicit and explicit defaults are mutually exclusive" // +kubebuilder:validation:XValidation:rule="!(has(self.overrides) && (has(self.patterns) || has(self.when) || has(self.rules)))",message="Implicit defaults and explicit overrides are mutually exclusive" // +kubebuilder:validation:XValidation:rule="!(has(self.overrides) && has(self.defaults))",message="Explicit overrides and explicit defaults are mutually exclusive" @@ -439,18 +394,6 @@ func (r *MergeablePatternExpressions) WithSource(source string) MergeableRule { return r } -type MergeablePatternExpressionOrRef struct { - authorinov1beta3.PatternExpressionOrRef `json:",inline"` - Source string `json:"-"` -} - -func (r *MergeablePatternExpressionOrRef) GetSpec() any { return r.PatternExpressionOrRef } -func (r *MergeablePatternExpressionOrRef) GetSource() string { return r.Source } -func (r *MergeablePatternExpressionOrRef) WithSource(source string) MergeableRule { - r.Source = source - return r -} - type MergeableAuthenticationSpec struct { authorinov1beta3.AuthenticationSpec `json:",inline"` Source string `json:"-"` @@ -609,13 +552,6 @@ type AuthPolicyList struct { Items []AuthPolicy `json:"items"` } -// DEPRECATED. impl: kuadrant.PolicyList -func (l *AuthPolicyList) GetItems() []kuadrant.Policy { - return utils.Map(l.Items, func(item AuthPolicy) kuadrant.Policy { - return &item - }) -} - func init() { SchemeBuilder.Register(&AuthPolicy{}, &AuthPolicyList{}) } diff --git a/api/v1/authpolicy_types_test.go b/api/v1/authpolicy_types_test.go deleted file mode 100644 index 16c1e6a03..000000000 --- a/api/v1/authpolicy_types_test.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build unit - -package v1 - -import ( - "testing" - - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -func TestAuthPolicyListGetItems(t *testing.T) { - list := &AuthPolicyList{} - if len(list.GetItems()) != 0 { - t.Errorf("Expected empty list of items") - } - policy := AuthPolicy{} - list.Items = []AuthPolicy{policy} - result := list.GetItems() - if len(result) != 1 { - t.Errorf("Expected 1 item, got %d", len(result)) - } - _, ok := result[0].(kuadrant.Policy) - if !ok { - t.Errorf("Expected item to be a Policy") - } -} diff --git a/api/v1/dnspolicy_types.go b/api/v1/dnspolicy_types.go index da5468f86..02a0eb31e 100644 --- a/api/v1/dnspolicy_types.go +++ b/api/v1/dnspolicy_types.go @@ -31,9 +31,8 @@ import ( dnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/policy-machinery/machinery" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) const ( @@ -198,35 +197,18 @@ func (p *DNSPolicy) Validate() error { return p.Spec.ExcludeAddresses.Validate() } -// Deprecated: kuadrant.Policy. -func (p *DNSPolicy) GetWrappedNamespace() gatewayapiv1.Namespace { - return gatewayapiv1.Namespace(p.Namespace) -} - -// Deprecated: kuadrant.Policy. -func (p *DNSPolicy) GetRulesHostnames() []string { - return make([]string, 0) -} - func (p *DNSPolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { return p.Spec.TargetRef.LocalPolicyTargetReference } -// Deprecated: kuadrant.Policy. func (p *DNSPolicy) GetStatus() kuadrantgatewayapi.PolicyStatus { return &p.Status } -// Deprecated: kuadrant.Policy. func (p *DNSPolicy) Kind() string { return DNSPolicyGroupKind.Kind } -// Deprecated: kuadrant.Policy. -func (p *DNSPolicy) PolicyClass() kuadrantgatewayapi.PolicyClass { - return kuadrantgatewayapi.DirectPolicy -} - //+kubebuilder:object:root=true // DNSPolicyList contains a list of DNSPolicy @@ -236,13 +218,6 @@ type DNSPolicyList struct { Items []DNSPolicy `json:"items"` } -// Deprecated: kuadrant.PolicyList. -func (l *DNSPolicyList) GetItems() []kuadrant.Policy { - return utils.Map(l.Items, func(item DNSPolicy) kuadrant.Policy { - return &item - }) -} - func init() { SchemeBuilder.Register(&DNSPolicy{}, &DNSPolicyList{}) } diff --git a/api/v1/ratelimitpolicy_types.go b/api/v1/ratelimitpolicy_types.go index e27449926..4c47f9d66 100644 --- a/api/v1/ratelimitpolicy_types.go +++ b/api/v1/ratelimitpolicy_types.go @@ -22,18 +22,10 @@ import ( "github.com/kuadrant/policy-machinery/machinery" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -const ( - // TODO: remove after fixing the integration tests that still depend on these - RateLimitPolicyBackReferenceAnnotationName = "kuadrant.io/ratelimitpolicies" - RateLimitPolicyDirectReferenceAnnotationName = "kuadrant.io/ratelimitpolicy" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) var ( @@ -77,7 +69,7 @@ func (p *RateLimitPolicy) GetLocator() string { return machinery.LocatorFromObject(p) } -// DEPRECATED: Use GetTargetRefs instead +// Deprecated: Use GetTargetRefs instead func (p *RateLimitPolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { return p.Spec.TargetRef.LocalPolicyTargetReference } @@ -150,41 +142,14 @@ func (p *RateLimitPolicy) SetRules(rules map[string]MergeableRule) { } } -// DEPRECATED. impl: kuadrant.Policy func (p *RateLimitPolicy) GetStatus() kuadrantgatewayapi.PolicyStatus { return &p.Status } -// DEPRECATED. impl: kuadrant.Policy -func (p *RateLimitPolicy) PolicyClass() kuadrantgatewayapi.PolicyClass { - return kuadrantgatewayapi.InheritedPolicy -} - -// DEPRECATED. impl: kuadrant.Policy -func (p *RateLimitPolicy) GetWrappedNamespace() gatewayapiv1.Namespace { - return gatewayapiv1.Namespace(p.GetNamespace()) -} - -// DEPRECATED. impl: kuadrant.Policy -func (p *RateLimitPolicy) GetRulesHostnames() []string { - return []string{} -} - -// DEPRECATED. impl: kuadrant.Policy func (p *RateLimitPolicy) Kind() string { return RateLimitPolicyGroupKind.Kind } -// TODO: remove -func (p *RateLimitPolicy) DirectReferenceAnnotationName() string { - return RateLimitPolicyDirectReferenceAnnotationName -} - -// TODO: remove -func (p *RateLimitPolicy) BackReferenceAnnotationName() string { - return RateLimitPolicyBackReferenceAnnotationName -} - // +kubebuilder:validation:XValidation:rule="!(has(self.defaults) && has(self.limits))",message="Implicit and explicit defaults are mutually exclusive" // +kubebuilder:validation:XValidation:rule="!(has(self.defaults) && has(self.overrides))",message="Overrides and explicit defaults are mutually exclusive" // +kubebuilder:validation:XValidation:rule="!(has(self.overrides) && has(self.limits))",message="Overrides and implicit defaults are mutually exclusive" @@ -359,13 +324,6 @@ type RateLimitPolicyList struct { Items []RateLimitPolicy `json:"items"` } -// DEPRECATED. impl: kuadrant.PolicyList -func (l *RateLimitPolicyList) GetItems() []kuadrant.Policy { - return utils.Map(l.Items, func(item RateLimitPolicy) kuadrant.Policy { - return &item - }) -} - func init() { SchemeBuilder.Register(&RateLimitPolicy{}, &RateLimitPolicyList{}) } diff --git a/api/v1/tlspolicy_types.go b/api/v1/tlspolicy_types.go index 58beb5082..1269317d7 100644 --- a/api/v1/tlspolicy_types.go +++ b/api/v1/tlspolicy_types.go @@ -28,9 +28,8 @@ import ( "github.com/kuadrant/policy-machinery/machinery" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) var ( @@ -176,27 +175,10 @@ func (p *TLSPolicy) Kind() string { return TLSPolicyGroupKind.Kind } -// Deprecated: kuadrant.Policy. -func (p *TLSPolicy) PolicyClass() kuadrantgatewayapi.PolicyClass { - return kuadrantgatewayapi.DirectPolicy -} - -// Deprecated: kuadrant.Policy. -func (p *TLSPolicy) GetWrappedNamespace() gatewayapiv1.Namespace { - return gatewayapiv1.Namespace(p.Namespace) -} - -// Deprecated: kuadrant.Policy. -func (p *TLSPolicy) GetRulesHostnames() []string { - return make([]string, 0) -} - -// DEPRECATED: Use GetTargetRefs instead func (p *TLSPolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { return p.Spec.TargetRef.LocalPolicyTargetReference } -// Deprecated: kuadrant.Policy. func (p *TLSPolicy) GetStatus() kuadrantgatewayapi.PolicyStatus { return &p.Status } @@ -210,13 +192,6 @@ type TLSPolicyList struct { Items []TLSPolicy `json:"items"` } -// Deprecated: kuadrant.PolicyList. -func (l *TLSPolicyList) GetItems() []kuadrant.Policy { - return utils.Map(l.Items, func(item TLSPolicy) kuadrant.Policy { - return &item - }) -} - func init() { SchemeBuilder.Register(&TLSPolicy{}, &TLSPolicyList{}) } diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 2f38aa0f3..d42236ddf 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -584,22 +584,6 @@ func (in *MergeableMetadataSpec) DeepCopy() *MergeableMetadataSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MergeablePatternExpressionOrRef) DeepCopyInto(out *MergeablePatternExpressionOrRef) { - *out = *in - in.PatternExpressionOrRef.DeepCopyInto(&out.PatternExpressionOrRef) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MergeablePatternExpressionOrRef. -func (in *MergeablePatternExpressionOrRef) DeepCopy() *MergeablePatternExpressionOrRef { - if in == nil { - return nil - } - out := new(MergeablePatternExpressionOrRef) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MergeablePatternExpressions) DeepCopyInto(out *MergeablePatternExpressions) { *out = *in diff --git a/api/v1beta1/kuadrant_types.go b/api/v1beta1/kuadrant_types.go index 4e7fa32e9..2b42cf3a9 100644 --- a/api/v1beta1/kuadrant_types.go +++ b/api/v1beta1/kuadrant_types.go @@ -19,13 +19,38 @@ package v1beta1 import ( "github.com/go-logr/logr" "github.com/google/go-cmp/cmp" + "github.com/kuadrant/policy-machinery/machinery" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. +var ( + KuadrantGroupKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "Kuadrant"} + + KuadrantsResource = GroupVersion.WithResource("kuadrants") +) + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason`,priority=2 +//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" + +// Kuadrant configures installations of Kuadrant Service Protection components +type Kuadrant struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec KuadrantSpec `json:"spec,omitempty"` + Status KuadrantStatus `json:"status,omitempty"` +} + +var _ machinery.Object = &Kuadrant{} + +func (p *Kuadrant) GetLocator() string { + return machinery.LocatorFromObject(p) +} // KuadrantSpec defines the desired state of Kuadrant type KuadrantSpec struct { @@ -65,20 +90,6 @@ func (r *KuadrantStatus) Equals(other *KuadrantStatus, logger logr.Logger) bool return true } -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status -//+kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[0].reason`,priority=2 -//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" - -// Kuadrant configures installations of Kuadrant Service Protection components -type Kuadrant struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec KuadrantSpec `json:"spec,omitempty"` - Status KuadrantStatus `json:"status,omitempty"` -} - //+kubebuilder:object:root=true // KuadrantList contains a list of Kuadrant diff --git a/api/v1beta1/topology.go b/api/v1beta1/topology.go index e36a8bb8e..95c48cc2b 100644 --- a/api/v1beta1/topology.go +++ b/api/v1beta1/topology.go @@ -2,7 +2,6 @@ package v1beta1 import ( authorinooperatorv1beta1 "github.com/kuadrant/authorino-operator/api/v1beta1" - authorinov1beta3 "github.com/kuadrant/authorino/api/v1beta3" limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" "github.com/kuadrant/policy-machinery/controller" "github.com/kuadrant/policy-machinery/machinery" @@ -12,25 +11,13 @@ import ( ) var ( - KuadrantGroupKind = schema.GroupKind{Group: GroupVersion.Group, Kind: "Kuadrant"} - LimitadorGroupKind = schema.GroupKind{Group: limitadorv1alpha1.GroupVersion.Group, Kind: "Limitador"} - AuthorinoGroupKind = schema.GroupKind{Group: authorinooperatorv1beta1.GroupVersion.Group, Kind: "Authorino"} - AuthConfigGroupKind = schema.GroupKind{Group: authorinov1beta3.GroupVersion.Group, Kind: "AuthConfig"} + LimitadorGroupKind = schema.GroupKind{Group: limitadorv1alpha1.GroupVersion.Group, Kind: "Limitador"} + AuthorinoGroupKind = schema.GroupKind{Group: authorinooperatorv1beta1.GroupVersion.Group, Kind: "Authorino"} - KuadrantsResource = GroupVersion.WithResource("kuadrants") - LimitadorsResource = limitadorv1alpha1.GroupVersion.WithResource("limitadors") - AuthorinosResource = authorinooperatorv1beta1.GroupVersion.WithResource("authorinos") - AuthConfigsResource = authorinov1beta3.GroupVersion.WithResource("authconfigs") - - AuthConfigHTTPRouteRuleAnnotation = machinery.HTTPRouteRuleGroupKind.String() + LimitadorsResource = limitadorv1alpha1.GroupVersion.WithResource("limitadors") + AuthorinosResource = authorinooperatorv1beta1.GroupVersion.WithResource("authorinos") ) -var _ machinery.Object = &Kuadrant{} - -func (p *Kuadrant) GetLocator() string { - return machinery.LocatorFromObject(p) -} - func LinkKuadrantToGatewayClasses(objs controller.Store) machinery.LinkFunc { kuadrants := lo.Map(objs.FilterByGroupKind(KuadrantGroupKind), controller.ObjectAs[*Kuadrant]) @@ -74,22 +61,3 @@ func LinkKuadrantToAuthorino(objs controller.Store) machinery.LinkFunc { }, } } - -func LinkHTTPRouteRuleToAuthConfig(objs controller.Store) machinery.LinkFunc { - httpRoutes := lo.Map(objs.FilterByGroupKind(machinery.HTTPRouteGroupKind), controller.ObjectAs[*gatewayapiv1.HTTPRoute]) - httpRouteRules := lo.FlatMap(lo.Map(httpRoutes, func(r *gatewayapiv1.HTTPRoute, _ int) *machinery.HTTPRoute { - return &machinery.HTTPRoute{HTTPRoute: r} - }), machinery.HTTPRouteRulesFromHTTPRouteFunc) - - return machinery.LinkFunc{ - From: machinery.HTTPRouteRuleGroupKind, - To: AuthConfigGroupKind, - Func: func(child machinery.Object) []machinery.Object { - return lo.FilterMap(httpRouteRules, func(httpRouteRule *machinery.HTTPRouteRule, _ int) (machinery.Object, bool) { - authConfig := child.(*controller.RuntimeObject).Object.(*authorinov1beta3.AuthConfig) - annotations := authConfig.GetAnnotations() - return httpRouteRule, annotations != nil && annotations[AuthConfigHTTPRouteRuleAnnotation] == httpRouteRule.GetLocator() - }) - }, - } -} diff --git a/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml b/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml index d08667ef4..5341118d9 100644 --- a/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml +++ b/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml @@ -105,7 +105,7 @@ metadata: capabilities: Basic Install categories: Integration & Delivery containerImage: quay.io/kuadrant/kuadrant-operator:latest - createdAt: "2024-11-08T14:46:34Z" + createdAt: "2024-11-08T16:43:37Z" description: A Kubernetes Operator to manage the lifecycle of the Kuadrant system operators.operatorframework.io/builder: operator-sdk-v1.32.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 @@ -286,26 +286,20 @@ spec: resources: - gatewayclasses verbs: + - get - list - watch - apiGroups: - gateway.networking.k8s.io resources: - gateways + - httproutes verbs: - - create - - delete - get - list - patch - update - watch - - apiGroups: - - gateway.networking.k8s.io - resources: - - gateways/finalizers - verbs: - - update - apiGroups: - gateway.networking.k8s.io resources: @@ -315,37 +309,15 @@ spec: - get - patch - update - - apiGroups: - - gateway.networking.k8s.io - resources: - - httproutes - verbs: - - get - - list - - patch - - update - - watch - - apiGroups: - - install.istio.io - resources: - - istiooperators - verbs: - - create - - get - - list - - patch - - update - - watch - apiGroups: - kuadrant.io resources: - authpolicies - - dnsrecords + - dnspolicies - kuadrants - ratelimitpolicies + - tlspolicies verbs: - - create - - delete - get - list - patch @@ -356,7 +328,6 @@ spec: resources: - authpolicies/finalizers - dnspolicies/finalizers - - kuadrants/finalizers - ratelimitpolicies/finalizers - tlspolicies/finalizers verbs: @@ -376,9 +347,9 @@ spec: - apiGroups: - kuadrant.io resources: - - dnspolicies - - tlspolicies + - dnsrecords verbs: + - create - delete - get - list @@ -403,29 +374,6 @@ spec: - patch - update - watch - - apiGroups: - - maistra.io - resources: - - servicemeshcontrolplanes - verbs: - - get - - list - - patch - - update - - use - - watch - - apiGroups: - - maistra.io - resources: - - servicemeshmembers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - networking.istio.io resources: @@ -450,17 +398,6 @@ spec: - patch - update - watch - - apiGroups: - - operator.istio.io - resources: - - istios - verbs: - - create - - get - - list - - patch - - update - - watch serviceAccountName: kuadrant-operator-controller-manager deployments: - label: diff --git a/charts/kuadrant-operator/templates/manifests.yaml b/charts/kuadrant-operator/templates/manifests.yaml index 36f814c01..51510d0d0 100644 --- a/charts/kuadrant-operator/templates/manifests.yaml +++ b/charts/kuadrant-operator/templates/manifests.yaml @@ -8637,26 +8637,20 @@ rules: resources: - gatewayclasses verbs: + - get - list - watch - apiGroups: - gateway.networking.k8s.io resources: - gateways + - httproutes verbs: - - create - - delete - get - list - patch - update - watch -- apiGroups: - - gateway.networking.k8s.io - resources: - - gateways/finalizers - verbs: - - update - apiGroups: - gateway.networking.k8s.io resources: @@ -8666,37 +8660,15 @@ rules: - get - patch - update -- apiGroups: - - gateway.networking.k8s.io - resources: - - httproutes - verbs: - - get - - list - - patch - - update - - watch -- apiGroups: - - install.istio.io - resources: - - istiooperators - verbs: - - create - - get - - list - - patch - - update - - watch - apiGroups: - kuadrant.io resources: - authpolicies - - dnsrecords + - dnspolicies - kuadrants - ratelimitpolicies + - tlspolicies verbs: - - create - - delete - get - list - patch @@ -8707,7 +8679,6 @@ rules: resources: - authpolicies/finalizers - dnspolicies/finalizers - - kuadrants/finalizers - ratelimitpolicies/finalizers - tlspolicies/finalizers verbs: @@ -8727,9 +8698,9 @@ rules: - apiGroups: - kuadrant.io resources: - - dnspolicies - - tlspolicies + - dnsrecords verbs: + - create - delete - get - list @@ -8754,29 +8725,6 @@ rules: - patch - update - watch -- apiGroups: - - maistra.io - resources: - - servicemeshcontrolplanes - verbs: - - get - - list - - patch - - update - - use - - watch -- apiGroups: - - maistra.io - resources: - - servicemeshmembers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - networking.istio.io resources: @@ -8801,17 +8749,6 @@ rules: - patch - update - watch -- apiGroups: - - operator.istio.io - resources: - - istios - verbs: - - create - - get - - list - - patch - - update - - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 0f51c826d..e36117ada 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -134,26 +134,20 @@ rules: resources: - gatewayclasses verbs: + - get - list - watch - apiGroups: - gateway.networking.k8s.io resources: - gateways + - httproutes verbs: - - create - - delete - get - list - patch - update - watch -- apiGroups: - - gateway.networking.k8s.io - resources: - - gateways/finalizers - verbs: - - update - apiGroups: - gateway.networking.k8s.io resources: @@ -163,37 +157,15 @@ rules: - get - patch - update -- apiGroups: - - gateway.networking.k8s.io - resources: - - httproutes - verbs: - - get - - list - - patch - - update - - watch -- apiGroups: - - install.istio.io - resources: - - istiooperators - verbs: - - create - - get - - list - - patch - - update - - watch - apiGroups: - kuadrant.io resources: - authpolicies - - dnsrecords + - dnspolicies - kuadrants - ratelimitpolicies + - tlspolicies verbs: - - create - - delete - get - list - patch @@ -204,7 +176,6 @@ rules: resources: - authpolicies/finalizers - dnspolicies/finalizers - - kuadrants/finalizers - ratelimitpolicies/finalizers - tlspolicies/finalizers verbs: @@ -224,9 +195,9 @@ rules: - apiGroups: - kuadrant.io resources: - - dnspolicies - - tlspolicies + - dnsrecords verbs: + - create - delete - get - list @@ -251,29 +222,6 @@ rules: - patch - update - watch -- apiGroups: - - maistra.io - resources: - - servicemeshcontrolplanes - verbs: - - get - - list - - patch - - update - - use - - watch -- apiGroups: - - maistra.io - resources: - - servicemeshmembers - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - apiGroups: - networking.istio.io resources: @@ -298,14 +246,3 @@ rules: - patch - update - watch -- apiGroups: - - operator.istio.io - resources: - - istios - verbs: - - create - - get - - list - - patch - - update - - watch diff --git a/controllers/auth_policies_validator.go b/controllers/auth_policies_validator.go index 95500e3cd..ac232735b 100644 --- a/controllers/auth_policies_validator.go +++ b/controllers/auth_policies_validator.go @@ -12,7 +12,7 @@ import ( "k8s.io/utils/ptr" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - kuadrant "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + kuadrant "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) type AuthPolicyValidator struct{} diff --git a/controllers/auth_policy_status_updater.go b/controllers/auth_policy_status_updater.go index 687a10c98..65b99ef80 100644 --- a/controllers/auth_policy_status_updater.go +++ b/controllers/auth_policy_status_updater.go @@ -23,11 +23,12 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" + kuadrantauthorino "github.com/kuadrant/kuadrant-operator/pkg/authorino" kuadrantenvoygateway "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" kuadrantistio "github.com/kuadrant/kuadrant-operator/pkg/istio" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" ) type AuthPolicyStatusUpdater struct { @@ -44,7 +45,7 @@ func (r *AuthPolicyStatusUpdater) Subscription() controller.Subscription { {Kind: &machinery.GatewayGroupKind}, {Kind: &machinery.HTTPRouteGroupKind}, {Kind: &kuadrantv1.AuthPolicyGroupKind}, - {Kind: &kuadrantv1beta1.AuthConfigGroupKind}, + {Kind: &kuadrantauthorino.AuthConfigGroupKind}, {Kind: &kuadrantistio.EnvoyFilterGroupKind}, {Kind: &kuadrantistio.WasmPluginGroupKind}, {Kind: &kuadrantenvoygateway.EnvoyPatchPolicyGroupKind}, @@ -142,7 +143,7 @@ func (r *AuthPolicyStatusUpdater) enforcedCondition(policy *kuadrantv1.AuthPolic if len(kuadrantv1.PoliciesInPath(effectivePolicy.Path, func(p machinery.Policy) bool { return p.GetLocator() == policy.GetLocator() })) == 0 { continue } - gatewayClass, gateway, listener, httpRoute, httpRouteRule, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + gatewayClass, gateway, listener, httpRoute, httpRouteRule, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) if !kuadrantgatewayapi.IsListenerReady(listener.Listener, gateway.Gateway) || !kuadrantgatewayapi.IsHTTPRouteReady(httpRoute.HTTPRoute, gateway.Gateway, gatewayClass.GatewayClass.Spec.ControllerName) { continue } @@ -172,7 +173,7 @@ func (r *AuthPolicyStatusUpdater) enforcedCondition(policy *kuadrantv1.AuthPolic } // all rules of the policy have been overridden by at least one other policy overridingPoliciesKeys := lo.FilterMap(lo.Uniq(lo.Flatten(lo.Values(overridingPolicies))), func(policyLocator string, _ int) (k8stypes.NamespacedName, bool) { - policyKey, err := common.NamespacedNameFromLocator(policyLocator) + policyKey, err := kuadrantpolicymachinery.NamespacedNameFromLocator(policyLocator) return policyKey, err == nil }) return kuadrant.EnforcedCondition(policy, kuadrant.NewErrOverridden(policyKind, overridingPoliciesKeys), false) @@ -194,10 +195,10 @@ func (r *AuthPolicyStatusUpdater) enforcedCondition(policy *kuadrantv1.AuthPolic for pathID, httpRouteRule := range affectedHTTPRouteRules { authConfigName := AuthConfigNameForPath(pathID) authConfig, found := lo.Find(topology.Objects().Children(httpRouteRule), func(authConfig machinery.Object) bool { - return authConfig.GroupVersionKind().GroupKind() == kuadrantv1beta1.AuthConfigGroupKind && authConfig.GetName() == authConfigName + return authConfig.GroupVersionKind().GroupKind() == kuadrantauthorino.AuthConfigGroupKind && authConfig.GetName() == authConfigName }) if !found || !isAuthConfigReady(authConfig.(*controller.RuntimeObject).Object.(*authorinov1beta3.AuthConfig)) { - componentsToSync = append(componentsToSync, fmt.Sprintf("%s (%s)", kuadrantv1beta1.AuthConfigGroupKind.Kind, authConfigName)) + componentsToSync = append(componentsToSync, fmt.Sprintf("%s (%s)", kuadrantauthorino.AuthConfigGroupKind.Kind, authConfigName)) } } diff --git a/controllers/auth_workflow_helpers.go b/controllers/auth_workflow_helpers.go index e04dadc67..022925484 100644 --- a/controllers/auth_workflow_helpers.go +++ b/controllers/auth_workflow_helpers.go @@ -17,7 +17,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" + kuadrant "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/pkg/wasm" ) @@ -34,11 +34,6 @@ var ( ErrMissingStateEffectiveAuthPolicies = fmt.Errorf("missing auth effective policies stored in the reconciliation state") ) -//+kubebuilder:rbac:groups=kuadrant.io,resources=authpolicies,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=kuadrant.io,resources=authpolicies/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=kuadrant.io,resources=authpolicies/finalizers,verbs=update -//+kubebuilder:rbac:groups=authorino.kuadrant.io,resources=authconfigs,verbs=get;list;watch;create;update;patch;delete - func GetAuthorinoFromTopology(topology *machinery.Topology) (*authorinooperatorv1beta1.Authorino, error) { kuadrant, err := GetKuadrantFromTopology(topology) if err != nil { @@ -68,13 +63,13 @@ func AuthClusterName(gatewayName string) string { func authClusterPatch(host string, port int) map[string]any { return map[string]any{ - "name": common.KuadrantAuthClusterName, + "name": kuadrant.KuadrantAuthClusterName, "type": "STRICT_DNS", "connect_timeout": "1s", "lb_policy": "ROUND_ROBIN", "http2_protocol_options": map[string]any{}, "load_assignment": map[string]any{ - "cluster_name": common.KuadrantAuthClusterName, + "cluster_name": kuadrant.KuadrantAuthClusterName, "endpoints": []map[string]any{ { "lb_endpoints": []map[string]any{ diff --git a/controllers/authconfigs_reconciler.go b/controllers/authconfigs_reconciler.go index 5c19cc873..9e840906d 100644 --- a/controllers/authconfigs_reconciler.go +++ b/controllers/authconfigs_reconciler.go @@ -18,10 +18,13 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + kuadrantauthorino "github.com/kuadrant/kuadrant-operator/pkg/authorino" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) +//+kubebuilder:rbac:groups=authorino.kuadrant.io,resources=authconfigs,verbs=get;list;watch;create;update;patch;delete + type AuthConfigsReconciler struct { client *dynamic.DynamicClient } @@ -36,7 +39,7 @@ func (r *AuthConfigsReconciler) Subscription() controller.Subscription { {Kind: &machinery.GatewayGroupKind}, {Kind: &machinery.HTTPRouteGroupKind}, {Kind: &kuadrantv1.AuthPolicyGroupKind}, - {Kind: &kuadrantv1beta1.AuthConfigGroupKind}, + {Kind: &kuadrantauthorino.AuthConfigGroupKind}, }, } } @@ -68,7 +71,7 @@ func (r *AuthConfigsReconciler) Reconcile(ctx context.Context, _ []controller.Re modifiedAuthConfigs := []string{} for pathID, effectivePolicy := range effectivePoliciesMap { - _, _, _, httpRoute, httpRouteRule, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + _, _, _, httpRoute, httpRouteRule, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) httpRouteKey := k8stypes.NamespacedName{Name: httpRoute.GetName(), Namespace: httpRoute.GetNamespace()} httpRouteRuleKey := httpRouteRule.Name @@ -76,10 +79,10 @@ func (r *AuthConfigsReconciler) Reconcile(ctx context.Context, _ []controller.Re desiredAuthConfig := r.buildDesiredAuthConfig(effectivePolicy, authConfigName, authConfigsNamespace) desiredAuthConfigs[k8stypes.NamespacedName{Name: desiredAuthConfig.GetName(), Namespace: desiredAuthConfig.GetNamespace()}] = struct{}{} - resource := r.client.Resource(kuadrantv1beta1.AuthConfigsResource).Namespace(desiredAuthConfig.GetNamespace()) + resource := r.client.Resource(kuadrantauthorino.AuthConfigsResource).Namespace(desiredAuthConfig.GetNamespace()) existingAuthConfigObj, found := lo.Find(topology.Objects().Children(httpRouteRule), func(child machinery.Object) bool { - return child.GroupVersionKind().GroupKind() == kuadrantv1beta1.AuthConfigGroupKind && child.GetName() == authConfigName && labels.Set(child.(*controller.RuntimeObject).GetLabels()).AsSelector().Matches(labels.Set(desiredAuthConfig.GetLabels())) + return child.GroupVersionKind().GroupKind() == kuadrantauthorino.AuthConfigGroupKind && child.GetName() == authConfigName && labels.Set(child.(*controller.RuntimeObject).GetLabels()).AsSelector().Matches(labels.Set(desiredAuthConfig.GetLabels())) }) // create @@ -137,10 +140,10 @@ func (r *AuthConfigsReconciler) Reconcile(ctx context.Context, _ []controller.Re // cleanup authconfigs that are not in the effective policies staleAuthConfigs := topology.Objects().Items(func(o machinery.Object) bool { _, desired := desiredAuthConfigs[k8stypes.NamespacedName{Name: o.GetName(), Namespace: o.GetNamespace()}] - return o.GroupVersionKind().GroupKind() == kuadrantv1beta1.AuthConfigGroupKind && labels.Set(o.(*controller.RuntimeObject).GetLabels()).AsSelector().Matches(AuthObjectLabels()) && !desired + return o.GroupVersionKind().GroupKind() == kuadrantauthorino.AuthConfigGroupKind && labels.Set(o.(*controller.RuntimeObject).GetLabels()).AsSelector().Matches(AuthObjectLabels()) && !desired }) for _, authConfig := range staleAuthConfigs { - if err := r.client.Resource(kuadrantv1beta1.AuthConfigsResource).Namespace(authConfig.GetNamespace()).Delete(ctx, authConfig.GetName(), metav1.DeleteOptions{}); err != nil { + if err := r.client.Resource(kuadrantauthorino.AuthConfigsResource).Namespace(authConfig.GetNamespace()).Delete(ctx, authConfig.GetName(), metav1.DeleteOptions{}); err != nil { logger.Error(err, "failed to delete authconfig object", "authconfig", fmt.Sprintf("%s/%s", authConfig.GetNamespace(), authConfig.GetName())) // TODO: handle error } @@ -150,7 +153,7 @@ func (r *AuthConfigsReconciler) Reconcile(ctx context.Context, _ []controller.Re } func (r *AuthConfigsReconciler) buildDesiredAuthConfig(effectivePolicy EffectiveAuthPolicy, name, namespace string) *authorinov1beta3.AuthConfig { - _, _, _, _, httpRouteRule, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + _, _, _, _, httpRouteRule, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) authConfig := &authorinov1beta3.AuthConfig{ TypeMeta: metav1.TypeMeta{ @@ -161,7 +164,7 @@ func (r *AuthConfigsReconciler) buildDesiredAuthConfig(effectivePolicy Effective Name: name, Namespace: namespace, Annotations: map[string]string{ - kuadrantv1beta1.AuthConfigHTTPRouteRuleAnnotation: httpRouteRule.GetLocator(), + kuadrantauthorino.AuthConfigHTTPRouteRuleAnnotation: httpRouteRule.GetLocator(), }, Labels: AuthObjectLabels(), }, @@ -260,7 +263,7 @@ func equalAuthConfigs(existing, desired *authorinov1beta3.AuthConfig) bool { // httprouterule back ref annotation existingAnnotations := existing.GetAnnotations() desiredAnnotations := desired.GetAnnotations() - if existingAnnotations == nil || desiredAnnotations == nil || existingAnnotations[kuadrantv1beta1.AuthConfigHTTPRouteRuleAnnotation] != desiredAnnotations[kuadrantv1beta1.AuthConfigHTTPRouteRuleAnnotation] { + if existingAnnotations == nil || desiredAnnotations == nil || existingAnnotations[kuadrantauthorino.AuthConfigHTTPRouteRuleAnnotation] != desiredAnnotations[kuadrantauthorino.AuthConfigHTTPRouteRuleAnnotation] { return false } diff --git a/controllers/authorino_reconciler.go b/controllers/authorino_reconciler.go index f8983f839..dd6a4a924 100644 --- a/controllers/authorino_reconciler.go +++ b/controllers/authorino_reconciler.go @@ -21,6 +21,8 @@ type AuthorinoReconciler struct { Client *dynamic.DynamicClient } +//+kubebuilder:rbac:groups=operator.authorino.kuadrant.io,resources=authorinos,verbs=get;list;watch;create;update;delete;patch + func NewAuthorinoReconciler(client *dynamic.DynamicClient) *AuthorinoReconciler { return &AuthorinoReconciler{Client: client} } diff --git a/controllers/consoleplugin_reconciler.go b/controllers/consoleplugin_reconciler.go index b1718b963..ce20eb225 100644 --- a/controllers/consoleplugin_reconciler.go +++ b/controllers/consoleplugin_reconciler.go @@ -14,11 +14,11 @@ import ( "k8s.io/utils/ptr" ctrlruntime "sigs.k8s.io/controller-runtime" - "github.com/kuadrant/kuadrant-operator/pkg/library/reconcilers" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" "github.com/kuadrant/kuadrant-operator/pkg/log" "github.com/kuadrant/kuadrant-operator/pkg/openshift" "github.com/kuadrant/kuadrant-operator/pkg/openshift/consoleplugin" + "github.com/kuadrant/kuadrant-operator/pkg/reconcilers" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) //+kubebuilder:rbac:groups=console.openshift.io,resources=consoleplugins,verbs=get;list;watch;create;update;patch;delete diff --git a/controllers/consoleplugin_reconciler_test.go b/controllers/consoleplugin_reconciler_test.go index cb7c7fbdd..edd4e8d89 100644 --- a/controllers/consoleplugin_reconciler_test.go +++ b/controllers/consoleplugin_reconciler_test.go @@ -23,7 +23,7 @@ import ( gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" controllersfake "github.com/kuadrant/kuadrant-operator/controllers/fake" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/pkg/openshift" "github.com/kuadrant/kuadrant-operator/pkg/openshift/consoleplugin" ) diff --git a/controllers/data_plane_policies_workflow.go b/controllers/data_plane_policies_workflow.go index cd7352d12..ca7849a19 100644 --- a/controllers/data_plane_policies_workflow.go +++ b/controllers/data_plane_policies_workflow.go @@ -12,6 +12,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" + kuadrantauthorino "github.com/kuadrant/kuadrant-operator/pkg/authorino" kuadrantenvoygateway "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" kuadrantistio "github.com/kuadrant/kuadrant-operator/pkg/istio" ) @@ -37,7 +38,7 @@ var ( {Kind: &kuadrantv1.RateLimitPolicyGroupKind}, {Kind: &kuadrantv1beta1.LimitadorGroupKind}, {Kind: &kuadrantv1.AuthPolicyGroupKind}, - {Kind: &kuadrantv1beta1.AuthConfigGroupKind}, + {Kind: &kuadrantauthorino.AuthConfigGroupKind}, {Kind: &kuadrantistio.EnvoyFilterGroupKind}, {Kind: &kuadrantistio.WasmPluginGroupKind}, {Kind: &kuadrantenvoygateway.EnvoyPatchPolicyGroupKind}, @@ -45,6 +46,14 @@ var ( } ) +//+kubebuilder:rbac:groups=kuadrant.io,resources=authpolicies,verbs=get;list;watch;update;patch +//+kubebuilder:rbac:groups=kuadrant.io,resources=authpolicies/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=kuadrant.io,resources=authpolicies/finalizers,verbs=update + +//+kubebuilder:rbac:groups=kuadrant.io,resources=ratelimitpolicies,verbs=get;list;watch;update;patch +//+kubebuilder:rbac:groups=kuadrant.io,resources=ratelimitpolicies/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=kuadrant.io,resources=ratelimitpolicies/finalizers,verbs=update + func NewDataPlanePoliciesWorkflow(client *dynamic.DynamicClient, isIstioInstalled, isEnvoyGatewayInstalled bool) *controller.Workflow { dataPlanePoliciesValidation := &controller.Workflow{ Tasks: []controller.ReconcileFunc{ diff --git a/controllers/dns_workflow.go b/controllers/dns_workflow.go index 08368a85e..ced545c95 100644 --- a/controllers/dns_workflow.go +++ b/controllers/dns_workflow.go @@ -20,8 +20,8 @@ import ( "github.com/kuadrant/policy-machinery/machinery" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) const ( @@ -39,7 +39,7 @@ var ( ) //+kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch -//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies,verbs=get;list;watch;update;patch;delete +//+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies,verbs=get;list;watch;update;patch //+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies/status,verbs=get;update;patch //+kubebuilder:rbac:groups=kuadrant.io,resources=dnspolicies/finalizers,verbs=update diff --git a/controllers/dnspolicies_validator.go b/controllers/dnspolicies_validator.go index 9e6437ef4..2679060a8 100644 --- a/controllers/dnspolicies_validator.go +++ b/controllers/dnspolicies_validator.go @@ -12,7 +12,7 @@ import ( "github.com/kuadrant/policy-machinery/machinery" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) func NewDNSPoliciesValidator() *DNSPoliciesValidator { diff --git a/controllers/dnspolicy_status_updater.go b/controllers/dnspolicy_status_updater.go index 4ea20d6c8..38914f71e 100644 --- a/controllers/dnspolicy_status_updater.go +++ b/controllers/dnspolicy_status_updater.go @@ -20,8 +20,8 @@ import ( "github.com/kuadrant/policy-machinery/machinery" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) func NewDNSPolicyStatusUpdater(client *dynamic.DynamicClient) *DNSPolicyStatusUpdater { diff --git a/controllers/effective_dnspolicies_reconciler.go b/controllers/effective_dnspolicies_reconciler.go index 1742ead41..4550077b9 100644 --- a/controllers/effective_dnspolicies_reconciler.go +++ b/controllers/effective_dnspolicies_reconciler.go @@ -19,7 +19,7 @@ import ( "github.com/kuadrant/policy-machinery/machinery" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) var ( diff --git a/controllers/effective_tls_policies_reconciler.go b/controllers/effective_tls_policies_reconciler.go index f13c24834..8e47ed797 100644 --- a/controllers/effective_tls_policies_reconciler.go +++ b/controllers/effective_tls_policies_reconciler.go @@ -49,13 +49,6 @@ type CertTarget struct { target machinery.Targetable } -//+kubebuilder:rbac:groups=kuadrant.io,resources=tlspolicies,verbs=get;list;watch;update;patch;delete -//+kubebuilder:rbac:groups=kuadrant.io,resources=tlspolicies/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=kuadrant.io,resources=tlspolicies/finalizers,verbs=update -//+kubebuilder:rbac:groups="cert-manager.io",resources=issuers,verbs=get;list;watch; -//+kubebuilder:rbac:groups="cert-manager.io",resources=clusterissuers,verbs=get;list;watch; -//+kubebuilder:rbac:groups="cert-manager.io",resources=certificates,verbs=get;list;watch;create;update;patch;delete - func (t *EffectiveTLSPoliciesReconciler) Reconcile(ctx context.Context, _ []controller.ResourceEvent, topology *machinery.Topology, _ error, s *sync.Map) error { logger := controller.LoggerFromContext(ctx).WithName("EffectiveTLSPoliciesReconciler").WithName("Reconcile") diff --git a/controllers/envoy_gateway_auth_cluster_reconciler.go b/controllers/envoy_gateway_auth_cluster_reconciler.go index d70f7d23c..45d36ffe4 100644 --- a/controllers/envoy_gateway_auth_cluster_reconciler.go +++ b/controllers/envoy_gateway_auth_cluster_reconciler.go @@ -20,10 +20,13 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" kuadrantenvoygateway "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" + kuadrant "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" ) +//+kubebuilder:rbac:groups=gateway.envoyproxy.io,resources=envoypatchpolicies,verbs=get;list;watch;create;update;patch;delete + // EnvoyGatewayAuthClusterReconciler reconciles Envoy Gateway EnvoyPatchPolicy custom resources for auth type EnvoyGatewayAuthClusterReconciler struct { client *dynamic.DynamicClient @@ -75,7 +78,7 @@ func (r *EnvoyGatewayAuthClusterReconciler) Reconcile(ctx context.Context, _ []c } gateways := lo.UniqBy(lo.FilterMap(lo.Values(effectivePolicies.(EffectiveAuthPolicies)), func(effectivePolicy EffectiveAuthPolicy, _ int) (*machinery.Gateway, bool) { - gatewayClass, gateway, _, _, _, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + gatewayClass, gateway, _, _, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) return gateway, gatewayClass.Spec.ControllerName == envoyGatewayGatewayControllerName }), func(gateway *machinery.Gateway) string { return gateway.GetLocator() @@ -192,7 +195,7 @@ func (r *EnvoyGatewayAuthClusterReconciler) buildDesiredEnvoyPatchPolicy(authori } authorinoServiceInfo := authorinoServiceInfoFromAuthorino(authorino) - jsonPatches, err := kuadrantenvoygateway.BuildEnvoyPatchPolicyClusterPatch(common.KuadrantAuthClusterName, authorinoServiceInfo.Host, int(authorinoServiceInfo.Port), authClusterPatch) + jsonPatches, err := kuadrantenvoygateway.BuildEnvoyPatchPolicyClusterPatch(kuadrant.KuadrantAuthClusterName, authorinoServiceInfo.Host, int(authorinoServiceInfo.Port), authClusterPatch) if err != nil { return nil, err } diff --git a/controllers/envoy_gateway_extension_reconciler.go b/controllers/envoy_gateway_extension_reconciler.go index c2dc539e1..adf5d90a9 100644 --- a/controllers/envoy_gateway_extension_reconciler.go +++ b/controllers/envoy_gateway_extension_reconciler.go @@ -19,13 +19,15 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" kuadrantenvoygateway "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" + "github.com/kuadrant/kuadrant-operator/pkg/utils" "github.com/kuadrant/kuadrant-operator/pkg/wasm" ) +//+kubebuilder:rbac:groups=gateway.envoyproxy.io,resources=envoyextensionpolicies,verbs=get;list;watch;create;update;patch;delete + // EnvoyGatewayExtensionReconciler reconciles Envoy Gateway EnvoyExtensionPolicy custom resources type EnvoyGatewayExtensionReconciler struct { client *dynamic.DynamicClient @@ -167,7 +169,7 @@ func (r *EnvoyGatewayExtensionReconciler) buildWasmConfigs(ctx context.Context, pathID := paths[i].Key path := paths[i].Value - gatewayClass, gateway, _, _, _, _ := common.ObjectsInRequestPath(path) + gatewayClass, gateway, _, _, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(path) // ignore if not an envoy gateway gateway if gatewayClass.Spec.ControllerName != envoyGatewayGatewayControllerName { diff --git a/controllers/envoy_gateway_ratelimit_cluster_reconciler.go b/controllers/envoy_gateway_ratelimit_cluster_reconciler.go index c480567f2..11edef590 100644 --- a/controllers/envoy_gateway_ratelimit_cluster_reconciler.go +++ b/controllers/envoy_gateway_ratelimit_cluster_reconciler.go @@ -20,10 +20,13 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" kuadrantenvoygateway "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" + kuadrant "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" ) +//+kubebuilder:rbac:groups=gateway.envoyproxy.io,resources=envoypatchpolicies,verbs=get;list;watch;create;update;patch;delete + // EnvoyGatewayRateLimitClusterReconciler reconciles Envoy Gateway EnvoyPatchPolicy custom resources for rate limiting type EnvoyGatewayRateLimitClusterReconciler struct { client *dynamic.DynamicClient @@ -75,7 +78,7 @@ func (r *EnvoyGatewayRateLimitClusterReconciler) Reconcile(ctx context.Context, } gateways := lo.UniqBy(lo.FilterMap(lo.Values(effectivePolicies.(EffectiveRateLimitPolicies)), func(effectivePolicy EffectiveRateLimitPolicy, _ int) (*machinery.Gateway, bool) { - gatewayClass, gateway, _, _, _, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + gatewayClass, gateway, _, _, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) return gateway, gatewayClass.Spec.ControllerName == envoyGatewayGatewayControllerName }), func(gateway *machinery.Gateway) string { return gateway.GetLocator() @@ -191,7 +194,7 @@ func (r *EnvoyGatewayRateLimitClusterReconciler) buildDesiredEnvoyPatchPolicy(li }, } - jsonPatches, err := kuadrantenvoygateway.BuildEnvoyPatchPolicyClusterPatch(common.KuadrantRateLimitClusterName, limitador.Status.Service.Host, int(limitador.Status.Service.Ports.GRPC), rateLimitClusterPatch) + jsonPatches, err := kuadrantenvoygateway.BuildEnvoyPatchPolicyClusterPatch(kuadrant.KuadrantRateLimitClusterName, limitador.Status.Service.Host, int(limitador.Status.Service.Ports.GRPC), rateLimitClusterPatch) if err != nil { return nil, err } diff --git a/controllers/gateway_kuadrant_controller.go b/controllers/gateway_kuadrant_controller.go deleted file mode 100644 index 48b3ba547..000000000 --- a/controllers/gateway_kuadrant_controller.go +++ /dev/null @@ -1,179 +0,0 @@ -/* -Copyright 2021 Red Hat, Inc. - -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 controllers - -import ( - "context" - "encoding/json" - "strings" - - "github.com/go-logr/logr" - apierrors "k8s.io/apimachinery/pkg/api/errors" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/builder" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/predicate" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/mappers" - "github.com/kuadrant/kuadrant-operator/pkg/library/reconcilers" -) - -// GatewayKuadrantReconciler is responsible of assiging gateways to a kuadrant instances -// Currently only one kuadrant instance is allowed per cluster -// This controller will annotate every gateway in the cluster -// with the namespace of the kuadrant instance -// TODO: After the RFC defined, we might want to get the gw to label/annotate from Kuadrant.Spec or manual labeling/annotation -type GatewayKuadrantReconciler struct { - *reconcilers.BaseReconciler -} - -//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=kuadrant.io,resources=kuadrants,verbs=get;list - -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.10.0/pkg/reconcile -func (r *GatewayKuadrantReconciler) Reconcile(eventCtx context.Context, req ctrl.Request) (ctrl.Result, error) { - logger := r.Logger().WithValues("Gateway", req.NamespacedName) - logger.Info("Reconciling Kuadrant annotations") - ctx := logr.NewContext(eventCtx, logger) - - gw := &gatewayapiv1.Gateway{} - if err := r.Client().Get(ctx, req.NamespacedName, gw); err != nil { - if apierrors.IsNotFound(err) { - logger.Info("no gateway found") - return ctrl.Result{}, nil - } - logger.Error(err, "failed to get gateway") - return ctrl.Result{}, err - } - - if logger.V(1).Enabled() { - jsonData, err := json.MarshalIndent(gw, "", " ") - if err != nil { - return ctrl.Result{}, err - } - logger.V(1).Info(string(jsonData)) - } - - err := r.reconcileGatewayWithKuadrantMetadata(ctx, gw) - - if err != nil { - return ctrl.Result{}, err - } - - logger.Info("Gateway kuadrant annotations reconciled successfully") - return ctrl.Result{}, nil -} - -func (r *GatewayKuadrantReconciler) reconcileGatewayWithKuadrantMetadata(ctx context.Context, gw *gatewayapiv1.Gateway) error { - logger, err := logr.FromContext(ctx) - if err != nil { - return err - } - - kuadrantList := &kuadrantv1beta1.KuadrantList{} - if err := r.Client().List(ctx, kuadrantList); err != nil { - return err - } - - if len(kuadrantList.Items) > 1 { - // multiple kuadrant instances? not supported - keys := make([]string, len(kuadrantList.Items)) - for idx := range kuadrantList.Items { - keys[idx] = client.ObjectKeyFromObject(&kuadrantList.Items[idx]).String() - } - logger.Info("Multiple kuadrant instances found", "num", len(kuadrantList.Items), "keys", strings.Join(keys[:], ",")) - return nil - } - - if len(kuadrantList.Items) == 0 { - logger.Info("Kuadrant instance not found in the cluster") - return r.removeKuadrantNamespaceAnnotation(ctx, gw) - } - - val, ok := gw.GetAnnotations()[kuadrant.KuadrantNamespaceAnnotation] - if !ok || val != kuadrantList.Items[0].Namespace { - // Either the annotation does not exist or - // the namespace differs from the available Kuadrant CR, hence the gateway is updated. - annotations := gw.GetAnnotations() - if annotations == nil { - annotations = map[string]string{} - } - annotations[kuadrant.KuadrantNamespaceAnnotation] = kuadrantList.Items[0].Namespace - gw.SetAnnotations(annotations) - logger.Info("annotate gateway with kuadrant namespace", "namespace", kuadrantList.Items[0].Namespace) - return r.UpdateResource(ctx, gw) - } - - return nil -} - -func (r *GatewayKuadrantReconciler) removeKuadrantNamespaceAnnotation(ctx context.Context, gw *gatewayapiv1.Gateway) error { - logger, err := logr.FromContext(ctx) - if err != nil { - return err - } - - if _, ok := gw.GetAnnotations()[kuadrant.KuadrantNamespaceAnnotation]; ok { - delete(gw.Annotations, kuadrant.KuadrantNamespaceAnnotation) - logger.Info("remove gateway annotation with kuadrant namespace") - return r.UpdateResource(ctx, gw) - } - - return nil -} - -// SetupWithManager sets up the controller with the Manager. -func (r *GatewayKuadrantReconciler) SetupWithManager(mgr ctrl.Manager) error { - ok, err := kuadrantgatewayapi.IsGatewayAPIInstalled(mgr.GetRESTMapper()) - if err != nil { - return err - } - if !ok { - r.Logger().Info("GatewayKuadrant controller disabled. GatewayAPI was not found") - return nil - } - - // maps any kuadrant event to gateway event - // on any kuadrant event, one reconciliation request for every gateway in the cluster is created - kuadrantToGatewayEventMapper := mappers.NewKuadrantToGatewayEventMapper( - mappers.WithLogger(r.Logger().WithName("kuadrantToGatewayEventMapper")), - mappers.WithClient(r.Client()), - ) - - return ctrl.NewControllerManagedBy(mgr). - // Gateway Kuadrant controller only cares about the annotations - For(&gatewayapiv1.Gateway{}, builder.WithPredicates(predicate.AnnotationChangedPredicate{})). - // Watch for any kuadrant CR being created or deleted - Watches( - &kuadrantv1beta1.Kuadrant{}, - handler.EnqueueRequestsFromMapFunc(kuadrantToGatewayEventMapper.Map), - builder.WithPredicates(predicate.Funcs{ - UpdateFunc: func(event.UpdateEvent) bool { - // The reconciler only cares about creation/deletion events - return false - }, - }), - ). - Complete(r) -} diff --git a/controllers/httproute_policy_discoverability_reconciler.go b/controllers/httproute_policy_discoverability_reconciler.go index 525cbade2..438d77eb1 100644 --- a/controllers/httproute_policy_discoverability_reconciler.go +++ b/controllers/httproute_policy_discoverability_reconciler.go @@ -18,8 +18,8 @@ import ( gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) type HTTPRoutePolicyDiscoverabilityReconciler struct { diff --git a/controllers/httprouteparentrefs_eventmapper.go b/controllers/httprouteparentrefs_eventmapper.go deleted file mode 100644 index 98389a6a9..000000000 --- a/controllers/httprouteparentrefs_eventmapper.go +++ /dev/null @@ -1,83 +0,0 @@ -package controllers - -import ( - "context" - "fmt" - - "github.com/go-logr/logr" - "k8s.io/utils/ptr" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -// HTTPRouteParentRefsEventMapper is an EventHandler that maps HTTPRoute events to policy events, -// by going through the parentRefs of the route and finding all policies that target one of its -// parent resources, thus yielding events for those policies. -type HTTPRouteParentRefsEventMapper struct { - Logger logr.Logger - Client client.Client -} - -func (m *HTTPRouteParentRefsEventMapper) MapToRateLimitPolicy(obj client.Object) []reconcile.Request { - return m.mapToPolicyRequest(obj, "ratelimitpolicy", &kuadrantv1.RateLimitPolicyList{}) -} - -func (m *HTTPRouteParentRefsEventMapper) MapToAuthPolicy(obj client.Object) []reconcile.Request { - return m.mapToPolicyRequest(obj, "authpolicy", &kuadrantv1.AuthPolicyList{}) -} - -func (m *HTTPRouteParentRefsEventMapper) mapToPolicyRequest(obj client.Object, policyKind string, policyList client.ObjectList) []reconcile.Request { - logger := m.Logger.V(1).WithValues( - "object", client.ObjectKeyFromObject(obj), - "policyKind", policyKind, - ) - - route, ok := obj.(*gatewayapiv1.HTTPRoute) - if !ok { - logger.Info("mapToPolicyRequest:", "error", fmt.Sprintf("%T is not a *gatewayapiv1.HTTPRoute", obj)) - return []reconcile.Request{} - } - - requests := make([]reconcile.Request, 0) - - for _, parentRef := range route.Spec.ParentRefs { - // skips if parentRef is not a Gateway - if (parentRef.Group != nil && *parentRef.Group != gatewayapiv1.GroupName) || (parentRef.Kind != nil && *parentRef.Kind != "Gateway") { - continue - } - // list policies in the same namespace as the parent gateway of the route - parentRefNamespace := parentRef.Namespace - if parentRefNamespace == nil { - ns := gatewayapiv1.Namespace(route.GetNamespace()) - parentRefNamespace = &ns - } - if err := m.Client.List(context.Background(), policyList, &client.ListOptions{Namespace: string(*parentRefNamespace)}); err != nil { - logger.Error(err, "failed to list policies") - } - // triggers the reconciliation of any policy that targets the parent gateway of the route - policies, ok := policyList.(kuadrant.PolicyList) - if !ok { - logger.Info("mapToPolicyRequest:", "error", fmt.Sprintf("%T is not a PolicyList", policyList)) - continue - } - for _, policy := range policies.GetItems() { - targetRef := policy.GetTargetRef() - if !kuadrantgatewayapi.IsTargetRefGateway(targetRef) { - continue - } - targetRefNamespace := ptr.To(policy.GetWrappedNamespace()) - - if *parentRefNamespace == *targetRefNamespace && parentRef.Name == targetRef.Name { - obj, _ := policy.(client.Object) - requests = append(requests, reconcile.Request{NamespacedName: client.ObjectKeyFromObject(obj)}) - } - } - } - - return requests -} diff --git a/controllers/istio_auth_cluster_reconciler.go b/controllers/istio_auth_cluster_reconciler.go index 9f76f6f64..1f559aed6 100644 --- a/controllers/istio_auth_cluster_reconciler.go +++ b/controllers/istio_auth_cluster_reconciler.go @@ -21,10 +21,12 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" kuadrantistio "github.com/kuadrant/kuadrant-operator/pkg/istio" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" ) +//+kubebuilder:rbac:groups=networking.istio.io,resources=envoyfilters,verbs=get;list;watch;create;update;patch;delete + // IstioAuthClusterReconciler reconciles Istio EnvoyFilter custom resources for auth type IstioAuthClusterReconciler struct { client *dynamic.DynamicClient @@ -76,7 +78,7 @@ func (r *IstioAuthClusterReconciler) Reconcile(ctx context.Context, _ []controll } gateways := lo.UniqBy(lo.FilterMap(lo.Values(effectivePolicies.(EffectiveAuthPolicies)), func(effectivePolicy EffectiveAuthPolicy, _ int) (*machinery.Gateway, bool) { - gatewayClass, gateway, _, _, _, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + gatewayClass, gateway, _, _, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) return gateway, gatewayClass.Spec.ControllerName == istioGatewayControllerName }), func(gateway *machinery.Gateway) string { return gateway.GetLocator() diff --git a/controllers/istio_extension_reconciler.go b/controllers/istio_extension_reconciler.go index 9ba474771..293793808 100644 --- a/controllers/istio_extension_reconciler.go +++ b/controllers/istio_extension_reconciler.go @@ -20,13 +20,15 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" kuadrantistio "github.com/kuadrant/kuadrant-operator/pkg/istio" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" + "github.com/kuadrant/kuadrant-operator/pkg/utils" "github.com/kuadrant/kuadrant-operator/pkg/wasm" ) +//+kubebuilder:rbac:groups=extensions.istio.io,resources=wasmplugins,verbs=get;list;watch;create;update;patch;delete + // IstioExtensionReconciler reconciles Istio WasmPlugin custom resources type IstioExtensionReconciler struct { client *dynamic.DynamicClient @@ -170,7 +172,7 @@ func (r *IstioExtensionReconciler) buildWasmConfigs(ctx context.Context, state * pathID := paths[i].Key path := paths[i].Value - gatewayClass, gateway, _, _, _, _ := common.ObjectsInRequestPath(path) + gatewayClass, gateway, _, _, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(path) // ignore if not an istio gateway if gatewayClass.Spec.ControllerName != istioGatewayControllerName { diff --git a/controllers/istio_ratelimit_cluster_reconciler.go b/controllers/istio_ratelimit_cluster_reconciler.go index 8dd1d8c62..cf2b56b97 100644 --- a/controllers/istio_ratelimit_cluster_reconciler.go +++ b/controllers/istio_ratelimit_cluster_reconciler.go @@ -21,10 +21,12 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" kuadrantistio "github.com/kuadrant/kuadrant-operator/pkg/istio" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" ) +//+kubebuilder:rbac:groups=networking.istio.io,resources=envoyfilters,verbs=get;list;watch;create;update;patch;delete + // IstioRateLimitClusterReconciler reconciles Istio EnvoyFilter custom resources for rate limiting type IstioRateLimitClusterReconciler struct { client *dynamic.DynamicClient @@ -76,7 +78,7 @@ func (r *IstioRateLimitClusterReconciler) Reconcile(ctx context.Context, _ []con } gateways := lo.UniqBy(lo.FilterMap(lo.Values(effectivePolicies.(EffectiveRateLimitPolicies)), func(effectivePolicy EffectiveRateLimitPolicy, _ int) (*machinery.Gateway, bool) { - gatewayClass, gateway, _, _, _, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + gatewayClass, gateway, _, _, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) return gateway, gatewayClass.Spec.ControllerName == istioGatewayControllerName }), func(gateway *machinery.Gateway) string { return gateway.GetLocator() diff --git a/controllers/kuadrant_status_updater.go b/controllers/kuadrant_status_updater.go index f89e3612f..8caddf819 100644 --- a/controllers/kuadrant_status_updater.go +++ b/controllers/kuadrant_status_updater.go @@ -20,7 +20,7 @@ import ( "k8s.io/utils/ptr" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" + "github.com/kuadrant/kuadrant-operator/pkg/authorino" ) const ( @@ -173,8 +173,8 @@ func checkLimitadorReady(limitadorObj *limitadorv1alpha1.Limitador) *string { return nil } -func checkAuthorinoAvailable(authorino *authorinov1beta1.Authorino) *string { - readyCondition := common.FindAuthorinoStatusCondition(authorino.Status.Conditions, "Ready") +func checkAuthorinoAvailable(authorinoObj *authorinov1beta1.Authorino) *string { + readyCondition := authorino.FindAuthorinoStatusCondition(authorinoObj.Status.Conditions, "Ready") if readyCondition == nil { tmp := "Ready condition not found" return &tmp diff --git a/controllers/limitador_limits_reconciler.go b/controllers/limitador_limits_reconciler.go index 59cd3a2e6..702d896ea 100644 --- a/controllers/limitador_limits_reconciler.go +++ b/controllers/limitador_limits_reconciler.go @@ -16,9 +16,9 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" "github.com/kuadrant/kuadrant-operator/pkg/ratelimit" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) type LimitadorLimitsReconciler struct { @@ -98,7 +98,7 @@ func (r *LimitadorLimitsReconciler) buildLimitadorLimits(ctx context.Context, st rateLimitIndex := ratelimit.NewIndex() for pathID, effectivePolicy := range effectivePoliciesMap { - _, _, _, httpRoute, _, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + _, _, _, httpRoute, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) limitsNamespace := LimitsNamespaceFromRoute(httpRoute.HTTPRoute) limitRules := lo.Filter(lo.Entries(effectivePolicy.Spec.Rules()), diff --git a/controllers/limitador_reconciler.go b/controllers/limitador_reconciler.go index daf8e3e68..771169095 100644 --- a/controllers/limitador_reconciler.go +++ b/controllers/limitador_reconciler.go @@ -15,13 +15,15 @@ import ( "k8s.io/utils/ptr" "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" + kuadrant "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) type LimitadorReconciler struct { Client *dynamic.DynamicClient } +//+kubebuilder:rbac:groups=limitador.kuadrant.io,resources=limitadors,verbs=get;list;watch;create;update;patch;delete + func NewLimitadorReconciler(client *dynamic.DynamicClient) *LimitadorReconciler { return &LimitadorReconciler{Client: client} } @@ -69,7 +71,7 @@ func (r *LimitadorReconciler) Reconcile(ctx context.Context, _ []controller.Reso APIVersion: "limitador.kuadrant.io/v1alpha1", }, ObjectMeta: metav1.ObjectMeta{ - Name: common.LimitadorName, + Name: kuadrant.LimitadorName, Namespace: kobj.Namespace, OwnerReferences: []metav1.OwnerReference{ { diff --git a/controllers/ratelimit_policies_validator.go b/controllers/ratelimit_policies_validator.go index f3d5312b1..4992950a0 100644 --- a/controllers/ratelimit_policies_validator.go +++ b/controllers/ratelimit_policies_validator.go @@ -12,7 +12,7 @@ import ( "k8s.io/utils/ptr" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - kuadrant "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + kuadrant "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) type RateLimitPolicyValidator struct{} diff --git a/controllers/ratelimit_policy_status_updater.go b/controllers/ratelimit_policy_status_updater.go index 82a3eeb2e..26adbf556 100644 --- a/controllers/ratelimit_policy_status_updater.go +++ b/controllers/ratelimit_policy_status_updater.go @@ -22,11 +22,11 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" kuadrantenvoygateway "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" kuadrantistio "github.com/kuadrant/kuadrant-operator/pkg/istio" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" ) type RateLimitPolicyStatusUpdater struct { @@ -133,7 +133,7 @@ func (r *RateLimitPolicyStatusUpdater) enforcedCondition(policy *kuadrantv1.Rate if len(kuadrantv1.PoliciesInPath(effectivePolicy.Path, func(p machinery.Policy) bool { return p.GetLocator() == policy.GetLocator() })) == 0 { continue } - gatewayClass, gateway, listener, httpRoute, _, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + gatewayClass, gateway, listener, httpRoute, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) if !kuadrantgatewayapi.IsListenerReady(listener.Listener, gateway.Gateway) || !kuadrantgatewayapi.IsHTTPRouteReady(httpRoute.HTTPRoute, gateway.Gateway, gatewayClass.GatewayClass.Spec.ControllerName) { continue } @@ -161,7 +161,7 @@ func (r *RateLimitPolicyStatusUpdater) enforcedCondition(policy *kuadrantv1.Rate } // all rules of the policy have been overridden by at least one other policy overridingPoliciesKeys := lo.FilterMap(lo.Uniq(lo.Flatten(lo.Values(overridingPolicies))), func(policyLocator string, _ int) (k8stypes.NamespacedName, bool) { - policyKey, err := common.NamespacedNameFromLocator(policyLocator) + policyKey, err := kuadrantpolicymachinery.NamespacedNameFromLocator(policyLocator) return policyKey, err == nil }) return kuadrant.EnforcedCondition(policy, kuadrant.NewErrOverridden(policyKind, overridingPoliciesKeys), false) diff --git a/controllers/ratelimit_workflow_helpers.go b/controllers/ratelimit_workflow_helpers.go index b73dc3689..22f2ba64b 100644 --- a/controllers/ratelimit_workflow_helpers.go +++ b/controllers/ratelimit_workflow_helpers.go @@ -20,7 +20,8 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/common" + kuadrant "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" "github.com/kuadrant/kuadrant-operator/pkg/wasm" ) @@ -38,11 +39,6 @@ var ( ErrMissingStateEffectiveRateLimitPolicies = fmt.Errorf("missing rate limit effective policies stored in the reconciliation state") ) -//+kubebuilder:rbac:groups=kuadrant.io,resources=ratelimitpolicies,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=kuadrant.io,resources=ratelimitpolicies/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=kuadrant.io,resources=ratelimitpolicies/finalizers,verbs=update -//+kubebuilder:rbac:groups=limitador.kuadrant.io,resources=limitadors,verbs=get;list;watch;create;update;patch;delete - func GetLimitadorFromTopology(topology *machinery.Topology) (*limitadorv1alpha1.Limitador, error) { kuadrant, err := GetKuadrantFromTopology(topology) if err != nil { @@ -95,13 +91,13 @@ func RateLimitClusterName(gatewayName string) string { func rateLimitClusterPatch(host string, port int) map[string]any { return map[string]any{ - "name": common.KuadrantRateLimitClusterName, + "name": kuadrant.KuadrantRateLimitClusterName, "type": "STRICT_DNS", "connect_timeout": "1s", "lb_policy": "ROUND_ROBIN", "http2_protocol_options": map[string]any{}, "load_assignment": map[string]any{ - "cluster_name": common.KuadrantRateLimitClusterName, + "cluster_name": kuadrant.KuadrantRateLimitClusterName, "endpoints": []map[string]any{ { "lb_endpoints": []map[string]any{ @@ -125,7 +121,7 @@ func rateLimitClusterPatch(host string, port int) map[string]any { func buildWasmActionsForRateLimit(effectivePolicy EffectiveRateLimitPolicy, state *sync.Map) []wasm.Action { policiesInPath := kuadrantv1.PoliciesInPath(effectivePolicy.Path, isRateLimitPolicyAcceptedAndNotDeletedFunc(state)) - _, _, _, httpRoute, _, _ := common.ObjectsInRequestPath(effectivePolicy.Path) + _, _, _, httpRoute, _, _ := kuadrantpolicymachinery.ObjectsInRequestPath(effectivePolicy.Path) limitsNamespace := LimitsNamespaceFromRoute(httpRoute.HTTPRoute) topLevelRules, limitRules := lo.FilterReject(lo.Entries(effectivePolicy.Spec.Rules()), diff --git a/controllers/state_of_the_world.go b/controllers/state_of_the_world.go index cd0863e7c..01c181a06 100644 --- a/controllers/state_of_the_world.go +++ b/controllers/state_of_the_world.go @@ -32,10 +32,11 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" + "github.com/kuadrant/kuadrant-operator/pkg/authorino" "github.com/kuadrant/kuadrant-operator/pkg/envoygateway" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" "github.com/kuadrant/kuadrant-operator/pkg/istio" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/pkg/openshift" "github.com/kuadrant/kuadrant-operator/pkg/openshift/consoleplugin" ) @@ -48,26 +49,15 @@ var ( ) // gateway-api permissions -//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gatewayclasses,verbs=list;watch +//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gatewayclasses,verbs=get;list;watch +//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways,verbs=get;list;watch;update;patch //+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways/finalizers,verbs=update //+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch;update;patch //+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes/status,verbs=get;update;patch -// istio permissions -//+kubebuilder:rbac:groups=networking.istio.io,resources=envoyfilters,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=extensions.istio.io,resources=wasmplugins,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=install.istio.io,resources=istiooperators,verbs=get;list;watch;create;update;patch -//+kubebuilder:rbac:groups=operator.istio.io,resources=istios,verbs=get;list;watch;create;update;patch - -// envoy gateway permissions -//+kubebuilder:rbac:groups=gateway.envoyproxy.io,resources=envoypatchpolicies,verbs=get;list;watch;create;update;patch;delete -//+kubebuilder:rbac:groups=gateway.envoyproxy.io,resources=envoyextensionpolicies,verbs=get;list;watch;create;update;patch;delete - // kuadrant permissions -//+kubebuilder:rbac:groups=kuadrant.io,resources=kuadrants,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=kuadrant.io,resources=kuadrants,verbs=get;list;watch;update;patch //+kubebuilder:rbac:groups=kuadrant.io,resources=kuadrants/status,verbs=get;update;patch -//+kubebuilder:rbac:groups=kuadrant.io,resources=kuadrants/finalizers,verbs=update // core, apps, coordination.k8s,io permissions //+kubebuilder:rbac:groups=core,resources=serviceaccounts;configmaps;services,verbs=get;list;watch;create;update;patch;delete @@ -76,13 +66,6 @@ var ( //+kubebuilder:rbac:groups="",resources=events,verbs=create;patch //+kubebuilder:rbac:groups="",resources=leases,verbs=get;list;watch;create;update;patch;delete -// maistra.io permissions -// +kubebuilder:rbac:groups=maistra.io,resources=servicemeshcontrolplanes,verbs=get;list;watch;update;use;patch -// +kubebuilder:rbac:groups=maistra.io,resources=servicemeshmembers,verbs=get;list;watch;create;update;delete;patch - -// authorino permissions -//+kubebuilder:rbac:groups=operator.authorino.kuadrant.io,resources=authorinos,verbs=get;list;watch;create;update;delete;patch - func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.DynamicClient, logger logr.Logger) *controller.Controller { // Base options controllerOpts := []controller.ControllerOption{ @@ -139,7 +122,7 @@ func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.D )), controller.WithRunnable("authconfig watcher", controller.Watch( &authorinov1beta3.AuthConfig{}, - kuadrantv1beta1.AuthConfigsResource, + authorino.AuthConfigsResource, metav1.NamespaceAll, controller.FilterResourcesByLabel[*authorinov1beta3.AuthConfig](fmt.Sprintf("%s=true", kuadrantManagedLabelKey)), )), @@ -154,13 +137,13 @@ func NewPolicyMachineryController(manager ctrlruntime.Manager, client *dynamic.D ConfigMapGroupKind, kuadrantv1beta1.LimitadorGroupKind, kuadrantv1beta1.AuthorinoGroupKind, - kuadrantv1beta1.AuthConfigGroupKind, + authorino.AuthConfigGroupKind, ), controller.WithObjectLinks( kuadrantv1beta1.LinkKuadrantToGatewayClasses, kuadrantv1beta1.LinkKuadrantToLimitador, kuadrantv1beta1.LinkKuadrantToAuthorino, - kuadrantv1beta1.LinkHTTPRouteRuleToAuthConfig, + authorino.LinkHTTPRouteRuleToAuthConfig, ), } diff --git a/controllers/test_common.go b/controllers/test_common.go index eafd55a3d..7b8804352 100644 --- a/controllers/test_common.go +++ b/controllers/test_common.go @@ -25,36 +25,29 @@ package controllers import ( "encoding/json" - certmanv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" - egv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + + certmanv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + egv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1" + authorinoopapi "github.com/kuadrant/authorino-operator/api/v1beta1" + authorinoapi "github.com/kuadrant/authorino/api/v1beta3" + kuadrantdnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" + limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" consolev1 "github.com/openshift/api/console/v1" istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" istioclientnetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" - istiosecurityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" - istioapis "istio.io/istio/operator/pkg/apis" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/rest" - istiov1alpha1 "maistra.io/istio-operator/api/v1alpha1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - - authorinoopapi "github.com/kuadrant/authorino-operator/api/v1beta1" - authorinoapi "github.com/kuadrant/authorino/api/v1beta3" - kuadrantdnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" - limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" - maistraapis "github.com/kuadrant/kuadrant-operator/api/external/maistra" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/library/fieldindexers" - "github.com/kuadrant/kuadrant-operator/pkg/library/reconcilers" ) func SetupKuadrantOperatorForTest(s *runtime.Scheme, cfg *rest.Config) { @@ -65,27 +58,6 @@ func SetupKuadrantOperatorForTest(s *runtime.Scheme, cfg *rest.Config) { }) Expect(err).ToNot(HaveOccurred()) - err = fieldindexers.HTTPRouteIndexByGateway( - mgr, - log.Log.WithName("kuadrant").WithName("indexer").WithName("routeIndexByGateway"), - ) - Expect(err).ToNot(HaveOccurred()) - - gatewayKuadrantBaseReconciler := reconcilers.NewBaseReconciler( - mgr.GetClient(), - mgr.GetScheme(), - mgr.GetAPIReader(), - log.Log.WithName("kuadrant").WithName("gateway"), - ) - - err = (&GatewayKuadrantReconciler{ - BaseReconciler: gatewayKuadrantBaseReconciler, - }).SetupWithManager(mgr) - - Expect(err).NotTo(HaveOccurred()) - - Expect(err).NotTo(HaveOccurred()) - dClient, err := dynamic.NewForConfig(mgr.GetConfig()) Expect(err).NotTo(HaveOccurred()) @@ -122,17 +94,12 @@ func BootstrapScheme() *runtime.Scheme { kuadrantv1.AddToScheme, kuadrantv1beta1.AddToScheme, gatewayapiv1.Install, - gatewayapiv1beta1.Install, authorinoopapi.AddToScheme, authorinoapi.AddToScheme, - istioapis.AddToScheme, - istiov1alpha1.AddToScheme, - istiosecurityv1beta1.AddToScheme, limitadorv1alpha1.AddToScheme, istioclientnetworkingv1alpha3.AddToScheme, istioclientgoextensionv1alpha1.AddToScheme, certmanv1.AddToScheme, - maistraapis.AddToScheme, egv1alpha1.AddToScheme, consolev1.AddToScheme, ) diff --git a/controllers/tls_workflow.go b/controllers/tls_workflow.go index 34d96a00f..df25b3290 100644 --- a/controllers/tls_workflow.go +++ b/controllers/tls_workflow.go @@ -33,6 +33,13 @@ var ( CertManagerClusterIssuerKind = schema.GroupKind{Group: certmanager.GroupName, Kind: certmanagerv1.ClusterIssuerKind} ) +//+kubebuilder:rbac:groups=kuadrant.io,resources=tlspolicies,verbs=get;list;watch;update;patch +//+kubebuilder:rbac:groups=kuadrant.io,resources=tlspolicies/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=kuadrant.io,resources=tlspolicies/finalizers,verbs=update +//+kubebuilder:rbac:groups="cert-manager.io",resources=issuers,verbs=get;list;watch; +//+kubebuilder:rbac:groups="cert-manager.io",resources=clusterissuers,verbs=get;list;watch; +//+kubebuilder:rbac:groups="cert-manager.io",resources=certificates,verbs=get;list;watch;create;update;patch;delete + func NewTLSWorkflow(client *dynamic.DynamicClient, scheme *runtime.Scheme, isCertManagerInstalled bool) *controller.Workflow { return &controller.Workflow{ Precondition: NewTLSPoliciesValidator(isCertManagerInstalled).Subscription().Reconcile, diff --git a/controllers/tlspolicies_validator.go b/controllers/tlspolicies_validator.go index a45cfd970..596c549a2 100644 --- a/controllers/tlspolicies_validator.go +++ b/controllers/tlspolicies_validator.go @@ -16,7 +16,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) func NewTLSPoliciesValidator(isCertManagerInstalled bool) *TLSPoliciesValidator { diff --git a/controllers/tlspolicy_status_updater.go b/controllers/tlspolicy_status_updater.go index 3591747bc..12ca40b22 100644 --- a/controllers/tlspolicy_status_updater.go +++ b/controllers/tlspolicy_status_updater.go @@ -21,8 +21,8 @@ import ( gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) type TLSPolicyStatusUpdater struct { diff --git a/controllers/tlspolicy_status_updater_test.go b/controllers/tlspolicy_status_updater_test.go index 68d2e32e7..789125bdd 100644 --- a/controllers/tlspolicy_status_updater_test.go +++ b/controllers/tlspolicy_status_updater_test.go @@ -20,7 +20,7 @@ import ( gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) func TestTLSPolicyStatusTask_enforcedCondition(t *testing.T) { diff --git a/controllers/topology_reconciler.go b/controllers/topology_reconciler.go index f68931f8d..ad97731ed 100644 --- a/controllers/topology_reconciler.go +++ b/controllers/topology_reconciler.go @@ -12,7 +12,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/dynamic" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" ) const ( diff --git a/go.mod b/go.mod index c9f80b43a..d51cb47ec 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/elliotchance/orderedmap/v2 v2.2.0 github.com/envoyproxy/gateway v1.1.0 github.com/go-logr/logr v1.4.2 - github.com/goccy/go-yaml v1.12.0 github.com/google/go-cmp v0.6.0 github.com/kuadrant/authorino v0.19.0 github.com/kuadrant/authorino-operator v0.11.1 @@ -25,14 +24,12 @@ require ( gotest.tools v2.2.0+incompatible istio.io/api v1.22.3-0.20240703105953-437a88321a16 istio.io/client-go v1.22.3-0.20240703110620-5f69a1e4c030 - istio.io/istio v0.0.0-20240709015522-1e0dc8dd8809 k8s.io/api v0.31.1 k8s.io/apiextensions-apiserver v0.31.1 k8s.io/apimachinery v0.31.1 k8s.io/client-go v0.31.1 k8s.io/klog/v2 v2.130.1 k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 - maistra.io/istio-operator v0.0.0-20240217080932-98753cb28cd7 sigs.k8s.io/controller-runtime v0.19.0 sigs.k8s.io/external-dns v0.14.0 sigs.k8s.io/gateway-api v1.1.0 @@ -40,124 +37,44 @@ require ( ) require ( - github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect - github.com/BurntSushi/toml v1.4.0 // indirect - github.com/MakeNowJust/heredoc v1.0.0 // indirect - github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.2.1 // indirect - github.com/Masterminds/sprig/v3 v3.2.3 // indirect - github.com/Masterminds/squirrel v1.5.4 // indirect - github.com/Microsoft/hcsshim v0.12.3 // indirect - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/chai2010/gettext-go v1.0.3 // indirect - github.com/containerd/containerd v1.7.17 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/cyphar/filepath-securejoin v0.2.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/distribution/reference v0.6.0 // indirect - github.com/docker/cli v27.0.3+incompatible // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v27.1.1+incompatible // indirect - github.com/docker/docker-credential-helpers v0.8.2 // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-metrics v0.0.1 // indirect github.com/emicklei/dot v1.6.2 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect - github.com/fatih/color v1.17.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/foxcpp/go-mockdns v1.1.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-errors/errors v1.5.1 // indirect - github.com/go-gorp/gorp/v3 v3.1.0 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/btree v1.1.2 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 // indirect - github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.1 // indirect - github.com/gosuri/uitable v0.0.4 // indirect - github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect - github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v1.0.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmoiron/sqlx v1.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect - github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect - github.com/lib/pq v1.10.9 // indirect - github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/reflectwalk v1.0.2 // indirect - github.com/moby/locker v1.0.1 // indirect - github.com/moby/spdystream v0.4.0 // indirect - github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/redis/go-redis/extra/redisotel/v9 v9.5.3 // indirect - github.com/redis/go-redis/v9 v9.6.1 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/rubenv/sql-migrate v1.6.1 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sergi/go-diff v1.3.1 // indirect - github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/cobra v1.8.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect - github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect - github.com/xeipuuv/gojsonschema v1.2.0 // indirect - github.com/xlab/treeprint v1.2.0 // indirect - go.opentelemetry.io/contrib/exporters/autoexport v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect - go.opentelemetry.io/otel v1.29.0 // indirect - go.opentelemetry.io/otel/metric v1.29.0 // indirect - go.opentelemetry.io/otel/trace v1.29.0 // indirect - go.starlark.net v0.0.0-20240520160348-046347dcd104 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect @@ -167,28 +84,15 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.24.0 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect - google.golang.org/grpc v1.66.2 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - helm.sh/helm/v3 v3.15.3 // indirect - k8s.io/apiserver v0.31.1 // indirect - k8s.io/cli-runtime v0.30.2 // indirect - k8s.io/component-base v0.31.1 // indirect k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect - k8s.io/kubectl v0.30.2 // indirect - oras.land/oras-go v1.2.5 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/kustomize/api v0.17.2 // indirect - sigs.k8s.io/kustomize/kyaml v0.17.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) -replace maistra.io/istio-operator => github.com/maistra/istio-operator v0.0.0-20240217080932-98753cb28cd7 - replace github.com/imdario/mergo => dario.cat/mergo v0.3.5 diff --git a/go.sum b/go.sum index 308d0056e..c2b7b0dc8 100644 --- a/go.sum +++ b/go.sum @@ -1,108 +1,17 @@ -cel.dev/expr v0.15.0 h1:O1jzfJCQBfL5BFoYktaxwIhuttaQPsVWerH9/EEKx0w= -cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= dario.cat/mergo v0.3.5 h1:rybKppoxBoyv1JiXjzlqE4gdrhB0Xk/us0OW7yDEAl0= dario.cat/mergo v0.3.5/go.mod h1:fvkCdyGtdx6UQvuEimZ9mB2dzc2AymrLoRgHC4lz6ec= -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= -github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= -github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= -github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= -github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= -github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= -github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= -github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= -github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= -github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.12.3 h1:LS9NXqXhMoqNCplK1ApmVSfB4UnVLRDWRapB6EIlxE0= -github.com/Microsoft/hcsshim v0.12.3/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= -github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70= -github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cert-manager/cert-manager v1.16.1 h1:1ceFMqTtwiqY2vyfaRT85CNiVmK7pJjt3GebYCx9awY= github.com/cert-manager/cert-manager v1.16.1/go.mod h1:MfLVTL45hFZsqmaT1O0+b2ugaNNQQZttSFV9hASHUb0= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chai2010/gettext-go v1.0.3 h1:9liNh8t+u26xl5ddmWLmsOsdNLwkdRTg5AG+JnTiM80= -github.com/chai2010/gettext-go v1.0.3/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= -github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw= -github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= -github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= -github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/containerd/containerd v1.7.17 h1:KjNnn0+tAVQHAoaWRjmdak9WlvnFR/8rU1CHHy8Rm2A= -github.com/containerd/containerd v1.7.17/go.mod h1:vK+hhT4TIv2uejlcDlbVIc8+h/BqtKLIyNrtCZol8lI= -github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= -github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= -github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM= -github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= -github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/datawire/dlib v1.3.0 h1:KkmyXU1kwm3oPBk1ypR70YbcOlEXWzEbx5RE0iRXTGk= github.com/datawire/dlib v1.3.0/go.mod h1:NiGDmetmbkBvtznpWSx6C0vA0s0LK9aHna3LJDqjruk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/distribution/distribution/v3 v3.0.0-alpha.1 h1:jn7I1gvjOvmLztH1+1cLiUFud7aeJCIQcgzugtwjyJo= -github.com/distribution/distribution/v3 v3.0.0-alpha.1/go.mod h1:LCp4JZp1ZalYg0W/TN05jarCQu+h4w7xc7ZfQF4Y/cY= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ= -github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= -github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= -github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= -github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8= -github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= github.com/elliotchance/orderedmap/v2 v2.2.0 h1:7/2iwO98kYT4XkOjA9mBEIwvi4KpGB4cyHeOFOnj4Vk= github.com/elliotchance/orderedmap/v2 v2.2.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q= github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= @@ -111,40 +20,16 @@ github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtz github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/gateway v1.1.0 h1:4+mNtirUNwLudBj8y9qXqL10qXxEDwBytQOU/2YgINQ= github.com/envoyproxy/gateway v1.1.0/go.mod h1:9hrhbkuH7sBwB0pzMXm3AFyw+lxG3e+YCvuWaM6JKrw= -github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 h1:IgJPqnrlY2Mr4pYB6oaMKvFvwJ9H+X6CCY5x1vCTcpc= -github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA= -github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= -github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= -github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= -github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= -github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= -github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= -github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= -github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= -github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= -github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= @@ -153,41 +38,16 @@ github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ= -github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= -github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= -github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= -github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -196,63 +56,18 @@ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA= github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= -github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY= -github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd h1:PpuIBO5P3e9hpqBD0O/HjhShYuM6XE0i/lbE6J94kww= -github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= -github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ= -github.com/hashicorp/golang-lru/arc/v2 v2.0.7/go.mod h1:Pe7gBlGdc8clY5LJ0LpJXMt5AmgmWNH1g+oFFVUHOEc= -github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= -github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= -github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= -github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kuadrant/authorino v0.19.0 h1:vPkDWVgQPi5A91MfIyWe06rLW0ZaACd+8j2SZPKrbHc= @@ -267,168 +82,46 @@ github.com/kuadrant/policy-machinery v0.6.4 h1:UMdZ2p7WyUdOKcWlJA2w2MzJnB8/Nn4dT github.com/kuadrant/policy-machinery v0.6.4/go.mod h1:ZV4xS0CCxPgu/Xg6gz+YUaS9zqEXKOiAj33bZ67B6Lo= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= -github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= -github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= -github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= -github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= -github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A= -github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= -github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= -github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= -github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= -github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= -github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ= -github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= -github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= -github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= -github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/maistra/istio-operator v0.0.0-20240217080932-98753cb28cd7 h1:hb04aN5i9DRUXBQ1SuU+p006IGgaqqDQY1/8vzAUvY4= -github.com/maistra/istio-operator v0.0.0-20240217080932-98753cb28cd7/go.mod h1:E/Qq7Lq+C43qZ8G3XSEDgDc2qMjZdKx8Er0jdAK1fKE= github.com/martinlindhe/base36 v1.1.1 h1:1F1MZ5MGghBXDZ2KJ3QfxmiydlWOGB8HCEtkap5NkVg= github.com/martinlindhe/base36 v1.1.1/go.mod h1:vMS8PaZ5e/jV9LwFKlm0YLnXl/hpOihiBxKkIoc3g08= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= -github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= -github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= -github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= -github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= -github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= -github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= -github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= -github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= -github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= -github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= -github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= -github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/openshift/api v0.0.0-20240926211938-f89ab92f1597 h1:4T4Zeh5+fghPguNzQeDV3O/DRwUlwJ0sQDWFc7A8BBU= github.com/openshift/api v0.0.0-20240926211938-f89ab92f1597/go.mod h1:OOh6Qopf21pSzqNVCB5gomomBXb8o5sGKZxG2KNpaXM= -github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= -github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= -github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= -github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_golang v1.20.4 h1:Tgh3Yr67PaOv/uTqloMsCEdeuFTatm5zIq5+qNN23vI= github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/prometheus v0.51.1 h1:V2e7x2oiUC0Megp26+xjffxBf9EGkyP1iQuGd4VjUSU= -github.com/prometheus/prometheus v0.51.1/go.mod h1:yv4MwOn3yHMQ6MZGHPg/U7Fcyqf+rxqiZfSur6myVtc= -github.com/redis/go-redis/extra/rediscmd/v9 v9.5.3 h1:1/BDligzCa40GTllkDnY3Y5DTHuKCONbB2JcRyIfl20= -github.com/redis/go-redis/extra/rediscmd/v9 v9.5.3/go.mod h1:3dZmcLn3Qw6FLlWASn1g4y+YO9ycEFUOM+bhBmzLVKQ= -github.com/redis/go-redis/extra/redisotel/v9 v9.5.3 h1:kuvuJL/+MZIEdvtb/kTBRiRgYaOmx1l+lYJyVdrRUOs= -github.com/redis/go-redis/extra/redisotel/v9 v9.5.3/go.mod h1:7f/FMrf5RRRVHXgfk7CzSVzXHiWeuOQUu2bsVqWoa+g= -github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= -github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rubenv/sql-migrate v1.6.1 h1:bo6/sjsan9HaXAsNxYP/jCEDUGibHp8JmOBw7NTGRos= -github.com/rubenv/sql-migrate v1.6.1/go.mod h1:tPzespupJS0jacLfhbwto/UjSX+8h2FdWB7ar+QlHa0= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= -github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= -github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -438,163 +131,44 @@ github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7 h1:GMw3nE github.com/telepresenceio/watchable v0.0.0-20220726211108-9bb86f92afa7/go.mod h1:ihJ97e2gsd8GuzFF/I3B1qcik3XZLpXjumQifXi8Slg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= -github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= -github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/bridges/prometheus v0.53.0 h1:BdkKDtcrHThgjcEia1737OUuFdP6xzBKAMx2sNZCkvE= -go.opentelemetry.io/contrib/bridges/prometheus v0.53.0/go.mod h1:ZkhVxcJgeXlL/lVyT/vxNHVFiSG5qOaDwYaSgD8IfZo= -go.opentelemetry.io/contrib/exporters/autoexport v0.53.0 h1:13K+tY7E8GJInkrvRiPAhC0gi/7vKjzDNhtmCf+QXG8= -go.opentelemetry.io/contrib/exporters/autoexport v0.53.0/go.mod h1:lyQF6xQ4iDnMg4sccNdFs1zf62xd79YI8vZqKjOTwMs= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= -go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0 h1:zBPZAISA9NOc5cE8zydqDiS0itvg/P/0Hn9m72a5gvM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.4.0/go.mod h1:gcj2fFjEsqpV3fXuzAA+0Ze1p2/4MJ4T7d77AmkvueQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0 h1:U2guen0GhqH8o/G2un8f/aG/y++OuW6MyCo6hT9prXk= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.28.0/go.mod h1:yeGZANgEcpdx/WK0IvvRFC+2oLiMS2u4L/0Rj2M2Qr0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 h1:aLmmtjRke7LPDQ3lvpFz+kNEH43faFhzW7v8BFIEydg= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0/go.mod h1:TC1pyCt6G9Sjb4bQpShH+P5R53pO6ZuGnHuuln9xMeE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= -go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng= -go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0 h1:0MH3f8lZrflbUWXVxyBg/zviDFdGE062uKh5+fu8Vv0= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.4.0/go.mod h1:Vh68vYiHY5mPdekTr0ox0sALsqjoVy0w3Os278yX5SQ= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0 h1:BJee2iLkfRfl9lc7aFmBwkWxY/RI1RDdXepSF6y8TPE= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.28.0/go.mod h1:DIzlHs3DRscCIBU3Y9YSzPfScwnYnzfnCd4g8zA7bZc= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y= -go.opentelemetry.io/otel/log v0.4.0 h1:/vZ+3Utqh18e8TPjuc3ecg284078KWrR8BRz+PQAj3o= -go.opentelemetry.io/otel/log v0.4.0/go.mod h1:DhGnQvky7pHy82MIRV43iXh3FlKN8UUKftn0KbLOq6I= -go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/sdk/log v0.4.0 h1:1mMI22L82zLqf6KtkjrRy5BbagOTWdJsqMY/HSqILAA= -go.opentelemetry.io/otel/sdk/log v0.4.0/go.mod h1:AYJ9FVF0hNOgAVzUG/ybg/QttnXhUePWAupmCqtdESo= -go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= -go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= -go.opentelemetry.io/otel/trace v1.29.0 h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= -go.starlark.net v0.0.0-20240520160348-046347dcd104 h1:3qhteRISupnJvaWshOmeqEUs2y9oc/+/ePPvDh3Eygg= -go.starlark.net v0.0.0-20240520160348-046347dcd104/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= @@ -603,19 +177,15 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0= google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= @@ -624,19 +194,13 @@ google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= -gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -645,40 +209,24 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -helm.sh/helm/v3 v3.15.3 h1:HcZDaVFe9uHa6hpsR54mJjYyRy4uz/pc6csg27nxFOc= -helm.sh/helm/v3 v3.15.3/go.mod h1:FzSIP8jDQaa6WAVg9F+OkKz7J0ZmAga4MABtTbsb9WQ= istio.io/api v1.22.3-0.20240703105953-437a88321a16 h1:0XRnzLqAZ1BYX1jBzBG1slXytUkdhRoVwC23upTyFl4= istio.io/api v1.22.3-0.20240703105953-437a88321a16/go.mod h1:S3l8LWqNYS9yT+d4bH+jqzH2lMencPkW7SKM1Cu9EyM= istio.io/client-go v1.22.3-0.20240703110620-5f69a1e4c030 h1:K/G2h2qeso2/xuNQFDNiJqcVNvOlyjsdACDN6Db+zkI= istio.io/client-go v1.22.3-0.20240703110620-5f69a1e4c030/go.mod h1:D/vNne1n5586423NgGXMnPgshE/99mQgnjnxK/Vw2yM= -istio.io/istio v0.0.0-20240709015522-1e0dc8dd8809 h1:Befi25J316GG748aL96JtBf/fbFEyxJ3tosqG0b5SaI= -istio.io/istio v0.0.0-20240709015522-1e0dc8dd8809/go.mod h1:SUACpPO3/iqxIDDMTPbngKB6gv7ht90iMBa6ddfq9qw= k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU= k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI= k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40= k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ= k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c= -k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM= -k8s.io/cli-runtime v0.30.2 h1:ooM40eEJusbgHNEqnHziN9ZpLN5U4WcQGsdLKVxpkKE= -k8s.io/cli-runtime v0.30.2/go.mod h1:Y4g/2XezFyTATQUbvV5WaChoUGhojv/jZAtdp5Zkm0A= k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0= k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg= -k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8= -k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUxmcUV/CtNU8QM7h1FLWQOo= k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= -k8s.io/kubectl v0.30.2 h1:cgKNIvsOiufgcs4yjvgkK0+aPCfa8pUwzXdJtkbhsH8= -k8s.io/kubectl v0.30.2/go.mod h1:rz7GHXaxwnigrqob0lJsiA07Df8RE3n1TSaC2CTeuB4= k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI= k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= -oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= sigs.k8s.io/external-dns v0.14.0 h1:pgY3DdyoBei+ej1nyZUzRt9ECm9RRwb9s6/CPWe51tc= @@ -687,12 +235,6 @@ sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM= sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/kustomize/api v0.17.2 h1:E7/Fjk7V5fboiuijoZHgs4aHuexi5Y2loXlVOAVAG5g= -sigs.k8s.io/kustomize/api v0.17.2/go.mod h1:UWTz9Ct+MvoeQsHcJ5e+vziRRkwimm3HytpZgIYqye0= -sigs.k8s.io/kustomize/kyaml v0.17.1 h1:TnxYQxFXzbmNG6gOINgGWQt09GghzgTP6mIurOgrLCQ= -sigs.k8s.io/kustomize/kyaml v0.17.1/go.mod h1:9V0mCjIEYjlXuCdYsSXvyoy2BTsLESH7TlGV81S282U= -sigs.k8s.io/mcs-api v0.1.0 h1:edDbg0oRGfXw8TmZjKYep06LcJLv/qcYLidejnUp0PM= -sigs.k8s.io/mcs-api v0.1.0/go.mod h1:gGiAryeFNB4GBsq2LBmVqSgKoobLxt+p7ii/WG5QYYw= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/main.go b/main.go index d44f4ca93..8c7f6a3e9 100644 --- a/main.go +++ b/main.go @@ -31,30 +31,22 @@ import ( consolev1 "github.com/openshift/api/console/v1" istioextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" istionetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" - istiosecurityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" - istioapis "istio.io/istio/operator/pkg/apis" corev1 "k8s.io/api/core/v1" apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" k8sruntime "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/dynamic" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - _ "k8s.io/client-go/plugin/pkg/client/auth" "k8s.io/utils/env" - istiov1alpha1 "maistra.io/istio-operator/api/v1alpha1" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/healthz" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - maistraapis "github.com/kuadrant/kuadrant-operator/api/external/maistra" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/library/fieldindexers" - "github.com/kuadrant/kuadrant-operator/pkg/library/reconcilers" "github.com/kuadrant/kuadrant-operator/pkg/log" "github.com/kuadrant/kuadrant-operator/version" //+kubebuilder:scaffold:imports @@ -75,15 +67,9 @@ func init() { utilruntime.Must(authorinoopapi.AddToScheme(scheme)) utilruntime.Must(authorinoapi.AddToScheme(scheme)) utilruntime.Must(istionetworkingv1alpha3.AddToScheme(scheme)) - utilruntime.Must(istiosecurityv1beta1.AddToScheme(scheme)) - utilruntime.Must(istiov1alpha1.AddToScheme(scheme)) utilruntime.Must(gatewayapiv1.Install(scheme)) - utilruntime.Must(gatewayapiv1beta1.Install(scheme)) utilruntime.Must(istioextensionv1alpha1.AddToScheme(scheme)) utilruntime.Must(apiextv1.AddToScheme(scheme)) - utilruntime.Must(istioapis.AddToScheme(scheme)) - utilruntime.Must(istiov1alpha1.AddToScheme(scheme)) - utilruntime.Must(maistraapis.AddToScheme(scheme)) utilruntime.Must(kuadrantv1.AddToScheme(scheme)) utilruntime.Must(kuadrantv1beta1.AddToScheme(scheme)) utilruntime.Must(kuadrantdnsv1alpha1.AddToScheme(scheme)) @@ -146,26 +132,6 @@ func main() { os.Exit(1) } - if err = fieldindexers.HTTPRouteIndexByGateway( - mgr, - log.Log.WithName("kuadrant").WithName("indexer").WithName("routeIndexByGateway"), - ); err != nil { - setupLog.Error(err, "unable to add indexer") - os.Exit(1) - } - - gatewayKuadrantBaseReconciler := reconcilers.NewBaseReconciler( - mgr.GetClient(), mgr.GetScheme(), mgr.GetAPIReader(), - log.Log.WithName("kuadrant").WithName("gateway"), - ) - - if err = (&controllers.GatewayKuadrantReconciler{ - BaseReconciler: gatewayKuadrantBaseReconciler, - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", "GatewayKuadrant") - os.Exit(1) - } - //+kubebuilder:scaffold:builder if err = mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/pkg/common/authorino_conditions.go b/pkg/authorino/conditions.go similarity index 95% rename from pkg/common/authorino_conditions.go rename to pkg/authorino/conditions.go index c50a36751..49010b476 100644 --- a/pkg/common/authorino_conditions.go +++ b/pkg/authorino/conditions.go @@ -1,4 +1,4 @@ -package common +package authorino import ( authorinov1beta1 "github.com/kuadrant/authorino-operator/api/v1beta1" diff --git a/pkg/common/authorino_conditions_test.go b/pkg/authorino/conditions_test.go similarity index 92% rename from pkg/common/authorino_conditions_test.go rename to pkg/authorino/conditions_test.go index efdc55fe5..d7e48f057 100644 --- a/pkg/common/authorino_conditions_test.go +++ b/pkg/authorino/conditions_test.go @@ -1,11 +1,11 @@ //go:build unit -package common +package authorino import ( "testing" - goCmp "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp" authorinov1beta1 "github.com/kuadrant/authorino-operator/api/v1beta1" ) @@ -47,7 +47,7 @@ func TestFindAuthorinoStatusCondition(t *testing.T) { t.Run(tc.name, func(t *testing.T) { result := FindAuthorinoStatusCondition(tc.input, tc.conditionType) - if diff := goCmp.Diff(tc.expected, result); diff != "" { + if diff := cmp.Diff(tc.expected, result); diff != "" { t.Errorf("Condition mismatch (-want +got):\n%s", diff) } }) diff --git a/pkg/authorino/utils.go b/pkg/authorino/utils.go new file mode 100644 index 000000000..d33a8a92e --- /dev/null +++ b/pkg/authorino/utils.go @@ -0,0 +1,36 @@ +package authorino + +import ( + authorinov1beta3 "github.com/kuadrant/authorino/api/v1beta3" + "github.com/kuadrant/policy-machinery/controller" + "github.com/kuadrant/policy-machinery/machinery" + "github.com/samber/lo" + "k8s.io/apimachinery/pkg/runtime/schema" + gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" +) + +var ( + AuthConfigGroupKind = schema.GroupKind{Group: authorinov1beta3.GroupVersion.Group, Kind: "AuthConfig"} + AuthConfigsResource = authorinov1beta3.GroupVersion.WithResource("authconfigs") + + AuthConfigHTTPRouteRuleAnnotation = machinery.HTTPRouteRuleGroupKind.String() +) + +func LinkHTTPRouteRuleToAuthConfig(objs controller.Store) machinery.LinkFunc { + httpRoutes := lo.Map(objs.FilterByGroupKind(machinery.HTTPRouteGroupKind), controller.ObjectAs[*gatewayapiv1.HTTPRoute]) + httpRouteRules := lo.FlatMap(lo.Map(httpRoutes, func(r *gatewayapiv1.HTTPRoute, _ int) *machinery.HTTPRoute { + return &machinery.HTTPRoute{HTTPRoute: r} + }), machinery.HTTPRouteRulesFromHTTPRouteFunc) + + return machinery.LinkFunc{ + From: machinery.HTTPRouteRuleGroupKind, + To: AuthConfigGroupKind, + Func: func(child machinery.Object) []machinery.Object { + return lo.FilterMap(httpRouteRules, func(httpRouteRule *machinery.HTTPRouteRule, _ int) (machinery.Object, bool) { + authConfig := child.(*controller.RuntimeObject).Object.(*authorinov1beta3.AuthConfig) + annotations := authConfig.GetAnnotations() + return httpRouteRule, annotations != nil && annotations[AuthConfigHTTPRouteRuleAnnotation] == httpRouteRule.GetLocator() + }) + }, + } +} diff --git a/pkg/common/common.go b/pkg/common/common.go deleted file mode 100644 index cd01b0568..000000000 --- a/pkg/common/common.go +++ /dev/null @@ -1,95 +0,0 @@ -/* -Copyright 2021 Red Hat, Inc. - -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 common - -import ( - "crypto/sha256" - "fmt" - "strings" - - "github.com/martinlindhe/base36" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// TODO: move the const to a proper place, or get it from config -const ( - KuadrantRateLimitClusterName = "kuadrant-ratelimit-service" - KuadrantAuthClusterName = "kuadrant-auth-service" - LimitadorName = "limitador" - - NamespaceSeparator = '/' -) - -// MergeMapStringString Merge desired into existing. -// Not Thread-Safe. Does it matter? -func MergeMapStringString(existing *map[string]string, desired map[string]string) bool { - modified := false - - if *existing == nil { - *existing = map[string]string{} - } - - for k, v := range desired { - if existingVal, ok := (*existing)[k]; !ok || v != existingVal { - (*existing)[k] = v - modified = true - } - } - - return modified -} - -// UnMarshallLimitNamespace parses limit namespace with format "gwNS/gwName#domain" -func UnMarshallLimitNamespace(ns string) (client.ObjectKey, string, error) { - delimIndex := strings.IndexRune(ns, '#') - if delimIndex == -1 { - return client.ObjectKey{}, "", fmt.Errorf("failed to split on #") - } - - gwSplit := ns[:delimIndex] - domain := ns[delimIndex+1:] - - objKey, err := UnMarshallObjectKey(gwSplit) - if err != nil { - return client.ObjectKey{}, "", err - } - - return objKey, domain, nil -} - -// UnMarshallObjectKey takes a string input and converts it into an ObjectKey struct that -// can be used to access a specific Kubernetes object. The input string is expected to be in the format "namespace/name". -// If the input string does not contain a NamespaceSeparator (typically '/') -// or has too few components, this function returns an error. -func UnMarshallObjectKey(keyStr string) (client.ObjectKey, error) { - namespaceEndIndex := strings.IndexRune(keyStr, NamespaceSeparator) - if namespaceEndIndex < 0 { - return client.ObjectKey{}, fmt.Errorf(fmt.Sprintf("failed to split on %s: '%s'", string(NamespaceSeparator), keyStr)) - } - - return client.ObjectKey{Namespace: keyStr[:namespaceEndIndex], Name: keyStr[namespaceEndIndex+1:]}, nil -} - -func ToBase36Hash(s string) string { - hash := sha256.Sum224([]byte(s)) - // convert the hash to base36 (alphanumeric) to decrease collision probabilities - return strings.ToLower(base36.EncodeBytes(hash[:])) -} - -func ToBase36HashLen(s string, l int) string { - return ToBase36Hash(s)[:l] -} diff --git a/pkg/common/common_test.go b/pkg/common/common_test.go deleted file mode 100644 index aa6a16e8f..000000000 --- a/pkg/common/common_test.go +++ /dev/null @@ -1,221 +0,0 @@ -//go:build unit - -package common - -import ( - "fmt" - "reflect" - "testing" - - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func TestMergeMapStringString(t *testing.T) { - testCases := []struct { - name string - existing map[string]string - desired map[string]string - expected bool - expectedState map[string]string - }{ - { - name: "when existing and desired are empty then return false and not modify the existing map", - existing: map[string]string{}, - desired: map[string]string{}, - expected: false, - expectedState: map[string]string{}, - }, - { - name: "when existing is empty and desired has values then return true and set the values in the existing map", - existing: map[string]string{}, - desired: map[string]string{"a": "1", "b": "2"}, - expected: true, - expectedState: map[string]string{"a": "1", "b": "2"}, - }, - { - name: "when existing has some values and desired has different/new values then return true and modify the existing map", - existing: map[string]string{"a": "1", "b": "2"}, - desired: map[string]string{"a": "3", "c": "4"}, - expected: true, - expectedState: map[string]string{"a": "3", "b": "2", "c": "4"}, - }, - { - name: "when existing has all the values from desired then return false and not modify the existing map", - existing: map[string]string{"a": "1", "b": "2"}, - desired: map[string]string{"a": "1", "b": "2"}, - expected: false, - expectedState: map[string]string{"a": "1", "b": "2"}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - existingCopy := make(map[string]string, len(tc.existing)) - for k, v := range tc.existing { - existingCopy[k] = v - } - modified := MergeMapStringString(&existingCopy, tc.desired) - - if modified != tc.expected { - t.Errorf("MergeMapStringString(%v, %v) returned %v; expected %v", tc.existing, tc.desired, modified, tc.expected) - } - - if !reflect.DeepEqual(existingCopy, tc.expectedState) { - t.Errorf("MergeMapStringString(%v, %v) modified the existing map to %v; expected %v", tc.existing, tc.desired, existingCopy, tc.expectedState) - } - }) - } -} - -func TestUnMarshallLimitNamespace(t *testing.T) { - testCases := []struct { - name string - namespace string - expectedKey client.ObjectKey - expectedDomain string - expectedError bool - }{ - { - name: "when namespace is valid and contains both namespace and domain then return the correct values", - namespace: "exampleNS/exampleGW#domain.com", - expectedKey: client.ObjectKey{Name: "exampleGW", Namespace: "exampleNS"}, - expectedDomain: "domain.com", - expectedError: false, - }, - { - name: "when namespace is invalid (no '#domain') then return an error", - namespace: "exampleNS/exampleGW", - expectedKey: client.ObjectKey{}, - expectedDomain: "", - expectedError: true, - }, - { - name: "when namespace missing both namespace and gateway parts then return an error", - namespace: "#domain.com", - expectedKey: client.ObjectKey{}, - expectedDomain: "", - expectedError: true, - }, - { - name: "when namespace has no domain name then return correct values", - namespace: "exampleNS/exampleGW#", - expectedKey: client.ObjectKey{Namespace: "exampleNS", Name: "exampleGW"}, - expectedDomain: "", - expectedError: false, - }, - { - name: "when namespace only has gateway name (missing 'namespace/') and domain then return an error", - namespace: "exampleGW#domain.com", - expectedKey: client.ObjectKey{}, - expectedDomain: "", - expectedError: true, - }, - { - name: "when namespace only has namespace name (missing '/gwName') and domain then return an error", - namespace: "exampleNS#domain.com", - expectedKey: client.ObjectKey{}, - expectedDomain: "", - expectedError: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - key, domain, err := UnMarshallLimitNamespace(tc.namespace) - - if tc.expectedError { - if err == nil { - t.Errorf("Expected an error, but got %v", err) - } - } else { - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - if key != tc.expectedKey { - t.Errorf("Expected %v, but got %v", tc.expectedKey, key) - } - - if domain != tc.expectedDomain { - t.Errorf("Expected %v, but got %v", tc.expectedDomain, domain) - } - } - }) - } -} - -func TestUnMarshallObjectKey(t *testing.T) { - testCases := []struct { - name string - input string - expectedOutput client.ObjectKey - expectedError error - }{ - { - name: "when valid key string then return valid ObjectKey", - input: "default/object1", - expectedOutput: client.ObjectKey{Namespace: "default", Name: "object1"}, - expectedError: nil, - }, - { - name: "when valid key string with non-default namespace then return valid ObjectKey", - input: "kube-system/object2", - expectedOutput: client.ObjectKey{Namespace: "kube-system", Name: "object2"}, - expectedError: nil, - }, - { - name: "when invalid namespace and name then return empty ObjectKey and error", - input: "invalid", - expectedOutput: client.ObjectKey{}, - expectedError: fmt.Errorf("failed to split on %s: 'invalid'", string(NamespaceSeparator)), - }, - { - name: "when '#' separator used instead of default separator ('/') then return an error", - input: "default#object1", - expectedOutput: client.ObjectKey{}, - expectedError: fmt.Errorf("failed to split on %s: 'default#object1'", string(NamespaceSeparator)), - }, - { - name: "when input string is empty then return an error", - input: "", - expectedOutput: client.ObjectKey{}, - expectedError: fmt.Errorf("failed to split on %s: ''", string(NamespaceSeparator)), - }, - { - name: "when empty namespace and name then return valid empty ObjectKey", - input: "/", - expectedOutput: client.ObjectKey{}, - expectedError: nil, - }, - { - name: "when valid namespace and empty name (strKey ends with '/') then return valid ObjectKey with namespace only", - input: "default/", - expectedOutput: client.ObjectKey{Namespace: "default", Name: ""}, - expectedError: nil, - }, - { - name: "when valid name and empty namespace (strKey starts with '/') then return valid ObjectKey with name only", - input: "/object", - expectedOutput: client.ObjectKey{Namespace: "", Name: "object"}, - expectedError: nil, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - output, err := UnMarshallObjectKey(tc.input) - - if err != nil && tc.expectedError == nil { - t.Errorf("unexpected error: got %v, want nil", err) - } else if err == nil && tc.expectedError != nil { - t.Errorf("expected error but got nil") - } else if err != nil && tc.expectedError != nil && err.Error() != tc.expectedError.Error() { - t.Errorf("unexpected error: got '%v', want '%v'", err, tc.expectedError) - } - - if output != tc.expectedOutput { - t.Errorf("unexpected output: got %v, want %v", output, tc.expectedOutput) - } - }) - } -} diff --git a/pkg/common/yaml_decoder.go b/pkg/common/yaml_decoder.go deleted file mode 100644 index cf5cfe4ba..000000000 --- a/pkg/common/yaml_decoder.go +++ /dev/null @@ -1,60 +0,0 @@ -package common - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer" - "k8s.io/apimachinery/pkg/util/yaml" -) - -type DecodeCallback = func(runtime.Object) error - -// DecodeFile decodes the provided file data (encoded YAML documents) into Kubernetes objects using the specified scheme, -// and invokes the callback function for each decoded object. Returns an error if any decoding error occurs. -func DecodeFile(ctx context.Context, fileData []byte, scheme *runtime.Scheme, cb DecodeCallback) error { - logger, logErr := logr.FromContext(ctx) - codec := serializer.NewCodecFactory(scheme) - decoder := codec.UniversalDeserializer() - - if logErr != nil { - return logErr - } - - // the maximum size used to buffer a doc 5M - buf := make([]byte, 5*1024*1024) - docDecoder := yaml.NewDocumentDecoder(io.NopCloser(bytes.NewReader(fileData))) - - for { - n, err := docDecoder.Read(buf) - if err != nil { - if errors.Is(io.EOF, err) { - break - } - return err - } - - if n == 0 || string(fileData) == "---" { - // Skip empty docs - continue - } - - docData := buf[:n] - obj, _, err := decoder.Decode(docData, nil, nil) - if err != nil { - logger.Info("Document decode error", "error", err) - return fmt.Errorf("failed to decode document: %w", err) - } - - err = cb(obj) - if err != nil { - return err - } - } - return nil -} diff --git a/pkg/common/yaml_decoder_test.go b/pkg/common/yaml_decoder_test.go deleted file mode 100644 index 2aa340381..000000000 --- a/pkg/common/yaml_decoder_test.go +++ /dev/null @@ -1,290 +0,0 @@ -//go:build unit - -package common - -import ( - "bytes" - "context" - "fmt" - "testing" - - "github.com/go-logr/logr" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/kuadrant/kuadrant-operator/pkg/log" -) - -type testCase struct { - name string - fileData []byte - objects []runtime.Object - expectErr bool - expectLogs bool -} - -func TestDecodeFile(t *testing.T) { - testCases := []testCase{ - { - name: "when decoding doc with known valid Kubernetes object then return no error or logs", - fileData: []byte(` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: example-deployment -spec: - replicas: 3 - template: - spec: - containers: - - name: nginx - image: nginx:latest - ports: - - containerPort: 80 -`), - objects: []runtime.Object{&appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "apps/v1", - }, - }}, - expectErr: false, - expectLogs: false, - }, - { - name: "when decoding multidoc YAML file with valid Kubernetes objects then return no error or logs", - fileData: []byte(` ---- -apiVersion: apps/v1 -kind: Pod -metadata: - name: example-pod -spec: - containers: - - name: nginx - image: nginx:latest - ports: - - containerPort: 80 ---- -apiVersion: apps/v1 -kind: Service -metadata: - name: example-service -spec: - selector: - app: nginx - ports: - - protocol: TCP - port: 80 - targetPort: 80 -`), - objects: []runtime.Object{&corev1.Pod{ - TypeMeta: metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "apps/v1", - }, - }, &corev1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - APIVersion: "apps/v1", - }, - }}, - expectErr: false, - expectLogs: false, - }, - { - name: "when decoding doc with invalid object then return error and logs", - fileData: []byte(` -apiVersion: v1 -kind: InvalidObject -metadata: - name: example-invalid -spec: - invalidField: invalidValue -`), - objects: []runtime.Object{&corev1.Pod{ - TypeMeta: metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "apps/v1", - }, - }, &corev1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - APIVersion: "apps/v1", - }, - }}, - expectErr: true, - expectLogs: true, - }, - { - name: "when decoding doc with known Kubernetes object which misses Kind then return error and logs", - fileData: []byte(` -apiVersion: v1 -metadata: - name: example-object -`), - objects: []runtime.Object{}, - expectErr: true, - expectLogs: true, - }, - { - name: "when decoding empty doc (consists of '---') then return error and logs", - fileData: []byte(`--- ---- -`), - objects: []runtime.Object{&corev1.Pod{ - TypeMeta: metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "apps/v1", - }, - }}, - expectErr: true, - expectLogs: true, - }, - { - name: "when decoding empty doc (empty file data) then return error and logs", - fileData: []byte(``), - objects: []runtime.Object{&corev1.Pod{ - TypeMeta: metav1.TypeMeta{ - Kind: "Pod", - APIVersion: "apps/v1", - }, - }}, - expectErr: false, - expectLogs: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - logBuffer := bytes.Buffer{} - logger := log.NewLogger( - log.WriteTo(&logBuffer), - log.SetLevel(log.DebugLevel), - log.SetMode(log.ModeDev)) - - scheme := runtime.NewScheme() - - // Add the necessary scheme information for decoding objects - for _, obj := range tc.objects { - gvk := schema.GroupVersionKind{ - Group: obj.GetObjectKind().GroupVersionKind().Group, - Version: obj.GetObjectKind().GroupVersionKind().Version, - Kind: obj.GetObjectKind().GroupVersionKind().Kind, - } - scheme.AddKnownTypeWithName(gvk, obj) - } - - ctx := logr.NewContext(context.Background(), logger) - - callback := func(obj runtime.Object) error { - // Fake callback function to handle the decoded object, - // perform validation and return an error if the object is invalid - switch obj := obj.(type) { - case *corev1.Pod, *appsv1.Deployment, *corev1.Service: - // valid object types - default: - return fmt.Errorf("unexpected object type: %T", obj) - } - - return nil - } - - // Call the DecodeFile function with the provided context, file data, scheme, and callback - err := DecodeFile(ctx, tc.fileData, scheme, callback) - - if (err != nil) != tc.expectErr { - if tc.expectErr { - t.Errorf("expected error, but got nil") - } else { - t.Errorf("unexpected error: %v", err) - } - } - - if tc.expectLogs && logBuffer.Len() == 0 { - t.Errorf("expected logs, but got none") - } - if !tc.expectLogs && logBuffer.Len() > 0 { - t.Errorf("unexpected logs: %s", logBuffer.String()) - } - }) - } -} - -func TestDecodeFileDetailedValidation(t *testing.T) { - t.Run("when decoding a valid Kubernetes object with detailed validation in callback then validate the object", func(t *testing.T) { - fileData := []byte(` -apiVersion: apps/v1 -kind: Deployment -metadata: - name: example-deployment -spec: - replicas: 3 - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: nginx:latest - ports: - - containerPort: 80 -`) - - logBuffer := bytes.Buffer{} - logger := log.NewLogger( - log.WriteTo(&logBuffer), - log.SetLevel(log.DebugLevel), - log.SetMode(log.ModeDev)) - - scheme := runtime.NewScheme() - scheme.AddKnownTypes(schema.GroupVersion{ - Group: "apps", - Version: "v1", - }, &appsv1.Deployment{}) - - ctx := logr.NewContext(context.Background(), logger) - - callback := func(obj runtime.Object) error { - deployment, ok := obj.(*appsv1.Deployment) - if !ok { - return fmt.Errorf("unexpected object type: %T", obj) - } - - // Perform validations on the deployment object - if deployment.Name != "example-deployment" { - t.Errorf("unexpected deployment name: %s", deployment.Name) - } - if *deployment.Spec.Replicas != int32(3) { - t.Errorf("unexpected number of replicas: %d", *deployment.Spec.Replicas) - } - if len(deployment.Spec.Template.Spec.Containers) != 1 { - t.Errorf("unexpected number of containers: %d", len(deployment.Spec.Template.Spec.Containers)) - } - if deployment.Spec.Template.Spec.Containers[0].Name != "nginx" { - t.Errorf("unexpected container name: %s", deployment.Spec.Template.Spec.Containers[0].Name) - } - if deployment.Spec.Template.Spec.Containers[0].Image != "nginx:latest" { - t.Errorf("unexpected container image: %s", deployment.Spec.Template.Spec.Containers[0].Image) - } - if deployment.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort != 80 { - t.Errorf("unexpected container port: %d", deployment.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort) - } - - return nil - } - - err := DecodeFile(ctx, fileData, scheme, callback) - if (err != nil) != false { - t.Errorf("unexpected error: %v", err) - } - - if logBuffer.Len() > 0 { - t.Errorf("unexpected logs: %s", logBuffer.String()) - } - }) -} diff --git a/pkg/envoygateway/mutators.go b/pkg/envoygateway/mutators.go deleted file mode 100644 index 10847dead..000000000 --- a/pkg/envoygateway/mutators.go +++ /dev/null @@ -1,69 +0,0 @@ -package envoygateway - -import ( - "fmt" - "reflect" - - egv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" -) - -func EnvoySecurityPolicyMutator(existingObj, desiredObj client.Object) (bool, error) { - existing, ok := existingObj.(*egv1alpha1.SecurityPolicy) - if !ok { - return false, fmt.Errorf("%T is not an *egapi.SecurityPolicy", existingObj) - } - desired, ok := desiredObj.(*egv1alpha1.SecurityPolicy) - if !ok { - return false, fmt.Errorf("%T is not an *egapi.SecurityPolicy", desiredObj) - } - - var update bool - - if !reflect.DeepEqual(existing.Spec.ExtAuth, desired.Spec.ExtAuth) { - update = true - existing.Spec.ExtAuth = desired.Spec.ExtAuth - } - - if !reflect.DeepEqual(existing.Spec.PolicyTargetReferences.TargetRefs, desired.Spec.PolicyTargetReferences.TargetRefs) { - update = true - existing.Spec.PolicyTargetReferences.TargetRefs = desired.Spec.PolicyTargetReferences.TargetRefs - } - - if !reflect.DeepEqual(existing.Annotations, desired.Annotations) { - update = true - existing.Annotations = desired.Annotations - } - - return update, nil -} - -func SecurityPolicyReferenceGrantMutator(existingObj, desiredObj client.Object) (bool, error) { - existing, ok := existingObj.(*gatewayapiv1beta1.ReferenceGrant) - if !ok { - return false, fmt.Errorf("%T is not an *gatewayapiv1beta1.ReferenceGrant", existingObj) - } - desired, ok := desiredObj.(*gatewayapiv1beta1.ReferenceGrant) - if !ok { - return false, fmt.Errorf("%T is not an *gatewayapiv1beta1.ReferenceGrant", desiredObj) - } - - var update bool - if !reflect.DeepEqual(existing.Spec.From, desired.Spec.From) { - update = true - existing.Spec.From = desired.Spec.From - } - - if !reflect.DeepEqual(existing.Spec.To, desired.Spec.To) { - update = true - existing.Spec.To = desired.Spec.To - } - - if !reflect.DeepEqual(existing.Annotations, desired.Annotations) { - update = true - existing.Annotations = desired.Annotations - } - - return update, nil -} diff --git a/pkg/envoygateway/utils.go b/pkg/envoygateway/utils.go index 7fc981992..48e5266e6 100644 --- a/pkg/envoygateway/utils.go +++ b/pkg/envoygateway/utils.go @@ -14,7 +14,7 @@ import ( gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) var ( @@ -41,24 +41,8 @@ func IsEnvoyExtensionPolicyInstalled(restMapper meta.RESTMapper) (bool, error) { envoygatewayv1alpha1.GroupVersion.Version) } -func IsEnvoyGatewaySecurityPolicyInstalled(restMapper meta.RESTMapper) (bool, error) { - return utils.IsCRDInstalled( - restMapper, - envoygatewayv1alpha1.GroupName, - envoygatewayv1alpha1.KindSecurityPolicy, - envoygatewayv1alpha1.GroupVersion.Version) -} - func IsEnvoyGatewayInstalled(restMapper meta.RESTMapper) (bool, error) { - ok, err := IsEnvoyGatewaySecurityPolicyInstalled(restMapper) - if err != nil { - return false, err - } - if !ok { - return false, nil - } - - ok, err = IsEnvoyExtensionPolicyInstalled(restMapper) + ok, err := IsEnvoyExtensionPolicyInstalled(restMapper) if err != nil { return false, err } diff --git a/pkg/library/gatewayapi/types.go b/pkg/gatewayapi/types.go similarity index 51% rename from pkg/library/gatewayapi/types.go rename to pkg/gatewayapi/types.go index 104aa3e7c..89e90d964 100644 --- a/pkg/library/gatewayapi/types.go +++ b/pkg/gatewayapi/types.go @@ -1,32 +1,21 @@ package gatewayapi import ( - "context" "fmt" "sort" "github.com/samber/lo" - "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -type PolicyClass int - -const ( - DirectPolicy PolicyClass = iota - InheritedPolicy + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) type Policy interface { client.Object - PolicyClass() PolicyClass GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference GetStatus() PolicyStatus } @@ -35,145 +24,6 @@ type PolicyStatus interface { GetConditions() []metav1.Condition } -type PolicyByCreationTimestamp []Policy - -func (a PolicyByCreationTimestamp) Len() int { return len(a) } -func (a PolicyByCreationTimestamp) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a PolicyByCreationTimestamp) Less(i, j int) bool { - p1Time := ptr.To(a[i].GetCreationTimestamp()) - p2Time := ptr.To(a[j].GetCreationTimestamp()) - if !p1Time.Equal(p2Time) { - return p1Time.Before(p2Time) - } - - // The policy appearing first in alphabetical order by "{namespace}/{name}". - return client.ObjectKeyFromObject(a[i]).String() < client.ObjectKeyFromObject(a[j]).String() -} - -type PolicyByTargetRefKindAndCreationTimeStamp []Policy - -func (a PolicyByTargetRefKindAndCreationTimeStamp) Len() int { return len(a) } -func (a PolicyByTargetRefKindAndCreationTimeStamp) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a PolicyByTargetRefKindAndCreationTimeStamp) Less(i, j int) bool { - targetRef1 := a[i].GetTargetRef() - targetRef2 := a[j].GetTargetRef() - - // Compare kind first - if targetRef1.Kind != targetRef2.Kind { - if targetRef1.Kind == "Gateway" { - return true - } else if targetRef2.Kind == "HTTPRoute" { - return false - } - return targetRef1.Kind < targetRef2.Kind - } - - // Then compare timestamp - p1Time := ptr.To(a[i].GetCreationTimestamp()) - p2Time := ptr.To(a[j].GetCreationTimestamp()) - if !p1Time.Equal(p2Time) { - return p1Time.Before(p2Time) - } - - // The policy appearing first in alphabetical order by "{namespace}/{name}". - return client.ObjectKeyFromObject(a[i]).String() < client.ObjectKeyFromObject(a[j]).String() -} - -type PolicyByTargetRefKindAndAcceptedStatus []Policy - -func (a PolicyByTargetRefKindAndAcceptedStatus) Len() int { return len(a) } -func (a PolicyByTargetRefKindAndAcceptedStatus) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a PolicyByTargetRefKindAndAcceptedStatus) Less(i, j int) bool { - targetRef1 := a[i].GetTargetRef() - targetRef2 := a[j].GetTargetRef() - - // Compare kind first - if targetRef1.Kind != targetRef2.Kind { - if targetRef1.Kind == "Gateway" { - return true - } else if targetRef2.Kind == "HTTPRoute" { - return false - } - return targetRef1.Kind < targetRef2.Kind - } - - // Compare by accepted condition - p1Status := meta.IsStatusConditionTrue(a[i].GetStatus().GetConditions(), string(gatewayapiv1alpha2.PolicyConditionAccepted)) - p2Status := meta.IsStatusConditionTrue(a[j].GetStatus().GetConditions(), string(gatewayapiv1alpha2.PolicyConditionAccepted)) - if p1Status != p2Status { - return p1Status - } - - // Compare by creation timestamp - p1Time := ptr.To(a[i].GetCreationTimestamp()) - p2Time := ptr.To(a[j].GetCreationTimestamp()) - if !p1Time.Equal(p2Time) { - return p1Time.Before(p2Time) - } - - // The policy appearing first in alphabetical order by "{namespace}/{name}". - return client.ObjectKeyFromObject(a[i]).String() < client.ObjectKeyFromObject(a[j]).String() -} - -type PolicyType interface { - GetGVK() schema.GroupVersionKind - GetInstance() client.Object - GetList(context.Context, client.Client, ...client.ListOption) ([]Policy, error) - BackReferenceAnnotationName() string - DirectReferenceAnnotationName() string -} - -type Type interface { - GetGVK() schema.GroupVersionKind - GetInstance() client.Object -} - -type gatewayType struct{} - -func (g gatewayType) GetGVK() schema.GroupVersionKind { - return schema.GroupVersionKind{ - Group: gatewayapiv1.GroupName, - Version: gatewayapiv1.GroupVersion.Version, - Kind: "Gateway", - } -} - -func (g gatewayType) GetInstance() client.Object { - return &gatewayapiv1.Gateway{ - TypeMeta: metav1.TypeMeta{ - Kind: "Gateway", - APIVersion: gatewayapiv1.GroupVersion.String(), - }, - } -} - -func NewGatewayType() Type { - return &gatewayType{} -} - -type httpRouteType struct{} - -func (h httpRouteType) GetGVK() schema.GroupVersionKind { - return schema.GroupVersionKind{ - Group: gatewayapiv1.GroupName, - Version: gatewayapiv1.GroupVersion.Version, - Kind: "HTTPRoute", - } -} - -func (h httpRouteType) GetInstance() client.Object { - return &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - Kind: "HTTPRoute", - APIVersion: gatewayapiv1.GroupVersion.String(), - }, - } -} - -func NewHTTPRouteType() Type { - return &httpRouteType{} -} - // HTTPRouteMatchConfig stores any config associated to an HTTPRouteRule type HTTPRouteMatchConfig struct { Hostname string diff --git a/pkg/gatewayapi/types_test.go b/pkg/gatewayapi/types_test.go new file mode 100644 index 000000000..963ce29e2 --- /dev/null +++ b/pkg/gatewayapi/types_test.go @@ -0,0 +1,73 @@ +//go:build unit + +package gatewayapi + +import ( + "context" + + "sigs.k8s.io/controller-runtime/pkg/client" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" +) + +var ( + _ Policy = &TestPolicy{} + _ PolicyStatus = &FakePolicyStatus{} +) + +type TestPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + TargetRef gatewayapiv1alpha2.LocalPolicyTargetReference `json:"targetRef"` + Status FakePolicyStatus `json:"status"` +} + +func (p *TestPolicy) Kind() string { + return "FakePolicy" +} + +func (p *TestPolicy) List(ctx context.Context, c client.Client, namespace string) []Policy { + return nil +} + +func (p *TestPolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { + return p.TargetRef +} + +func (p *TestPolicy) GetStatus() PolicyStatus { + return &p.Status +} + +func (p *TestPolicy) DeepCopyObject() runtime.Object { + if c := p.DeepCopy(); c != nil { + return c + } + return nil +} + +func (p *TestPolicy) DeepCopy() *TestPolicy { + if p == nil { + return nil + } + out := new(TestPolicy) + p.DeepCopyInto(out) + return out +} + +func (p *TestPolicy) DeepCopyInto(out *TestPolicy) { + *out = *p + out.TypeMeta = p.TypeMeta + p.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + p.TargetRef.DeepCopyInto(&out.TargetRef) +} + +type FakePolicyStatus struct { + Conditions []metav1.Condition +} + +func (s *FakePolicyStatus) GetConditions() []metav1.Condition { + return s.Conditions +} diff --git a/pkg/library/gatewayapi/utils.go b/pkg/gatewayapi/utils.go similarity index 60% rename from pkg/library/gatewayapi/utils.go rename to pkg/gatewayapi/utils.go index fba397d90..9012b41c7 100644 --- a/pkg/library/gatewayapi/utils.go +++ b/pkg/gatewayapi/utils.go @@ -1,10 +1,7 @@ package gatewayapi import ( - "context" - "fmt" "reflect" - "strings" "github.com/cert-manager/cert-manager/pkg/apis/certmanager" certmanv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" @@ -14,11 +11,10 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" - "sigs.k8s.io/controller-runtime/pkg/client" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) func HostnamesFromListenerAndHTTPRoute(listener *gatewayapiv1.Listener, httpRoute *gatewayapiv1.HTTPRoute) []gatewayapiv1.Hostname { @@ -35,70 +31,6 @@ func HostnamesFromListenerAndHTTPRoute(listener *gatewayapiv1.Listener, httpRout return hostnames } -func IsTargetRefHTTPRoute(targetRef gatewayapiv1alpha2.LocalPolicyTargetReference) bool { - return targetRef.Group == (gatewayapiv1.GroupName) && targetRef.Kind == ("HTTPRoute") -} - -func IsTargetRefGateway(targetRef gatewayapiv1alpha2.LocalPolicyTargetReference) bool { - return targetRef.Group == (gatewayapiv1.GroupName) && targetRef.Kind == ("Gateway") -} - -// TargetHostnames returns an array of hostnames coming from the network object (HTTPRoute, Gateway) -func TargetHostnames(targetNetworkObject client.Object) []string { - hosts := make([]string, 0) - switch obj := targetNetworkObject.(type) { - case *gatewayapiv1.HTTPRoute: - for _, hostname := range obj.Spec.Hostnames { - hosts = append(hosts, string(hostname)) - } - case *gatewayapiv1.Gateway: - for idx := range obj.Spec.Listeners { - if obj.Spec.Listeners[idx].Hostname != nil { - hosts = append(hosts, string(*obj.Spec.Listeners[idx].Hostname)) - } - } - } - - if len(hosts) == 0 { - hosts = append(hosts, "*") - } - - return hosts -} - -func GatewayHostnames(gw *gatewayapiv1.Gateway) []gatewayapiv1.Hostname { - hostnames := make([]gatewayapiv1.Hostname, 0) - if gw == nil { - return hostnames - } - - for idx := range gw.Spec.Listeners { - if gw.Spec.Listeners[idx].Hostname != nil { - hostnames = append(hostnames, *gw.Spec.Listeners[idx].Hostname) - } - } - - return hostnames -} - -func GetGatewayWorkloadSelector(ctx context.Context, cli client.Client, gateway *gatewayapiv1.Gateway) (map[string]string, error) { - address, found := utils.Find( - gateway.Status.Addresses, - func(address gatewayapiv1.GatewayStatusAddress) bool { - return address.Type != nil && *address.Type == gatewayapiv1.HostnameAddressType - }, - ) - if !found { - return nil, fmt.Errorf("cannot find service Hostname in the Gateway status") - } - serviceNameParts := strings.Split(address.Value, ".") - serviceKey := client.ObjectKey{ - Name: serviceNameParts[0], - Namespace: serviceNameParts[1], - } - return utils.GetServiceWorkloadSelector(ctx, cli, serviceKey) -} - // IsHTTPRouteAccepted returns true if a given HTTPRoute has the Accepted status condition added by any of its // parentRefs; otherwise, it returns false func IsHTTPRouteAccepted(httpRoute *gatewayapiv1.HTTPRoute) bool { @@ -111,30 +43,6 @@ func IsHTTPRouteAccepted(httpRoute *gatewayapiv1.HTTPRoute) bool { return len(acceptedParentRefs) == len(httpRoute.Spec.ParentRefs) } -func IsPolicyAccepted(policy Policy) bool { - condition := meta.FindStatusCondition(policy.GetStatus().GetConditions(), string(gatewayapiv1alpha2.PolicyConditionAccepted)) - return condition != nil && condition.Status == metav1.ConditionTrue -} - -func IsNotPolicyAccepted(policy Policy) bool { - condition := meta.FindStatusCondition(policy.GetStatus().GetConditions(), string(gatewayapiv1alpha2.PolicyConditionAccepted)) - return condition == nil || condition.Status != metav1.ConditionTrue -} - -// GetRouteAcceptedGatewayParentKeys returns the object keys of all gateways that have accepted a given route -func GetRouteAcceptedGatewayParentKeys(route *gatewayapiv1.HTTPRoute) []client.ObjectKey { - acceptedParentRefs := GetRouteAcceptedParentRefs(route) - - gatewayParentRefs := utils.Filter(acceptedParentRefs, IsParentGateway) - - return utils.Map(gatewayParentRefs, func(p gatewayapiv1.ParentReference) client.ObjectKey { - return client.ObjectKey{ - Name: string(p.Name), - Namespace: string(ptr.Deref(p.Namespace, gatewayapiv1.Namespace(route.Namespace))), - } - }) -} - // GetRouteAcceptedParentRefs returns the list of parentRefs for which a given route has the Accepted status condition func GetRouteAcceptedParentRefs(route *gatewayapiv1.HTTPRoute) []gatewayapiv1.ParentReference { if route == nil { @@ -151,72 +59,34 @@ func GetRouteAcceptedParentRefs(route *gatewayapiv1.HTTPRoute) []gatewayapiv1.Pa }) } -func IsParentGateway(ref gatewayapiv1.ParentReference) bool { - return (ref.Kind == nil || *ref.Kind == "Gateway") && (ref.Group == nil || *ref.Group == gatewayapiv1.GroupName) -} - -// FilterValidSubdomains returns every subdomain that is a subset of at least one of the (super) domains specified in the first argument. -func FilterValidSubdomains(domains, subdomains []gatewayapiv1.Hostname) []gatewayapiv1.Hostname { - arr := make([]gatewayapiv1.Hostname, 0) - for _, subsubdomain := range subdomains { - if _, found := utils.Find(domains, func(domain gatewayapiv1.Hostname) bool { - return utils.Name(subsubdomain).SubsetOf(utils.Name(domain)) - }); found { - arr = append(arr, subsubdomain) - } - } - return arr -} - -func IsGatewayAPIInstalled(restMapper meta.RESTMapper) (bool, error) { - return utils.IsCRDInstalled(restMapper, gatewayapiv1.GroupName, "HTTPRoute", gatewayapiv1.GroupVersion.Version) -} - -func IsCertManagerInstalled(restMapper meta.RESTMapper, logger logr.Logger) (bool, error) { - if ok, err := utils.IsCRDInstalled(restMapper, certmanager.GroupName, certmanv1.CertificateKind, certmanv1.SchemeGroupVersion.Version); !ok || err != nil { - logger.V(1).Error(err, "CertManager CRD was not installed", "group", certmanager.GroupName, "kind", certmanv1.CertificateKind, "version", certmanv1.SchemeGroupVersion.Version) - return false, err - } - - if ok, err := utils.IsCRDInstalled(restMapper, certmanager.GroupName, certmanv1.IssuerKind, certmanv1.SchemeGroupVersion.Version); !ok || err != nil { - logger.V(1).Error(err, "CertManager CRD was not installed", "group", certmanager.GroupName, "kind", certmanv1.IssuerKind, "version", certmanv1.SchemeGroupVersion.Version) - return false, err - } - - if ok, err := utils.IsCRDInstalled(restMapper, certmanager.GroupName, certmanv1.ClusterIssuerKind, certmanv1.SchemeGroupVersion.Version); !ok || err != nil { - logger.V(1).Error(err, "CertManager CRD was not installed", "group", certmanager.GroupName, "kind", certmanv1.ClusterIssuerKind, "version", certmanv1.SchemeGroupVersion.Version) - return false, err - } - - return true, nil -} - -// GetGatewayParentRefsFromRoute returns the list of parentRefs that are Gateway typed -func GetGatewayParentRefsFromRoute(route *gatewayapiv1.HTTPRoute) []gatewayapiv1.ParentReference { - if route == nil { - return nil +func IsHTTPRouteReady(httpRoute *gatewayapiv1.HTTPRoute, gateway *gatewayapiv1.Gateway, controllerName gatewayapiv1.GatewayController) bool { + routeStatus, found := lo.Find(httpRoute.Status.Parents, func(s gatewayapiv1.RouteParentStatus) bool { + ref := s.ParentRef + return s.ControllerName == controllerName && + ptr.Deref(ref.Group, gatewayapiv1.Group(gatewayapiv1.GroupName)) == gatewayapiv1.Group(gateway.GroupVersionKind().Group) && + ptr.Deref(ref.Kind, gatewayapiv1.Kind(machinery.GatewayGroupKind.Kind)) == gatewayapiv1.Kind(gateway.GroupVersionKind().Kind) && + ptr.Deref(ref.Namespace, gatewayapiv1.Namespace(httpRoute.GetNamespace())) == gatewayapiv1.Namespace(gateway.GetNamespace()) && + ref.Name == gatewayapiv1.ObjectName(gateway.GetName()) + }) + if !found { + return false } - return utils.Filter(route.Spec.ParentRefs, IsParentGateway) + return meta.IsStatusConditionTrue(routeStatus.Conditions, string(gatewayapiv1.RouteConditionAccepted)) } -// GetGatewayParentKeys returns the object keys of all parent gateways -func GetGatewayParentKeys(route *gatewayapiv1.HTTPRoute) []client.ObjectKey { - gatewayParentRefs := GetGatewayParentRefsFromRoute(route) - - return utils.Map(gatewayParentRefs, func(p gatewayapiv1.ParentReference) client.ObjectKey { - return client.ObjectKey{ - Name: string(p.Name), - Namespace: string(ptr.Deref(p.Namespace, gatewayapiv1.Namespace(route.Namespace))), - } +func IsListenerReady(listener *gatewayapiv1.Listener, gateway *gatewayapiv1.Gateway) bool { + listenerStatus, found := lo.Find(gateway.Status.Listeners, func(s gatewayapiv1.ListenerStatus) bool { + return s.Name == listener.Name }) + if !found { + return false + } + return meta.IsStatusConditionTrue(listenerStatus.Conditions, string(gatewayapiv1.ListenerConditionProgrammed)) } -func EqualLocalPolicyTargetReferencesWithSectionName(a, b []gatewayapiv1alpha2.LocalPolicyTargetReferenceWithSectionName) bool { - return len(a) == len(b) && lo.EveryBy(a, func(aTargetRef gatewayapiv1alpha2.LocalPolicyTargetReferenceWithSectionName) bool { - return lo.SomeBy(b, func(bTargetRef gatewayapiv1alpha2.LocalPolicyTargetReferenceWithSectionName) bool { - return aTargetRef.Group == bTargetRef.Group && aTargetRef.Kind == bTargetRef.Kind && aTargetRef.Name == bTargetRef.Name && ptr.Deref(aTargetRef.SectionName, gatewayapiv1alpha2.SectionName("")) == ptr.Deref(bTargetRef.SectionName, gatewayapiv1alpha2.SectionName("")) - }) - }) +func IsPolicyAccepted(policy Policy) bool { + condition := meta.FindStatusCondition(policy.GetStatus().GetConditions(), string(gatewayapiv1alpha2.PolicyConditionAccepted)) + return condition != nil && condition.Status == metav1.ConditionTrue } // PolicyStatusConditionsFromAncestor returns the conditions from a policy status for a given ancestor @@ -238,27 +108,33 @@ func PolicyStatusConditionsFromAncestor(policyStatus gatewayapiv1alpha2.PolicySt return nil } -func IsListenerReady(listener *gatewayapiv1.Listener, gateway *gatewayapiv1.Gateway) bool { - listenerStatus, found := lo.Find(gateway.Status.Listeners, func(s gatewayapiv1.ListenerStatus) bool { - return s.Name == listener.Name +func EqualLocalPolicyTargetReferencesWithSectionName(a, b []gatewayapiv1alpha2.LocalPolicyTargetReferenceWithSectionName) bool { + return len(a) == len(b) && lo.EveryBy(a, func(aTargetRef gatewayapiv1alpha2.LocalPolicyTargetReferenceWithSectionName) bool { + return lo.SomeBy(b, func(bTargetRef gatewayapiv1alpha2.LocalPolicyTargetReferenceWithSectionName) bool { + return aTargetRef.Group == bTargetRef.Group && aTargetRef.Kind == bTargetRef.Kind && aTargetRef.Name == bTargetRef.Name && ptr.Deref(aTargetRef.SectionName, gatewayapiv1alpha2.SectionName("")) == ptr.Deref(bTargetRef.SectionName, gatewayapiv1alpha2.SectionName("")) + }) }) - if !found { - return false - } - return meta.IsStatusConditionTrue(listenerStatus.Conditions, string(gatewayapiv1.ListenerConditionProgrammed)) } -func IsHTTPRouteReady(httpRoute *gatewayapiv1.HTTPRoute, gateway *gatewayapiv1.Gateway, controllerName gatewayapiv1.GatewayController) bool { - routeStatus, found := lo.Find(httpRoute.Status.Parents, func(s gatewayapiv1.RouteParentStatus) bool { - ref := s.ParentRef - return s.ControllerName == controllerName && - ptr.Deref(ref.Group, gatewayapiv1.Group(gatewayapiv1.GroupName)) == gatewayapiv1.Group(gateway.GroupVersionKind().Group) && - ptr.Deref(ref.Kind, gatewayapiv1.Kind(machinery.GatewayGroupKind.Kind)) == gatewayapiv1.Kind(gateway.GroupVersionKind().Kind) && - ptr.Deref(ref.Namespace, gatewayapiv1.Namespace(httpRoute.GetNamespace())) == gatewayapiv1.Namespace(gateway.GetNamespace()) && - ref.Name == gatewayapiv1.ObjectName(gateway.GetName()) - }) - if !found { - return false +func IsGatewayAPIInstalled(restMapper meta.RESTMapper) (bool, error) { + return utils.IsCRDInstalled(restMapper, gatewayapiv1.GroupName, "HTTPRoute", gatewayapiv1.GroupVersion.Version) +} + +func IsCertManagerInstalled(restMapper meta.RESTMapper, logger logr.Logger) (bool, error) { + if ok, err := utils.IsCRDInstalled(restMapper, certmanager.GroupName, certmanv1.CertificateKind, certmanv1.SchemeGroupVersion.Version); !ok || err != nil { + logger.V(1).Error(err, "CertManager CRD was not installed", "group", certmanager.GroupName, "kind", certmanv1.CertificateKind, "version", certmanv1.SchemeGroupVersion.Version) + return false, err } - return meta.IsStatusConditionTrue(routeStatus.Conditions, string(gatewayapiv1.RouteConditionAccepted)) + + if ok, err := utils.IsCRDInstalled(restMapper, certmanager.GroupName, certmanv1.IssuerKind, certmanv1.SchemeGroupVersion.Version); !ok || err != nil { + logger.V(1).Error(err, "CertManager CRD was not installed", "group", certmanager.GroupName, "kind", certmanv1.IssuerKind, "version", certmanv1.SchemeGroupVersion.Version) + return false, err + } + + if ok, err := utils.IsCRDInstalled(restMapper, certmanager.GroupName, certmanv1.ClusterIssuerKind, certmanv1.SchemeGroupVersion.Version); !ok || err != nil { + logger.V(1).Error(err, "CertManager CRD was not installed", "group", certmanager.GroupName, "kind", certmanv1.ClusterIssuerKind, "version", certmanv1.SchemeGroupVersion.Version) + return false, err + } + + return true, nil } diff --git a/pkg/library/gatewayapi/utils_test.go b/pkg/gatewayapi/utils_test.go similarity index 50% rename from pkg/library/gatewayapi/utils_test.go rename to pkg/gatewayapi/utils_test.go index a8af7d98d..7c215f6ea 100644 --- a/pkg/library/gatewayapi/utils_test.go +++ b/pkg/gatewayapi/utils_test.go @@ -3,73 +3,14 @@ package gatewayapi import ( - "context" - "reflect" "testing" "gotest.tools/assert" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/utils/ptr" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" ) -func TestGetGatewayWorkloadSelector(t *testing.T) { - hostnameAddress := gatewayapiv1.AddressType("Hostname") - gateway := &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw", - Labels: map[string]string{ - "app": "foo", - "control-plane": "kuadrant", - }, - }, - Status: gatewayapiv1.GatewayStatus{ - Addresses: []gatewayapiv1.GatewayStatusAddress{ - { - Type: &hostnameAddress, - Value: "my-gw-svc.my-ns.svc.cluster.local:80", - }, - }, - }, - } - - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw-svc", - Labels: map[string]string{ - "a-label": "irrelevant", - }, - }, - Spec: corev1.ServiceSpec{ - Selector: map[string]string{ - "a-selector": "what-we-are-looking-for", - }, - }, - } - - scheme := runtime.NewScheme() - _ = corev1.AddToScheme(scheme) - _ = gatewayapiv1.AddToScheme(scheme) - k8sClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(gateway, service).Build() - - var selector map[string]string - var err error - - selector, err = GetGatewayWorkloadSelector(context.TODO(), k8sClient, gateway) - if err != nil || len(selector) != 1 || selector["a-selector"] != "what-we-are-looking-for" { - t.Error("should not have failed to get the gateway workload selector") - } -} - func TestIsHTTPRouteAccepted(t *testing.T) { testCases := []struct { name string @@ -309,21 +250,6 @@ func TestIsPolicyAccepted(t *testing.T) { } } -func TestIsNotPolicyAccepted(t *testing.T) { - testCases := utils.Map(isPolicyAcceptedTestCases, func(tc isPolicyAcceptedTestCase) isPolicyAcceptedTestCase { - tc.expected = !tc.expected - return tc - }) - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := IsNotPolicyAccepted(tc.policy) - if res != tc.expected { - subT.Errorf("result (%t) does not match expected (%t)", res, tc.expected) - } - }) - } -} - func TestGetRouteAcceptedParentRefs(t *testing.T) { testCases := []struct { name string @@ -500,254 +426,3 @@ func TestGetRouteAcceptedParentRefs(t *testing.T) { }) } } - -func TestGetRouteAcceptedGatewayParentKeys(t *testing.T) { - testCases := []struct { - name string - route *gatewayapiv1.HTTPRoute - expected []client.ObjectKey - }{ - { - "nil", - nil, - []client.ObjectKey{}, - }, - { - "empty parent refs", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{}, - }, - []client.ObjectKey{}, - }, - { - "single gateway parentref accepted", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Kind: ptr.To(gatewayapiv1.Kind("Gateway")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "a", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Kind: ptr.To(gatewayapiv1.Kind("Gateway")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "a", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - }, - }, - }, - }, - []client.ObjectKey{ - { - Name: "a", - }, - }, - }, - { - "single not gateway parent ref accepted", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Kind: ptr.To(gatewayapiv1.Kind("Other")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "a", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Kind: ptr.To(gatewayapiv1.Kind("Other")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "a", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionFalse, - }, - }, - }, - }, - }, - }, - }, - []client.ObjectKey{}, - }, - { - "multiple parents only gateway ones are accepted", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Kind: ptr.To(gatewayapiv1.Kind("Gateway")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "a", - }, - { - Kind: ptr.To(gatewayapiv1.Kind("Other")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "b", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Kind: ptr.To(gatewayapiv1.Kind("Gateway")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "a", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - { - ParentRef: gatewayapiv1.ParentReference{ - Kind: ptr.To(gatewayapiv1.Kind("Other")), - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Name: "b", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionFalse, - }, - }, - }, - }, - }, - }, - }, - []client.ObjectKey{ - { - Name: "a", - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := GetRouteAcceptedGatewayParentKeys(tc.route) - assert.DeepEqual(subT, res, tc.expected) - }) - } -} - -func TestFilterValidSubdomains(t *testing.T) { - testCases := []struct { - name string - domains []gatewayapiv1.Hostname - subdomains []gatewayapiv1.Hostname - expected []gatewayapiv1.Hostname - }{ - { - name: "when all subdomains are valid", - domains: []gatewayapiv1.Hostname{"my-app.apps.io", "*.acme.com"}, - subdomains: []gatewayapiv1.Hostname{"toystore.acme.com", "my-app.apps.io", "carstore.acme.com"}, - expected: []gatewayapiv1.Hostname{"toystore.acme.com", "my-app.apps.io", "carstore.acme.com"}, - }, - { - name: "when some subdomains are valid and some are not", - domains: []gatewayapiv1.Hostname{"my-app.apps.io", "*.acme.com"}, - subdomains: []gatewayapiv1.Hostname{"toystore.acme.com", "my-app.apps.io", "other-app.apps.io"}, - expected: []gatewayapiv1.Hostname{"toystore.acme.com", "my-app.apps.io"}, - }, - { - name: "when none of subdomains are valid", - domains: []gatewayapiv1.Hostname{"my-app.apps.io", "*.acme.com"}, - subdomains: []gatewayapiv1.Hostname{"other-app.apps.io"}, - expected: []gatewayapiv1.Hostname{}, - }, - { - name: "when the set of super domains is empty", - domains: []gatewayapiv1.Hostname{}, - subdomains: []gatewayapiv1.Hostname{"toystore.acme.com"}, - expected: []gatewayapiv1.Hostname{}, - }, - { - name: "when the set of subdomains is empty", - domains: []gatewayapiv1.Hostname{"my-app.apps.io", "*.acme.com"}, - subdomains: []gatewayapiv1.Hostname{}, - expected: []gatewayapiv1.Hostname{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if r := FilterValidSubdomains(tc.domains, tc.subdomains); !reflect.DeepEqual(r, tc.expected) { - t.Errorf("expected=%v; got=%v", tc.expected, r) - } - }) - } -} - -func TestGetGatewayWorkloadSelectorWithoutHostnameAddress(t *testing.T) { - gateway := &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw", - Labels: map[string]string{ - "app": "foo", - "control-plane": "kuadrant", - }, - }, - } - - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw-svc", - Labels: map[string]string{ - "a-label": "irrelevant", - }, - }, - Spec: corev1.ServiceSpec{ - Selector: map[string]string{ - "a-selector": "what-we-are-looking-for", - }, - }, - } - - scheme := runtime.NewScheme() - _ = corev1.AddToScheme(scheme) - _ = gatewayapiv1.AddToScheme(scheme) - k8sClient := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(gateway, service).Build() - - var selector map[string]string - var err error - - selector, err = GetGatewayWorkloadSelector(context.TODO(), k8sClient, gateway) - if err == nil || err.Error() != "cannot find service Hostname in the Gateway status" || selector != nil { - t.Error("should have failed to get the gateway workload selector") - } -} diff --git a/pkg/istio/mutators.go b/pkg/istio/mutators.go deleted file mode 100644 index 7a70d1cb0..000000000 --- a/pkg/istio/mutators.go +++ /dev/null @@ -1,82 +0,0 @@ -package istio - -import ( - "fmt" - "reflect" - - istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" - istiov1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/kuadrant/kuadrant-operator/pkg/wasm" -) - -func WASMPluginMutator(existingObj, desiredObj client.Object) (bool, error) { - update := false - existing, ok := existingObj.(*istioclientgoextensionv1alpha1.WasmPlugin) - if !ok { - return false, fmt.Errorf("%T is not a *istioclientgoextensionv1alpha1.WasmPlugin", existingObj) - } - desired, ok := desiredObj.(*istioclientgoextensionv1alpha1.WasmPlugin) - if !ok { - return false, fmt.Errorf("%T is not a *istioclientgoextensionv1alpha1.WasmPlugin", desiredObj) - } - - existingWasmConfig, err := wasm.ConfigFromStruct(existing.Spec.PluginConfig) - if err != nil { - return false, err - } - - desiredWasmConfig, err := wasm.ConfigFromStruct(desired.Spec.PluginConfig) - if err != nil { - return false, err - } - - // TODO(eastizle): reflect.DeepEqual does not work well with lists without order - if !reflect.DeepEqual(desiredWasmConfig, existingWasmConfig) { - update = true - existing.Spec.PluginConfig = desired.Spec.PluginConfig - } - - return update, nil -} - -func AuthorizationPolicyMutator(existingObj, desiredObj client.Object) (bool, error) { - existing, ok := existingObj.(*istiov1beta1.AuthorizationPolicy) - if !ok { - return false, fmt.Errorf("%T is not an *istiov1beta1.AuthorizationPolicy", existingObj) - } - desired, ok := desiredObj.(*istiov1beta1.AuthorizationPolicy) - if !ok { - return false, fmt.Errorf("%T is not an *istiov1beta1.AuthorizationPolicy", desiredObj) - } - - var update bool - - if !reflect.DeepEqual(existing.Spec.Action, desired.Spec.Action) { - update = true - existing.Spec.Action = desired.Spec.Action - } - - if !reflect.DeepEqual(existing.Spec.ActionDetail, desired.Spec.ActionDetail) { - update = true - existing.Spec.ActionDetail = desired.Spec.ActionDetail - } - - if !reflect.DeepEqual(existing.Spec.Rules, desired.Spec.Rules) { - update = true - existing.Spec.Rules = desired.Spec.Rules - } - - if !reflect.DeepEqual(existing.Spec.Selector, desired.Spec.Selector) { - update = true - existing.Spec.Selector = desired.Spec.Selector - } - - if !reflect.DeepEqual(existing.Annotations, desired.Annotations) { - update = true - existing.Annotations = desired.Annotations - } - - return update, nil -} diff --git a/pkg/istio/utils.go b/pkg/istio/utils.go index c31ee30ed..cc71652be 100644 --- a/pkg/istio/utils.go +++ b/pkg/istio/utils.go @@ -11,13 +11,12 @@ import ( istioapiv1beta1 "istio.io/api/type/v1beta1" istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" istioclientgonetworkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" - istioclientgosecurityv1beta1 "istio.io/client-go/pkg/apis/security/v1beta1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) var ( @@ -28,14 +27,6 @@ var ( WasmPluginGroupKind = schema.GroupKind{Group: istioclientgoextensionv1alpha1.GroupName, Kind: "WasmPlugin"} ) -func PolicyTargetRefFromGateway(gateway *gatewayapiv1.Gateway) *istioapiv1beta1.PolicyTargetReference { - return &istioapiv1beta1.PolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "Gateway", - Name: gateway.Name, - } -} - func EqualTargetRefs(a, b []*istioapiv1beta1.PolicyTargetReference) bool { return len(a) == len(b) && lo.EveryBy(a, func(aTargetRef *istioapiv1beta1.PolicyTargetReference) bool { return lo.SomeBy(b, func(bTargetRef *istioapiv1beta1.PolicyTargetReference) bool { @@ -141,14 +132,6 @@ func IsWASMPluginInstalled(restMapper meta.RESTMapper) (bool, error) { istioclientgoextensionv1alpha1.SchemeGroupVersion.Version) } -func IsAuthorizationPolicyInstalled(restMapper meta.RESTMapper) (bool, error) { - return utils.IsCRDInstalled( - restMapper, - istioclientgosecurityv1beta1.GroupName, - "AuthorizationPolicy", - istioclientgosecurityv1beta1.SchemeGroupVersion.Version) -} - func IsIstioInstalled(restMapper meta.RESTMapper) (bool, error) { ok, err := IsWASMPluginInstalled(restMapper) if err != nil { @@ -158,14 +141,6 @@ func IsIstioInstalled(restMapper meta.RESTMapper) (bool, error) { return false, nil } - ok, err = IsAuthorizationPolicyInstalled(restMapper) - if err != nil { - return false, err - } - if !ok { - return false, nil - } - ok, err = IsEnvoyFilterInstalled(restMapper) if err != nil { return false, err diff --git a/pkg/istio/utils_test.go b/pkg/istio/utils_test.go deleted file mode 100644 index 4baee1961..000000000 --- a/pkg/istio/utils_test.go +++ /dev/null @@ -1,24 +0,0 @@ -//go:build unit - -package istio - -import ( - "testing" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" -) - -func TestPolicyTargetRefFromGateway(t *testing.T) { - gateway := &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw", - }, - } - - ref := PolicyTargetRefFromGateway(gateway) - if ref == nil || ref.Group != "gateway.networking.k8s.io" || ref.Kind != "Gateway" || ref.Name != "my-gw" { - t.Error("should have built the istio policy target reference from the gateway") - } -} diff --git a/pkg/library/kuadrant/apimachinery_status_conditions.go b/pkg/kuadrant/conditions.go similarity index 100% rename from pkg/library/kuadrant/apimachinery_status_conditions.go rename to pkg/kuadrant/conditions.go diff --git a/pkg/library/kuadrant/apimachinery_status_conditions_test.go b/pkg/kuadrant/conditions_test.go similarity index 100% rename from pkg/library/kuadrant/apimachinery_status_conditions_test.go rename to pkg/kuadrant/conditions_test.go diff --git a/pkg/library/kuadrant/errors.go b/pkg/kuadrant/errors.go similarity index 100% rename from pkg/library/kuadrant/errors.go rename to pkg/kuadrant/errors.go diff --git a/pkg/library/kuadrant/errors_test.go b/pkg/kuadrant/errors_test.go similarity index 100% rename from pkg/library/kuadrant/errors_test.go rename to pkg/kuadrant/errors_test.go diff --git a/pkg/kuadrant/kuadrant.go b/pkg/kuadrant/kuadrant.go new file mode 100644 index 000000000..79f3daf05 --- /dev/null +++ b/pkg/kuadrant/kuadrant.go @@ -0,0 +1,18 @@ +package kuadrant + +import ( + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" +) + +const ( + ControllerName = "kuadrant.io/policy-controller" + TopologyLabel = "kuadrant.io/topology" + KuadrantRateLimitClusterName = "kuadrant-ratelimit-service" + KuadrantAuthClusterName = "kuadrant-auth-service" + LimitadorName = "limitador" +) + +type Policy interface { + kuadrantgatewayapi.Policy + Kind() string +} diff --git a/pkg/kuadrant/test_utils.go b/pkg/kuadrant/test_utils.go new file mode 100644 index 000000000..dc0da8263 --- /dev/null +++ b/pkg/kuadrant/test_utils.go @@ -0,0 +1,45 @@ +//go:build unit + +package kuadrant + +import ( + "context" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" +) + +const ( + NS = "nsA" +) + +type FakePolicy struct { + client.Object + Hosts []string + targetRef gatewayapiv1alpha2.LocalPolicyTargetReference +} + +func (p *FakePolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { + return p.targetRef +} + +func (p *FakePolicy) GetStatus() kuadrantgatewayapi.PolicyStatus { + return &FakePolicyStatus{} +} + +func (p *FakePolicy) Kind() string { + return "FakePolicy" +} + +func (p *FakePolicy) List(ctx context.Context, c client.Client, namespace string) []kuadrantgatewayapi.Policy { + return nil +} + +type FakePolicyStatus struct{} + +func (s *FakePolicyStatus) GetConditions() []metav1.Condition { + return nil +} diff --git a/pkg/kuadranttools/topology_tools.go b/pkg/kuadranttools/topology_tools.go deleted file mode 100644 index 7fb6edb04..000000000 --- a/pkg/kuadranttools/topology_tools.go +++ /dev/null @@ -1,97 +0,0 @@ -package kuadranttools - -import ( - "context" - - "github.com/go-logr/logr" - "k8s.io/utils/ptr" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/fieldindexers" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -func TopologyFromGateway(ctx context.Context, cl client.Client, gw *gatewayapiv1.Gateway, policyType kuadrantgatewayapi.PolicyType) (*kuadrantgatewayapi.Topology, error) { - logger, err := logr.FromContext(ctx) - if err != nil { - return nil, err - } - - routeList := &gatewayapiv1.HTTPRouteList{} - // Get all the routes having the gateway as parent - err = cl.List( - ctx, - routeList, - client.MatchingFields{ - fieldindexers.HTTPRouteGatewayParentField: client.ObjectKeyFromObject(gw).String(), - }) - logger.V(1).Info("TopologyFromGateway: list httproutes from gateway", - "gateway", client.ObjectKeyFromObject(gw), - "#HTTPRoutes", len(routeList.Items), - "err", err) - if err != nil { - return nil, err - } - - // Get all the policyKind policies - policies, err := policyType.GetList(ctx, cl) - logger.V(1).Info("TopologyFromGateway: list policies", - "#policies", len(policies), - "err", err) - if err != nil { - return nil, err - } - - return kuadrantgatewayapi.NewTopology( - kuadrantgatewayapi.WithGateways([]*gatewayapiv1.Gateway{gw}), - kuadrantgatewayapi.WithRoutes(utils.Map(routeList.Items, ptr.To[gatewayapiv1.HTTPRoute])), - kuadrantgatewayapi.WithPolicies(policies), - kuadrantgatewayapi.WithLogger(logger), - ) -} - -func TopologyForPolicies(ctx context.Context, cl client.Client, policyType kuadrantgatewayapi.PolicyType) (*kuadrantgatewayapi.Topology, error) { - logger, err := logr.FromContext(ctx) - if err != nil { - return nil, err - } - - gatewayList := &gatewayapiv1.GatewayList{} - err = cl.List( - ctx, - gatewayList) - logger.V(1).Info("TopologyForPolicies: list all gateways", - "#Gateways", len(gatewayList.Items), - "err", err) - if err != nil { - return nil, err - } - - routeList := &gatewayapiv1.HTTPRouteList{} - err = cl.List( - ctx, - routeList) - logger.V(1).Info("TopologyForPolicies: list all httproutes", - "#HTTPRoutes", len(routeList.Items), - "err", err) - if err != nil { - return nil, err - } - - policies, err := policyType.GetList(ctx, cl) - logger.V(1).Info("TopologyForPolicies: list policies", - "#policies", len(policies), - "err", err) - if err != nil { - return nil, err - } - - return kuadrantgatewayapi.NewTopology( - kuadrantgatewayapi.WithGateways(utils.Map(gatewayList.Items, ptr.To[gatewayapiv1.Gateway])), - kuadrantgatewayapi.WithRoutes(utils.Map(routeList.Items, ptr.To[gatewayapiv1.HTTPRoute])), - kuadrantgatewayapi.WithPolicies(policies), - kuadrantgatewayapi.WithLogger(logger), - ) -} diff --git a/pkg/library/README.md b/pkg/library/README.md deleted file mode 100644 index 167a7145d..000000000 --- a/pkg/library/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Packages in this directory contains only contain common / useful functionality for policy controllers that will be -externalised to the https://github.com/Kuadrant/gateway-api-machinery diff --git a/pkg/library/dag/dag.go b/pkg/library/dag/dag.go deleted file mode 100644 index d31b8ec39..000000000 --- a/pkg/library/dag/dag.go +++ /dev/null @@ -1,284 +0,0 @@ -package dag - -import ( - "errors" - "fmt" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -// A Directed Acyclic Graph (DAG) is a graph representing a structure formed by vertices, or nodes, -// connected by directed edges. -// In a DAG, each edge has an initial node, called the parent, and a final node, called the child. -// The graph is considered acyclic because it does not contain any cycles, -// meaning there are no sequences of consecutive directed edges that form a closed loop. -// NOTE: this package is not thread-safe - -type NodeID = string - -type nodeNotFoundError struct { - id NodeID -} - -func (e *nodeNotFoundError) Error() string { - return fmt.Sprintf("node %s not found", e.id) -} - -func IsNodeNotFound(err error) bool { - var nodeNotFoundErr *nodeNotFoundError - return errors.As(err, &nodeNotFoundErr) -} - -type Node interface { - ID() NodeID -} - -type internalNode struct { - id NodeID - node Node - parents map[NodeID]*internalNode - children map[NodeID]*internalNode -} - -type Options struct { - fieldIndexers []FieldIndexer -} - -type NodeLabel = string -type Field = string - -type IndexerFunc func(Node) []NodeLabel - -func WithFieldIndexer(f Field, e IndexerFunc) *FieldIndexer { - return &FieldIndexer{f, e} -} - -type FieldIndexer struct { - field Field - indexer IndexerFunc -} - -func (f FieldIndexer) ApplyTo(opts *Options) { - opts.fieldIndexers = append(opts.fieldIndexers, f) -} - -type Opt interface { - // ApplyTo applies this configuration to the given options. - ApplyTo(*Options) -} - -var _ Opt = FieldIndexer{} - -type DAG struct { - nodes map[NodeID]*internalNode - fieldIndexers []FieldIndexer - nodeIndexes map[Field]map[NodeLabel][]Node -} - -func NewDAG(opts ...Opt) *DAG { - // Capture options - dagOpts := &Options{} - for _, opt := range opts { - opt.ApplyTo(dagOpts) - } - - return &DAG{ - nodes: make(map[NodeID]*internalNode), - fieldIndexers: dagOpts.fieldIndexers, - nodeIndexes: make(map[Field]map[NodeLabel][]Node), - } -} - -func (d *DAG) AddNode(node Node) error { - n := &internalNode{ - id: node.ID(), - node: node, - parents: make(map[string]*internalNode), - children: make(map[string]*internalNode), - } - - if _, exists := d.nodes[n.id]; exists { - return fmt.Errorf("node %s already exists", n.id) - } - - d.nodes[n.id] = n - d.populateIndexes(node) - - return nil -} - -func (d *DAG) populateIndexes(node Node) { - for _, fieldIndexer := range d.fieldIndexers { - nodelabels := fieldIndexer.indexer(node) - field := fieldIndexer.field - if d.nodeIndexes[field] == nil { - d.nodeIndexes[field] = make(map[NodeLabel][]Node) - } - for _, nodeLabel := range nodelabels { - d.nodeIndexes[field][nodeLabel] = append(d.nodeIndexes[field][nodeLabel], node) - } - } -} - -func (d *DAG) AddEdge(parent NodeID, child NodeID) error { - parentInternalNode, parentExists := d.nodes[parent] - if !parentExists { - return fmt.Errorf("parent node %s must exist", parent) - } - - childInternalNode, childExists := d.nodes[child] - if !childExists { - return fmt.Errorf("child node %s must exist", child) - } - - if _, exists := parentInternalNode.children[childInternalNode.id]; exists { - return fmt.Errorf("parent node %s already has an edge with child %s", parentInternalNode.id, childInternalNode.id) - } - - if _, exists := childInternalNode.parents[parentInternalNode.id]; exists { - return fmt.Errorf("child node %s already has an edge with parent %s", childInternalNode.id, parentInternalNode.id) - } - - parentInternalNode.children[childInternalNode.id] = childInternalNode - childInternalNode.parents[parentInternalNode.id] = parentInternalNode - - return nil -} - -// Parents return all parents of the node. -func (d *DAG) Parents(n NodeID) []Node { - internalNode, exists := d.nodes[n] - if !exists { - return nil - } - - result := make([]Node, 0) - - for _, parent := range internalNode.parents { - result = append(result, parent.node) - } - - return result -} - -// Children return all children of the node. -func (d *DAG) Children(n NodeID) []Node { - internalNode, exists := d.nodes[n] - if !exists { - return nil - } - - result := make([]Node, 0) - - for _, child := range internalNode.children { - result = append(result, child.node) - } - - return result -} - -func (d *DAG) GetNode(n NodeID) (Node, error) { - internalNode, exists := d.nodes[n] - if !exists { - return nil, &nodeNotFoundError{id: n} - } - - return internalNode.node, nil -} - -// GetNodes returns a list of nodes. Indexes are required in the constructor -func (d *DAG) GetNodes(field Field, label NodeLabel) []Node { - if fieldIndex, fieldExists := d.nodeIndexes[field]; fieldExists { - if nodeList, labelExists := fieldIndex[label]; labelExists { - return nodeList - } - } - - return nil -} - -// Validate validates the DAG. A DAG is valid if it has no cycles. -func (d *DAG) Validate() bool { - // Based on Kahn's algorithm - // https://en.wikipedia.org/wiki/Topological_sorting - - type node struct { - id string - parents map[string]interface{} - children []*node - } - - type graph struct { - nodes []*node - } - - // build a mutable simple graph representation out of DAG only for validating purposes - build := func() *graph { - g := &graph{ - nodes: make([]*node, 0), - } - - nodeIndex := make(map[string]*node) - - // the index needs to be built before populating parents and children - for id := range d.nodes { - nodeIndex[id] = &node{ - id: id, - parents: make(map[string]interface{}), - children: make([]*node, 0), - } - } - - for id, n := range d.nodes { - simpleNode := nodeIndex[id] // should exist - if simpleNode == nil { - panic("it should not happen") - } - for parentID := range n.parents { - simpleNode.parents[parentID] = nil - } - for childID := range n.children { - simpleNode.children = append(simpleNode.children, nodeIndex[childID]) - } - } - - for _, simpleNode := range nodeIndex { - g.nodes = append(g.nodes, simpleNode) - } - - return g - } - - g := build() - - // S: Set of all nodes with no incoming edge - s := utils.Filter(g.nodes, func(n *node) bool { return len(n.parents) == 0 }) - - for len(s) != 0 { - var n *node - // remove a node n from S - n, s = s[0], s[1:] - - // for each node m with an edge e from n to m do - for len(n.children) != 0 { - var m *node - // remove edge e from the graph - m, n.children = n.children[0], n.children[1:] - delete(m.parents, n.id) - // if m has no other incoming edges then insert m into S - if len(m.parents) == 0 { - s = append(s, m) - } - } - } - - for _, n := range g.nodes { - if len(n.parents) > 0 { - // if graph has edges then return error - // graph has at least one cycle - return false - } - } - - return true -} diff --git a/pkg/library/dag/dag_test.go b/pkg/library/dag/dag_test.go deleted file mode 100644 index c4d105877..000000000 --- a/pkg/library/dag/dag_test.go +++ /dev/null @@ -1,380 +0,0 @@ -//go:build unit - -package dag - -import ( - "errors" - "testing" - - "gotest.tools/assert" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -type NodeTest string - -func (n NodeTest) ID() string { - return string(n) -} - -type NodeTest2 string - -func (n NodeTest2) ID() string { - return string(n) -} - -func TestDAGValidate(t *testing.T) { - t.Run("empty DAG is valid", func(subT *testing.T) { - d := NewDAG() - assert.Assert(subT, d.Validate(), "empty DAG is not valid") - }) - - t.Run("DAG edgeless is valid", func(subT *testing.T) { - d := NewDAG() - nodes := []Node{ - NodeTest("0"), - NodeTest("1"), - NodeTest("2"), - NodeTest("3"), - NodeTest("4"), - } - - for _, node := range nodes { - assert.NilError(subT, d.AddNode(node)) - } - - assert.Assert(subT, d.Validate(), "edgeless DAG is not valid") - }) - - t.Run("DAG without roots with cycles is not valid", func(subT *testing.T) { - d := NewDAG() - - nodes := []Node{ - NodeTest("0"), - NodeTest("1"), - NodeTest("2"), - NodeTest("3"), - NodeTest("4"), - } - - for _, node := range nodes { - assert.NilError(subT, d.AddNode(node)) - } - - // all nodes have some parent - edges := []struct { - parent NodeID - child NodeID - }{ - {"0", "1"}, - {"1", "2"}, - {"2", "3"}, - {"3", "0"}, - {"0", "4"}, - {"4", "2"}, - } - - for _, edge := range edges { - assert.NilError(subT, d.AddEdge(edge.parent, edge.child)) - } - - assert.Assert(subT, !d.Validate(), "DAG with cycles should not be valid") - }) - - t.Run("DAG with roots with cycles is not valid", func(subT *testing.T) { - d := NewDAG() - - nodes := []Node{ - NodeTest("0"), - NodeTest("1"), - NodeTest("2"), - NodeTest("3"), - } - - for _, node := range nodes { - assert.NilError(subT, d.AddNode(node)) - } - - // 0 node has no parent - edges := []struct { - parent NodeID - child NodeID - }{ - {"0", "1"}, - {"0", "3"}, - {"1", "2"}, - {"2", "3"}, - {"3", "1"}, - } - - for _, edge := range edges { - assert.NilError(subT, d.AddEdge(edge.parent, edge.child)) - } - - assert.Assert(subT, !d.Validate(), "DAG with cycles should not be valid") - }) - - t.Run("DAG without cycles is valid", func(subT *testing.T) { - d := NewDAG() - - nodes := []Node{ - NodeTest("5"), - NodeTest("7"), - NodeTest("3"), - NodeTest("11"), - NodeTest("8"), - NodeTest("2"), - NodeTest("9"), - NodeTest("10"), - } - - for _, node := range nodes { - assert.NilError(subT, d.AddNode(node)) - } - - edges := []struct { - parent NodeID - child NodeID - }{ - {"5", "11"}, - {"7", "11"}, - {"7", "8"}, - {"3", "8"}, - {"3", "9"}, - {"11", "2"}, - {"11", "9"}, - {"11", "10"}, - {"8", "9"}, - } - - for _, edge := range edges { - assert.NilError(subT, d.AddEdge(edge.parent, edge.child)) - } - - assert.Assert(subT, d.Validate(), "DAG without cycles should be valid") - }) -} - -func TestDAGIsNodeNotFound(t *testing.T) { - t.Run("nil returns false", func(subT *testing.T) { - if IsNodeNotFound(nil) { - subT.Fatal("nil returns true") - } - }) - - t.Run("errors.New returns false", func(subT *testing.T) { - if IsNodeNotFound(errors.New("some error")) { - subT.Fatal("errors.New returns true") - } - }) - - t.Run("nodeNotFoundError instance returns true", func(subT *testing.T) { - if !IsNodeNotFound(&nodeNotFoundError{id: "1"}) { - subT.Fatal("should return true") - } - }) -} - -func TestDAGAddEdge(t *testing.T) { - d := NewDAG() - - assert.NilError(t, d.AddNode(NodeTest("0"))) - assert.NilError(t, d.AddNode(NodeTest("1"))) - - assert.Error(t, d.AddEdge("unknown", "0"), "parent node unknown must exist") - - assert.NilError(t, d.AddEdge("0", "1")) -} - -func TestDAGParents(t *testing.T) { - d := NewDAG() - nodes := []Node{NodeTest("0"), NodeTest("1")} - for _, node := range nodes { - assert.NilError(t, d.AddNode(node)) - } - - assert.NilError(t, d.AddEdge("0", "1")) - - t.Run("unknown node returns empty", func(subT *testing.T) { - assert.Assert(subT, len(d.Parents("unknown")) == 0, "unknown node returns not empty") - }) - - t.Run("node with parent returns expected nodes", func(subT *testing.T) { - parents := d.Parents("1") - assert.Assert(subT, utils.SameElements(parents, []Node{NodeTest("0")}), "unexpected parents", "parents", parents) - }) - - t.Run("node without parent returns empty", func(subT *testing.T) { - parents := d.Parents("0") - assert.Assert(subT, len(parents) == 0, "parents should be empty", "parents", parents) - }) -} - -func TestDAGChildren(t *testing.T) { - d := NewDAG() - - nodes := []Node{NodeTest("0"), NodeTest("1")} - for _, node := range nodes { - assert.NilError(t, d.AddNode(node)) - } - - assert.NilError(t, d.AddEdge("0", "1")) - - t.Run("unknown node returns empty", func(subT *testing.T) { - assert.Assert(subT, len(d.Children("unknown")) == 0, "unknown node returns not empty") - }) - - t.Run("node with children returns expected nodes", func(subT *testing.T) { - children := d.Children("0") - assert.Assert(subT, utils.SameElements(children, []Node{NodeTest("1")}), "unexpected children", "children", children) - }) - - t.Run("node without children returns empty", func(subT *testing.T) { - children := d.Children("1") - assert.Assert(subT, len(children) == 0, "children should be empty", "children", children) - }) -} - -func TestDAGGetNode(t *testing.T) { - d := NewDAG() - - assert.NilError(t, d.AddNode(NodeTest("0"))) - assert.NilError(t, d.AddNode(NodeTest("1"))) - - t.Run("unknown id returns not found", func(subT *testing.T) { - _, err := d.GetNode("unknown") - assert.Assert(subT, IsNodeNotFound(err), "unknown id does not return not found") - }) - - t.Run("existing id returns node", func(subT *testing.T) { - for _, nodeID := range []string{"0", "1"} { - node, err := d.GetNode(nodeID) - assert.NilError(subT, err) - - nodeTest, ok := node.(NodeTest) - assert.Assert(subT, ok, "unexpected node type", "nodeID", nodeID) - assert.Equal(subT, nodeTest, NodeTest(nodeID)) - } - }) -} - -func TestDAGIndexes(t *testing.T) { - t.Run("empty indexer does not index nodes", func(subT *testing.T) { - d := NewDAG() - - nodes := []Node{ - NodeTest("0"), - NodeTest("1"), - } - - for _, node := range nodes { - assert.NilError(subT, d.AddNode(node)) - } - - assert.NilError(subT, d.AddEdge("0", "1")) - - assert.Assert(subT, d.Validate(), "DAG without cycles should be valid") - - indexedNodes := d.GetNodes(Field("1"), NodeLabel("somelabel")) - assert.Assert(subT, len(indexedNodes) == 0, "empty index should not return any node") - }) - - t.Run("multiple indexes return expected nodes", func(subT *testing.T) { - // root indexer will only label node 0 with root - rootIndexer := WithFieldIndexer(Field("rootIndex"), func(n Node) []NodeLabel { - if n.ID() == "0" { - return []NodeLabel{NodeLabel("root")} - } - return nil - }) - - // every node will be labeled with node ID - selfIDIndexer := WithFieldIndexer(Field("selfID"), func(n Node) []NodeLabel { - return []NodeLabel{NodeLabel(n.ID())} - }) - - d := NewDAG(rootIndexer, selfIDIndexer) - - nodes := []Node{NodeTest("0"), NodeTest("1")} - - for _, node := range nodes { - assert.NilError(subT, d.AddNode(node)) - } - - assert.NilError(subT, d.AddEdge("0", "1")) - assert.Assert(subT, d.Validate(), "DAG without cycles should be valid") - - assert.Assert(subT, utils.SameElements( - d.GetNodes(Field("rootIndex"), NodeLabel("root")), - []Node{NodeTest("0")}, - ), "index for Field rootIndex and root label failed") - - for _, node := range nodes { - assert.Assert(subT, utils.SameElements( - d.GetNodes(Field("selfID"), NodeLabel(node.ID())), - []Node{NodeTest(node.ID())}, - ), "index for Field selfID failed", "label", node.ID()) - } - - // mixing labels and fields does not work - // rootIndexer does not generate any label other than "root" - assert.Assert(subT, len(d.GetNodes(Field("rootIndex"), NodeLabel("0"))) == 0, - "index for Field rootIndex has nodes indexed with '0' label") - assert.Assert(subT, len(d.GetNodes(Field("rootIndex"), NodeLabel("1"))) == 0, - "index for Field rootIndex has nodes indexed with '1' label") - // selfIDIndexer does not generate any label other than node ID - assert.Assert(subT, len(d.GetNodes(Field("selfID"), NodeLabel("root"))) == 0, - "index for Field selfID has nodes indexed with 'root' label") - }) - - t.Run("multiple labels returns expected nodes", func(subT *testing.T) { - nodeIndexer1 := WithFieldIndexer(Field("1"), func(n Node) []NodeLabel { - nodeLabels := []NodeLabel{NodeLabel("commonLabel")} - switch n.(type) { - case NodeTest: - return append(nodeLabels, NodeLabel("NodeTest")) - case NodeTest2: - return append(nodeLabels, NodeLabel("NodeTest2")) - default: - return nil - } - }) - - d := NewDAG(nodeIndexer1) - - nodes := []Node{ - NodeTest("00"), - NodeTest("01"), - NodeTest2("20"), - NodeTest2("21"), - } - - for _, node := range nodes { - assert.NilError(subT, d.AddNode(node)) - } - - edges := []struct { - parent NodeID - child NodeID - }{ - {"00", "01"}, - {"01", "20"}, - {"20", "21"}, - } - - for _, edge := range edges { - assert.NilError(subT, d.AddEdge(edge.parent, edge.child)) - } - - assert.Assert(subT, d.Validate(), "DAG without cycles should be valid") - - indexedNodes := d.GetNodes(Field("1"), NodeLabel("NodeTest")) - assert.Assert(subT, utils.SameElements(indexedNodes, []Node{NodeTest("00"), NodeTest("01")}), - "index for Field 1 and label NodeTest failed") - indexedNodes = d.GetNodes(Field("1"), NodeLabel("NodeTest2")) - assert.Assert(subT, utils.SameElements(indexedNodes, []Node{NodeTest2("20"), NodeTest2("21")}), - "index for Field 1 and label NodeTest2 failed") - indexedNodes = d.GetNodes(Field("1"), NodeLabel("commonLabel")) - assert.Assert(subT, utils.SameElements(indexedNodes, nodes), "index for Field 1 and label commonLabel failed") - }) -} diff --git a/pkg/library/fieldindexers/httproute_parents.go b/pkg/library/fieldindexers/httproute_parents.go deleted file mode 100644 index 6fd910073..000000000 --- a/pkg/library/fieldindexers/httproute_parents.go +++ /dev/null @@ -1,53 +0,0 @@ -package fieldindexers - -import ( - "context" - "fmt" - - "github.com/go-logr/logr" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -const ( - HTTPRouteGatewayParentField = ".metadata.parentRefs.gateway" -) - -// HTTPRouteByGatewayIndexer declares an index key that we can later use with the client as a pseudo-field name, -// allowing to query all the routes parented by a given gateway -// to prevent creating the same index field multiple times, the function is declared private to be -// called only by this controller -func HTTPRouteIndexByGateway(mgr ctrl.Manager, baseLogger logr.Logger) error { - ok, err := kuadrantgatewayapi.IsGatewayAPIInstalled(mgr.GetRESTMapper()) - if err != nil { - return err - } - if !ok { - baseLogger.Info("HTTPRouteIndexByGateway index disabled. GatewayAPI was not found") - return nil - } - - if err := mgr.GetFieldIndexer().IndexField(context.Background(), &gatewayapiv1.HTTPRoute{}, HTTPRouteGatewayParentField, func(rawObj client.Object) []string { - // grab the route object, extract the parents - route, assertionOk := rawObj.(*gatewayapiv1.HTTPRoute) - if !assertionOk { - baseLogger.V(1).Error(fmt.Errorf("%T is not a *gatewayapiv1.HTTPRoute", rawObj), "cannot map") - return nil - } - - logger := baseLogger.WithValues("route", client.ObjectKeyFromObject(route).String()) - - return utils.Map(kuadrantgatewayapi.GetRouteAcceptedGatewayParentKeys(route), func(key client.ObjectKey) string { - logger.V(1).Info("new gateway added", "key", key.String()) - return key.String() - }) - }); err != nil { - return err - } - - return nil -} diff --git a/pkg/library/gatewayapi/helper_test.go b/pkg/library/gatewayapi/helper_test.go deleted file mode 100644 index fdde24b1f..000000000 --- a/pkg/library/gatewayapi/helper_test.go +++ /dev/null @@ -1,140 +0,0 @@ -//go:build unit - -package gatewayapi - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/ptr" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -const ( - NS = "nsA" -) - -func testBasicGateway(name, namespace string) *gatewayapiv1.Gateway { - // Valid gateway - return &gatewayapiv1.Gateway{ - TypeMeta: metav1.TypeMeta{ - APIVersion: gatewayapiv1.GroupVersion.String(), - Kind: "Gateway", - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - Name: name, - }, - Status: gatewayapiv1.GatewayStatus{ - Conditions: []metav1.Condition{ - { - Type: string(gatewayapiv1.GatewayConditionProgrammed), - Status: metav1.ConditionTrue, - }, - }, - }, - } -} - -func testInvalidGateway(name, namespace string) *gatewayapiv1.Gateway { - gw := testBasicGateway(name, namespace) - // remove conditions to make it invalid - gw.Status = gatewayapiv1.GatewayStatus{} - - return gw -} - -func testBasicRoute(name, namespace string, parents ...*gatewayapiv1.Gateway) *gatewayapiv1.HTTPRoute { - parentRefs := make([]gatewayapiv1.ParentReference, 0) - for _, val := range parents { - parentRefs = append(parentRefs, gatewayapiv1.ParentReference{ - Group: ptr.To(gatewayapiv1.Group(gatewayapiv1.GroupName)), - Kind: ptr.To(gatewayapiv1.Kind("Gateway")), - Namespace: ptr.To(gatewayapiv1.Namespace(val.Namespace)), - Name: gatewayapiv1.ObjectName(val.Name), - }) - } - - parentStatusRefs := utils.Map(parentRefs, func(p gatewayapiv1.ParentReference) gatewayapiv1.RouteParentStatus { - return gatewayapiv1.RouteParentStatus{ - ParentRef: p, - Conditions: []metav1.Condition{{Type: "Accepted", Status: metav1.ConditionTrue}}, - } - }) - - return &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - APIVersion: gatewayapiv1.GroupVersion.String(), - Kind: "HTTPRoute", - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - Name: name, - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: parentRefs, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: parentStatusRefs, - }, - }, - } -} - -func testBasicGatewayPolicy(name, namespace string, gateway *gatewayapiv1.Gateway) Policy { - return &TestPolicy{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "example.com/v1", - Kind: "TestPolicy", - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - Name: name, - }, - TargetRef: gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.Group(gatewayapiv1.GroupName), - Kind: gatewayapiv1.Kind("Gateway"), - Name: gatewayapiv1.ObjectName(gateway.Name), - }, - } -} - -func testBasicRoutePolicy(name, namespace string, route *gatewayapiv1.HTTPRoute) Policy { - return &TestPolicy{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "example.com/v1", - Kind: "TestPolicy", - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - Name: name, - }, - TargetRef: gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.Group(gatewayapiv1.GroupName), - Kind: gatewayapiv1.Kind("HTTPRoute"), - Name: gatewayapiv1.ObjectName(route.Name), - }, - } -} - -func testStandalonePolicy(name, namespace string) Policy { - return &TestPolicy{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "example.com/v1", - Kind: "TestPolicy", - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - Name: name, - }, - TargetRef: gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.Group(gatewayapiv1.GroupName), - Kind: gatewayapiv1.Kind("Gateway"), - Name: gatewayapiv1.ObjectName("unknown"), - }, - } -} diff --git a/pkg/library/gatewayapi/topology.go b/pkg/library/gatewayapi/topology.go deleted file mode 100644 index 9632aa249..000000000 --- a/pkg/library/gatewayapi/topology.go +++ /dev/null @@ -1,459 +0,0 @@ -package gatewayapi - -import ( - "errors" - "fmt" - - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/meta" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/dag" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -const ( - typeField dag.Field = dag.Field("type") - gatewayLabel dag.NodeLabel = dag.NodeLabel("gateway") - httprouteLabel dag.NodeLabel = dag.NodeLabel("httproute") - policyLabel dag.NodeLabel = dag.NodeLabel("policy") -) - -type PolicyTargetNode interface { - GetGatewayNode() *GatewayNode - GetRouteNode() *RouteNode - GetObject() client.Object - AttachedPolicies() []PolicyNode -} - -type PolicyNode struct { - policyDAGNode - - graph *dag.DAG -} - -func (p *PolicyNode) GetPolicy() Policy { - return p.Policy -} - -func (p *PolicyNode) TargetRef() PolicyTargetNode { - targetNodes := p.graph.Parents(p.ID()) - - if len(targetNodes) == 0 { - return nil - } - - // there should be only one - switch typedNode := targetNodes[0].(type) { - case gatewayDAGNode: - return &GatewayNode{typedNode, p.graph} - case httpRouteDAGNode: - return &RouteNode{typedNode, p.graph} - } - - return nil -} - -type RouteNode struct { - httpRouteDAGNode - - graph *dag.DAG -} - -var _ PolicyTargetNode = &RouteNode{} - -func (r *RouteNode) AttachedPolicies() []PolicyNode { - // get children of Policy kind - policyNodeList := utils.Filter(r.graph.Children(r.ID()), func(n dag.Node) bool { - _, ok := n.(policyDAGNode) - return ok - }) - - return utils.Map(policyNodeList, func(n dag.Node) PolicyNode { - return PolicyNode{n.(policyDAGNode), r.graph} - }) -} - -func (r *RouteNode) Route() *gatewayapiv1.HTTPRoute { - return r.HTTPRoute -} - -func (r *RouteNode) ObjectKey() client.ObjectKey { - return client.ObjectKeyFromObject(r.HTTPRoute) -} - -func (r *RouteNode) GetObject() client.Object { - return r.Route() -} - -func (r *RouteNode) GetGatewayNode() *GatewayNode { - return nil -} - -func (r *RouteNode) GetRouteNode() *RouteNode { - return r -} - -type GatewayNode struct { - gatewayDAGNode - - graph *dag.DAG -} - -var _ PolicyTargetNode = &GatewayNode{} - -func (g *GatewayNode) AttachedPolicies() []PolicyNode { - // get children of Policy kind - policyNodeList := utils.Filter(g.graph.Children(g.ID()), func(n dag.Node) bool { - _, ok := n.(policyDAGNode) - return ok - }) - - return utils.Map(policyNodeList, func(n dag.Node) PolicyNode { - return PolicyNode{n.(policyDAGNode), g.graph} - }) -} - -func (g *GatewayNode) GetGateway() *gatewayapiv1.Gateway { - return g.Gateway -} - -func (g *GatewayNode) Routes() []RouteNode { - // get children of httproute kind - routeNodeList := utils.Filter(g.graph.Children(g.ID()), func(n dag.Node) bool { - _, ok := n.(httpRouteDAGNode) - return ok - }) - - return utils.Map(routeNodeList, func(n dag.Node) RouteNode { - routeDAGNode := n.(httpRouteDAGNode) - return RouteNode{routeDAGNode, g.graph} - }) -} - -func (g *GatewayNode) ObjectKey() client.ObjectKey { - return client.ObjectKeyFromObject(g.Gateway) -} - -func (g *GatewayNode) GetObject() client.Object { - return g.GetGateway() -} - -func (g *GatewayNode) GetGatewayNode() *GatewayNode { - return g -} - -func (g *GatewayNode) GetRouteNode() *RouteNode { - return nil -} - -// Topology defines a graph with Gateway API entities. -// Contains GatewayNodes (Gateway API gateways) -// Contains RouteNodes (Gateway API httproutes) -// Contains PolicyNodes (Gateway API policy attachment objects) -// Hierarchy is as follows. -// GatewayNode children can be either RouteNode or PolicyNode nodes -// RouteNode children are PolicyNode nodes -// PolicyNode parents can be either RouteNode or GatewayNode nodes -type Topology struct { - graph *dag.DAG - Logger logr.Logger -} - -type gatewayDAGNode struct { - *gatewayapiv1.Gateway -} - -func dagNodeIDFromObject(obj client.Object) dag.NodeID { - return fmt.Sprintf("%s#%s", obj.GetObjectKind().GroupVersionKind().String(), client.ObjectKeyFromObject(obj).String()) -} - -func (g gatewayDAGNode) ID() dag.NodeID { - return dagNodeIDFromObject(g.Gateway) -} - -type httpRouteDAGNode struct { - *gatewayapiv1.HTTPRoute -} - -func (h httpRouteDAGNode) ID() dag.NodeID { - return dagNodeIDFromObject(h.HTTPRoute) -} - -type policyDAGNode struct { - Policy -} - -func (p policyDAGNode) ID() dag.NodeID { - return dagNodeIDFromObject(p.Policy) -} - -type topologyOptions struct { - gateways []*gatewayapiv1.Gateway - routes []*gatewayapiv1.HTTPRoute - policies []Policy - logger logr.Logger - programmedGatewaysOnly bool - linkAcceptedRoutesOnly bool -} - -// TopologyOpts allows to manipulate topologyOptions. -type TopologyOpts func(*topologyOptions) - -func WithAcceptedRoutesLinkedOnly() TopologyOpts { - return func(o *topologyOptions) { - o.linkAcceptedRoutesOnly = true - } -} - -func WithLogger(logger logr.Logger) TopologyOpts { - return func(o *topologyOptions) { - o.logger = logger - } -} - -func WithGateways(gateways []*gatewayapiv1.Gateway) TopologyOpts { - return func(o *topologyOptions) { - o.gateways = gateways - } -} - -func WithRoutes(routes []*gatewayapiv1.HTTPRoute) TopologyOpts { - return func(o *topologyOptions) { - o.routes = routes - } -} - -func WithPolicies(policies []Policy) TopologyOpts { - return func(o *topologyOptions) { - o.policies = policies - } -} - -func WithProgrammedGatewaysOnly() TopologyOpts { - return func(o *topologyOptions) { - o.programmedGatewaysOnly = true - } -} - -func NewTopology(opts ...TopologyOpts) (*Topology, error) { - // defaults - o := &topologyOptions{ - logger: logr.Discard(), - programmedGatewaysOnly: false, - linkAcceptedRoutesOnly: false, - } - - for _, opt := range opts { - opt(o) - } - - typeIndexer := dag.WithFieldIndexer(typeField, func(n dag.Node) []dag.NodeLabel { - switch n.(type) { - case gatewayDAGNode: - return []dag.NodeLabel{gatewayLabel} - case httpRouteDAGNode: - return []dag.NodeLabel{httprouteLabel} - case policyDAGNode: - return []dag.NodeLabel{policyLabel} - default: - return nil - } - }) - - graph := dag.NewDAG(typeIndexer) - - gatewayDAGNodes := utils.Map(o.gateways, func(g *gatewayapiv1.Gateway) gatewayDAGNode { - return gatewayDAGNode{Gateway: g} - }) - - routeDAGNodes := utils.Map(o.routes, func(route *gatewayapiv1.HTTPRoute) httpRouteDAGNode { - return httpRouteDAGNode{HTTPRoute: route} - }) - - policyDAGNodes := utils.Map(o.policies, func(policy Policy) policyDAGNode { - return policyDAGNode{Policy: policy} - }) - - for _, node := range gatewayDAGNodes { - err := graph.AddNode(node) - if err != nil { - return nil, err - } - } - - for _, node := range routeDAGNodes { - err := graph.AddNode(node) - if err != nil { - return nil, err - } - } - - for _, node := range policyDAGNodes { - err := graph.AddNode(node) - if err != nil { - return nil, err - } - } - - edges := buildDAGEdges(o, gatewayDAGNodes, routeDAGNodes, policyDAGNodes) - - for _, edge := range edges { - err := graph.AddEdge(edge.parent.ID(), edge.child.ID()) - if err != nil { - return nil, err - } - } - - if !graph.Validate() { - return nil, errors.New("DAG is not valid") - } - - return &Topology{graph, o.logger}, nil -} - -type edge struct { - parent dag.Node - child dag.Node -} - -func buildDAGEdges(opts *topologyOptions, gateways []gatewayDAGNode, routes []httpRouteDAGNode, policies []policyDAGNode) []edge { - effectiveGateways := gateways - - if opts.programmedGatewaysOnly { - // filter out not programmed gateways - effectiveGateways = utils.Filter(gateways, func(g gatewayDAGNode) bool { - return meta.IsStatusConditionTrue(g.Status.Conditions, string(gatewayapiv1.GatewayConditionProgrammed)) - }) - } - - // internal index: key -> gateway for reference - gatewaysIndex := make(map[client.ObjectKey]gatewayDAGNode, len(effectiveGateways)) - for _, gateway := range effectiveGateways { - gatewaysIndex[client.ObjectKeyFromObject(gateway.Gateway)] = gateway - } - - edges := make([]edge, 0) - - for _, route := range routes { - gatewayParentKeys := GetGatewayParentKeys(route.HTTPRoute) - - if opts.linkAcceptedRoutesOnly { - gatewayParentKeys = GetRouteAcceptedGatewayParentKeys(route.HTTPRoute) - } - - for _, parentKey := range gatewayParentKeys { - // the parent gateway may not be in the available list of gateways - // or the gateway may not be valid - if gateway, ok := gatewaysIndex[parentKey]; ok { - edges = append(edges, edge{parent: gateway, child: route}) - } - } - - // Compute route's child (attached) policies - attachedPolicies := utils.Filter(policies, func(p policyDAGNode) bool { - group := p.GetTargetRef().Group - kind := p.GetTargetRef().Kind - name := p.GetTargetRef().Name - namespace := p.GetNamespace() - - return group == gatewayapiv1.GroupName && - kind == "HTTPRoute" && - name == gatewayapiv1.ObjectName(route.Name) && - namespace == route.Namespace - }) - - for _, attachedPolicy := range attachedPolicies { - edges = append(edges, edge{parent: route, child: attachedPolicy}) - } - } - - for _, g := range effectiveGateways { - // Compute gateway's child (attached) policies - attachedPolicies := utils.Filter(policies, func(p policyDAGNode) bool { - group := p.GetTargetRef().Group - kind := p.GetTargetRef().Kind - name := p.GetTargetRef().Name - namespace := p.GetNamespace() - - return group == gatewayapiv1.GroupName && - kind == "Gateway" && - name == gatewayapiv1.ObjectName(g.Name) && - namespace == g.Namespace - }) - - for _, attachedPolicy := range attachedPolicies { - edges = append(edges, edge{parent: g, child: attachedPolicy}) - } - } - - return edges -} - -func (g *Topology) Gateways() []GatewayNode { - gatewayNodes := g.graph.GetNodes(typeField, gatewayLabel) - - return utils.Map(gatewayNodes, func(n dag.Node) GatewayNode { - gNode, ok := n.(gatewayDAGNode) - if !ok { // should not happen - g.Logger.Error( - fmt.Errorf("node ID %s type %T", n.ID(), n), - "DAG gateway index returns nodes that are not gateways", - ) - return GatewayNode{} - } - - return GatewayNode{gNode, g.graph} - }) -} - -func (g *Topology) Routes() []RouteNode { - routeNodes := g.graph.GetNodes(typeField, httprouteLabel) - - return utils.Map(routeNodes, func(r dag.Node) RouteNode { - rNode, ok := r.(httpRouteDAGNode) - if !ok { // should not happen - g.Logger.Error( - fmt.Errorf("node ID %s type %T", r.ID(), r), - "DAG route index returns nodes that are not routes", - ) - return RouteNode{} - } - return RouteNode{rNode, g.graph} - }) -} - -func (g *Topology) Policies() []PolicyNode { - policyNodes := g.graph.GetNodes(typeField, policyLabel) - - return utils.Map(policyNodes, func(r dag.Node) PolicyNode { - pNode, ok := r.(policyDAGNode) - if !ok { // should not happen - g.Logger.Error( - fmt.Errorf("node ID %s type %T", r.ID(), r), - "DAG policy index returns nodes that are not policies", - ) - return PolicyNode{} - } - return PolicyNode{pNode, g.graph} - }) -} - -func (g *Topology) GetPolicy(policy Policy) (PolicyNode, bool) { - dagNode, err := g.graph.GetNode(policyDAGNode{policy}.ID()) - if err != nil { - return PolicyNode{}, false - } - - pNode, ok := dagNode.(policyDAGNode) - if !ok { - g.Logger.Error( - fmt.Errorf("policy key %s with node ID %s type %T", - client.ObjectKeyFromObject(policy), dagNode.ID(), dagNode), - "the policy ID conflicts with another graph node type", - ) - return PolicyNode{}, false - } - return PolicyNode{pNode, g.graph}, true -} diff --git a/pkg/library/gatewayapi/topology_indexes.go b/pkg/library/gatewayapi/topology_indexes.go deleted file mode 100644 index 7f1ff6310..000000000 --- a/pkg/library/gatewayapi/topology_indexes.go +++ /dev/null @@ -1,220 +0,0 @@ -package gatewayapi - -import ( - "encoding/json" - - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -type TopologyIndexes struct { - // gatewayPolicies is an index of gateways mapping to Kuadrant Policies which - // directly or indirectly are targeting the indexed gateway. - // When a kuadrant policy directly or indirectly targets a gateway, the policy's configuration - // needs to be added to that gateway. - // Type: Gateway -> []Policy - gatewayPolicies map[client.ObjectKey][]Policy - - // policyRoute is an index of policies mapping to HTTPRoutes - // The index only includes policies targeting only existing and accepted (by parent gateways) HTTPRoutes - // Type: Policy -> HTTPRoute - policyRoute map[client.ObjectKey]*gatewayapiv1.HTTPRoute - - // policyTarget is an index of policies mapping to objects - // The index only includes policies targeting either Gateways or existing and accepted (by parent gateways) HTTPRoutes - // Type: Policy -> client.Object - policyTarget map[client.ObjectKey]client.Object - - // untargetedRoutes is an index of gateways mapping to HTTPRoutes not targeted by a kuadrant policy - // Gateway -> []HTTPRoute - untargetedRoutes map[client.ObjectKey][]*gatewayapiv1.HTTPRoute - - // Raw topology with gateways, routes and policies - // Currently only used for logging - internalTopology *Topology -} - -func NewTopologyIndexes(t *Topology) *TopologyIndexes { - if t == nil { - return nil - } - - return &TopologyIndexes{ - gatewayPolicies: buildGatewayPoliciesIndex(t), - policyRoute: buildPolicyRouteIndex(t), - policyTarget: buildPolicyTargetIndex(t), - untargetedRoutes: buildUntargetedRoutesIndex(t), - internalTopology: t, - } -} - -// PoliciesFromGateway returns Kuadrant Policies which -// directly or indirectly are targeting the gateway given as input. -// Type: Gateway -> []Policy -func (k *TopologyIndexes) PoliciesFromGateway(gateway *gatewayapiv1.Gateway) []Policy { - return k.gatewayPolicies[client.ObjectKeyFromObject(gateway)] -} - -// GetPolicyHTTPRoute returns the HTTPRoute being targeted by the policy. -// The method only returns existing and accepted (by parent gateways) HTTPRoutes -// Type: Policy -> HTTPRoute -func (k *TopologyIndexes) GetPolicyHTTPRoute(policy Policy) *gatewayapiv1.HTTPRoute { - return k.policyRoute[client.ObjectKeyFromObject(policy)] -} - -// GetPolicyTargetObject returns the client.Object targeted by the policy. -// Type: Policy -> client.Object -func (k *TopologyIndexes) GetPolicyTargetObject(policy Policy) client.Object { - return k.policyTarget[client.ObjectKeyFromObject(policy)] -} - -// GetUntargetedRoutes returns the HTTPRoutes not targeted by any kuadrant policy -// having the gateway given as input as parent. -// Gateway -> []HTTPRoute -func (k *TopologyIndexes) GetUntargetedRoutes(gateway *gatewayapiv1.Gateway) []*gatewayapiv1.HTTPRoute { - return k.untargetedRoutes[client.ObjectKeyFromObject(gateway)] -} - -// String representation of the topology -// This is not designed to be a serialization format that could be deserialized -func (k *TopologyIndexes) String() string { - policiesPerGateway := func() map[string][]string { - index := make(map[string][]string, 0) - for gatewayKey, policyList := range k.gatewayPolicies { - index[gatewayKey.String()] = utils.Map(policyList, func(p Policy) string { - return client.ObjectKeyFromObject(p).String() - }) - } - if len(index) == 0 { - return nil - } - return index - }() - - policiesTargetingRoutes := func() map[string]string { - index := make(map[string]string, 0) - for policyKey, route := range k.policyRoute { - index[policyKey.String()] = client.ObjectKeyFromObject(route).String() - } - if len(index) == 0 { - return nil - } - return index - }() - - policiesTargetingObjects := func() map[string]string { - index := make(map[string]string) - for policyKey, target := range k.policyTarget { - index[policyKey.String()] = client.ObjectKeyFromObject(target).String() - } - if len(index) == 0 { - return nil - } - return index - }() - - untargetedRoutesPerGateway := func() map[string][]string { - index := make(map[string][]string, 0) - for gatewayKey, routeList := range k.untargetedRoutes { - index[gatewayKey.String()] = utils.Map(routeList, func(route *gatewayapiv1.HTTPRoute) string { - return client.ObjectKeyFromObject(route).String() - }) - } - if len(index) == 0 { - return nil - } - return index - }() - - indexesRepr := struct { - GatewayPolicies map[string][]string `json:"policiesPerGateway"` - PolicyRoute map[string]string `json:"policiesTargetingRoutes"` - PolicyTarget map[string]string `json:"policiesTargetingObjects"` - UntargetedRoutes map[string][]string `json:"untargetedRoutesPerGateway"` - }{ - policiesPerGateway, - policiesTargetingRoutes, - policiesTargetingObjects, - untargetedRoutesPerGateway, - } - - jsonData, err := json.MarshalIndent(indexesRepr, "", " ") - if err != nil { - panic(err) - } - return string(jsonData) -} - -func buildGatewayPoliciesIndex(t *Topology) map[client.ObjectKey][]Policy { - // Build Gateway -> []Policy index with all the policies affecting the indexed gateway - index := make(map[client.ObjectKey][]Policy, 0) - for _, gatewayNode := range t.Gateways() { - // Consisting of: - // - Policy targeting directly the gateway - // - Policies targeting the descendant routes of the gateway - policies := make([]PolicyNode, 0) - - policies = append(policies, gatewayNode.AttachedPolicies()...) - - for _, routeNode := range gatewayNode.Routes() { - policies = append(policies, routeNode.AttachedPolicies()...) - } - - index[gatewayNode.ObjectKey()] = utils.Map(policies, func(pNode PolicyNode) Policy { - return pNode.Policy - }) - } - - return index -} - -func buildPolicyRouteIndex(t *Topology) map[client.ObjectKey]*gatewayapiv1.HTTPRoute { - // Build Policy -> HTTPRoute index with the route targeted by the indexed policy - index := make(map[client.ObjectKey]*gatewayapiv1.HTTPRoute, 0) - for _, routeNode := range t.Routes() { - for _, policy := range routeNode.AttachedPolicies() { - index[client.ObjectKeyFromObject(policy)] = routeNode.Route() - } - } - - return index -} - -func buildPolicyTargetIndex(t *Topology) map[client.ObjectKey]client.Object { - index := make(map[client.ObjectKey]client.Object) - for _, gatewayNode := range t.Gateways() { - obj := gatewayNode.GetObject() - for _, policy := range gatewayNode.AttachedPolicies() { - index[client.ObjectKeyFromObject(policy)] = obj - } - } - for _, routeNode := range t.Routes() { - obj := routeNode.GetObject() - for _, policy := range routeNode.AttachedPolicies() { - index[client.ObjectKeyFromObject(policy)] = obj - } - } - - return index -} - -func buildUntargetedRoutesIndex(t *Topology) map[client.ObjectKey][]*gatewayapiv1.HTTPRoute { - // Build Gateway -> []HTTPRoute index with all the routes not targeted by a policy - index := make(map[client.ObjectKey][]*gatewayapiv1.HTTPRoute, 0) - - for _, gatewayNode := range t.Gateways() { - routes := make([]*gatewayapiv1.HTTPRoute, 0) - - for _, routeNode := range gatewayNode.Routes() { - if len(routeNode.AttachedPolicies()) == 0 { - routes = append(routes, routeNode.Route()) - } - } - - index[gatewayNode.ObjectKey()] = routes - } - - return index -} diff --git a/pkg/library/gatewayapi/topology_indexes_test.go b/pkg/library/gatewayapi/topology_indexes_test.go deleted file mode 100644 index 8b11865a2..000000000 --- a/pkg/library/gatewayapi/topology_indexes_test.go +++ /dev/null @@ -1,392 +0,0 @@ -//go:build unit - -package gatewayapi - -import ( - "strings" - "testing" - - "gotest.tools/assert" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/log" -) - -func TestTopologyIndexes_PoliciesFromGateway(t *testing.T) { - t.Run("empty topology", func(subT *testing.T) { - t, err := NewTopology(WithLogger(log.NewLogger())) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - policies := topologyIndexes.PoliciesFromGateway(testBasicGateway("gw1", NS)) - assert.Equal(subT, len(policies), 0) - }) - - t.Run("unknown gateway", func(subT *testing.T) { - gateways := []*gatewayapiv1.Gateway{ - testBasicGateway("gw1", NS), - testBasicGateway("gw2", NS), - } - - t, err := NewTopology(WithGateways(gateways), WithLogger(log.NewLogger())) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - policies := topologyIndexes.PoliciesFromGateway(testBasicGateway("unknown", NS)) - assert.Equal(subT, len(policies), 0) - }) - - t.Run("invalid gateway is skipped", func(subT *testing.T) { - // route1 -> gw1 - // policy1 -> gw1 - // policy2 -> route1 - - invalidGateway := testInvalidGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{invalidGateway} - - route1 := testBasicRoute("route1", NS, invalidGateway) - routes := []*gatewayapiv1.HTTPRoute{route1} - - gwPolicy := testBasicGatewayPolicy("policy1", NS, invalidGateway) - routePolicy := testBasicRoutePolicy("policy2", NS, route1) - policies := []Policy{gwPolicy, routePolicy} - - t, err := NewTopology( - WithProgrammedGatewaysOnly(), - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - policiesFromGateway := topologyIndexes.PoliciesFromGateway(invalidGateway) - assert.Equal(subT, len(policiesFromGateway), 0) - }) - - t.Run("gateway with direct policy", func(subT *testing.T) { - // route1 -> gw1 - // policy1 -> gw1 - - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - route1 := testBasicRoute("route1", NS, gw1) - routes := []*gatewayapiv1.HTTPRoute{route1} - - gwPolicy := testBasicGatewayPolicy("policy1", NS, gw1) - policies := []Policy{gwPolicy} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - policiesFromGateway := topologyIndexes.PoliciesFromGateway(gw1) - assert.Equal(subT, len(policiesFromGateway), 1) - assert.Equal(subT, - client.ObjectKeyFromObject(policiesFromGateway[0]), - client.ObjectKeyFromObject(gwPolicy), - ) - }) - - t.Run("gateway with policies targeting routes", func(subT *testing.T) { - // route1 -> gw1 - // policy1 -> route1 - - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - route1 := testBasicRoute("route1", NS, gw1) - routes := []*gatewayapiv1.HTTPRoute{route1} - - routePolicy := testBasicRoutePolicy("policy1", NS, route1) - policies := []Policy{routePolicy} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - policiesFromGateway := topologyIndexes.PoliciesFromGateway(gw1) - assert.Equal(subT, len(policiesFromGateway), 1) - assert.Equal(subT, - client.ObjectKeyFromObject(policiesFromGateway[0]), - client.ObjectKeyFromObject(routePolicy), - ) - }) - - t.Run("single policy targeting route with multiple parent gateways", func(subT *testing.T) { - // route1 -> gw1 - // route1 -> gw2 - // policy1 -> route1 - - gw1 := testBasicGateway("gw1", NS) - gw2 := testBasicGateway("gw2", NS) - gateways := []*gatewayapiv1.Gateway{gw1, gw2} - - route1 := testBasicRoute("route1", NS, gw1, gw2) - routes := []*gatewayapiv1.HTTPRoute{route1} - - routePolicy := testBasicRoutePolicy("policy1", NS, route1) - policies := []Policy{routePolicy} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - policiesGw1 := topologyIndexes.PoliciesFromGateway(gw1) - assert.Equal(subT, len(policiesGw1), 1) - assert.Equal(subT, - client.ObjectKeyFromObject(policiesGw1[0]), - client.ObjectKeyFromObject(routePolicy), - ) - - policiesGw2 := topologyIndexes.PoliciesFromGateway(gw2) - assert.Equal(subT, len(policiesGw2), 1) - assert.Equal(subT, - client.ObjectKeyFromObject(policiesGw2[0]), - client.ObjectKeyFromObject(routePolicy), - ) - }) -} - -func TestTopologyIndexes_GetPolicyHTTPRoute(t *testing.T) { - t.Run("empty topology", func(subT *testing.T) { - // policy1 -> route1 - - route1 := testBasicRoute("route1", NS, nil...) - policy := testBasicRoutePolicy("policy1", NS, route1) - - t, err := NewTopology(WithLogger(log.NewLogger())) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - route := topologyIndexes.GetPolicyHTTPRoute(policy) - assert.Assert(subT, route == nil) - }) - - t.Run("gateway with direct policy", func(subT *testing.T) { - // policy1 -> gw1 - - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - gwPolicy := testBasicGatewayPolicy("policy1", NS, gw1) - policies := []Policy{gwPolicy} - - t, err := NewTopology( - WithGateways(gateways), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - route := topologyIndexes.GetPolicyHTTPRoute(gwPolicy) - assert.Assert(subT, route == nil) - }) - - t.Run("route with direct policy", func(subT *testing.T) { - // route1 -> gw1 - // policy1 -> route1 - - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - route1 := testBasicRoute("route1", NS, gw1) - routes := []*gatewayapiv1.HTTPRoute{route1} - - routePolicy := testBasicRoutePolicy("policy1", NS, route1) - policies := []Policy{routePolicy} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - route := topologyIndexes.GetPolicyHTTPRoute(routePolicy) - assert.Assert(subT, route != nil) - assert.Equal(subT, - client.ObjectKeyFromObject(route), - client.ObjectKeyFromObject(route1), - ) - }) -} - -func TestTopologyIndexes_GetUntargetedRoutes(t *testing.T) { - t.Run("gateway without routes", func(subT *testing.T) { - // gw1 - // policy1 -> gw1 - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - gatewayPolicy := testBasicGatewayPolicy("policy1", NS, gw1) - policies := []Policy{gatewayPolicy} - - t, err := NewTopology( - WithGateways(gateways), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - untargetedRoutes := topologyIndexes.GetUntargetedRoutes(gw1) - assert.Equal(subT, len(untargetedRoutes), 0) - }) - - t.Run("all routes have policies", func(subT *testing.T) { - // gw1 - // route 1 -> gw1 - // route 2 -> gw1 - // policy1 -> route1 - // policy2 -> route1 - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - route1 := testBasicRoute("route1", NS, gw1) - route2 := testBasicRoute("route2", NS, gw1) - routes := []*gatewayapiv1.HTTPRoute{route1, route2} - - routePolicy1 := testBasicRoutePolicy("policy1", NS, route1) - routePolicy2 := testBasicRoutePolicy("policy2", NS, route2) - policies := []Policy{routePolicy1, routePolicy2} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - untargetedRoutes := topologyIndexes.GetUntargetedRoutes(gw1) - assert.Equal(subT, len(untargetedRoutes), 0) - }) - - t.Run("only one route is untargeted", func(subT *testing.T) { - // gw1 - // route 1 -> gw1 - // route 2 -> gw1 - // policy1 -> route1 - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - route1 := testBasicRoute("route1", NS, gw1) - route2 := testBasicRoute("route2", NS, gw1) - routes := []*gatewayapiv1.HTTPRoute{route1, route2} - - routePolicy1 := testBasicRoutePolicy("policy1", NS, route1) - policies := []Policy{routePolicy1} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - untargetedRoutes := topologyIndexes.GetUntargetedRoutes(gw1) - assert.Equal(subT, len(untargetedRoutes), 1) - assert.Equal(subT, - client.ObjectKeyFromObject(untargetedRoutes[0]), - client.ObjectKeyFromObject(route2), - ) - }) - - t.Run("all routes are untargeted", func(subT *testing.T) { - // gw1 - // route 1 -> gw1 - // route 2 -> gw1 - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - route1 := testBasicRoute("route1", NS, gw1) - route2 := testBasicRoute("route2", NS, gw1) - routes := []*gatewayapiv1.HTTPRoute{route1, route2} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - untargetedRoutes := topologyIndexes.GetUntargetedRoutes(gw1) - assert.Equal(subT, len(untargetedRoutes), 2) - }) -} - -func TestTopologyIndexes_TopologyString(t *testing.T) { - t.Run("empty topology", func(subT *testing.T) { - t, err := NewTopology(WithLogger(log.NewLogger())) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - assert.NilError(subT, err) - - topologyStr := topologyIndexes.String() - assert.Assert(subT, strings.Contains(topologyStr, `"policiesPerGateway": null`)) - assert.Assert(subT, strings.Contains(topologyStr, `"policiesTargetingRoutes": null`)) - assert.Assert(subT, strings.Contains(topologyStr, `"untargetedRoutesPerGateway": null`)) - }) - - t.Run("1 gateway 1 route 1 policy for route", func(subT *testing.T) { - // route1 -> gw1 - // policy1 -> route1 - - gw1 := testBasicGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{gw1} - - route1 := testBasicRoute("route1", NS, gw1) - routes := []*gatewayapiv1.HTTPRoute{route1} - - routePolicy := testBasicRoutePolicy("policy1", NS, route1) - policies := []Policy{routePolicy} - - t, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - topologyIndexes := NewTopologyIndexes(t) - - topologyStr := topologyIndexes.String() - assert.Assert(subT, strings.Contains(topologyStr, `"policiesPerGateway": { - "nsA/gw1": [ - "nsA/policy1" - ] - }`)) - assert.Assert(subT, strings.Contains(topologyStr, `"policiesTargetingRoutes": { - "nsA/policy1": "nsA/route1" - }`)) - assert.Assert(subT, strings.Contains(topologyStr, `"untargetedRoutesPerGateway": { - "nsA/gw1": [] - }`)) - }) -} diff --git a/pkg/library/gatewayapi/topology_test.go b/pkg/library/gatewayapi/topology_test.go deleted file mode 100644 index d5b75ba3a..000000000 --- a/pkg/library/gatewayapi/topology_test.go +++ /dev/null @@ -1,387 +0,0 @@ -//go:build unit - -package gatewayapi - -import ( - "testing" - - "gotest.tools/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" - "github.com/kuadrant/kuadrant-operator/pkg/log" -) - -func TestGatewayAPITopology_Gateways(t *testing.T) { - t.Run("no gateways", func(subT *testing.T) { - topology, err := NewTopology(WithLogger(log.NewLogger())) - assert.NilError(subT, err) - assert.Assert(subT, len(topology.Gateways()) == 0, "topology should not return any gateway") - }) - - t.Run("invalid gateway is added as a topology node", func(subT *testing.T) { - invalidGateway := testInvalidGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{invalidGateway} - - topology, err := NewTopology(WithGateways(gateways), WithLogger(log.NewLogger())) - assert.NilError(subT, err) - - assert.Equal(subT, len(topology.Gateways()), 1, "not ready gateways should be added") - }) - - t.Run("valid gateways are included", func(subT *testing.T) { - gateways := make([]*gatewayapiv1.Gateway, 0) - gwKeys := []client.ObjectKey{ - {Name: "gw1", Namespace: NS}, - {Name: "gw2", Namespace: NS}, - {Name: "gw3", Namespace: NS}, - } - for _, gwKey := range gwKeys { - gateways = append(gateways, testBasicGateway(gwKey.Name, gwKey.Namespace)) - } - - topology, err := NewTopology(WithGateways(gateways), WithLogger(log.NewLogger())) - assert.NilError(subT, err) - - assert.Assert(subT, len(topology.Gateways()) == 3, "expected gateways not returned") - returnedKeys := make([]client.ObjectKey, 0) - for _, gw := range topology.Gateways() { - returnedKeys = append(returnedKeys, client.ObjectKeyFromObject(gw.Gateway)) - } - assert.Assert(subT, utils.SameElements(gwKeys, returnedKeys)) - }) -} - -func TestGatewayAPITopology_GatewayNode_Routes(t *testing.T) { - t.Run("empty routes", func(subT *testing.T) { - gw1 := testBasicGateway("gw1", NS) - gw2 := testBasicGateway("gw2", NS) - gw3 := testBasicGateway("gw3", NS) - gateways := []*gatewayapiv1.Gateway{gw1, gw2, gw3} - - topology, err := NewTopology(WithGateways(gateways), WithLogger(log.NewLogger())) - assert.NilError(subT, err) - - for _, gw := range topology.Gateways() { - assert.Equal(subT, len(gw.Routes()), 0) - } - }) - - t.Run("some routes", func(subT *testing.T) { - // route11 -> gw1 - // route21 -> gw2 - - gw1 := testBasicGateway("gw1", NS) - gw2 := testBasicGateway("gw2", NS) - gateways := []*gatewayapiv1.Gateway{gw1, gw2} - - route11 := testBasicRoute("route11", NS, gw1) - route21 := testBasicRoute("route21", NS, gw2) - routes := []*gatewayapiv1.HTTPRoute{route11, route21} - - topology, err := NewTopology( - WithGateways(gateways), - WithRoutes(routes), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - gwIndex := map[client.ObjectKey]GatewayNode{} - for _, gw := range topology.Gateways() { - gwIndex[client.ObjectKeyFromObject(gw.Gateway)] = gw - } - - gw1Node, ok := gwIndex[client.ObjectKeyFromObject(gw1)] - assert.Assert(subT, ok, "expected gateway not found") - assert.Equal(subT, len(gw1Node.Routes()), 1) - assert.Equal(subT, client.ObjectKeyFromObject(route11), client.ObjectKeyFromObject(gw1Node.Routes()[0].Route())) - - gw2Node, ok := gwIndex[client.ObjectKeyFromObject(gw2)] - assert.Assert(subT, ok, "expected gateway not found") - assert.Equal(subT, len(gw2Node.Routes()), 1) - assert.Equal(subT, client.ObjectKeyFromObject(route21), client.ObjectKeyFromObject(gw2Node.Routes()[0].Route())) - }) - - t.Run("some routes not accepted by gateway", func(subT *testing.T) { - // routeA -> gw1 (accepted) - // routeB -> gw1 (accepted) - // routeB -> gw2 (not accepted) - - gw1 := testBasicGateway("gw1", NS) - gw2 := testBasicGateway("gw2", NS) - gateways := []*gatewayapiv1.Gateway{gw1, gw2} - - routeA := testBasicRoute("routeA", NS, gw1) - routeB := testBasicRoute("routeB", NS, gw1, gw2) - routeB.Status.Parents[1].Conditions[0].Status = metav1.ConditionFalse - routes := []*gatewayapiv1.HTTPRoute{routeA, routeB} - - topology, err := NewTopology( - WithAcceptedRoutesLinkedOnly(), - WithGateways(gateways), - WithRoutes(routes), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - gwIndex := map[client.ObjectKey]GatewayNode{} - for _, gw := range topology.Gateways() { - gwIndex[client.ObjectKeyFromObject(gw.Gateway)] = gw - } - - gw1Node, ok := gwIndex[client.ObjectKeyFromObject(gw1)] - assert.Assert(subT, ok, "expected gateway not found") - assert.Equal(subT, len(gw1Node.Routes()), 2) - returnedKeys := make([]client.ObjectKey, 0) - for _, route := range gw1Node.Routes() { - returnedKeys = append(returnedKeys, client.ObjectKeyFromObject(route.Route())) - } - expectedKeys := []client.ObjectKey{ - {Name: "routeA", Namespace: NS}, - {Name: "routeB", Namespace: NS}, - } - assert.Assert(subT, utils.SameElements(expectedKeys, returnedKeys)) - - gw2Node, ok := gwIndex[client.ObjectKeyFromObject(gw2)] - assert.Assert(subT, ok, "expected gateway not found") - assert.Equal(subT, len(gw2Node.Routes()), 0) - }) - - t.Run("routes targeting unprogrammed gateway are not linked", func(subT *testing.T) { - // routeA -> gw1 (unprogrammed) - invalidGateway := testInvalidGateway("gw1", NS) - gateways := []*gatewayapiv1.Gateway{invalidGateway} - route := testBasicRoute("route", NS, invalidGateway) - routes := []*gatewayapiv1.HTTPRoute{route} - - topology, err := NewTopology( - WithProgrammedGatewaysOnly(), - WithGateways(gateways), - WithRoutes(routes), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - gws := topology.Gateways() - assert.Equal(subT, len(gws), 1, "not ready gateways should be added") - assert.Equal(subT, len(gws[0].Routes()), 0, "routes targeting invalid gateways should not be linked") - }) -} - -func TestGatewayAPITopology_GatewayNode_AttachedPolicies(t *testing.T) { - // policy1 -> gw 1 - // none -> gw2 - - gw1 := testBasicGateway("gw1", NS) - gw2 := testBasicGateway("gw2", NS) - gateways := []*gatewayapiv1.Gateway{gw1, gw2} - - gwPolicy := testBasicGatewayPolicy("policy1", NS, gw1) - policies := []Policy{gwPolicy} - - topology, err := NewTopology( - WithGateways(gateways), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(t, err) - - gwIndex := map[client.ObjectKey]GatewayNode{} - for _, gw := range topology.Gateways() { - gwIndex[client.ObjectKeyFromObject(gw.Gateway)] = gw - } - - gw1Node, ok := gwIndex[client.ObjectKeyFromObject(gw1)] - assert.Assert(t, ok, "expected gateway not found") - assert.Equal(t, len(gw1Node.AttachedPolicies()), 1) - assert.Equal(t, client.ObjectKeyFromObject(gwPolicy), client.ObjectKeyFromObject(gw1Node.AttachedPolicies()[0])) - - gw2Node, ok := gwIndex[client.ObjectKeyFromObject(gw2)] - assert.Assert(t, ok, "expected gateway not found") - assert.Equal(t, len(gw2Node.AttachedPolicies()), 0) -} - -func TestGatewayAPITopology_Routes(t *testing.T) { - t.Run("no routes", func(subT *testing.T) { - topology, err := NewTopology(WithLogger(log.NewLogger())) - if err != nil { - subT.Fatal(err) - } - - if len(topology.Routes()) != 0 { - subT.Fatal("topology should not return any route") - } - }) - - t.Run("parentless routes are included", func(subT *testing.T) { - routes := make([]*gatewayapiv1.HTTPRoute, 0) - for _, routeName := range []string{"r1", "r2", "r3"} { - routes = append(routes, testBasicRoute(routeName, NS)) - } - - topology, err := NewTopology(WithRoutes(routes), WithLogger(log.NewLogger())) - assert.NilError(subT, err) - - assert.Assert(subT, len(topology.Routes()) == 3, "expected routes not returned") - }) -} - -func TestGatewayAPITopology_RouteNode_AttachedPolicies(t *testing.T) { - // policy1 -> route 1 - // none -> route 2 - - route1 := testBasicRoute("route1", NS) - route2 := testBasicRoute("route2", NS) - routes := []*gatewayapiv1.HTTPRoute{route1, route2} - - routePolicy := testBasicRoutePolicy("policy1", NS, route1) - policies := []Policy{routePolicy} - - topology, err := NewTopology( - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(t, err) - - routeIndex := map[client.ObjectKey]RouteNode{} - for _, route := range topology.Routes() { - routeIndex[client.ObjectKeyFromObject(route.Route())] = route - } - - route1Node, ok := routeIndex[client.ObjectKeyFromObject(route1)] - assert.Assert(t, ok, "expected route not found") - assert.Equal(t, len(route1Node.AttachedPolicies()), 1) - assert.Equal(t, client.ObjectKeyFromObject(routePolicy), client.ObjectKeyFromObject(route1Node.AttachedPolicies()[0])) - - route2Node, ok := routeIndex[client.ObjectKeyFromObject(route2)] - assert.Assert(t, ok, "expected route not found") - assert.Equal(t, len(route2Node.AttachedPolicies()), 0) -} - -func TestGatewayAPITopology_Policies(t *testing.T) { - t.Run("no policies", func(subT *testing.T) { - topology, err := NewTopology(WithLogger(log.NewLogger())) - assert.NilError(subT, err) - assert.Assert(subT, len(topology.Policies()) == 0, "topology should not return any policy") - }) - - t.Run("policy targeting missing network objet is added as a topology node", func(subT *testing.T) { - policies := make([]Policy, 0) - for _, pName := range []string{"p1", "p2", "p3"} { - policies = append(policies, testStandalonePolicy(pName, NS)) - } - - topology, err := NewTopology(WithPolicies(policies), WithLogger(log.NewLogger())) - assert.NilError(subT, err) - - assert.Equal(subT, len(topology.Policies()), 3, "standalone policies should be added") - }) - - t.Run("happy path", func(subT *testing.T) { - route := testBasicRoute("route", NS) - routes := []*gatewayapiv1.HTTPRoute{route} - - routePolicy := testBasicRoutePolicy("policy", NS, route) - policies := []Policy{routePolicy} - - topology, err := NewTopology( - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - assert.Equal(subT, len(topology.Policies()), 1, "expected policies not returned") - }) -} - -func TestGatewayAPITopology_Policies_TargetRef(t *testing.T) { - t.Run("policy targeting missing network objet does not return TargetRef", func(subT *testing.T) { - topology, err := NewTopology( - WithPolicies([]Policy{testStandalonePolicy("p", NS)}), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - policyNodes := topology.Policies() - assert.Equal(subT, len(policyNodes), 1, "standalone policies should be added") - assert.Assert(subT, policyNodes[0].TargetRef() == nil, "standalone policies should not have target ref") - }) - - t.Run("targeting a httproute should return routenode", func(subT *testing.T) { - route := testBasicRoute("route", NS) - routes := []*gatewayapiv1.HTTPRoute{route} - - routePolicy := testBasicRoutePolicy("policy", NS, route) - policies := []Policy{routePolicy} - - topology, err := NewTopology( - WithRoutes(routes), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - policyNodes := topology.Policies() - assert.Equal(subT, len(policyNodes), 1, "expected policies not returned") - targetRefNode := policyNodes[0].TargetRef() - targetRouteNode, ok := targetRefNode.(*RouteNode) - assert.Assert(subT, ok, "policy's target ref is not routenode") - assert.Equal(subT, targetRouteNode.ObjectKey(), client.ObjectKeyFromObject(route), "policy's target ref has unexpected key") - }) - - t.Run("targeting a gateway should return gatewaynode", func(subT *testing.T) { - gw := testBasicGateway("gw", NS) - gateways := []*gatewayapiv1.Gateway{gw} - - gwPolicy := testBasicGatewayPolicy("policy", NS, gw) - policies := []Policy{gwPolicy} - - topology, err := NewTopology( - WithGateways(gateways), - WithPolicies(policies), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - policyNodes := topology.Policies() - assert.Equal(subT, len(policyNodes), 1, "expected policies not returned") - targetRefNode := policyNodes[0].TargetRef() - targetGatewayNode, ok := targetRefNode.(*GatewayNode) - assert.Assert(subT, ok, "policy's target ref is not gatewaynode") - assert.Equal(subT, targetGatewayNode.ObjectKey(), client.ObjectKeyFromObject(gw), "policy's target ref has unexpected key") - }) -} - -func TestGatewayAPITopology_GetPolicy(t *testing.T) { - t.Run("when ID is not found, returns not found", func(subT *testing.T) { - topology, err := NewTopology( - WithPolicies([]Policy{testStandalonePolicy("p", NS)}), - WithLogger(log.NewLogger()), - ) - assert.NilError(subT, err) - - _, ok := topology.GetPolicy(testStandalonePolicy("other", NS)) - assert.Assert(subT, !ok, "'other' policy should not be found") - }) - - t.Run("when ID is found, returns the policy", func(subT *testing.T) { - policies := make([]Policy, 0) - for _, pName := range []string{"p1", "p2", "p3"} { - policies = append(policies, testStandalonePolicy(pName, NS)) - } - - topology, err := NewTopology(WithPolicies(policies), WithLogger(log.NewLogger())) - assert.NilError(subT, err) - - policyNode, ok := topology.GetPolicy(testStandalonePolicy("p1", NS)) - assert.Assert(subT, ok, "policy should be found") - - assert.Equal(subT, client.ObjectKeyFromObject(policyNode), client.ObjectKey{ - Name: "p1", Namespace: NS, - }) - }) -} diff --git a/pkg/library/gatewayapi/types_test.go b/pkg/library/gatewayapi/types_test.go deleted file mode 100644 index 162c67ec1..000000000 --- a/pkg/library/gatewayapi/types_test.go +++ /dev/null @@ -1,302 +0,0 @@ -//go:build unit - -package gatewayapi - -import ( - "context" - "reflect" - "sort" - "testing" - "time" - - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/google/go-cmp/cmp" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" -) - -var ( - _ Policy = &TestPolicy{} - _ PolicyStatus = &FakePolicyStatus{} -) - -type TestPolicy struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - TargetRef gatewayapiv1alpha2.LocalPolicyTargetReference `json:"targetRef"` - Status FakePolicyStatus `json:"status"` -} - -func (p *TestPolicy) Kind() string { - return "FakePolicy" -} - -func (p *TestPolicy) List(ctx context.Context, c client.Client, namespace string) []Policy { - return nil -} - -func (p *TestPolicy) BackReferenceAnnotationName() string { - return "" -} - -func (p *TestPolicy) DirectReferenceAnnotationName() string { - return "" -} - -func (p *TestPolicy) PolicyClass() PolicyClass { - return DirectPolicy -} - -func (p *TestPolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { - return p.TargetRef -} - -func (p *TestPolicy) GetStatus() PolicyStatus { - return &p.Status -} - -func (p *TestPolicy) TargetProgrammedGatewaysOnly() bool { - return true -} -func (p *TestPolicy) DeepCopyObject() runtime.Object { - if c := p.DeepCopy(); c != nil { - return c - } - return nil -} - -func (p *TestPolicy) DeepCopy() *TestPolicy { - if p == nil { - return nil - } - out := new(TestPolicy) - p.DeepCopyInto(out) - return out -} - -func (p *TestPolicy) DeepCopyInto(out *TestPolicy) { - *out = *p - out.TypeMeta = p.TypeMeta - p.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - p.TargetRef.DeepCopyInto(&out.TargetRef) -} - -type FakePolicyStatus struct { - Conditions []metav1.Condition -} - -func (s *FakePolicyStatus) GetConditions() []metav1.Condition { - return s.Conditions -} - -func TestPolicyByCreationTimestamp(t *testing.T) { - testCases := []struct { - name string - policies []Policy - sortedPolicies []Policy - }{ - { - name: "nil input", - policies: nil, - sortedPolicies: nil, - }, - { - name: "empty slices", - policies: make([]Policy, 0), - sortedPolicies: make([]Policy, 0), - }, - { - name: "by creation date", - policies: []Policy{ - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("bbb", time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("aaa", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - }, - sortedPolicies: []Policy{ - createTestPolicy("aaa", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("bbb", time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC)), - }, - }, - { - name: "by name when creation date are equal", - policies: []Policy{ - createTestPolicy("ccc", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("bbb", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("aaa", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - }, - sortedPolicies: []Policy{ - createTestPolicy("aaa", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("bbb", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - createTestPolicy("ccc", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC)), - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - sort.Sort(PolicyByCreationTimestamp(tc.policies)) - if !reflect.DeepEqual(tc.policies, tc.sortedPolicies) { - subT.Errorf("expected=%v; got=%v", tc.sortedPolicies, tc.policies) - } - }) - } -} - -func TestPolicyByTargetRef(t *testing.T) { - testCases := []struct { - name string - policies []Policy - sortedPolicies []Policy - }{ - { - name: "nil input", - policies: nil, - sortedPolicies: nil, - }, - { - name: "empty slices", - policies: make([]Policy, 0), - sortedPolicies: make([]Policy, 0), - }, - { - name: "by kind, and creation date", - policies: []Policy{ - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("bbb", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute")), - createTestPolicy("aaa", time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("ddd", time.Date(2005, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service")), - }, - sortedPolicies: []Policy{ - createTestPolicy("aaa", time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("bbb", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute")), - createTestPolicy("ddd", time.Date(2005, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service")), - }, - }, - { - name: "by kind, and then name when creation date equal", - policies: []Policy{ - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("bbb", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute")), - createTestPolicy("aaa", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("ddd", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service")), - }, - sortedPolicies: []Policy{ - createTestPolicy("aaa", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway")), - createTestPolicy("bbb", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute")), - createTestPolicy("ddd", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service")), - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - sort.Sort(PolicyByTargetRefKindAndCreationTimeStamp(tc.policies)) - if !reflect.DeepEqual(tc.policies, tc.sortedPolicies) { - subT.Errorf("expected=%v; got=%v", tc.sortedPolicies, tc.policies) - } - }) - } -} - -func TestPolicyByTargetRefAndStatus(t *testing.T) { - testCases := []struct { - name string - policies []Policy - sortedPolicies []Policy - }{ - { - name: "nil input", - policies: nil, - sortedPolicies: nil, - }, - { - name: "empty slices", - policies: make([]Policy, 0), - sortedPolicies: make([]Policy, 0), - }, - { - name: "by kind, accepted status, and creation date", - policies: []Policy{ - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("bbb", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("aaa", time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("ddd", time.Date(2005, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("fff", time.Date(2003, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("eee", time.Date(2008, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - }, - sortedPolicies: []Policy{ - createTestPolicy("aaa", time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("fff", time.Date(2003, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("eee", time.Date(2008, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("bbb", time.Date(2000, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("ddd", time.Date(2005, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service"), withAcceptedStatus(metav1.ConditionTrue)), - }, - }, - { - name: "by kind, accepted status, creation date and then name when creation date equal", - policies: []Policy{ - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("bbb", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("aaa", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("ddd", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("eee", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("fff", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("ggg", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionFalse)), - }, - sortedPolicies: []Policy{ - createTestPolicy("aaa", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("ccc", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Gateway"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("eee", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("fff", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionTrue)), - createTestPolicy("bbb", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("ggg", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("HTTPRoute"), withAcceptedStatus(metav1.ConditionFalse)), - createTestPolicy("ddd", time.Date(2020, time.November, 10, 23, 0, 0, 0, time.UTC), withTargetRefKind("Service"), withAcceptedStatus(metav1.ConditionTrue)), - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - sort.Sort(PolicyByTargetRefKindAndAcceptedStatus(tc.policies)) - if !reflect.DeepEqual(tc.policies, tc.sortedPolicies) { - subT.Errorf("expected=%v; got=%v; diff=%v", tc.sortedPolicies, tc.policies, cmp.Diff(tc.policies, tc.sortedPolicies)) - } - }) - } -} - -func createTestPolicy(name string, creationTime time.Time, mutateFn ...func(p *TestPolicy)) *TestPolicy { - p := &TestPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "testnamespace", - Name: name, - CreationTimestamp: metav1.Time{Time: creationTime}, - }, - } - for _, fn := range mutateFn { - fn(p) - } - - return p -} - -func withTargetRefKind(targetRefKind string) func(p *TestPolicy) { - return func(p *TestPolicy) { - p.TargetRef = gatewayapiv1alpha2.LocalPolicyTargetReference{Kind: gatewayapiv1.Kind(targetRefKind)} - } -} - -func withAcceptedStatus(status metav1.ConditionStatus) func(p *TestPolicy) { - return func(p *TestPolicy) { - meta.SetStatusCondition(&p.Status.Conditions, metav1.Condition{Type: string(gatewayapiv1alpha2.PolicyConditionAccepted), Status: status, LastTransitionTime: metav1.Time{Time: time.Date(2010, time.November, 10, 23, 0, 0, 0, time.UTC)}}) - } -} diff --git a/pkg/library/kuadrant/gateway_wrapper.go b/pkg/library/kuadrant/gateway_wrapper.go deleted file mode 100644 index e4e55b9d1..000000000 --- a/pkg/library/kuadrant/gateway_wrapper.go +++ /dev/null @@ -1,150 +0,0 @@ -package kuadrant - -import ( - "encoding/json" - "slices" - - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -// GatewayWrapper wraps a Gateway API Gateway adding methods and configs to manage policy references in annotations -type GatewayWrapper struct { - *gatewayapiv1.Gateway - Referrer -} - -func (g GatewayWrapper) Key() client.ObjectKey { - if g.Gateway == nil { - return client.ObjectKey{} - } - return client.ObjectKeyFromObject(g.Gateway) -} - -func (g GatewayWrapper) PolicyRefs() []client.ObjectKey { - if g.Gateway == nil { - return make([]client.ObjectKey, 0) - } - - gwAnnotations := utils.ReadAnnotationsFromObject(g) - - val, ok := gwAnnotations[g.BackReferenceAnnotationName()] - if !ok { - return make([]client.ObjectKey, 0) - } - - refs := BackReferencesFromObject(g.Gateway, g.BackReferenceAnnotationName()) - - err := json.Unmarshal([]byte(val), &refs) - if err != nil { - return make([]client.ObjectKey, 0) - } - - return refs -} - -func (g GatewayWrapper) ContainsPolicy(policyKey client.ObjectKey) bool { - if g.Gateway == nil { - return false - } - refs := BackReferencesFromObject(g.Gateway, g.BackReferenceAnnotationName()) - return slices.Contains(refs, policyKey) -} - -// AddPolicy tries to add a policy to the existing ref list. -// Returns true if policy was added, false otherwise -func (g GatewayWrapper) AddPolicy(policyKey client.ObjectKey) bool { - if g.Gateway == nil { - return false - } - - // annotation exists and contains a back reference to the policy → nothing to do - if g.ContainsPolicy(policyKey) { - return false - } - - gwAnnotations := utils.ReadAnnotationsFromObject(g) - _, annotationFound := gwAnnotations[g.BackReferenceAnnotationName()] - - // annotation does not exist → create it - if !annotationFound { - refs := []client.ObjectKey{policyKey} - serialized, err := json.Marshal(refs) - if err != nil { - return false - } - gwAnnotations[g.BackReferenceAnnotationName()] = string(serialized) - g.SetAnnotations(gwAnnotations) - return true - } - - // annotation exists and does not contain a back reference to the policy → add the policy to it - refs := append(BackReferencesFromObject(g.Gateway, g.BackReferenceAnnotationName()), policyKey) - serialized, err := json.Marshal(refs) - if err != nil { - return false - } - gwAnnotations[g.BackReferenceAnnotationName()] = string(serialized) - g.SetAnnotations(gwAnnotations) - return true -} - -// DeletePolicy tries to delete a policy from the existing ref list. -// Returns true if the policy was deleted, false otherwise -func (g GatewayWrapper) DeletePolicy(policyKey client.ObjectKey) bool { - if g.Gateway == nil { - return false - } - - gwAnnotations := utils.ReadAnnotationsFromObject(g) - - // annotation does not exist → nothing to do - refsAsStr, annotationFound := gwAnnotations[g.BackReferenceAnnotationName()] - if !annotationFound { - return false - } - - var refs []client.ObjectKey - err := json.Unmarshal([]byte(refsAsStr), &refs) - if err != nil { - return false - } - - // annotation exists and contains a back reference to the policy → remove the policy from it - if idx := slices.Index(refs, policyKey); idx >= 0 { - refs = append(refs[:idx], refs[idx+1:]...) - serialized, err := json.Marshal(refs) - if err != nil { - return false - } - gwAnnotations[g.BackReferenceAnnotationName()] = string(serialized) - g.SetAnnotations(gwAnnotations) - return true - } - - // annotation exists and does not contain a back reference the policy → nothing to do - return false -} - -// Hostnames builds a list of hostnames from the listeners. -func (g GatewayWrapper) Hostnames() []gatewayapiv1.Hostname { - return kuadrantgatewayapi.GatewayHostnames(g.Gateway) -} - -// GatewayWrapperList is a list of GatewayWrappers that implements sort.Interface -type GatewayWrapperList []GatewayWrapper - -func (g GatewayWrapperList) Len() int { - return len(g) -} - -func (g GatewayWrapperList) Less(i, j int) bool { - return g[i].CreationTimestamp.Before(&g[j].CreationTimestamp) -} - -func (g GatewayWrapperList) Swap(i, j int) { - g[i], g[j] = g[j], g[i] -} diff --git a/pkg/library/kuadrant/gateway_wrapper_test.go b/pkg/library/kuadrant/gateway_wrapper_test.go deleted file mode 100644 index da90afd5a..000000000 --- a/pkg/library/kuadrant/gateway_wrapper_test.go +++ /dev/null @@ -1,175 +0,0 @@ -//go:build unit - -package kuadrant - -import ( - "slices" - "testing" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - k8stypes "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -func TestGatewayWrapperKey(t *testing.T) { - gw := GatewayWrapper{ - Gateway: &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - }, - Referrer: &PolicyKindStub{}, - } - if gw.Key().Namespace != "gw-ns" || gw.Key().Name != "gw-1" { - t.Fail() - } -} - -func TestGatewayWrapperPolicyRefs(t *testing.T) { - gw := GatewayWrapper{ - Gateway: &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - }, - Referrer: &PolicyKindStub{}, - } - refs := utils.Map(gw.PolicyRefs(), func(ref k8stypes.NamespacedName) string { return ref.String() }) - if !slices.Contains(refs, "app-ns/policy-1") { - t.Error("GatewayWrapper.PolicyRefs() should contain app-ns/policy-1") - } - if !slices.Contains(refs, "app-ns/policy-2") { - t.Error("GatewayWrapper.PolicyRefs() should contain app-ns/policy-2") - } - if len(refs) != 2 { - t.Fail() - } -} - -func TestGatewayWrapperContainsPolicy(t *testing.T) { - gw := GatewayWrapper{ - Gateway: &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - }, - Referrer: &PolicyKindStub{}, - } - if !gw.ContainsPolicy(client.ObjectKey{Namespace: "app-ns", Name: "policy-1"}) { - t.Error("GatewayWrapper.ContainsPolicy() should contain app-ns/policy-1") - } - if !gw.ContainsPolicy(client.ObjectKey{Namespace: "app-ns", Name: "policy-2"}) { - t.Error("GatewayWrapper.ContainsPolicy() should contain app-ns/policy-1") - } - if gw.ContainsPolicy(client.ObjectKey{Namespace: "app-ns", Name: "policy-3"}) { - t.Error("GatewayWrapper.ContainsPolicy() should not contain app-ns/policy-1") - } -} - -func TestGatewayWrapperAddPolicy(t *testing.T) { - gateway := gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - } - gw := GatewayWrapper{ - Gateway: &gateway, - Referrer: &PolicyKindStub{}, - } - if gw.AddPolicy(client.ObjectKey{Namespace: "app-ns", Name: "policy-1"}) { - t.Error("GatewayWrapper.AddPolicy() expected to return false") - } - if !gw.AddPolicy(client.ObjectKey{Namespace: "app-ns", Name: "policy-3"}) { - t.Error("GatewayWrapper.AddPolicy() expected to return true") - } - if gw.Annotations["kuadrant.io/testpolicies"] != `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"},{"Namespace":"app-ns","Name":"policy-3"}]` { - t.Error("GatewayWrapper.AddPolicy() expected to have added policy ref to the annotations") - } -} - -func TestGatewayDeletePolicy(t *testing.T) { - gateway := gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - } - gw := GatewayWrapper{ - Gateway: &gateway, - Referrer: &PolicyKindStub{}, - } - if !gw.DeletePolicy(client.ObjectKey{Namespace: "app-ns", Name: "policy-1"}) { - t.Error("GatewayWrapper.DeletePolicy() expected to return true") - } - if gw.DeletePolicy(client.ObjectKey{Namespace: "app-ns", Name: "policy-3"}) { - t.Error("GatewayWrapper.DeletePolicy() expected to return false") - } - if gw.Annotations["kuadrant.io/testpolicies"] != `[{"Namespace":"app-ns","Name":"policy-2"}]` { - t.Error("GatewayWrapper.DeletePolicy() expected to have deleted policy ref from the annotations") - } -} - -func TestGatewayHostnames(t *testing.T) { - hostname := gatewayapiv1.Hostname("toystore.com") - gateway := gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/ratelimitpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - Spec: gatewayapiv1.GatewaySpec{ - Listeners: []gatewayapiv1.Listener{ - { - Name: "my-listener", - Hostname: &hostname, - }, - }, - }, - } - gw := GatewayWrapper{ - Gateway: &gateway, - Referrer: &PolicyKindStub{}, - } - hostnames := gw.Hostnames() - if !slices.Contains(hostnames, "toystore.com") { - t.Error("GatewayWrapper.Hostnames() expected to contain 'toystore.com'") - } - if len(hostnames) != 1 { - t.Fail() - } -} - -func TestBackReferencesFromGatewayWrapper(t *testing.T) { - gw := GatewayWrapper{ - Gateway: &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - }, - Referrer: &PolicyKindStub{}, - } - refs := utils.Map(BackReferencesFromObject(gw.Gateway, gw.BackReferenceAnnotationName()), func(ref client.ObjectKey) string { return ref.String() }) - if !slices.Contains(refs, "app-ns/policy-1") { - t.Error("GatewayWrapper.PolicyRefs() should contain app-ns/policy-1") - } - if !slices.Contains(refs, "app-ns/policy-2") { - t.Error("GatewayWrapper.PolicyRefs() should contain app-ns/policy-2") - } - if len(refs) != 2 { - t.Fail() - } -} diff --git a/pkg/library/kuadrant/kuadrant.go b/pkg/library/kuadrant/kuadrant.go deleted file mode 100644 index a607f5009..000000000 --- a/pkg/library/kuadrant/kuadrant.go +++ /dev/null @@ -1,338 +0,0 @@ -package kuadrant - -import ( - "context" - "fmt" - "reflect" - "strings" - - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "k8s.io/utils/ptr" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -const ( - KuadrantNamespaceAnnotation = "kuadrant.io/namespace" - TopologyLabel = "kuadrant.io/topology" - ControllerName = "kuadrant.io/policy-controller" -) - -type Policy interface { - kuadrantgatewayapi.Policy - GetWrappedNamespace() gatewayapiv1.Namespace - GetRulesHostnames() []string - Kind() string -} - -type PolicyList interface { - GetItems() []Policy -} - -type HTTPRouteRule struct { - Paths []string - Methods []string - Hosts []string -} - -func IsKuadrantManaged(obj client.Object) bool { - _, isSet := obj.GetAnnotations()[KuadrantNamespaceAnnotation] - return isSet -} - -func GetKuadrantNamespaceFromPolicyTargetRef(ctx context.Context, cli client.Client, policy Policy) (string, error) { - targetRef := policy.GetTargetRef() - gwNamespacedName := types.NamespacedName{Namespace: policy.GetNamespace(), Name: string(targetRef.Name)} - if kuadrantgatewayapi.IsTargetRefHTTPRoute(targetRef) { - route := &gatewayapiv1.HTTPRoute{} - if err := cli.Get( - ctx, - types.NamespacedName{Namespace: policy.GetNamespace(), Name: string(targetRef.Name)}, - route, - ); err != nil { - return "", err - } - // First should be OK considering there's 1 Kuadrant instance per cluster and all are tagged - parentRef := route.Spec.ParentRefs[0] - gwNamespacedName = types.NamespacedName{Namespace: string(ptr.Deref(parentRef.Namespace, gatewayapiv1.Namespace(route.Namespace))), Name: string(parentRef.Name)} - } - gw := &gatewayapiv1.Gateway{} - if err := cli.Get(ctx, gwNamespacedName, gw); err != nil { - return "", err - } - return GetKuadrantNamespace(gw) -} - -func GetKuadrantNamespaceFromPolicy(p Policy) (string, bool) { - if kuadrantNamespace, isSet := p.GetAnnotations()[KuadrantNamespaceAnnotation]; isSet { - return kuadrantNamespace, true - } - return "", false -} - -func GetKuadrantNamespace(obj client.Object) (string, error) { - if !IsKuadrantManaged(obj) { - return "", errors.NewInternalError(fmt.Errorf("object %T is not Kuadrant managed", obj)) - } - return obj.GetAnnotations()[KuadrantNamespaceAnnotation], nil -} - -func AnnotateObject(obj client.Object, namespace string) { - annotations := obj.GetAnnotations() - if len(annotations) == 0 { - obj.SetAnnotations( - map[string]string{ - KuadrantNamespaceAnnotation: namespace, - }, - ) - } else { - annotations[KuadrantNamespaceAnnotation] = namespace - obj.SetAnnotations(annotations) - } -} - -// RulesFromHTTPRoute computes a list of rules from the HTTPRoute object -func RulesFromHTTPRoute(route *gatewayapiv1.HTTPRoute) []HTTPRouteRule { - if route == nil { - return nil - } - - var rules []HTTPRouteRule - - for routeRuleIdx := range route.Spec.Rules { - for matchIdx := range route.Spec.Rules[routeRuleIdx].Matches { - match := &route.Spec.Rules[routeRuleIdx].Matches[matchIdx] - - rule := HTTPRouteRule{ - Hosts: RouteHostnames(route), - Methods: RouteHTTPMethodToRuleMethod(match.Method), - Paths: routePathMatchToRulePath(match.Path), - } - - if len(rule.Methods) != 0 || len(rule.Paths) != 0 { - // Only append rule when there are methods or path rules - // a valid rule must include HTTPRoute hostnames as well - rules = append(rules, rule) - } - } - } - - // If no rules compiled from the route, at least one rule for the hosts - if len(rules) == 0 { - rules = []HTTPRouteRule{{Hosts: RouteHostnames(route)}} - } - - return rules -} - -// routePathMatchToRulePath converts HTTPRoute pathmatch rule to kuadrant's rule path -func routePathMatchToRulePath(pathMatch *gatewayapiv1.HTTPPathMatch) []string { - if pathMatch == nil { - return nil - } - - // Only support for Exact and Prefix match - if pathMatch.Type != nil && *pathMatch.Type != gatewayapiv1.PathMatchPathPrefix && - *pathMatch.Type != gatewayapiv1.PathMatchExact { - return nil - } - - // Exact path match - suffix := "" - if pathMatch.Type == nil || *pathMatch.Type == gatewayapiv1.PathMatchPathPrefix { - // defaults to path prefix match type - suffix = "*" - } - - val := "/" - if pathMatch.Value != nil { - val = *pathMatch.Value - } - - return []string{val + suffix} -} - -// ValidateHierarchicalRules returns error if the policy rules hostnames fail to match the target network hosts -func ValidateHierarchicalRules(policy Policy, targetNetworkObject client.Object) error { - targetHostnames := kuadrantgatewayapi.TargetHostnames(targetNetworkObject) - - if valid, invalidHost := utils.ValidSubdomains(targetHostnames, policy.GetRulesHostnames()); !valid { - return fmt.Errorf( - "rule host (%s) does not follow any hierarchical constraints, "+ - "for the %T to be validated, it must match with at least one of the target network hostnames %+q", - invalidHost, - policy, - targetHostnames, - ) - } - - return nil -} - -type HTTPRouteRuleSelector struct { - *gatewayapiv1.HTTPRouteMatch -} - -func (s *HTTPRouteRuleSelector) Selects(rule gatewayapiv1.HTTPRouteRule) bool { - if s.HTTPRouteMatch == nil { - return true - } - - _, found := utils.Find(rule.Matches, func(ruleMatch gatewayapiv1.HTTPRouteMatch) bool { - // path - if s.Path != nil && !reflect.DeepEqual(s.Path, ruleMatch.Path) { - return false - } - - // method - if s.Method != nil && !reflect.DeepEqual(s.Method, ruleMatch.Method) { - return false - } - - // headers - for _, header := range s.Headers { - if _, found := utils.Find(ruleMatch.Headers, func(otherHeader gatewayapiv1.HTTPHeaderMatch) bool { - return reflect.DeepEqual(header, otherHeader) - }); !found { - return false - } - } - - // query params - for _, param := range s.QueryParams { - if _, found := utils.Find(ruleMatch.QueryParams, func(otherParam gatewayapiv1.HTTPQueryParamMatch) bool { - return reflect.DeepEqual(param, otherParam) - }); !found { - return false - } - } - - return true - }) - - return found -} - -// HostnamesFromHTTPRoute returns an array of all hostnames specified in a HTTPRoute or inherited from its parent Gateways -func HostnamesFromHTTPRoute(ctx context.Context, route *gatewayapiv1.HTTPRoute, cli client.Client) ([]string, error) { - if len(route.Spec.Hostnames) > 0 { - return RouteHostnames(route), nil - } - - hosts := []string{} - - for _, ref := range route.Spec.ParentRefs { - if (ref.Kind != nil && *ref.Kind != "Gateway") || (ref.Group != nil && *ref.Group != gatewayapiv1.GroupName) { - continue - } - gw := &gatewayapiv1.Gateway{} - ns := route.Namespace - if ref.Namespace != nil { - ns = string(*ref.Namespace) - } - if err := cli.Get(ctx, types.NamespacedName{Namespace: ns, Name: string(ref.Name)}, gw); err != nil { - return nil, err - } - gwHostanmes := utils.HostnamesToStrings(kuadrantgatewayapi.GatewayHostnames(gw)) - hosts = append(hosts, gwHostanmes...) - } - - return hosts, nil -} - -func RouteHostnames(route *gatewayapiv1.HTTPRoute) []string { - if route == nil { - return nil - } - - if len(route.Spec.Hostnames) == 0 { - return []string{"*"} - } - - hosts := make([]string, 0, len(route.Spec.Hostnames)) - - for _, hostname := range route.Spec.Hostnames { - hosts = append(hosts, string(hostname)) - } - - return hosts -} - -func RouteHTTPMethodToRuleMethod(httpMethod *gatewayapiv1.HTTPMethod) []string { - if httpMethod == nil { - return nil - } - - return []string{string(*httpMethod)} -} - -// HTTPRouteRuleToString prints the matches of a HTTPRouteRule as string -func HTTPRouteRuleToString(rule gatewayapiv1.HTTPRouteRule) string { - matches := utils.Map(rule.Matches, HTTPRouteMatchToString) - return fmt.Sprintf("{matches:[%s]}", strings.Join(matches, ",")) -} - -func HTTPRouteMatchToString(match gatewayapiv1.HTTPRouteMatch) string { - var patterns []string - if method := match.Method; method != nil { - patterns = append(patterns, fmt.Sprintf("method:%v", HTTPMethodToString(method))) - } - if path := match.Path; path != nil { - patterns = append(patterns, fmt.Sprintf("path:%s", HTTPPathMatchToString(path))) - } - if len(match.QueryParams) > 0 { - queryParams := utils.Map(match.QueryParams, HTTPQueryParamMatchToString) - patterns = append(patterns, fmt.Sprintf("queryParams:[%s]", strings.Join(queryParams, ","))) - } - if len(match.Headers) > 0 { - headers := utils.Map(match.Headers, HTTPHeaderMatchToString) - patterns = append(patterns, fmt.Sprintf("headers:[%s]", strings.Join(headers, ","))) - } - return fmt.Sprintf("{%s}", strings.Join(patterns, ",")) -} - -func HTTPPathMatchToString(path *gatewayapiv1.HTTPPathMatch) string { - if path == nil { - return "*" - } - if path.Type != nil { - switch *path.Type { - case gatewayapiv1.PathMatchExact: - return *path.Value - case gatewayapiv1.PathMatchRegularExpression: - return fmt.Sprintf("~/%s/", *path.Value) - } - } - return fmt.Sprintf("%s*", *path.Value) -} - -func HTTPHeaderMatchToString(header gatewayapiv1.HTTPHeaderMatch) string { - if header.Type != nil { - switch *header.Type { - case gatewayapiv1.HeaderMatchRegularExpression: - return fmt.Sprintf("{%s:~/%s/}", header.Name, header.Value) - } - } - return fmt.Sprintf("{%s:%s}", header.Name, header.Value) -} - -func HTTPQueryParamMatchToString(queryParam gatewayapiv1.HTTPQueryParamMatch) string { - if queryParam.Type != nil { - switch *queryParam.Type { - case gatewayapiv1.QueryParamMatchRegularExpression: - return fmt.Sprintf("{%s:~/%s/}", queryParam.Name, queryParam.Value) - } - } - return fmt.Sprintf("{%s:%s}", queryParam.Name, queryParam.Value) -} - -func HTTPMethodToString(method *gatewayapiv1.HTTPMethod) string { - if method == nil { - return "*" - } - return string(*method) -} diff --git a/pkg/library/kuadrant/kuadrant_test.go b/pkg/library/kuadrant/kuadrant_test.go deleted file mode 100644 index 2cea354b2..000000000 --- a/pkg/library/kuadrant/kuadrant_test.go +++ /dev/null @@ -1,877 +0,0 @@ -//go:build unit - -package kuadrant - -import ( - "context" - "fmt" - "reflect" - "testing" - - "gotest.tools/assert" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/utils/ptr" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" -) - -func TestRulesFromHTTPRoute(t *testing.T) { - var ( - getMethod = "GET" - catsPath = "/cats" - dogsPath = "/dogs" - rabbitsPath = "/rabbits" - getHTTPMethod gatewayapiv1.HTTPMethod = "GET" - postHTTPMethod gatewayapiv1.HTTPMethod = "POST" - pathPrefix = gatewayapiv1.PathMatchPathPrefix - pathExact = gatewayapiv1.PathMatchExact - catsPrefixPatchMatch = gatewayapiv1.HTTPPathMatch{ - Type: &pathPrefix, - Value: &catsPath, - } - dogsExactPatchMatch = gatewayapiv1.HTTPPathMatch{ - Type: &pathExact, - Value: &dogsPath, - } - rabbitsPrefixPatchMatch = gatewayapiv1.HTTPPathMatch{ - Value: &rabbitsPath, - } - ) - - testCases := []struct { - name string - route *gatewayapiv1.HTTPRoute - expected []HTTPRouteRule - }{ - { - "nil", - nil, - nil, - }, - { - "nil rules", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Rules: nil, - Hostnames: []gatewayapiv1.Hostname{"*.com"}, - }, - }, - []HTTPRouteRule{{Hosts: []string{"*.com"}}}, - }, - { - "empty rules", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Rules: make([]gatewayapiv1.HTTPRouteRule, 0), - Hostnames: []gatewayapiv1.Hostname{"*.com"}, - }, - }, - []HTTPRouteRule{{Hosts: []string{"*.com"}}}, - }, - { - "with method", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Rules: []gatewayapiv1.HTTPRouteRule{ - { - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Method: &getHTTPMethod, - }, - }, - }, - }, - }, - }, - []HTTPRouteRule{{ - Hosts: []string{"*"}, - Methods: []string{getMethod}, - }}, - }, - { - "with path", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Rules: []gatewayapiv1.HTTPRouteRule{ - { - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Path: &catsPrefixPatchMatch, - }, - }, - }, - }, - }, - }, - []HTTPRouteRule{{ - Hosts: []string{"*"}, - Paths: []string{"/cats*"}, - }}, - }, - { - "with path and default path match type", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Rules: []gatewayapiv1.HTTPRouteRule{ - { - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Path: &rabbitsPrefixPatchMatch, - }, - }, - }, - }, - }, - }, - []HTTPRouteRule{{ - Hosts: []string{"*"}, - Paths: []string{"/rabbits*"}, - }}, - }, - { - "no paths or methods", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Rules: []gatewayapiv1.HTTPRouteRule{ - { - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - }, - }, - Hostnames: []gatewayapiv1.Hostname{"*.com"}, - }, - }, - []HTTPRouteRule{{Hosts: []string{"*.com"}}}, - }, - { - "basic", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Hostnames: []gatewayapiv1.Hostname{"*.com"}, - Rules: []gatewayapiv1.HTTPRouteRule{ - { - // GET /cats* - // POST /dogs - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Path: &catsPrefixPatchMatch, - Method: &getHTTPMethod, - }, - { - Path: &dogsExactPatchMatch, - Method: &postHTTPMethod, - }, - }, - }, - }, - }, - }, - []HTTPRouteRule{ - { - Hosts: []string{"*.com"}, - Methods: []string{"GET"}, - Paths: []string{"/cats*"}, - }, { - Hosts: []string{"*.com"}, - Methods: []string{"POST"}, - Paths: []string{"/dogs"}, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := RulesFromHTTPRoute(tc.route) - if !reflect.DeepEqual(res, tc.expected) { - subT.Errorf("result (%+v) does not match expected (%+v)", res, tc.expected) - } - }) - } -} - -func TestRouteHostnames(t *testing.T) { - testCases := []struct { - name string - route *gatewayapiv1.HTTPRoute - expected []string - }{ - { - "nil", - nil, - nil, - }, - { - "nil hostname", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Hostnames: nil, - }, - }, - []string{"*"}, - }, - { - "basic", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Hostnames: []gatewayapiv1.Hostname{"*.com", "example.net", "test.example.net"}, - }, - }, - []string{"*.com", "example.net", "test.example.net"}, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := RouteHostnames(tc.route) - if !reflect.DeepEqual(res, tc.expected) { - subT.Errorf("result (%v) does not match expected (%v)", res, tc.expected) - } - }) - } -} - -func TestHTTPRouteRuleSelectorSelects(t *testing.T) { - testCases := []struct { - name string - selector HTTPRouteRuleSelector - rule gatewayapiv1.HTTPRouteRule - expected bool - }{ - { - name: "when the httproutrule contains the exact match then return true", - selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - rule: gatewayapiv1.HTTPRouteRule{ - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "when the httproutrule contains the exact match and more then return true", - selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - }, - }, - rule: gatewayapiv1.HTTPRouteRule{ - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "when the httproutrule contains all the matching headers and more then return true", - selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - rule: gatewayapiv1.HTTPRouteRule{ - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchRegularExpression}[0], - Name: "someotherheader", - Value: "someregex.*", - }, - }, - }, - }, - }, - expected: true, - }, - { - name: "when the httproutrule contains an inexact match then return false", - selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - rule: gatewayapiv1.HTTPRouteRule{ - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPost}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - }, - expected: false, - }, - { - name: "when the httproutrule is empty then return false", - rule: gatewayapiv1.HTTPRouteRule{}, - selector: HTTPRouteRuleSelector{ - HTTPRouteMatch: &gatewayapiv1.HTTPRouteMatch{ - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - }, - }, - expected: false, - }, - { - name: "when the selector is empty then return true", - selector: HTTPRouteRuleSelector{}, - rule: gatewayapiv1.HTTPRouteRule{ - Matches: []gatewayapiv1.HTTPRouteMatch{ - { - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - Headers: []gatewayapiv1.HTTPHeaderMatch{ - { - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "someheader", - Value: "somevalue", - }, - }, - }, - }, - }, - expected: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if r := tc.selector.Selects(tc.rule); r != tc.expected { - expectedStr := "" - resultStr := "not" - if !tc.expected { - expectedStr = "not" - resultStr = "" - } - t.Error("expected selector", HTTPRouteMatchToString(*tc.selector.HTTPRouteMatch), expectedStr, "to select rule", HTTPRouteRuleToString(tc.rule), "but it does", resultStr) - } - }) - } -} - -func TestHTTPPathMatchToString(t *testing.T) { - testCases := []struct { - name string - input *gatewayapiv1.HTTPPathMatch - expected string - }{ - { - name: "exact path match", - input: &[]gatewayapiv1.HTTPPathMatch{ - { - Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchExact}[0], - Value: &[]string{"/foo"}[0], - }, - }[0], - expected: "/foo", - }, - { - name: "regex path match", - input: &[]gatewayapiv1.HTTPPathMatch{ - { - Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchRegularExpression}[0], - Value: &[]string{"^\\/foo.*"}[0], - }, - }[0], - expected: "~/^\\/foo.*/", - }, - { - name: "path prefix match", - input: &[]gatewayapiv1.HTTPPathMatch{ - { - Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchPathPrefix}[0], - Value: &[]string{"/foo"}[0], - }, - }[0], - expected: "/foo*", - }, - { - name: "path match with default type", - input: &[]gatewayapiv1.HTTPPathMatch{ - { - Value: &[]string{"/foo"}[0], - }, - }[0], - expected: "/foo*", - }, - { - name: "nil path match", - input: nil, - expected: "*", - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if r := HTTPPathMatchToString(tc.input); r != tc.expected { - t.Errorf("expected: %s, got: %s", tc.expected, r) - } - }) - } -} - -func TestHTTPHeaderMatchToString(t *testing.T) { - testCases := []struct { - name string - input gatewayapiv1.HTTPHeaderMatch - expected string - }{ - { - name: "exact header match", - input: gatewayapiv1.HTTPHeaderMatch{ - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchExact}[0], - Name: "some-header", - Value: "foo", - }, - expected: "{some-header:foo}", - }, - { - name: "regex header match", - input: gatewayapiv1.HTTPHeaderMatch{ - Type: &[]gatewayapiv1.HeaderMatchType{gatewayapiv1.HeaderMatchRegularExpression}[0], - Name: "some-header", - Value: "^foo.*", - }, - expected: "{some-header:~/^foo.*/}", - }, - { - name: "header match with default type", - input: gatewayapiv1.HTTPHeaderMatch{ - Name: "some-header", - Value: "foo", - }, - expected: "{some-header:foo}", - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if r := HTTPHeaderMatchToString(tc.input); r != tc.expected { - t.Errorf("expected: %s, got: %s", tc.expected, r) - } - }) - } -} - -func TestHTTPRouteMatchToString(t *testing.T) { - match := gatewayapiv1.HTTPRouteMatch{ - Path: &gatewayapiv1.HTTPPathMatch{ - Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchExact}[0], - Value: &[]string{"/foo"}[0], - }, - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - QueryParams: []gatewayapiv1.HTTPQueryParamMatch{ - { - Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchRegularExpression}[0], - Name: "page", - Value: "\\d+", - }, - }, - } - - expected := "{method:GET,path:/foo,queryParams:[{page:~/\\d+/}]}" - - if r := HTTPRouteMatchToString(match); r != expected { - t.Errorf("expected: %s, got: %s", expected, r) - } - - match.Headers = []gatewayapiv1.HTTPHeaderMatch{ - { - Name: "x-foo", - Value: "bar", - }, - } - - expected = "{method:GET,path:/foo,queryParams:[{page:~/\\d+/}],headers:[{x-foo:bar}]}" - - if r := HTTPRouteMatchToString(match); r != expected { - t.Errorf("expected: %s, got: %s", expected, r) - } -} - -func TestHTTPRouteRuleToString(t *testing.T) { - rule := gatewayapiv1.HTTPRouteRule{} - - expected := "{matches:[]}" - - if r := HTTPRouteRuleToString(rule); r != expected { - t.Errorf("expected: %s, got: %s", expected, r) - } - - rule.Matches = []gatewayapiv1.HTTPRouteMatch{ - { - Path: &gatewayapiv1.HTTPPathMatch{ - Type: &[]gatewayapiv1.PathMatchType{gatewayapiv1.PathMatchExact}[0], - Value: &[]string{"/foo"}[0], - }, - Method: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - QueryParams: []gatewayapiv1.HTTPQueryParamMatch{ - { - Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchRegularExpression}[0], - Name: "page", - Value: "\\d+", - }, - }, - }, - } - - expected = "{matches:[{method:GET,path:/foo,queryParams:[{page:~/\\d+/}]}]}" - - if r := HTTPRouteRuleToString(rule); r != expected { - t.Errorf("expected: %s, got: %s", expected, r) - } -} - -func TestHTTPMethodToString(t *testing.T) { - testCases := []struct { - input *gatewayapiv1.HTTPMethod - expected string - }{ - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodGet}[0], - expected: "GET", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodHead}[0], - expected: "HEAD", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPost}[0], - expected: "POST", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPut}[0], - expected: "PUT", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodPatch}[0], - expected: "PATCH", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodDelete}[0], - expected: "DELETE", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodConnect}[0], - expected: "CONNECT", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodOptions}[0], - expected: "OPTIONS", - }, - { - input: &[]gatewayapiv1.HTTPMethod{gatewayapiv1.HTTPMethodTrace}[0], - expected: "TRACE", - }, - { - input: nil, - expected: "*", - }, - } - for _, tc := range testCases { - if r := HTTPMethodToString(tc.input); r != tc.expected { - t.Errorf("expected: %s, got: %s", tc.expected, r) - } - } -} - -func TestHTTPQueryParamMatchToString(t *testing.T) { - testCases := []struct { - name string - input gatewayapiv1.HTTPQueryParamMatch - expected string - }{ - { - name: "exact query param match", - input: gatewayapiv1.HTTPQueryParamMatch{ - Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchExact}[0], - Name: "some-param", - Value: "foo", - }, - expected: "{some-param:foo}", - }, - { - name: "regex query param match", - input: gatewayapiv1.HTTPQueryParamMatch{ - Type: &[]gatewayapiv1.QueryParamMatchType{gatewayapiv1.QueryParamMatchRegularExpression}[0], - Name: "some-param", - Value: "^foo.*", - }, - expected: "{some-param:~/^foo.*/}", - }, - { - name: "query param match with default type", - input: gatewayapiv1.HTTPQueryParamMatch{ - Name: "some-param", - Value: "foo", - }, - expected: "{some-param:foo}", - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if r := HTTPQueryParamMatchToString(tc.input); r != tc.expected { - t.Errorf("expected: %s, got: %s", tc.expected, r) - } - }) - } -} - -func TestGetKuadrantNamespaceFromPolicyTargetRef(t *testing.T) { - scheme := runtime.NewScheme() - _ = corev1.AddToScheme(scheme) - _ = gatewayapiv1.AddToScheme(scheme) - - testCases := []struct { - name string - k8sClient client.Client - policy *FakePolicy - expected string - expectedErr bool - }{ - { - "retrieve gateway namespace from httproute", - fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( - &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw", - Annotations: map[string]string{"kuadrant.io/namespace": "my-ns"}, - }, - }, - &gatewayapiv1.HTTPRoute{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-httproute", - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "my-gw", - Namespace: ptr.To[gatewayapiv1.Namespace](gatewayapiv1.Namespace("my-ns")), - }, - }, - }, - }, - }, - ).Build(), - &FakePolicy{ - Object: &metav1.PartialObjectMetadata{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-policy", - Namespace: "my-ns", - }, - }, - targetRef: gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "HTTPRoute", - Name: "my-httproute", - }, - }, - "my-ns", - false, - }, - { - "retrieve gateway namespace from httproute implicitly", - fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( - &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw", - Annotations: map[string]string{"kuadrant.io/namespace": "my-ns"}, - }, - }, - &gatewayapiv1.HTTPRoute{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-httproute", - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "my-gw", - }, - }, - }, - }, - }, - ).Build(), - &FakePolicy{ - Object: &metav1.PartialObjectMetadata{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-policy", - Namespace: "my-ns", - }, - }, - targetRef: gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "HTTPRoute", - Name: "my-httproute", - }, - }, - "my-ns", - false, - }, - { - "error retrieving gateway namespace not annotated", - fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( - &gatewayapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-gw", - }, - }, - &gatewayapiv1.HTTPRoute{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "my-ns", - Name: "my-httproute", - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "my-gw", - }, - }, - }, - }, - }, - ).Build(), - &FakePolicy{ - Object: &metav1.PartialObjectMetadata{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-policy", - Namespace: "my-ns", - }, - }, - targetRef: gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "HTTPRoute", - Name: "my-httproute", - }, - }, - "", - true, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res, err := GetKuadrantNamespaceFromPolicyTargetRef(context.TODO(), tc.k8sClient, tc.policy) - if err != nil && !tc.expectedErr { - subT.Errorf("received err (%s) when expected error (%T)", err, tc.expectedErr) - } - if res != tc.expected { - subT.Errorf("result (%s) does not match expected (%s)", res, tc.expected) - } - }) - } -} - -func TestValidateHierarchicalRules(t *testing.T) { - hostname := gatewayapiv1.Hostname("*.example.com") - gateway := &gatewayapiv1.Gateway{ - Spec: gatewayapiv1.GatewaySpec{Listeners: []gatewayapiv1.Listener{ - { - Hostname: &hostname, - }, - }}, - } - httpRoute := &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - Hostnames: []gatewayapiv1.Hostname{hostname}, - }, - } - - policy1 := FakePolicy{Hosts: []string{"this.example.com", "*.example.com"}} - policy2 := FakePolicy{Hosts: []string{"*.z.com"}} - - if err := ValidateHierarchicalRules(&policy1, gateway); err != nil { - t.Fatal(err) - } - - t.Run("gateway - contains host", func(subT *testing.T) { - assert.NilError(subT, ValidateHierarchicalRules(&policy1, gateway)) - }) - - t.Run("gateway error - host has no match", func(subT *testing.T) { - expectedError := fmt.Sprintf("rule host (%s) does not follow any hierarchical constraints, "+ - "for the %T to be validated, it must match with at least one of the target network hostnames %+q", - "*.z.com", - &policy2, - []string{"*.example.com"}, - ) - assert.Error(subT, ValidateHierarchicalRules(&policy2, gateway), expectedError) - }) - - t.Run("gateway - no hosts", func(subT *testing.T) { - assert.NilError(subT, ValidateHierarchicalRules(&policy1, &gatewayapiv1.Gateway{})) - }) - - t.Run("httpRoute - contains host ", func(subT *testing.T) { - assert.NilError(subT, ValidateHierarchicalRules(&policy1, httpRoute)) - }) -} diff --git a/pkg/library/kuadrant/referrer.go b/pkg/library/kuadrant/referrer.go deleted file mode 100644 index 9c658b346..000000000 --- a/pkg/library/kuadrant/referrer.go +++ /dev/null @@ -1,50 +0,0 @@ -package kuadrant - -import ( - "encoding/json" - "fmt" - "strings" - - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -type Referrer interface { - // Kind returns the kind of the referrer object, typically a Kuadrant Policy kind. - Kind() string - // BackReferenceAnnotationName returns the name of the annotation in a target reference object that contains the back references to the referrer objects. - BackReferenceAnnotationName() string - // DirectReferenceAnnotationName return the name of the annotation for direct reference - DirectReferenceAnnotationName() string -} - -// BackReferencesFromObject returns the names of the policies listed in the annotations of a target ref object. -func BackReferencesFromObject(obj client.Object, backrefAnnotation string) []client.ObjectKey { - backRefs, found := utils.ReadAnnotationsFromObject(obj)[backrefAnnotation] - if !found { - return make([]client.ObjectKey, 0) - } - - var refs []client.ObjectKey - - err := json.Unmarshal([]byte(backRefs), &refs) - if err != nil { - return make([]client.ObjectKey, 0) - } - - return refs -} - -func DirectReferencesFromObject(obj client.Object, directAnnotation string) (client.ObjectKey, error) { - annotations := utils.ReadAnnotationsFromObject(obj) - directRefs, found := annotations[directAnnotation] - if !found { - return client.ObjectKey{}, fmt.Errorf("annotation %s not found", directAnnotation) - } - - parts := strings.Split(directRefs, "/") - ref := client.ObjectKey{Namespace: parts[0], Name: parts[1]} - - return ref, nil -} diff --git a/pkg/library/kuadrant/referrer_test.go b/pkg/library/kuadrant/referrer_test.go deleted file mode 100644 index 0c22c0d34..000000000 --- a/pkg/library/kuadrant/referrer_test.go +++ /dev/null @@ -1,38 +0,0 @@ -//go:build unit - -package kuadrant - -import ( - "slices" - "testing" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -func TestBackReferencesFromObject(t *testing.T) { - obj := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - Spec: corev1.ServiceSpec{}, - } - - policyKind := &PolicyKindStub{} - - refs := utils.Map(BackReferencesFromObject(obj, policyKind.BackReferenceAnnotationName()), func(ref client.ObjectKey) string { return ref.String() }) - if !slices.Contains(refs, "app-ns/policy-1") { - t.Error("GatewayWrapper.PolicyRefs() should contain app-ns/policy-1") - } - if !slices.Contains(refs, "app-ns/policy-2") { - t.Error("GatewayWrapper.PolicyRefs() should contain app-ns/policy-2") - } - if len(refs) != 2 { - t.Fail() - } -} diff --git a/pkg/library/kuadrant/test_utils.go b/pkg/library/kuadrant/test_utils.go deleted file mode 100644 index 2b185a541..000000000 --- a/pkg/library/kuadrant/test_utils.go +++ /dev/null @@ -1,86 +0,0 @@ -//go:build unit - -package kuadrant - -import ( - "context" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" -) - -var _ Referrer = &PolicyKindStub{} - -type PolicyKindStub struct{} - -func (tpk *PolicyKindStub) Kind() string { - return "TestPolicy" -} - -func (tpk *PolicyKindStub) BackReferenceAnnotationName() string { - return "kuadrant.io/testpolicies" -} - -func (tpk *PolicyKindStub) DirectReferenceAnnotationName() string { - return "kuadrant.io/testpolicy" -} - -const ( - NS = "nsA" -) - -type FakePolicy struct { - client.Object - Hosts []string - targetRef gatewayapiv1alpha2.LocalPolicyTargetReference -} - -func (p *FakePolicy) GetTargetRef() gatewayapiv1alpha2.LocalPolicyTargetReference { - return p.targetRef -} - -func (p *FakePolicy) GetStatus() kuadrantgatewayapi.PolicyStatus { - return &FakePolicyStatus{} -} - -func (p *FakePolicy) GetWrappedNamespace() gatewayapiv1.Namespace { - return gatewayapiv1.Namespace(p.GetNamespace()) -} - -func (p *FakePolicy) GetRulesHostnames() []string { - return p.Hosts -} - -func (p *FakePolicy) Kind() string { - return "FakePolicy" -} - -func (p *FakePolicy) List(ctx context.Context, c client.Client, namespace string) []kuadrantgatewayapi.Policy { - return nil -} - -func (p *FakePolicy) BackReferenceAnnotationName() string { - return "" -} - -func (p *FakePolicy) DirectReferenceAnnotationName() string { - return "" -} - -func (_ *FakePolicy) PolicyClass() kuadrantgatewayapi.PolicyClass { - return kuadrantgatewayapi.DirectPolicy -} - -func (p *FakePolicy) TargetProgrammedGatewaysOnly() bool { - return true -} - -type FakePolicyStatus struct{} - -func (s *FakePolicyStatus) GetConditions() []metav1.Condition { - return nil -} diff --git a/pkg/library/mappers/envoysecuritypolicy_to_kuadrant.go b/pkg/library/mappers/envoysecuritypolicy_to_kuadrant.go deleted file mode 100644 index 8c70642f2..000000000 --- a/pkg/library/mappers/envoysecuritypolicy_to_kuadrant.go +++ /dev/null @@ -1,54 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - egv1alpha1 "github.com/envoyproxy/gateway/api/v1alpha1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -type SecurityPolicyToKuadrantEventMapper struct { - opts MapperOptions -} - -func NewSecurityPolicyToKuadrantEventMapper(o ...MapperOption) *SecurityPolicyToKuadrantEventMapper { - return &SecurityPolicyToKuadrantEventMapper{opts: Apply(o...)} -} - -func (m *SecurityPolicyToKuadrantEventMapper) Map(ctx context.Context, obj client.Object) []reconcile.Request { - logger := m.opts.Logger.WithValues("object", client.ObjectKeyFromObject(obj)) - - esp, ok := obj.(*egv1alpha1.SecurityPolicy) - if !ok { - logger.Error(fmt.Errorf("%T is not a *egv1alpha1.SecurityPolicy", obj), "cannot map") - return []reconcile.Request{} - } - - if !kuadrant.IsKuadrantManaged(esp) { - logger.V(1).Info("SecurityPolicy is not kuadrant managed", "securitypolicy", esp) - return []reconcile.Request{} - } - - kuadrantNamespace, err := kuadrant.GetKuadrantNamespace(esp) - if err != nil { - logger.Error(err, "cannot get kuadrant namespace") - return []reconcile.Request{} - } - kuadrantList := &kuadrantv1beta1.KuadrantList{} - err = m.opts.Client.List(ctx, kuadrantList, &client.ListOptions{Namespace: kuadrantNamespace}) - if err != nil { - logger.Error(err, "cannot list kuadrants") - return []reconcile.Request{} - } - if len(kuadrantList.Items) == 0 { - logger.Error(err, "kuadrant does not exist in expected namespace") - return []reconcile.Request{} - } - - return []reconcile.Request{{NamespacedName: client.ObjectKeyFromObject(&kuadrantList.Items[0])}} -} diff --git a/pkg/library/mappers/event_mapper.go b/pkg/library/mappers/event_mapper.go deleted file mode 100644 index 31b1a4a4b..000000000 --- a/pkg/library/mappers/event_mapper.go +++ /dev/null @@ -1,58 +0,0 @@ -package mappers - -import ( - "github.com/go-logr/logr" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -// options - -// TODO(@guicassolato): unit test -func WithLogger(logger logr.Logger) MapperOption { - return newFuncMapperOption(func(o *MapperOptions) { - o.Logger = logger - }) -} - -func WithClient(cl client.Client) MapperOption { - return newFuncMapperOption(func(o *MapperOptions) { - o.Client = cl - }) -} - -type MapperOption interface { - apply(*MapperOptions) -} - -type MapperOptions struct { - Logger logr.Logger - Client client.Client -} - -var defaultMapperOptions = MapperOptions{ - Logger: logr.Discard(), - Client: fake.NewClientBuilder().Build(), -} - -func newFuncMapperOption(f func(*MapperOptions)) *funcMapperOption { - return &funcMapperOption{ - f: f, - } -} - -type funcMapperOption struct { - f func(*MapperOptions) -} - -func (fmo *funcMapperOption) apply(opts *MapperOptions) { - fmo.f(opts) -} - -func Apply(opt ...MapperOption) MapperOptions { - opts := defaultMapperOptions - for _, o := range opt { - o.apply(&opts) - } - return opts -} diff --git a/pkg/library/mappers/gateway.go b/pkg/library/mappers/gateway.go deleted file mode 100644 index c7a2cb7a9..000000000 --- a/pkg/library/mappers/gateway.go +++ /dev/null @@ -1,71 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - "k8s.io/utils/ptr" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/fieldindexers" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -func NewGatewayEventMapper(policyType kuadrantgatewayapi.PolicyType, o ...MapperOption) *GatewayEventMapper { - return &GatewayEventMapper{ - policyType: policyType, - opts: Apply(o...), - } -} - -type GatewayEventMapper struct { - opts MapperOptions - policyType kuadrantgatewayapi.PolicyType -} - -func (m *GatewayEventMapper) Map(ctx context.Context, obj client.Object) []reconcile.Request { - logger := m.opts.Logger.WithValues("gateway", client.ObjectKeyFromObject(obj)) - gateway, ok := obj.(*gatewayapiv1.Gateway) - if !ok { - logger.Info("cannot map gateway related event", "error", fmt.Sprintf("%T is not a *gatewayapiv1beta1.Gateway", obj)) - return []reconcile.Request{} - } - routeList := &gatewayapiv1.HTTPRouteList{} - fields := client.MatchingFields{fieldindexers.HTTPRouteGatewayParentField: client.ObjectKeyFromObject(gateway).String()} - if err := m.opts.Client.List(ctx, routeList, fields); err != nil { - logger.V(1).Error(err, "unable to list HTTPRoutes") - return []reconcile.Request{} - } - - policies, err := m.policyType.GetList(ctx, m.opts.Client) - if err != nil { - logger.V(1).Error(err, "unable to list policies") - return []reconcile.Request{} - } - - if len(policies) == 0 { - logger.V(1).Info("no kuadrant policy possibly affected by the gateway related event") - return []reconcile.Request{} - } - - topology, err := kuadrantgatewayapi.NewTopology( - kuadrantgatewayapi.WithGateways([]*gatewayapiv1.Gateway{gateway}), - kuadrantgatewayapi.WithRoutes(utils.Map(routeList.Items, ptr.To[gatewayapiv1.HTTPRoute])), - kuadrantgatewayapi.WithPolicies(policies), - kuadrantgatewayapi.WithLogger(logger), - ) - if err != nil { - logger.V(1).Error(err, "unable to build topology for gateway") - return []reconcile.Request{} - } - - index := kuadrantgatewayapi.NewTopologyIndexes(topology) - return utils.Map(index.PoliciesFromGateway(gateway), func(p kuadrantgatewayapi.Policy) reconcile.Request { - policyKey := client.ObjectKeyFromObject(p) - logger.V(1).Info("new request", "policy key", policyKey) - return reconcile.Request{NamespacedName: policyKey} - }) -} diff --git a/pkg/library/mappers/gateway_test.go b/pkg/library/mappers/gateway_test.go deleted file mode 100644 index 1cd35c35e..000000000 --- a/pkg/library/mappers/gateway_test.go +++ /dev/null @@ -1,146 +0,0 @@ -//go:build unit - -package mappers - -import ( - "context" - "testing" - - "gotest.tools/assert" - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/fieldindexers" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" - "github.com/kuadrant/kuadrant-operator/pkg/log" -) - -func TestNewGatewayEventMapper(t *testing.T) { - testScheme := runtime.NewScheme() - - err := appsv1.AddToScheme(testScheme) - if err != nil { - t.Fatal(err) - } - - err = gatewayapiv1.Install(testScheme) - if err != nil { - t.Fatal(err) - } - - err = kuadrantv1.AddToScheme(testScheme) - if err != nil { - t.Fatal(err) - } - - ctx := context.Background() - - clientBuilder := func(objs []runtime.Object) client.Client { - return fake.NewClientBuilder(). - WithScheme(testScheme). - WithRuntimeObjects(objs...). - WithIndex(&gatewayapiv1.HTTPRoute{}, fieldindexers.HTTPRouteGatewayParentField, func(rawObj client.Object) []string { - route, assertionOk := rawObj.(*gatewayapiv1.HTTPRoute) - if !assertionOk { - return nil - } - - return utils.Map(kuadrantgatewayapi.GetGatewayParentKeys(route), func(key client.ObjectKey) string { - return key.String() - }) - }). - Build() - } - - t.Run("not gateway related event", func(subT *testing.T) { - objs := []runtime.Object{} - cl := clientBuilder(objs) - em := NewGatewayEventMapper(&rateLimitPolicyType{}, WithClient(cl), WithLogger(log.NewLogger())) - requests := em.Map(ctx, &gatewayapiv1.HTTPRoute{}) - assert.DeepEqual(subT, []reconcile.Request{}, requests) - }) - - t.Run("gateway related event - no policies - no requests", func(subT *testing.T) { - objs := []runtime.Object{} - cl := clientBuilder(objs) - em := NewGatewayEventMapper(&rateLimitPolicyType{}, WithClient(cl), WithLogger(log.NewLogger())) - requests := em.Map(ctx, &gatewayapiv1.Gateway{}) - assert.DeepEqual(subT, []reconcile.Request{}, requests) - }) - - t.Run("gateway related event - requests", func(subT *testing.T) { - gw := gatewayFactory("ns-a", "gw-1") - route := routeFactory("ns-a", "route-1", gatewayapiv1.ParentReference{Name: "gw-1"}) - pGw := policyFactory("ns-a", "pRoute", gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "HTTPRoute", - Name: gatewayapiv1.ObjectName("route-1"), - }) - pRoute := policyFactory("ns-a", "pGw", gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "Gateway", - Name: gatewayapiv1.ObjectName("gw-1"), - }) - objs := []runtime.Object{gw, route, pGw, pRoute} - cl := clientBuilder(objs) - em := NewGatewayEventMapper(&rateLimitPolicyType{}, WithClient(cl), WithLogger(log.NewLogger())) - requests := em.Map(ctx, gw) - assert.Equal(subT, len(requests), 2) - assert.Assert(subT, utils.Index(requests, func(r reconcile.Request) bool { - return r.NamespacedName == types.NamespacedName{Namespace: "ns-a", Name: "pGw"} - }) >= 0) - assert.Assert(subT, utils.Index(requests, func(r reconcile.Request) bool { - return r.NamespacedName == types.NamespacedName{Namespace: "ns-a", Name: "pRoute"} - }) >= 0) - }) -} - -const ( - RateLimitPolicyBackReferenceAnnotationName = "kuadrant.io/ratelimitpolicies" - RateLimitPolicyDirectReferenceAnnotationName = "kuadrant.io/ratelimitpolicy" -) - -type rateLimitPolicyType struct{} - -func (r rateLimitPolicyType) GetGVK() schema.GroupVersionKind { - return schema.GroupVersionKind{ - Group: kuadrantv1.GroupVersion.Group, - Version: kuadrantv1.GroupVersion.Version, - Kind: "RateLimitPolicy", - } -} -func (r rateLimitPolicyType) GetInstance() client.Object { - return &kuadrantv1.RateLimitPolicy{ - TypeMeta: metav1.TypeMeta{ - Kind: kuadrantv1.RateLimitPolicyGroupKind.Kind, - APIVersion: kuadrantv1.GroupVersion.String(), - }, - } -} - -func (r rateLimitPolicyType) BackReferenceAnnotationName() string { - return RateLimitPolicyBackReferenceAnnotationName -} - -func (r rateLimitPolicyType) DirectReferenceAnnotationName() string { - return RateLimitPolicyDirectReferenceAnnotationName -} - -func (r rateLimitPolicyType) GetList(ctx context.Context, cl client.Client, listOpts ...client.ListOption) ([]kuadrantgatewayapi.Policy, error) { - rlpList := &kuadrantv1.RateLimitPolicyList{} - err := cl.List(ctx, rlpList, listOpts...) - if err != nil { - return nil, err - } - return utils.Map(rlpList.Items, func(p kuadrantv1.RateLimitPolicy) kuadrantgatewayapi.Policy { return &p }), nil -} diff --git a/pkg/library/mappers/gateway_to_kuadrant.go b/pkg/library/mappers/gateway_to_kuadrant.go deleted file mode 100644 index e8e87679c..000000000 --- a/pkg/library/mappers/gateway_to_kuadrant.go +++ /dev/null @@ -1,54 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -type GatewayToKuadrantEventMapper struct { - opts MapperOptions -} - -func NewGatewayToKuadrantEventMapper(o ...MapperOption) *GatewayToKuadrantEventMapper { - return &GatewayToKuadrantEventMapper{opts: Apply(o...)} -} - -func (m *GatewayToKuadrantEventMapper) Map(ctx context.Context, obj client.Object) []reconcile.Request { - logger := m.opts.Logger.WithValues("object", client.ObjectKeyFromObject(obj)) - - gw, ok := obj.(*gatewayapiv1.Gateway) - if !ok { - logger.Error(fmt.Errorf("%T is not a *gatweayapiv1.Gateway", obj), "cannot map") - return []reconcile.Request{} - } - - if !kuadrant.IsKuadrantManaged(gw) { - logger.V(1).Info("gateway is not kuadrant managed", "gateway", gw) - return []reconcile.Request{} - } - - kuadrantNamespace, err := kuadrant.GetKuadrantNamespace(gw) - if err != nil { - logger.Error(err, "cannot get kuadrant namespace") - return []reconcile.Request{} - } - kuadrantList := &kuadrantv1beta1.KuadrantList{} - err = m.opts.Client.List(ctx, kuadrantList, &client.ListOptions{Namespace: kuadrantNamespace}) - if err != nil { - logger.Error(err, "cannot list kuadrants") - return []reconcile.Request{} - } - if len(kuadrantList.Items) == 0 { - logger.Error(err, "kuadrant does not exist in expected namespace") - return []reconcile.Request{} - } - - return []reconcile.Request{{NamespacedName: client.ObjectKeyFromObject(&kuadrantList.Items[0])}} -} diff --git a/pkg/library/mappers/httproute_to_gateway.go b/pkg/library/mappers/httproute_to_gateway.go deleted file mode 100644 index fc528c7ec..000000000 --- a/pkg/library/mappers/httproute_to_gateway.go +++ /dev/null @@ -1,38 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -// HTTPRouteToParentGatewaysEventMapper is an EventHandler that maps HTTPRoute events to gateway events, -// by going through the parentRefs of the route -type HTTPRouteToParentGatewaysEventMapper struct { - opts MapperOptions -} - -func NewHTTPRouteToParentGatewaysEventMapper(o ...MapperOption) *HTTPRouteToParentGatewaysEventMapper { - return &HTTPRouteToParentGatewaysEventMapper{opts: Apply(o...)} -} - -func (m *HTTPRouteToParentGatewaysEventMapper) Map(_ context.Context, obj client.Object) []reconcile.Request { - logger := m.opts.Logger.WithValues("object", client.ObjectKeyFromObject(obj)) - - route, ok := obj.(*gatewayapiv1.HTTPRoute) - if !ok { - logger.Error(fmt.Errorf("%T is not a *gatewayapiv1.HTTPRoute", obj), "cannot map") - return []reconcile.Request{} - } - - return utils.Map(kuadrantgatewayapi.GetRouteAcceptedGatewayParentKeys(route), func(key client.ObjectKey) reconcile.Request { - logger.V(1).Info("new gateway event", "key", key.String()) - return reconcile.Request{NamespacedName: key} - }) -} diff --git a/pkg/library/mappers/httproute_to_kuadrant.go b/pkg/library/mappers/httproute_to_kuadrant.go deleted file mode 100644 index 28fbb6c43..000000000 --- a/pkg/library/mappers/httproute_to_kuadrant.go +++ /dev/null @@ -1,66 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -type HTTPRouteToKuadrantEventMapper struct { - opts MapperOptions -} - -func NewHTTPRouteToKuadrantEventMapper(o ...MapperOption) *HTTPRouteToKuadrantEventMapper { - return &HTTPRouteToKuadrantEventMapper{opts: Apply(o...)} -} - -func (m *HTTPRouteToKuadrantEventMapper) Map(ctx context.Context, obj client.Object) []reconcile.Request { - logger := m.opts.Logger.WithValues("object", client.ObjectKeyFromObject(obj)) - - httpRoute, ok := obj.(*gatewayapiv1.HTTPRoute) - if !ok { - logger.Error(fmt.Errorf("%T is not a *gatweayapiv1.HTTPRoute", obj), "cannot map") - return []reconcile.Request{} - } - - gatewayKeys := kuadrantgatewayapi.GetRouteAcceptedGatewayParentKeys(httpRoute) - - for _, gatewayKey := range gatewayKeys { - gateway := &gatewayapiv1.Gateway{} - err := m.opts.Client.Get(ctx, gatewayKey, gateway) - if err != nil { - logger.Info("cannot get gateway", "error", err) - continue - } - - if !kuadrant.IsKuadrantManaged(gateway) { - logger.V(1).Info("gateway is not kuadrant managed", "gateway", gateway) - continue - } - kuadrantNamespace, err := kuadrant.GetKuadrantNamespace(gateway) - if err != nil { - logger.Error(err, "cannot get kuadrant namespace") - continue - } - kuadrantList := &kuadrantv1beta1.KuadrantList{} - err = m.opts.Client.List(ctx, kuadrantList, &client.ListOptions{Namespace: kuadrantNamespace}) - if err != nil { - logger.Error(err, "cannot list kuadrants") - return []reconcile.Request{} - } - if len(kuadrantList.Items) == 0 { - logger.Error(err, "kuadrant does not exist in expected namespace") - return []reconcile.Request{} - } - return []reconcile.Request{{NamespacedName: client.ObjectKeyFromObject(&kuadrantList.Items[0])}} - } - logger.V(1).Info("no matching kuadrant instance found") - return []reconcile.Request{} -} diff --git a/pkg/library/mappers/kuadrant_list_mapper.go b/pkg/library/mappers/kuadrant_list_mapper.go deleted file mode 100644 index d3554edce..000000000 --- a/pkg/library/mappers/kuadrant_list_mapper.go +++ /dev/null @@ -1,33 +0,0 @@ -package mappers - -import ( - "context" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" -) - -type KuadrantListEventMapper struct { - opts MapperOptions -} - -func NewKuadrantListEventMapper(o ...MapperOption) *KuadrantListEventMapper { - return &KuadrantListEventMapper{opts: Apply(o...)} -} - -func (m *KuadrantListEventMapper) Map(ctx context.Context, _ client.Object) []reconcile.Request { - kuadrantList := &kuadrantv1beta1.KuadrantList{} - err := m.opts.Client.List(ctx, kuadrantList) - if err != nil { - m.opts.Logger.Error(err, "cannot list kuadrants") - return []reconcile.Request{} - } - if len(kuadrantList.Items) == 0 { - m.opts.Logger.Error(err, "kuadrant does not exist in expected namespace") - return []reconcile.Request{} - } - - return []reconcile.Request{{NamespacedName: client.ObjectKeyFromObject(&kuadrantList.Items[0])}} -} diff --git a/pkg/library/mappers/kuadrant_to_gateway.go b/pkg/library/mappers/kuadrant_to_gateway.go deleted file mode 100644 index 4173cf05f..000000000 --- a/pkg/library/mappers/kuadrant_to_gateway.go +++ /dev/null @@ -1,41 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -func NewKuadrantToGatewayEventMapper(o ...MapperOption) *KuadrantToGatewayEventMapper { - return &KuadrantToGatewayEventMapper{opts: Apply(o...)} -} - -type KuadrantToGatewayEventMapper struct { - opts MapperOptions -} - -func (k *KuadrantToGatewayEventMapper) Map(ctx context.Context, obj client.Object) []reconcile.Request { - logger := k.opts.Logger.WithValues("object", client.ObjectKeyFromObject(obj)) - - _, ok := obj.(*kuadrantv1beta1.Kuadrant) - if !ok { - logger.Error(fmt.Errorf("%T is not a kuadrant instance", obj), "cannot map") - return []reconcile.Request{} - } - - gwList := &gatewayapiv1.GatewayList{} - if err := k.opts.Client.List(ctx, gwList); err != nil { - logger.Error(err, "failed to list gateways") - return []reconcile.Request{} - } - - return utils.Map(gwList.Items, func(gw gatewayapiv1.Gateway) reconcile.Request { - return reconcile.Request{NamespacedName: client.ObjectKeyFromObject(&gw)} - }) -} diff --git a/pkg/library/mappers/policy_to_gateway.go b/pkg/library/mappers/policy_to_gateway.go deleted file mode 100644 index 7814848f8..000000000 --- a/pkg/library/mappers/policy_to_gateway.go +++ /dev/null @@ -1,63 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -// PolicyToParentGatewaysEventMapper is an EventHandler that maps policies to gateway events, -// by going through the policies targetRefs and parentRefs of the route -type PolicyToParentGatewaysEventMapper struct { - opts MapperOptions -} - -func NewPolicyToParentGatewaysEventMapper(o ...MapperOption) *PolicyToParentGatewaysEventMapper { - return &PolicyToParentGatewaysEventMapper{opts: Apply(o...)} -} - -func (k *PolicyToParentGatewaysEventMapper) Map(ctx context.Context, obj client.Object) []reconcile.Request { - logger := k.opts.Logger.WithValues("object", client.ObjectKeyFromObject(obj), "kind", obj.GetObjectKind().GroupVersionKind().Kind) - - policy, ok := obj.(kuadrantgatewayapi.Policy) - if !ok { - logger.Error(fmt.Errorf("%T is not a Policy", obj), "cannot map") - return []reconcile.Request{} - } - - if kuadrantgatewayapi.IsTargetRefGateway(policy.GetTargetRef()) { - nn := types.NamespacedName{Name: string(policy.GetTargetRef().Name), Namespace: policy.GetNamespace()} - logger.V(1).Info("map", " gateway", nn) - - return []reconcile.Request{{NamespacedName: nn}} - } - - if kuadrantgatewayapi.IsTargetRefHTTPRoute(policy.GetTargetRef()) { - routeKey := client.ObjectKey{Name: string(policy.GetTargetRef().Name), Namespace: policy.GetNamespace()} - route := &gatewayapiv1.HTTPRoute{} - if err := k.opts.Client.Get(ctx, routeKey, route); err != nil { - if apierrors.IsNotFound(err) { - logger.V(1).Info("no route found", "route", routeKey) - return []reconcile.Request{} - } - logger.Error(err, "failed to get target", "route", routeKey) - return []reconcile.Request{} - } - - return utils.Map(kuadrantgatewayapi.GetRouteAcceptedGatewayParentKeys(route), func(key client.ObjectKey) reconcile.Request { - logger.V(1).Info("new gateway event", "key", key.String()) - return reconcile.Request{NamespacedName: key} - }) - } - - logger.V(1).Info("policy targeting unexpected resource, skipping it", "key", client.ObjectKeyFromObject(policy)) - return []reconcile.Request{} -} diff --git a/pkg/library/mappers/policy_to_kuadrant.go b/pkg/library/mappers/policy_to_kuadrant.go deleted file mode 100644 index 4fc96cfe9..000000000 --- a/pkg/library/mappers/policy_to_kuadrant.go +++ /dev/null @@ -1,48 +0,0 @@ -package mappers - -import ( - "context" - "fmt" - - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -type PolicyToKuadrantEventMapper struct { - opts MapperOptions -} - -func NewPolicyToKuadrantEventMapper(o ...MapperOption) *PolicyToKuadrantEventMapper { - return &PolicyToKuadrantEventMapper{opts: Apply(o...)} -} - -func (m *PolicyToKuadrantEventMapper) Map(ctx context.Context, obj client.Object) []reconcile.Request { - logger := m.opts.Logger.WithValues("object", client.ObjectKeyFromObject(obj)) - - policy, ok := obj.(kuadrant.Policy) - if !ok { - logger.Error(fmt.Errorf("%T is not a kuadrant.Policy", obj), "cannot map") - return []reconcile.Request{} - } - - kuadrantNamespace, err := kuadrant.GetKuadrantNamespaceFromPolicyTargetRef(ctx, m.opts.Client, policy) - if err != nil { - logger.Error(err, "cannot get kuadrant namespace") - return []reconcile.Request{} - } - kuadrantList := &kuadrantv1beta1.KuadrantList{} - err = m.opts.Client.List(ctx, kuadrantList, &client.ListOptions{Namespace: kuadrantNamespace}) - if err != nil { - logger.Error(err, "cannot list kuadrants") - return []reconcile.Request{} - } - if len(kuadrantList.Items) == 0 { - logger.Error(err, "kuadrant does not exist in expected namespace") - return []reconcile.Request{} - } - - return []reconcile.Request{{NamespacedName: client.ObjectKeyFromObject(&kuadrantList.Items[0])}} -} diff --git a/pkg/library/mappers/utils_test.go b/pkg/library/mappers/utils_test.go deleted file mode 100644 index dbc7d3e0b..000000000 --- a/pkg/library/mappers/utils_test.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build unit - -package mappers - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" -) - -func gatewayFactory(ns, name string) *gatewayapiv1.Gateway { - return &gatewayapiv1.Gateway{ - TypeMeta: metav1.TypeMeta{Kind: "Gateway", APIVersion: gatewayapiv1.GroupVersion.String()}, - ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns}, - Spec: gatewayapiv1.GatewaySpec{}, - } -} - -func routeFactory(ns, name string, parentRef gatewayapiv1.ParentReference) *gatewayapiv1.HTTPRoute { - return &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{Kind: "HTTPRoute", APIVersion: gatewayapiv1.GroupVersion.String()}, - ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns}, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{parentRef}, - }, - }, - } -} - -func policyFactory(ns, name string, targetRef gatewayapiv1alpha2.LocalPolicyTargetReference) *kuadrantv1.RateLimitPolicy { - return &kuadrantv1.RateLimitPolicy{ - TypeMeta: metav1.TypeMeta{Kind: "RateLimitPolicy", APIVersion: kuadrantv1.GroupVersion.String()}, - ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns}, - Spec: kuadrantv1.RateLimitPolicySpec{TargetRef: gatewayapiv1alpha2.LocalPolicyTargetReferenceWithSectionName{LocalPolicyTargetReference: targetRef}}, - } -} diff --git a/pkg/library/reconcilers/fetcher.go b/pkg/library/reconcilers/fetcher.go deleted file mode 100644 index dbf00c73b..000000000 --- a/pkg/library/reconcilers/fetcher.go +++ /dev/null @@ -1,102 +0,0 @@ -package reconcilers - -import ( - "context" - "fmt" - "reflect" - - "github.com/go-logr/logr" - "k8s.io/apimachinery/pkg/api/meta" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" -) - -// FetchTargetRefObject fetches the target reference object and checks the status is valid -func FetchTargetRefObject(ctx context.Context, k8sClient client.Reader, targetRef gatewayapiv1alpha2.LocalPolicyTargetReference, defaultNs string, fetchOnlyProgrammedGateways bool) (client.Object, error) { - ns := defaultNs - objKey := client.ObjectKey{Name: string(targetRef.Name), Namespace: ns} - - switch targetRef.Kind { - case "Gateway": - if fetchOnlyProgrammedGateways { - return fetchProgrammedGateway(ctx, k8sClient, objKey) - } - return fetchGateway(ctx, k8sClient, objKey) - case "HTTPRoute": - return fetchHTTPRoute(ctx, k8sClient, objKey) - default: - return nil, fmt.Errorf("FetchValidTargetRef: targetRef (%v) to unknown network resource", targetRef) - } -} - -func fetchGateway(ctx context.Context, k8sClient client.Reader, key client.ObjectKey) (*gatewayapiv1.Gateway, error) { - logger, _ := logr.FromContext(ctx) - - gw := &gatewayapiv1.Gateway{} - err := k8sClient.Get(ctx, key, gw) - logger.V(1).Info("fetch Gateway policy targetRef", "gateway", key, "err", err) - if err != nil { - return nil, err - } - - return gw, nil -} - -func fetchProgrammedGateway(ctx context.Context, k8sClient client.Reader, key client.ObjectKey) (*gatewayapiv1.Gateway, error) { - gw, err := fetchGateway(ctx, k8sClient, key) - if err != nil { - return nil, err - } - if meta.IsStatusConditionFalse(gw.Status.Conditions, string(gatewayapiv1.GatewayConditionProgrammed)) { - return nil, fmt.Errorf("gateway (%v) not ready", key) - } - - return gw, nil -} - -func fetchHTTPRoute(ctx context.Context, k8sClient client.Reader, key client.ObjectKey) (*gatewayapiv1.HTTPRoute, error) { - logger, _ := logr.FromContext(ctx) - - httpRoute := &gatewayapiv1.HTTPRoute{} - err := k8sClient.Get(ctx, key, httpRoute) - logger.V(1).Info("fetch HTTPRoute policy targetRef", "httpRoute", key, "err", err) - if err != nil { - return nil, err - } - - if !httpRouteAccepted(httpRoute) { - return nil, fmt.Errorf("httproute (%v) not accepted", key) - } - - return httpRoute, nil -} - -func httpRouteAccepted(httpRoute *gatewayapiv1.HTTPRoute) bool { - if httpRoute == nil { - return false - } - - if len(httpRoute.Spec.CommonRouteSpec.ParentRefs) == 0 { - return false - } - - // Check HTTProute parents (gateways) in the status object - // if any of the current parent gateways reports not "Admitted", return false - for _, parentRef := range httpRoute.Spec.CommonRouteSpec.ParentRefs { - routeParentStatus := func(pRef gatewayapiv1.ParentReference) *gatewayapiv1.RouteParentStatus { - for idx := range httpRoute.Status.RouteStatus.Parents { - if reflect.DeepEqual(pRef, httpRoute.Status.RouteStatus.Parents[idx].ParentRef) { - return &httpRoute.Status.RouteStatus.Parents[idx] - } - } - return nil - }(parentRef) - - if routeParentStatus == nil || meta.IsStatusConditionFalse(routeParentStatus.Conditions, string(gatewayapiv1.RouteReasonAccepted)) { - return false - } - } - - return true -} diff --git a/pkg/library/reconcilers/fetcher_test.go b/pkg/library/reconcilers/fetcher_test.go deleted file mode 100644 index 5a741ab65..000000000 --- a/pkg/library/reconcilers/fetcher_test.go +++ /dev/null @@ -1,495 +0,0 @@ -//go:build unit - -package reconcilers - -import ( - "context" - "fmt" - "reflect" - "testing" - - "github.com/go-logr/logr" - "github.com/google/go-cmp/cmp" - "gotest.tools/assert" - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/log" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" -) - -func TestFetchTargetRefObject(t *testing.T) { - var ( - namespace = "operator-unittest" - routeName = "my-route" - gatewayName = "my-gw" - ) - baseCtx := context.Background() - ctx := logr.NewContext(baseCtx, log.Log) - - s := scheme.Scheme - err := appsv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - err = gatewayapiv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - - routeTargetRef := gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "HTTPRoute", - Name: gatewayapiv1.ObjectName(routeName), - } - - gatewayTargetRef := gatewayapiv1alpha2.LocalPolicyTargetReference{ - Group: gatewayapiv1.GroupName, - Kind: "Gateway", - Name: gatewayapiv1.ObjectName(gatewayName), - } - - routeFactory := func(status metav1.ConditionStatus) *gatewayapiv1.HTTPRoute { - return &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1", - Kind: "HTTPRoute", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: routeName, - Namespace: namespace, - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "gwName", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "gwName", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: status, - }, - }, - }, - }, - }, - }, - } - } - - gatewayFactory := func(status metav1.ConditionStatus) *gatewayapiv1.Gateway { - return &gatewayapiv1.Gateway{ - TypeMeta: metav1.TypeMeta{ - Kind: "Gateway", - APIVersion: "gateway.networking.k8s.io/v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: gatewayName, - Namespace: namespace, - }, - Status: gatewayapiv1.GatewayStatus{ - Conditions: []metav1.Condition{ - { - Type: string(gatewayapiv1.GatewayConditionProgrammed), - Status: status, - }, - }, - }, - } - } - - clientFactory := func(objs ...runtime.Object) client.WithWatch { - return fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - } - - assertion := func(res, existing client.Object) { - switch obj := res.(type) { - case *gatewayapiv1.HTTPRoute: - if !reflect.DeepEqual(obj, existing) { - t.Fatal("res spec not as expected", cmp.Diff(obj, existing)) - } - case *gatewayapiv1.Gateway: - if !reflect.DeepEqual(obj, existing) { - t.Fatal("res spec not as expected", cmp.Diff(obj, existing)) - } - default: - t.Fatal("res type not known") - } - } - - t.Run("fetch http route", func(subT *testing.T) { - existingRoute := routeFactory(metav1.ConditionTrue) - clientAPIReader := clientFactory(existingRoute) - res, err := FetchTargetRefObject(ctx, clientAPIReader, routeTargetRef, namespace, true) - assert.NilError(subT, err) - assert.Equal(subT, res == nil, false) - assertion(res, existingRoute) - }) - - t.Run("fetch http route - not accepted", func(subT *testing.T) { - existingRoute := routeFactory(metav1.ConditionFalse) - clientAPIReader := clientFactory(existingRoute) - res, err := FetchTargetRefObject(ctx, clientAPIReader, routeTargetRef, namespace, true) - assert.Error(subT, err, fmt.Sprintf("httproute (%s/%s) not accepted", namespace, routeName)) - assert.DeepEqual(subT, res, (*gatewayapiv1.HTTPRoute)(nil)) - }) - - t.Run("fetch gateway", func(subT *testing.T) { - existingGateway := gatewayFactory(metav1.ConditionTrue) - clientAPIReader := clientFactory(existingGateway) - res, err := FetchTargetRefObject(ctx, clientAPIReader, gatewayTargetRef, namespace, true) - assert.NilError(subT, err) - assert.Equal(subT, res == nil, false) - assertion(res, existingGateway) - }) - - t.Run("fetch gateway - not ready", func(subT *testing.T) { - existingGateway := gatewayFactory(metav1.ConditionFalse) - clientAPIReader := clientFactory(existingGateway) - res, err := FetchTargetRefObject(ctx, clientAPIReader, gatewayTargetRef, namespace, true) - assert.Error(subT, err, fmt.Sprintf("gateway (%s/%s) not ready", namespace, gatewayName)) - assert.DeepEqual(subT, res, (*gatewayapiv1.Gateway)(nil)) - }) - - t.Run("fetch gateway - not ready - skip check for only ready gateways", func(subT *testing.T) { - existingGateway := gatewayFactory(metav1.ConditionFalse) - clientAPIReader := clientFactory(existingGateway) - res, err := FetchTargetRefObject(ctx, clientAPIReader, gatewayTargetRef, namespace, false) - assert.NilError(subT, err) - assert.Equal(subT, res == nil, false) - assertion(res, existingGateway) - }) - - t.Run("unknown network resource", func(subT *testing.T) { - targetRef := gatewayapiv1alpha2.LocalPolicyTargetReference{Kind: "Service", Name: "my-sv"} - clientAPIReader := clientFactory() - res, err := FetchTargetRefObject(ctx, clientAPIReader, targetRef, namespace, true) - assert.Error(subT, err, fmt.Sprintf("FetchValidTargetRef: targetRef (%v) to unknown network resource", targetRef)) - assert.DeepEqual(subT, res, nil) - }) -} - -func TestFetchGateway(t *testing.T) { - var ( - namespace = "operator-unittest" - gwName = "my-gateway" - ) - baseCtx := context.Background() - ctx := logr.NewContext(baseCtx, log.Log) - - s := scheme.Scheme - err := appsv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - err = gatewayapiv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - - existingGateway := &gatewayapiv1.Gateway{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1", - Kind: "Gateway", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: gwName, - Namespace: namespace, - }, - Spec: gatewayapiv1.GatewaySpec{ - GatewayClassName: "istio", - }, - Status: gatewayapiv1.GatewayStatus{ - Conditions: []metav1.Condition{ - { - Type: "Ready", - Status: metav1.ConditionTrue, - }, - }, - }, - } - - // Objects to track in the fake client. - objs := []runtime.Object{existingGateway} - - // Create a fake client to mock API calls. - clientAPIReader := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - - key := client.ObjectKey{Name: gwName, Namespace: namespace} - - res, err := fetchGateway(ctx, clientAPIReader, key) - if err != nil { - t.Fatal(err) - } - - if res == nil { - t.Fatal("res is nil") - } - - if !reflect.DeepEqual(res.Spec, existingGateway.Spec) { - t.Fatal("res spec not as expected") - } -} - -func TestFetchHTTPRoute(t *testing.T) { - var ( - namespace = "operator-unittest" - routeName = "my-route" - ) - baseCtx := context.Background() - ctx := logr.NewContext(baseCtx, log.Log) - - s := scheme.Scheme - err := appsv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - err = gatewayapiv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - - existingRoute := &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1", - Kind: "HTTPRoute", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: routeName, - Namespace: namespace, - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "gwName", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "gwName", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - }, - }, - }, - } - - // Objects to track in the fake client. - objs := []runtime.Object{existingRoute} - - // Create a fake client to mock API calls. - clientAPIReader := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - - key := client.ObjectKey{Name: routeName, Namespace: namespace} - - res, err := fetchHTTPRoute(ctx, clientAPIReader, key) - if err != nil { - t.Fatal(err) - } - - if res == nil { - t.Fatal("res is nil") - } - - if !reflect.DeepEqual(res.Spec, existingRoute.Spec) { - t.Fatal("res spec not as expected") - } -} - -func TestHTTPRouteAccepted(t *testing.T) { - testCases := []struct { - name string - route *gatewayapiv1.HTTPRoute - expected bool - }{ - { - "nil", - nil, - false, - }, - { - "empty parent refs", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{}, - }, - false, - }, - { - "single parent accepted", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "a", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "a", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - }, - }, - }, - }, - true, - }, - { - "single parent not accepted", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "a", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "a", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionFalse, - }, - }, - }, - }, - }, - }, - }, - false, - }, - { - "wrong parent is accepted", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "a", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "b", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - }, - }, - }, - }, - false, - }, - { - "multiple parents only one is accepted", - &gatewayapiv1.HTTPRoute{ - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "a", - }, - { - Name: "b", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "a", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "b", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionFalse, - }, - }, - }, - }, - }, - }, - }, - false, - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := httpRouteAccepted(tc.route) - if res != tc.expected { - subT.Errorf("result (%t) does not match expected (%t)", res, tc.expected) - } - }) - } -} diff --git a/pkg/library/reconcilers/gateway_diffs.go b/pkg/library/reconcilers/gateway_diffs.go deleted file mode 100644 index 05ee74ee6..000000000 --- a/pkg/library/reconcilers/gateway_diffs.go +++ /dev/null @@ -1,123 +0,0 @@ -package reconcilers - -import ( - "context" - "fmt" - "slices" - - "github.com/go-logr/logr" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -type GatewayDiffs struct { - GatewaysMissingPolicyRef []kuadrant.GatewayWrapper - GatewaysWithValidPolicyRef []kuadrant.GatewayWrapper - GatewaysWithInvalidPolicyRef []kuadrant.GatewayWrapper -} - -// ComputeGatewayDiffs computes all the differences to reconcile regarding the gateways whose behaviors should/should not be extended by the policy. -// These include gateways directly referenced by the policy and gateways indirectly referenced through the policy's target network objects. -// * list of gateways to which the policy applies for the first time -// * list of gateways to which the policy no longer applies -// * list of gateways to which the policy still applies -// TODO(@guicassolato): unit test -func ComputeGatewayDiffs(ctx context.Context, k8sClient client.Reader, policy, targetNetworkObject client.Object) (*GatewayDiffs, error) { - logger, _ := logr.FromContext(ctx) - - var gwKeys []client.ObjectKey - if policy.GetDeletionTimestamp() == nil { - gwKeys = targetedGatewayKeys(targetNetworkObject) - } - - // TODO(rahulanand16nov): maybe think about optimizing it with a label later - allGwList := &gatewayapiv1.GatewayList{} - err := k8sClient.List(ctx, allGwList) - if err != nil { - return nil, err - } - - policyKind, ok := policy.(kuadrant.Referrer) - if !ok { - return nil, fmt.Errorf("policy %s is not a referrer", policy.GetObjectKind().GroupVersionKind()) - } - - gwDiff := &GatewayDiffs{ - GatewaysMissingPolicyRef: gatewaysMissingPolicyRef(allGwList, client.ObjectKeyFromObject(policy), gwKeys, policyKind), - GatewaysWithValidPolicyRef: gatewaysWithValidPolicyRef(allGwList, client.ObjectKeyFromObject(policy), gwKeys, policyKind), - GatewaysWithInvalidPolicyRef: gatewaysWithInvalidPolicyRef(allGwList, client.ObjectKeyFromObject(policy), gwKeys, policyKind), - } - - logger.V(1).Info("ComputeGatewayDiffs", - "missing-policy-ref", len(gwDiff.GatewaysMissingPolicyRef), - "valid-policy-ref", len(gwDiff.GatewaysWithValidPolicyRef), - "invalid-policy-ref", len(gwDiff.GatewaysWithInvalidPolicyRef), - ) - - return gwDiff, nil -} - -// gatewaysMissingPolicyRef returns gateways referenced by the policy but that miss the reference to it the annotations -func gatewaysMissingPolicyRef(gwList *gatewayapiv1.GatewayList, policyKey client.ObjectKey, policyGwKeys []client.ObjectKey, policyKind kuadrant.Referrer) []kuadrant.GatewayWrapper { - gateways := make([]kuadrant.GatewayWrapper, 0) - for i := range gwList.Items { - gateway := gwList.Items[i] - gw := kuadrant.GatewayWrapper{Gateway: &gateway, Referrer: policyKind} - if slices.Contains(policyGwKeys, client.ObjectKeyFromObject(&gateway)) && !gw.ContainsPolicy(policyKey) { - gateways = append(gateways, gw) - } - } - return gateways -} - -// gatewaysWithValidPolicyRef returns gateways referenced by the policy that also have the reference in the annotations -func gatewaysWithValidPolicyRef(gwList *gatewayapiv1.GatewayList, policyKey client.ObjectKey, policyGwKeys []client.ObjectKey, policyKind kuadrant.Referrer) []kuadrant.GatewayWrapper { - gateways := make([]kuadrant.GatewayWrapper, 0) - for i := range gwList.Items { - gateway := gwList.Items[i] - gw := kuadrant.GatewayWrapper{Gateway: &gateway, Referrer: policyKind} - if slices.Contains(policyGwKeys, client.ObjectKeyFromObject(&gateway)) && gw.ContainsPolicy(policyKey) { - gateways = append(gateways, gw) - } - } - return gateways -} - -// gatewaysWithInvalidPolicyRef returns gateways not referenced by the policy that still have the reference in the annotations -func gatewaysWithInvalidPolicyRef(gwList *gatewayapiv1.GatewayList, policyKey client.ObjectKey, policyGwKeys []client.ObjectKey, policyKind kuadrant.Referrer) []kuadrant.GatewayWrapper { - gateways := make([]kuadrant.GatewayWrapper, 0) - for i := range gwList.Items { - gateway := gwList.Items[i] - gw := kuadrant.GatewayWrapper{Gateway: &gateway, Referrer: policyKind} - if !slices.Contains(policyGwKeys, client.ObjectKeyFromObject(&gateway)) && gw.ContainsPolicy(policyKey) { - gateways = append(gateways, gw) - } - } - return gateways -} - -// targetedGatewayKeys returns the list of gateways in the hierarchy of a target network object -func targetedGatewayKeys(targetNetworkObject client.Object) []client.ObjectKey { - switch obj := targetNetworkObject.(type) { - case *gatewayapiv1.HTTPRoute: - gwKeys := make([]client.ObjectKey, 0) - for _, parentRef := range obj.Spec.CommonRouteSpec.ParentRefs { - gwKey := client.ObjectKey{Name: string(parentRef.Name), Namespace: obj.Namespace} - if parentRef.Namespace != nil { - gwKey.Namespace = string(*parentRef.Namespace) - } - gwKeys = append(gwKeys, gwKey) - } - return gwKeys - - case *gatewayapiv1.Gateway: - return []client.ObjectKey{client.ObjectKeyFromObject(targetNetworkObject)} - - // If the targetNetworkObject is nil, we don't fail; instead, we return an empty slice of gateway keys. - // This is for supporting a smooth cleanup in cases where the network object has been deleted already - default: - return []client.ObjectKey{} - } -} diff --git a/pkg/library/reconcilers/gateway_diffs_test.go b/pkg/library/reconcilers/gateway_diffs_test.go deleted file mode 100644 index c12032a4f..000000000 --- a/pkg/library/reconcilers/gateway_diffs_test.go +++ /dev/null @@ -1,308 +0,0 @@ -//go:build unit - -package reconcilers - -import ( - "slices" - "testing" - - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -func TestGatewaysMissingPolicyRef(t *testing.T) { - gwList := &gatewayapiv1.GatewayList{ - Items: []gatewayapiv1.Gateway{ - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-2", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"}]`}, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-3", - }, - }, - }, - } - - var gws []string - policyKind := &kuadrant.PolicyKindStub{} - gwName := func(gw kuadrant.GatewayWrapper) string { return gw.Gateway.Name } - - gws = utils.Map(gatewaysMissingPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-1"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-2"}, - {Namespace: "gw-ns", Name: "gw-3"}, - }, policyKind), gwName) - - if slices.Contains(gws, "gw-1") { - t.Error("gateway expected not to be listed as missing policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as missing policy ref") - } - if !slices.Contains(gws, "gw-3") { - t.Error("gateway expected to be listed as missing policy ref") - } - - gws = utils.Map(gatewaysMissingPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-2"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-1"}, - }, policyKind), gwName) - - if slices.Contains(gws, "gw-1") { - t.Error("gateway expected not to be listed as missing policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as missing policy ref") - } - if slices.Contains(gws, "gw-3") { - t.Error("gateway expected not to be listed as missing policy ref") - } - - gws = utils.Map(gatewaysMissingPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-3"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-1"}, - {Namespace: "gw-ns", Name: "gw-3"}, - }, policyKind), gwName) - - if !slices.Contains(gws, "gw-1") { - t.Error("gateway expected to be listed as missing policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as missing policy ref") - } - if !slices.Contains(gws, "gw-3") { - t.Error("gateway expected to be listed as missing policy ref") - } -} - -func TestGatewaysWithValidPolicyRef(t *testing.T) { - gwList := &gatewayapiv1.GatewayList{ - Items: []gatewayapiv1.Gateway{ - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-2", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"}]`}, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-3", - }, - }, - }, - } - - var gws []string - policyKind := &kuadrant.PolicyKindStub{} - gwName := func(gw kuadrant.GatewayWrapper) string { return gw.Gateway.Name } - - gws = utils.Map(gatewaysWithValidPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-1"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-2"}, - {Namespace: "gw-ns", Name: "gw-3"}, - }, policyKind), gwName) - - if slices.Contains(gws, "gw-1") { - t.Error("gateway expected not to be listed as with valid policy ref") - } - if !slices.Contains(gws, "gw-2") { - t.Error("gateway expected to be listed as with valid policy ref") - } - if slices.Contains(gws, "gw-3") { - t.Error("gateway expected not to be listed as with valid policy ref") - } - - gws = utils.Map(gatewaysWithValidPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-2"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-1"}, - }, policyKind), gwName) - - if !slices.Contains(gws, "gw-1") { - t.Error("gateway expected to be listed as with valid policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as with valid policy ref") - } - if slices.Contains(gws, "gw-3") { - t.Error("gateway expected not to be listed as with valid policy ref") - } - - gws = utils.Map(gatewaysWithValidPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-3"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-1"}, - {Namespace: "gw-ns", Name: "gw-3"}, - }, policyKind), gwName) - - if slices.Contains(gws, "gw-1") { - t.Error("gateway expected not to be listed as with valid policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as with valid policy ref") - } - if slices.Contains(gws, "gw-3") { - t.Error("gateway expected not to be listed as with valid policy ref") - } -} - -func TestGatewaysWithInvalidPolicyRef(t *testing.T) { - gwList := &gatewayapiv1.GatewayList{ - Items: []gatewayapiv1.Gateway{ - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-1", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"},{"Namespace":"app-ns","Name":"policy-2"}]`}, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-2", - Annotations: map[string]string{"kuadrant.io/testpolicies": `[{"Namespace":"app-ns","Name":"policy-1"}]`}, - }, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Namespace: "gw-ns", - Name: "gw-3", - }, - }, - }, - } - - var gws []string - policyKind := &kuadrant.PolicyKindStub{} - gwName := func(gw kuadrant.GatewayWrapper) string { return gw.Gateway.Name } - - gws = utils.Map(gatewaysWithInvalidPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-1"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-2"}, - {Namespace: "gw-ns", Name: "gw-3"}, - }, policyKind), gwName) - - if !slices.Contains(gws, "gw-1") { - t.Error("gateway expected to be listed as with invalid policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } - if slices.Contains(gws, "gw-3") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } - - gws = utils.Map(gatewaysWithInvalidPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-2"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-1"}, - }, policyKind), gwName) - - if slices.Contains(gws, "gw-1") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } - if slices.Contains(gws, "gw-3") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } - - gws = utils.Map(gatewaysWithInvalidPolicyRef(gwList, client.ObjectKey{Namespace: "app-ns", Name: "policy-3"}, []client.ObjectKey{ - {Namespace: "gw-ns", Name: "gw-1"}, - {Namespace: "gw-ns", Name: "gw-3"}, - }, policyKind), gwName) - - if slices.Contains(gws, "gw-1") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } - if slices.Contains(gws, "gw-2") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } - if slices.Contains(gws, "gw-3") { - t.Error("gateway expected not to be listed as with invalid policy ref") - } -} - -func TestTargetedGatewayKeys(t *testing.T) { - var ( - namespace = "operator-unittest" - routeName = "my-route" - ) - - s := scheme.Scheme - err := appsv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - err = gatewayapiv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - - httpRoute := &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1", - Kind: "HTTPRoute", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: routeName, - Namespace: namespace, - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "gwName", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "gwName", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - }, - }, - }, - } - - keys := targetedGatewayKeys(httpRoute) - - if len(keys) != 1 { - t.Fatalf("gateway key slice length is %d and it was expected to be 1", len(keys)) - } - - expectedKey := client.ObjectKey{Name: "gwName", Namespace: namespace} - - if keys[0] != expectedKey { - t.Fatalf("gwKey value (%+v) does not match expected (%+v)", keys[0], expectedKey) - } -} diff --git a/pkg/library/reconcilers/target_ref_reconciler.go b/pkg/library/reconcilers/target_ref_reconciler.go deleted file mode 100644 index 3e35dee99..000000000 --- a/pkg/library/reconcilers/target_ref_reconciler.go +++ /dev/null @@ -1,213 +0,0 @@ -/* -Copyright 2021 Red Hat, Inc. - -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 reconcilers - -import ( - "context" - "fmt" - - "github.com/go-logr/logr" - "sigs.k8s.io/controller-runtime/pkg/client" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" -) - -type TargetRefReconciler struct { - client.Client -} - -// FetchAcceptedGatewayHTTPRoutes returns the list of HTTPRoutes that have been accepted as children of a gateway. -func (r *TargetRefReconciler) FetchAcceptedGatewayHTTPRoutes(ctx context.Context, gateway *gatewayapiv1.Gateway) (routes []gatewayapiv1.HTTPRoute) { - gwKey := client.ObjectKeyFromObject(gateway) - logger, _ := logr.FromContext(ctx) - logger = logger.WithName("FetchAcceptedGatewayHTTPRoutes").WithValues("gateway", gwKey) - - routeList := &gatewayapiv1.HTTPRouteList{} - err := r.Client.List(ctx, routeList) - if err != nil { - logger.V(1).Info("failed to list httproutes", "err", err) - return - } - - for idx := range routeList.Items { - route := routeList.Items[idx] - if utils.Index(kuadrantgatewayapi.GetRouteAcceptedGatewayParentKeys(&route), func(parentGatewayKey client.ObjectKey) bool { return parentGatewayKey == gwKey }) >= 0 { - logger.V(1).Info("found route attached to gateway", "httproute", client.ObjectKeyFromObject(&route)) - routes = append(routes, route) - continue - } - logger.V(1).Info("skipping route, not attached to gateway", "httproute", client.ObjectKeyFromObject(&route)) - } - - return -} - -// TargetedGatewayKeys returns the list of gateways that are being referenced from the target. -func (r *TargetRefReconciler) TargetedGatewayKeys(_ context.Context, targetNetworkObject client.Object) []client.ObjectKey { - switch obj := targetNetworkObject.(type) { - case *gatewayapiv1.HTTPRoute: - gwKeys := make([]client.ObjectKey, 0) - for _, parentRef := range obj.Spec.CommonRouteSpec.ParentRefs { - gwKey := client.ObjectKey{Name: string(parentRef.Name), Namespace: obj.Namespace} - if parentRef.Namespace != nil { - gwKey.Namespace = string(*parentRef.Namespace) - } - gwKeys = append(gwKeys, gwKey) - } - return gwKeys - - case *gatewayapiv1.Gateway: - return []client.ObjectKey{client.ObjectKeyFromObject(targetNetworkObject)} - - // If the targetNetworkObject is nil, we don't fail; instead, we return an empty slice of gateway keys. - // This is for supporting a smooth cleanup in cases where the network object has been deleted already - default: - return []client.ObjectKey{} - } -} - -// ReconcileTargetBackReference reconciles policy key in annotations of the target object -func (r *TargetRefReconciler) ReconcileTargetBackReference(ctx context.Context, p kuadrant.Policy, targetNetworkObject client.Object, annotationName string) error { - logger, _ := logr.FromContext(ctx) - - policyKey := client.ObjectKeyFromObject(p) - targetNetworkObjectKey := client.ObjectKeyFromObject(targetNetworkObject) - targetNetworkObjectKind := targetNetworkObject.GetObjectKind().GroupVersionKind() - - // Step 1 Build list of network objects in the same namespace as the policy - // Step 2 Remove the direct back reference annotation to the current policy from any network object not being currently referenced - // Step 3 Check direct back ref annotation from the current target network object - // Step 3.1 if it does not exit -> create it - // Step 3.2 if it already exits and the reference is the current policy -> nothing to do - // Step 3.3 if it already exits and the reference is not the current policy -> return err - - // Step 1 - gwList := &gatewayapiv1.GatewayList{} - err := r.Client.List(ctx, gwList, client.InNamespace(p.GetNamespace())) - logger.V(1).Info("ReconcileTargetBackReference: list gateways", "#Gateways", len(gwList.Items), "err", err) - if err != nil { - return err - } - - routeList := &gatewayapiv1.HTTPRouteList{} - err = r.Client.List(ctx, routeList, client.InNamespace(p.GetNamespace())) - logger.V(1).Info("ReconcileTargetBackReference: list httproutes", "#HTTPRoutes", len(routeList.Items), "err", err) - if err != nil { - return err - } - - networkObjectList := utils.Map(gwList.Items, func(g gatewayapiv1.Gateway) client.Object { return &g }) - networkObjectList = append(networkObjectList, utils.Map(routeList.Items, func(g gatewayapiv1.HTTPRoute) client.Object { return &g })...) - // remove currently targeted network resource from the list - networkObjectList = utils.Filter(networkObjectList, func(obj client.Object) bool { - return targetNetworkObjectKey != client.ObjectKeyFromObject(obj) - }) - - // Step 2 - for _, networkObject := range networkObjectList { - annotations := networkObject.GetAnnotations() - if val, ok := annotations[annotationName]; ok && val == policyKey.String() { - delete(annotations, annotationName) - networkObject.SetAnnotations(annotations) - err := r.Client.Update(ctx, networkObject) - logger.V(1).Info("ReconcileTargetBackReference: update network resource", - "kind", networkObject.GetObjectKind().GroupVersionKind(), - "name", client.ObjectKeyFromObject(networkObject), "err", err) - if err != nil { - return err - } - } - } - - // Step 3 - objAnnotations := utils.ReadAnnotationsFromObject(targetNetworkObject) - - if val, ok := objAnnotations[annotationName]; ok { - if val != policyKey.String() { - // Step 3.3 - return kuadrant.NewErrConflict(p.Kind(), val, fmt.Errorf("the %s target %s is already referenced by policy %s", targetNetworkObjectKind, targetNetworkObjectKey, val)) - } - // Step 3.2 - // NO OP - } else { - // Step 3.1 - objAnnotations[annotationName] = policyKey.String() - targetNetworkObject.SetAnnotations(objAnnotations) - err := r.Client.Update(ctx, targetNetworkObject) - logger.V(1).Info("ReconcileTargetBackReference: update target object", "kind", targetNetworkObjectKind, "name", targetNetworkObjectKey, "err", err) - if err != nil { - return err - } - } - - return nil -} - -func (r *TargetRefReconciler) DeleteTargetBackReference(ctx context.Context, targetNetworkObject client.Object, annotationName string) error { - logger, _ := logr.FromContext(ctx) - - targetNetworkObjectKey := client.ObjectKeyFromObject(targetNetworkObject) - targetNetworkObjectKind := targetNetworkObject.GetObjectKind().GroupVersionKind() - - // Reconcile the back reference: - objAnnotations := utils.ReadAnnotationsFromObject(targetNetworkObject) - - if _, ok := objAnnotations[annotationName]; ok { - delete(objAnnotations, annotationName) - targetNetworkObject.SetAnnotations(objAnnotations) - err := r.Client.Update(ctx, targetNetworkObject) - logger.V(1).Info("DeleteTargetBackReference: update network resource", "kind", targetNetworkObjectKind, "name", targetNetworkObjectKey, "err", err) - if err != nil { - return err - } - } - - return nil -} - -// ReconcileGatewayPolicyReferences updates the annotations in the Gateway resources that list to all the policies -// that directly or indirectly target the gateway, based upon a pre-computed gateway diff object -func (r *TargetRefReconciler) ReconcileGatewayPolicyReferences(ctx context.Context, policy client.Object, gwDiffObj *GatewayDiffs) error { - logger, _ := logr.FromContext(ctx) - - // delete the policy from the annotations of the gateways no longer target by the policy - for _, gw := range gwDiffObj.GatewaysWithInvalidPolicyRef { - if gw.DeletePolicy(client.ObjectKeyFromObject(policy)) { - err := r.Client.Update(ctx, gw.Gateway) - logger.V(1).Info("ReconcileGatewayPolicyReferences: update gateway", "gateway with invalid policy ref", gw.Key(), "err", err) - if err != nil { - return err - } - } - } - - // add the policy to the annotations of the gateways target by the policy - for _, gw := range gwDiffObj.GatewaysMissingPolicyRef { - if gw.AddPolicy(client.ObjectKeyFromObject(policy)) { - err := r.Client.Update(ctx, gw.Gateway) - logger.V(1).Info("ReconcileGatewayPolicyReferences: update gateway", "gateway missing policy ref", gw.Key(), "err", err) - if err != nil { - return err - } - } - } - - return nil -} diff --git a/pkg/library/reconcilers/target_ref_reconciler_test.go b/pkg/library/reconcilers/target_ref_reconciler_test.go deleted file mode 100644 index 93057183a..000000000 --- a/pkg/library/reconcilers/target_ref_reconciler_test.go +++ /dev/null @@ -1,207 +0,0 @@ -//go:build unit - -package reconcilers - -import ( - "context" - "testing" - - "github.com/go-logr/logr" - appsv1 "k8s.io/api/apps/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/log" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" -) - -func TestReconcileTargetBackReference(t *testing.T) { - var ( - namespace = "operator-unittest" - routeName = "my-route" - annotationName = "some-annotation" - ) - baseCtx := context.Background() - ctx := logr.NewContext(baseCtx, log.Log) - - s := scheme.Scheme - err := appsv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - err = gatewayapiv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - - policy := &kuadrant.FakePolicy{ - Object: &metav1.PartialObjectMetadata{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-policy", - Namespace: "my-ns", - }, - }, - } - - existingRoute := &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1", - Kind: "HTTPRoute", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: routeName, - Namespace: namespace, - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "gwName", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "gwName", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - }, - }, - }, - } - - // Objects to track in the fake client. - objs := []runtime.Object{existingRoute} - - // Create a fake client to mock API calls. - cl := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - - targetRefReconciler := TargetRefReconciler{ - Client: cl, - } - - err = targetRefReconciler.ReconcileTargetBackReference(ctx, policy, existingRoute, annotationName) - if err != nil { - t.Fatal(err) - } - - res := &gatewayapiv1.HTTPRoute{} - err = cl.Get(ctx, client.ObjectKey{Name: routeName, Namespace: namespace}, res) - if err != nil { - t.Fatal(err) - } - - if len(res.GetAnnotations()) == 0 { - t.Fatal("annotations are empty") - } - - val, ok := res.GetAnnotations()[annotationName] - if !ok { - t.Fatal("expected annotation not found") - } - - if val != client.ObjectKeyFromObject(policy).String() { - t.Fatalf("annotation value (%s) does not match expected (%s)", val, client.ObjectKeyFromObject(policy).String()) - } -} - -func TestDeleteTargetBackReference(t *testing.T) { - var ( - namespace = "operator-unittest" - routeName = "my-route" - annotationName = "some-annotation" - ) - baseCtx := context.Background() - ctx := logr.NewContext(baseCtx, log.Log) - - s := scheme.Scheme - err := appsv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - err = gatewayapiv1.AddToScheme(s) - if err != nil { - t.Fatal(err) - } - - existingRoute := &gatewayapiv1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "gateway.networking.k8s.io/v1", - Kind: "HTTPRoute", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: routeName, - Namespace: namespace, - Annotations: map[string]string{ - annotationName: "annotationValue", - }, - }, - Spec: gatewayapiv1.HTTPRouteSpec{ - CommonRouteSpec: gatewayapiv1.CommonRouteSpec{ - ParentRefs: []gatewayapiv1.ParentReference{ - { - Name: "gwName", - }, - }, - }, - }, - Status: gatewayapiv1.HTTPRouteStatus{ - RouteStatus: gatewayapiv1.RouteStatus{ - Parents: []gatewayapiv1.RouteParentStatus{ - { - ParentRef: gatewayapiv1.ParentReference{ - Name: "gwName", - }, - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - }, - }, - }, - }, - }, - }, - } - - // Objects to track in the fake client. - objs := []runtime.Object{existingRoute} - - // Create a fake client to mock API calls. - cl := fake.NewClientBuilder().WithRuntimeObjects(objs...).Build() - targetRefReconciler := TargetRefReconciler{ - Client: cl, - } - - err = targetRefReconciler.DeleteTargetBackReference(ctx, existingRoute, annotationName) - if err != nil { - t.Fatal(err) - } - - res := &gatewayapiv1.HTTPRoute{} - err = cl.Get(ctx, client.ObjectKey{Name: routeName, Namespace: namespace}, res) - if err != nil { - t.Fatal(err) - } - - if len(res.GetAnnotations()) > 0 { - _, ok := res.GetAnnotations()[annotationName] - if ok { - t.Fatal("expected annotation found and it should have been deleted") - } - } -} diff --git a/pkg/library/utils/domains.go b/pkg/library/utils/domains.go deleted file mode 100644 index 178a21d39..000000000 --- a/pkg/library/utils/domains.go +++ /dev/null @@ -1,24 +0,0 @@ -package utils - -// ValidSubdomains returns (true, "") when every single subdomains item -// is a subset of at least one of the domains. -// Domains and subdomains may be prefixed with a wildcard label (*.). -// The wildcard label must appear by itself as the first label. -// When one of the subdomains is not a subset of the domains, it returns false and -// the subdomain not being subset of the domains -func ValidSubdomains(domains, subdomains []string) (bool, string) { - for _, subdomain := range subdomains { - validSubdomain := false - for _, domain := range domains { - if Name(subdomain).SubsetOf(Name(domain)) { - validSubdomain = true - break - } - } - - if !validSubdomain { - return false, subdomain - } - } - return true, "" -} diff --git a/pkg/library/utils/domains_test.go b/pkg/library/utils/domains_test.go deleted file mode 100644 index ca1d5cf09..000000000 --- a/pkg/library/utils/domains_test.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build unit - -package utils - -import "testing" - -func TestValidSubdomains(t *testing.T) { - testCases := []struct { - name string - domains []string - subdomains []string - expected bool - expectedHostname string - }{ - {"nil", nil, nil, true, ""}, - {"nil subdomains", []string{"*.example.com"}, nil, true, ""}, - {"nil domains", nil, []string{"*.example.com"}, false, "*.example.com"}, - {"dot matters", []string{"*.example.com"}, []string{"example.com"}, false, "example.com"}, - {"dot matters2", []string{"example.com"}, []string{"*.example.com"}, false, "*.example.com"}, - {"happy path", []string{"*.example.com", "*.net"}, []string{"*.other.net", "test.example.com"}, true, ""}, - {"not all match", []string{"*.example.com", "*.net"}, []string{"*.other.com", "*.example.com"}, false, "*.other.com"}, - {"wildcard in subdomains does not match", []string{"*.example.com", "*.net"}, []string{"*", "*.example.com"}, false, "*"}, - {"wildcard in domains matches all", []string{"*", "*.net"}, []string{"*.net", "*.example.com"}, true, ""}, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - valid, hostname := ValidSubdomains(tc.domains, tc.subdomains) - if valid != tc.expected { - subT.Errorf("expected (%t), got (%t)", tc.expected, valid) - } - if hostname != tc.expectedHostname { - subT.Errorf("expected hostname (%s), got (%s)", tc.expectedHostname, hostname) - } - }) - } -} diff --git a/pkg/library/utils/hostname_test.go b/pkg/library/utils/hostname_test.go deleted file mode 100644 index 836b66ed2..000000000 --- a/pkg/library/utils/hostname_test.go +++ /dev/null @@ -1,175 +0,0 @@ -//go:build unit - -package utils - -import ( - "reflect" - "sort" - "testing" - - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" -) - -func TestNameSubsetOf(t *testing.T) { - testCases := []struct { - name string - a string - b string - expected bool - }{ - {"equal hostnames", "foo.com", "foo.com", true}, - {"diff hostnames", "foo.com", "bar.com", false}, - {"wildcard hostname not subset of a hostname", "*.com", "foo.com", false}, - {"hostname subset of a wildcard hostname", "foo.com", "*.com", true}, - {"wildcard subdomain is not subset", "*.foo.com", "foo.com", false}, - {"hostname is not subset of wildcard subdomain", "foo.com", "*.foo.com", false}, - {"global wildcard is not subset of wildcard hostname", "*", "*.com", false}, - {"wildcard hostname is subset of global wildcard", "*.com", "*", true}, - {"wildcards with different TLDs", "*.com", "*.org", false}, - {"wildcards at different levels in domain hierarchy", "*.foo.com", "*.bar.foo.com", false}, - {"wildcards with subdomains", "*.foo.com", "*.baz.foo.com", false}, - {"empty hostnames", "", "", true}, - {"one empty hostname", "", "foo.com", false}, - {"multiple wildcards", "*.foo.*.com", "*.foo.*.com", true}, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := Name(tc.a).SubsetOf(Name(tc.b)) - if res != tc.expected { - subT.Errorf("expected (%t), got (%t)", tc.expected, res) - } - }) - } -} - -func TestIsWildCarded(t *testing.T) { - testCases := []struct { - name string - hostname Name - expected bool - }{ - {"when wildcard at beginning then return true", "*.example.com", true}, - {"when empty string then return false", "", false}, - {"when no wildcard then return false", "example.com", false}, - {"when wildcard in middle then return false", "subdomain.*.example.com", false}, - {"when wildcard at end then return false", "subdomain.example.*", false}, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := tc.hostname.IsWildCarded() - if res != tc.expected { - subT.Errorf("expected (%t) for hostname '%s', but got (%t)", tc.expected, tc.hostname, res) - } - }) - } -} - -func TestString(t *testing.T) { - testCases := []struct { - name string - actual Name - expected string - }{ - {"empty name", "", ""}, - {"non-empty name", "example.com", "example.com"}, - {"wildcarded name", "*.com", "*.com"}, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := tc.actual.String() - if res != tc.expected { - subT.Errorf("expected (%s), got (%s)", tc.expected, res) - } - }) - } -} - -func TestHostnamesToStrings(t *testing.T) { - testCases := []struct { - name string - inputHostnames []gatewayapiv1.Hostname - expectedOutput []string - }{ - { - name: "when input is empty then return empty output", - inputHostnames: []gatewayapiv1.Hostname{}, - expectedOutput: []string{}, - }, - { - name: "when input has a single precise hostname then return a single string", - inputHostnames: []gatewayapiv1.Hostname{"example.com"}, - expectedOutput: []string{"example.com"}, - }, - { - name: "when input has multiple precise hostnames then return the corresponding strings", - inputHostnames: []gatewayapiv1.Hostname{"example.com", "test.com", "localhost"}, - expectedOutput: []string{"example.com", "test.com", "localhost"}, - }, - { - name: "when input has a wildcard hostname then return the wildcard string", - inputHostnames: []gatewayapiv1.Hostname{"*.example.com"}, - expectedOutput: []string{"*.example.com"}, - }, - { - name: "when input has both precise and wildcard hostnames then return the corresponding strings", - inputHostnames: []gatewayapiv1.Hostname{"example.com", "*.test.com"}, - expectedOutput: []string{"example.com", "*.test.com"}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - output := HostnamesToStrings(tc.inputHostnames) - if !reflect.DeepEqual(tc.expectedOutput, output) { - t.Errorf("Unexpected output. Expected %v but got %v", tc.expectedOutput, output) - } - }) - } -} - -func TestSortableHostnames(t *testing.T) { - testCases := []struct { - name string - inputHostnames []string - expectedOutput []string - }{ - { - name: "when input is empty then return empty output", - inputHostnames: []string{}, - expectedOutput: []string{}, - }, - { - name: "when input has a single precise hostname then return the hostname", - inputHostnames: []string{"example.com"}, - expectedOutput: []string{"example.com"}, - }, - { - name: "when input has multiple precise hostnames then return the hostnames ordered lexicographically", - inputHostnames: []string{"example.com", "test.com", "localhost"}, - expectedOutput: []string{"example.com", "test.com", "localhost"}, - }, - { - name: "when input has precise and wildcard hostnames then return the hostnames ordered from most specific to least specific", - inputHostnames: []string{"*.com", "*.example.com", "*", "other.example.com"}, - expectedOutput: []string{"other.example.com", "*.example.com", "*.com", "*"}, - }, - { - name: "when input contains repeated hostnames then return the equal hostnames adjacent to each other", - inputHostnames: []string{"*.com", "other.example.com", "*.example.com", "*", "*.com", "*.example.com", "other.example.com"}, - expectedOutput: []string{"other.example.com", "other.example.com", "*.example.com", "*.example.com", "*.com", "*.com", "*"}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - hostnames := SortableHostnames(tc.inputHostnames) - sort.Sort(hostnames) - if !reflect.DeepEqual(tc.expectedOutput, tc.expectedOutput) { - t.Errorf("Unexpected output. Expected %v but got %v", tc.expectedOutput, tc.expectedOutput) - } - }) - } -} diff --git a/pkg/library/utils/k8s_utils_test.go b/pkg/library/utils/k8s_utils_test.go deleted file mode 100644 index 7d36a48a3..000000000 --- a/pkg/library/utils/k8s_utils_test.go +++ /dev/null @@ -1,953 +0,0 @@ -//go:build unit - -package utils - -import ( - "context" - "fmt" - "reflect" - "testing" - "time" - - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/intstr" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - dfake "k8s.io/client-go/dynamic/fake" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - - "github.com/kuadrant/limitador-operator/api/v1alpha1" -) - -func TestObjectKeyListDifference(t *testing.T) { - key1 := client.ObjectKey{Namespace: "ns1", Name: "obj1"} - key2 := client.ObjectKey{Namespace: "ns2", Name: "obj2"} - key3 := client.ObjectKey{Namespace: "ns3", Name: "obj3"} - key4 := client.ObjectKey{Namespace: "ns4", Name: "obj4"} - - testCases := []struct { - name string - a []client.ObjectKey - b []client.ObjectKey - expected []client.ObjectKey - }{ - { - "when both input slices are empty then return an empty slice", - []client.ObjectKey{}, - []client.ObjectKey{}, - []client.ObjectKey{}, - }, - { - "when inputA is empty and inputB has elements then return an empty slice", - []client.ObjectKey{}, - []client.ObjectKey{key1}, - []client.ObjectKey{}, - }, - { - "when inputA has elements and inputB is empty then return inputA as the result", - []client.ObjectKey{key1, key2}, - []client.ObjectKey{}, - []client.ObjectKey{key1, key2}, - }, - { - "when inputA and inputB are equal then return an empty slice", - []client.ObjectKey{key1, key2, key3}, - []client.ObjectKey{key1, key2, key3}, - []client.ObjectKey{}, - }, - { - "when inputA and inputB have common elements then return the difference", - []client.ObjectKey{key1, key2, key3}, - []client.ObjectKey{key1, key3}, - []client.ObjectKey{key2}, - }, - { - "when inputA and inputB have no common elements then return inputA as the result", - []client.ObjectKey{key1, key2}, - []client.ObjectKey{key3, key4}, - []client.ObjectKey{key1, key2}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - res := ObjectKeyListDifference(tc.a, tc.b) - if len(res) != len(tc.expected) { - subT.Errorf("expected len (%d), got (%d)", len(tc.expected), len(res)) - } - - for idx := range res { - if res[idx] != tc.expected[idx] { - subT.Errorf("expected object (index %d) does not match. Expected (%s), got (%s)", idx, tc.expected[idx], res[idx]) - } - } - }) - } -} - -func TestObjectInfo(t *testing.T) { - testCases := []struct { - name string - input client.Object - expected string - }{ - { - name: "when given a Kubernetes object then return formatted string", - input: &v1alpha1.Limitador{ - TypeMeta: metav1.TypeMeta{ - Kind: "Limitador", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "test-limitador", - }, - }, - expected: "Limitador/test-limitador", - }, - { - name: "when given a Kubernetes object with empty Kind then return formatted string", - input: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-service", - }, - }, - expected: "/test-service", - }, - { - name: "when given a Kubernetes object with empty Name then return formatted string", - input: &corev1.Namespace{ - TypeMeta: metav1.TypeMeta{ - Kind: "Namespace", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "", - }, - }, - expected: "Namespace/", - }, - { - name: "when given empty Kubernetes object then return formatted string (separator only)", - input: &corev1.Pod{}, - expected: "/", - }, - } - - for _, c := range testCases { - t.Run(c.name, func(t *testing.T) { - if actual := ObjectInfo(c.input); actual != c.expected { - t.Errorf("Expected %q, got %q", c.expected, actual) - } - }) - } -} - -func TestTagObjectToDelete(t *testing.T) { - testCases := []struct { - name string - input client.Object - expectedTags map[string]string - }{ - { - name: "when object has no annotations (nil) then initialize them with empty map and add 'delete' tag", - input: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-pod", - Annotations: nil, - }, - }, - expectedTags: map[string]string{ - DeleteTagAnnotation: "true", - }, - }, - { - name: "when object has empty annotations (empty map) then add 'delete' tag", - input: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-service", - Annotations: map[string]string{}, - }, - }, - expectedTags: map[string]string{ - DeleteTagAnnotation: "true", - }, - }, - { - name: "when object already has annotations then add 'delete' tag", - input: &v1alpha1.Limitador{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-service", - Annotations: map[string]string{ - "key1": "value1", - "key2": "value2", - }, - }, - }, - expectedTags: map[string]string{ - DeleteTagAnnotation: "true", - "key1": "value1", - "key2": "value2", - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - TagObjectToDelete(tc.input) - - annotations := tc.input.GetAnnotations() - if annotations == nil { - t.Fatal("Expected annotations to be not nil, but got nil") - } - - if !reflect.DeepEqual(annotations, tc.expectedTags) { - t.Errorf("Expected annotations to be '%v', but got '%v'", tc.expectedTags, annotations) - } - }) - } -} - -func TestIsObjectTaggedToDelete(t *testing.T) { - testCases := []struct { - name string - input client.Object - annotations map[string]string - expected bool - }{ - { - name: "when object has delete tag annotation set to true then return true", - input: &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - DeleteTagAnnotation: "true", - }, - }, - }, - expected: true, - }, - { - name: "when object has delete tag annotation set to false then return false", - input: &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - DeleteTagAnnotation: "false", - }, - }, - }, - expected: false, - }, - { - name: "when object has no delete tag annotation then return false", - input: &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{}, - }, - }, - expected: false, - }, - { - name: "when object annotations are nil then return false", - input: &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: nil, - }, - }, - expected: false, - }, - } - - for _, c := range testCases { - t.Run(c.name, func(t *testing.T) { - actual := IsObjectTaggedToDelete(c.input) - if actual != c.expected { - t.Errorf("Expected %v, but got %v", c.expected, actual) - } - }) - } -} - -func TestStatusConditionsMarshalJSON(t *testing.T) { - now := time.Now() - nowFmt := now.UTC().Format("2006-01-02T15:04:05Z") - - testCases := []struct { - name string - input []metav1.Condition - expected []byte - err error - }{ - { - name: "when input is empty then return an empty JSON array", - input: []metav1.Condition{}, - expected: []byte("[]"), - err: nil, - }, - { - name: "when input contains multiple conditions then return the sorted JSON array", - input: []metav1.Condition{ - { - Type: "ConditionB", - Status: metav1.ConditionFalse, - LastTransitionTime: metav1.Time{Time: now}, - Reason: "ReasonB", - Message: "MessageB", - }, - { - Type: "ConditionC", - Status: metav1.ConditionTrue, - LastTransitionTime: metav1.Time{Time: now}, - Reason: "ReasonC", - Message: "MessageC", - }, - { - Type: "ConditionA", - Status: metav1.ConditionTrue, - LastTransitionTime: metav1.Time{Time: now}, - Reason: "ReasonA", - Message: "MessageA", - }, - }, - expected: []byte(`[{"type":"ConditionA","status":"True","lastTransitionTime":"` + nowFmt + `","reason":"ReasonA","message":"MessageA"},{"type":"ConditionB","status":"False","lastTransitionTime":"` + nowFmt + `","reason":"ReasonB","message":"MessageB"},{"type":"ConditionC","status":"True","lastTransitionTime":"` + nowFmt + `","reason":"ReasonC","message":"MessageC"}]`), - err: nil, - }, - { - name: "when input contains condition with empty LastTransitionTime then return JSON with according null value", - input: []metav1.Condition{ - { - Type: "ConditionA", - Status: metav1.ConditionTrue, - Reason: "ReasonA", - Message: "MessageA", - }, - }, - expected: []byte(`[{"type":"ConditionA","status":"True","lastTransitionTime":null,"reason":"ReasonA","message":"MessageA"}]`), - err: nil, - }, - { - name: "when input contains condition with empty Type, Status, Reason and Message then return JSON with according empty values", - input: []metav1.Condition{ - { - LastTransitionTime: metav1.Time{Time: now}, - }, - }, - expected: []byte(`[{"type":"","status":"","lastTransitionTime":"` + nowFmt + `","reason":"","message":""}]`), - err: nil, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual, err := StatusConditionsMarshalJSON(tc.input) - if err != tc.err { - t.Errorf("unexpected error: got %v, want %v", err, tc.err) - } - - if !reflect.DeepEqual(actual, tc.expected) { - t.Errorf("unexpected result: got %s, want %s", string(actual), string(tc.expected)) - } - }) - } -} - -func TestIsOwnedBy(t *testing.T) { - testCases := []struct { - name string - owned client.Object - owner client.Object - expected bool - }{ - { - name: "when owned object has owner reference then return true", - owned: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "v1", - Kind: "Deployment", - Name: "my-deployment", - }, - }, - }, - }, - owner: &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-deployment", - }, - }, - expected: true, - }, - { - name: "when owned object does not have owner reference then return false", - owned: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{}, - }, - owner: &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-deployment", - }, - }, - expected: false, - }, - { - name: "when owned object has owner reference with different group then return false", - owned: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "apps/v1", - Kind: "Deployment", - Name: "my-deployment", - }, - }, - }, - }, - owner: &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-deployment", - }, - }, - expected: false, - }, - { - name: "when owned object has owner reference with different kind then return false", - owned: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "v1", - Kind: "StatefulSet", - Name: "my-deployment", - }, - }, - }, - }, - owner: &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-deployment", - }, - }, - expected: false, - }, - { - name: "when owned object has owner reference with different name then return false", - owned: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "v1", - Kind: "Deployment", - Name: "other-deployment", - }, - }, - }, - }, - owner: &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-deployment", - }, - }, - expected: false, - }, - { - name: "when owned object has owner reference and in same namespace then return true", - owned: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "ns1", - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "v1", - Kind: "Deployment", - Name: "my-deployment", - }, - }, - }, - }, - owner: &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-deployment", - Namespace: "ns1", - }, - }, - expected: true, - }, - { - name: "when owned object has owner reference but in different namespace then return false", - owned: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "ns1", - OwnerReferences: []metav1.OwnerReference{ - { - APIVersion: "v1", - Kind: "Deployment", - Name: "my-deployment", - }, - }, - }, - }, - owner: &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - APIVersion: "v1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "my-deployment", - Namespace: "ns2", - }, - }, - expected: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual := IsOwnedBy(tc.owned, tc.owner) - if actual != tc.expected { - t.Errorf("unexpected result: got %v, want %v", actual, tc.expected) - } - }) - } -} - -func TestGetServicePortNumber(t *testing.T) { - ctx := context.TODO() - k8sClient := fake.NewClientBuilder().Build() - - tests := []struct { - name string - servicePort string - expected int32 - service *corev1.Service - serviceKey client.ObjectKey - expectedErr error - }{ - { - name: "when port is already a number then return the number", - servicePort: "8080", - expected: 8080, - serviceKey: client.ObjectKey{Name: "my-service1", Namespace: "default"}, - }, - { - name: "when port is a named existing port then return the target port", - servicePort: "http", - expected: 8080, - service: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "my-service2", Namespace: "default"}, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "http", - Port: 80, - TargetPort: intstr.FromInt32(8080), - }, - }, - }, - }, - serviceKey: client.ObjectKey{Name: "my-service2", Namespace: "default"}, - }, - { - name: "when port not found then return an error", - servicePort: "unknown", - expectedErr: fmt.Errorf("service port unknown was not found in default/my-service3"), - service: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "my-service3", Namespace: "default"}, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "http", - Port: 80, - TargetPort: intstr.FromInt32(8080), - }, - }, - }, - }, - serviceKey: client.ObjectKey{Name: "my-service3", Namespace: "default"}, - }, - { - name: "when service not found then return an error", - servicePort: "http", - expectedErr: fmt.Errorf("services \"my-service4\" not found"), - expected: 0, - serviceKey: client.ObjectKey{Name: "my-service4", Namespace: "default"}, - }, - { - name: "when multiple ports exist and the port is found then return the target port", - servicePort: "http2", - expected: 8090, - service: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "my-service5", Namespace: "default"}, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "http1", - Port: 8080, - TargetPort: intstr.FromInt32(8080), - }, - { - Name: "http2", - Port: 8090, - TargetPort: intstr.FromInt32(8090), - }, - { - Name: "http3", - Port: 8100, - TargetPort: intstr.FromInt32(8100), - }, - }, - }, - }, - serviceKey: client.ObjectKey{Name: "my-service5", Namespace: "default"}, - }, - { - name: "when multiple ports exist and the port is not found then return an error", - servicePort: "https2", - expectedErr: fmt.Errorf("service port https2 was not found in default/my-service6"), - service: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "my-service6", Namespace: "default"}, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "http1", - Port: 8080, - TargetPort: intstr.FromInt32(8080), - }, - { - Name: "http2", - Port: 8090, - TargetPort: intstr.FromInt32(8090), - }, - { - Name: "http3", - Port: 8100, - TargetPort: intstr.FromInt32(8100), - }, - }, - }, - }, - serviceKey: client.ObjectKey{Name: "my-service6", Namespace: "default"}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.service != nil { - err := k8sClient.Create(ctx, tt.service) - if err != nil { - t.Fatalf("failed to create service: %v", err) - } - } - - portNumber, err := GetServicePortNumber(ctx, k8sClient, tt.serviceKey, tt.servicePort) - - if err != nil && tt.expectedErr == nil { - t.Errorf("unexpected error: %v", err) - } - if err == nil && tt.expectedErr != nil { - t.Error("expected an error, but got nil") - } - if err != nil && tt.expectedErr != nil && err.Error() != tt.expectedErr.Error() { - t.Errorf("unexpected error: got %v, want %v", err, tt.expectedErr) - } - - if portNumber != tt.expected { - t.Errorf("unexpected port number: got %d, want %d", portNumber, tt.expected) - } - }) - } -} - -func TestFindObjectKey(t *testing.T) { - key1 := client.ObjectKey{Namespace: "ns1", Name: "obj1"} - key2 := client.ObjectKey{Namespace: "ns2", Name: "obj2"} - key3 := client.ObjectKey{Namespace: "ns3", Name: "obj3"} - - testCases := []struct { - name string - list []client.ObjectKey - key client.ObjectKey - expected int - }{ - { - name: "when input slice has one search ObjectKey then return its index", - list: []client.ObjectKey{key1, key2, key3}, - key: key2, - expected: 1, - }, - { - name: "when input slice has no search ObjectKey then return length of input slice", - list: []client.ObjectKey{key1, key3}, - key: key2, - expected: 2, - }, - { - name: "when input slice is empty then return 0", - list: []client.ObjectKey{}, - key: key1, - expected: 0, - }, - { - name: "when there are multiple occurrences of the search ObjectKey then return the index of first occurrence", - list: []client.ObjectKey{key1, key2, key1, key3}, - key: key2, - expected: 1, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if output := FindObjectKey(tc.list, tc.key); output != tc.expected { - t.Errorf("expected %d but got %d", tc.expected, output) - } - }) - } -} - -func TestFindDeploymentStatusCondition(t *testing.T) { - tests := []struct { - name string - conditions []appsv1.DeploymentCondition - conditionType string - expected *appsv1.DeploymentCondition - }{ - { - name: "when search condition exists then return the condition", - conditions: []appsv1.DeploymentCondition{ - { - Type: appsv1.DeploymentConditionType("Ready"), - Status: corev1.ConditionTrue, - }, - { - Type: appsv1.DeploymentConditionType("Progressing"), - Status: corev1.ConditionFalse, - }, - }, - conditionType: "Ready", - expected: &appsv1.DeploymentCondition{ - Type: appsv1.DeploymentConditionType("Ready"), - Status: corev1.ConditionTrue, - }, - }, - { - name: "when search condition does not exist then return nil", - conditions: []appsv1.DeploymentCondition{ - { - Type: appsv1.DeploymentConditionType("Progressing"), - Status: corev1.ConditionFalse, - }, - }, - conditionType: "Ready", - expected: nil, - }, - { - name: "when conditions slice is empty then return nil", - conditions: []appsv1.DeploymentCondition{}, - conditionType: "Ready", - expected: nil, - }, - { - name: "when multiple conditions have the same type then return the first occurrence", - conditions: []appsv1.DeploymentCondition{ - { - Type: appsv1.DeploymentConditionType("Ready"), - Status: corev1.ConditionTrue, - }, - { - Type: appsv1.DeploymentConditionType("Progressing"), - Status: corev1.ConditionTrue, - }, - { - Type: appsv1.DeploymentConditionType("Ready"), - Status: corev1.ConditionFalse, - }, - }, - conditionType: "Ready", - expected: &appsv1.DeploymentCondition{ - Type: appsv1.DeploymentConditionType("Ready"), - Status: corev1.ConditionTrue, - }, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - actual := FindDeploymentStatusCondition(tc.conditions, tc.conditionType) - if !reflect.DeepEqual(actual, tc.expected) { - t.Errorf("unexpected result: got %s, want %s", actual.String(), tc.expected.String()) - } - }) - } -} - -func TestHasLabel(t *testing.T) { - testCases := []struct { - name string - obj metav1.Object - label string - expect bool - }{ - { - name: "existing label found", - obj: &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-object", - Labels: map[string]string{ - "test-key": "value", - }, - }, - }, - label: "test-key", - expect: true, - }, - { - name: "existing label not found", - obj: &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-object", - Labels: map[string]string{ - "test-fail": "value", - }, - }, - }, - label: "test-key", - expect: false, - }, - { - name: "no labels", - obj: &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-object", - Labels: nil, - }, - }, - label: "test-key", - expect: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - got := HasLabel(tc.obj, tc.label) - if got != tc.expect { - t.Errorf("expected '%v' got '%v'", tc.expect, got) - } - }) - } -} - -func TestGetLabel(t *testing.T) { - testCases := []struct { - name string - obj metav1.Object - label string - expect string - }{ - { - name: "existing label found", - obj: &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-object", - Labels: map[string]string{ - "test-key": "value", - }, - }, - }, - label: "test-key", - expect: "value", - }, - { - name: "existing label not found", - obj: &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-object", - Labels: map[string]string{ - "test-fail": "value", - }, - }, - }, - label: "test-key", - expect: "", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - got := GetLabel(tc.obj, tc.label) - if got != tc.expect { - t.Errorf("expected '%v' got '%v'", tc.expect, got) - } - }) - } -} - -func TestGetClusterUID(t *testing.T) { - var tScheme = runtime.NewScheme() - utilruntime.Must(corev1.AddToScheme(tScheme)) - - var testCases = []struct { - Name string - Objects []runtime.Object - Validation func(t *testing.T, e error, id string) - }{ - { - Name: "an absent namespace generates an error", - Objects: []runtime.Object{}, - Validation: func(t *testing.T, e error, id string) { - if !errors.IsNotFound(e) { - t.Errorf("expected not found error, got '%v'", e) - } - }, - }, - { - Name: "a UID generates a valid deterministic cluster ID", - Objects: []runtime.Object{ - &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: clusterIDNamespace, - UID: "random-uid", - }, - }, - }, - Validation: func(t *testing.T, e error, id string) { - if e != nil { - t.Errorf("unexpected error, got '%v', expected nil", e) - } - - if id != "random-uid" { - t.Errorf("unexpected cluster ID got '%s', expected 'random-uid'", id) - } - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.Name, func(t *testing.T) { - fc := dfake.NewSimpleDynamicClient(tScheme, testCase.Objects...) - id, err := GetClusterUID(context.Background(), fc) - testCase.Validation(t, err, id) - }) - } -} diff --git a/pkg/library/utils/object_utils.go b/pkg/library/utils/object_utils.go deleted file mode 100644 index 950fb0870..000000000 --- a/pkg/library/utils/object_utils.go +++ /dev/null @@ -1,26 +0,0 @@ -package utils - -import ( - "strings" - - "sigs.k8s.io/controller-runtime/pkg/client" -) - -// NamespacedNameToObjectKey converts format string to k8s object key. -// It's common for K8s to reference an object using this format. For e.g. gateways in VirtualService. -func NamespacedNameToObjectKey(namespacedName, defaultNamespace string) client.ObjectKey { - if i := strings.IndexRune(namespacedName, '/'); i >= 0 { - return client.ObjectKey{Namespace: namespacedName[:i], Name: namespacedName[i+1:]} - } - return client.ObjectKey{Namespace: defaultNamespace, Name: namespacedName} -} - -// ReadAnnotationsFromObject reads the annotations from a Kubernetes object -// and returns them as a map. If the object has no annotations, it returns an empty map. -func ReadAnnotationsFromObject(obj client.Object) map[string]string { - annotations := obj.GetAnnotations() - if annotations == nil { - annotations = map[string]string{} - } - return annotations -} diff --git a/pkg/library/utils/object_utils_test.go b/pkg/library/utils/object_utils_test.go deleted file mode 100644 index b34d4583c..000000000 --- a/pkg/library/utils/object_utils_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package utils - -import ( - "reflect" - "testing" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func TestNamespacedNameToObjectKey(t *testing.T) { - t.Run("when a namespaced name is provided then return an ObjectKey with corresponding namespace and name", func(t *testing.T) { - namespacedName := "test-namespace/test-name" - defaultNamespace := "default" - - result := NamespacedNameToObjectKey(namespacedName, defaultNamespace) - - expected := client.ObjectKey{Name: "test-name", Namespace: "test-namespace"} - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, but got %v", expected, result) - } - }) - - t.Run("when only a name is provided then return an ObjectKey with the default namespace and provided name", func(t *testing.T) { - namespacedName := "test-name" - defaultNamespace := "default" - - result := NamespacedNameToObjectKey(namespacedName, defaultNamespace) - - expected := client.ObjectKey{Name: "test-name", Namespace: "default"} - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, but got %v", expected, result) - } - }) - - t.Run("when an empty string is provided, then return an ObjectKey with default namespace and empty name", func(t *testing.T) { - namespacedName := "" - defaultNamespace := "default" - - result := NamespacedNameToObjectKey(namespacedName, defaultNamespace) - - expected := client.ObjectKey{Name: "", Namespace: "default"} - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, but got %v", expected, result) - } - }) -} - -func TestReadAnnotationsFromObject(t *testing.T) { - testCases := []struct { - name string - input client.Object - expected map[string]string - }{ - { - name: "when object has annotations then return the annotations", - input: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - "key1": "value1", - "key2": "value2", - }, - }, - }, - expected: map[string]string{ - "key1": "value1", - "key2": "value2", - }, - }, - { - name: "when object has no annotations then return an empty map", - input: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{}, - }, - expected: map[string]string{}, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - actual := ReadAnnotationsFromObject(tc.input) - if !reflect.DeepEqual(actual, tc.expected) { - t.Errorf("Expected annotations %v, but got %v", tc.expected, actual) - } - }) - } -} diff --git a/pkg/library/utils/service.go b/pkg/library/utils/service.go deleted file mode 100644 index 1073ec7e9..000000000 --- a/pkg/library/utils/service.go +++ /dev/null @@ -1,50 +0,0 @@ -package utils - -import ( - "context" - "fmt" - "strconv" - - corev1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -func GetServiceWorkloadSelector(ctx context.Context, k8sClient client.Client, serviceKey client.ObjectKey) (map[string]string, error) { - service, err := GetService(ctx, k8sClient, serviceKey) - if err != nil { - return nil, err - } - return service.Spec.Selector, nil -} - -func GetService(ctx context.Context, k8sClient client.Client, serviceKey client.ObjectKey) (*corev1.Service, error) { - service := &corev1.Service{} - if err := k8sClient.Get(ctx, serviceKey, service); err != nil { - return nil, err - } - return service, nil -} - -// GetServicePortNumber returns the port number from the referenced key and port info -// the port info can be named port or already a number. -func GetServicePortNumber(ctx context.Context, k8sClient client.Client, serviceKey client.ObjectKey, servicePort string) (int32, error) { - // check if the port is a number already. - if num, err := strconv.ParseInt(servicePort, 10, 32); err == nil { - return int32(num), nil - } - - // As the port is name, resolv the port from the service - service, err := GetService(ctx, k8sClient, serviceKey) - if err != nil { - // the service must exist - return 0, err - } - - for _, p := range service.Spec.Ports { - if p.Name == servicePort { - return int32(p.TargetPort.IntValue()), nil - } - } - - return 0, fmt.Errorf("service port %s was not found in %s", servicePort, serviceKey.String()) -} diff --git a/pkg/library/utils/service_test.go b/pkg/library/utils/service_test.go deleted file mode 100644 index 901a8a6ee..000000000 --- a/pkg/library/utils/service_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package utils - -import ( - "context" - "testing" - - corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -func TestGetService(t *testing.T) { - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "svc-ns", - Name: "my-svc", - Labels: map[string]string{ - "a-label": "irrelevant", - }, - }, - Spec: corev1.ServiceSpec{ - Selector: map[string]string{ - "a-selector": "what-we-are-looking-for", - }, - }, - } - - k8sClient := fake.NewClientBuilder().WithRuntimeObjects(service).Build() - - var svc *corev1.Service - var err error - - svc, err = GetService(context.TODO(), k8sClient, client.ObjectKey{Namespace: "svc-ns", Name: "my-svc"}) - if err != nil || svc == nil || svc.GetNamespace() != service.GetNamespace() || svc.GetName() != service.GetName() { - t.Error("should have gotten Service svc-ns/my-svc") - } - - svc, err = GetService(context.TODO(), k8sClient, client.ObjectKey{Namespace: "svc-ns", Name: "unknown"}) - if err == nil || !apierrors.IsNotFound(err) || svc != nil { - t.Error("should have gotten no Service") - } -} - -func TestGetServiceWorkloadSelector(t *testing.T) { - service := &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: "svc-ns", - Name: "my-svc", - Labels: map[string]string{ - "a-label": "irrelevant", - }, - }, - Spec: corev1.ServiceSpec{ - Selector: map[string]string{ - "a-selector": "what-we-are-looking-for", - }, - }, - } - - k8sClient := fake.NewClientBuilder().WithRuntimeObjects(service).Build() - - var selector map[string]string - var err error - - selector, err = GetServiceWorkloadSelector(context.TODO(), k8sClient, client.ObjectKey{Namespace: "svc-ns", Name: "my-svc"}) - if err != nil || len(selector) != 1 || selector["a-selector"] != "what-we-are-looking-for" { - t.Error("should not have failed to get the service workload selector") - } - - selector, err = GetServiceWorkloadSelector(context.TODO(), k8sClient, client.ObjectKey{Namespace: "svc-ns", Name: "unknown-svc"}) - if err == nil || !apierrors.IsNotFound(err) || selector != nil { - t.Error("should have failed to get the service workload selector") - } -} diff --git a/pkg/library/utils/slice_utils_test.go b/pkg/library/utils/slice_utils_test.go deleted file mode 100644 index feb4063dc..000000000 --- a/pkg/library/utils/slice_utils_test.go +++ /dev/null @@ -1,318 +0,0 @@ -package utils - -import ( - "reflect" - "testing" -) - -func TestFind(t *testing.T) { - s := []string{"a", "ab", "abc"} - - if r, found := Find(s, func(el string) bool { return el == "ab" }); !found || r == nil || *r != "ab" { - t.Error("should have found 'ab' in the slice") - } - - if r, found := Find(s, func(el string) bool { return len(el) <= 3 }); !found || r == nil || *r != "a" { - t.Error("should have found 'a' in the slice") - } - - if r, found := Find(s, func(el string) bool { return len(el) >= 3 }); !found || r == nil || *r != "abc" { - t.Error("should have found 'abc' in the slice") - } - - if r, found := Find(s, func(el string) bool { return len(el) == 4 }); found || r != nil { - t.Error("should not have found anything in the slice") - } - - i := []int{1, 2, 3} - - if r, found := Find(i, func(el int) bool { return el/3 == 1 }); !found || r == nil || *r != 3 { - t.Error("should have found 3 in the slice") - } - - if r, found := Find(i, func(el int) bool { return el == 75 }); found || r != nil { - t.Error("should not have found anything in the slice") - } -} - -func TestGetEmptySliceIfNil(t *testing.T) { - t.Run("when a non-nil slice is provided then return same slice", func(t *testing.T) { - value := []int{1, 2, 3} - expected := value - - result := GetEmptySliceIfNil(value) - - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, but got %v", expected, result) - } - }) - - t.Run("when a nil slice is provided then return an empty slice of the same type", func(t *testing.T) { - var value []int - expected := []int{} - - result := GetEmptySliceIfNil(value) - - if !reflect.DeepEqual(result, expected) { - t.Errorf("Expected %v, but got %v", expected, result) - } - }) -} - -func TestSameElements(t *testing.T) { - testCases := []struct { - name string - slice1 []string - slice2 []string - expected bool - }{ - { - name: "when slice1 and slice2 contain the same elements then return true", - slice1: []string{"test-gw1", "test-gw2", "test-gw3"}, - slice2: []string{"test-gw1", "test-gw2", "test-gw3"}, - expected: true, - }, - { - name: "when slice1 and slice2 contain unique elements then return false", - slice1: []string{"test-gw1", "test-gw2"}, - slice2: []string{"test-gw1", "test-gw3"}, - expected: false, - }, - { - name: "when both slices are empty then return true", - slice1: []string{}, - slice2: []string{}, - expected: true, - }, - { - name: "when both slices are nil then return true", - expected: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if SameElements(tc.slice1, tc.slice2) != tc.expected { - t.Errorf("when slice1=%v and slice2=%v, expected=%v, but got=%v", tc.slice1, tc.slice2, tc.expected, !tc.expected) - } - }) - } -} - -func TestIntersect(t *testing.T) { - testCases := []struct { - name string - slice1 []string - slice2 []string - expected bool - }{ - { - name: "when slice1 and slice2 have one common item then return true", - slice1: []string{"test-gw1", "test-gw2"}, - slice2: []string{"test-gw1", "test-gw3", "test-gw4"}, - expected: true, - }, - { - name: "when slice1 and slice2 have no common item then return false", - slice1: []string{"test-gw1", "test-gw2"}, - slice2: []string{"test-gw3", "test-gw4"}, - expected: false, - }, - { - name: "when slice1 is empty then return false", - slice1: []string{}, - slice2: []string{"test-gw3", "test-gw4"}, - expected: false, - }, - { - name: "when slice2 is empty then return false", - slice1: []string{"test-gw1", "test-gw2"}, - slice2: []string{}, - expected: false, - }, - { - name: "when both slices are empty then return false", - slice1: []string{}, - slice2: []string{}, - expected: false, - }, - { - name: "when slice1 is nil then return false", - slice2: []string{"test-gw3", "test-gw4"}, - expected: false, - }, - { - name: "when slice2 is nil then return false", - slice1: []string{"test-gw1", "test-gw2"}, - expected: false, - }, - { - name: "when both slices are nil then return false", - expected: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if Intersect(tc.slice1, tc.slice2) != tc.expected { - t.Errorf("when slice1=%v and slice2=%v, expected=%v, but got=%v", tc.slice1, tc.slice2, tc.expected, !tc.expected) - } - }) - } -} - -func TestIntersectWithInts(t *testing.T) { - testCases := []struct { - name string - slice1 []int - slice2 []int - expected bool - }{ - { - name: "when slice1 and slice2 have one common item then return true", - slice1: []int{1, 2}, - slice2: []int{1, 3, 4}, - expected: true, - }, - { - name: "when slice1 and slice2 have no common item then return false", - slice1: []int{1, 2}, - slice2: []int{3, 4}, - expected: false, - }, - { - name: "when slice1 is empty then return false", - slice1: []int{}, - slice2: []int{3, 4}, - expected: false, - }, - { - name: "when slice2 is empty then return false", - slice1: []int{1, 2}, - slice2: []int{}, - expected: false, - }, - { - name: "when both slices are empty then return false", - slice1: []int{}, - slice2: []int{}, - expected: false, - }, - { - name: "when slice1 is nil then return false", - slice2: []int{3, 4}, - expected: false, - }, - { - name: "when slice2 is nil then return false", - slice1: []int{1, 2}, - expected: false, - }, - { - name: "when both slices are nil then return false", - expected: false, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if Intersect(tc.slice1, tc.slice2) != tc.expected { - t.Errorf("when slice1=%v and slice2=%v, expected=%v, but got=%v", tc.slice1, tc.slice2, tc.expected, !tc.expected) - } - }) - } -} - -func TestIntersection(t *testing.T) { - testCases := []struct { - name string - slice1 []string - slice2 []string - expected []string - }{ - { - name: "when slice1 and slice2 have one common item then return that item", - slice1: []string{"test-gw1", "test-gw2"}, - slice2: []string{"test-gw1", "test-gw3", "test-gw4"}, - expected: []string{"test-gw1"}, - }, - { - name: "when slice1 and slice2 have no common item then return nil", - slice1: []string{"test-gw1", "test-gw2"}, - slice2: []string{"test-gw3", "test-gw4"}, - expected: nil, - }, - { - name: "when slice1 is empty then return nil", - slice1: []string{}, - slice2: []string{"test-gw3", "test-gw4"}, - expected: nil, - }, - { - name: "when slice2 is empty then return nil", - slice1: []string{"test-gw1", "test-gw2"}, - slice2: []string{}, - expected: nil, - }, - { - name: "when both slices are empty then return nil", - slice1: []string{}, - slice2: []string{}, - expected: nil, - }, - { - name: "when slice1 is nil then return nil", - slice2: []string{"test-gw3", "test-gw4"}, - expected: nil, - }, - { - name: "when slice2 is nil then return nil", - slice1: []string{"test-gw1", "test-gw2"}, - expected: nil, - }, - { - name: "when both slices are nil then return nil", - expected: nil, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - if r := Intersection(tc.slice1, tc.slice2); !reflect.DeepEqual(r, tc.expected) { - t.Errorf("expected=%v; got=%v", tc.expected, r) - } - }) - } -} - -func TestMap(t *testing.T) { - slice1 := []int{1, 2, 3, 4} - f1 := func(x int) int { return x + 1 } - expected1 := []int{2, 3, 4, 5} - result1 := Map(slice1, f1) - t.Run("when mapping an int slice with an increment function then return new slice with the incremented values", func(t *testing.T) { - if !reflect.DeepEqual(result1, expected1) { - t.Errorf("result1 = %v; expected %v", result1, expected1) - } - }) - - slice2 := []string{"hello", "world", "buz", "a"} - f2 := func(s string) int { return len(s) } - expected2 := []int{5, 5, 3, 1} - result2 := Map(slice2, f2) - t.Run("when mapping a string slice with string->int mapping then return new slice with the mapped values", func(t *testing.T) { - if !reflect.DeepEqual(result2, expected2) { - t.Errorf("result2 = %v; expected %v", result2, expected2) - } - }) - - slice3 := []int{} - f3 := func(x int) float32 { return float32(x) / 2 } - expected3 := []float32{} - result3 := Map(slice3, f3) - t.Run("when mapping an empty int slice then return an empty slice", func(t *testing.T) { - if !reflect.DeepEqual(result3, expected3) { - t.Errorf("result3 = %v; expected %v", result3, expected3) - } - }) -} diff --git a/pkg/openshift/utils.go b/pkg/openshift/utils.go index b9f1827de..7c938f73b 100644 --- a/pkg/openshift/utils.go +++ b/pkg/openshift/utils.go @@ -5,7 +5,7 @@ import ( "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/runtime/schema" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) var ( diff --git a/pkg/common/policy_machinery_helpers.go b/pkg/policymachinery/utils.go similarity index 98% rename from pkg/common/policy_machinery_helpers.go rename to pkg/policymachinery/utils.go index ccf096e2f..40991618a 100644 --- a/pkg/common/policy_machinery_helpers.go +++ b/pkg/policymachinery/utils.go @@ -1,6 +1,6 @@ // TODO: Move to github.com/kuadrant/policy-machinery -package common +package policymachinery import ( "fmt" @@ -12,7 +12,7 @@ import ( "k8s.io/utils/ptr" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) func NewErrInvalidPath(message string) error { diff --git a/pkg/common/policy_machinery_helpers_test.go b/pkg/policymachinery/utils_test.go similarity index 99% rename from pkg/common/policy_machinery_helpers_test.go rename to pkg/policymachinery/utils_test.go index 2a7992edb..83f0a1989 100644 --- a/pkg/common/policy_machinery_helpers_test.go +++ b/pkg/policymachinery/utils_test.go @@ -1,6 +1,6 @@ //go:build unit -package common +package policymachinery import ( "testing" diff --git a/pkg/ratelimit/index.go b/pkg/ratelimit/index.go index fbfa38727..7be6d0773 100644 --- a/pkg/ratelimit/index.go +++ b/pkg/ratelimit/index.go @@ -9,7 +9,7 @@ import ( "github.com/elliotchance/orderedmap/v2" limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) // NewIndex builds an index to manage sets of rate limits, organized by key diff --git a/pkg/library/reconcilers/base_mutator.go b/pkg/reconcilers/base_mutator.go similarity index 100% rename from pkg/library/reconcilers/base_mutator.go rename to pkg/reconcilers/base_mutator.go diff --git a/pkg/library/reconcilers/base_reconciler.go b/pkg/reconcilers/base_reconciler.go similarity index 88% rename from pkg/library/reconcilers/base_reconciler.go rename to pkg/reconcilers/base_reconciler.go index bf4d73f56..bb27b103e 100644 --- a/pkg/library/reconcilers/base_reconciler.go +++ b/pkg/reconcilers/base_reconciler.go @@ -30,7 +30,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/reconcile" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) type StatusMeta struct { @@ -238,35 +238,3 @@ func (b *BaseReconciler) RemoveFinalizer(ctx context.Context, obj client.Object, } return nil } - -// SetOwnerReference sets owner as a Controller OwnerReference on owned -func (b *BaseReconciler) SetOwnerReference(owner, obj client.Object) error { - err := controllerutil.SetControllerReference(owner, obj, b.Scheme()) - if err != nil { - b.Logger().Error(err, "Error setting OwnerReference on object", - "Kind", obj.GetObjectKind().GroupVersionKind().String(), - "Namespace", obj.GetNamespace(), - "Name", obj.GetName(), - ) - } - return err -} - -// EnsureOwnerReference sets owner as a Controller OwnerReference on owned -// returns boolean to notify when the object has been updated -func (b *BaseReconciler) EnsureOwnerReference(owner, obj client.Object) (bool, error) { - changed := false - - originalSize := len(obj.GetOwnerReferences()) - err := b.SetOwnerReference(owner, obj) - if err != nil { - return false, err - } - - newSize := len(obj.GetOwnerReferences()) - if originalSize != newSize { - changed = true - } - - return changed, nil -} diff --git a/pkg/library/reconcilers/base_reconciler_test.go b/pkg/reconcilers/base_reconciler_test.go similarity index 99% rename from pkg/library/reconcilers/base_reconciler_test.go rename to pkg/reconcilers/base_reconciler_test.go index 90ad7d161..2d24762af 100644 --- a/pkg/library/reconcilers/base_reconciler_test.go +++ b/pkg/reconcilers/base_reconciler_test.go @@ -35,8 +35,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" "github.com/kuadrant/kuadrant-operator/pkg/log" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) func TestMain(m *testing.M) { diff --git a/pkg/library/reconcilers/deployment.go b/pkg/reconcilers/deployment.go similarity index 100% rename from pkg/library/reconcilers/deployment.go rename to pkg/reconcilers/deployment.go diff --git a/pkg/utils/base36.go b/pkg/utils/base36.go new file mode 100644 index 000000000..04b925527 --- /dev/null +++ b/pkg/utils/base36.go @@ -0,0 +1,18 @@ +package utils + +import ( + "crypto/sha256" + "strings" + + "github.com/martinlindhe/base36" +) + +func ToBase36Hash(s string) string { + hash := sha256.Sum224([]byte(s)) + // convert the hash to base36 (alphanumeric) to decrease collision probabilities + return strings.ToLower(base36.EncodeBytes(hash[:])) +} + +func ToBase36HashLen(s string, l int) string { + return ToBase36Hash(s)[:l] +} diff --git a/pkg/library/utils/crd.go b/pkg/utils/crd.go similarity index 100% rename from pkg/library/utils/crd.go rename to pkg/utils/crd.go diff --git a/pkg/library/utils/hostname.go b/pkg/utils/hostname.go similarity index 67% rename from pkg/library/utils/hostname.go rename to pkg/utils/hostname.go index af6ff7a11..ed0e10e19 100644 --- a/pkg/library/utils/hostname.go +++ b/pkg/utils/hostname.go @@ -4,9 +4,6 @@ package utils import ( "strings" - - "github.com/kuadrant/authorino/pkg/utils" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" ) // Name describes a (possibly wildcarded) hostname @@ -47,20 +44,6 @@ func (n Name) String() string { return string(n) } -// HostnamesToStrings converts []gatewayapiv1.Hostname to []string -func HostnamesToStrings(hostnames []gatewayapiv1.Hostname) []string { - return utils.Map(hostnames, func(hostname gatewayapiv1.Hostname) string { - return string(hostname) - }) -} - -// SortableHostnames is a slice of hostnames that can be sorted from the most specific to the least specific -type SortableHostnames []string - -func (h SortableHostnames) Len() int { return len(h) } -func (h SortableHostnames) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h SortableHostnames) Less(i, j int) bool { return CompareHostnamesSpecificity(h[i], h[j]) } - // CompareHostnamesSpecificity returns true if hostname1 is more specific than hostname2 func CompareHostnamesSpecificity(hostname1, hostname2 string) bool { labels1 := len(strings.Split(hostname1, ".")) diff --git a/pkg/utils/hostname_test.go b/pkg/utils/hostname_test.go new file mode 100644 index 000000000..f5478d351 --- /dev/null +++ b/pkg/utils/hostname_test.go @@ -0,0 +1,84 @@ +//go:build unit + +package utils + +import ( + "testing" +) + +func TestNameSubsetOf(t *testing.T) { + testCases := []struct { + name string + a string + b string + expected bool + }{ + {"equal hostnames", "foo.com", "foo.com", true}, + {"diff hostnames", "foo.com", "bar.com", false}, + {"wildcard hostname not subset of a hostname", "*.com", "foo.com", false}, + {"hostname subset of a wildcard hostname", "foo.com", "*.com", true}, + {"wildcard subdomain is not subset", "*.foo.com", "foo.com", false}, + {"hostname is not subset of wildcard subdomain", "foo.com", "*.foo.com", false}, + {"global wildcard is not subset of wildcard hostname", "*", "*.com", false}, + {"wildcard hostname is subset of global wildcard", "*.com", "*", true}, + {"wildcards with different TLDs", "*.com", "*.org", false}, + {"wildcards at different levels in domain hierarchy", "*.foo.com", "*.bar.foo.com", false}, + {"wildcards with subdomains", "*.foo.com", "*.baz.foo.com", false}, + {"empty hostnames", "", "", true}, + {"one empty hostname", "", "foo.com", false}, + {"multiple wildcards", "*.foo.*.com", "*.foo.*.com", true}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(subT *testing.T) { + res := Name(tc.a).SubsetOf(Name(tc.b)) + if res != tc.expected { + subT.Errorf("expected (%t), got (%t)", tc.expected, res) + } + }) + } +} + +func TestIsWildCarded(t *testing.T) { + testCases := []struct { + name string + hostname Name + expected bool + }{ + {"when wildcard at beginning then return true", "*.example.com", true}, + {"when empty string then return false", "", false}, + {"when no wildcard then return false", "example.com", false}, + {"when wildcard in middle then return false", "subdomain.*.example.com", false}, + {"when wildcard at end then return false", "subdomain.example.*", false}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(subT *testing.T) { + res := tc.hostname.IsWildCarded() + if res != tc.expected { + subT.Errorf("expected (%t) for hostname '%s', but got (%t)", tc.expected, tc.hostname, res) + } + }) + } +} + +func TestString(t *testing.T) { + testCases := []struct { + name string + actual Name + expected string + }{ + {"empty name", "", ""}, + {"non-empty name", "example.com", "example.com"}, + {"wildcarded name", "*.com", "*.com"}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(subT *testing.T) { + res := tc.actual.String() + if res != tc.expected { + subT.Errorf("expected (%s), got (%s)", tc.expected, res) + } + }) + } +} diff --git a/pkg/library/utils/k8s_utils.go b/pkg/utils/k8s_utils.go similarity index 61% rename from pkg/library/utils/k8s_utils.go rename to pkg/utils/k8s_utils.go index 913347277..a4b7a4a4a 100644 --- a/pkg/library/utils/k8s_utils.go +++ b/pkg/utils/k8s_utils.go @@ -18,11 +18,7 @@ package utils import ( "context" - "encoding/json" - "fmt" - "sort" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -38,12 +34,6 @@ const ( var clusterUID string -// ObjectInfo generates a string representation of the provided Kubernetes object, including its kind and name. -// The generated string follows the format: "kind/name". -func ObjectInfo(obj client.Object) string { - return fmt.Sprintf("%s/%s", obj.GetObjectKind().GroupVersionKind().Kind, obj.GetName()) -} - // TagObjectToDelete adds a special DeleteTagAnnotation to the object's annotations. // If the object's annotations are nil, it first initializes the Annotations field with an empty map. func TagObjectToDelete(obj client.Object) { @@ -69,19 +59,6 @@ func IsObjectTaggedToDelete(obj client.Object) bool { return ok && annotation == "true" } -// StatusConditionsMarshalJSON marshals the list of conditions as a JSON array, sorted by -// condition type. -func StatusConditionsMarshalJSON(input []metav1.Condition) ([]byte, error) { - conds := make([]metav1.Condition, 0, len(input)) - conds = append(conds, input...) - - sort.Slice(conds, func(a, b int) bool { - return conds[a].Type < conds[b].Type - }) - - return json.Marshal(conds) -} - // IsOwnedBy checks if the provided owned object is owned by the given owner object. // Ownership is determined based on matching the owner reference's group, kind, and name. // The version of the owner reference is not checked in this implementation. @@ -108,57 +85,6 @@ func IsOwnedBy(owned, owner client.Object) bool { return false } -// ObjectKeyListDifference computest a - b -func ObjectKeyListDifference(a, b []client.ObjectKey) []client.ObjectKey { - target := map[client.ObjectKey]bool{} - for _, x := range b { - target[x] = true - } - - result := make([]client.ObjectKey, 0) - for _, x := range a { - if _, ok := target[x]; !ok { - result = append(result, x) - } - } - - return result -} - -// FindObjectKey returns the smallest index i at which x == a[i], -// or len(a) if there is no such index. -func FindObjectKey(a []client.ObjectKey, x client.ObjectKey) int { - for i, n := range a { - if x == n { - return i - } - } - return len(a) -} - -func FindDeploymentStatusCondition(conditions []appsv1.DeploymentCondition, conditionType string) *appsv1.DeploymentCondition { - for i := range conditions { - if conditions[i].Type == appsv1.DeploymentConditionType(conditionType) { - return &conditions[i] - } - } - - return nil -} - -func HasLabel(obj metav1.Object, key string) bool { - labels := obj.GetLabels() - _, ok := labels[key] - return ok -} - -func GetLabel(obj metav1.Object, key string) string { - if !HasLabel(obj, key) { - return "" - } - return obj.GetLabels()[key] -} - func GetClusterUID(ctx context.Context, c dynamic.Interface) (string, error) { //Already calculated? return it if clusterUID != "" { diff --git a/pkg/utils/k8s_utils_test.go b/pkg/utils/k8s_utils_test.go new file mode 100644 index 000000000..dc28b6da4 --- /dev/null +++ b/pkg/utils/k8s_utils_test.go @@ -0,0 +1,375 @@ +//go:build unit + +package utils + +import ( + "context" + "reflect" + "testing" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + dfake "k8s.io/client-go/dynamic/fake" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/kuadrant/limitador-operator/api/v1alpha1" +) + +func TestTagObjectToDelete(t *testing.T) { + testCases := []struct { + name string + input client.Object + expectedTags map[string]string + }{ + { + name: "when object has no annotations (nil) then initialize them with empty map and add 'delete' tag", + input: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Annotations: nil, + }, + }, + expectedTags: map[string]string{ + DeleteTagAnnotation: "true", + }, + }, + { + name: "when object has empty annotations (empty map) then add 'delete' tag", + input: &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-service", + Annotations: map[string]string{}, + }, + }, + expectedTags: map[string]string{ + DeleteTagAnnotation: "true", + }, + }, + { + name: "when object already has annotations then add 'delete' tag", + input: &v1alpha1.Limitador{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-service", + Annotations: map[string]string{ + "key1": "value1", + "key2": "value2", + }, + }, + }, + expectedTags: map[string]string{ + DeleteTagAnnotation: "true", + "key1": "value1", + "key2": "value2", + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + TagObjectToDelete(tc.input) + + annotations := tc.input.GetAnnotations() + if annotations == nil { + t.Fatal("Expected annotations to be not nil, but got nil") + } + + if !reflect.DeepEqual(annotations, tc.expectedTags) { + t.Errorf("Expected annotations to be '%v', but got '%v'", tc.expectedTags, annotations) + } + }) + } +} + +func TestIsObjectTaggedToDelete(t *testing.T) { + testCases := []struct { + name string + input client.Object + annotations map[string]string + expected bool + }{ + { + name: "when object has delete tag annotation set to true then return true", + input: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + DeleteTagAnnotation: "true", + }, + }, + }, + expected: true, + }, + { + name: "when object has delete tag annotation set to false then return false", + input: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + DeleteTagAnnotation: "false", + }, + }, + }, + expected: false, + }, + { + name: "when object has no delete tag annotation then return false", + input: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{}, + }, + }, + expected: false, + }, + { + name: "when object annotations are nil then return false", + input: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: nil, + }, + }, + expected: false, + }, + } + + for _, c := range testCases { + t.Run(c.name, func(t *testing.T) { + actual := IsObjectTaggedToDelete(c.input) + if actual != c.expected { + t.Errorf("Expected %v, but got %v", c.expected, actual) + } + }) + } +} + +func TestIsOwnedBy(t *testing.T) { + testCases := []struct { + name string + owned client.Object + owner client.Object + expected bool + }{ + { + name: "when owned object has owner reference then return true", + owned: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Deployment", + Name: "my-deployment", + }, + }, + }, + }, + owner: &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + }, + }, + expected: true, + }, + { + name: "when owned object does not have owner reference then return false", + owned: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{}, + }, + owner: &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + }, + }, + expected: false, + }, + { + name: "when owned object has owner reference with different group then return false", + owned: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "apps/v1", + Kind: "Deployment", + Name: "my-deployment", + }, + }, + }, + }, + owner: &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + }, + }, + expected: false, + }, + { + name: "when owned object has owner reference with different kind then return false", + owned: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "StatefulSet", + Name: "my-deployment", + }, + }, + }, + }, + owner: &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + }, + }, + expected: false, + }, + { + name: "when owned object has owner reference with different name then return false", + owned: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Deployment", + Name: "other-deployment", + }, + }, + }, + }, + owner: &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + }, + }, + expected: false, + }, + { + name: "when owned object has owner reference and in same namespace then return true", + owned: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns1", + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Deployment", + Name: "my-deployment", + }, + }, + }, + }, + owner: &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + Namespace: "ns1", + }, + }, + expected: true, + }, + { + name: "when owned object has owner reference but in different namespace then return false", + owned: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns1", + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: "v1", + Kind: "Deployment", + Name: "my-deployment", + }, + }, + }, + }, + owner: &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-deployment", + Namespace: "ns2", + }, + }, + expected: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual := IsOwnedBy(tc.owned, tc.owner) + if actual != tc.expected { + t.Errorf("unexpected result: got %v, want %v", actual, tc.expected) + } + }) + } +} + +func TestGetClusterUID(t *testing.T) { + var tScheme = runtime.NewScheme() + utilruntime.Must(corev1.AddToScheme(tScheme)) + + var testCases = []struct { + Name string + Objects []runtime.Object + Validation func(t *testing.T, e error, id string) + }{ + { + Name: "an absent namespace generates an error", + Objects: []runtime.Object{}, + Validation: func(t *testing.T, e error, id string) { + if !errors.IsNotFound(e) { + t.Errorf("expected not found error, got '%v'", e) + } + }, + }, + { + Name: "a UID generates a valid deterministic cluster ID", + Objects: []runtime.Object{ + &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterIDNamespace, + UID: "random-uid", + }, + }, + }, + Validation: func(t *testing.T, e error, id string) { + if e != nil { + t.Errorf("unexpected error, got '%v', expected nil", e) + } + + if id != "random-uid" { + t.Errorf("unexpected cluster ID got '%s', expected 'random-uid'", id) + } + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.Name, func(t *testing.T) { + fc := dfake.NewSimpleDynamicClient(tScheme, testCase.Objects...) + id, err := GetClusterUID(context.Background(), fc) + testCase.Validation(t, err, id) + }) + } +} diff --git a/pkg/library/utils/slice_utils.go b/pkg/utils/slice_utils.go similarity index 56% rename from pkg/library/utils/slice_utils.go rename to pkg/utils/slice_utils.go index 34dacaf92..17c171fb1 100644 --- a/pkg/library/utils/slice_utils.go +++ b/pkg/utils/slice_utils.go @@ -1,7 +1,5 @@ package utils -import "slices" - // GetEmptySliceIfNil returns a provided slice, or an empty slice of the same type if the input slice is nil. func GetEmptySliceIfNil[T any](val []T) []T { if val == nil { @@ -10,44 +8,6 @@ func GetEmptySliceIfNil[T any](val []T) []T { return val } -// SameElements checks if the two slices contain the exact same elements. Order does not matter. -func SameElements[T comparable](s1, s2 []T) bool { - if len(s1) != len(s2) { - return false - } - for _, v := range s1 { - if !slices.Contains(s2, v) { - return false - } - } - return true -} - -func Intersect[T comparable](slice1, slice2 []T) bool { - for _, item := range slice1 { - if slices.Contains(slice2, item) { - return true - } - } - return false -} - -func Intersection[T comparable](slice1, slice2 []T) []T { - smallerSlice := slice1 - largerSlice := slice2 - if len(slice1) > len(slice2) { - smallerSlice = slice2 - largerSlice = slice1 - } - var result []T - for _, item := range smallerSlice { - if slices.Contains(largerSlice, item) { - result = append(result, item) - } - } - return result -} - func Index[T any](slice []T, match func(T) bool) int { for i, item := range slice { if match(item) { diff --git a/pkg/utils/slice_utils_test.go b/pkg/utils/slice_utils_test.go new file mode 100644 index 000000000..d8d7f2cb9 --- /dev/null +++ b/pkg/utils/slice_utils_test.go @@ -0,0 +1,92 @@ +package utils + +import ( + "reflect" + "testing" +) + +func TestFind(t *testing.T) { + s := []string{"a", "ab", "abc"} + + if r, found := Find(s, func(el string) bool { return el == "ab" }); !found || r == nil || *r != "ab" { + t.Error("should have found 'ab' in the slice") + } + + if r, found := Find(s, func(el string) bool { return len(el) <= 3 }); !found || r == nil || *r != "a" { + t.Error("should have found 'a' in the slice") + } + + if r, found := Find(s, func(el string) bool { return len(el) >= 3 }); !found || r == nil || *r != "abc" { + t.Error("should have found 'abc' in the slice") + } + + if r, found := Find(s, func(el string) bool { return len(el) == 4 }); found || r != nil { + t.Error("should not have found anything in the slice") + } + + i := []int{1, 2, 3} + + if r, found := Find(i, func(el int) bool { return el/3 == 1 }); !found || r == nil || *r != 3 { + t.Error("should have found 3 in the slice") + } + + if r, found := Find(i, func(el int) bool { return el == 75 }); found || r != nil { + t.Error("should not have found anything in the slice") + } +} + +func TestGetEmptySliceIfNil(t *testing.T) { + t.Run("when a non-nil slice is provided then return same slice", func(t *testing.T) { + value := []int{1, 2, 3} + expected := value + + result := GetEmptySliceIfNil(value) + + if !reflect.DeepEqual(result, expected) { + t.Errorf("Expected %v, but got %v", expected, result) + } + }) + + t.Run("when a nil slice is provided then return an empty slice of the same type", func(t *testing.T) { + var value []int + expected := []int{} + + result := GetEmptySliceIfNil(value) + + if !reflect.DeepEqual(result, expected) { + t.Errorf("Expected %v, but got %v", expected, result) + } + }) +} + +func TestMap(t *testing.T) { + slice1 := []int{1, 2, 3, 4} + f1 := func(x int) int { return x + 1 } + expected1 := []int{2, 3, 4, 5} + result1 := Map(slice1, f1) + t.Run("when mapping an int slice with an increment function then return new slice with the incremented values", func(t *testing.T) { + if !reflect.DeepEqual(result1, expected1) { + t.Errorf("result1 = %v; expected %v", result1, expected1) + } + }) + + slice2 := []string{"hello", "world", "buz", "a"} + f2 := func(s string) int { return len(s) } + expected2 := []int{5, 5, 3, 1} + result2 := Map(slice2, f2) + t.Run("when mapping a string slice with string->int mapping then return new slice with the mapped values", func(t *testing.T) { + if !reflect.DeepEqual(result2, expected2) { + t.Errorf("result2 = %v; expected %v", result2, expected2) + } + }) + + slice3 := []int{} + f3 := func(x int) float32 { return float32(x) / 2 } + expected3 := []float32{} + result3 := Map(slice3, f3) + t.Run("when mapping an empty int slice then return an empty slice", func(t *testing.T) { + if !reflect.DeepEqual(result3, expected3) { + t.Errorf("result3 = %v; expected %v", result3, expected3) + } + }) +} diff --git a/pkg/wasm/utils.go b/pkg/wasm/utils.go index 06fd9d034..5fffe8eb3 100644 --- a/pkg/wasm/utils.go +++ b/pkg/wasm/utils.go @@ -13,8 +13,9 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - "github.com/kuadrant/kuadrant-operator/pkg/common" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + kuadrantpolicymachinery "github.com/kuadrant/kuadrant-operator/pkg/policymachinery" ) const ( @@ -31,12 +32,12 @@ func BuildConfigForActionSet(actionSets []ActionSet) Config { Services: map[string]Service{ AuthServiceName: { Type: AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: FailureModeDeny, }, RateLimitServiceName: { Type: RateLimitServiceType, - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: FailureModeAllow, }, }, @@ -45,7 +46,7 @@ func BuildConfigForActionSet(actionSets []ActionSet) Config { } func BuildActionSetsForPath(pathID string, path []machinery.Targetable, actions []Action) ([]kuadrantgatewayapi.HTTPRouteMatchConfig, error) { - _, _, listener, httpRoute, httpRouteRule, err := common.ObjectsInRequestPath(path) + _, _, listener, httpRoute, httpRouteRule, err := kuadrantpolicymachinery.ObjectsInRequestPath(path) if err != nil { return nil, err } diff --git a/tests/common/authpolicy/authpolicy_controller_test.go b/tests/common/authpolicy/authpolicy_controller_test.go index 9b5bb7206..3e7cd2aea 100644 --- a/tests/common/authpolicy/authpolicy_controller_test.go +++ b/tests/common/authpolicy/authpolicy_controller_test.go @@ -28,7 +28,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/tests" ) diff --git a/tests/common/targetstatus/target_status_controller_test.go b/tests/common/discoverability/policy_discoverability_reconciler_test.go similarity index 99% rename from tests/common/targetstatus/target_status_controller_test.go rename to tests/common/discoverability/policy_discoverability_reconciler_test.go index e97213392..e25eab58a 100644 --- a/tests/common/targetstatus/target_status_controller_test.go +++ b/tests/common/discoverability/policy_discoverability_reconciler_test.go @@ -1,6 +1,6 @@ //go:build integration -package targetstatus +package discoverability import ( "context" @@ -26,12 +26,12 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/utils" "github.com/kuadrant/kuadrant-operator/tests" ) -var _ = Describe("Target status reconciler", func() { +var _ = Describe("Policy discoverability reconciler", func() { const ( testTimeOut = SpecTimeout(2 * time.Minute) afterEachTimeOut = NodeTimeout(3 * time.Minute) @@ -203,15 +203,13 @@ var _ = Describe("Target status reconciler", func() { Eventually(policyAcceptedAndTargetsAffected(ctx, routePolicy1)).WithContext(ctx).Should(BeTrue()) - routePolicy2 := policyFactory(func(p *kuadrantv1.AuthPolicy) { // another policy that targets the same route. this policy will not be accepted + routePolicy2 := policyFactory(func(p *kuadrantv1.AuthPolicy) { // another policy that targets the same route p.Name = "route-auth-2" }) Expect(k8sClient.Create(ctx, routePolicy2)).To(Succeed()) Eventually(func() bool { - return policyAcceptedAndTargetsAffected(ctx, routePolicy1)() && - !tests.IsAuthPolicyAccepted(ctx, testClient(), routePolicy2)() && - !routeAffected(ctx, TestHTTPRouteName, policyAffectedCondition, client.ObjectKeyFromObject(routePolicy2)) + return policyAcceptedAndTargetsAffected(ctx, routePolicy1)() && policyAcceptedAndTargetsAffected(ctx, routePolicy2)() }).WithContext(ctx).Should(BeTrue()) }, testTimeOut) diff --git a/tests/common/targetstatus/suite_test.go b/tests/common/discoverability/suite_test.go similarity index 99% rename from tests/common/targetstatus/suite_test.go rename to tests/common/discoverability/suite_test.go index 9646cf5f0..e9473db96 100644 --- a/tests/common/targetstatus/suite_test.go +++ b/tests/common/discoverability/suite_test.go @@ -16,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package targetstatus +package discoverability import ( "context" diff --git a/tests/common/dnspolicy/dnspolicy_controller_single_cluster_test.go b/tests/common/dnspolicy/dnspolicy_controller_single_cluster_test.go index 51ef882af..273f9dc42 100644 --- a/tests/common/dnspolicy/dnspolicy_controller_single_cluster_test.go +++ b/tests/common/dnspolicy/dnspolicy_controller_single_cluster_test.go @@ -22,8 +22,7 @@ import ( kuadrantdnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/common" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" "github.com/kuadrant/kuadrant-operator/tests" ) @@ -71,9 +70,9 @@ var _ = Describe("DNSPolicy Single Cluster", func() { Gateway Expect(k8sClient.Create(ctx, gateway)).To(Succeed()) - clusterHash = common.ToBase36HashLen(clusterUID, utils.ClusterIDLength) + clusterHash = utils.ToBase36HashLen(clusterUID, utils.ClusterIDLength) - gwHash = common.ToBase36HashLen(gateway.Name+"-"+gateway.Namespace, 6) + gwHash = utils.ToBase36HashLen(gateway.Name+"-"+gateway.Namespace, 6) // refresh gateway Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(gateway), gateway)).To(Succeed()) diff --git a/tests/common/dnspolicy/dnspolicy_controller_test.go b/tests/common/dnspolicy/dnspolicy_controller_test.go index 7945dee91..5912cf3fd 100644 --- a/tests/common/dnspolicy/dnspolicy_controller_test.go +++ b/tests/common/dnspolicy/dnspolicy_controller_test.go @@ -23,9 +23,8 @@ import ( kuadrantdnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/common" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/utils" "github.com/kuadrant/kuadrant-operator/tests" ) @@ -1052,8 +1051,8 @@ var _ = Describe("DNSPolicy controller", func() { clusterUID, err := getClusterUID(ctx, k8sClient) Expect(err).To(BeNil()) - clusterHash := common.ToBase36HashLen(clusterUID, utils.ClusterIDLength) - gwHash := common.ToBase36HashLen(gateway.Name+"-"+gateway.Namespace, 6) + clusterHash := utils.ToBase36HashLen(clusterUID, utils.ClusterIDLength) + gwHash := utils.ToBase36HashLen(gateway.Name+"-"+gateway.Namespace, 6) endpointMatcher := func(targets ...string) types.GomegaMatcher { return PointTo(MatchFields(IgnoreExtras, Fields{ diff --git a/tests/common/gatewaykuadrant/gateway_kuadrant_controller_test.go b/tests/common/gatewaykuadrant/gateway_kuadrant_controller_test.go deleted file mode 100644 index adcf3e594..000000000 --- a/tests/common/gatewaykuadrant/gateway_kuadrant_controller_test.go +++ /dev/null @@ -1,216 +0,0 @@ -//go:build integration - -package gatewaykuadrant - -import ( - "context" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" - logf "sigs.k8s.io/controller-runtime/pkg/log" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" - - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/tests" -) - -var _ = Describe("Kuadrant Gateway controller", Serial, func() { - const ( - testTimeOut = SpecTimeout(2 * time.Minute) - afterEachTimeOut = NodeTimeout(3 * time.Minute) - ) - var ( - testNamespace string - gwAName = "gw-a" - gwBName = "gw-b" - kuadrantName = "sample" - ) - - beforeEachCallback := func(ctx SpecContext) { - testNamespace = tests.CreateNamespace(ctx, testClient()) - } - - BeforeEach(beforeEachCallback) - AfterEach(func(ctx SpecContext) { - tests.DeleteNamespace(ctx, testClient(), testNamespace) - }, afterEachTimeOut) - - Context("two gateways created after Kuadrant instance", func() { - It("gateways should have required annotation", func(ctx SpecContext) { - // it is not required that the kuadrant cr object is reconciled successfully. - kuadrantCR := &kuadrantv1beta1.Kuadrant{ - TypeMeta: metav1.TypeMeta{ - Kind: "Kuadrant", - APIVersion: kuadrantv1beta1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{Name: kuadrantName, Namespace: testNamespace}, - } - Expect(testClient().Create(ctx, kuadrantCR)).ToNot(HaveOccurred()) - - gwA := tests.BuildBasicGateway(gwAName, testNamespace) - err := testClient().Create(ctx, gwA) - Expect(err).ToNot(HaveOccurred()) - - gwB := tests.BuildBasicGateway(gwBName, testNamespace) - err = testClient().Create(ctx, gwB) - Expect(err).ToNot(HaveOccurred()) - - // Check gwA is annotated with kuadrant annotation - Eventually(testIsGatewayKuadrantManaged(ctx, testClient(), gwA, testNamespace)).WithContext(ctx).Should(BeTrue()) - - // Check gwB is annotated with kuadrant annotation - Eventually(testIsGatewayKuadrantManaged(ctx, testClient(), gwB, testNamespace)).WithContext(ctx).Should(BeTrue()) - }, testTimeOut) - }) - - Context("two gateways created before Kuadrant instance", func() { - It("gateways should have required annotation", func(ctx SpecContext) { - gwA := tests.BuildBasicGateway(gwAName, testNamespace) - err := testClient().Create(ctx, gwA) - Expect(err).ToNot(HaveOccurred()) - - gwB := tests.BuildBasicGateway(gwBName, testNamespace) - err = testClient().Create(ctx, gwB) - Expect(err).ToNot(HaveOccurred()) - - // it is not required that the kuadrant cr object is reconciled successfully. - kuadrantCR := &kuadrantv1beta1.Kuadrant{ - TypeMeta: metav1.TypeMeta{ - Kind: "Kuadrant", - APIVersion: kuadrantv1beta1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{Name: kuadrantName, Namespace: testNamespace}, - } - Expect(testClient().Create(ctx, kuadrantCR)).ToNot(HaveOccurred()) - - // Check gwA is annotated with kuadrant annotation - Eventually(testIsGatewayKuadrantManaged(ctx, testClient(), gwA, testNamespace)).WithContext(ctx).Should(BeTrue()) - - // Check gwB is annotated with kuadrant annotation - Eventually(testIsGatewayKuadrantManaged(ctx, testClient(), gwB, testNamespace)).WithContext(ctx).Should(BeTrue()) - }, testTimeOut) - }) - - Context("when Kuadrant instance is deleted", func() { - It("gateways should not have kuadrant annotation", func(ctx SpecContext) { - // it is not required that the kuadrant cr object is reconciled successfully. - kuadrantCR := &kuadrantv1beta1.Kuadrant{ - TypeMeta: metav1.TypeMeta{ - Kind: "Kuadrant", - APIVersion: kuadrantv1beta1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{Name: kuadrantName, Namespace: testNamespace}, - } - Expect(testClient().Create(ctx, kuadrantCR)).ToNot(HaveOccurred()) - - gwA := tests.BuildBasicGateway(gwAName, testNamespace) - err := testClient().Create(ctx, gwA) - Expect(err).ToNot(HaveOccurred()) - - gwB := tests.BuildBasicGateway(gwBName, testNamespace) - err = testClient().Create(ctx, gwB) - Expect(err).ToNot(HaveOccurred()) - - // Check gwA is annotated with kuadrant annotation - Eventually(testIsGatewayKuadrantManaged(ctx, testClient(), gwA, testNamespace)).WithContext(ctx).Should(BeTrue()) - - // Check gwB is annotated with kuadrant annotation - Eventually(testIsGatewayKuadrantManaged(ctx, testClient(), gwB, testNamespace)).WithContext(ctx).Should(BeTrue()) - - kObj := &kuadrantv1beta1.Kuadrant{ObjectMeta: metav1.ObjectMeta{Name: kuadrantName, Namespace: testNamespace}} - err = testClient().Delete(ctx, kObj) - - // Check gwA is not annotated with kuadrant annotation - Eventually(func() bool { - existingGateway := &gatewayapiv1.Gateway{} - err := testClient().Get(ctx, client.ObjectKeyFromObject(gwA), existingGateway) - if err != nil { - logf.Log.Info("[WARN] Getting gateway failed", "error", err) - return false - } - _, isSet := existingGateway.GetAnnotations()[kuadrant.KuadrantNamespaceAnnotation] - return !isSet - }).WithContext(ctx).Should(BeTrue()) - - // Check gwB is not annotated with kuadrant annotation - Eventually(func() bool { - existingGateway := &gatewayapiv1.Gateway{} - err := testClient().Get(ctx, client.ObjectKeyFromObject(gwB), existingGateway) - if err != nil { - logf.Log.Info("[WARN] Getting gateway failed", "error", err) - return false - } - _, isSet := existingGateway.GetAnnotations()[kuadrant.KuadrantNamespaceAnnotation] - return !isSet - }).WithContext(ctx).Should(BeTrue()) - }, testTimeOut) - }) - - Context("Two kuadrant instances", func() { - var ( - secondNamespace string - kuadrantAName = "kuadrant-a" - kuadrantBName = "kuadrant-b" - ) - - BeforeEach(func(ctx SpecContext) { - firstKuadrant := &kuadrantv1beta1.Kuadrant{ - TypeMeta: metav1.TypeMeta{ - Kind: "Kuadrant", - APIVersion: kuadrantv1beta1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{Name: kuadrantAName, Namespace: testNamespace}, - } - Expect(testClient().Create(ctx, firstKuadrant)).ToNot(HaveOccurred()) - - secondNamespace = tests.CreateNamespace(ctx, testClient()) - secondKuadrant := &kuadrantv1beta1.Kuadrant{ - TypeMeta: metav1.TypeMeta{ - Kind: "Kuadrant", - APIVersion: kuadrantv1beta1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{Name: kuadrantBName, Namespace: secondNamespace}, - } - Expect(testClient().Create(ctx, secondKuadrant)).ToNot(HaveOccurred()) - }) - - AfterEach(func(ctx SpecContext) { - tests.DeleteNamespace(ctx, testClient(), secondNamespace) - }, afterEachTimeOut) - - It("new gateway should not be annotated", func(ctx SpecContext) { - gateway := tests.BuildBasicGateway("gw-a", testNamespace) - err := testClient().Create(ctx, gateway) - Expect(err).ToNot(HaveOccurred()) - - // Check gateway is not annotated with kuadrant annotation - Eventually(func() bool { - existingGateway := &gatewayapiv1.Gateway{} - err := testClient().Get(ctx, client.ObjectKeyFromObject(gateway), existingGateway) - if err != nil { - logf.Log.V(1).Info("[WARN] Getting gateway failed", "error", err) - return false - } - _, isSet := existingGateway.GetAnnotations()[kuadrant.KuadrantNamespaceAnnotation] - return !isSet - }).WithContext(ctx).Should(BeTrue()) - }, testTimeOut) - }) -}) - -func testIsGatewayKuadrantManaged(ctx context.Context, cl client.Client, gw *gatewayapiv1.Gateway, ns string) func() bool { - return func() bool { - existingGateway := &gatewayapiv1.Gateway{} - err := cl.Get(ctx, client.ObjectKeyFromObject(gw), existingGateway) - if err != nil { - logf.Log.Info("[WARN] Getting gateway failed", "error", err) - return false - } - val, isSet := existingGateway.GetAnnotations()[kuadrant.KuadrantNamespaceAnnotation] - return isSet && val == ns - } -} diff --git a/tests/common/gatewaykuadrant/suite_test.go b/tests/common/gatewaykuadrant/suite_test.go deleted file mode 100644 index adcb6e97d..000000000 --- a/tests/common/gatewaykuadrant/suite_test.go +++ /dev/null @@ -1,115 +0,0 @@ -//go:build integration - -/* -Copyright 2021. - -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 gatewaykuadrant - -import ( - "encoding/json" - "os" - "testing" - - "github.com/kuadrant/kuadrant-operator/tests" - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/log" -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -// This test suite will be run on k8s env with GatewayAPI CRDs, Istio and Kuadrant CRDs installed - -var k8sClient client.Client -var testEnv *envtest.Environment - -func testClient() client.Client { return k8sClient } - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Kuadrant Gateway Controller Suite") -} - -var _ = SynchronizedBeforeSuite(func() []byte { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - UseExistingCluster: &[]bool{true}[0], - } - - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - controllers.SetupKuadrantOperatorForTest(controllers.BootstrapScheme(), cfg) - - data := controllers.MarshalConfig(cfg) - - return data -}, func(data []byte) { - // Unmarshal the shared configuration struct - var sharedCfg controllers.SharedConfig - Expect(json.Unmarshal(data, &sharedCfg)).To(Succeed()) - - // Create the rest.Config object from the shared configuration - cfg := &rest.Config{ - Host: sharedCfg.Host, - TLSClientConfig: rest.TLSClientConfig{ - Insecure: sharedCfg.TLSClientConfig.Insecure, - CertData: sharedCfg.TLSClientConfig.CertData, - KeyData: sharedCfg.TLSClientConfig.KeyData, - CAData: sharedCfg.TLSClientConfig.CAData, - }, - } - - // Create new scheme for each client - s := controllers.BootstrapScheme() - - // Set the shared configuration - var err error - k8sClient, err = client.New(cfg, client.Options{Scheme: s}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - tests.GatewayClassName = os.Getenv("GATEWAYAPI_PROVIDER") - Expect(tests.GatewayClassName).NotTo(BeZero(), "Please make sure GATEWAYAPI_PROVIDER is set correctly.") -}) - -var _ = SynchronizedAfterSuite(func() {}, func() { - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) - -func TestMain(m *testing.M) { - logger := log.NewLogger( - log.SetLevel(log.DebugLevel), - log.SetMode(log.ModeDev), - log.WriteTo(GinkgoWriter), - ).WithName("kuadrant_gateway_controller_test") - log.SetLogger(logger) - os.Exit(m.Run()) -} diff --git a/tests/common/ratelimitpolicy/ratelimitpolicy_controller_test.go b/tests/common/ratelimitpolicy/ratelimitpolicy_controller_test.go index 848020a0d..7ba2a736d 100644 --- a/tests/common/ratelimitpolicy/ratelimitpolicy_controller_test.go +++ b/tests/common/ratelimitpolicy/ratelimitpolicy_controller_test.go @@ -22,8 +22,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/common" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/tests" ) @@ -216,7 +215,7 @@ var _ = Describe("RateLimitPolicy controller", func() { limitadorContainsLimit := func(ctx context.Context, limits ...limitadorv1alpha1.RateLimit) func(g Gomega) { return func(g Gomega) { - limitadorKey := client.ObjectKey{Name: common.LimitadorName, Namespace: kuadrantInstallationNS} + limitadorKey := client.ObjectKey{Name: kuadrant.LimitadorName, Namespace: kuadrantInstallationNS} existingLimitador := &limitadorv1alpha1.Limitador{} g.Expect(k8sClient.Get(ctx, limitadorKey, existingLimitador)).To(Succeed()) for i := range limits { @@ -258,7 +257,7 @@ var _ = Describe("RateLimitPolicy controller", func() { // check limits Eventually(func(g Gomega) { - limitadorKey := client.ObjectKey{Name: common.LimitadorName, Namespace: kuadrantInstallationNS} + limitadorKey := client.ObjectKey{Name: kuadrant.LimitadorName, Namespace: kuadrantInstallationNS} existingLimitador := &limitadorv1alpha1.Limitador{} err = k8sClient.Get(ctx, limitadorKey, existingLimitador) // must exist @@ -331,7 +330,7 @@ var _ = Describe("RateLimitPolicy controller", func() { // check limits Eventually(func(g Gomega) { - limitadorKey := client.ObjectKey{Name: common.LimitadorName, Namespace: kuadrantInstallationNS} + limitadorKey := client.ObjectKey{Name: kuadrant.LimitadorName, Namespace: kuadrantInstallationNS} existingLimitador := &limitadorv1alpha1.Limitador{} err = k8sClient.Get(ctx, limitadorKey, existingLimitador) // must exist @@ -362,7 +361,7 @@ var _ = Describe("RateLimitPolicy controller", func() { // check limits Eventually(func(g Gomega) { - limitadorKey := client.ObjectKey{Name: common.LimitadorName, Namespace: kuadrantInstallationNS} + limitadorKey := client.ObjectKey{Name: kuadrant.LimitadorName, Namespace: kuadrantInstallationNS} existingLimitador := &limitadorv1alpha1.Limitador{} err = k8sClient.Get(ctx, limitadorKey, existingLimitador) // must exist diff --git a/tests/common/tlspolicy/tlspolicy_controller_test.go b/tests/common/tlspolicy/tlspolicy_controller_test.go index a6a91f093..bdec97c61 100644 --- a/tests/common/tlspolicy/tlspolicy_controller_test.go +++ b/tests/common/tlspolicy/tlspolicy_controller_test.go @@ -22,7 +22,7 @@ import ( gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/tests" ) diff --git a/tests/commons.go b/tests/commons.go index 4978b372e..af4a06b42 100644 --- a/tests/commons.go +++ b/tests/commons.go @@ -14,8 +14,8 @@ import ( authorinoapi "github.com/kuadrant/authorino/api/v1beta3" kuadrantdnsv1alpha1 "github.com/kuadrant/dns-operator/api/v1alpha1" kuadrantdnsbuilder "github.com/kuadrant/dns-operator/pkg/builder" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/utils" limitadorv1alpha1 "github.com/kuadrant/limitador-operator/api/v1alpha1" . "github.com/onsi/gomega" istioclientgoextensionv1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1" @@ -32,7 +32,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" + kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/gatewayapi" ) const ( diff --git a/tests/envoygateway/extension_reconciler_test.go b/tests/envoygateway/extension_reconciler_test.go index ffccba610..467691819 100644 --- a/tests/envoygateway/extension_reconciler_test.go +++ b/tests/envoygateway/extension_reconciler_test.go @@ -21,7 +21,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/common" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/pkg/wasm" "github.com/kuadrant/kuadrant-operator/tests" ) @@ -169,12 +169,12 @@ var _ = Describe("wasm controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { Type: wasm.RateLimitServiceType, - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, }, }, @@ -333,12 +333,12 @@ var _ = Describe("wasm controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { Type: wasm.RateLimitServiceType, - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, }, }, diff --git a/tests/envoygateway/rate_limit_cluster_reconciler_test.go b/tests/envoygateway/rate_limit_cluster_reconciler_test.go index a770c0ac8..c6c19e860 100644 --- a/tests/envoygateway/rate_limit_cluster_reconciler_test.go +++ b/tests/envoygateway/rate_limit_cluster_reconciler_test.go @@ -22,7 +22,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/common" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/tests" ) @@ -152,7 +152,7 @@ var _ = Describe("limitador cluster controller", func() { Expect(patch.Spec.Type).To(Equal(egv1alpha1.JSONPatchEnvoyPatchType)) Expect(patch.Spec.JSONPatches).To(HaveLen(1)) Expect(patch.Spec.JSONPatches[0].Type).To(Equal(egv1alpha1.ClusterEnvoyResourceType)) - Expect(patch.Spec.JSONPatches[0].Name).To(Equal(common.KuadrantRateLimitClusterName)) + Expect(patch.Spec.JSONPatches[0].Name).To(Equal(kuadrant.KuadrantRateLimitClusterName)) Expect(patch.Spec.JSONPatches[0].Operation.Op).To(Equal(egv1alpha1.JSONPatchOperationType("add"))) // Check patch value @@ -168,13 +168,13 @@ var _ = Describe("limitador cluster controller", func() { Expect(existingPatchValue).To(Equal( map[string]any{ - "name": common.KuadrantRateLimitClusterName, + "name": kuadrant.KuadrantRateLimitClusterName, "type": "STRICT_DNS", "connect_timeout": "1s", "lb_policy": "ROUND_ROBIN", "http2_protocol_options": map[string]any{}, "load_assignment": map[string]any{ - "cluster_name": common.KuadrantRateLimitClusterName, + "cluster_name": kuadrant.KuadrantRateLimitClusterName, "endpoints": []any{ map[string]any{ "lb_endpoints": []any{ diff --git a/tests/envoygateway/utils_test.go b/tests/envoygateway/utils_test.go index aa9f8acde..be7857b82 100644 --- a/tests/envoygateway/utils_test.go +++ b/tests/envoygateway/utils_test.go @@ -14,7 +14,7 @@ import ( gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - "github.com/kuadrant/kuadrant-operator/pkg/library/utils" + "github.com/kuadrant/kuadrant-operator/pkg/utils" ) // IsEnvoyExtenstionPolicyAccepted checks extension policy accepted status for a given target ref. diff --git a/tests/istio/extension_reconciler_test.go b/tests/istio/extension_reconciler_test.go index cf9ffeb83..75b0e684a 100644 --- a/tests/istio/extension_reconciler_test.go +++ b/tests/istio/extension_reconciler_test.go @@ -23,8 +23,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/common" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/pkg/wasm" "github.com/kuadrant/kuadrant-operator/tests" ) @@ -148,12 +147,12 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { Type: wasm.RateLimitServiceType, - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, }, }, @@ -285,7 +284,7 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { existingWASMConfig, err := wasm.ConfigFromStruct(existingWasmPlugin.Spec.PluginConfig) Expect(err).ToNot(HaveOccurred()) Expect(existingWASMConfig.Services).To(HaveKeyWithValue(wasm.RateLimitServiceName, wasm.Service{ - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, })) @@ -713,11 +712,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -933,12 +932,12 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { expectedPlugin := &wasm.Config{ Services: map[string]wasm.Service{ wasm.AuthServiceName: { - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, Type: wasm.AuthServiceType, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -1144,11 +1143,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -1272,11 +1271,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -1472,11 +1471,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -1563,11 +1562,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -1738,11 +1737,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -1847,11 +1846,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -2058,11 +2057,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -2164,11 +2163,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -2329,11 +2328,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, @@ -2405,11 +2404,11 @@ var _ = Describe("Rate Limiting WasmPlugin controller", func() { Services: map[string]wasm.Service{ wasm.AuthServiceName: { Type: wasm.AuthServiceType, - Endpoint: common.KuadrantAuthClusterName, + Endpoint: kuadrant.KuadrantAuthClusterName, FailureMode: wasm.FailureModeDeny, }, wasm.RateLimitServiceName: { - Endpoint: common.KuadrantRateLimitClusterName, + Endpoint: kuadrant.KuadrantRateLimitClusterName, FailureMode: wasm.FailureModeAllow, Type: wasm.RateLimitServiceType, }, diff --git a/tests/istio/rate_limit_cluster_reconciler_test.go b/tests/istio/rate_limit_cluster_reconciler_test.go index 528a1354b..b198b955f 100644 --- a/tests/istio/rate_limit_cluster_reconciler_test.go +++ b/tests/istio/rate_limit_cluster_reconciler_test.go @@ -19,8 +19,7 @@ import ( kuadrantv1 "github.com/kuadrant/kuadrant-operator/api/v1" "github.com/kuadrant/kuadrant-operator/controllers" - "github.com/kuadrant/kuadrant-operator/pkg/common" - "github.com/kuadrant/kuadrant-operator/pkg/library/kuadrant" + "github.com/kuadrant/kuadrant-operator/pkg/kuadrant" "github.com/kuadrant/kuadrant-operator/tests" ) @@ -59,7 +58,7 @@ var _ = Describe("Limitador Cluster EnvoyFilter controller", func() { // Check Limitador Status is Ready Eventually(func() bool { limitador := &limitadorv1alpha1.Limitador{} - err := testClient().Get(ctx, client.ObjectKey{Name: common.LimitadorName, Namespace: kuadrantInstallationNS}, limitador) + err := testClient().Get(ctx, client.ObjectKey{Name: kuadrant.LimitadorName, Namespace: kuadrantInstallationNS}, limitador) if err != nil { return false }