diff --git a/api/v1alpha1/group_types.go b/api/v1alpha1/group_types.go index a08787d..b703625 100644 --- a/api/v1alpha1/group_types.go +++ b/api/v1alpha1/group_types.go @@ -1,9 +1,25 @@ package v1alpha1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// +kubebuilder:validation:XValidation:rule="(has(self.id)?1:0)+(has(self.name)?1:0)+(has(self.localRef)?1:0)==1",message="Exactly one of id, name, or localRef must be set" +type GroupReference struct { + // Name is the name of the group. + // +optional + Name *string `json:"name,omitempty"` + + // ID is the id of the group. + // +optional + ID *string `json:"id,omitempty"` + + // LocalReference is a reference to a group in the same namespace. + // +optional + LocalRef *corev1.LocalObjectReference `json:"localRef,omitempty"` +} + // GroupSpec defines the desired state of Group. type GroupSpec struct { // Name of the group. diff --git a/api/v1alpha1/networkresource_types.go b/api/v1alpha1/networkresource_types.go index 68effbd..867cd4c 100644 --- a/api/v1alpha1/networkresource_types.go +++ b/api/v1alpha1/networkresource_types.go @@ -16,7 +16,7 @@ type NetworkResourceSpec struct { // Groups are references to groups that the resource will be a part of. // +optional - Groups []ResourceReference `json:"groups,omitempty"` + Groups []GroupReference `json:"groups,omitempty"` } // NetworkResourceStatus defines the observed state of NetworkResource. diff --git a/api/v1alpha1/reference_type.go b/api/v1alpha1/reference_type.go index b6cbe8d..d227006 100644 --- a/api/v1alpha1/reference_type.go +++ b/api/v1alpha1/reference_type.go @@ -1,18 +1,5 @@ package v1alpha1 -import corev1 "k8s.io/api/core/v1" - -// +kubebuilder:validation:XValidation:rule="(has(self.id) && !has(self.localRef)) || (!has(self.id) && has(self.localRef))",message="exactly one of id or localRef must be set" -type ResourceReference struct { - // ID is the id of a resource in the Netbird API. - // +optional - ID *string `json:"id,omitempty"` - - // LocalReference is a reference to a object in the same namespace. - // +optional - LocalRef *corev1.LocalObjectReference `json:"localRef,omitempty"` -} - type CrossNamespaceReference struct { // Name of the referent. // +required diff --git a/api/v1alpha1/setupkey_types.go b/api/v1alpha1/setupkey_types.go index 8546216..a0b1c5e 100644 --- a/api/v1alpha1/setupkey_types.go +++ b/api/v1alpha1/setupkey_types.go @@ -23,7 +23,7 @@ type SetupKeySpec struct { // AutoGroups are groups that will be automatically assigned to peers using setup key. // +optional - AutoGroups []ResourceReference `json:"autoGroups,omitempty"` + AutoGroups []GroupReference `json:"autoGroups,omitempty"` } // SetupKeyStatus defines the observed state of SetupKey. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6cdd245..ff93134 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -5,8 +5,8 @@ package v1alpha1 import ( - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -99,6 +99,36 @@ func (in *GroupList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GroupReference) DeepCopyInto(out *GroupReference) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.LocalRef != nil { + in, out := &in.LocalRef, &out.LocalRef + *out = new(v1.LocalObjectReference) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GroupReference. +func (in *GroupReference) DeepCopy() *GroupReference { + if in == nil { + return nil + } + out := new(GroupReference) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GroupSpec) DeepCopyInto(out *GroupSpec) { *out = *in @@ -119,7 +149,7 @@ func (in *GroupStatus) DeepCopyInto(out *GroupStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) + *out = make([]metav1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -202,7 +232,7 @@ func (in *NetworkResourceSpec) DeepCopyInto(out *NetworkResourceSpec) { out.ServiceRef = in.ServiceRef if in.Groups != nil { in, out := &in.Groups, &out.Groups - *out = make([]ResourceReference, len(*in)) + *out = make([]GroupReference, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -224,7 +254,7 @@ func (in *NetworkResourceStatus) DeepCopyInto(out *NetworkResourceStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) + *out = make([]metav1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -326,7 +356,7 @@ func (in *NetworkRouterStatus) DeepCopyInto(out *NetworkRouterStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) + *out = make([]metav1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -343,31 +373,6 @@ func (in *NetworkRouterStatus) DeepCopy() *NetworkRouterStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceReference) DeepCopyInto(out *ResourceReference) { - *out = *in - if in.ID != nil { - in, out := &in.ID, &out.ID - *out = new(string) - **out = **in - } - if in.LocalRef != nil { - in, out := &in.LocalRef, &out.LocalRef - *out = new(corev1.LocalObjectReference) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceReference. -func (in *ResourceReference) DeepCopy() *ResourceReference { - if in == nil { - return nil - } - out := new(ResourceReference) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SetupKey) DeepCopyInto(out *SetupKey) { *out = *in @@ -432,12 +437,12 @@ func (in *SetupKeySpec) DeepCopyInto(out *SetupKeySpec) { *out = *in if in.Duration != nil { in, out := &in.Duration, &out.Duration - *out = new(v1.Duration) + *out = new(metav1.Duration) **out = **in } if in.AutoGroups != nil { in, out := &in.AutoGroups, &out.AutoGroups - *out = make([]ResourceReference, len(*in)) + *out = make([]GroupReference, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -459,7 +464,7 @@ func (in *SetupKeyStatus) DeepCopyInto(out *SetupKeyStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) + *out = make([]metav1.Condition, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -500,7 +505,7 @@ func (in *WorkloadOverride) DeepCopyInto(out *WorkloadOverride) { } if in.PodTemplate != nil { in, out := &in.PodTemplate, &out.PodTemplate - *out = new(corev1.PodTemplateSpec) + *out = new(v1.PodTemplateSpec) (*in).DeepCopyInto(*out) } } diff --git a/examples/refactor/networkresource.yaml b/examples/refactor/networkresource.yaml index 0d8648b..ec484ae 100644 --- a/examples/refactor/networkresource.yaml +++ b/examples/refactor/networkresource.yaml @@ -53,3 +53,5 @@ spec: namespace: netbird serviceRef: name: nginx + groups: + - name: All diff --git a/helm/kubernetes-operator/crds/netbird.io_networkresources.yaml b/helm/kubernetes-operator/crds/netbird.io_networkresources.yaml index 0f350f0..4ed250a 100644 --- a/helm/kubernetes-operator/crds/netbird.io_networkresources.yaml +++ b/helm/kubernetes-operator/crds/netbird.io_networkresources.yaml @@ -52,10 +52,10 @@ spec: items: properties: id: - description: ID is the id of a resource in the Netbird API. + description: ID is the id of the group. type: string localRef: - description: LocalReference is a reference to a object in the + description: LocalReference is a reference to a group in the same namespace. properties: name: @@ -69,11 +69,13 @@ spec: 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 or localRef must be set - rule: (has(self.id) && !has(self.localRef)) || (!has(self.id) - && has(self.localRef)) + - 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 networkRouterRef: description: NetworkRouterRef is a reference to the network and router diff --git a/helm/kubernetes-operator/crds/netbird.io_setupkeys.yaml b/helm/kubernetes-operator/crds/netbird.io_setupkeys.yaml index 36af5d4..0b1cad4 100644 --- a/helm/kubernetes-operator/crds/netbird.io_setupkeys.yaml +++ b/helm/kubernetes-operator/crds/netbird.io_setupkeys.yaml @@ -52,10 +52,10 @@ spec: items: properties: id: - description: ID is the id of a resource in the Netbird API. + description: ID is the id of the group. type: string localRef: - description: LocalReference is a reference to a object in the + description: LocalReference is a reference to a group in the same namespace. properties: name: @@ -69,11 +69,13 @@ spec: 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 or localRef must be set - rule: (has(self.id) && !has(self.localRef)) || (!has(self.id) - && has(self.localRef)) + - 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 duration: description: Duration sets how long the setup key is valid for. diff --git a/internal/controller/networkrouter_controller.go b/internal/controller/networkrouter_controller.go index dae9378..0954dad 100644 --- a/internal/controller/networkrouter_controller.go +++ b/internal/controller/networkrouter_controller.go @@ -132,7 +132,7 @@ func (r *NetworkRouterReconciler) Reconcile(ctx context.Context, req ctrl.Reques nbv1alpha1ac.SetupKeySpec(). WithName(fmt.Sprintf("networkrouter-%s", uniqueSuffix)). WithEphemeral(true). - WithAutoGroups(nbv1alpha1ac.ResourceReference().WithID(group.Status.GroupID)), + WithAutoGroups(nbv1alpha1ac.GroupReference().WithID(group.Status.GroupID)), ) err = r.Client.Apply(ctx, setupKeyAC) if err != nil { diff --git a/internal/netbirdutil/group.go b/internal/netbirdutil/group.go index 2aaaa08..9d2c5aa 100644 --- a/internal/netbirdutil/group.go +++ b/internal/netbirdutil/group.go @@ -11,16 +11,22 @@ import ( nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1" ) -func GetGroupIDs(ctx context.Context, k8sClient client.Client, nbClient *netbird.Client, refs []nbv1alpha1.ResourceReference, namespace string) ([]string, error) { +func GetGroupIDs(ctx context.Context, k8sClient client.Client, nbClient *netbird.Client, refs []nbv1alpha1.GroupReference, namespace string) ([]string, error) { groupIDs := []string{} for _, ref := range refs { switch { - case ref.ID != nil: - _, err := nbClient.Groups.Get(ctx, *ref.ID) + case ref.Name != nil: + group, err := nbClient.Groups.GetByName(ctx, *ref.Name) if err != nil { return nil, err } - groupIDs = append(groupIDs, *ref.ID) + groupIDs = append(groupIDs, group.Id) + case ref.ID != nil: + group, err := nbClient.Groups.Get(ctx, *ref.ID) + if err != nil { + return nil, err + } + groupIDs = append(groupIDs, group.Id) case ref.LocalRef != nil: group := nbv1alpha1.Group{ ObjectMeta: metav1.ObjectMeta{ diff --git a/pkg/applyconfigurations/api/v1alpha1/groupreference.go b/pkg/applyconfigurations/api/v1alpha1/groupreference.go new file mode 100644 index 0000000..35f934e --- /dev/null +++ b/pkg/applyconfigurations/api/v1alpha1/groupreference.go @@ -0,0 +1,48 @@ +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/api/core/v1" +) + +// GroupReferenceApplyConfiguration represents a declarative configuration of the GroupReference type for use +// with apply. +type GroupReferenceApplyConfiguration struct { + // Name is the name of the group. + Name *string `json:"name,omitempty"` + // ID is the id of the group. + ID *string `json:"id,omitempty"` + // LocalReference is a reference to a group in the same namespace. + LocalRef *v1.LocalObjectReference `json:"localRef,omitempty"` +} + +// GroupReferenceApplyConfiguration constructs a declarative configuration of the GroupReference type for use with +// apply. +func GroupReference() *GroupReferenceApplyConfiguration { + return &GroupReferenceApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *GroupReferenceApplyConfiguration) WithName(value string) *GroupReferenceApplyConfiguration { + b.Name = &value + return b +} + +// WithID sets the ID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ID field is set to the value of the last call. +func (b *GroupReferenceApplyConfiguration) WithID(value string) *GroupReferenceApplyConfiguration { + b.ID = &value + return b +} + +// WithLocalRef sets the LocalRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LocalRef field is set to the value of the last call. +func (b *GroupReferenceApplyConfiguration) WithLocalRef(value v1.LocalObjectReference) *GroupReferenceApplyConfiguration { + b.LocalRef = &value + return b +} diff --git a/pkg/applyconfigurations/api/v1alpha1/networkresourcespec.go b/pkg/applyconfigurations/api/v1alpha1/networkresourcespec.go index 656fcfd..61b7ca9 100644 --- a/pkg/applyconfigurations/api/v1alpha1/networkresourcespec.go +++ b/pkg/applyconfigurations/api/v1alpha1/networkresourcespec.go @@ -16,7 +16,7 @@ type NetworkResourceSpecApplyConfiguration struct { // ServiceRef is a reference to the service to expose in the Network. ServiceRef *v1.LocalObjectReference `json:"serviceRef,omitempty"` // Groups are references to groups that the resource will be a part of. - Groups []ResourceReferenceApplyConfiguration `json:"groups,omitempty"` + Groups []GroupReferenceApplyConfiguration `json:"groups,omitempty"` } // NetworkResourceSpecApplyConfiguration constructs a declarative configuration of the NetworkResourceSpec type for use with @@ -44,7 +44,7 @@ func (b *NetworkResourceSpecApplyConfiguration) WithServiceRef(value v1.LocalObj // 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 *NetworkResourceSpecApplyConfiguration) WithGroups(values ...*ResourceReferenceApplyConfiguration) *NetworkResourceSpecApplyConfiguration { +func (b *NetworkResourceSpecApplyConfiguration) WithGroups(values ...*GroupReferenceApplyConfiguration) *NetworkResourceSpecApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithGroups") diff --git a/pkg/applyconfigurations/api/v1alpha1/setupkeyspec.go b/pkg/applyconfigurations/api/v1alpha1/setupkeyspec.go index c1c1785..b16ce18 100644 --- a/pkg/applyconfigurations/api/v1alpha1/setupkeyspec.go +++ b/pkg/applyconfigurations/api/v1alpha1/setupkeyspec.go @@ -18,7 +18,7 @@ type SetupKeySpecApplyConfiguration struct { // Duration sets how long the setup key is valid for. Duration *v1.Duration `json:"duration,omitempty"` // AutoGroups are groups that will be automatically assigned to peers using setup key. - AutoGroups []ResourceReferenceApplyConfiguration `json:"autoGroups,omitempty"` + AutoGroups []GroupReferenceApplyConfiguration `json:"autoGroups,omitempty"` } // SetupKeySpecApplyConfiguration constructs a declarative configuration of the SetupKeySpec type for use with @@ -54,7 +54,7 @@ func (b *SetupKeySpecApplyConfiguration) WithDuration(value v1.Duration) *SetupK // WithAutoGroups adds the given value to the AutoGroups 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 AutoGroups field. -func (b *SetupKeySpecApplyConfiguration) WithAutoGroups(values ...*ResourceReferenceApplyConfiguration) *SetupKeySpecApplyConfiguration { +func (b *SetupKeySpecApplyConfiguration) WithAutoGroups(values ...*GroupReferenceApplyConfiguration) *SetupKeySpecApplyConfiguration { for i := range values { if values[i] == nil { panic("nil value passed to WithAutoGroups") diff --git a/pkg/applyconfigurations/utils.go b/pkg/applyconfigurations/utils.go index b3eb325..073a785 100644 --- a/pkg/applyconfigurations/utils.go +++ b/pkg/applyconfigurations/utils.go @@ -22,6 +22,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &apiv1alpha1.DNSZoneReferenceApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("Group"): return &apiv1alpha1.GroupApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("GroupReference"): + return &apiv1alpha1.GroupReferenceApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("GroupSpec"): return &apiv1alpha1.GroupSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("GroupStatus"): @@ -38,8 +40,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &apiv1alpha1.NetworkRouterSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("NetworkRouterStatus"): return &apiv1alpha1.NetworkRouterStatusApplyConfiguration{} - case v1alpha1.SchemeGroupVersion.WithKind("ResourceReference"): - return &apiv1alpha1.ResourceReferenceApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("SetupKey"): return &apiv1alpha1.SetupKeyApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("SetupKeySpec"):