diff --git a/README.md b/README.md
index 9022da3..b294f60 100644
--- a/README.md
+++ b/README.md
@@ -28,3 +28,4 @@ helm upgrade --install --create-namespace -n netbird netbird-operator oci://ghcr
| [NetworkRouter](docs/api-reference.md#networkrouter) | `netbird.io/v1alpha1` |
| [SetupKey](docs/api-reference.md#setupkey) | `netbird.io/v1alpha1` |
| [SidecarProfile](docs/api-reference.md#sidecarprofile) | `netbird.io/v1alpha1` |
+| [ClusterProxy](docs/api-reference.md#clusterproxy) | `netbird.io/v1alpha1` |
diff --git a/api/v1alpha1/clusterproxy_types.go b/api/v1alpha1/clusterproxy_types.go
index e799bf2..2b51c50 100644
--- a/api/v1alpha1/clusterproxy_types.go
+++ b/api/v1alpha1/clusterproxy_types.go
@@ -21,6 +21,10 @@ type ClusterProxySpec struct {
// ServiceAccountName is a reference to the service account used for impersonation.
// +required
ServiceAccountName string `json:"serviceAccountName"`
+
+ // Groups are references to groups that the peer will be a part of.
+ // +optional
+ Groups []GroupReference `json:"groups,omitempty"`
}
// ClusterProxyStatus defines the observed state of ClusterProxy.
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 29058ee..fbf0304 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -17,7 +17,7 @@ func (in *ClusterProxy) DeepCopyInto(out *ClusterProxy) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
- out.Spec = in.Spec
+ in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
@@ -74,6 +74,13 @@ func (in *ClusterProxyList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClusterProxySpec) DeepCopyInto(out *ClusterProxySpec) {
*out = *in
+ if in.Groups != nil {
+ in, out := &in.Groups, &out.Groups
+ *out = make([]GroupReference, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterProxySpec.
diff --git a/charts/netbird-operator/crds/netbird.io_clusterproxies.yaml b/charts/netbird-operator/crds/netbird.io_clusterproxies.yaml
index 8ea4b4c..3acfea8 100644
--- a/charts/netbird-operator/crds/netbird.io_clusterproxies.yaml
+++ b/charts/netbird-operator/crds/netbird.io_clusterproxies.yaml
@@ -57,6 +57,37 @@ spec:
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
+ groups:
+ description: Groups are references to groups that the peer will be
+ a part of.
+ items:
+ properties:
+ id:
+ description: ID is the id of the group.
+ type: string
+ localRef:
+ description: LocalReference is a reference to a group in the
+ same namespace.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ name:
+ description: Name is the name of the group.
+ type: string
+ type: object
+ x-kubernetes-validations:
+ - message: Exactly one of id, name, or localRef must be set
+ rule: (has(self.id)?1:0)+(has(self.name)?1:0)+(has(self.localRef)?1:0)==1
+ type: array
serviceAccountName:
description: ServiceAccountName is a reference to the service account
used for impersonation.
diff --git a/config/crd/bases/netbird.io_clusterproxies.yaml b/config/crd/bases/netbird.io_clusterproxies.yaml
index 8ea4b4c..3acfea8 100644
--- a/config/crd/bases/netbird.io_clusterproxies.yaml
+++ b/config/crd/bases/netbird.io_clusterproxies.yaml
@@ -57,6 +57,37 @@ spec:
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
+ groups:
+ description: Groups are references to groups that the peer will be
+ a part of.
+ items:
+ properties:
+ id:
+ description: ID is the id of the group.
+ type: string
+ localRef:
+ description: LocalReference is a reference to a group in the
+ same namespace.
+ properties:
+ name:
+ default: ""
+ description: |-
+ Name of the referent.
+ This field is effectively required, but due to backwards compatibility is
+ allowed to be empty. Instances of this type with an empty value here are
+ almost certainly wrong.
+ More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+ type: string
+ type: object
+ x-kubernetes-map-type: atomic
+ name:
+ description: Name is the name of the group.
+ type: string
+ type: object
+ x-kubernetes-validations:
+ - message: Exactly one of id, name, or localRef must be set
+ rule: (has(self.id)?1:0)+(has(self.name)?1:0)+(has(self.localRef)?1:0)==1
+ type: array
serviceAccountName:
description: ServiceAccountName is a reference to the service account
used for impersonation.
diff --git a/docs/api-reference.md b/docs/api-reference.md
index 90c0493..b4d91d6 100644
--- a/docs/api-reference.md
+++ b/docs/api-reference.md
@@ -55,6 +55,7 @@ _Appears in:_
| `clusterName` _string_ | ClusterName is the name of the Kubernetes cluster. | | Required: \{\}
|
| `apiServer` _string_ | APIServer is the URL of the Kubernetes API server to proxy requests to. | https://kubernetes.default.svc.cluster.local | Required: \{\}
|
| `serviceAccountName` _string_ | ServiceAccountName is a reference to the service account used for impersonation. | | Required: \{\}
|
+| `groups` _[GroupReference](#groupreference) array_ | Groups are references to groups that the peer will be a part of. | | Optional: \{\}
|
#### ClusterProxyStatus
@@ -158,6 +159,7 @@ Group is the Schema for the groups API.
_Appears in:_
+- [ClusterProxySpec](#clusterproxyspec)
- [NetworkResourceSpec](#networkresourcespec)
- [SetupKeySpec](#setupkeyspec)
diff --git a/examples/api-proxy/api-proxy.yaml b/examples/cluster-proxy/cluster-proxy.yaml
similarity index 100%
rename from examples/api-proxy/api-proxy.yaml
rename to examples/cluster-proxy/cluster-proxy.yaml
diff --git a/internal/controller/clusterproxy_controller.go b/internal/controller/clusterproxy_controller.go
index b94fdb0..715f793 100644
--- a/internal/controller/clusterproxy_controller.go
+++ b/internal/controller/clusterproxy_controller.go
@@ -67,6 +67,16 @@ func (r *ClusterProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request
WithEphemeral(true).
WithAllowExtraDnsLabels(true),
)
+ for _, group := range clusterProxy.Spec.Groups {
+ switch {
+ case group.ID != nil:
+ setupKeyAC.Spec.AutoGroups = append(setupKeyAC.Spec.AutoGroups, *nbv1alpha1ac.GroupReference().WithID(*group.ID))
+ case group.Name != nil:
+ setupKeyAC.Spec.AutoGroups = append(setupKeyAC.Spec.AutoGroups, *nbv1alpha1ac.GroupReference().WithName(*group.Name))
+ case group.LocalRef != nil:
+ setupKeyAC.Spec.AutoGroups = append(setupKeyAC.Spec.AutoGroups, *nbv1alpha1ac.GroupReference().WithLocalRef(*group.LocalRef))
+ }
+ }
err = r.Client.Apply(ctx, setupKeyAC, client.ForceOwnership)
if err != nil {
return ctrl.Result{}, err
diff --git a/pkg/applyconfigurations/api/v1alpha1/clusterproxyspec.go b/pkg/applyconfigurations/api/v1alpha1/clusterproxyspec.go
index 5be3f70..0835750 100644
--- a/pkg/applyconfigurations/api/v1alpha1/clusterproxyspec.go
+++ b/pkg/applyconfigurations/api/v1alpha1/clusterproxyspec.go
@@ -15,6 +15,8 @@ type ClusterProxySpecApplyConfiguration struct {
APIServer *string `json:"apiServer,omitempty"`
// ServiceAccountName is a reference to the service account used for impersonation.
ServiceAccountName *string `json:"serviceAccountName,omitempty"`
+ // Groups are references to groups that the peer will be a part of.
+ Groups []GroupReferenceApplyConfiguration `json:"groups,omitempty"`
}
// ClusterProxySpecApplyConfiguration constructs a declarative configuration of the ClusterProxySpec type for use with
@@ -46,3 +48,16 @@ func (b *ClusterProxySpecApplyConfiguration) WithServiceAccountName(value string
b.ServiceAccountName = &value
return b
}
+
+// WithGroups adds the given value to the Groups field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the Groups field.
+func (b *ClusterProxySpecApplyConfiguration) WithGroups(values ...*GroupReferenceApplyConfiguration) *ClusterProxySpecApplyConfiguration {
+ for i := range values {
+ if values[i] == nil {
+ panic("nil value passed to WithGroups")
+ }
+ b.Groups = append(b.Groups, *values[i])
+ }
+ return b
+}