mirror of
https://github.com/YuzuZensai/netbird-kubernetes-operator.git
synced 2026-09-13 10:49:15 +00:00
Add groups option to cluster proxy (#297)
This change adds an option to specify groups a cluster proxy peer is a member of. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added optional `spec.groups` to the ClusterProxy custom resource to associate group references by `id`, `name`, or `localRef`. * CRD schema includes OpenAPI validation to enforce that each group reference specifies exactly one selector. * **Bug Fixes** * Improved deep-copy behavior for ClusterProxy spec so group references are copied safely and don’t share underlying slices. * **Documentation** * Updated API reference docs and README API table to include the new `groups` field. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -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` |
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -55,6 +55,7 @@ _Appears in:_
|
||||
| `clusterName` _string_ | ClusterName is the name of the Kubernetes cluster. | | Required: \{\} <br /> |
|
||||
| `apiServer` _string_ | APIServer is the URL of the Kubernetes API server to proxy requests to. | https://kubernetes.default.svc.cluster.local | Required: \{\} <br /> |
|
||||
| `serviceAccountName` _string_ | ServiceAccountName is a reference to the service account used for impersonation. | | Required: \{\} <br /> |
|
||||
| `groups` _[GroupReference](#groupreference) array_ | Groups are references to groups that the peer will be a part of. | | Optional: \{\} <br /> |
|
||||
|
||||
|
||||
#### ClusterProxyStatus
|
||||
@@ -158,6 +159,7 @@ Group is the Schema for the groups API.
|
||||
|
||||
|
||||
_Appears in:_
|
||||
- [ClusterProxySpec](#clusterproxyspec)
|
||||
- [NetworkResourceSpec](#networkresourcespec)
|
||||
- [SetupKeySpec](#setupkeyspec)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user