diff --git a/go.mod b/go.mod index 5758e8dc..af9b5451 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( k8s.io/api v0.30.3 k8s.io/apimachinery v0.30.3 k8s.io/client-go v0.30.3 - knative.dev/eventing v0.42.1-0.20240816055941-2b922992c8f4 + knative.dev/eventing v0.42.1-0.20240826165623-833f4aa12066 knative.dev/hack v0.0.0-20240814130635-06f7aff93954 knative.dev/pkg v0.0.0-20240815051656-89743d9bbf7c ) diff --git a/go.sum b/go.sum index a428c380..98bf2688 100644 --- a/go.sum +++ b/go.sum @@ -704,8 +704,8 @@ k8s.io/kube-openapi v0.0.0-20240808142205-8e686545bdb8 h1:1Wof1cGQgA5pqgo8MxKPtf k8s.io/kube-openapi v0.0.0-20240808142205-8e686545bdb8/go.mod h1:Os6V6dZwLNii3vxFpxcNaTmH8LJJBkOTg1N0tOA0fvA= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -knative.dev/eventing v0.42.1-0.20240816055941-2b922992c8f4 h1:phPrPjJo+shjObPBF0Qzxd9kfghUA00UFQp/72ONvBE= -knative.dev/eventing v0.42.1-0.20240816055941-2b922992c8f4/go.mod h1:eTJLSCpHchscm2VV/e10w3HcGIB7dOYdGAzeBIRmJ08= +knative.dev/eventing v0.42.1-0.20240826165623-833f4aa12066 h1:joVzbKyPOjw79jVhGrT4zKA1jrDTqk+UDQ8Mbq2vtAU= +knative.dev/eventing v0.42.1-0.20240826165623-833f4aa12066/go.mod h1:Clx8z37Nwg321H9+vGNxp5C6bVdo4l4XM5g6T5CgZVI= knative.dev/hack v0.0.0-20240814130635-06f7aff93954 h1:dGMK5VoL75szvrYQTL9NqhPYHu1f5dGaXx1hJI8fAFM= knative.dev/hack v0.0.0-20240814130635-06f7aff93954/go.mod h1:R0ritgYtjLDO9527h5vb5X6gfvt5LCrJ55BNbVDsWiY= knative.dev/pkg v0.0.0-20240815051656-89743d9bbf7c h1:2crXVk4FG0dSG6WHaIT+WKbUzn7qG2wn0AfYmvA22zs= diff --git a/vendor/knative.dev/eventing/pkg/apis/config/defaults.go b/vendor/knative.dev/eventing/pkg/apis/config/defaults.go index f12b83ab..fcbdb50a 100644 --- a/vendor/knative.dev/eventing/pkg/apis/config/defaults.go +++ b/vendor/knative.dev/eventing/pkg/apis/config/defaults.go @@ -68,28 +68,88 @@ func NewDefaultsConfigFromConfigMap(config *corev1.ConfigMap) (*Defaults, error) return NewDefaultsConfigFromMap(config.Data) } +/* +The priority precedence for determining the broker class and configuration is as follows: + +1. If a specific broker class is provided: + a. Check namespace-specific configuration for the given broker class + b. If not found, check cluster-wide configuration for the given broker class + c. If still not found, use the cluster-wide default configuration + +2. If no specific broker class is provided: + a. Check namespace-specific default broker class + b. If found, use its configuration (following step 1) + c. If not found, use cluster-wide default broker class and configuration + +3. If no default cluster configuration is set, return an error + +4. If no default namespace configuration is set, will use the cluster-wide default configuration. + +This can be represented as a flow chart: + + Start + | + v + Is broker class provided? + / \ + Yes No + / \ + Check namespace config Check namespace + for provided class default class + | | + v v + Found? Found? + / \ / \ + Yes No Yes No + | | | | + | | | | + | v | v + | Check cluster | Use cluster + | config for class | default class + | | | and config + | v | + | Found? | + | / \ | + | Yes No | + | | | | + | | v | + | | Use cluster | + | | default config | + v v v + Use found configuration + +The system prioritizes namespace-specific configurations over cluster-wide defaults, +and explicitly provided broker classes over default classes. +*/ + // Defaults includes the default values to be populated by the webhook. type Defaults struct { // NamespaceDefaultsConfig are the default Broker Configs for each namespace. - // Namespace is the key, the value is the KReference to the config. - NamespaceDefaultsConfig map[string]*ClassAndBrokerConfig `json:"namespaceDefaults,omitempty"` + // Namespace is the key, the value is the NamespaceDefaultConfig + NamespaceDefaultsConfig map[string]*DefaultConfig `json:"namespaceDefaults,omitempty"` - // ClusterDefaultBrokerConfig is the default broker config for all the namespaces that - // are not in NamespaceDefaultBrokerConfigs. - ClusterDefault *ClassAndBrokerConfig `json:"clusterDefault,omitempty"` + // ClusterDefaultConfig is the default broker config for all the namespaces that + // are not in NamespaceDefaultBrokerConfigs. Different broker class could have + // different default config. + ClusterDefaultConfig *DefaultConfig `json:"clusterDefault,omitempty"` } -// ClassAndBrokerConfig contains configuration for a given namespace for broker. Allows -// configuring the Class of the Broker, the reference to the -// config it should use and it's delivery. -type ClassAndBrokerConfig struct { - BrokerClass string `json:"brokerClass,omitempty"` +// DefaultConfig struct contains the default configuration for the cluster and namespace. +type DefaultConfig struct { + // DefaultBrokerClass and DefaultBrokerClassConfig are the default broker class for the whole cluster/namespace. + // Users have to specify both of them + DefaultBrokerClass string `json:"brokerClass,omitempty"` + + //Deprecated: Use the config in BrokerClasses instead *BrokerConfig `json:",inline"` + // Optional: BrokerClasses are the default broker classes' config. The key is the broker class name, and the value is the config for that broker class. + BrokerClasses map[string]*BrokerConfig `json:"brokerClasses,omitempty"` + DisallowDifferentNamespaceConfig *bool `json:"disallowDifferentNamespaceConfig,omitempty"` } -// BrokerConfig contains configuration for a given namespace for broker. Allows +// BrokerConfig contains configuration for a given broker. Allows // configuring the reference to the // config it should use and it's delivery. type BrokerConfig struct { @@ -97,36 +157,115 @@ type BrokerConfig struct { Delivery *eventingduckv1.DeliverySpec `json:"delivery,omitempty"` } -// GetBrokerConfig returns a namespace specific Broker Configuration, and if -// that doesn't exist, return a Cluster Default and if that doesn't exist -// return an error. -func (d *Defaults) GetBrokerConfig(ns string) (*BrokerConfig, error) { +// GetBrokerConfig returns a namespace specific Broker Config, and if +// that doesn't exist, return a Cluster Default and if that doesn't exist return an error. +func (d *Defaults) GetBrokerConfig(ns string, brokerClassName *string) (*BrokerConfig, error) { if d == nil { - return nil, errors.New("Defaults are nil") + return nil, errors.New("Defaults for Broker Configurations for cluster have not been set up. You can set them via ConfigMap config-br-defaults.") + } + + // Early return if brokerClassName is provided and valid + if brokerClassName != nil && *brokerClassName != "" { + return d.getBrokerConfigByClassName(ns, *brokerClassName) + } + + // Handling empty brokerClassName + return d.getBrokerConfigForEmptyClassName(ns) +} + +// getBrokerConfigByClassName returns the BrokerConfig for the given brokerClassName. +// It first checks the namespace specific configuration, then the cluster default configuration. +func (d *Defaults) getBrokerConfigByClassName(ns string, brokerClassName string) (*BrokerConfig, error) { + // Check namespace specific configuration + if nsConfig, ok := d.NamespaceDefaultsConfig[ns]; ok && nsConfig != nil { + // check if the brokerClassName is the default broker class for this namespace + if nsConfig.DefaultBrokerClass == brokerClassName { + if nsConfig.BrokerConfig == nil { + // as no default broker class config is set for this namespace, check whether nsconfig's brokerClasses map has the config for this broker class + if config, ok := nsConfig.BrokerClasses[brokerClassName]; ok && config != nil { + return config, nil + } + // if not found, return the cluster default config + return d.getClusterDefaultBrokerConfig(brokerClassName) + } else { + // If the brokerClassName exists in the BrokerClasses, return the config in the BrokerClasses + if config, ok := nsConfig.BrokerClasses[brokerClassName]; ok && config != nil { + return config, nil + } else { + // If the brokerClassName is the default broker class for the namespace, return the BrokerConfig + return nsConfig.BrokerConfig, nil + } + } + } else { + // if the brokerClassName is not the default broker class for the namespace, check whether nsconfig's brokerClasses map has the config for this broker class + if config, ok := nsConfig.BrokerClasses[brokerClassName]; ok && config != nil { + return config, nil + } + } } - value, present := d.NamespaceDefaultsConfig[ns] - if present && value.BrokerConfig != nil { - return value.BrokerConfig, nil + + // Check cluster default configuration + return d.getClusterDefaultBrokerConfig(brokerClassName) +} + +// getBrokerConfigForEmptyClassName returns the BrokerConfig for the given namespace when brokerClassName is empty. +// It first checks the namespace specific configuration, then the cluster default configuration. +func (d *Defaults) getBrokerConfigForEmptyClassName(ns string) (*BrokerConfig, error) { + // Check if namespace has a default broker class + if nsConfig, ok := d.NamespaceDefaultsConfig[ns]; ok && nsConfig != nil { + if nsConfig.DefaultBrokerClass != "" { + return d.getBrokerConfigByClassName(ns, nsConfig.DefaultBrokerClass) + } } - if d.ClusterDefault != nil && d.ClusterDefault.BrokerConfig != nil { - return d.ClusterDefault.BrokerConfig, nil + + // Fallback to cluster default configuration + return d.getClusterDefaultBrokerConfig("") +} + +// getClusterDefaultBrokerConfig returns the BrokerConfig for the given brokerClassName. +func (d *Defaults) getClusterDefaultBrokerConfig(brokerClassName string) (*BrokerConfig, error) { + if d.ClusterDefaultConfig == nil || d.ClusterDefaultConfig.BrokerConfig == nil { + return nil, errors.New("Defaults for Broker Configurations for cluster have not been set up. You can set them via ConfigMap config-br-defaults.") } - return nil, errors.New("Defaults for Broker Configurations have not been set up.") + + // Check if the brokerClassName is the default broker class for the whole cluster + if brokerClassName == "" || d.ClusterDefaultConfig.DefaultBrokerClass == brokerClassName { + // If the brokerClassName exists in the BrokerClasses, return the config in the BrokerClasses + if config, ok := d.ClusterDefaultConfig.BrokerClasses[brokerClassName]; ok && config != nil { + return config, nil + } else { + // If the brokerClassName is the default broker class for the cluster, return the BrokerConfig + return d.ClusterDefaultConfig.BrokerConfig, nil + } + } + + if config, ok := d.ClusterDefaultConfig.BrokerClasses[brokerClassName]; ok && config != nil { + return config, nil + } + + return d.ClusterDefaultConfig.BrokerConfig, nil } // GetBrokerClass returns a namespace specific Broker Class, and if -// that doesn't exist, return a Cluster Default and if that doesn't exist +// that doesn't exist, return a Cluster Default and if the defaults doesn't exist // return an error. func (d *Defaults) GetBrokerClass(ns string) (string, error) { if d == nil { - return "", errors.New("Defaults are nil") + return "", errors.New("Defaults for Broker Configurations for cluster have not been set up. You can set them via ConfigMap config-br-defaults.") } - value, present := d.NamespaceDefaultsConfig[ns] - if present && value.BrokerClass != "" { - return value.BrokerClass, nil + + // Check if the namespace has a specific configuration + if nsConfig, ok := d.NamespaceDefaultsConfig[ns]; ok && nsConfig != nil { + if nsConfig.DefaultBrokerClass != "" { + return nsConfig.DefaultBrokerClass, nil + } } - if d.ClusterDefault != nil && d.ClusterDefault.BrokerClass != "" { - return d.ClusterDefault.BrokerClass, nil + + // Fallback to cluster default configuration if namespace specific configuration is not set + if d.ClusterDefaultConfig != nil && d.ClusterDefaultConfig.DefaultBrokerClass != "" { + return d.ClusterDefaultConfig.DefaultBrokerClass, nil } - return "", errors.New("Defaults for Broker Configurations have not been set up.") + + // If neither namespace specific nor cluster default broker class is found + return "", fmt.Errorf("Neither namespace specific nor cluster default broker class is found for namespace %q, please set them via ConfigMap config-br-defaults", ns) } diff --git a/vendor/knative.dev/eventing/pkg/apis/config/zz_generated.deepcopy.go b/vendor/knative.dev/eventing/pkg/apis/config/zz_generated.deepcopy.go index e02665cc..753fea32 100644 --- a/vendor/knative.dev/eventing/pkg/apis/config/zz_generated.deepcopy.go +++ b/vendor/knative.dev/eventing/pkg/apis/config/zz_generated.deepcopy.go @@ -53,13 +53,28 @@ func (in *BrokerConfig) DeepCopy() *BrokerConfig { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClassAndBrokerConfig) DeepCopyInto(out *ClassAndBrokerConfig) { +func (in *DefaultConfig) DeepCopyInto(out *DefaultConfig) { *out = *in if in.BrokerConfig != nil { in, out := &in.BrokerConfig, &out.BrokerConfig *out = new(BrokerConfig) (*in).DeepCopyInto(*out) } + if in.BrokerClasses != nil { + in, out := &in.BrokerClasses, &out.BrokerClasses + *out = make(map[string]*BrokerConfig, len(*in)) + for key, val := range *in { + var outVal *BrokerConfig + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(BrokerConfig) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } if in.DisallowDifferentNamespaceConfig != nil { in, out := &in.DisallowDifferentNamespaceConfig, &out.DisallowDifferentNamespaceConfig *out = new(bool) @@ -68,12 +83,12 @@ func (in *ClassAndBrokerConfig) DeepCopyInto(out *ClassAndBrokerConfig) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClassAndBrokerConfig. -func (in *ClassAndBrokerConfig) DeepCopy() *ClassAndBrokerConfig { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultConfig. +func (in *DefaultConfig) DeepCopy() *DefaultConfig { if in == nil { return nil } - out := new(ClassAndBrokerConfig) + out := new(DefaultConfig) in.DeepCopyInto(out) return out } @@ -83,22 +98,22 @@ func (in *Defaults) DeepCopyInto(out *Defaults) { *out = *in if in.NamespaceDefaultsConfig != nil { in, out := &in.NamespaceDefaultsConfig, &out.NamespaceDefaultsConfig - *out = make(map[string]*ClassAndBrokerConfig, len(*in)) + *out = make(map[string]*DefaultConfig, len(*in)) for key, val := range *in { - var outVal *ClassAndBrokerConfig + var outVal *DefaultConfig if val == nil { (*out)[key] = nil } else { in, out := &val, &outVal - *out = new(ClassAndBrokerConfig) + *out = new(DefaultConfig) (*in).DeepCopyInto(*out) } (*out)[key] = outVal } } - if in.ClusterDefault != nil { - in, out := &in.ClusterDefault, &out.ClusterDefault - *out = new(ClassAndBrokerConfig) + if in.ClusterDefaultConfig != nil { + in, out := &in.ClusterDefaultConfig, &out.ClusterDefaultConfig + *out = new(DefaultConfig) (*in).DeepCopyInto(*out) } return diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_defaults.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_defaults.go index f4fc1550..80873137 100644 --- a/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_defaults.go +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_defaults.go @@ -30,13 +30,18 @@ import ( func (b *Broker) SetDefaults(ctx context.Context) { // Default Spec fields. withNS := apis.WithinParent(ctx, b.ObjectMeta) - b.Spec.SetDefaults(withNS) + b.Spec.SetDefaults(withNS, b.Annotations["eventing.knative.dev/broker.class"]) eventing.DefaultBrokerClassIfUnset(withNS, &b.ObjectMeta) } -func (bs *BrokerSpec) SetDefaults(ctx context.Context) { +func (bs *BrokerSpec) SetDefaults(ctx context.Context, brokerClass string) { cfg := config.FromContextOrDefaults(ctx) - c, err := cfg.Defaults.GetBrokerConfig(apis.ParentMeta(ctx).Namespace) + c, err := cfg.Defaults.GetBrokerConfig(apis.ParentMeta(ctx).Namespace, &brokerClass) + + if bs.Config != nil { + c, err = cfg.Defaults.GetBrokerConfig(apis.ParentMeta(ctx).Namespace, &bs.Config.Kind) + } + if err == nil { if bs.Config == nil { bs.Config = c.KReference @@ -49,10 +54,14 @@ func (bs *BrokerSpec) SetDefaults(ctx context.Context) { BackoffDelay: c.Delivery.BackoffDelay, } } + } + // Default the namespace if not given if bs.Config != nil { bs.Config.SetDefaults(ctx) } + bs.Delivery.SetDefaults(ctx) + } diff --git a/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_validation.go b/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_validation.go index 51e30e10..345d2714 100644 --- a/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_validation.go +++ b/vendor/knative.dev/eventing/pkg/apis/eventing/v1/broker_validation.go @@ -33,36 +33,48 @@ const ( func (b *Broker) Validate(ctx context.Context) *apis.FieldError { ctx = apis.WithinParent(ctx, b.ObjectMeta) - cfg := config.FromContextOrDefaults(ctx) - var brConfig *config.ClassAndBrokerConfig - if cfg.Defaults != nil { - if c, ok := cfg.Defaults.NamespaceDefaultsConfig[b.GetNamespace()]; ok { - brConfig = c - } else { - brConfig = cfg.Defaults.ClusterDefault - } - } - withNS := ctx - if brConfig == nil || brConfig.DisallowDifferentNamespaceConfig == nil || !*brConfig.DisallowDifferentNamespaceConfig { - withNS = apis.AllowDifferentNamespace(ctx) - } + var errs *apis.FieldError + withNS := determineNamespaceAllowance(ctx, cfg.Defaults) // Make sure a BrokerClassAnnotation exists - var errs *apis.FieldError if bc, ok := b.GetAnnotations()[BrokerClassAnnotationKey]; !ok || bc == "" { errs = errs.Also(apis.ErrMissingField(BrokerClassAnnotationKey)) } + // Further validation logic errs = errs.Also(b.Spec.Validate(withNS).ViaField("spec")) if apis.IsInUpdate(ctx) { original := apis.GetBaseline(ctx).(*Broker) errs = errs.Also(b.CheckImmutableFields(ctx, original)) } + return errs } +// Determine if the namespace allowance based on the given configuration +func determineNamespaceAllowance(ctx context.Context, brConfig *config.Defaults) context.Context { + + // If there is no configurations set, allow different namespace by default + if brConfig == nil || (brConfig.NamespaceDefaultsConfig == nil && brConfig.ClusterDefaultConfig == nil) { + return apis.AllowDifferentNamespace(ctx) + } + namespace := apis.ParentMeta(ctx).Namespace + nsConfig := brConfig.NamespaceDefaultsConfig[namespace] + + // Check if the namespace disallows different namespace first + if nsConfig == nil || nsConfig.DisallowDifferentNamespaceConfig == nil || !*nsConfig.DisallowDifferentNamespaceConfig { + // If there is no namespace specific configuration or DisallowDifferentNamespaceConfig is false, check the cluster level configuration + if brConfig.ClusterDefaultConfig == nil || brConfig.ClusterDefaultConfig.DisallowDifferentNamespaceConfig == nil || !*brConfig.ClusterDefaultConfig.DisallowDifferentNamespaceConfig { + // If there is no cluster level configuration or DisallowDifferentNamespaceConfig in cluster level is false, allow different namespace + return apis.AllowDifferentNamespace(ctx) + } + } + // If we reach here, it means DisallowDifferentNamespaceConfig is true at either level, no need to explicitly disallow, just return the original context + return ctx +} + func (bs *BrokerSpec) Validate(ctx context.Context) *apis.FieldError { var errs *apis.FieldError diff --git a/vendor/modules.txt b/vendor/modules.txt index 81e4d80b..70a91e8c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -958,7 +958,7 @@ k8s.io/utils/pointer k8s.io/utils/ptr k8s.io/utils/strings/slices k8s.io/utils/trace -# knative.dev/eventing v0.42.1-0.20240816055941-2b922992c8f4 +# knative.dev/eventing v0.42.1-0.20240826165623-833f4aa12066 ## explicit; go 1.22.0 knative.dev/eventing/pkg/adapter/v2 knative.dev/eventing/pkg/adapter/v2/util/crstatusevent