Skip to content

Commit

Permalink
IPPool controller
Browse files Browse the repository at this point in the history
Add IPPool controller, watching Pools.
The IP range allocations are available on the CR status.
Node controller triggers event on all Pools when
Node is added/updated/deleted.

Signed-off-by: Fred Rolland <[email protected]>
  • Loading branch information
rollandf committed Sep 12, 2023
1 parent 9a0db98 commit 2847204
Show file tree
Hide file tree
Showing 17 changed files with 730 additions and 973 deletions.
54 changes: 21 additions & 33 deletions cmd/ipam-controller/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,13 @@ import (

"github.com/go-logr/logr"
"github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/component-base/term"
"k8s.io/klog/v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/healthz"

Expand All @@ -40,12 +37,11 @@ import (
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"

ipamv1alpha1 "github.com/Mellanox/nvidia-k8s-ipam/api/v1alpha1"
"github.com/Mellanox/nvidia-k8s-ipam/cmd/ipam-controller/app/options"
"github.com/Mellanox/nvidia-k8s-ipam/pkg/common"
"github.com/Mellanox/nvidia-k8s-ipam/pkg/ipam-controller/allocator"
configmapctrl "github.com/Mellanox/nvidia-k8s-ipam/pkg/ipam-controller/controllers/configmap"
poolctrl "github.com/Mellanox/nvidia-k8s-ipam/pkg/ipam-controller/controllers/ippool"
nodectrl "github.com/Mellanox/nvidia-k8s-ipam/pkg/ipam-controller/controllers/node"
"github.com/Mellanox/nvidia-k8s-ipam/pkg/ipam-controller/selector"
"github.com/Mellanox/nvidia-k8s-ipam/pkg/version"
)

Expand Down Expand Up @@ -98,8 +94,7 @@ func RunController(ctx context.Context, config *rest.Config, opts *options.Optio
ctrl.SetLogger(logger)

logger.Info("start IPAM controller",
"version", version.GetVersionString(), "config", opts.ConfigMapName,
"configNamespace", opts.ConfigMapNamespace)
"version", version.GetVersionString(), "poolsNamespace", opts.IPPoolsNamespace)

scheme := runtime.NewScheme()

Expand All @@ -108,15 +103,14 @@ func RunController(ctx context.Context, config *rest.Config, opts *options.Optio
return err
}

if err := ipamv1alpha1.AddToScheme(scheme); err != nil {
logger.Error(err, "failed to register ipamv1alpha1 scheme")
return err
}

mgr, err := ctrl.NewManager(config, ctrl.Options{
Scheme: scheme,
NewCache: cache.BuilderWithOptions(cache.Options{
SelectorsByObject: cache.SelectorsByObject{&corev1.ConfigMap{}: cache.ObjectSelector{
Field: fields.AndSelectors(
fields.ParseSelectorOrDie(fmt.Sprintf("metadata.name=%s", opts.ConfigMapName)),
fields.ParseSelectorOrDie(fmt.Sprintf("metadata.namespace=%s", opts.ConfigMapNamespace))),
}},
}),
Scheme: scheme,
Namespace: opts.IPPoolsNamespace,
MetricsBindAddress: opts.MetricsAddr,
Port: 9443,
HealthProbeBindAddress: opts.ProbeAddr,
Expand All @@ -131,31 +125,25 @@ func RunController(ctx context.Context, config *rest.Config, opts *options.Optio
return err
}

netAllocator := allocator.New()
nodeSelector := selector.New()
configEventCH := make(chan event.GenericEvent, 1)
nodeEventCH := make(chan event.GenericEvent, 1)

if err = (&nodectrl.NodeReconciler{
Allocator: netAllocator,
Selector: nodeSelector,
ConfigEventCh: configEventCH,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
NodeEventCh: nodeEventCH,
PoolsNamespace: opts.IPPoolsNamespace,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
logger.Error(err, "unable to create controller", "controller", "Node")
return err
}

if err = (&configmapctrl.ConfigMapReconciler{
Allocator: netAllocator,
Selector: nodeSelector,
ConfigEventCh: configEventCH,
ConfigMapName: opts.ConfigMapName,
ConfigMapNamespace: opts.ConfigMapNamespace,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
if err = (&poolctrl.IPPoolReconciler{
NodeEventCh: nodeEventCH,
PoolsNamespace: opts.IPPoolsNamespace,
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
logger.Error(err, "unable to create controller", "controller", "ConfigMap")
logger.Error(err, "unable to create controller", "controller", "IPPool")
return err
}

Expand Down
15 changes: 13 additions & 2 deletions cmd/ipam-controller/app/app_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ import (
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"

ipamv1alpha1 "github.com/Mellanox/nvidia-k8s-ipam/api/v1alpha1"
)

const (
Expand All @@ -46,17 +49,25 @@ func TestApp(t *testing.T) {

var _ = BeforeSuite(func() {
By("bootstrapping test environment")
testEnv = &envtest.Environment{}
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{"../../../deploy/crds"},
CRDInstallOptions: envtest.CRDInstallOptions{
ErrorIfPathMissing: true,
},
}

ctx, cFunc = context.WithCancel(context.Background())

var err error
err = ipamv1alpha1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

// cfg is defined in this file globally.
cfg, err = testEnv.Start()
Expect(err).NotTo(HaveOccurred())
Expect(cfg).NotTo(BeNil())

k8sClient, err = client.New(cfg, client.Options{})
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).NotTo(HaveOccurred())
Expect(k8sClient).NotTo(BeNil())

Expand Down
Loading

0 comments on commit 2847204

Please sign in to comment.