Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 59 additions & 7 deletions apix/config/v1alpha1/endpointpickerconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ import (
type EndpointPickerConfig struct {
metav1.TypeMeta `json:",inline"`

// +optional
// FeatureGates is a set of flags that enable various experimental features with the EPP.
// If omitted non of these experimental features will be enabled.
FeatureGates FeatureGates `json:"featureGates,omitempty"`

// +required
// +kubebuilder:validation:Required
// Plugins is the list of plugins that will be instantiated.
Expand All @@ -41,23 +46,23 @@ type EndpointPickerConfig struct {
// that will be created.
SchedulingProfiles []SchedulingProfile `json:"schedulingProfiles"`

// +optional
// FeatureGates is a set of flags that enable various experimental features with the EPP.
// If omitted non of these experimental features will be enabled.
FeatureGates FeatureGates `json:"featureGates,omitempty"`

// +optional
// SaturationDetector when present specifies the configuration of the
// Saturation detector. If not present, default values are used.
SaturationDetector *SaturationDetector `json:"saturationDetector,omitempty"`

// +optional
// Data configures the DataLayer. It is required if the new DataLayer is enabled.
Data *DataLayerConfig `json:"data"`
}

func (cfg EndpointPickerConfig) String() string {
return fmt.Sprintf(
"{Plugins: %v, SchedulingProfiles: %v, FeatureGates: %v, SaturationDetector: %v}",
"{FeatureGates: %v, Plugins: %v, SchedulingProfiles: %v, Data: %v, SaturationDetector: %v}",
cfg.FeatureGates,
cfg.Plugins,
cfg.SchedulingProfiles,
cfg.FeatureGates,
cfg.Data,
cfg.SaturationDetector,
)
}
Expand Down Expand Up @@ -193,3 +198,50 @@ func (sd *SaturationDetector) String() string {
}
return "{" + result + "}"
}

// DataLayerConfig contains the configuration of the DataLayer feature
type DataLayerConfig struct {
// +required
// +kubebuilder:validation:Required
// Sources is the list of sources to define to the DataLayer
Sources []DataLayerSource `json:"sources"`
}

func (dlc DataLayerConfig) String() string {
return fmt.Sprintf("{Sources: %v}", dlc.Sources)
}

// DataLayerSource contains the configuration of a DataSource of the DataLayer feature
type DataLayerSource struct {
// +required
// +kubebuilder:validation:Required
// PluginRef specifies a partiular Plugin instance to be associated with
// this Source. The reference is to the name of an entry of the Plugins
// defined in the configuration's Plugins section
PluginRef string `json:"pluginRef"`

// +required
// +kubebuilder:validation:Required
// Extractors specifies the list of Plugin instances to be associated with
// this Source. The entries are references to the names of entries of the Plugins
// defined in the configuration's Plugins section
Extractors []DataLayerExtractor `json:"extractors"`
}

func (dls DataLayerSource) String() string {
return fmt.Sprintf("{PluginRef: %s, Extractors: %v}", dls.PluginRef, dls.Extractors)
}

// DataLayerExtractor contains the configuration of an Extractor of the DataLayer feature
type DataLayerExtractor struct {
// +required
// +kubebuilder:validation:Required
// PluginRef specifies a partiular Plugin instance to be associated with
// this Extractor. The reference is to the name of an entry of the Plugins
// defined in the configuration's Plugins section
PluginRef string `json:"pluginRef"`
}

func (dle DataLayerExtractor) String() string {
return "{PluginRef: " + dle.PluginRef + "}"
}
72 changes: 67 additions & 5 deletions apix/config/v1alpha1/zz_generated.deepcopy.go

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

2 changes: 2 additions & 0 deletions pkg/epp/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package config

import (
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/saturationdetector"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling"
)
Expand All @@ -25,4 +26,5 @@ import (
type Config struct {
SchedulerConfig *scheduling.SchedulerConfig
SaturationDetectorConfig *saturationdetector.Config
DataConfig *datalayer.Config
}
44 changes: 44 additions & 0 deletions pkg/epp/config/loader/configloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (

configapi "sigs.k8s.io/gateway-api-inference-extension/apix/config/v1alpha1"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/config"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/datalayer"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/plugins"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/saturationdetector"
"sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling"
Expand Down Expand Up @@ -87,6 +88,11 @@ func LoadConfigPhaseTwo(rawConfig *configapi.EndpointPickerConfig, handle plugin
}
config.SaturationDetectorConfig = loadSaturationDetectorConfig(rawConfig.SaturationDetector)

config.DataConfig, err = loadDataLayerConfig(rawConfig.Data, rawConfig.FeatureGates, handle)
if err != nil {
return nil, err
}

return config, nil
}

Expand Down Expand Up @@ -170,6 +176,44 @@ func loadSaturationDetectorConfig(sd *configapi.SaturationDetector) *saturationd
return &sdConfig
}

func loadDataLayerConfig(rawDataConfig *configapi.DataLayerConfig, rawFeatureGates configapi.FeatureGates, handle plugins.Handle) (*datalayer.Config, error) {
featureGates := loadFeatureConfig(rawFeatureGates)
if !featureGates[datalayer.FeatureGate] {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we return an error if the datalayer (or any feature) is configured with plugins but the feature gate is closed? A user may want to know about that early on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a check and an error.

if rawDataConfig != nil {
return nil, errors.New("the Datalayer has not been enabled, but you specified a configuration for it")
}
return nil, nil
}

if rawDataConfig == nil {
return nil, errors.New("the Datalayer has been enabled. You must specify the Data section in the configuration")
}

dataConfig := datalayer.Config{
Sources: []datalayer.DataSourceConfig{},
}
for _, source := range rawDataConfig.Sources {
if sourcePlugin, ok := handle.Plugin(source.PluginRef).(datalayer.DataSource); ok {
sourceConfig := datalayer.DataSourceConfig{
Plugin: sourcePlugin,
Extractors: []datalayer.Extractor{},
}
for _, extractor := range source.Extractors {
if extractorPlugin, ok := handle.Plugin(extractor.PluginRef).(datalayer.Extractor); ok {
sourceConfig.Extractors = append(sourceConfig.Extractors, extractorPlugin)
} else {
return nil, fmt.Errorf("the plugin %s is not a datalayer.Extractor", source.PluginRef)
}
}
dataConfig.Sources = append(dataConfig.Sources, sourceConfig)
} else {
return nil, fmt.Errorf("the plugin %s is not a datalayer.Source", source.PluginRef)
}
}

return &dataConfig, nil
}

func instantiatePlugins(configuredPlugins []configapi.PluginSpec, handle plugins.Handle) error {
pluginNames := sets.New[string]() // set of plugin names, a name must be unique

Expand Down
Loading