Skip to content
Merged
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
23 changes: 9 additions & 14 deletions cmd/epp/runner/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,54 +44,49 @@ func RegisterAllPlugins() {

// eppHandle is an implementation of the interface plugins.Handle
type eppHandle struct {
ctx context.Context
plugins plugins.HandlePlugins
ctx context.Context
plugins.HandlePlugins
}

// Context returns a context the plugins can use, if they need one
func (h *eppHandle) Context() context.Context {
return h.ctx
}

// Plugins returns the sub-handle for working with instantiated plugins
func (h *eppHandle) Plugins() plugins.HandlePlugins {
return h.plugins
}

// eppHandlePlugins implements the set of APIs to work with instantiated plugins
type eppHandlePlugins struct {
thePlugins map[string]plugins.Plugin
plugins map[string]plugins.Plugin
}

// Plugin returns the named plugin instance
func (h *eppHandlePlugins) Plugin(name string) plugins.Plugin {
return h.thePlugins[name]
return h.plugins[name]
}

// AddPlugin adds a plugin to the set of known plugin instances
func (h *eppHandlePlugins) AddPlugin(name string, plugin plugins.Plugin) {
h.thePlugins[name] = plugin
h.plugins[name] = plugin
}

// GetAllPlugins returns all of the known plugins
func (h *eppHandlePlugins) GetAllPlugins() []plugins.Plugin {
result := make([]plugins.Plugin, 0)
for _, plugin := range h.thePlugins {
for _, plugin := range h.plugins {
result = append(result, plugin)
}
return result
}

// GetAllPluginsWithNames returns al of the known plugins with their names
func (h *eppHandlePlugins) GetAllPluginsWithNames() map[string]plugins.Plugin {
return h.thePlugins
return h.plugins
}

func newEppHandle(ctx context.Context) *eppHandle {
return &eppHandle{
ctx: ctx,
plugins: &eppHandlePlugins{
thePlugins: map[string]plugins.Plugin{},
HandlePlugins: &eppHandlePlugins{
plugins: map[string]plugins.Plugin{},
},
}
}
2 changes: 1 addition & 1 deletion cmd/epp/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ func (r *Runner) parseConfiguration(ctx context.Context) error {
}

// Add requestControl plugins
r.requestControlConfig.AddPlugins(handle.Plugins().GetAllPlugins()...)
r.requestControlConfig.AddPlugins(handle.GetAllPlugins()...)

return nil
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/epp/common/config/loader/configloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func LoadSchedulerConfig(configProfiles []v1alpha1.SchedulingProfile, handle plu
for _, namedProfile := range configProfiles {
profile := framework.NewSchedulerProfile()
for _, plugin := range namedProfile.Plugins {
referencedPlugin := handle.Plugins().Plugin(plugin.PluginRef)
referencedPlugin := handle.Plugin(plugin.PluginRef)
if scorer, ok := referencedPlugin.(framework.Scorer); ok {
if plugin.Weight == nil {
return nil, fmt.Errorf("scorer '%s' is missing a weight", plugin.PluginRef)
Expand All @@ -81,7 +81,7 @@ func LoadSchedulerConfig(configProfiles []v1alpha1.SchedulingProfile, handle plu
}

var profileHandler framework.ProfileHandler
for pluginName, plugin := range handle.Plugins().GetAllPluginsWithNames() {
for pluginName, plugin := range handle.GetAllPluginsWithNames() {
if theProfileHandler, ok := plugin.(framework.ProfileHandler); ok {
if profileHandler != nil {
return nil, fmt.Errorf("only one profile handler is allowed. Both %s and %s are profile handlers", profileHandler.TypedName().Name, pluginName)
Expand Down Expand Up @@ -119,7 +119,7 @@ func instantiatePlugins(configuredPlugins []configapi.PluginSpec, handle plugins
return fmt.Errorf("failed to instantiate the plugin type '%s' - %w", pluginConfig.Type, err)
}

handle.Plugins().AddPlugin(pluginConfig.Name, plugin)
handle.AddPlugin(pluginConfig.Name, plugin)
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions pkg/epp/common/config/loader/configloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,10 @@ func TestInstantiatePlugins(t *testing.T) {
if err != nil {
t.Fatalf("LoadConfig returned unexpected error - %v", err)
}
if len(handle.Plugins().GetAllPlugins()) == 0 {
if len(handle.GetAllPlugins()) == 0 {
t.Fatalf("unexpected empty set of loaded plugins")
}
if t1 := handle.Plugins().Plugin("test1"); t1 == nil {
if t1 := handle.Plugin("test1"); t1 == nil {
t.Fatalf("loaded plugins did not contain test1")
} else if _, ok := t1.(*test1); !ok {
t.Fatalf("loaded plugins returned test1 has the wrong type %#v", t1)
Expand Down
60 changes: 60 additions & 0 deletions pkg/epp/plugins/handle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
Copyright 2025 The Kubernetes Authors.

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 plugins

import (
"context"
"fmt"
)

// Handle provides plugins a set of standard data and tools to work with
type Handle interface {
// Context returns a context the plugins can use, if they need one
Context() context.Context

HandlePlugins
}

// HandlePlugins defines a set of APIs to work with instantiated plugins
type HandlePlugins interface {
// Plugin returns the named plugin instance
Plugin(name string) Plugin

// AddPlugin adds a plugin to the set of known plugin instances
AddPlugin(name string, plugin Plugin)

// GetAllPlugins returns all of the known plugins
GetAllPlugins() []Plugin

// GetAllPluginsWithNames returns all of the known plugins with their names
GetAllPluginsWithNames() map[string]Plugin
}

// PluginByType retrieves the specified plugin by name and verifies its type
func PluginByType[P Plugin](handlePlugins HandlePlugins, name string) (P, error) {
var zero P

rawPlugin := handlePlugins.Plugin(name)
if rawPlugin == nil {
return zero, fmt.Errorf("there is no plugin with the name '%s' defined", name)
}
plugin, ok := rawPlugin.(P)
if !ok {
return zero, fmt.Errorf("the plugin with the name '%s' is not an instance of %T", name, zero)
}
return plugin, nil
}
44 changes: 0 additions & 44 deletions pkg/epp/plugins/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,53 +16,9 @@ limitations under the License.

package plugins

import (
"context"
"fmt"
)

// Plugin defines the interface for a plugin.
// This interface should be embedded in all plugins across the code.
type Plugin interface {
// TypedName returns the type and name tuple of this plugin instance.
TypedName() TypedName
}

// Handle provides plugins a set of standard data and tools to work with
type Handle interface {
// Context returns a context the plugins can use, if they need one
Context() context.Context

// Plugins returns the sub-handle for working with instantiated plugins
Plugins() HandlePlugins
}

// HandlePlugins defines a set of APIs to work with instantiated plugins
type HandlePlugins interface {
// Plugin returns the named plugin instance
Plugin(name string) Plugin

// AddPlugin adds a plugin to the set of known plugin instances
AddPlugin(name string, plugin Plugin)

// GetAllPlugins returns all of the known plugins
GetAllPlugins() []Plugin

// GetAllPluginsWithNames returns all of the known plugins with their names
GetAllPluginsWithNames() map[string]Plugin
}

// PluginByType retrieves the specified plugin by name and verifies its type
func PluginByType[P Plugin](handlePlugins HandlePlugins, name string) (P, error) {
var zero P

rawPlugin := handlePlugins.Plugin(name)
if rawPlugin == nil {
return zero, fmt.Errorf("there is no plugin with the name '%s' defined", name)
}
thePlugin, ok := rawPlugin.(P)
if !ok {
return zero, fmt.Errorf("the plugin with the name '%s' is not an instance of %T", name, zero)
}
return thePlugin, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func loadDecisionTreeEntry(entry *decisionTreeFilterEntry, handle plugins.Handle
}

if entry.PluginRef != nil {
instance := handle.Plugins().Plugin(*entry.PluginRef)
instance := handle.Plugin(*entry.PluginRef)
if instance == nil {
return nil, errors.New(*entry.PluginRef + " is a reference to an undefined Plugin")
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/epp/scheduling/framework/plugins/filter/filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,12 @@ func TestDecisionTreeFilterFactory(t *testing.T) {

testHandle := utils.NewTestHandle(context.Background())

testHandle.Plugins().AddPlugin("leastKvCache", leastKvCacheFilter)
testHandle.Plugins().AddPlugin("leastQueue", leastQueueFilter)
testHandle.Plugins().AddPlugin("loraAffinity", loraAffinityFilter)
testHandle.Plugins().AddPlugin("lowQueue", lowQueueFilter)
testHandle.AddPlugin("leastKvCache", leastKvCacheFilter)
testHandle.AddPlugin("leastQueue", leastQueueFilter)
testHandle.AddPlugin("loraAffinity", loraAffinityFilter)
testHandle.AddPlugin("lowQueue", lowQueueFilter)

testHandle.Plugins().AddPlugin("kvCacheScorer", kvCacheScorer)
testHandle.AddPlugin("kvCacheScorer", kvCacheScorer)

tests := []struct {
name string
Expand Down
22 changes: 9 additions & 13 deletions test/utils/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,48 +24,44 @@ import (

// testHandle is an implmentation of plugins.Handle for test purposes
type testHandle struct {
ctx context.Context
plugins plugins.HandlePlugins
ctx context.Context
plugins.HandlePlugins
}

// Context returns a context the plugins can use, if they need one
func (h *testHandle) Context() context.Context {
return h.ctx
}

func (h *testHandle) Plugins() plugins.HandlePlugins {
return h.plugins
}

type testHandlePlugins struct {
thePlugins map[string]plugins.Plugin
plugins map[string]plugins.Plugin
}

func (h *testHandlePlugins) Plugin(name string) plugins.Plugin {
return h.thePlugins[name]
return h.plugins[name]
}

func (h *testHandlePlugins) AddPlugin(name string, plugin plugins.Plugin) {
h.thePlugins[name] = plugin
h.plugins[name] = plugin
}

func (h *testHandlePlugins) GetAllPlugins() []plugins.Plugin {
result := make([]plugins.Plugin, 0)
for _, plugin := range h.thePlugins {
for _, plugin := range h.plugins {
result = append(result, plugin)
}
return result
}

func (h *testHandlePlugins) GetAllPluginsWithNames() map[string]plugins.Plugin {
return h.thePlugins
return h.plugins
}

func NewTestHandle(ctx context.Context) plugins.Handle {
return &testHandle{
ctx: ctx,
plugins: &testHandlePlugins{
thePlugins: map[string]plugins.Plugin{},
HandlePlugins: &testHandlePlugins{
plugins: map[string]plugins.Plugin{},
},
}
}