mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-05-22 09:03:35 +00:00
@@ -6,5 +6,8 @@ ENV GO_PACKAGE github.com/open-cluster-management/placement
|
||||
RUN make build --warn-undefined-variables
|
||||
|
||||
FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
|
||||
ENV USER_UID=10001
|
||||
COPY --from=builder /go/src/github.com/open-cluster-management/placement/placement /
|
||||
RUN microdnf update && microdnf clean all
|
||||
|
||||
USER ${USER_UID}
|
||||
|
||||
55
cmd/placement/main.go
Normal file
55
cmd/placement/main.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
goflag "flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
utilflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/component-base/logs"
|
||||
|
||||
"github.com/open-cluster-management/placement/pkg/cmd/hub"
|
||||
"github.com/open-cluster-management/placement/pkg/version"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
|
||||
pflag.CommandLine.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
|
||||
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
|
||||
|
||||
logs.InitLogs()
|
||||
defer logs.FlushLogs()
|
||||
|
||||
command := newPlacementCommand()
|
||||
if err := command.Execute(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func newPlacementCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "placement",
|
||||
Short: "Placement Controller",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_ = cmd.Help()
|
||||
os.Exit(1)
|
||||
},
|
||||
}
|
||||
|
||||
if v := version.Get().String(); len(v) == 0 {
|
||||
cmd.Version = "<unknown>"
|
||||
} else {
|
||||
cmd.Version = v
|
||||
}
|
||||
|
||||
cmd.AddCommand(hub.NewController())
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -21,6 +21,7 @@ func RunControllerManager(ctx context.Context, controllerContext *controllercmd.
|
||||
|
||||
placementController := placement.NewPlacementController(
|
||||
clusterInformers.Cluster().V1().ManagedClusters(),
|
||||
clusterInformers.Cluster().V1alpha1().ManagedClusterSets(),
|
||||
controllerContext.EventRecorder,
|
||||
)
|
||||
|
||||
|
||||
66
pkg/controllers/placement/controller.go
Normal file
66
pkg/controllers/placement/controller.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package placement
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/openshift/library-go/pkg/controller/factory"
|
||||
"github.com/openshift/library-go/pkg/operator/events"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
clusterinformerv1 "github.com/open-cluster-management/api/client/cluster/informers/externalversions/cluster/v1"
|
||||
clusterinformerv1alpha1 "github.com/open-cluster-management/api/client/cluster/informers/externalversions/cluster/v1alpha1"
|
||||
clusterlisterv1 "github.com/open-cluster-management/api/client/cluster/listers/cluster/v1"
|
||||
clusterlisterv1alpha1 "github.com/open-cluster-management/api/client/cluster/listers/cluster/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
clusterSetLabel = "cluster.open-cluster-management.io/clusterset"
|
||||
)
|
||||
|
||||
// placementController makes placement decisions for Placements
|
||||
type placementController struct {
|
||||
clusterLister clusterlisterv1.ManagedClusterLister
|
||||
clusterSetLister clusterlisterv1alpha1.ManagedClusterSetLister
|
||||
}
|
||||
|
||||
// NewPlacementController return an instance of placementController
|
||||
func NewPlacementController(
|
||||
clusterInformer clusterinformerv1.ManagedClusterInformer,
|
||||
clusterSetInformer clusterinformerv1alpha1.ManagedClusterSetInformer,
|
||||
recorder events.Recorder,
|
||||
) factory.Controller {
|
||||
c := placementController{
|
||||
clusterLister: clusterInformer.Lister(),
|
||||
clusterSetLister: clusterSetInformer.Lister(),
|
||||
}
|
||||
|
||||
return factory.New().
|
||||
WithFilteredEventsInformersQueueKeyFunc(func(obj runtime.Object) string {
|
||||
accessor, _ := meta.Accessor(obj)
|
||||
return fmt.Sprintf("cluster:%s", accessor.GetName())
|
||||
}, func(obj interface{}) bool {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// ignore cluster belongs to no clusterset
|
||||
labels := accessor.GetLabels()
|
||||
clusterSetName, ok := labels[clusterSetLabel]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// ignore cluster if its clusterset does not exist
|
||||
_, err = c.clusterSetLister.Get(clusterSetName)
|
||||
return err == nil
|
||||
}, clusterInformer.Informer()).
|
||||
WithSync(c.sync).
|
||||
ToController("PlacementController", recorder)
|
||||
}
|
||||
|
||||
func (c *placementController) sync(ctx context.Context, syncCtx factory.SyncContext) error {
|
||||
return nil
|
||||
}
|
||||
44
pkg/controllers/placement/controller_test.go
Normal file
44
pkg/controllers/placement/controller_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package placement
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
|
||||
clusterfake "github.com/open-cluster-management/api/client/cluster/clientset/versioned/fake"
|
||||
clusterinformers "github.com/open-cluster-management/api/client/cluster/informers/externalversions"
|
||||
testinghelpers "github.com/open-cluster-management/placement/pkg/helpers/testing"
|
||||
)
|
||||
|
||||
func TestSync(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
queueKey string
|
||||
initObjs []runtime.Object
|
||||
validateActions func(t *testing.T, hubActions, agentActions []clienttesting.Action)
|
||||
}{}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
clusterClient := clusterfake.NewSimpleClientset(c.initObjs...)
|
||||
clusterInformerFactory := clusterinformers.NewSharedInformerFactory(clusterClient, time.Minute*10)
|
||||
clusterStore := clusterInformerFactory.Cluster().V1().ManagedClusters().Informer().GetStore()
|
||||
for _, cluster := range c.initObjs {
|
||||
clusterStore.Add(cluster)
|
||||
}
|
||||
|
||||
ctrl := placementController{
|
||||
clusterLister: clusterInformerFactory.Cluster().V1().ManagedClusters().Lister(),
|
||||
}
|
||||
syncErr := ctrl.sync(context.TODO(), testinghelpers.NewFakeSyncContext(t, c.queueKey))
|
||||
if syncErr != nil {
|
||||
t.Errorf("unexpected err: %v", syncErr)
|
||||
}
|
||||
|
||||
//c.validateActions(t, nil)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user