process nodes
diff --git a/core/nebula/apis/nebula/v1/register.go b/core/nebula/apis/nebula/v1/register.go
index 3e17a02..5586188 100644
--- a/core/nebula/apis/nebula/v1/register.go
+++ b/core/nebula/apis/nebula/v1/register.go
@@ -33,6 +33,8 @@
scheme.AddKnownTypes(SchemeGroupVersion,
&NebulaCA{},
&NebulaCAList{},
+ &NebulaNode{},
+ &NebulaNodeList{},
)
scheme.AddKnownTypes(SchemeGroupVersion,
diff --git a/core/nebula/apis/nebula/v1/types.go b/core/nebula/apis/nebula/v1/types.go
index 0eddd7b..1a33752 100644
--- a/core/nebula/apis/nebula/v1/types.go
+++ b/core/nebula/apis/nebula/v1/types.go
@@ -4,10 +4,9 @@
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
-// genclient:nonNamespaced
-
-// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient
+// genclient:nonNamespaced
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type NebulaCA struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata"`
@@ -40,3 +39,41 @@
Items []NebulaCA `json:"items"`
}
+
+// +genclient
+// genclient:nonNamespaced
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+type NebulaNode struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata"`
+
+ Spec NebulaNodeSpec `json:"spec"`
+ Status NebulaNodeStatus `json:"status,omitempty"`
+}
+
+type NebulaNodeSpec struct {
+ CAName string `json:"caName"`
+ NodeName string `json:"nodeName"`
+ IPCidr string `json:"ipCidr"`
+ SecretName string `json:"secretName"`
+}
+
+type NebulaNodeStatus struct {
+ State NebulaNodeState `json:"state,omitempty"`
+ Message string `json:"message,omitempty"`
+}
+
+type NebulaNodeState string
+
+const (
+ NebulaNodeStateCreating NebulaNodeState = "Creating"
+ NebulaNodeStateReady NebulaNodeState = "Ready"
+)
+
+// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
+type NebulaNodeList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata"`
+
+ Items []NebulaNode `json:"items"`
+}
diff --git a/core/nebula/apis/nebula/v1/zz_generated.deepcopy.go b/core/nebula/apis/nebula/v1/zz_generated.deepcopy.go
index 2acd8b3..e47733d 100644
--- a/core/nebula/apis/nebula/v1/zz_generated.deepcopy.go
+++ b/core/nebula/apis/nebula/v1/zz_generated.deepcopy.go
@@ -102,3 +102,96 @@
in.DeepCopyInto(out)
return out
}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NebulaNode) DeepCopyInto(out *NebulaNode) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebulaNode.
+func (in *NebulaNode) DeepCopy() *NebulaNode {
+ if in == nil {
+ return nil
+ }
+ out := new(NebulaNode)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *NebulaNode) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NebulaNodeList) DeepCopyInto(out *NebulaNodeList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]NebulaNode, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebulaNodeList.
+func (in *NebulaNodeList) DeepCopy() *NebulaNodeList {
+ if in == nil {
+ return nil
+ }
+ out := new(NebulaNodeList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *NebulaNodeList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NebulaNodeSpec) DeepCopyInto(out *NebulaNodeSpec) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebulaNodeSpec.
+func (in *NebulaNodeSpec) DeepCopy() *NebulaNodeSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(NebulaNodeSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NebulaNodeStatus) DeepCopyInto(out *NebulaNodeStatus) {
+ *out = *in
+ return
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebulaNodeStatus.
+func (in *NebulaNodeStatus) DeepCopy() *NebulaNodeStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(NebulaNodeStatus)
+ in.DeepCopyInto(out)
+ return out
+}
diff --git a/core/nebula/controllers/ca.go b/core/nebula/controllers/ca.go
index e5279da..452b9e5 100644
--- a/core/nebula/controllers/ca.go
+++ b/core/nebula/controllers/ca.go
@@ -15,44 +15,74 @@
"k8s.io/apimachinery/pkg/selection"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
+ corev1informers "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
+ corev1listers "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
"k8s.io/klog/v2"
nebulav1 "github.com/giolekva/pcloud/core/nebula/apis/nebula/v1"
clientset "github.com/giolekva/pcloud/core/nebula/generated/clientset/versioned"
- informers "github.com/giolekva/pcloud/core/nebula/generated/informers/externalversions"
+ informers "github.com/giolekva/pcloud/core/nebula/generated/informers/externalversions/nebula/v1"
listers "github.com/giolekva/pcloud/core/nebula/generated/listers/nebula/v1"
)
var secretImmutable = true
+type caRef struct {
+ key string
+}
+
+type nodeRef struct {
+ key string
+}
+
type CAController struct {
kubeClient kubernetes.Interface
nebulaClient clientset.Interface
caLister listers.NebulaCALister
caSynced cache.InformerSynced
+ nodeLister listers.NebulaNodeLister
+ nodeSynced cache.InformerSynced
+ secretLister corev1listers.SecretLister
+ secretSynced cache.InformerSynced
workqueue workqueue.RateLimitingInterface
nebulaCert string
}
-func NewCAController(kubeClient kubernetes.Interface, nebulaClient clientset.Interface, nebulaInformerFactory informers.SharedInformerFactory, nebulaCert string) *CAController {
- nebulaInformer := nebulaInformerFactory.Lekva().V1().NebulaCAs().Informer()
+func NewCAController(kubeClient kubernetes.Interface,
+ nebulaClient clientset.Interface,
+ caInformer informers.NebulaCAInformer,
+ nodeInformer informers.NebulaNodeInformer,
+ secretInformer corev1informers.SecretInformer,
+ nebulaCert string) *CAController {
c := &CAController{
kubeClient: kubeClient,
nebulaClient: nebulaClient,
- caLister: nebulaInformerFactory.Lekva().V1().NebulaCAs().Lister(),
- caSynced: nebulaInformer.HasSynced,
- workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "NebulaCAs"),
+ caLister: caInformer.Lister(),
+ caSynced: caInformer.Informer().HasSynced,
+ nodeLister: nodeInformer.Lister(),
+ nodeSynced: nodeInformer.Informer().HasSynced,
+ secretLister: secretInformer.Lister(),
+ secretSynced: secretInformer.Informer().HasSynced,
+ workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Nebula"),
nebulaCert: nebulaCert,
}
- nebulaInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
- AddFunc: c.enqueue,
+ caInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
+ AddFunc: c.enqueueCA,
UpdateFunc: func(_, o interface{}) {
- c.enqueue(o)
+ c.enqueueCA(o)
+ },
+ DeleteFunc: func(o interface{}) {
+ },
+ })
+ nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
+ AddFunc: c.enqueueNode,
+ UpdateFunc: func(_, o interface{}) {
+ c.enqueueNode(o)
},
DeleteFunc: func(o interface{}) {
},
@@ -61,14 +91,24 @@
return c
}
-func (c *CAController) enqueue(o interface{}) {
+func (c *CAController) enqueueCA(o interface{}) {
var key string
var err error
if key, err = cache.MetaNamespaceKeyFunc(o); err != nil {
utilruntime.HandleError(err)
return
}
- c.workqueue.Add(key)
+ c.workqueue.Add(caRef{key})
+}
+
+func (c *CAController) enqueueNode(o interface{}) {
+ var key string
+ var err error
+ if key, err = cache.MetaNamespaceKeyFunc(o); err != nil {
+ utilruntime.HandleError(err)
+ return
+ }
+ c.workqueue.Add(nodeRef{key})
}
func (c *CAController) Run(workers int, stopCh <-chan struct{}) error {
@@ -76,7 +116,7 @@
defer c.workqueue.ShutDown()
klog.Info("Starting NebulaCA controller")
klog.Info("Waiting for informer caches to sync")
- if ok := cache.WaitForCacheSync(stopCh, c.caSynced); !ok {
+ if ok := cache.WaitForCacheSync(stopCh, c.caSynced, c.nodeSynced, c.secretSynced); !ok {
return fmt.Errorf("Failed to wait for caches to sync")
}
fmt.Println("Starting workers")
@@ -101,19 +141,24 @@
}
err := func(o interface{}) error {
defer c.workqueue.Done(o)
- var key string
- var ok bool
- if key, ok = o.(string); !ok {
+ if ref, ok := o.(caRef); ok {
+ if err := c.processCAWithKey(ref.key); err != nil {
+ c.workqueue.AddRateLimited(ref)
+ return fmt.Errorf("Error syncing '%s': %s, requeuing", ref.key, err.Error())
+ }
+ fmt.Printf("Successfully synced CA '%s'\n", ref.key)
+ } else if ref, ok := o.(nodeRef); ok {
+ if err := c.processNodeWithKey(ref.key); err != nil {
+ c.workqueue.AddRateLimited(ref)
+ return fmt.Errorf("Error syncing '%s': %s, requeuing", ref.key, err.Error())
+ }
+ fmt.Printf("Successfully synced Node '%s'\n", ref.key)
+ } else {
c.workqueue.Forget(o)
- utilruntime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", o))
+ utilruntime.HandleError(fmt.Errorf("expected reference in workqueue but got %#v", o))
return nil
}
- if err := c.processCAWithKey(key); err != nil {
- c.workqueue.AddRateLimited(key)
- return fmt.Errorf("Rrror syncing '%s': %s, requeuing", key, err.Error())
- }
c.workqueue.Forget(o)
- fmt.Printf("Successfully synced '%s'\n", key)
return nil
}(o)
if err != nil {
@@ -151,14 +196,66 @@
if err != nil {
panic(err)
}
- err = c.updateStatus(ca, nebulav1.NebulaCAStateReady, "Generated credentials")
+ err = c.updateCAStatus(ca, nebulav1.NebulaCAStateReady, "Generated credentials")
if err != nil {
panic(err)
}
return nil
}
-func (c *CAController) updateStatus(ca *nebulav1.NebulaCA, state nebulav1.NebulaCAState, msg string) error {
+func (c *CAController) processNodeWithKey(key string) error {
+ namespace, name, err := cache.SplitMetaNamespaceKey(key)
+ if err != nil {
+ return nil
+ }
+ node, err := c.getNode(namespace, name)
+ if err != nil {
+ panic(err)
+ }
+ if node.Status.State == nebulav1.NebulaNodeStateReady {
+ fmt.Printf("%s Node is already in Ready state\n", node.Name)
+ return nil
+ }
+ ca, err := c.getCA(namespace, node.Spec.CAName)
+ if ca.Status.State != nebulav1.NebulaCAStateReady {
+ return fmt.Errorf("Referenced CA %s is not ready yet.", node.Spec.CAName)
+ }
+ caSecret, err := c.getSecret(ca.Namespace, ca.Spec.SecretName)
+ if err != nil {
+ panic(err)
+ }
+ dir, err := extractSecret(caSecret)
+ if err != nil {
+ panic(err)
+ }
+ if err := generateNodeKey(node.Spec.NodeName, node.Spec.IPCidr, dir, c.nebulaCert); err != nil {
+ panic(err)
+ }
+ defer os.RemoveAll(dir)
+ if err := os.Remove(filepath.Join(dir, "ca.key")); err != nil {
+ panic(err)
+ }
+ if err := os.Remove(filepath.Join(dir, "ca.png")); err != nil {
+ panic(err)
+ }
+ secret, err := createSecretFromDir(dir)
+ if err != nil {
+ panic(err)
+ }
+ secret.Immutable = &secretImmutable
+ secret.Name = node.Spec.SecretName
+ _, err = c.kubeClient.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
+ if err != nil {
+ panic(err)
+ }
+ err = c.updateNodeStatus(node, nebulav1.NebulaNodeStateReady, "Generated credentials")
+ if err != nil {
+ panic(err)
+ }
+ return nil
+}
+
+func (c *CAController) updateCAStatus(ca *nebulav1.NebulaCA, state nebulav1.NebulaCAState, msg string) error {
cp := ca.DeepCopy()
cp.Status.State = state
cp.Status.Message = msg
@@ -166,6 +263,14 @@
return err
}
+func (c *CAController) updateNodeStatus(node *nebulav1.NebulaNode, state nebulav1.NebulaNodeState, msg string) error {
+ cp := node.DeepCopy()
+ cp.Status.State = state
+ cp.Status.Message = msg
+ _, err := c.nebulaClient.LekvaV1().NebulaNodes(cp.Namespace).UpdateStatus(context.TODO(), cp, metav1.UpdateOptions{})
+ return err
+}
+
func createSecretFromDir(path string) (*corev1.Secret, error) {
all, err := ioutil.ReadDir(path)
if err != nil {
@@ -187,12 +292,25 @@
return secret, nil
}
+func extractSecret(secret *corev1.Secret) (string, error) {
+ tmp, err := os.MkdirTemp("", secret.Name)
+ if err != nil {
+ return "", err
+ }
+ for name, data := range secret.Data {
+ if err := ioutil.WriteFile(filepath.Join(tmp, name), data, 0644); err != nil {
+ defer os.RemoveAll(tmp)
+ return "", nil
+ }
+ }
+ return tmp, nil
+}
+
func generateCAKey(name, nebulaCert string) (string, error) {
tmp, err := os.MkdirTemp("", name)
if err != nil {
return "", err
}
- fmt.Println(tmp)
cmd := exec.Command(nebulaCert, "ca",
"-name", name,
"-out-key", filepath.Join(tmp, "ca.key"),
@@ -204,6 +322,21 @@
return tmp, nil
}
+func generateNodeKey(name, ip, dir, nebulaCert string) error {
+ cmd := exec.Command(nebulaCert, "sign",
+ "-ca-crt", filepath.Join(dir, "ca.crt"),
+ "-ca-key", filepath.Join(dir, "ca.key"),
+ "-name", name,
+ "-ip", ip,
+ "-out-key", filepath.Join(dir, "host.key"),
+ "-out-crt", filepath.Join(dir, "host.crt"),
+ "-out-qr", filepath.Join(dir, "host.png"))
+ if d, err := cmd.CombinedOutput(); err != nil {
+ return fmt.Errorf(string(d))
+ }
+ return nil
+}
+
func (c *CAController) getCA(namespace, name string) (*nebulav1.NebulaCA, error) {
s := labels.NewSelector()
r, err := labels.NewRequirement("metadata.namespace", selection.Equals, []string{namespace})
@@ -224,3 +357,28 @@
}
return ncas[0], nil
}
+
+func (c *CAController) getNode(namespace, name string) (*nebulav1.NebulaNode, error) {
+ s := labels.NewSelector()
+ r, err := labels.NewRequirement("metadata.namespace", selection.Equals, []string{namespace})
+ if err != nil {
+ panic(err)
+ }
+ r1, err := labels.NewRequirement("metadata.name", selection.Equals, []string{name})
+ if err != nil {
+ panic(err)
+ }
+ s.Add(*r, *r1)
+ nodes, err := c.nodeLister.List(s)
+ if err != nil {
+ panic(err)
+ }
+ if len(nodes) != 1 {
+ panic("err")
+ }
+ return nodes[0], nil
+}
+
+func (c *CAController) getSecret(namespace, name string) (*corev1.Secret, error) {
+ return c.secretLister.Secrets(namespace).Get(name)
+}
diff --git a/core/nebula/crds/nebula.crds.yaml b/core/nebula/crds/nebula.crds.yaml
index 984b2c9..d75cac0 100644
--- a/core/nebula/crds/nebula.crds.yaml
+++ b/core/nebula/crds/nebula.crds.yaml
@@ -37,3 +37,47 @@
type: string
message:
type: string
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ name: nebulanodes.lekva.me
+spec:
+ group: lekva.me
+ scope: Namespaced
+ names:
+ kind: NebulaNode
+ listKind: NebulaNodeList
+ plural: nebulanodes
+ singular: nebulanode
+ shortNames:
+ - nnode
+ - nnodes
+ versions:
+ - name: v1
+ served: true
+ storage: true
+ subresources:
+ status: {}
+ schema:
+ openAPIV3Schema:
+ type: object
+ properties:
+ spec:
+ type: object
+ properties:
+ caName:
+ type: string
+ nodeName:
+ type: string
+ ipCidr:
+ type: string
+ secretName:
+ type: string
+ status:
+ type: object
+ properties:
+ state:
+ type: string
+ message:
+ type: string
diff --git a/core/nebula/crds/test-node.yaml b/core/nebula/crds/test-node.yaml
new file mode 100644
index 0000000..bcabecf
--- /dev/null
+++ b/core/nebula/crds/test-node.yaml
@@ -0,0 +1,10 @@
+apiVersion: lekva.me/v1
+kind: NebulaNode
+metadata:
+ name: test-host
+ namespace: test-nebula
+spec:
+ caName: lekva-pcloud
+ nodeName: lighthouse
+ ipCidr: "111.0.0.1/24"
+ secretName: node-lighthouse
diff --git a/core/nebula/generated/clientset/versioned/typed/nebula/v1/fake/fake_nebula_client.go b/core/nebula/generated/clientset/versioned/typed/nebula/v1/fake/fake_nebula_client.go
index 727021a..e5f530e 100644
--- a/core/nebula/generated/clientset/versioned/typed/nebula/v1/fake/fake_nebula_client.go
+++ b/core/nebula/generated/clientset/versioned/typed/nebula/v1/fake/fake_nebula_client.go
@@ -18,6 +18,10 @@
return &FakeNebulaCAs{c, namespace}
}
+func (c *FakeLekvaV1) NebulaNodes(namespace string) v1.NebulaNodeInterface {
+ return &FakeNebulaNodes{c, namespace}
+}
+
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeLekvaV1) RESTClient() rest.Interface {
diff --git a/core/nebula/generated/clientset/versioned/typed/nebula/v1/fake/fake_nebulanode.go b/core/nebula/generated/clientset/versioned/typed/nebula/v1/fake/fake_nebulanode.go
new file mode 100644
index 0000000..cbd3957
--- /dev/null
+++ b/core/nebula/generated/clientset/versioned/typed/nebula/v1/fake/fake_nebulanode.go
@@ -0,0 +1,128 @@
+// gen
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+ "context"
+
+ nebulav1 "github.com/giolekva/pcloud/core/nebula/apis/nebula/v1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ labels "k8s.io/apimachinery/pkg/labels"
+ schema "k8s.io/apimachinery/pkg/runtime/schema"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ testing "k8s.io/client-go/testing"
+)
+
+// FakeNebulaNodes implements NebulaNodeInterface
+type FakeNebulaNodes struct {
+ Fake *FakeLekvaV1
+ ns string
+}
+
+var nebulanodesResource = schema.GroupVersionResource{Group: "lekva.me", Version: "v1", Resource: "nebulanodes"}
+
+var nebulanodesKind = schema.GroupVersionKind{Group: "lekva.me", Version: "v1", Kind: "NebulaNode"}
+
+// Get takes name of the nebulaNode, and returns the corresponding nebulaNode object, and an error if there is any.
+func (c *FakeNebulaNodes) Get(ctx context.Context, name string, options v1.GetOptions) (result *nebulav1.NebulaNode, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewGetAction(nebulanodesResource, c.ns, name), &nebulav1.NebulaNode{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*nebulav1.NebulaNode), err
+}
+
+// List takes label and field selectors, and returns the list of NebulaNodes that match those selectors.
+func (c *FakeNebulaNodes) List(ctx context.Context, opts v1.ListOptions) (result *nebulav1.NebulaNodeList, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewListAction(nebulanodesResource, nebulanodesKind, c.ns, opts), &nebulav1.NebulaNodeList{})
+
+ if obj == nil {
+ return nil, err
+ }
+
+ label, _, _ := testing.ExtractFromListOptions(opts)
+ if label == nil {
+ label = labels.Everything()
+ }
+ list := &nebulav1.NebulaNodeList{ListMeta: obj.(*nebulav1.NebulaNodeList).ListMeta}
+ for _, item := range obj.(*nebulav1.NebulaNodeList).Items {
+ if label.Matches(labels.Set(item.Labels)) {
+ list.Items = append(list.Items, item)
+ }
+ }
+ return list, err
+}
+
+// Watch returns a watch.Interface that watches the requested nebulaNodes.
+func (c *FakeNebulaNodes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
+ return c.Fake.
+ InvokesWatch(testing.NewWatchAction(nebulanodesResource, c.ns, opts))
+
+}
+
+// Create takes the representation of a nebulaNode and creates it. Returns the server's representation of the nebulaNode, and an error, if there is any.
+func (c *FakeNebulaNodes) Create(ctx context.Context, nebulaNode *nebulav1.NebulaNode, opts v1.CreateOptions) (result *nebulav1.NebulaNode, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewCreateAction(nebulanodesResource, c.ns, nebulaNode), &nebulav1.NebulaNode{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*nebulav1.NebulaNode), err
+}
+
+// Update takes the representation of a nebulaNode and updates it. Returns the server's representation of the nebulaNode, and an error, if there is any.
+func (c *FakeNebulaNodes) Update(ctx context.Context, nebulaNode *nebulav1.NebulaNode, opts v1.UpdateOptions) (result *nebulav1.NebulaNode, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateAction(nebulanodesResource, c.ns, nebulaNode), &nebulav1.NebulaNode{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*nebulav1.NebulaNode), err
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *FakeNebulaNodes) UpdateStatus(ctx context.Context, nebulaNode *nebulav1.NebulaNode, opts v1.UpdateOptions) (*nebulav1.NebulaNode, error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewUpdateSubresourceAction(nebulanodesResource, "status", c.ns, nebulaNode), &nebulav1.NebulaNode{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*nebulav1.NebulaNode), err
+}
+
+// Delete takes name of the nebulaNode and deletes it. Returns an error if one occurs.
+func (c *FakeNebulaNodes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
+ _, err := c.Fake.
+ Invokes(testing.NewDeleteAction(nebulanodesResource, c.ns, name), &nebulav1.NebulaNode{})
+
+ return err
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *FakeNebulaNodes) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
+ action := testing.NewDeleteCollectionAction(nebulanodesResource, c.ns, listOpts)
+
+ _, err := c.Fake.Invokes(action, &nebulav1.NebulaNodeList{})
+ return err
+}
+
+// Patch applies the patch and returns the patched nebulaNode.
+func (c *FakeNebulaNodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *nebulav1.NebulaNode, err error) {
+ obj, err := c.Fake.
+ Invokes(testing.NewPatchSubresourceAction(nebulanodesResource, c.ns, name, pt, data, subresources...), &nebulav1.NebulaNode{})
+
+ if obj == nil {
+ return nil, err
+ }
+ return obj.(*nebulav1.NebulaNode), err
+}
diff --git a/core/nebula/generated/clientset/versioned/typed/nebula/v1/generated_expansion.go b/core/nebula/generated/clientset/versioned/typed/nebula/v1/generated_expansion.go
index 00ebd78..db9c80a 100644
--- a/core/nebula/generated/clientset/versioned/typed/nebula/v1/generated_expansion.go
+++ b/core/nebula/generated/clientset/versioned/typed/nebula/v1/generated_expansion.go
@@ -5,3 +5,5 @@
package v1
type NebulaCAExpansion interface{}
+
+type NebulaNodeExpansion interface{}
diff --git a/core/nebula/generated/clientset/versioned/typed/nebula/v1/nebula_client.go b/core/nebula/generated/clientset/versioned/typed/nebula/v1/nebula_client.go
index bf63c93..261bb36 100644
--- a/core/nebula/generated/clientset/versioned/typed/nebula/v1/nebula_client.go
+++ b/core/nebula/generated/clientset/versioned/typed/nebula/v1/nebula_client.go
@@ -13,6 +13,7 @@
type LekvaV1Interface interface {
RESTClient() rest.Interface
NebulaCAsGetter
+ NebulaNodesGetter
}
// LekvaV1Client is used to interact with features provided by the lekva.me group.
@@ -24,6 +25,10 @@
return newNebulaCAs(c, namespace)
}
+func (c *LekvaV1Client) NebulaNodes(namespace string) NebulaNodeInterface {
+ return newNebulaNodes(c, namespace)
+}
+
// NewForConfig creates a new LekvaV1Client for the given config.
func NewForConfig(c *rest.Config) (*LekvaV1Client, error) {
config := *c
diff --git a/core/nebula/generated/clientset/versioned/typed/nebula/v1/nebulanode.go b/core/nebula/generated/clientset/versioned/typed/nebula/v1/nebulanode.go
new file mode 100644
index 0000000..4c38986
--- /dev/null
+++ b/core/nebula/generated/clientset/versioned/typed/nebula/v1/nebulanode.go
@@ -0,0 +1,181 @@
+// gen
+
+// Code generated by client-gen. DO NOT EDIT.
+
+package v1
+
+import (
+ "context"
+ "time"
+
+ v1 "github.com/giolekva/pcloud/core/nebula/apis/nebula/v1"
+ scheme "github.com/giolekva/pcloud/core/nebula/generated/clientset/versioned/scheme"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ types "k8s.io/apimachinery/pkg/types"
+ watch "k8s.io/apimachinery/pkg/watch"
+ rest "k8s.io/client-go/rest"
+)
+
+// NebulaNodesGetter has a method to return a NebulaNodeInterface.
+// A group's client should implement this interface.
+type NebulaNodesGetter interface {
+ NebulaNodes(namespace string) NebulaNodeInterface
+}
+
+// NebulaNodeInterface has methods to work with NebulaNode resources.
+type NebulaNodeInterface interface {
+ Create(ctx context.Context, nebulaNode *v1.NebulaNode, opts metav1.CreateOptions) (*v1.NebulaNode, error)
+ Update(ctx context.Context, nebulaNode *v1.NebulaNode, opts metav1.UpdateOptions) (*v1.NebulaNode, error)
+ UpdateStatus(ctx context.Context, nebulaNode *v1.NebulaNode, opts metav1.UpdateOptions) (*v1.NebulaNode, error)
+ Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
+ DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
+ Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.NebulaNode, error)
+ List(ctx context.Context, opts metav1.ListOptions) (*v1.NebulaNodeList, error)
+ Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
+ Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.NebulaNode, err error)
+ NebulaNodeExpansion
+}
+
+// nebulaNodes implements NebulaNodeInterface
+type nebulaNodes struct {
+ client rest.Interface
+ ns string
+}
+
+// newNebulaNodes returns a NebulaNodes
+func newNebulaNodes(c *LekvaV1Client, namespace string) *nebulaNodes {
+ return &nebulaNodes{
+ client: c.RESTClient(),
+ ns: namespace,
+ }
+}
+
+// Get takes name of the nebulaNode, and returns the corresponding nebulaNode object, and an error if there is any.
+func (c *nebulaNodes) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.NebulaNode, err error) {
+ result = &v1.NebulaNode{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ Name(name).
+ VersionedParams(&options, scheme.ParameterCodec).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// List takes label and field selectors, and returns the list of NebulaNodes that match those selectors.
+func (c *nebulaNodes) List(ctx context.Context, opts metav1.ListOptions) (result *v1.NebulaNodeList, err error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ result = &v1.NebulaNodeList{}
+ err = c.client.Get().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// Watch returns a watch.Interface that watches the requested nebulaNodes.
+func (c *nebulaNodes) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
+ var timeout time.Duration
+ if opts.TimeoutSeconds != nil {
+ timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
+ }
+ opts.Watch = true
+ return c.client.Get().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Watch(ctx)
+}
+
+// Create takes the representation of a nebulaNode and creates it. Returns the server's representation of the nebulaNode, and an error, if there is any.
+func (c *nebulaNodes) Create(ctx context.Context, nebulaNode *v1.NebulaNode, opts metav1.CreateOptions) (result *v1.NebulaNode, err error) {
+ result = &v1.NebulaNode{}
+ err = c.client.Post().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(nebulaNode).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// Update takes the representation of a nebulaNode and updates it. Returns the server's representation of the nebulaNode, and an error, if there is any.
+func (c *nebulaNodes) Update(ctx context.Context, nebulaNode *v1.NebulaNode, opts metav1.UpdateOptions) (result *v1.NebulaNode, err error) {
+ result = &v1.NebulaNode{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ Name(nebulaNode.Name).
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(nebulaNode).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// UpdateStatus was generated because the type contains a Status member.
+// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+func (c *nebulaNodes) UpdateStatus(ctx context.Context, nebulaNode *v1.NebulaNode, opts metav1.UpdateOptions) (result *v1.NebulaNode, err error) {
+ result = &v1.NebulaNode{}
+ err = c.client.Put().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ Name(nebulaNode.Name).
+ SubResource("status").
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(nebulaNode).
+ Do(ctx).
+ Into(result)
+ return
+}
+
+// Delete takes name of the nebulaNode and deletes it. Returns an error if one occurs.
+func (c *nebulaNodes) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ Name(name).
+ Body(&opts).
+ Do(ctx).
+ Error()
+}
+
+// DeleteCollection deletes a collection of objects.
+func (c *nebulaNodes) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
+ var timeout time.Duration
+ if listOpts.TimeoutSeconds != nil {
+ timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
+ }
+ return c.client.Delete().
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ VersionedParams(&listOpts, scheme.ParameterCodec).
+ Timeout(timeout).
+ Body(&opts).
+ Do(ctx).
+ Error()
+}
+
+// Patch applies the patch and returns the patched nebulaNode.
+func (c *nebulaNodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.NebulaNode, err error) {
+ result = &v1.NebulaNode{}
+ err = c.client.Patch(pt).
+ Namespace(c.ns).
+ Resource("nebulanodes").
+ Name(name).
+ SubResource(subresources...).
+ VersionedParams(&opts, scheme.ParameterCodec).
+ Body(data).
+ Do(ctx).
+ Into(result)
+ return
+}
diff --git a/core/nebula/generated/informers/externalversions/generic.go b/core/nebula/generated/informers/externalversions/generic.go
index fbefa76..9df56e4 100644
--- a/core/nebula/generated/informers/externalversions/generic.go
+++ b/core/nebula/generated/informers/externalversions/generic.go
@@ -41,6 +41,8 @@
// Group=lekva.me, Version=v1
case v1.SchemeGroupVersion.WithResource("nebulacas"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Lekva().V1().NebulaCAs().Informer()}, nil
+ case v1.SchemeGroupVersion.WithResource("nebulanodes"):
+ return &genericInformer{resource: resource.GroupResource(), informer: f.Lekva().V1().NebulaNodes().Informer()}, nil
}
diff --git a/core/nebula/generated/informers/externalversions/nebula/v1/interface.go b/core/nebula/generated/informers/externalversions/nebula/v1/interface.go
index c9ca5e8..eb7fc27 100644
--- a/core/nebula/generated/informers/externalversions/nebula/v1/interface.go
+++ b/core/nebula/generated/informers/externalversions/nebula/v1/interface.go
@@ -12,6 +12,8 @@
type Interface interface {
// NebulaCAs returns a NebulaCAInformer.
NebulaCAs() NebulaCAInformer
+ // NebulaNodes returns a NebulaNodeInformer.
+ NebulaNodes() NebulaNodeInformer
}
type version struct {
@@ -29,3 +31,8 @@
func (v *version) NebulaCAs() NebulaCAInformer {
return &nebulaCAInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
+
+// NebulaNodes returns a NebulaNodeInformer.
+func (v *version) NebulaNodes() NebulaNodeInformer {
+ return &nebulaNodeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+}
diff --git a/core/nebula/generated/informers/externalversions/nebula/v1/nebulanode.go b/core/nebula/generated/informers/externalversions/nebula/v1/nebulanode.go
new file mode 100644
index 0000000..b3d3c65
--- /dev/null
+++ b/core/nebula/generated/informers/externalversions/nebula/v1/nebulanode.go
@@ -0,0 +1,76 @@
+// gen
+
+// Code generated by informer-gen. DO NOT EDIT.
+
+package v1
+
+import (
+ "context"
+ time "time"
+
+ nebulav1 "github.com/giolekva/pcloud/core/nebula/apis/nebula/v1"
+ versioned "github.com/giolekva/pcloud/core/nebula/generated/clientset/versioned"
+ internalinterfaces "github.com/giolekva/pcloud/core/nebula/generated/informers/externalversions/internalinterfaces"
+ v1 "github.com/giolekva/pcloud/core/nebula/generated/listers/nebula/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ runtime "k8s.io/apimachinery/pkg/runtime"
+ watch "k8s.io/apimachinery/pkg/watch"
+ cache "k8s.io/client-go/tools/cache"
+)
+
+// NebulaNodeInformer provides access to a shared informer and lister for
+// NebulaNodes.
+type NebulaNodeInformer interface {
+ Informer() cache.SharedIndexInformer
+ Lister() v1.NebulaNodeLister
+}
+
+type nebulaNodeInformer struct {
+ factory internalinterfaces.SharedInformerFactory
+ tweakListOptions internalinterfaces.TweakListOptionsFunc
+ namespace string
+}
+
+// NewNebulaNodeInformer constructs a new informer for NebulaNode type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewNebulaNodeInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+ return NewFilteredNebulaNodeInformer(client, namespace, resyncPeriod, indexers, nil)
+}
+
+// NewFilteredNebulaNodeInformer constructs a new informer for NebulaNode type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredNebulaNodeInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+ return cache.NewSharedIndexInformer(
+ &cache.ListWatch{
+ ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.LekvaV1().NebulaNodes(namespace).List(context.TODO(), options)
+ },
+ WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
+ if tweakListOptions != nil {
+ tweakListOptions(&options)
+ }
+ return client.LekvaV1().NebulaNodes(namespace).Watch(context.TODO(), options)
+ },
+ },
+ &nebulav1.NebulaNode{},
+ resyncPeriod,
+ indexers,
+ )
+}
+
+func (f *nebulaNodeInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+ return NewFilteredNebulaNodeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *nebulaNodeInformer) Informer() cache.SharedIndexInformer {
+ return f.factory.InformerFor(&nebulav1.NebulaNode{}, f.defaultInformer)
+}
+
+func (f *nebulaNodeInformer) Lister() v1.NebulaNodeLister {
+ return v1.NewNebulaNodeLister(f.Informer().GetIndexer())
+}
diff --git a/core/nebula/generated/listers/nebula/v1/expansion_generated.go b/core/nebula/generated/listers/nebula/v1/expansion_generated.go
index a6436ea..8b4d0e8 100644
--- a/core/nebula/generated/listers/nebula/v1/expansion_generated.go
+++ b/core/nebula/generated/listers/nebula/v1/expansion_generated.go
@@ -11,3 +11,11 @@
// NebulaCANamespaceListerExpansion allows custom methods to be added to
// NebulaCANamespaceLister.
type NebulaCANamespaceListerExpansion interface{}
+
+// NebulaNodeListerExpansion allows custom methods to be added to
+// NebulaNodeLister.
+type NebulaNodeListerExpansion interface{}
+
+// NebulaNodeNamespaceListerExpansion allows custom methods to be added to
+// NebulaNodeNamespaceLister.
+type NebulaNodeNamespaceListerExpansion interface{}
diff --git a/core/nebula/generated/listers/nebula/v1/nebulanode.go b/core/nebula/generated/listers/nebula/v1/nebulanode.go
new file mode 100644
index 0000000..f861e18
--- /dev/null
+++ b/core/nebula/generated/listers/nebula/v1/nebulanode.go
@@ -0,0 +1,85 @@
+// gen
+
+// Code generated by lister-gen. DO NOT EDIT.
+
+package v1
+
+import (
+ v1 "github.com/giolekva/pcloud/core/nebula/apis/nebula/v1"
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/client-go/tools/cache"
+)
+
+// NebulaNodeLister helps list NebulaNodes.
+// All objects returned here must be treated as read-only.
+type NebulaNodeLister interface {
+ // List lists all NebulaNodes in the indexer.
+ // Objects returned here must be treated as read-only.
+ List(selector labels.Selector) (ret []*v1.NebulaNode, err error)
+ // NebulaNodes returns an object that can list and get NebulaNodes.
+ NebulaNodes(namespace string) NebulaNodeNamespaceLister
+ NebulaNodeListerExpansion
+}
+
+// nebulaNodeLister implements the NebulaNodeLister interface.
+type nebulaNodeLister struct {
+ indexer cache.Indexer
+}
+
+// NewNebulaNodeLister returns a new NebulaNodeLister.
+func NewNebulaNodeLister(indexer cache.Indexer) NebulaNodeLister {
+ return &nebulaNodeLister{indexer: indexer}
+}
+
+// List lists all NebulaNodes in the indexer.
+func (s *nebulaNodeLister) List(selector labels.Selector) (ret []*v1.NebulaNode, err error) {
+ err = cache.ListAll(s.indexer, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1.NebulaNode))
+ })
+ return ret, err
+}
+
+// NebulaNodes returns an object that can list and get NebulaNodes.
+func (s *nebulaNodeLister) NebulaNodes(namespace string) NebulaNodeNamespaceLister {
+ return nebulaNodeNamespaceLister{indexer: s.indexer, namespace: namespace}
+}
+
+// NebulaNodeNamespaceLister helps list and get NebulaNodes.
+// All objects returned here must be treated as read-only.
+type NebulaNodeNamespaceLister interface {
+ // List lists all NebulaNodes in the indexer for a given namespace.
+ // Objects returned here must be treated as read-only.
+ List(selector labels.Selector) (ret []*v1.NebulaNode, err error)
+ // Get retrieves the NebulaNode from the indexer for a given namespace and name.
+ // Objects returned here must be treated as read-only.
+ Get(name string) (*v1.NebulaNode, error)
+ NebulaNodeNamespaceListerExpansion
+}
+
+// nebulaNodeNamespaceLister implements the NebulaNodeNamespaceLister
+// interface.
+type nebulaNodeNamespaceLister struct {
+ indexer cache.Indexer
+ namespace string
+}
+
+// List lists all NebulaNodes in the indexer for a given namespace.
+func (s nebulaNodeNamespaceLister) List(selector labels.Selector) (ret []*v1.NebulaNode, err error) {
+ err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
+ ret = append(ret, m.(*v1.NebulaNode))
+ })
+ return ret, err
+}
+
+// Get retrieves the NebulaNode from the indexer for a given namespace and name.
+func (s nebulaNodeNamespaceLister) Get(name string) (*v1.NebulaNode, error) {
+ obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ return nil, errors.NewNotFound(v1.Resource("nebulanode"), name)
+ }
+ return obj.(*v1.NebulaNode), nil
+}
diff --git a/core/nebula/main.go b/core/nebula/main.go
index dd62db0..af7b0b5 100644
--- a/core/nebula/main.go
+++ b/core/nebula/main.go
@@ -5,6 +5,7 @@
"time"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+ kubeinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
@@ -12,6 +13,7 @@
clientset "github.com/giolekva/pcloud/core/nebula/generated/clientset/versioned"
"github.com/giolekva/pcloud/core/nebula/generated/clientset/versioned/scheme"
informers "github.com/giolekva/pcloud/core/nebula/generated/informers/externalversions"
+
nebulascheme "k8s.io/sample-controller/pkg/generated/clientset/versioned/scheme"
)
@@ -25,15 +27,23 @@
if err != nil {
panic(err)
}
- kc, err := kubernetes.NewForConfig(cfg)
+ kubeClient, err := kubernetes.NewForConfig(cfg)
if err != nil {
panic(err)
}
nebulaClient := clientset.NewForConfigOrDie(cfg)
utilruntime.Must(nebulascheme.AddToScheme(scheme.Scheme))
+ kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Second*30)
nebulaInformerFactory := informers.NewSharedInformerFactory(nebulaClient, 5*time.Second)
- c := controllers.NewCAController(kc, nebulaClient, nebulaInformerFactory, *nebulaCert)
+ c := controllers.NewCAController(
+ kubeClient,
+ nebulaClient,
+ nebulaInformerFactory.Lekva().V1().NebulaCAs(),
+ nebulaInformerFactory.Lekva().V1().NebulaNodes(),
+ kubeInformerFactory.Core().V1().Secrets(),
+ *nebulaCert)
stopCh := make(chan struct{})
+ kubeInformerFactory.Start(stopCh)
nebulaInformerFactory.Start(stopCh)
if err := c.Run(1, stopCh); err != nil {
panic(err)