From 45a1ebb053c6a0441d8fe731bada15ec8ed926db Mon Sep 17 00:00:00 2001 From: Yang Le Date: Thu, 6 May 2021 15:37:21 +0800 Subject: [PATCH] add missing files Signed-off-by: Yang Le --- Dockerfile | 3 + cmd/placement/main.go | 55 ++++++++++++++++ pkg/controllers/manager.go | 1 + pkg/controllers/placement/controller.go | 66 ++++++++++++++++++++ pkg/controllers/placement/controller_test.go | 44 +++++++++++++ 5 files changed, 169 insertions(+) create mode 100644 cmd/placement/main.go create mode 100644 pkg/controllers/placement/controller.go create mode 100644 pkg/controllers/placement/controller_test.go diff --git a/Dockerfile b/Dockerfile index 2c1109ca4..29dfbe90e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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} diff --git a/cmd/placement/main.go b/cmd/placement/main.go new file mode 100644 index 000000000..b2bed4998 --- /dev/null +++ b/cmd/placement/main.go @@ -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 = "" + } else { + cmd.Version = v + } + + cmd.AddCommand(hub.NewController()) + + return cmd +} diff --git a/pkg/controllers/manager.go b/pkg/controllers/manager.go index b83f07bbf..1b21e30fc 100644 --- a/pkg/controllers/manager.go +++ b/pkg/controllers/manager.go @@ -21,6 +21,7 @@ func RunControllerManager(ctx context.Context, controllerContext *controllercmd. placementController := placement.NewPlacementController( clusterInformers.Cluster().V1().ManagedClusters(), + clusterInformers.Cluster().V1alpha1().ManagedClusterSets(), controllerContext.EventRecorder, ) diff --git a/pkg/controllers/placement/controller.go b/pkg/controllers/placement/controller.go new file mode 100644 index 000000000..6f5eec922 --- /dev/null +++ b/pkg/controllers/placement/controller.go @@ -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 +} diff --git a/pkg/controllers/placement/controller_test.go b/pkg/controllers/placement/controller_test.go new file mode 100644 index 000000000..6dab065fa --- /dev/null +++ b/pkg/controllers/placement/controller_test.go @@ -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) + }) + } +}