mirror of
https://github.com/YuzuZensai/netbird-kubernetes-operator.git
synced 2026-09-13 10:49:15 +00:00
Add network router and resource (#189)
This change adds two new resources, NetworkRouter and NetworkResource, which enable clusters to expose Kubernetes services to Netbird. The NetworkRouter is responsible for creating the network, group, setup key and routing peer all of which are unique to the isntance. Along with the deployment of the client in the cluster. The NetworkResource exposes a service by linking to the specific router it wants to expose to. This makes coupling between the resource and network easy to understand. Routers also set a DNS zone which is used to give names to resources based on the name and namespace of the service being exposed. Part of #172 Signed-off-by: Philip Laine <philip.laine@gmail.com>
This commit is contained in:
@@ -89,7 +89,7 @@ endif
|
|||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: manifests ## Install CRDs into the K8s cluster specified in ~/.kube/config.
|
install: manifests ## Install CRDs into the K8s cluster specified in ~/.kube/config.
|
||||||
$(KUBECTL) apply -f helm/kubernetes-operator/crds
|
$(KUBECTL) apply --server-side -f helm/kubernetes-operator/crds
|
||||||
|
|
||||||
.PHONY: uninstall
|
.PHONY: uninstall
|
||||||
uninstall: manifests ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
|
uninstall: manifests ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
|
||||||
|
|||||||
@@ -91,4 +91,20 @@ resources:
|
|||||||
kind: Group
|
kind: Group
|
||||||
path: github.com/netbirdio/kubernetes-operator/api/v1alpha1
|
path: github.com/netbirdio/kubernetes-operator/api/v1alpha1
|
||||||
version: v1alpha1
|
version: v1alpha1
|
||||||
|
- api:
|
||||||
|
crdVersion: v1
|
||||||
|
namespaced: true
|
||||||
|
controller: true
|
||||||
|
domain: netbird.io
|
||||||
|
kind: NetworkRouter
|
||||||
|
path: github.com/netbirdio/kubernetes-operator/api/v1alpha1
|
||||||
|
version: v1alpha1
|
||||||
|
- api:
|
||||||
|
crdVersion: v1
|
||||||
|
namespaced: true
|
||||||
|
controller: true
|
||||||
|
domain: netbird.io
|
||||||
|
kind: NetworkResource
|
||||||
|
path: github.com/netbirdio/kubernetes-operator/api/v1alpha1
|
||||||
|
version: v1alpha1
|
||||||
version: "3"
|
version: "3"
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ const ReadyCondition = "Ready"
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ReconciledReason = "Reconciled"
|
ReconciledReason = "Reconciled"
|
||||||
|
DependencyReason = "Dependency"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkResourceSpec defines the desired state of NetworkResource.
|
||||||
|
type NetworkResourceSpec struct {
|
||||||
|
// NetworkRouterRef is a reference to the network and router where the resource will be created.
|
||||||
|
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value is immutable"
|
||||||
|
NetworkRouterRef CrossNamespaceReference `json:"networkRouterRef"`
|
||||||
|
|
||||||
|
// ServiceRef is a reference to the service to expose in the Network.
|
||||||
|
ServiceRef corev1.LocalObjectReference `json:"serviceRef"`
|
||||||
|
|
||||||
|
// Groups are references to groups that the resource will be a part of.
|
||||||
|
// +optional
|
||||||
|
Groups []ResourceReference `json:"groups,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkResourceStatus defines the observed state of NetworkResource.
|
||||||
|
type NetworkResourceStatus struct {
|
||||||
|
// ObservedGeneration is the last reconciled generation.
|
||||||
|
// +optional
|
||||||
|
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||||
|
|
||||||
|
// Conditions holds the conditions for the NetworkResource.
|
||||||
|
// +listType=map
|
||||||
|
// +listMapKey=type
|
||||||
|
// +optional
|
||||||
|
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||||
|
|
||||||
|
// NetworkID is the id of the network the resource is created in.
|
||||||
|
// +optional
|
||||||
|
NetworkID string `json:"networkID,omitempty"`
|
||||||
|
|
||||||
|
// ResourceID is the id of the created resource.
|
||||||
|
// +optional
|
||||||
|
ResourceID string `json:"resourceID,omitempty"`
|
||||||
|
|
||||||
|
// DNSZoneID is the id of the zone the DNS record is created in.
|
||||||
|
// +optional
|
||||||
|
DNSZoneID string `json:"dnsZoneID,omitempty"`
|
||||||
|
|
||||||
|
// DNSRecordID is the id of the created DNS record.
|
||||||
|
// +optional
|
||||||
|
DNSRecordID string `json:"dnsRecordID,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
|
// +kubebuilder:resource
|
||||||
|
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
||||||
|
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
|
||||||
|
|
||||||
|
// NetworkResource is the Schema for the networkresources API.
|
||||||
|
type NetworkResource struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
// +required
|
||||||
|
Spec NetworkResourceSpec `json:"spec"`
|
||||||
|
|
||||||
|
// +kubebuilder:default={"observedGeneration":-1}
|
||||||
|
Status NetworkResourceStatus `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConditions returns the status conditions of the object.
|
||||||
|
func (n *NetworkResource) GetConditions() []metav1.Condition {
|
||||||
|
return n.Status.Conditions
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConditions sets the status conditions on the object.
|
||||||
|
func (n *NetworkResource) SetConditions(conditions []metav1.Condition) {
|
||||||
|
n.Status.Conditions = conditions
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// NetworkResourceList contains a list of NetworkResource.
|
||||||
|
type NetworkResourceList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitzero"`
|
||||||
|
Items []NetworkResource `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SchemeBuilder.Register(&NetworkResource{}, &NetworkResourceList{})
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkRouterSpec defines the desired state of NetworkRouter.
|
||||||
|
type NetworkRouterSpec struct {
|
||||||
|
// DNSZoneRef is a reference to the DNS zone used to create records for resources.
|
||||||
|
// +required
|
||||||
|
DNSZoneRef DNSZoneReference `json:"dnsZoneRef"`
|
||||||
|
|
||||||
|
// WorkloadOverride contains configuration that will override the default workload.
|
||||||
|
// +optional
|
||||||
|
WorkloadOverride *WorkloadOverride `json:"workloadOverride,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSZoneReference references a Netbird DNS zone by domain name.
|
||||||
|
type DNSZoneReference struct {
|
||||||
|
// Name is the domain name of an existing Netbird DNS zone, e.g. "example.com".
|
||||||
|
// +required
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WorkloadOverride struct {
|
||||||
|
// Labels that will be added.
|
||||||
|
// +optional
|
||||||
|
Labels map[string]string `json:"labels"`
|
||||||
|
|
||||||
|
// Annotations that will be added.
|
||||||
|
// +optional
|
||||||
|
Annotations map[string]string `json:"annotations"`
|
||||||
|
|
||||||
|
// Replicas sets the amount of client replicas.
|
||||||
|
// +optional
|
||||||
|
Replicas *int32 `json:"replicas"`
|
||||||
|
|
||||||
|
// PodTemplate overrides the pod template.
|
||||||
|
// +optional
|
||||||
|
// +kubebuilder:pruning:PreserveUnknownFields
|
||||||
|
// +kubebuilder:validation:Schemaless
|
||||||
|
PodTemplate *corev1.PodTemplateSpec `json:"podTemplate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkRouterStatus defines the observed state of NetworkRouter.
|
||||||
|
type NetworkRouterStatus struct {
|
||||||
|
// ObservedGeneration is the last reconciled generation.
|
||||||
|
// +optional
|
||||||
|
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||||
|
|
||||||
|
// Conditions holds the conditions for the NetworkRouter.
|
||||||
|
// +listType=map
|
||||||
|
// +listMapKey=type
|
||||||
|
// +optional
|
||||||
|
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||||
|
|
||||||
|
// RoutingPeerID is the id of the created routing peer.
|
||||||
|
// +optional
|
||||||
|
RoutingPeerID string `json:"routingPeerID,omitempty"`
|
||||||
|
|
||||||
|
// NetworkID is the id of the network the routing peer was created in.
|
||||||
|
// +optional
|
||||||
|
NetworkID string `json:"networkID,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
|
// +kubebuilder:resource
|
||||||
|
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
||||||
|
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description=""
|
||||||
|
|
||||||
|
// NetworkRouter is the Schema for the networkrouters API.
|
||||||
|
type NetworkRouter struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
|
// +required
|
||||||
|
Spec NetworkRouterSpec `json:"spec"`
|
||||||
|
|
||||||
|
// +kubebuilder:default={"observedGeneration":-1}
|
||||||
|
Status NetworkRouterStatus `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConditions returns the status conditions of the object.
|
||||||
|
func (n *NetworkRouter) GetConditions() []metav1.Condition {
|
||||||
|
return n.Status.Conditions
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConditions sets the status conditions on the object.
|
||||||
|
func (n *NetworkRouter) SetConditions(conditions []metav1.Condition) {
|
||||||
|
n.Status.Conditions = conditions
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// NetworkRouterList contains a list of NetworkRouter.
|
||||||
|
type NetworkRouterList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitzero"`
|
||||||
|
Items []NetworkRouter `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SchemeBuilder.Register(&NetworkRouter{}, &NetworkRouterList{})
|
||||||
|
}
|
||||||
@@ -4,11 +4,21 @@ 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"
|
// +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 {
|
type ResourceReference struct {
|
||||||
// id of the resource in the Netbird API.
|
// ID is the id of a resource in the Netbird API.
|
||||||
// +optional
|
// +optional
|
||||||
ID *string `json:"id,omitempty"`
|
ID *string `json:"id,omitempty"`
|
||||||
|
|
||||||
// local reference to the object in the same namespace.
|
// LocalReference is a reference to a object in the same namespace.
|
||||||
// +optional
|
// +optional
|
||||||
LocalRef *corev1.LocalObjectReference `json:"localRef,omitempty"`
|
LocalRef *corev1.LocalObjectReference `json:"localRef,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CrossNamespaceReference struct {
|
||||||
|
// Name of the referent.
|
||||||
|
// +required
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// Namespace of the referent.
|
||||||
|
// +required
|
||||||
|
Namespace string `json:"namespace"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ import (
|
|||||||
|
|
||||||
// SetupKeySpec defines the desired state of SetupKey.
|
// SetupKeySpec defines the desired state of SetupKey.
|
||||||
type SetupKeySpec struct {
|
type SetupKeySpec struct {
|
||||||
|
// Name of the setup key.
|
||||||
|
// +kubebuilder:validation:MinLength=1
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
// Ephemeral decides if peers added with the key are ephemeral or not.
|
// Ephemeral decides if peers added with the key are ephemeral or not.
|
||||||
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ephemeral is immutable"
|
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ephemeral is immutable"
|
||||||
Ephemeral bool `json:"ephemeral"`
|
Ephemeral bool `json:"ephemeral"`
|
||||||
|
|||||||
@@ -10,6 +10,36 @@ import (
|
|||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *CrossNamespaceReference) DeepCopyInto(out *CrossNamespaceReference) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CrossNamespaceReference.
|
||||||
|
func (in *CrossNamespaceReference) DeepCopy() *CrossNamespaceReference {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(CrossNamespaceReference)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *DNSZoneReference) DeepCopyInto(out *DNSZoneReference) {
|
||||||
|
*out = *in
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSZoneReference.
|
||||||
|
func (in *DNSZoneReference) DeepCopy() *DNSZoneReference {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(DNSZoneReference)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *Group) DeepCopyInto(out *Group) {
|
func (in *Group) DeepCopyInto(out *Group) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -106,6 +136,213 @@ func (in *GroupStatus) DeepCopy() *GroupStatus {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *NetworkResource) DeepCopyInto(out *NetworkResource) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
|
in.Status.DeepCopyInto(&out.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkResource.
|
||||||
|
func (in *NetworkResource) DeepCopy() *NetworkResource {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkResource)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *NetworkResource) 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 *NetworkResourceList) DeepCopyInto(out *NetworkResourceList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]NetworkResource, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkResourceList.
|
||||||
|
func (in *NetworkResourceList) DeepCopy() *NetworkResourceList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkResourceList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *NetworkResourceList) 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 *NetworkResourceSpec) DeepCopyInto(out *NetworkResourceSpec) {
|
||||||
|
*out = *in
|
||||||
|
out.NetworkRouterRef = in.NetworkRouterRef
|
||||||
|
out.ServiceRef = in.ServiceRef
|
||||||
|
if in.Groups != nil {
|
||||||
|
in, out := &in.Groups, &out.Groups
|
||||||
|
*out = make([]ResourceReference, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkResourceSpec.
|
||||||
|
func (in *NetworkResourceSpec) DeepCopy() *NetworkResourceSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkResourceSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *NetworkResourceStatus) DeepCopyInto(out *NetworkResourceStatus) {
|
||||||
|
*out = *in
|
||||||
|
if in.Conditions != nil {
|
||||||
|
in, out := &in.Conditions, &out.Conditions
|
||||||
|
*out = make([]v1.Condition, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkResourceStatus.
|
||||||
|
func (in *NetworkResourceStatus) DeepCopy() *NetworkResourceStatus {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkResourceStatus)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *NetworkRouter) DeepCopyInto(out *NetworkRouter) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
|
in.Status.DeepCopyInto(&out.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkRouter.
|
||||||
|
func (in *NetworkRouter) DeepCopy() *NetworkRouter {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkRouter)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *NetworkRouter) 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 *NetworkRouterList) DeepCopyInto(out *NetworkRouterList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]NetworkRouter, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkRouterList.
|
||||||
|
func (in *NetworkRouterList) DeepCopy() *NetworkRouterList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkRouterList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *NetworkRouterList) 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 *NetworkRouterSpec) DeepCopyInto(out *NetworkRouterSpec) {
|
||||||
|
*out = *in
|
||||||
|
out.DNSZoneRef = in.DNSZoneRef
|
||||||
|
if in.WorkloadOverride != nil {
|
||||||
|
in, out := &in.WorkloadOverride, &out.WorkloadOverride
|
||||||
|
*out = new(WorkloadOverride)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkRouterSpec.
|
||||||
|
func (in *NetworkRouterSpec) DeepCopy() *NetworkRouterSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkRouterSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *NetworkRouterStatus) DeepCopyInto(out *NetworkRouterStatus) {
|
||||||
|
*out = *in
|
||||||
|
if in.Conditions != nil {
|
||||||
|
in, out := &in.Conditions, &out.Conditions
|
||||||
|
*out = make([]v1.Condition, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkRouterStatus.
|
||||||
|
func (in *NetworkRouterStatus) DeepCopy() *NetworkRouterStatus {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(NetworkRouterStatus)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *ResourceReference) DeepCopyInto(out *ResourceReference) {
|
func (in *ResourceReference) DeepCopyInto(out *ResourceReference) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@@ -238,3 +475,42 @@ func (in *SetupKeyStatus) DeepCopy() *SetupKeyStatus {
|
|||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *WorkloadOverride) DeepCopyInto(out *WorkloadOverride) {
|
||||||
|
*out = *in
|
||||||
|
if in.Labels != nil {
|
||||||
|
in, out := &in.Labels, &out.Labels
|
||||||
|
*out = make(map[string]string, len(*in))
|
||||||
|
for key, val := range *in {
|
||||||
|
(*out)[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.Annotations != nil {
|
||||||
|
in, out := &in.Annotations, &out.Annotations
|
||||||
|
*out = make(map[string]string, len(*in))
|
||||||
|
for key, val := range *in {
|
||||||
|
(*out)[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.Replicas != nil {
|
||||||
|
in, out := &in.Replicas, &out.Replicas
|
||||||
|
*out = new(int32)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
if in.PodTemplate != nil {
|
||||||
|
in, out := &in.PodTemplate, &out.PodTemplate
|
||||||
|
*out = new(corev1.PodTemplateSpec)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadOverride.
|
||||||
|
func (in *WorkloadOverride) DeepCopy() *WorkloadOverride {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(WorkloadOverride)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|||||||
+29
-9
@@ -29,7 +29,7 @@ import (
|
|||||||
// to ensure that exec-entrypoint and run can make use of them.
|
// to ensure that exec-entrypoint and run can make use of them.
|
||||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||||
|
|
||||||
netbirdrest "github.com/netbirdio/netbird/shared/management/client/rest"
|
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
@@ -222,11 +222,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(netbirdAPIKey) > 0 {
|
if len(netbirdAPIKey) > 0 {
|
||||||
netbird := netbirdrest.New(managementURL, netbirdAPIKey)
|
nbClient := netbird.NewWithOptions(
|
||||||
|
netbird.WithManagementURL(managementURL),
|
||||||
|
netbird.WithBearerToken(netbirdAPIKey),
|
||||||
|
netbird.WithUserAgent("netbird-operator"),
|
||||||
|
)
|
||||||
|
|
||||||
if err = (&controller.NBRoutingPeerReconciler{
|
if err = (&controller.NBRoutingPeerReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Netbird: netbird,
|
Netbird: nbClient,
|
||||||
ClientImage: clientImage,
|
ClientImage: clientImage,
|
||||||
ClusterName: clusterName,
|
ClusterName: clusterName,
|
||||||
ManagementURL: managementURL,
|
ManagementURL: managementURL,
|
||||||
@@ -251,7 +255,7 @@ func main() {
|
|||||||
|
|
||||||
if err = (&controller.NBResourceReconciler{
|
if err = (&controller.NBResourceReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Netbird: netbird,
|
Netbird: nbClient,
|
||||||
AllowAutomaticPolicyCreation: allowAutomaticPolicyCreation,
|
AllowAutomaticPolicyCreation: allowAutomaticPolicyCreation,
|
||||||
ClusterName: clusterName,
|
ClusterName: clusterName,
|
||||||
DefaultLabels: defaultLabelsMap,
|
DefaultLabels: defaultLabelsMap,
|
||||||
@@ -262,7 +266,7 @@ func main() {
|
|||||||
|
|
||||||
if err = (&controller.NBGroupReconciler{
|
if err = (&controller.NBGroupReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Netbird: netbird,
|
Netbird: nbClient,
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "NBGroup")
|
setupLog.Error(err, "unable to create controller", "controller", "NBGroup")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -270,7 +274,7 @@ func main() {
|
|||||||
|
|
||||||
if err = (&controller.NBPolicyReconciler{
|
if err = (&controller.NBPolicyReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Netbird: netbird,
|
Netbird: nbClient,
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "NBPolicy")
|
setupLog.Error(err, "unable to create controller", "controller", "NBPolicy")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -285,18 +289,34 @@ func main() {
|
|||||||
|
|
||||||
if err := (&controller.SetupKeyReconciler{
|
if err := (&controller.SetupKeyReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Netbird: netbird,
|
Netbird: nbClient,
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "Failed to create controller", "controller", "SetupKey")
|
setupLog.Error(err, "Failed to create controller", "controller", "SetupKey")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if err := (&controller.GroupReconciler{
|
if err := (&controller.GroupReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Netbird: netbird,
|
Netbird: nbClient,
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "Failed to create controller", "controller", "Group")
|
setupLog.Error(err, "Failed to create controller", "controller", "Group")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
if err := (&controller.NetworkRouterReconciler{
|
||||||
|
Client: mgr.GetClient(),
|
||||||
|
Netbird: nbClient,
|
||||||
|
ClientImage: clientImage,
|
||||||
|
ManagementURL: managementURL,
|
||||||
|
}).SetupWithManager(mgr); err != nil {
|
||||||
|
setupLog.Error(err, "Failed to create controller", "controller", "NetworkRouter")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if err := (&controller.NetworkResourceReconciler{
|
||||||
|
Client: mgr.GetClient(),
|
||||||
|
Netbird: nbClient,
|
||||||
|
}).SetupWithManager(mgr); err != nil {
|
||||||
|
setupLog.Error(err, "Failed to create controller", "controller", "NetworkResource")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
if gatewayAPIEnabled {
|
if gatewayAPIEnabled {
|
||||||
if err = (&controller.GatewayClassReconciler{
|
if err = (&controller.GatewayClassReconciler{
|
||||||
@@ -313,7 +333,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
if err = (&controller.HTTPRouteReconciler{
|
if err = (&controller.HTTPRouteReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Netbird: netbird,
|
Netbird: nbClient,
|
||||||
ClusterDNS: clusterDNS,
|
ClusterDNS: clusterDNS,
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "HTTPRoute")
|
setupLog.Error(err, "unable to create controller", "controller", "HTTPRoute")
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ apiVersion: netbird.io/v1alpha1
|
|||||||
kind: Group
|
kind: Group
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
namespace: default
|
namespace: netbird
|
||||||
spec:
|
spec:
|
||||||
name: test
|
name: test
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: nginx
|
||||||
|
strategy:
|
||||||
|
rollingUpdate:
|
||||||
|
maxSurge: 25%
|
||||||
|
maxUnavailable: 25%
|
||||||
|
type: RollingUpdate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
imagePullPolicy: Always
|
||||||
|
name: nginx
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: 80
|
||||||
|
selector:
|
||||||
|
app: nginx
|
||||||
|
---
|
||||||
|
apiVersion: netbird.io/v1alpha1
|
||||||
|
kind: NetworkResource
|
||||||
|
metadata:
|
||||||
|
name: test
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
networkRouterRef:
|
||||||
|
name: test
|
||||||
|
namespace: netbird
|
||||||
|
serviceRef:
|
||||||
|
name: nginx
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: netbird.io/v1alpha1
|
||||||
|
kind: NetworkRouter
|
||||||
|
metadata:
|
||||||
|
name: test
|
||||||
|
namespace: netbird
|
||||||
|
spec:
|
||||||
|
dnsZoneRef:
|
||||||
|
name: cluster.local
|
||||||
@@ -2,6 +2,6 @@ apiVersion: netbird.io/v1alpha1
|
|||||||
kind: SetupKey
|
kind: SetupKey
|
||||||
metadata:
|
metadata:
|
||||||
name: test
|
name: test
|
||||||
namespace: default
|
namespace: netbird
|
||||||
spec:
|
spec:
|
||||||
ephemeral: true
|
name: test
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.20.1
|
||||||
|
name: networkresources.netbird.io
|
||||||
|
spec:
|
||||||
|
group: netbird.io
|
||||||
|
names:
|
||||||
|
kind: NetworkResource
|
||||||
|
listKind: NetworkResourceList
|
||||||
|
plural: networkresources
|
||||||
|
singular: networkresource
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||||
|
name: Ready
|
||||||
|
type: string
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: NetworkResource is the Schema for the networkresources API.
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: |-
|
||||||
|
APIVersion defines the versioned schema of this representation of an object.
|
||||||
|
Servers should convert recognized schemas to the latest internal value, and
|
||||||
|
may reject unrecognized values.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: |-
|
||||||
|
Kind is a string value representing the REST resource this object represents.
|
||||||
|
Servers may infer this from the endpoint the client submits requests to.
|
||||||
|
Cannot be updated.
|
||||||
|
In CamelCase.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: NetworkResourceSpec defines the desired state of NetworkResource.
|
||||||
|
properties:
|
||||||
|
groups:
|
||||||
|
description: Groups are references to groups that the resource will
|
||||||
|
be a part of.
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
description: ID is the id of a resource in the Netbird API.
|
||||||
|
type: string
|
||||||
|
localRef:
|
||||||
|
description: LocalReference is a reference to a object 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
|
||||||
|
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))
|
||||||
|
type: array
|
||||||
|
networkRouterRef:
|
||||||
|
description: NetworkRouterRef is a reference to the network and router
|
||||||
|
where the resource will be created.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name of the referent.
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
description: Namespace of the referent.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- namespace
|
||||||
|
type: object
|
||||||
|
x-kubernetes-validations:
|
||||||
|
- message: Value is immutable
|
||||||
|
rule: self == oldSelf
|
||||||
|
serviceRef:
|
||||||
|
description: ServiceRef is a reference to the service to expose in
|
||||||
|
the Network.
|
||||||
|
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
|
||||||
|
required:
|
||||||
|
- networkRouterRef
|
||||||
|
- serviceRef
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
default:
|
||||||
|
observedGeneration: -1
|
||||||
|
description: NetworkResourceStatus defines the observed state of NetworkResource.
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: Conditions holds the conditions for the NetworkResource.
|
||||||
|
items:
|
||||||
|
description: Condition contains details for one aspect of the current
|
||||||
|
state of this API Resource.
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: |-
|
||||||
|
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||||
|
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: |-
|
||||||
|
message is a human readable message indicating details about the transition.
|
||||||
|
This may be an empty string.
|
||||||
|
maxLength: 32768
|
||||||
|
type: string
|
||||||
|
observedGeneration:
|
||||||
|
description: |-
|
||||||
|
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||||
|
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||||
|
with respect to the current state of the instance.
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
type: integer
|
||||||
|
reason:
|
||||||
|
description: |-
|
||||||
|
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||||
|
Producers of specific condition types may define expected values and meanings for this field,
|
||||||
|
and whether the values are considered a guaranteed API.
|
||||||
|
The value should be a CamelCase string.
|
||||||
|
This field may not be empty.
|
||||||
|
maxLength: 1024
|
||||||
|
minLength: 1
|
||||||
|
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: status of the condition, one of True, False, Unknown.
|
||||||
|
enum:
|
||||||
|
- "True"
|
||||||
|
- "False"
|
||||||
|
- Unknown
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||||
|
maxLength: 316
|
||||||
|
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- lastTransitionTime
|
||||||
|
- message
|
||||||
|
- reason
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
dnsRecordID:
|
||||||
|
description: DNSRecordID is the id of the created DNS record.
|
||||||
|
type: string
|
||||||
|
dnsZoneID:
|
||||||
|
description: DNSZoneID is the id of the zone the DNS record is created
|
||||||
|
in.
|
||||||
|
type: string
|
||||||
|
networkID:
|
||||||
|
description: NetworkID is the id of the network the resource is created
|
||||||
|
in.
|
||||||
|
type: string
|
||||||
|
observedGeneration:
|
||||||
|
description: ObservedGeneration is the last reconciled generation.
|
||||||
|
format: int64
|
||||||
|
type: integer
|
||||||
|
resourceID:
|
||||||
|
description: ResourceID is the id of the created resource.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.20.1
|
||||||
|
name: networkrouters.netbird.io
|
||||||
|
spec:
|
||||||
|
group: netbird.io
|
||||||
|
names:
|
||||||
|
kind: NetworkRouter
|
||||||
|
listKind: NetworkRouterList
|
||||||
|
plural: networkrouters
|
||||||
|
singular: networkrouter
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||||
|
name: Ready
|
||||||
|
type: string
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: NetworkRouter is the Schema for the networkrouters API.
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: |-
|
||||||
|
APIVersion defines the versioned schema of this representation of an object.
|
||||||
|
Servers should convert recognized schemas to the latest internal value, and
|
||||||
|
may reject unrecognized values.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: |-
|
||||||
|
Kind is a string value representing the REST resource this object represents.
|
||||||
|
Servers may infer this from the endpoint the client submits requests to.
|
||||||
|
Cannot be updated.
|
||||||
|
In CamelCase.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: NetworkRouterSpec defines the desired state of NetworkRouter.
|
||||||
|
properties:
|
||||||
|
dnsZoneRef:
|
||||||
|
description: DNSZoneRef is a reference to the DNS zone used to create
|
||||||
|
records for resources.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Name is the domain name of an existing Netbird DNS
|
||||||
|
zone, e.g. "example.com".
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
workloadOverride:
|
||||||
|
description: WorkloadOverride contains configuration that will override
|
||||||
|
the default workload.
|
||||||
|
properties:
|
||||||
|
annotations:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: Annotations that will be added.
|
||||||
|
type: object
|
||||||
|
labels:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: Labels that will be added.
|
||||||
|
type: object
|
||||||
|
podTemplate:
|
||||||
|
description: PodTemplate overrides the pod template.
|
||||||
|
x-kubernetes-preserve-unknown-fields: true
|
||||||
|
replicas:
|
||||||
|
description: Replicas sets the amount of client replicas.
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- dnsZoneRef
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
default:
|
||||||
|
observedGeneration: -1
|
||||||
|
description: NetworkRouterStatus defines the observed state of NetworkRouter.
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: Conditions holds the conditions for the NetworkRouter.
|
||||||
|
items:
|
||||||
|
description: Condition contains details for one aspect of the current
|
||||||
|
state of this API Resource.
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: |-
|
||||||
|
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||||
|
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: |-
|
||||||
|
message is a human readable message indicating details about the transition.
|
||||||
|
This may be an empty string.
|
||||||
|
maxLength: 32768
|
||||||
|
type: string
|
||||||
|
observedGeneration:
|
||||||
|
description: |-
|
||||||
|
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||||
|
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||||
|
with respect to the current state of the instance.
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
type: integer
|
||||||
|
reason:
|
||||||
|
description: |-
|
||||||
|
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||||
|
Producers of specific condition types may define expected values and meanings for this field,
|
||||||
|
and whether the values are considered a guaranteed API.
|
||||||
|
The value should be a CamelCase string.
|
||||||
|
This field may not be empty.
|
||||||
|
maxLength: 1024
|
||||||
|
minLength: 1
|
||||||
|
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: status of the condition, one of True, False, Unknown.
|
||||||
|
enum:
|
||||||
|
- "True"
|
||||||
|
- "False"
|
||||||
|
- Unknown
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||||
|
maxLength: 316
|
||||||
|
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- lastTransitionTime
|
||||||
|
- message
|
||||||
|
- reason
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
networkID:
|
||||||
|
description: NetworkID is the id of the network the routing peer was
|
||||||
|
created in.
|
||||||
|
type: string
|
||||||
|
observedGeneration:
|
||||||
|
description: ObservedGeneration is the last reconciled generation.
|
||||||
|
format: int64
|
||||||
|
type: integer
|
||||||
|
routingPeerID:
|
||||||
|
description: RoutingPeerID is the id of the created routing peer.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
@@ -52,10 +52,11 @@ spec:
|
|||||||
items:
|
items:
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
description: id of the resource in the Netbird API.
|
description: ID is the id of a resource in the Netbird API.
|
||||||
type: string
|
type: string
|
||||||
localRef:
|
localRef:
|
||||||
description: local reference to the object in the same namespace.
|
description: LocalReference is a reference to a object in the
|
||||||
|
same namespace.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
default: ""
|
default: ""
|
||||||
@@ -87,8 +88,13 @@ spec:
|
|||||||
x-kubernetes-validations:
|
x-kubernetes-validations:
|
||||||
- message: ephemeral is immutable
|
- message: ephemeral is immutable
|
||||||
rule: self == oldSelf
|
rule: self == oldSelf
|
||||||
|
name:
|
||||||
|
description: Name of the setup key.
|
||||||
|
minLength: 1
|
||||||
|
type: string
|
||||||
required:
|
required:
|
||||||
- ephemeral
|
- ephemeral
|
||||||
|
- name
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -0,0 +1,301 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/fluxcd/pkg/runtime/conditions"
|
||||||
|
"github.com/fluxcd/pkg/runtime/patch"
|
||||||
|
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/types"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
|
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
|
"github.com/netbirdio/kubernetes-operator/internal/netbirdutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NetworkResourceReconciler struct {
|
||||||
|
client.Client
|
||||||
|
|
||||||
|
Netbird *netbird.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=networkresources,verbs=get;list;watch;create;update;patch;delete
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=networkresources/status,verbs=get;update;patch
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=networkresources/finalizers,verbs=update
|
||||||
|
|
||||||
|
// nolint:gocyclo
|
||||||
|
func (r *NetworkResourceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||||
|
netResource := &nbv1alpha1.NetworkResource{}
|
||||||
|
err := r.Get(ctx, req.NamespacedName, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||||
|
}
|
||||||
|
sp := patch.NewSerialPatcher(netResource, r.Client)
|
||||||
|
|
||||||
|
if !netResource.DeletionTimestamp.IsZero() {
|
||||||
|
return r.reconcileDelete(ctx, sp, netResource)
|
||||||
|
}
|
||||||
|
|
||||||
|
svc := &corev1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: netResource.Spec.ServiceRef.Name,
|
||||||
|
Namespace: netResource.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = r.Get(ctx, client.ObjectKeyFromObject(svc), svc)
|
||||||
|
if err != nil {
|
||||||
|
if kerrors.IsNotFound(err) {
|
||||||
|
conditions.MarkFalse(netResource, nbv1alpha1.ReadyCondition, nbv1alpha1.DependencyReason, "Referenced Service cannot be found.")
|
||||||
|
err = sp.Patch(ctx, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
if svc.Spec.Type != corev1.ServiceTypeClusterIP {
|
||||||
|
conditions.MarkFalse(netResource, nbv1alpha1.ReadyCondition, nbv1alpha1.DependencyReason, "Referenced Service is not of type ClusterIP.")
|
||||||
|
err = sp.Patch(ctx, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
if svc.Spec.ClusterIP == "" || svc.Spec.ClusterIP == corev1.ClusterIPNone {
|
||||||
|
conditions.MarkFalse(netResource, nbv1alpha1.ReadyCondition, nbv1alpha1.DependencyReason, "Referenced Service does not have a ClusterIP set.")
|
||||||
|
err = sp.Patch(ctx, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
netRouter := &nbv1alpha1.NetworkRouter{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: netResource.Spec.NetworkRouterRef.Name,
|
||||||
|
Namespace: netResource.Spec.NetworkRouterRef.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = r.Get(ctx, client.ObjectKeyFromObject(netRouter), netRouter)
|
||||||
|
if err != nil {
|
||||||
|
if kerrors.IsNotFound(err) {
|
||||||
|
conditions.MarkFalse(netResource, nbv1alpha1.ReadyCondition, nbv1alpha1.DependencyReason, "Referenced NetworkRouter cannot be found.")
|
||||||
|
err = sp.Patch(ctx, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
if netRouter.Status.NetworkID == "" || netRouter.Status.RoutingPeerID == "" {
|
||||||
|
conditions.MarkFalse(netResource, nbv1alpha1.ReadyCondition, nbv1alpha1.DependencyReason, "Referenced NetworkRouter is not ready.")
|
||||||
|
err = sp.Patch(ctx, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
groupIDs, err := netbirdutil.GetGroupIDs(ctx, r.Client, r.Netbird, netResource.Spec.Groups, netResource.Namespace)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerutil.AddFinalizer(netResource, nbv1alpha1.NetbirdFinalizer)
|
||||||
|
|
||||||
|
resourceID, err := func() (string, error) {
|
||||||
|
netReq := api.NetworkResourceRequest{
|
||||||
|
Name: svc.Name + "/" + svc.Namespace,
|
||||||
|
Address: svc.Spec.ClusterIP,
|
||||||
|
Enabled: true,
|
||||||
|
Groups: groupIDs,
|
||||||
|
}
|
||||||
|
if netResource.Status.ResourceID != "" {
|
||||||
|
netResp, err := r.Netbird.Networks.Resources(netRouter.Status.NetworkID).Update(ctx, netResource.Status.ResourceID, netReq)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
return netResp.Id, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
netResp, err := r.Netbird.Networks.Resources(netRouter.Status.NetworkID).Create(ctx, netReq)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return netResp.Id, nil
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
netResource.Status.NetworkID = netRouter.Status.NetworkID
|
||||||
|
netResource.Status.ResourceID = resourceID
|
||||||
|
err = sp.Patch(ctx, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create DNS records for resource.
|
||||||
|
zone, err := netbirdutil.GetDNSZoneByName(ctx, r.Netbird, netRouter.Spec.DNSZoneRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If zone has changed we need to delete the old records.
|
||||||
|
if netResource.Status.DNSZoneID != "" && netResource.Status.DNSZoneID != zone.Id {
|
||||||
|
err = r.Netbird.DNSZones.DeleteRecord(ctx, netResource.Status.DNSZoneID, netResource.Status.DNSRecordID)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
netResource.Status.DNSZoneID = ""
|
||||||
|
netResource.Status.DNSRecordID = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
recordID, err := func() (string, error) {
|
||||||
|
dnsReq := api.DNSRecordRequest{
|
||||||
|
Content: svc.Spec.ClusterIP,
|
||||||
|
Name: strings.Join([]string{svc.Name, svc.Namespace, zone.Name}, "."),
|
||||||
|
Ttl: int(5 * time.Minute / time.Second),
|
||||||
|
Type: api.DNSRecordTypeA,
|
||||||
|
}
|
||||||
|
if netResource.Status.DNSZoneID != "" && netResource.Status.DNSRecordID != "" {
|
||||||
|
recordResp, err := r.Netbird.DNSZones.UpdateRecord(ctx, netResource.Status.DNSZoneID, netResource.Status.DNSRecordID, dnsReq)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
return recordResp.Id, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recordResp, err := r.Netbird.DNSZones.CreateRecord(ctx, zone.Id, dnsReq)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return recordResp.Id, nil
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
netResource.Status.DNSZoneID = zone.Id
|
||||||
|
netResource.Status.DNSRecordID = recordID
|
||||||
|
|
||||||
|
conditions.MarkTrue(netResource, nbv1alpha1.ReadyCondition, nbv1alpha1.ReconciledReason, "")
|
||||||
|
err = sp.Patch(ctx, netResource, patch.WithStatusObservedGeneration{})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *NetworkResourceReconciler) reconcileDelete(ctx context.Context, sp *patch.SerialPatcher, netResource *nbv1alpha1.NetworkResource) (ctrl.Result, error) {
|
||||||
|
if netResource.Status.NetworkID != "" && netResource.Status.ResourceID != "" {
|
||||||
|
err := r.Netbird.Networks.Resources(netResource.Status.NetworkID).Delete(ctx, netResource.Status.ResourceID)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if netResource.Status.DNSZoneID != "" && netResource.Status.DNSRecordID != "" {
|
||||||
|
err := r.Netbird.DNSZones.DeleteRecord(ctx, netResource.Status.DNSZoneID, netResource.Status.DNSRecordID)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerutil.RemoveFinalizer(netResource, nbv1alpha1.NetbirdFinalizer)
|
||||||
|
err := sp.Patch(ctx, netResource)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *NetworkResourceReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
|
err := mgr.GetFieldIndexer().IndexField(context.Background(), &nbv1alpha1.NetworkResource{}, ".spec.networkRouterRef", func(obj client.Object) []string {
|
||||||
|
netResource := obj.(*nbv1alpha1.NetworkResource)
|
||||||
|
ref := netResource.Spec.NetworkRouterRef
|
||||||
|
if ref.Name == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if ref.Namespace == "" {
|
||||||
|
ref.Namespace = netResource.Namespace
|
||||||
|
}
|
||||||
|
return []string{fmt.Sprintf("%s/%s", ref.Name, ref.Namespace)}
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = mgr.GetFieldIndexer().IndexField(context.Background(), &nbv1alpha1.NetworkResource{}, ".spec.serviceRef", func(obj client.Object) []string {
|
||||||
|
netResource := obj.(*nbv1alpha1.NetworkResource)
|
||||||
|
ref := netResource.Spec.ServiceRef
|
||||||
|
if ref.Name == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return []string{netResource.Spec.ServiceRef.Name}
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrl.NewControllerManagedBy(mgr).
|
||||||
|
For(&nbv1alpha1.NetworkResource{}).
|
||||||
|
Watches(
|
||||||
|
&nbv1alpha1.NetworkRouter{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request {
|
||||||
|
netResourceList := &nbv1alpha1.NetworkResourceList{}
|
||||||
|
err := r.List(ctx, netResourceList, client.MatchingFields{".spec.networkRouterRef": fmt.Sprintf("%s/%s", obj.GetName(), obj.GetNamespace())})
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
requests := make([]reconcile.Request, len(netResourceList.Items))
|
||||||
|
for i, item := range netResourceList.Items {
|
||||||
|
requests[i] = reconcile.Request{
|
||||||
|
NamespacedName: types.NamespacedName{
|
||||||
|
Name: item.Name,
|
||||||
|
Namespace: item.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return requests
|
||||||
|
}),
|
||||||
|
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
|
||||||
|
).
|
||||||
|
Watches(
|
||||||
|
&corev1.Service{},
|
||||||
|
handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request {
|
||||||
|
netResourceList := &nbv1alpha1.NetworkResourceList{}
|
||||||
|
err := r.List(ctx, netResourceList, client.InNamespace(obj.GetNamespace()), client.MatchingFields{".spec.serviceRef": obj.GetName()})
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
requests := make([]reconcile.Request, len(netResourceList.Items))
|
||||||
|
for i, item := range netResourceList.Items {
|
||||||
|
requests[i] = reconcile.Request{
|
||||||
|
NamespacedName: types.NamespacedName{
|
||||||
|
Name: item.Name,
|
||||||
|
Namespace: item.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return requests
|
||||||
|
}),
|
||||||
|
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
|
||||||
|
).
|
||||||
|
Complete(r)
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
|
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
|
"github.com/netbirdio/kubernetes-operator/internal/netbirdmock"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("NetworkResource Controller", func() {
|
||||||
|
Context("When reconciling a resource", func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var netResourceRec *NetworkResourceReconciler
|
||||||
|
var netRouterRec *NetworkRouterReconciler
|
||||||
|
var setupKeyRec *SetupKeyReconciler
|
||||||
|
var groupRec *GroupReconciler
|
||||||
|
|
||||||
|
nn := client.ObjectKey{
|
||||||
|
Name: "test-resource",
|
||||||
|
Namespace: "network-resource",
|
||||||
|
}
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
nbClient := netbirdmock.Client()
|
||||||
|
netResourceRec = &NetworkResourceReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
}
|
||||||
|
netRouterRec = &NetworkRouterReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
ClientImage: "docker.io/netbirdio/netbird:latest",
|
||||||
|
ManagementURL: "https://netbird.io",
|
||||||
|
}
|
||||||
|
setupKeyRec = &SetupKeyReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
}
|
||||||
|
groupRec = &GroupReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := &corev1.Namespace{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, ns)).To(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
ns := &corev1.Namespace{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), ns)
|
||||||
|
if kerrors.IsNotFound(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(k8sClient.Delete(ctx, ns)).To(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("creates a network resource and DNS record", func() {
|
||||||
|
zoneReq := api.ZoneRequest{
|
||||||
|
Name: "cluster.local",
|
||||||
|
Domain: "cluster.local",
|
||||||
|
}
|
||||||
|
_, err := netRouterRec.Netbird.DNSZones.CreateZone(ctx, zoneReq)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// Create network router that we reference.
|
||||||
|
netRouter := &nbv1alpha1.NetworkRouter{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Name,
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
Spec: nbv1alpha1.NetworkRouterSpec{
|
||||||
|
DNSZoneRef: nbv1alpha1.DNSZoneReference{
|
||||||
|
Name: "cluster.local",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, netRouter)).To(Succeed())
|
||||||
|
for range 3 {
|
||||||
|
_, err := netRouterRec.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
key := client.ObjectKey{Name: fmt.Sprintf("networkrouter-%s", netRouter.Name), Namespace: nn.Namespace}
|
||||||
|
_, err = groupRec.Reconcile(ctx, reconcile.Request{NamespacedName: key})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = setupKeyRec.Reconcile(ctx, reconcile.Request{NamespacedName: key})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
svc := &corev1.Service{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test",
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
Spec: corev1.ServiceSpec{
|
||||||
|
Ports: []corev1.ServicePort{
|
||||||
|
{
|
||||||
|
Port: 8080,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, svc)).To(Succeed())
|
||||||
|
|
||||||
|
netResource := &nbv1alpha1.NetworkResource{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Name,
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
Spec: nbv1alpha1.NetworkResourceSpec{
|
||||||
|
NetworkRouterRef: nbv1alpha1.CrossNamespaceReference{
|
||||||
|
Name: netRouter.Name,
|
||||||
|
Namespace: netRouter.Namespace,
|
||||||
|
},
|
||||||
|
ServiceRef: corev1.LocalObjectReference{
|
||||||
|
Name: svc.Name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, netResource)).To(Succeed())
|
||||||
|
_, err = netResourceRec.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = k8sClient.Get(ctx, nn, netResource)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(netResource.Status.NetworkID).NotTo(BeEmpty())
|
||||||
|
Expect(netResource.Status.ResourceID).NotTo(BeEmpty())
|
||||||
|
Expect(netResource.Status.DNSZoneID).NotTo(BeEmpty())
|
||||||
|
Expect(netResource.Status.DNSRecordID).NotTo(BeEmpty())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,322 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"maps"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/fluxcd/pkg/runtime/conditions"
|
||||||
|
"github.com/fluxcd/pkg/runtime/patch"
|
||||||
|
"github.com/netbirdio/kubernetes-operator/internal/netbirdutil"
|
||||||
|
"github.com/netbirdio/kubernetes-operator/internal/ssautil"
|
||||||
|
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
|
appsv1ac "k8s.io/client-go/applyconfigurations/apps/v1"
|
||||||
|
corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
|
||||||
|
metav1ac "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
|
"k8s.io/utils/ptr"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
|
|
||||||
|
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
|
nbv1alpha1ac "github.com/netbirdio/kubernetes-operator/pkg/applyconfigurations/api/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NetworkRouterReconciler struct {
|
||||||
|
client.Client
|
||||||
|
|
||||||
|
Netbird *netbird.Client
|
||||||
|
ManagementURL string
|
||||||
|
ClientImage string
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=networkrouters,verbs=get;list;watch;create;update;patch;delete
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=networkrouters/status,verbs=get;update;patch
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=networkrouters/finalizers,verbs=update
|
||||||
|
|
||||||
|
// nolint:gocyclo
|
||||||
|
func (r *NetworkRouterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||||
|
netRouter := &nbv1alpha1.NetworkRouter{}
|
||||||
|
err := r.Get(ctx, req.NamespacedName, netRouter)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||||
|
}
|
||||||
|
sp := patch.NewSerialPatcher(netRouter, r.Client)
|
||||||
|
|
||||||
|
if !netRouter.DeletionTimestamp.IsZero() {
|
||||||
|
return r.reconcileDelete(ctx, sp, netRouter)
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerRef, err := ssautil.OwnerReference(netRouter, r.Scheme())
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the DNS Zone exists.
|
||||||
|
_, err = netbirdutil.GetDNSZoneByName(ctx, r.Netbird, netRouter.Spec.DNSZoneRef.Name)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerutil.AddFinalizer(netRouter, nbv1alpha1.NetbirdFinalizer)
|
||||||
|
|
||||||
|
networkID, err := func() (string, error) {
|
||||||
|
networkReq := api.NetworkRequest{
|
||||||
|
Name: netRouter.Name,
|
||||||
|
}
|
||||||
|
if netRouter.Status.NetworkID != "" {
|
||||||
|
networkResp, err := r.Netbird.Networks.Update(ctx, netRouter.Status.NetworkID, networkReq)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
return networkResp.Id, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
networkResp, err := r.Netbird.Networks.Create(ctx, networkReq)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return networkResp.Id, nil
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
netRouter.Status.NetworkID = networkID
|
||||||
|
err = sp.Patch(ctx, netRouter)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate unique suffix used for Netbird resources.
|
||||||
|
sum := sha256.Sum256([]byte(netRouter.UID))
|
||||||
|
uniqueSuffix := networkID + "-" + fmt.Sprintf("%x", sum[:4])[:8]
|
||||||
|
|
||||||
|
// Create the group used by the router to discover peers.
|
||||||
|
groupAC := nbv1alpha1ac.Group(fmt.Sprintf("networkrouter-%s", netRouter.Name), req.Namespace).
|
||||||
|
WithOwnerReferences(ownerRef).
|
||||||
|
WithSpec(
|
||||||
|
nbv1alpha1ac.GroupSpec().
|
||||||
|
WithName(fmt.Sprintf("networkrouter-%s", uniqueSuffix)),
|
||||||
|
)
|
||||||
|
err = r.Client.Apply(ctx, groupAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
group := &nbv1alpha1.Group{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: *groupAC.Name,
|
||||||
|
Namespace: *groupAC.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = r.Client.Get(ctx, client.ObjectKeyFromObject(group), group)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
if group.Status.GroupID == "" {
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the setup key used by routing peers.
|
||||||
|
setupKeyAC := nbv1alpha1ac.SetupKey(fmt.Sprintf("networkrouter-%s", netRouter.Name), req.Namespace).
|
||||||
|
WithOwnerReferences(ownerRef).
|
||||||
|
WithSpec(
|
||||||
|
nbv1alpha1ac.SetupKeySpec().
|
||||||
|
WithName(fmt.Sprintf("networkrouter-%s", uniqueSuffix)).
|
||||||
|
WithEphemeral(true).
|
||||||
|
WithAutoGroups(nbv1alpha1ac.ResourceReference().WithID(group.Status.GroupID)),
|
||||||
|
)
|
||||||
|
err = r.Client.Apply(ctx, setupKeyAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
setupKey := nbv1alpha1.SetupKey{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: *setupKeyAC.Name,
|
||||||
|
Namespace: *setupKeyAC.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = r.Get(ctx, client.ObjectKeyFromObject(&setupKey), &setupKey)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
if setupKey.Status.SetupKeyID == "" {
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the routing peer in netbird.
|
||||||
|
routingPeerID, err := func() (string, error) {
|
||||||
|
routerReq := api.NetworkRouterRequest{
|
||||||
|
Enabled: true,
|
||||||
|
Masquerade: true,
|
||||||
|
Metric: 9999,
|
||||||
|
PeerGroups: ptr.To([]string{group.Status.GroupID}),
|
||||||
|
}
|
||||||
|
if netRouter.Status.RoutingPeerID != "" {
|
||||||
|
resp, err := r.Netbird.Networks.Routers(networkID).Update(ctx, netRouter.Status.RoutingPeerID, routerReq)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
return resp.Id, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp, err := r.Netbird.Networks.Routers(networkID).Create(ctx, routerReq)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return resp.Id, nil
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
netRouter.Status.RoutingPeerID = routingPeerID
|
||||||
|
err = sp.Patch(ctx, netRouter, patch.WithStatusObservedGeneration{})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the deployment.
|
||||||
|
selectorLabels := map[string]string{
|
||||||
|
"app.kubernetes.io/name": "networkrouter",
|
||||||
|
"app.kubernetes.io/instance": req.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
podTemplateSpecAC := corev1ac.PodTemplateSpec().
|
||||||
|
WithLabels(selectorLabels).
|
||||||
|
WithSpec(corev1ac.PodSpec().
|
||||||
|
WithContainers(corev1ac.Container().
|
||||||
|
WithName("netbird").
|
||||||
|
WithImage(r.ClientImage).
|
||||||
|
WithEnv(
|
||||||
|
corev1ac.EnvVar().
|
||||||
|
WithName("NB_SETUP_KEY").
|
||||||
|
WithValueFrom(corev1ac.EnvVarSource().
|
||||||
|
WithSecretKeyRef(corev1ac.SecretKeySelector().
|
||||||
|
WithName(setupKey.SecretName()).
|
||||||
|
WithKey(SetupKeySecretKey),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
corev1ac.EnvVar().
|
||||||
|
WithName("NB_MANAGEMENT_URL").
|
||||||
|
WithValue(r.ManagementURL),
|
||||||
|
corev1ac.EnvVar().
|
||||||
|
WithName("NB_LOG_LEVEL").
|
||||||
|
WithValue("info"),
|
||||||
|
).
|
||||||
|
WithStartupProbe(corev1ac.Probe().WithExec(corev1ac.ExecAction().WithCommand("netbird", "status", "--check", "startup"))).
|
||||||
|
WithReadinessProbe(corev1ac.Probe().WithExec(corev1ac.ExecAction().WithCommand("netbird", "status", "--check", "ready"))).
|
||||||
|
WithSecurityContext(corev1ac.SecurityContext().
|
||||||
|
WithCapabilities(corev1ac.Capabilities().
|
||||||
|
WithAdd("NET_ADMIN").
|
||||||
|
WithAdd("SYS_RESOURCE").
|
||||||
|
WithAdd("SYS_ADMIN"),
|
||||||
|
).
|
||||||
|
WithPrivileged(true),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
depLabels := map[string]string{}
|
||||||
|
depAnnotations := map[string]string{}
|
||||||
|
replicas := int32(3)
|
||||||
|
if netRouter.Spec.WorkloadOverride != nil {
|
||||||
|
if netRouter.Spec.WorkloadOverride.Labels != nil {
|
||||||
|
depLabels = netRouter.Spec.WorkloadOverride.Labels
|
||||||
|
}
|
||||||
|
if netRouter.Spec.WorkloadOverride.Annotations != nil {
|
||||||
|
depAnnotations = netRouter.Spec.WorkloadOverride.Annotations
|
||||||
|
}
|
||||||
|
if netRouter.Spec.WorkloadOverride.Replicas != nil {
|
||||||
|
replicas = *netRouter.Spec.WorkloadOverride.Replicas
|
||||||
|
}
|
||||||
|
if netRouter.Spec.WorkloadOverride.PodTemplate != nil {
|
||||||
|
baseJSON, err := json.Marshal(&podTemplateSpecAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
overrideJSON, err := json.Marshal(netRouter.Spec.WorkloadOverride.PodTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
mergedJSON, err := strategicpatch.StrategicMergePatch(baseJSON, overrideJSON, corev1.PodTemplateSpec{})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(mergedJSON, &podTemplateSpecAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maps.Copy(depLabels, selectorLabels)
|
||||||
|
|
||||||
|
depAC := appsv1ac.Deployment(fmt.Sprintf("networkrouter-%s", req.Name), req.Namespace).
|
||||||
|
WithOwnerReferences(ownerRef).
|
||||||
|
WithLabels(depLabels).
|
||||||
|
WithAnnotations(depAnnotations).
|
||||||
|
WithSpec(appsv1ac.DeploymentSpec().WithReplicas(replicas).WithSelector(metav1ac.LabelSelector().WithMatchLabels(selectorLabels)).WithTemplate(podTemplateSpecAC))
|
||||||
|
err = r.Client.Apply(ctx, depAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
dep := &appsv1.Deployment{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: *depAC.Name,
|
||||||
|
Namespace: *depAC.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = r.Client.Get(ctx, client.ObjectKeyFromObject(dep), dep)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
if dep.Status.ReadyReplicas != dep.Status.Replicas {
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
conditions.MarkTrue(netRouter, nbv1alpha1.ReadyCondition, nbv1alpha1.ReconciledReason, "")
|
||||||
|
err = sp.Patch(ctx, netRouter, patch.WithStatusObservedGeneration{})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{RequeueAfter: 15 * time.Minute}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *NetworkRouterReconciler) reconcileDelete(ctx context.Context, sp *patch.SerialPatcher, netRouter *nbv1alpha1.NetworkRouter) (ctrl.Result, error) {
|
||||||
|
if netRouter.Status.RoutingPeerID != "" {
|
||||||
|
err := r.Netbird.Networks.Routers(netRouter.Status.NetworkID).Delete(ctx, netRouter.Status.RoutingPeerID)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if netRouter.Status.NetworkID != "" {
|
||||||
|
err := r.Netbird.Networks.Delete(ctx, netRouter.Status.NetworkID)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerutil.RemoveFinalizer(netRouter, nbv1alpha1.NetbirdFinalizer)
|
||||||
|
err := sp.Patch(ctx, netRouter)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *NetworkRouterReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
|
return ctrl.NewControllerManagedBy(mgr).
|
||||||
|
For(&nbv1alpha1.NetworkRouter{}).
|
||||||
|
Owns(&nbv1alpha1.Group{}).
|
||||||
|
Owns(&nbv1alpha1.SetupKey{}).
|
||||||
|
Owns(&appsv1.Deployment{}).
|
||||||
|
Complete(r)
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo/v2"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||||
|
|
||||||
|
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
|
"github.com/netbirdio/kubernetes-operator/internal/netbirdmock"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("NetworkRouter Controller", func() {
|
||||||
|
Context("When reconciling a resource", func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
var netRouterRec *NetworkRouterReconciler
|
||||||
|
var setupKeyRec *SetupKeyReconciler
|
||||||
|
var groupRec *GroupReconciler
|
||||||
|
|
||||||
|
nn := client.ObjectKey{
|
||||||
|
Name: "test-resource",
|
||||||
|
Namespace: "network-router",
|
||||||
|
}
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
nbClient := netbirdmock.Client()
|
||||||
|
netRouterRec = &NetworkRouterReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
ClientImage: "docker.io/netbirdio/netbird:latest",
|
||||||
|
ManagementURL: "https://netbird.io",
|
||||||
|
}
|
||||||
|
setupKeyRec = &SetupKeyReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
}
|
||||||
|
groupRec = &GroupReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := &corev1.Namespace{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, ns)).To(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
ns := &corev1.Namespace{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(ns), ns)
|
||||||
|
if kerrors.IsNotFound(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(k8sClient.Delete(ctx, ns)).To(Succeed())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("creates a routing peer along with a deployment", func() {
|
||||||
|
zoneReq := api.ZoneRequest{
|
||||||
|
Name: "cluster.local",
|
||||||
|
Domain: "cluster.local",
|
||||||
|
}
|
||||||
|
_, err := netRouterRec.Netbird.DNSZones.CreateZone(ctx, zoneReq)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
netRouter := &nbv1alpha1.NetworkRouter{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Name,
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
Spec: nbv1alpha1.NetworkRouterSpec{
|
||||||
|
DNSZoneRef: nbv1alpha1.DNSZoneReference{
|
||||||
|
Name: "cluster.local",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, netRouter)).To(Succeed())
|
||||||
|
|
||||||
|
group := &nbv1alpha1.Group{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: fmt.Sprintf("networkrouter-%s", netRouter.Name),
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
setupKey := &nbv1alpha1.SetupKey{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: fmt.Sprintf("networkrouter-%s", netRouter.Name),
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dep := &appsv1.Deployment{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: fmt.Sprintf("networkrouter-%s", netRouter.Name),
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for range 3 {
|
||||||
|
_, err := netRouterRec.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = groupRec.Reconcile(ctx, reconcile.Request{NamespacedName: client.ObjectKeyFromObject(group)})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = setupKeyRec.Reconcile(ctx, reconcile.Request{NamespacedName: client.ObjectKeyFromObject(setupKey)})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = k8sClient.Get(ctx, nn, netRouter)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(netRouter.Status.NetworkID).ToNot(BeEmpty())
|
||||||
|
_, err = netRouterRec.Netbird.Networks.Routers(netRouter.Status.NetworkID).Get(ctx, netRouter.Status.RoutingPeerID)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(group), group)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(group.OwnerReferences[0].UID).To(Equal(netRouter.UID))
|
||||||
|
|
||||||
|
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(setupKey), setupKey)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(setupKey.OwnerReferences[0].UID).To(Equal(netRouter.UID))
|
||||||
|
|
||||||
|
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(dep), dep)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(dep.OwnerReferences[0].UID).To(Equal(netRouter.UID))
|
||||||
|
|
||||||
|
routingPeerResp, err := netRouterRec.Netbird.Networks.Routers(netRouter.Status.NetworkID).Get(ctx, netRouter.Status.RoutingPeerID)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect((*routingPeerResp.PeerGroups)[0]).To(Equal(group.Status.GroupID))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -3,7 +3,6 @@ package controller
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fluxcd/pkg/runtime/conditions"
|
"github.com/fluxcd/pkg/runtime/conditions"
|
||||||
@@ -12,7 +11,6 @@ import (
|
|||||||
"github.com/netbirdio/netbird/shared/management/http/api"
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
|
corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
|
||||||
"k8s.io/utils/ptr"
|
"k8s.io/utils/ptr"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
@@ -20,6 +18,7 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
|
|
||||||
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
|
"github.com/netbirdio/kubernetes-operator/internal/netbirdutil"
|
||||||
"github.com/netbirdio/kubernetes-operator/internal/ssautil"
|
"github.com/netbirdio/kubernetes-operator/internal/ssautil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -52,32 +51,9 @@ func (r *SetupKeyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
|
|||||||
return r.reconcileDelete(ctx, sp, setupKey)
|
return r.reconcileDelete(ctx, sp, setupKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get ids for auto groups.
|
autoGroupIDs, err := netbirdutil.GetGroupIDs(ctx, r.Client, r.Netbird, setupKey.Spec.AutoGroups, setupKey.Namespace)
|
||||||
autoGroupIDs := []string{}
|
if err != nil {
|
||||||
for _, ref := range setupKey.Spec.AutoGroups {
|
return ctrl.Result{}, err
|
||||||
switch {
|
|
||||||
case ref.ID != nil:
|
|
||||||
_, err := r.Netbird.Groups.Get(ctx, *ref.ID)
|
|
||||||
if err != nil {
|
|
||||||
return ctrl.Result{}, err
|
|
||||||
}
|
|
||||||
autoGroupIDs = append(autoGroupIDs, *ref.ID)
|
|
||||||
case ref.LocalRef != nil:
|
|
||||||
group := nbv1alpha1.Group{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: ref.LocalRef.Name,
|
|
||||||
Namespace: setupKey.Namespace,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
err = r.Client.Get(ctx, client.ObjectKeyFromObject(&group), &group)
|
|
||||||
if err != nil {
|
|
||||||
return ctrl.Result{}, err
|
|
||||||
}
|
|
||||||
if group.Status.GroupID == "" {
|
|
||||||
return ctrl.Result{}, fmt.Errorf("group %s in auto groups list is not ready", group.Name)
|
|
||||||
}
|
|
||||||
autoGroupIDs = append(autoGroupIDs, group.Status.GroupID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
controllerutil.AddFinalizer(setupKey, nbv1alpha1.NetbirdFinalizer)
|
controllerutil.AddFinalizer(setupKey, nbv1alpha1.NetbirdFinalizer)
|
||||||
@@ -151,7 +127,7 @@ func (r *SetupKeyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
|
|||||||
AutoGroups: autoGroupIDs,
|
AutoGroups: autoGroupIDs,
|
||||||
Ephemeral: ptr.To(setupKey.Spec.Ephemeral),
|
Ephemeral: ptr.To(setupKey.Spec.Ephemeral),
|
||||||
ExpiresIn: expiresIn,
|
ExpiresIn: expiresIn,
|
||||||
Name: req.Name,
|
Name: setupKey.Spec.Name,
|
||||||
Type: "reusable",
|
Type: "reusable",
|
||||||
UsageLimit: 0,
|
UsageLimit: 0,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ var _ = Describe("SetupKey Controller", func() {
|
|||||||
Name: nn.Name,
|
Name: nn.Name,
|
||||||
Namespace: nn.Namespace,
|
Namespace: nn.Namespace,
|
||||||
},
|
},
|
||||||
|
Spec: nbv1alpha1.SetupKeySpec{
|
||||||
|
Name: "test",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
Expect(k8sClient.Create(ctx, setupKey)).To(Succeed())
|
Expect(k8sClient.Create(ctx, setupKey)).To(Succeed())
|
||||||
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
@@ -80,6 +83,9 @@ var _ = Describe("SetupKey Controller", func() {
|
|||||||
Name: nn.Name,
|
Name: nn.Name,
|
||||||
Namespace: nn.Namespace,
|
Namespace: nn.Namespace,
|
||||||
},
|
},
|
||||||
|
Spec: nbv1alpha1.SetupKeySpec{
|
||||||
|
Name: "test",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
Expect(k8sClient.Create(ctx, setupKey)).To(Succeed())
|
Expect(k8sClient.Create(ctx, setupKey)).To(Succeed())
|
||||||
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
|||||||
@@ -31,6 +31,46 @@ func Client() *netbird.Client {
|
|||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
|
addHandler(mux, "networks", func(id string, input api.NetworkRequest, output api.Network) api.Network {
|
||||||
|
output.Id = id
|
||||||
|
output.Name = input.Name
|
||||||
|
output.Description = input.Description
|
||||||
|
return output
|
||||||
|
})
|
||||||
|
addHandler(mux, "networks/{network}/routers", func(id string, input api.NetworkRouterRequest, output api.NetworkRouter) api.NetworkRouter {
|
||||||
|
output.Id = id
|
||||||
|
output.Enabled = input.Enabled
|
||||||
|
output.Masquerade = input.Masquerade
|
||||||
|
output.Metric = input.Metric
|
||||||
|
output.PeerGroups = input.PeerGroups
|
||||||
|
return output
|
||||||
|
})
|
||||||
|
addHandler(mux, "networks/{network}/resources", func(id string, input api.NetworkResourceRequest, output api.NetworkResource) api.NetworkResource {
|
||||||
|
output.Id = id
|
||||||
|
output.Address = input.Address
|
||||||
|
output.Description = input.Description
|
||||||
|
output.Enabled = input.Enabled
|
||||||
|
return output
|
||||||
|
})
|
||||||
|
addHandler(mux, "dns/zones", func(id string, input api.ZoneRequest, output api.Zone) api.Zone {
|
||||||
|
output.Id = id
|
||||||
|
output.Name = input.Name
|
||||||
|
output.Domain = input.Domain
|
||||||
|
output.DistributionGroups = input.DistributionGroups
|
||||||
|
output.EnableSearchDomain = input.EnableSearchDomain
|
||||||
|
if input.Enabled != nil {
|
||||||
|
output.Enabled = *input.Enabled
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
})
|
||||||
|
addHandler(mux, "dns/zones/{zone}/records", func(id string, input api.DNSRecordRequest, output api.DNSRecord) api.DNSRecord {
|
||||||
|
output.Id = id
|
||||||
|
output.Name = input.Name
|
||||||
|
output.Ttl = input.Ttl
|
||||||
|
output.Type = input.Type
|
||||||
|
output.Content = input.Content
|
||||||
|
return output
|
||||||
|
})
|
||||||
|
|
||||||
srv := httptest.NewServer(mux)
|
srv := httptest.NewServer(mux)
|
||||||
return netbird.New(srv.URL, "ABC")
|
return netbird.New(srv.URL, "ABC")
|
||||||
@@ -38,14 +78,33 @@ func Client() *netbird.Client {
|
|||||||
|
|
||||||
func addHandler[T, U any](mux *http.ServeMux, resource string, convertFn func(string, U, T) T) {
|
func addHandler[T, U any](mux *http.ServeMux, resource string, convertFn func(string, U, T) T) {
|
||||||
var itemMx sync.RWMutex
|
var itemMx sync.RWMutex
|
||||||
items := map[string]T{}
|
store := map[string]T{}
|
||||||
|
|
||||||
|
mux.Handle(fmt.Sprintf("GET /api/%s", resource), http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
itemMx.RLock()
|
||||||
|
defer itemMx.RUnlock()
|
||||||
|
|
||||||
|
items := make([]T, 0, len(store))
|
||||||
|
for _, v := range store {
|
||||||
|
items = append(items, v)
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(items)
|
||||||
|
if err != nil {
|
||||||
|
util.WriteErrorResponse("Marshal Error", http.StatusInternalServerError, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = rw.Write(b)
|
||||||
|
if err != nil {
|
||||||
|
util.WriteErrorResponse("Write Error", http.StatusInternalServerError, rw)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}))
|
||||||
mux.Handle(fmt.Sprintf("GET /api/%s/{id}", resource), http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
mux.Handle(fmt.Sprintf("GET /api/%s/{id}", resource), http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
itemMx.RLock()
|
itemMx.RLock()
|
||||||
defer itemMx.RUnlock()
|
defer itemMx.RUnlock()
|
||||||
|
|
||||||
id := req.PathValue("id")
|
id := req.PathValue("id")
|
||||||
respData, ok := items[id]
|
respData, ok := store[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
util.WriteErrorResponse("Not Found", http.StatusNotFound, rw)
|
util.WriteErrorResponse("Not Found", http.StatusNotFound, rw)
|
||||||
return
|
return
|
||||||
@@ -79,7 +138,7 @@ func addHandler[T, U any](mux *http.ServeMux, resource string, convertFn func(st
|
|||||||
id := fmt.Sprintf("id-%d", rand.Int64())
|
id := fmt.Sprintf("id-%d", rand.Int64())
|
||||||
var zero T
|
var zero T
|
||||||
respData := convertFn(id, reqData, zero)
|
respData := convertFn(id, reqData, zero)
|
||||||
items[id] = respData
|
store[id] = respData
|
||||||
b, err = json.Marshal(respData)
|
b, err = json.Marshal(respData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteErrorResponse("Marshal Error", http.StatusInternalServerError, rw)
|
util.WriteErrorResponse("Marshal Error", http.StatusInternalServerError, rw)
|
||||||
@@ -96,7 +155,7 @@ func addHandler[T, U any](mux *http.ServeMux, resource string, convertFn func(st
|
|||||||
defer itemMx.Unlock()
|
defer itemMx.Unlock()
|
||||||
|
|
||||||
id := req.PathValue("id")
|
id := req.PathValue("id")
|
||||||
respData, ok := items[id]
|
respData, ok := store[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
util.WriteErrorResponse("Not Found", http.StatusNotFound, rw)
|
util.WriteErrorResponse("Not Found", http.StatusNotFound, rw)
|
||||||
return
|
return
|
||||||
@@ -114,7 +173,7 @@ func addHandler[T, U any](mux *http.ServeMux, resource string, convertFn func(st
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
respData = convertFn(id, reqData, respData)
|
respData = convertFn(id, reqData, respData)
|
||||||
items[id] = respData
|
store[id] = respData
|
||||||
b, err = json.Marshal(respData)
|
b, err = json.Marshal(respData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.WriteErrorResponse("Marshal Error", http.StatusInternalServerError, rw)
|
util.WriteErrorResponse("Marshal Error", http.StatusInternalServerError, rw)
|
||||||
@@ -131,11 +190,11 @@ func addHandler[T, U any](mux *http.ServeMux, resource string, convertFn func(st
|
|||||||
defer itemMx.Unlock()
|
defer itemMx.Unlock()
|
||||||
|
|
||||||
id := req.PathValue("id")
|
id := req.PathValue("id")
|
||||||
_, ok := items[id]
|
_, ok := store[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
util.WriteErrorResponse("Not Found", http.StatusNotFound, rw)
|
util.WriteErrorResponse("Not Found", http.StatusNotFound, rw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delete(items, id)
|
delete(store, id)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package netbirdutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
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) {
|
||||||
|
groupIDs := []string{}
|
||||||
|
for _, ref := range refs {
|
||||||
|
switch {
|
||||||
|
case ref.ID != nil:
|
||||||
|
_, err := nbClient.Groups.Get(ctx, *ref.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
groupIDs = append(groupIDs, *ref.ID)
|
||||||
|
case ref.LocalRef != nil:
|
||||||
|
group := nbv1alpha1.Group{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: ref.LocalRef.Name,
|
||||||
|
Namespace: namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(&group), &group)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if group.Status.GroupID == "" {
|
||||||
|
return nil, fmt.Errorf("group %s in groups list is not ready", group.Name)
|
||||||
|
}
|
||||||
|
groupIDs = append(groupIDs, group.Status.GroupID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groupIDs, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package netbirdutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetDNSZoneByName(ctx context.Context, nbClient *netbird.Client, name string) (api.Zone, error) {
|
||||||
|
resp, err := nbClient.DNSZones.ListZones(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return api.Zone{}, err
|
||||||
|
}
|
||||||
|
zoneIdx := slices.IndexFunc(resp, func(zone api.Zone) bool {
|
||||||
|
return zone.Name == name
|
||||||
|
})
|
||||||
|
if zoneIdx == -1 {
|
||||||
|
return api.Zone{}, fmt.Errorf("zone with name %s cannot be found", name)
|
||||||
|
}
|
||||||
|
return resp[zoneIdx], nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// CrossNamespaceReferenceApplyConfiguration represents a declarative configuration of the CrossNamespaceReference type for use
|
||||||
|
// with apply.
|
||||||
|
type CrossNamespaceReferenceApplyConfiguration struct {
|
||||||
|
// Name of the referent.
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
// Namespace of the referent.
|
||||||
|
Namespace *string `json:"namespace,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CrossNamespaceReferenceApplyConfiguration constructs a declarative configuration of the CrossNamespaceReference type for use with
|
||||||
|
// apply.
|
||||||
|
func CrossNamespaceReference() *CrossNamespaceReferenceApplyConfiguration {
|
||||||
|
return &CrossNamespaceReferenceApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 *CrossNamespaceReferenceApplyConfiguration) WithName(value string) *CrossNamespaceReferenceApplyConfiguration {
|
||||||
|
b.Name = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNamespace sets the Namespace 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 Namespace field is set to the value of the last call.
|
||||||
|
func (b *CrossNamespaceReferenceApplyConfiguration) WithNamespace(value string) *CrossNamespaceReferenceApplyConfiguration {
|
||||||
|
b.Namespace = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeploymentOverrideApplyConfiguration represents a declarative configuration of the DeploymentOverride type for use
|
||||||
|
// with apply.
|
||||||
|
type DeploymentOverrideApplyConfiguration struct {
|
||||||
|
// Labels that will be added to the deployment.
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
|
// Annotations that will be added to the deployment.
|
||||||
|
Annotations map[string]string `json:"annotations,omitempty"`
|
||||||
|
// Replicas set for the deployment.
|
||||||
|
Replicas *int32 `json:"replicas,omitempty"`
|
||||||
|
// PodTemplate overrides the deployment pod template.
|
||||||
|
PodTemplate *v1.PodTemplateSpec `json:"podTemplate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeploymentOverrideApplyConfiguration constructs a declarative configuration of the DeploymentOverride type for use with
|
||||||
|
// apply.
|
||||||
|
func DeploymentOverride() *DeploymentOverrideApplyConfiguration {
|
||||||
|
return &DeploymentOverrideApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||||
|
// overwriting an existing map entries in Labels field with the same key.
|
||||||
|
func (b *DeploymentOverrideApplyConfiguration) WithLabels(entries map[string]string) *DeploymentOverrideApplyConfiguration {
|
||||||
|
if b.Labels == nil && len(entries) > 0 {
|
||||||
|
b.Labels = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.Labels[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||||
|
// overwriting an existing map entries in Annotations field with the same key.
|
||||||
|
func (b *DeploymentOverrideApplyConfiguration) WithAnnotations(entries map[string]string) *DeploymentOverrideApplyConfiguration {
|
||||||
|
if b.Annotations == nil && len(entries) > 0 {
|
||||||
|
b.Annotations = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.Annotations[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithReplicas sets the Replicas 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 Replicas field is set to the value of the last call.
|
||||||
|
func (b *DeploymentOverrideApplyConfiguration) WithReplicas(value int32) *DeploymentOverrideApplyConfiguration {
|
||||||
|
b.Replicas = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPodTemplate sets the PodTemplate 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 PodTemplate field is set to the value of the last call.
|
||||||
|
func (b *DeploymentOverrideApplyConfiguration) WithPodTemplate(value v1.PodTemplateSpec) *DeploymentOverrideApplyConfiguration {
|
||||||
|
b.PodTemplate = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// DNSZoneReferenceApplyConfiguration represents a declarative configuration of the DNSZoneReference type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// DNSZoneReference references a Netbird DNS zone by domain name.
|
||||||
|
type DNSZoneReferenceApplyConfiguration struct {
|
||||||
|
// Name is the domain name of an existing Netbird DNS zone, e.g. "example.com".
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DNSZoneReferenceApplyConfiguration constructs a declarative configuration of the DNSZoneReference type for use with
|
||||||
|
// apply.
|
||||||
|
func DNSZoneReference() *DNSZoneReferenceApplyConfiguration {
|
||||||
|
return &DNSZoneReferenceApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 *DNSZoneReferenceApplyConfiguration) WithName(value string) *DNSZoneReferenceApplyConfiguration {
|
||||||
|
b.Name = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
|
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkResourceApplyConfiguration represents a declarative configuration of the NetworkResource type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// NetworkResource is the Schema for the networkresources API.
|
||||||
|
type NetworkResourceApplyConfiguration struct {
|
||||||
|
v1.TypeMetaApplyConfiguration `json:",inline"`
|
||||||
|
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||||
|
Spec *NetworkResourceSpecApplyConfiguration `json:"spec,omitempty"`
|
||||||
|
Status *NetworkResourceStatusApplyConfiguration `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkResource constructs a declarative configuration of the NetworkResource type for use with
|
||||||
|
// apply.
|
||||||
|
func NetworkResource(name, namespace string) *NetworkResourceApplyConfiguration {
|
||||||
|
b := &NetworkResourceApplyConfiguration{}
|
||||||
|
b.WithName(name)
|
||||||
|
b.WithNamespace(namespace)
|
||||||
|
b.WithKind("NetworkResource")
|
||||||
|
b.WithAPIVersion("netbird.io/v1alpha1")
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b NetworkResourceApplyConfiguration) IsApplyConfiguration() {}
|
||||||
|
|
||||||
|
// WithKind sets the Kind 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 Kind field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithKind(value string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.TypeMetaApplyConfiguration.Kind = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAPIVersion sets the APIVersion 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 APIVersion field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithAPIVersion(value string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.TypeMetaApplyConfiguration.APIVersion = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 *NetworkResourceApplyConfiguration) WithName(value string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.Name = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithGenerateName sets the GenerateName 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 GenerateName field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithGenerateName(value string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.GenerateName = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNamespace sets the Namespace 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 Namespace field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithNamespace(value string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.Namespace = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUID sets the UID 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 UID field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithUID(value types.UID) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.UID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithResourceVersion sets the ResourceVersion 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 ResourceVersion field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithResourceVersion(value string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.ResourceVersion = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithGeneration sets the Generation 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 Generation field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithGeneration(value int64) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.Generation = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCreationTimestamp sets the CreationTimestamp 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 CreationTimestamp field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithCreationTimestamp(value metav1.Time) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDeletionTimestamp sets the DeletionTimestamp 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 DeletionTimestamp field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds 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 DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||||
|
// overwriting an existing map entries in Labels field with the same key.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithLabels(entries map[string]string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
|
||||||
|
b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.ObjectMetaApplyConfiguration.Labels[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||||
|
// overwriting an existing map entries in Annotations field with the same key.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithAnnotations(entries map[string]string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
|
||||||
|
b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.ObjectMetaApplyConfiguration.Annotations[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithOwnerReferences adds the given value to the OwnerReferences 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 OwnerReferences field.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
for i := range values {
|
||||||
|
if values[i] == nil {
|
||||||
|
panic("nil value passed to WithOwnerReferences")
|
||||||
|
}
|
||||||
|
b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithFinalizers adds the given value to the Finalizers 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 Finalizers field.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithFinalizers(values ...string) *NetworkResourceApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
for i := range values {
|
||||||
|
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *NetworkResourceApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||||
|
if b.ObjectMetaApplyConfiguration == nil {
|
||||||
|
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSpec sets the Spec 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 Spec field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithSpec(value *NetworkResourceSpecApplyConfiguration) *NetworkResourceApplyConfiguration {
|
||||||
|
b.Spec = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStatus sets the Status 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 Status field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) WithStatus(value *NetworkResourceStatusApplyConfiguration) *NetworkResourceApplyConfiguration {
|
||||||
|
b.Status = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKind retrieves the value of the Kind field in the declarative configuration.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) GetKind() *string {
|
||||||
|
return b.TypeMetaApplyConfiguration.Kind
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) GetAPIVersion() *string {
|
||||||
|
return b.TypeMetaApplyConfiguration.APIVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) GetName() *string {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
return b.ObjectMetaApplyConfiguration.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
|
||||||
|
func (b *NetworkResourceApplyConfiguration) GetNamespace() *string {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
return b.ObjectMetaApplyConfiguration.Namespace
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkResourceSpecApplyConfiguration represents a declarative configuration of the NetworkResourceSpec type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// NetworkResourceSpec defines the desired state of NetworkResource.
|
||||||
|
type NetworkResourceSpecApplyConfiguration struct {
|
||||||
|
// NetworkRouterRef is a reference to the network and router where the resource will be created.
|
||||||
|
NetworkRouterRef *CrossNamespaceReferenceApplyConfiguration `json:"networkRouterRef,omitempty"`
|
||||||
|
// 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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkResourceSpecApplyConfiguration constructs a declarative configuration of the NetworkResourceSpec type for use with
|
||||||
|
// apply.
|
||||||
|
func NetworkResourceSpec() *NetworkResourceSpecApplyConfiguration {
|
||||||
|
return &NetworkResourceSpecApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNetworkRouterRef sets the NetworkRouterRef 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 NetworkRouterRef field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceSpecApplyConfiguration) WithNetworkRouterRef(value *CrossNamespaceReferenceApplyConfiguration) *NetworkResourceSpecApplyConfiguration {
|
||||||
|
b.NetworkRouterRef = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithServiceRef sets the ServiceRef 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 ServiceRef field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceSpecApplyConfiguration) WithServiceRef(value v1.LocalObjectReference) *NetworkResourceSpecApplyConfiguration {
|
||||||
|
b.ServiceRef = &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 *NetworkResourceSpecApplyConfiguration) WithGroups(values ...*ResourceReferenceApplyConfiguration) *NetworkResourceSpecApplyConfiguration {
|
||||||
|
for i := range values {
|
||||||
|
if values[i] == nil {
|
||||||
|
panic("nil value passed to WithGroups")
|
||||||
|
}
|
||||||
|
b.Groups = append(b.Groups, *values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkResourceStatusApplyConfiguration represents a declarative configuration of the NetworkResourceStatus type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// NetworkResourceStatus defines the observed state of NetworkResource.
|
||||||
|
type NetworkResourceStatusApplyConfiguration struct {
|
||||||
|
// ObservedGeneration is the last reconciled generation.
|
||||||
|
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
|
||||||
|
// Conditions holds the conditions for the NetworkResource.
|
||||||
|
Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
|
||||||
|
// NetworkID is the id of the network the resource is created in.
|
||||||
|
NetworkID *string `json:"networkID,omitempty"`
|
||||||
|
// ResourceID is the id of the created resource.
|
||||||
|
ResourceID *string `json:"resourceID,omitempty"`
|
||||||
|
// DNSZoneID is the id of the zone the DNS record is created in.
|
||||||
|
DNSZoneID *string `json:"dnsZoneID,omitempty"`
|
||||||
|
// DNSRecordID is the id of the created DNS record.
|
||||||
|
DNSRecordID *string `json:"dnsRecordID,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkResourceStatusApplyConfiguration constructs a declarative configuration of the NetworkResourceStatus type for use with
|
||||||
|
// apply.
|
||||||
|
func NetworkResourceStatus() *NetworkResourceStatusApplyConfiguration {
|
||||||
|
return &NetworkResourceStatusApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithObservedGeneration sets the ObservedGeneration 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 ObservedGeneration field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceStatusApplyConfiguration) WithObservedGeneration(value int64) *NetworkResourceStatusApplyConfiguration {
|
||||||
|
b.ObservedGeneration = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithConditions adds the given value to the Conditions 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 Conditions field.
|
||||||
|
func (b *NetworkResourceStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *NetworkResourceStatusApplyConfiguration {
|
||||||
|
for i := range values {
|
||||||
|
if values[i] == nil {
|
||||||
|
panic("nil value passed to WithConditions")
|
||||||
|
}
|
||||||
|
b.Conditions = append(b.Conditions, *values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNetworkID sets the NetworkID 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 NetworkID field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceStatusApplyConfiguration) WithNetworkID(value string) *NetworkResourceStatusApplyConfiguration {
|
||||||
|
b.NetworkID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithResourceID sets the ResourceID 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 ResourceID field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceStatusApplyConfiguration) WithResourceID(value string) *NetworkResourceStatusApplyConfiguration {
|
||||||
|
b.ResourceID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDNSZoneID sets the DNSZoneID 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 DNSZoneID field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceStatusApplyConfiguration) WithDNSZoneID(value string) *NetworkResourceStatusApplyConfiguration {
|
||||||
|
b.DNSZoneID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDNSRecordID sets the DNSRecordID 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 DNSRecordID field is set to the value of the last call.
|
||||||
|
func (b *NetworkResourceStatusApplyConfiguration) WithDNSRecordID(value string) *NetworkResourceStatusApplyConfiguration {
|
||||||
|
b.DNSRecordID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
types "k8s.io/apimachinery/pkg/types"
|
||||||
|
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkRouterApplyConfiguration represents a declarative configuration of the NetworkRouter type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// NetworkRouter is the Schema for the networkrouters API.
|
||||||
|
type NetworkRouterApplyConfiguration struct {
|
||||||
|
v1.TypeMetaApplyConfiguration `json:",inline"`
|
||||||
|
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||||
|
Spec *NetworkRouterSpecApplyConfiguration `json:"spec,omitempty"`
|
||||||
|
Status *NetworkRouterStatusApplyConfiguration `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkRouter constructs a declarative configuration of the NetworkRouter type for use with
|
||||||
|
// apply.
|
||||||
|
func NetworkRouter(name, namespace string) *NetworkRouterApplyConfiguration {
|
||||||
|
b := &NetworkRouterApplyConfiguration{}
|
||||||
|
b.WithName(name)
|
||||||
|
b.WithNamespace(namespace)
|
||||||
|
b.WithKind("NetworkRouter")
|
||||||
|
b.WithAPIVersion("netbird.io/v1alpha1")
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b NetworkRouterApplyConfiguration) IsApplyConfiguration() {}
|
||||||
|
|
||||||
|
// WithKind sets the Kind 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 Kind field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithKind(value string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.TypeMetaApplyConfiguration.Kind = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAPIVersion sets the APIVersion 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 APIVersion field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithAPIVersion(value string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.TypeMetaApplyConfiguration.APIVersion = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 *NetworkRouterApplyConfiguration) WithName(value string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.Name = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithGenerateName sets the GenerateName 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 GenerateName field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithGenerateName(value string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.GenerateName = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNamespace sets the Namespace 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 Namespace field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithNamespace(value string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.Namespace = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUID sets the UID 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 UID field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithUID(value types.UID) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.UID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithResourceVersion sets the ResourceVersion 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 ResourceVersion field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithResourceVersion(value string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.ResourceVersion = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithGeneration sets the Generation 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 Generation field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithGeneration(value int64) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.Generation = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCreationTimestamp sets the CreationTimestamp 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 CreationTimestamp field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithCreationTimestamp(value metav1.Time) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDeletionTimestamp sets the DeletionTimestamp 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 DeletionTimestamp field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds 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 DeletionGracePeriodSeconds field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||||
|
// overwriting an existing map entries in Labels field with the same key.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithLabels(entries map[string]string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
|
||||||
|
b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.ObjectMetaApplyConfiguration.Labels[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||||
|
// overwriting an existing map entries in Annotations field with the same key.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithAnnotations(entries map[string]string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
|
||||||
|
b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.ObjectMetaApplyConfiguration.Annotations[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithOwnerReferences adds the given value to the OwnerReferences 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 OwnerReferences field.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
for i := range values {
|
||||||
|
if values[i] == nil {
|
||||||
|
panic("nil value passed to WithOwnerReferences")
|
||||||
|
}
|
||||||
|
b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithFinalizers adds the given value to the Finalizers 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 Finalizers field.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithFinalizers(values ...string) *NetworkRouterApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
for i := range values {
|
||||||
|
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *NetworkRouterApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
|
||||||
|
if b.ObjectMetaApplyConfiguration == nil {
|
||||||
|
b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSpec sets the Spec 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 Spec field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithSpec(value *NetworkRouterSpecApplyConfiguration) *NetworkRouterApplyConfiguration {
|
||||||
|
b.Spec = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithStatus sets the Status 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 Status field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) WithStatus(value *NetworkRouterStatusApplyConfiguration) *NetworkRouterApplyConfiguration {
|
||||||
|
b.Status = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKind retrieves the value of the Kind field in the declarative configuration.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) GetKind() *string {
|
||||||
|
return b.TypeMetaApplyConfiguration.Kind
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) GetAPIVersion() *string {
|
||||||
|
return b.TypeMetaApplyConfiguration.APIVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) GetName() *string {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
return b.ObjectMetaApplyConfiguration.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
|
||||||
|
func (b *NetworkRouterApplyConfiguration) GetNamespace() *string {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
return b.ObjectMetaApplyConfiguration.Namespace
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
// NetworkRouterSpecApplyConfiguration represents a declarative configuration of the NetworkRouterSpec type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// NetworkRouterSpec defines the desired state of NetworkRouter.
|
||||||
|
type NetworkRouterSpecApplyConfiguration struct {
|
||||||
|
// DNSZoneRef is a reference to the DNS zone used to create records for resources.
|
||||||
|
DNSZoneRef *DNSZoneReferenceApplyConfiguration `json:"dnsZoneRef,omitempty"`
|
||||||
|
// WorkloadOverride contains configuration that will override the default workload.
|
||||||
|
WorkloadOverride *WorkloadOverrideApplyConfiguration `json:"workloadOverride,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkRouterSpecApplyConfiguration constructs a declarative configuration of the NetworkRouterSpec type for use with
|
||||||
|
// apply.
|
||||||
|
func NetworkRouterSpec() *NetworkRouterSpecApplyConfiguration {
|
||||||
|
return &NetworkRouterSpecApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDNSZoneRef sets the DNSZoneRef 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 DNSZoneRef field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterSpecApplyConfiguration) WithDNSZoneRef(value *DNSZoneReferenceApplyConfiguration) *NetworkRouterSpecApplyConfiguration {
|
||||||
|
b.DNSZoneRef = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithWorkloadOverride sets the WorkloadOverride 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 WorkloadOverride field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterSpecApplyConfiguration) WithWorkloadOverride(value *WorkloadOverrideApplyConfiguration) *NetworkRouterSpecApplyConfiguration {
|
||||||
|
b.WorkloadOverride = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NetworkRouterStatusApplyConfiguration represents a declarative configuration of the NetworkRouterStatus type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// NetworkRouterStatus defines the observed state of NetworkRouter.
|
||||||
|
type NetworkRouterStatusApplyConfiguration struct {
|
||||||
|
// ObservedGeneration is the last reconciled generation.
|
||||||
|
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
|
||||||
|
// Conditions holds the conditions for the NetworkRouter.
|
||||||
|
Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
|
||||||
|
// RoutingPeerID is the id of the created routing peer.
|
||||||
|
RoutingPeerID *string `json:"routingPeerID,omitempty"`
|
||||||
|
// NetworkID is the id of the network the routing peer was created in.
|
||||||
|
NetworkID *string `json:"networkID,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NetworkRouterStatusApplyConfiguration constructs a declarative configuration of the NetworkRouterStatus type for use with
|
||||||
|
// apply.
|
||||||
|
func NetworkRouterStatus() *NetworkRouterStatusApplyConfiguration {
|
||||||
|
return &NetworkRouterStatusApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithObservedGeneration sets the ObservedGeneration 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 ObservedGeneration field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterStatusApplyConfiguration) WithObservedGeneration(value int64) *NetworkRouterStatusApplyConfiguration {
|
||||||
|
b.ObservedGeneration = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithConditions adds the given value to the Conditions 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 Conditions field.
|
||||||
|
func (b *NetworkRouterStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *NetworkRouterStatusApplyConfiguration {
|
||||||
|
for i := range values {
|
||||||
|
if values[i] == nil {
|
||||||
|
panic("nil value passed to WithConditions")
|
||||||
|
}
|
||||||
|
b.Conditions = append(b.Conditions, *values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRoutingPeerID sets the RoutingPeerID 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 RoutingPeerID field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterStatusApplyConfiguration) WithRoutingPeerID(value string) *NetworkRouterStatusApplyConfiguration {
|
||||||
|
b.RoutingPeerID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNetworkID sets the NetworkID 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 NetworkID field is set to the value of the last call.
|
||||||
|
func (b *NetworkRouterStatusApplyConfiguration) WithNetworkID(value string) *NetworkRouterStatusApplyConfiguration {
|
||||||
|
b.NetworkID = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
// ResourceReferenceApplyConfiguration represents a declarative configuration of the ResourceReference type for use
|
// ResourceReferenceApplyConfiguration represents a declarative configuration of the ResourceReference type for use
|
||||||
// with apply.
|
// with apply.
|
||||||
type ResourceReferenceApplyConfiguration struct {
|
type ResourceReferenceApplyConfiguration struct {
|
||||||
// id of the resource in the Netbird API.
|
// ID is the id of a resource in the Netbird API.
|
||||||
ID *string `json:"id,omitempty"`
|
ID *string `json:"id,omitempty"`
|
||||||
// local reference to the object in the same namespace.
|
// LocalReference is a reference to a object in the same namespace.
|
||||||
LocalRef *v1.LocalObjectReference `json:"localRef,omitempty"`
|
LocalRef *v1.LocalObjectReference `json:"localRef,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import (
|
|||||||
//
|
//
|
||||||
// SetupKeySpec defines the desired state of SetupKey.
|
// SetupKeySpec defines the desired state of SetupKey.
|
||||||
type SetupKeySpecApplyConfiguration struct {
|
type SetupKeySpecApplyConfiguration struct {
|
||||||
|
// Name of the setup key.
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
// Ephemeral decides if peers added with the key are ephemeral or not.
|
// Ephemeral decides if peers added with the key are ephemeral or not.
|
||||||
Ephemeral *bool `json:"ephemeral,omitempty"`
|
Ephemeral *bool `json:"ephemeral,omitempty"`
|
||||||
// Duration sets how long the setup key is valid for.
|
// Duration sets how long the setup key is valid for.
|
||||||
@@ -25,6 +27,14 @@ func SetupKeySpec() *SetupKeySpecApplyConfiguration {
|
|||||||
return &SetupKeySpecApplyConfiguration{}
|
return &SetupKeySpecApplyConfiguration{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 *SetupKeySpecApplyConfiguration) WithName(value string) *SetupKeySpecApplyConfiguration {
|
||||||
|
b.Name = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
// WithEphemeral sets the Ephemeral field in the declarative configuration to the given value
|
// WithEphemeral sets the Ephemeral field in the declarative configuration to the given value
|
||||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||||
// If called multiple times, the Ephemeral field is set to the value of the last call.
|
// If called multiple times, the Ephemeral field is set to the value of the last call.
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WorkloadOverrideApplyConfiguration represents a declarative configuration of the WorkloadOverride type for use
|
||||||
|
// with apply.
|
||||||
|
type WorkloadOverrideApplyConfiguration struct {
|
||||||
|
// Labels that will be added.
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
|
// Annotations that will be added.
|
||||||
|
Annotations map[string]string `json:"annotations,omitempty"`
|
||||||
|
// Replicas sets the amount of client replicas.
|
||||||
|
Replicas *int32 `json:"replicas,omitempty"`
|
||||||
|
// PodTemplate overrides the pod template.
|
||||||
|
PodTemplate *v1.PodTemplateSpec `json:"podTemplate,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// WorkloadOverrideApplyConfiguration constructs a declarative configuration of the WorkloadOverride type for use with
|
||||||
|
// apply.
|
||||||
|
func WorkloadOverride() *WorkloadOverrideApplyConfiguration {
|
||||||
|
return &WorkloadOverrideApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLabels puts the entries into the Labels field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Labels field,
|
||||||
|
// overwriting an existing map entries in Labels field with the same key.
|
||||||
|
func (b *WorkloadOverrideApplyConfiguration) WithLabels(entries map[string]string) *WorkloadOverrideApplyConfiguration {
|
||||||
|
if b.Labels == nil && len(entries) > 0 {
|
||||||
|
b.Labels = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.Labels[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAnnotations puts the entries into the Annotations field in the declarative configuration
|
||||||
|
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||||
|
// If called multiple times, the entries provided by each call will be put on the Annotations field,
|
||||||
|
// overwriting an existing map entries in Annotations field with the same key.
|
||||||
|
func (b *WorkloadOverrideApplyConfiguration) WithAnnotations(entries map[string]string) *WorkloadOverrideApplyConfiguration {
|
||||||
|
if b.Annotations == nil && len(entries) > 0 {
|
||||||
|
b.Annotations = make(map[string]string, len(entries))
|
||||||
|
}
|
||||||
|
for k, v := range entries {
|
||||||
|
b.Annotations[k] = v
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithReplicas sets the Replicas 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 Replicas field is set to the value of the last call.
|
||||||
|
func (b *WorkloadOverrideApplyConfiguration) WithReplicas(value int32) *WorkloadOverrideApplyConfiguration {
|
||||||
|
b.Replicas = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithPodTemplate sets the PodTemplate 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 PodTemplate field is set to the value of the last call.
|
||||||
|
func (b *WorkloadOverrideApplyConfiguration) WithPodTemplate(value v1.PodTemplateSpec) *WorkloadOverrideApplyConfiguration {
|
||||||
|
b.PodTemplate = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -16,12 +16,28 @@ import (
|
|||||||
func ForKind(kind schema.GroupVersionKind) interface{} {
|
func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||||
switch kind {
|
switch kind {
|
||||||
// Group=netbird.io, Version=v1alpha1
|
// Group=netbird.io, Version=v1alpha1
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("CrossNamespaceReference"):
|
||||||
|
return &apiv1alpha1.CrossNamespaceReferenceApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("DNSZoneReference"):
|
||||||
|
return &apiv1alpha1.DNSZoneReferenceApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("Group"):
|
case v1alpha1.SchemeGroupVersion.WithKind("Group"):
|
||||||
return &apiv1alpha1.GroupApplyConfiguration{}
|
return &apiv1alpha1.GroupApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("GroupSpec"):
|
case v1alpha1.SchemeGroupVersion.WithKind("GroupSpec"):
|
||||||
return &apiv1alpha1.GroupSpecApplyConfiguration{}
|
return &apiv1alpha1.GroupSpecApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("GroupStatus"):
|
case v1alpha1.SchemeGroupVersion.WithKind("GroupStatus"):
|
||||||
return &apiv1alpha1.GroupStatusApplyConfiguration{}
|
return &apiv1alpha1.GroupStatusApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("NetworkResource"):
|
||||||
|
return &apiv1alpha1.NetworkResourceApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("NetworkResourceSpec"):
|
||||||
|
return &apiv1alpha1.NetworkResourceSpecApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("NetworkResourceStatus"):
|
||||||
|
return &apiv1alpha1.NetworkResourceStatusApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("NetworkRouter"):
|
||||||
|
return &apiv1alpha1.NetworkRouterApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("NetworkRouterSpec"):
|
||||||
|
return &apiv1alpha1.NetworkRouterSpecApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("NetworkRouterStatus"):
|
||||||
|
return &apiv1alpha1.NetworkRouterStatusApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("ResourceReference"):
|
case v1alpha1.SchemeGroupVersion.WithKind("ResourceReference"):
|
||||||
return &apiv1alpha1.ResourceReferenceApplyConfiguration{}
|
return &apiv1alpha1.ResourceReferenceApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("SetupKey"):
|
case v1alpha1.SchemeGroupVersion.WithKind("SetupKey"):
|
||||||
@@ -30,6 +46,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
|
|||||||
return &apiv1alpha1.SetupKeySpecApplyConfiguration{}
|
return &apiv1alpha1.SetupKeySpecApplyConfiguration{}
|
||||||
case v1alpha1.SchemeGroupVersion.WithKind("SetupKeyStatus"):
|
case v1alpha1.SchemeGroupVersion.WithKind("SetupKeyStatus"):
|
||||||
return &apiv1alpha1.SetupKeyStatusApplyConfiguration{}
|
return &apiv1alpha1.SetupKeyStatusApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("WorkloadOverride"):
|
||||||
|
return &apiv1alpha1.WorkloadOverrideApplyConfiguration{}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user