Skip to content
Open
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
8 changes: 8 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func main() {
netbirdAPIKey string
allowAutomaticPolicyCreation bool
defaultLabels string
routingPeerNamePrefix string
)
flag.StringVar(&managementURL, "netbird-management-url", "https://api.netbird.io", "Management service URL")
flag.StringVar(&clientImage, "netbird-client-image", "netbirdio/netbird:latest", "Image for netbird client container")
Expand Down Expand Up @@ -105,6 +106,12 @@ func main() {
"",
"Default labels used for all resources, in format key=value,key=value",
)
flag.StringVar(
&routingPeerNamePrefix,
"routing-peer-name-prefix",
"",
"Prefix applied to routing peer names (final name becomes <prefix>router)",
)

// Controller generic flags
var (
Expand Down Expand Up @@ -255,6 +262,7 @@ func main() {
NamespacedNetworks: namespacedNetworks,
ControllerNamespace: controllerNamespace,
DefaultLabels: defaultLabelsMap,
RouterNamePrefix: routingPeerNamePrefix,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Service")
os.Exit(1)
Expand Down
5 changes: 3 additions & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ With this setup, all peers with the same extra label would be used in a DNS roun
1. Alternatively, provision secret in the same namespace as the operator and set the key `NB_API_KEY` to the access token generated.
2. Set `netbirdAPI.keyFromSecret` to the name of the secret created.
4. Set `ingress.enabled` to `true`.
1. Optionally, to provision the network immediately, set `ingress.router.enabled` to `true`.
2. Optionally, to provision 1 network per namespace, set `ingress.namespacedNetworks` to `true`.
1. Optionally, to provision the network immediately, set `ingress.router.enabled` to `true`.
2. Optionally, to provision 1 network per namespace, set `ingress.namespacedNetworks` to `true`.
3. Optionally, set `ingress.router.namePrefix` to prepend a custom string to every routing peer name (resulting name becomes `<prefix>-router`).
5. Run `helm install` or `helm upgrade`.

Minimum values.yaml example:
Expand Down
1 change: 1 addition & 0 deletions examples/ingress/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ingress:
enabled: true
router:
enabled: true
# namePrefix: "demo-"
# policies:
# default:
# name: Kubernetes Default Policy
Expand Down
3 changes: 3 additions & 0 deletions helm/kubernetes-operator/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ spec:
{{- if .Values.ingress.namespacedNetworks }}
- --namespaced-networks={{.Values.ingress.namespacedNetworks}}
{{- end }}
{{- if .Values.ingress.router.namePrefix }}
- --routing-peer-name-prefix={{ .Values.ingress.router.namePrefix }}
{{- end }}
{{- if .Values.cluster.dns }}
- --cluster-dns={{.Values.cluster.dns}}
{{- end }}
Expand Down
14 changes: 11 additions & 3 deletions helm/kubernetes-operator/templates/kubernetes-nbresource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
{{- if .Values.ingress.namespacedNetworks }}
{{- $routerNS = "default" }}
{{- end }}
{{- $routerName := "router" }}
{{- if .Values.ingress.router.namePrefix }}
{{- $routerName = printf "%s-router" .Values.ingress.router.namePrefix }}
{{- end }}
apiVersion: batch/v1
kind: Job
metadata:
Expand Down Expand Up @@ -32,7 +36,7 @@ spec:
- bash
- -c
args:
- kubectl wait --for 'jsonpath={.status.networkID}' -n {{ $routerNS }} nbroutingpeer router;
- kubectl wait --for 'jsonpath={.status.networkID}' -n {{ $routerNS }} nbroutingpeer {{ $routerName }};
containers:
- name: apply-nbresource
image: "bitnami/kubectl:latest"
Expand All @@ -47,10 +51,14 @@ spec:
name: kubernetes
namespace: default
spec:
{{- if .Values.cluster.apiserver }}
address: {{ .Values.cluster.apiserver }}
{{- else }}
address: kubernetes.default.{{.Values.cluster.dns}}
{{- end }}
groups:
{{- if .Values.ingress.kubernetesAPI.groups }}
{{ toYaml .Values.ingress.kubernetesAPI.groups }}
{{ toYaml .Values.ingress.kubernetesAPI.groups | nindent 14 }}
{{- else }}
- {{ .Values.cluster.name }}-default-api-access
{{- end }}
Expand All @@ -65,7 +73,7 @@ spec:
- bash
- -c
args:
- kubectl delete NBResource --ignore-not-found -n default kubernetes; export NETWORK_ID=$(kubectl get NBRoutingPeer -n {{ $routerNS }} router -o 'jsonpath={.status.networkID}'); echo "$NBRESOURCE_VALUE" | envsubst | kubectl apply -f -
- kubectl delete NBResource --ignore-not-found -n default kubernetes; export NETWORK_ID=$(kubectl get NBRoutingPeer -n {{ $routerNS }} {{ $routerName }} -o 'jsonpath={.status.networkID}'); echo "$NBRESOURCE_VALUE" | envsubst | kubectl apply -f -
serviceAccountName: {{ include "kubernetes-operator.serviceAccountName" . }}
restartPolicy: Never
{{- end }}
8 changes: 5 additions & 3 deletions helm/kubernetes-operator/templates/nbroutingpeers.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{{- if and .Values.ingress.enabled .Values.ingress.router.enabled }}
{{- $routerNamePrefix := default "" .Values.ingress.router.namePrefix }}
{{- $routerResourceName := printf "%s-%s" $routerNamePrefix "router" }}
{{- if .Values.ingress.namespacedNetworks }}
{{ $defaults := .Values.ingress.router }}
{{ range $k, $v := .Values.ingress.router.namespaces }}
Expand All @@ -10,9 +12,9 @@ metadata:
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" $ | nindent 4 }}
name: router
name: {{ $routerResourceName }}
namespace: {{ $k }}
{{ $spec := merge $defaults $v }}
{{ $spec := merge (dict) $defaults $v }}
{{- if or (or (or $spec.replicas $spec.resources) (or $spec.labels $spec.annotations)) (or $spec.nodeSelector $spec.tolerations) }}
spec:
{{- if $spec.replicas }}
Expand Down Expand Up @@ -51,7 +53,7 @@ metadata:
labels:
app.kubernetes.io/component: operator
{{- include "kubernetes-operator.labels" $ | nindent 4 }}
name: router
name: {{ $routerResourceName }}
{{- if or (or (or .replicas .resources) (or .labels .annotations)) (or .nodeSelector .tolerations) }}
spec:
{{- if .replicas }}
Expand Down
4 changes: 4 additions & 0 deletions helm/kubernetes-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ ingress:
router:
# Deploy routing peer(s)
enabled: false
# Prefix appended to routing peer names (final name becomes <prefix>router)
namePrefix: ""
# replicas: 3
# resources:
# requests:
Expand Down Expand Up @@ -187,6 +189,8 @@ ingress:
cluster:
# Cluster DNS name (used for webhooks certificates and for network resource DNS names)
dns: svc.cluster.local
# Cluster API server address (overrides in-cluster address detection)
# apiserver: https://my-custom-apiserver:6443
# Cluster name (used for generating network and network resource names in NetBird)
name: kubernetes

Expand Down
11 changes: 9 additions & 2 deletions internal/controller/service_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type ServiceReconciler struct {
NamespacedNetworks bool
ControllerNamespace string
DefaultLabels map[string]string
RouterNamePrefix string
}

const (
Expand All @@ -40,6 +41,7 @@ const (
serviceProtocolAnnotation = "netbird.io/policy-protocol"
servicePolicySourceGroupsAnnotation = "netbird.io/policy-source-groups"
servicePolicyNameAnnotation = "netbird.io/policy-name"
routingPeerBaseName = "router"
)

var (
Expand Down Expand Up @@ -114,6 +116,7 @@ func (r *ServiceReconciler) exposeService(ctx context.Context, req ctrl.Request,
if r.NamespacedNetworks {
routerNamespace = req.Namespace
}
routerName := r.routingPeerName()

if !util.Contains(svc.Finalizers, "netbird.io/cleanup") {
svc.Finalizers = append(svc.Finalizers, "netbird.io/cleanup")
Expand All @@ -126,7 +129,7 @@ func (r *ServiceReconciler) exposeService(ctx context.Context, req ctrl.Request,

var routingPeer netbirdiov1.NBRoutingPeer
// Check if NBRoutingPeer exists
err := r.Client.Get(ctx, types.NamespacedName{Namespace: routerNamespace, Name: "router"}, &routingPeer)
err := r.Client.Get(ctx, types.NamespacedName{Namespace: routerNamespace, Name: routerName}, &routingPeer)
if err != nil && !errors.IsNotFound(err) {
logger.Error(errKubernetesAPI, "error getting NBRoutingPeer", "err", err)
return ctrl.Result{}, err
Expand All @@ -136,7 +139,7 @@ func (r *ServiceReconciler) exposeService(ctx context.Context, req ctrl.Request,
if errors.IsNotFound(err) {
routingPeer = netbirdiov1.NBRoutingPeer{
ObjectMeta: v1.ObjectMeta{
Name: "router",
Name: routerName,
Namespace: routerNamespace,
Finalizers: []string{"netbird.io/cleanup"},
Labels: r.DefaultLabels,
Expand Down Expand Up @@ -294,6 +297,10 @@ func (r *ServiceReconciler) applyPolicy(nbResource *netbirdiov1.NBResource, svc
return nil
}

func (r *ServiceReconciler) routingPeerName() string {
return fmt.Sprintf("%s-%s", r.RouterNamePrefix, routingPeerBaseName)
}

// SetupWithManager sets up the controller with the Manager.
func (r *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
Expand Down
31 changes: 25 additions & 6 deletions internal/controller/service_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,13 @@ var _ = Describe("Service Controller", func() {
}
}

nbrp := &netbirdiov1.NBRoutingPeer{}
err = k8sClient.Get(ctx, types.NamespacedName{Namespace: "default", Name: "router"}, nbrp)
if !errors.IsNotFound(err) {
nbrpList := &netbirdiov1.NBRoutingPeerList{}
Expect(k8sClient.List(ctx, nbrpList)).To(Succeed())
for i := range nbrpList.Items {
nbrp := &nbrpList.Items[i]
if nbrp.Namespace != typeNamespacedName.Namespace {
continue
}
if len(nbrp.Finalizers) > 0 {
nbrp.Finalizers = nil
Expect(k8sClient.Update(ctx, nbrp)).To(Succeed())
Expand Down Expand Up @@ -144,7 +148,7 @@ var _ = Describe("Service Controller", func() {
Expect(err).NotTo(HaveOccurred())
Expect(res.RequeueAfter).NotTo(BeZero())
nbrp := &netbirdiov1.NBRoutingPeer{}
Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: typeNamespacedName.Namespace, Name: "router"}, nbrp)).To(Succeed())
Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: typeNamespacedName.Namespace, Name: controllerReconciler.routingPeerName()}, nbrp)).To(Succeed())
Expect(nbrp.Labels).To(HaveKeyWithValue("dog", "bark"))
res, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
Expand All @@ -159,13 +163,28 @@ var _ = Describe("Service Controller", func() {
Expect(err).NotTo(HaveOccurred())
Expect(res.RequeueAfter).To(BeZero())
})
It("should honor router name prefix when creating NBRoutingPeer", func() {
controllerReconciler.RouterNamePrefix = "custom-"
defer func() {
controllerReconciler.RouterNamePrefix = ""
}()

_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
})
Expect(err).NotTo(HaveOccurred())
nbrp := &netbirdiov1.NBRoutingPeer{}
expectedName := controllerReconciler.RouterNamePrefix + routingPeerBaseName
Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: typeNamespacedName.Namespace, Name: expectedName}, nbrp)).To(Succeed())
Expect(nbrp.Name).To(Equal("custom-router"))
})
})
When("NBRoutingPeer exists", func() {
BeforeEach(func() {
nbrp := &netbirdiov1.NBRoutingPeer{
ObjectMeta: v1.ObjectMeta{
Namespace: typeNamespacedName.Namespace,
Name: "router",
Name: controllerReconciler.routingPeerName(),
},
Spec: netbirdiov1.NBRoutingPeerSpec{},
}
Expand Down Expand Up @@ -313,7 +332,7 @@ var _ = Describe("Service Controller", func() {
nbrp := &netbirdiov1.NBRoutingPeer{
ObjectMeta: v1.ObjectMeta{
Namespace: typeNamespacedName.Namespace,
Name: "router",
Name: controllerReconciler.routingPeerName(),
},
Spec: netbirdiov1.NBRoutingPeerSpec{},
}
Expand Down