mirror of
https://github.com/YuzuZensai/netbird-kubernetes-operator.git
synced 2026-09-13 10:49:15 +00:00
Implement new setup key resource (#178)
This change implements a new resource called SetupKey that manages the lifecycle of setup keys and stores them in secrets. A major change here is that we are also switching to using SSA for resource management. Part of #172 Signed-off-by: Philip Laine <philip.laine@gmail.com>
This commit is contained in:
@@ -17,6 +17,7 @@ RUN go mod download
|
|||||||
COPY cmd/main.go cmd/main.go
|
COPY cmd/main.go cmd/main.go
|
||||||
COPY api/ api/
|
COPY api/ api/
|
||||||
COPY internal/ internal/
|
COPY internal/ internal/
|
||||||
|
COPY pkg/ pkg/
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
# the GOARCH has not a default value to allow the binary be built according to the host where the command
|
# the GOARCH has not a default value to allow the binary be built according to the host where the command
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ manifests: ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefin
|
|||||||
|
|
||||||
.PHONY: generate
|
.PHONY: generate
|
||||||
generate: ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
|
generate: ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations.
|
||||||
go tool controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
|
go tool controller-gen applyconfiguration:headerFile="hack/boilerplate.go.txt" object:headerFile="hack/boilerplate.go.txt" paths="./..."
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt: ## Run go fmt against code.
|
fmt: ## Run go fmt against code.
|
||||||
|
|||||||
@@ -75,4 +75,12 @@ resources:
|
|||||||
kind: NBPolicy
|
kind: NBPolicy
|
||||||
path: github.com/netbirdio/kubernetes-operator/api/v1
|
path: github.com/netbirdio/kubernetes-operator/api/v1
|
||||||
version: v1
|
version: v1
|
||||||
|
- api:
|
||||||
|
crdVersion: v1
|
||||||
|
namespaced: true
|
||||||
|
controller: true
|
||||||
|
domain: netbird.io
|
||||||
|
kind: SetupKey
|
||||||
|
path: github.com/netbirdio/kubernetes-operator/api/v1alpha1
|
||||||
|
version: v1alpha1
|
||||||
version: "3"
|
version: "3"
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Package v1alpha1 contains API Schema definitions for the v1alpha1 API group.
|
||||||
|
// +kubebuilder:object:generate=true
|
||||||
|
// +groupName=netbird.io
|
||||||
|
// +kubebuilder:ac:generate=true
|
||||||
|
// +kubebuilder:ac:output:package=../../pkg/applyconfigurations
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// GroupVersion is group version used to register these objects.
|
||||||
|
GroupVersion = schema.GroupVersion{Group: "netbird.io", Version: "v1alpha1"}
|
||||||
|
SchemeGroupVersion = GroupVersion
|
||||||
|
|
||||||
|
// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
|
||||||
|
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||||
|
|
||||||
|
// AddToScheme adds the types in this group-version to the given scheme.
|
||||||
|
AddToScheme = SchemeBuilder.AddToScheme
|
||||||
|
)
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetupKeySpec defines the desired state of SetupKey
|
||||||
|
type SetupKeySpec struct {
|
||||||
|
// Ephemeral decides if peers added with the key are ephemeral or not.
|
||||||
|
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="ephemeral is immutable"
|
||||||
|
Ephemeral bool `json:"ephemeral"`
|
||||||
|
|
||||||
|
// Duration sets how long the setup key is valid for.
|
||||||
|
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="duration is immutable"
|
||||||
|
// +optional
|
||||||
|
Duration *metav1.Duration `json:"duration,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupKeyStatus defines the observed state of SetupKey.
|
||||||
|
type SetupKeyStatus struct {
|
||||||
|
// SetupKeyID of the setup key.
|
||||||
|
SetupKeyID *string `json:"setupKeyID,omitempty"`
|
||||||
|
|
||||||
|
// The status of each condition is one of True, False, or Unknown.
|
||||||
|
// +listType=map
|
||||||
|
// +listMapKey=type
|
||||||
|
// +optional
|
||||||
|
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
// +kubebuilder:subresource:status
|
||||||
|
// +kubebuilder:resource
|
||||||
|
|
||||||
|
// SetupKey is the Schema for the setupkeys API
|
||||||
|
type SetupKey struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
|
// metadata is a standard object metadata
|
||||||
|
// +optional
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitzero"`
|
||||||
|
|
||||||
|
// spec defines the desired state of SetupKey
|
||||||
|
// +required
|
||||||
|
Spec SetupKeySpec `json:"spec"`
|
||||||
|
|
||||||
|
// status defines the observed state of SetupKey
|
||||||
|
// +optional
|
||||||
|
Status SetupKeyStatus `json:"status,omitzero"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sk SetupKey) SecretName() string {
|
||||||
|
return "setup-key-" + sk.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
|
||||||
|
// SetupKeyList contains a list of SetupKey
|
||||||
|
type SetupKeyList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ListMeta `json:"metadata,omitzero"`
|
||||||
|
Items []SetupKey `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
SchemeBuilder.Register(&SetupKey{}, &SetupKeyList{})
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
//go:build !ignore_autogenerated
|
||||||
|
|
||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
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 *SetupKey) DeepCopyInto(out *SetupKey) {
|
||||||
|
*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 SetupKey.
|
||||||
|
func (in *SetupKey) DeepCopy() *SetupKey {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(SetupKey)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *SetupKey) 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 *SetupKeyList) DeepCopyInto(out *SetupKeyList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]SetupKey, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SetupKeyList.
|
||||||
|
func (in *SetupKeyList) DeepCopy() *SetupKeyList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(SetupKeyList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *SetupKeyList) 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 *SetupKeySpec) DeepCopyInto(out *SetupKeySpec) {
|
||||||
|
*out = *in
|
||||||
|
if in.Duration != nil {
|
||||||
|
in, out := &in.Duration, &out.Duration
|
||||||
|
*out = new(v1.Duration)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SetupKeySpec.
|
||||||
|
func (in *SetupKeySpec) DeepCopy() *SetupKeySpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(SetupKeySpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *SetupKeyStatus) DeepCopyInto(out *SetupKeyStatus) {
|
||||||
|
*out = *in
|
||||||
|
if in.SetupKeyID != nil {
|
||||||
|
in, out := &in.SetupKeyID, &out.SetupKeyID
|
||||||
|
*out = new(string)
|
||||||
|
**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 SetupKeyStatus.
|
||||||
|
func (in *SetupKeyStatus) DeepCopy() *SetupKeyStatus {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(SetupKeyStatus)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
+13
@@ -36,6 +36,7 @@ import (
|
|||||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
|
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
"sigs.k8s.io/controller-runtime/pkg/healthz"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||||
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
||||||
@@ -44,6 +45,7 @@ import (
|
|||||||
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||||
|
|
||||||
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
||||||
|
netbirdiov1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
"github.com/netbirdio/kubernetes-operator/internal/controller"
|
"github.com/netbirdio/kubernetes-operator/internal/controller"
|
||||||
webhooknetbirdiov1 "github.com/netbirdio/kubernetes-operator/internal/webhook/v1"
|
webhooknetbirdiov1 "github.com/netbirdio/kubernetes-operator/internal/webhook/v1"
|
||||||
// +kubebuilder:scaffold:imports
|
// +kubebuilder:scaffold:imports
|
||||||
@@ -61,6 +63,7 @@ func init() {
|
|||||||
utilruntime.Must(corev1.AddToScheme(scheme))
|
utilruntime.Must(corev1.AddToScheme(scheme))
|
||||||
utilruntime.Must(gatewayv1.Install(scheme))
|
utilruntime.Must(gatewayv1.Install(scheme))
|
||||||
utilruntime.Must(gatewayv1alpha2.Install(scheme))
|
utilruntime.Must(gatewayv1alpha2.Install(scheme))
|
||||||
|
utilruntime.Must(netbirdiov1alpha1.AddToScheme(scheme))
|
||||||
// +kubebuilder:scaffold:scheme
|
// +kubebuilder:scaffold:scheme
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +192,9 @@ func main() {
|
|||||||
Metrics: metricsserver.Options{
|
Metrics: metricsserver.Options{
|
||||||
BindAddress: metricsAddr,
|
BindAddress: metricsAddr,
|
||||||
},
|
},
|
||||||
|
Client: client.Options{
|
||||||
|
FieldOwner: "netbird-operator",
|
||||||
|
},
|
||||||
WebhookServer: webhookServer,
|
WebhookServer: webhookServer,
|
||||||
HealthProbeBindAddress: probeAddr,
|
HealthProbeBindAddress: probeAddr,
|
||||||
LeaderElectionNamespace: runtimeNamespace,
|
LeaderElectionNamespace: runtimeNamespace,
|
||||||
@@ -277,6 +283,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := (&controller.SetupKeyReconciler{
|
||||||
|
Client: mgr.GetClient(),
|
||||||
|
Netbird: netbird,
|
||||||
|
}).SetupWithManager(mgr); err != nil {
|
||||||
|
setupLog.Error(err, "Failed to create controller", "controller", "SetupKey")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
if gatewayAPIEnabled {
|
if gatewayAPIEnabled {
|
||||||
if err = (&controller.GatewayClassReconciler{
|
if err = (&controller.GatewayClassReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: netbird.io/v1alpha1
|
||||||
|
kind: SetupKey
|
||||||
|
metadata:
|
||||||
|
name: test
|
||||||
|
namespace: default
|
||||||
|
spec:
|
||||||
|
expiration: 0
|
||||||
@@ -13,8 +13,10 @@ require (
|
|||||||
k8s.io/api v0.35.2
|
k8s.io/api v0.35.2
|
||||||
k8s.io/apimachinery v0.35.2
|
k8s.io/apimachinery v0.35.2
|
||||||
k8s.io/client-go v0.35.2
|
k8s.io/client-go v0.35.2
|
||||||
|
k8s.io/utils v0.0.0-20260108192941-914a6e750570
|
||||||
sigs.k8s.io/controller-runtime v0.23.3
|
sigs.k8s.io/controller-runtime v0.23.3
|
||||||
sigs.k8s.io/gateway-api v1.5.1
|
sigs.k8s.io/gateway-api v1.5.1
|
||||||
|
sigs.k8s.io/structured-merge-diff/v6 v6.3.2
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -87,11 +89,9 @@ require (
|
|||||||
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect
|
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
k8s.io/klog/v2 v2.130.1 // indirect
|
||||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
|
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
|
||||||
k8s.io/utils v0.0.0-20260108192941-914a6e750570 // indirect
|
|
||||||
sigs.k8s.io/controller-tools v0.20.1 // indirect
|
sigs.k8s.io/controller-tools v0.20.1 // indirect
|
||||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
|
|
||||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
||||||
|
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
||||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
||||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||||
@@ -19,6 +21,8 @@ github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA
|
|||||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||||
github.com/TheJumpCloud/jcapi-go v3.0.0+incompatible h1:hqcTK6ZISdip65SR792lwYJTa/axESA0889D3UlZbLo=
|
github.com/TheJumpCloud/jcapi-go v3.0.0+incompatible h1:hqcTK6ZISdip65SR792lwYJTa/axESA0889D3UlZbLo=
|
||||||
github.com/TheJumpCloud/jcapi-go v3.0.0+incompatible/go.mod h1:6B1nuc1MUs6c62ODZDl7hVE5Pv7O2XGSkgg2olnq34I=
|
github.com/TheJumpCloud/jcapi-go v3.0.0+incompatible/go.mod h1:6B1nuc1MUs6c62ODZDl7hVE5Pv7O2XGSkgg2olnq34I=
|
||||||
|
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
|
||||||
|
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||||
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
|
github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
|
||||||
@@ -53,6 +57,8 @@ github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE=
|
|||||||
github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
|
github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||||
|
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||||
github.com/c-robinson/iplib v1.0.3 h1:NG0UF0GoEsrC1/vyfX1Lx2Ss7CySWl3KqqXh3q4DdPU=
|
github.com/c-robinson/iplib v1.0.3 h1:NG0UF0GoEsrC1/vyfX1Lx2Ss7CySWl3KqqXh3q4DdPU=
|
||||||
github.com/c-robinson/iplib v1.0.3/go.mod h1:i3LuuFL1hRT5gFpBRnEydzw8R6yhGkF4szNDIbF8pgo=
|
github.com/c-robinson/iplib v1.0.3/go.mod h1:i3LuuFL1hRT5gFpBRnEydzw8R6yhGkF4szNDIbF8pgo=
|
||||||
@@ -157,6 +163,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek
|
|||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||||
|
github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
|
||||||
|
github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
|
||||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
@@ -180,6 +188,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
|||||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs=
|
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc=
|
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI=
|
||||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
@@ -282,10 +292,14 @@ github.com/netbirdio/management-integrations/integrations v0.0.0-20260210160626-
|
|||||||
github.com/netbirdio/management-integrations/integrations v0.0.0-20260210160626-df4b180c7b25/go.mod h1:y7CxagMYzg9dgu+masRqYM7BQlOGA5Y8US85MCNFPlY=
|
github.com/netbirdio/management-integrations/integrations v0.0.0-20260210160626-df4b180c7b25/go.mod h1:y7CxagMYzg9dgu+masRqYM7BQlOGA5Y8US85MCNFPlY=
|
||||||
github.com/netbirdio/netbird v0.66.4 h1:jZt9e4yDjeBybLPcW4SQhhlsn15o2Jx0OzVPM9RY8mE=
|
github.com/netbirdio/netbird v0.66.4 h1:jZt9e4yDjeBybLPcW4SQhhlsn15o2Jx0OzVPM9RY8mE=
|
||||||
github.com/netbirdio/netbird v0.66.4/go.mod h1:Yeh8fZDsfngjcWedgGrzLKzsxKbGw2dQBOrJpLntpiw=
|
github.com/netbirdio/netbird v0.66.4/go.mod h1:Yeh8fZDsfngjcWedgGrzLKzsxKbGw2dQBOrJpLntpiw=
|
||||||
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI=
|
github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI=
|
||||||
github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
|
github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
|
||||||
github.com/okta/okta-sdk-golang/v2 v2.18.0 h1:cfDasMb7CShbZvOrF6n+DnLevWwiHgedWMGJ8M8xKDc=
|
github.com/okta/okta-sdk-golang/v2 v2.18.0 h1:cfDasMb7CShbZvOrF6n+DnLevWwiHgedWMGJ8M8xKDc=
|
||||||
github.com/okta/okta-sdk-golang/v2 v2.18.0/go.mod h1:dz30v3ctAiMb7jpsCngGfQUAEGm1/NsWT92uTbNDQIs=
|
github.com/okta/okta-sdk-golang/v2 v2.18.0/go.mod h1:dz30v3ctAiMb7jpsCngGfQUAEGm1/NsWT92uTbNDQIs=
|
||||||
|
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
|
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||||
github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=
|
github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI=
|
||||||
github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
|
github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
|
||||||
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
|
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
|
||||||
@@ -340,6 +354,8 @@ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
|||||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||||
|
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
|
||||||
|
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
@@ -389,6 +405,10 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6h
|
|||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||||
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
|
||||||
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.48.0 h1:sBQe3VNGUjY9IKWQC6z2lNqa5iGbDSxhs60ABwK4y0s=
|
go.opentelemetry.io/otel/exporters/prometheus v0.48.0 h1:sBQe3VNGUjY9IKWQC6z2lNqa5iGbDSxhs60ABwK4y0s=
|
||||||
go.opentelemetry.io/otel/exporters/prometheus v0.48.0/go.mod h1:DtrbMzoZWwQHyrQmCfLam5DZbnmorsGbOtTbYHycU5o=
|
go.opentelemetry.io/otel/exporters/prometheus v0.48.0/go.mod h1:DtrbMzoZWwQHyrQmCfLam5DZbnmorsGbOtTbYHycU5o=
|
||||||
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
|
||||||
@@ -399,6 +419,8 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6
|
|||||||
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
|
||||||
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
|
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
|
||||||
@@ -438,6 +460,10 @@ golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
|||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||||
|
golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
|
||||||
|
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
|
||||||
|
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
|
||||||
|
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20230704135630-469159ecf7d1 h1:EY138uSo1JYlDq+97u1FtcOUwPpIU6WL1Lkt7WpYjPA=
|
golang.zx2c4.com/wireguard v0.0.0-20230704135630-469159ecf7d1 h1:EY138uSo1JYlDq+97u1FtcOUwPpIU6WL1Lkt7WpYjPA=
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 h1:CawjfCvYQH2OU3/TnxLx97WDSUDRABfT18pCOYwc2GE=
|
||||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6/go.mod h1:3rxYc4HtVcSG9gVaTs2GEBdehh+sYPOwKtyUWEOTb80=
|
||||||
@@ -447,6 +473,8 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw
|
|||||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||||
google.golang.org/api v0.257.0 h1:8Y0lzvHlZps53PEaw+G29SsQIkuKrumGWs9puiexNAA=
|
google.golang.org/api v0.257.0 h1:8Y0lzvHlZps53PEaw+G29SsQIkuKrumGWs9puiexNAA=
|
||||||
google.golang.org/api v0.257.0/go.mod h1:4eJrr+vbVaZSqs7vovFd1Jb/A6ml6iw2e6FBYf3GAO4=
|
google.golang.org/api v0.257.0/go.mod h1:4eJrr+vbVaZSqs7vovFd1Jb/A6ml6iw2e6FBYf3GAO4=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 h1:Wgl1rcDNThT+Zn47YyCXOXyX/COgMTIdhJ717F0l4xk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 h1:Wgl1rcDNThT+Zn47YyCXOXyX/COgMTIdhJ717F0l4xk=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||||
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
|
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
|
||||||
@@ -470,6 +498,8 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST
|
|||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@@ -489,10 +519,14 @@ k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJa
|
|||||||
k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU=
|
k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU=
|
||||||
k8s.io/apimachinery v0.35.2 h1:NqsM/mmZA7sHW02JZ9RTtk3wInRgbVxL8MPfzSANAK8=
|
k8s.io/apimachinery v0.35.2 h1:NqsM/mmZA7sHW02JZ9RTtk3wInRgbVxL8MPfzSANAK8=
|
||||||
k8s.io/apimachinery v0.35.2/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
k8s.io/apimachinery v0.35.2/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||||
|
k8s.io/apiserver v0.35.0 h1:CUGo5o+7hW9GcAEF3x3usT3fX4f9r8xmgQeCBDaOgX4=
|
||||||
|
k8s.io/apiserver v0.35.0/go.mod h1:QUy1U4+PrzbJaM3XGu2tQ7U9A4udRRo5cyxkFX0GEds=
|
||||||
k8s.io/client-go v0.35.2 h1:YUfPefdGJA4aljDdayAXkc98DnPkIetMl4PrKX97W9o=
|
k8s.io/client-go v0.35.2 h1:YUfPefdGJA4aljDdayAXkc98DnPkIetMl4PrKX97W9o=
|
||||||
k8s.io/client-go v0.35.2/go.mod h1:4QqEwh4oQpeK8AaefZ0jwTFJw/9kIjdQi0jpKeYvz7g=
|
k8s.io/client-go v0.35.2/go.mod h1:4QqEwh4oQpeK8AaefZ0jwTFJw/9kIjdQi0jpKeYvz7g=
|
||||||
k8s.io/code-generator v0.35.0 h1:TvrtfKYZTm9oDF2z+veFKSCcgZE3Igv0svY+ehCmjHQ=
|
k8s.io/code-generator v0.35.0 h1:TvrtfKYZTm9oDF2z+veFKSCcgZE3Igv0svY+ehCmjHQ=
|
||||||
k8s.io/code-generator v0.35.0/go.mod h1:iS1gvVf3c/T71N5DOGYO+Gt3PdJ6B9LYSvIyQ4FHzgc=
|
k8s.io/code-generator v0.35.0/go.mod h1:iS1gvVf3c/T71N5DOGYO+Gt3PdJ6B9LYSvIyQ4FHzgc=
|
||||||
|
k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94=
|
||||||
|
k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0=
|
||||||
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ=
|
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ=
|
||||||
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM=
|
k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
@@ -501,6 +535,8 @@ k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZ
|
|||||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||||
k8s.io/utils v0.0.0-20260108192941-914a6e750570 h1:JT4W8lsdrGENg9W+YwwdLJxklIuKWdRm+BC+xt33FOY=
|
k8s.io/utils v0.0.0-20260108192941-914a6e750570 h1:JT4W8lsdrGENg9W+YwwdLJxklIuKWdRm+BC+xt33FOY=
|
||||||
k8s.io/utils v0.0.0-20260108192941-914a6e750570/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
k8s.io/utils v0.0.0-20260108192941-914a6e750570/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||||
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM=
|
||||||
|
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
||||||
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
|
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
|
||||||
sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
|
sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
|
||||||
sigs.k8s.io/controller-tools v0.20.1 h1:gkfMt9YodI0K85oT8rVi80NTXO/kDmabKR5Ajn5GYxs=
|
sigs.k8s.io/controller-tools v0.20.1 h1:gkfMt9YodI0K85oT8rVi80NTXO/kDmabKR5Ajn5GYxs=
|
||||||
|
|||||||
@@ -0,0 +1,132 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.20.1
|
||||||
|
name: setupkeys.netbird.io
|
||||||
|
spec:
|
||||||
|
group: netbird.io
|
||||||
|
names:
|
||||||
|
kind: SetupKey
|
||||||
|
listKind: SetupKeyList
|
||||||
|
plural: setupkeys
|
||||||
|
singular: setupkey
|
||||||
|
scope: Namespaced
|
||||||
|
versions:
|
||||||
|
- name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: SetupKey is the Schema for the setupkeys 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: spec defines the desired state of SetupKey
|
||||||
|
properties:
|
||||||
|
duration:
|
||||||
|
description: Duration sets how long the setup key is valid for.
|
||||||
|
type: string
|
||||||
|
x-kubernetes-validations:
|
||||||
|
- message: duration is immutable
|
||||||
|
rule: self == oldSelf
|
||||||
|
ephemeral:
|
||||||
|
description: Ephemeral decides if peers added with the key are ephemeral
|
||||||
|
or not.
|
||||||
|
type: boolean
|
||||||
|
x-kubernetes-validations:
|
||||||
|
- message: ephemeral is immutable
|
||||||
|
rule: self == oldSelf
|
||||||
|
required:
|
||||||
|
- ephemeral
|
||||||
|
type: object
|
||||||
|
status:
|
||||||
|
description: status defines the observed state of SetupKey
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
description: The status of each condition is one of True, False, or
|
||||||
|
Unknown.
|
||||||
|
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
|
||||||
|
setupKeyID:
|
||||||
|
description: SetupKeyID of the setup key.
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
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"
|
||||||
|
corev1ac "k8s.io/client-go/applyconfigurations/core/v1"
|
||||||
|
"k8s.io/utils/ptr"
|
||||||
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
|
||||||
|
nbv1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
|
"github.com/netbirdio/kubernetes-operator/internal/ssautil"
|
||||||
|
nbv1alpha1ac "github.com/netbirdio/kubernetes-operator/pkg/applyconfigurations/api/v1alpha1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SetupKeyFinalizer = "netbird.io/setupkey"
|
||||||
|
SetupKeySecretKey = "setup-key"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SetupKeyReconciler struct {
|
||||||
|
client.Client
|
||||||
|
|
||||||
|
Netbird *netbird.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=setupkeys,verbs=get;list;watch;create;update;patch;delete
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=setupkeys/status,verbs=get;update;patch
|
||||||
|
// +kubebuilder:rbac:groups=netbird.io,resources=setupkeys/finalizers,verbs=update
|
||||||
|
func (r *SetupKeyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||||
|
setupKey := nbv1alpha1.SetupKey{}
|
||||||
|
err := r.Get(ctx, req.NamespacedName, &setupKey)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !setupKey.DeletionTimestamp.IsZero() {
|
||||||
|
return r.reconcileDelete(ctx, setupKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set finalizer on the setup key.
|
||||||
|
setupKeyAC := nbv1alpha1ac.SetupKey(req.Name, req.Namespace).WithFinalizers(SetupKeyFinalizer)
|
||||||
|
err = r.Client.Apply(ctx, setupKeyAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if setup key is up to date.
|
||||||
|
ok, err := func() (bool, error) {
|
||||||
|
if setupKey.Status.SetupKeyID == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check setup key in Netbird.
|
||||||
|
resp, err := r.Netbird.SetupKeys.Get(ctx, *setupKey.Status.SetupKeyID)
|
||||||
|
if netbird.IsNotFound(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch resp.State {
|
||||||
|
case "valid":
|
||||||
|
case "overused":
|
||||||
|
return false, errors.New("setup key is overused")
|
||||||
|
default:
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secret exists and has not been modified.
|
||||||
|
secret := &corev1.Secret{}
|
||||||
|
err = r.Client.Get(ctx, client.ObjectKey{Name: setupKey.SecretName(), Namespace: req.Namespace}, secret)
|
||||||
|
if kerrors.IsNotFound(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
if resp.Key[:5] != string(secret.Data[SetupKeySecretKey])[:5] {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto groups have not been changed.
|
||||||
|
setupKeyReq := api.PutApiSetupKeysKeyIdJSONRequestBody{
|
||||||
|
AutoGroups: []string{},
|
||||||
|
}
|
||||||
|
_, err = r.Netbird.SetupKeys.Update(ctx, *setupKey.Status.SetupKeyID, setupKeyReq)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}()
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
|
return ctrl.Result{RequeueAfter: 15 * time.Minute}, nil
|
||||||
|
}
|
||||||
|
oldSetupKeyID := setupKey.Status.SetupKeyID
|
||||||
|
|
||||||
|
// Setup key does not exist so we create one.
|
||||||
|
expiresIn := 0
|
||||||
|
if setupKey.Spec.Duration != nil {
|
||||||
|
expiresIn = int(setupKey.Spec.Duration.Seconds())
|
||||||
|
}
|
||||||
|
setupKeyReq := api.PostApiSetupKeysJSONRequestBody{
|
||||||
|
AllowExtraDnsLabels: ptr.To(false),
|
||||||
|
AutoGroups: []string{},
|
||||||
|
Ephemeral: ptr.To(setupKey.Spec.Ephemeral),
|
||||||
|
ExpiresIn: expiresIn,
|
||||||
|
Name: req.Name,
|
||||||
|
Type: "reusable",
|
||||||
|
UsageLimit: 0,
|
||||||
|
}
|
||||||
|
resp, err := r.Netbird.SetupKeys.Create(ctx, setupKeyReq)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the status with the id.
|
||||||
|
setupKeyAC = nbv1alpha1ac.SetupKey(req.Name, req.Namespace).WithStatus(nbv1alpha1ac.SetupKeyStatus().WithSetupKeyID(resp.Id))
|
||||||
|
err = r.Client.Status().Apply(ctx, setupKeyAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the secret containing the key.
|
||||||
|
owner, err := ssautil.OwnerReference(&setupKey, r.Scheme())
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
data := map[string]string{
|
||||||
|
SetupKeySecretKey: resp.Key,
|
||||||
|
}
|
||||||
|
secret := corev1ac.Secret(setupKey.SecretName(), req.Namespace).
|
||||||
|
WithStringData(data).
|
||||||
|
WithOwnerReferences(owner)
|
||||||
|
err = r.Client.Apply(ctx, secret)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the old status key if we are recreating.
|
||||||
|
if oldSetupKeyID != nil {
|
||||||
|
err = r.Netbird.SetupKeys.Delete(ctx, *oldSetupKeyID)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrl.Result{RequeueAfter: 15 * time.Minute}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SetupKeyReconciler) reconcileDelete(ctx context.Context, setupKey nbv1alpha1.SetupKey) (ctrl.Result, error) {
|
||||||
|
if setupKey.Status.SetupKeyID == nil {
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := r.Netbird.SetupKeys.Delete(ctx, *setupKey.Status.SetupKeyID)
|
||||||
|
if err != nil && !netbird.IsNotFound(err) {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
setupKeyAC := nbv1alpha1ac.SetupKey(setupKey.Name, setupKey.Namespace).WithFinalizers()
|
||||||
|
err = r.Client.Apply(ctx, setupKeyAC)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SetupKeyReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||||
|
return ctrl.NewControllerManagedBy(mgr).
|
||||||
|
For(&nbv1alpha1.SetupKey{}).
|
||||||
|
Owns(&corev1.Secret{}).
|
||||||
|
Complete(r)
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
|
||||||
|
netbird "github.com/netbirdio/netbird/shared/management/client/rest"
|
||||||
|
"github.com/netbirdio/netbird/shared/management/http/api"
|
||||||
|
. "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"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("SetupKey Controller", func() {
|
||||||
|
Context("When reconciling a resource", func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
r := rand.New(rand.NewSource(GinkgoRandomSeed()))
|
||||||
|
|
||||||
|
setupKeyStore := map[string]*api.SetupKey{}
|
||||||
|
mux := &http.ServeMux{}
|
||||||
|
mux.HandleFunc("/api/setup-keys", func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
switch req.Method {
|
||||||
|
case http.MethodPost:
|
||||||
|
resp := api.SetupKeyClear{
|
||||||
|
Id: fmt.Sprintf("id-%d", r.Int63()),
|
||||||
|
Key: fmt.Sprintf("%d", r.Int63()),
|
||||||
|
State: "valid",
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(resp)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = rw.Write(b)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
setupKey := api.SetupKey{
|
||||||
|
Id: resp.Id,
|
||||||
|
Key: resp.Key,
|
||||||
|
State: resp.State,
|
||||||
|
}
|
||||||
|
setupKeyStore[resp.Id] = &setupKey
|
||||||
|
default:
|
||||||
|
rw.WriteHeader(http.StatusNotFound)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
mux.HandleFunc("/api/setup-keys/{id}", func(rw http.ResponseWriter, req *http.Request) {
|
||||||
|
id := req.PathValue("id")
|
||||||
|
setupKey, ok := setupKeyStore[id]
|
||||||
|
if !ok {
|
||||||
|
rw.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch req.Method {
|
||||||
|
case http.MethodDelete:
|
||||||
|
delete(setupKeyStore, id)
|
||||||
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
case http.MethodGet:
|
||||||
|
b, err := json.Marshal(setupKey)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = rw.Write(b)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
case http.MethodPut:
|
||||||
|
b, err := io.ReadAll(req.Body)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
putReq := api.SetupKeyRequest{}
|
||||||
|
err = json.Unmarshal(b, &putReq)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
setupKey.AutoGroups = putReq.AutoGroups
|
||||||
|
|
||||||
|
b, err = json.Marshal(setupKey)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = rw.Write(b)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
default:
|
||||||
|
rw.WriteHeader(http.StatusNotFound)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
server := httptest.NewServer(mux)
|
||||||
|
nbClient := netbird.New(server.URL, "ABC")
|
||||||
|
|
||||||
|
var controllerReconciler *SetupKeyReconciler
|
||||||
|
nn := client.ObjectKey{
|
||||||
|
Name: "test-resource",
|
||||||
|
Namespace: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
controllerReconciler = &SetupKeyReconciler{
|
||||||
|
Client: k8sClient,
|
||||||
|
Netbird: nbClient,
|
||||||
|
}
|
||||||
|
setupKeyStore = map[string]*api.SetupKey{}
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
setupKey := &nbv1alpha1.SetupKey{}
|
||||||
|
err := k8sClient.Get(ctx, nn, setupKey)
|
||||||
|
if kerrors.IsNotFound(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(k8sClient.Delete(ctx, setupKey)).To(Succeed())
|
||||||
|
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
It("creates a secret containing the setup key", func() {
|
||||||
|
setupKey := &nbv1alpha1.SetupKey{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Name,
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, setupKey)).To(Succeed())
|
||||||
|
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = k8sClient.Get(ctx, nn, setupKey)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(*setupKey.Status.SetupKeyID).NotTo(BeEmpty())
|
||||||
|
|
||||||
|
secret := &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: setupKey.SecretName(),
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(secret), secret)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(string(secret.Data[SetupKeySecretKey])).To(Equal(setupKeyStore[*setupKey.Status.SetupKeyID].Key))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("creates a new setup key when the secret is deleted", func() {
|
||||||
|
setupKey := &nbv1alpha1.SetupKey{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: nn.Name,
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Expect(k8sClient.Create(ctx, setupKey)).To(Succeed())
|
||||||
|
_, err := controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
firstSetupKey := nbv1alpha1.SetupKey{}
|
||||||
|
err = k8sClient.Get(ctx, nn, &firstSetupKey)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
firstSecret := corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: firstSetupKey.SecretName(),
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(&firstSecret), &firstSecret)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(k8sClient.Delete(ctx, &firstSecret)).To(Succeed())
|
||||||
|
|
||||||
|
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{NamespacedName: nn})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
secondSetupKey := nbv1alpha1.SetupKey{}
|
||||||
|
err = k8sClient.Get(ctx, nn, &secondSetupKey)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
secondSecret := corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: secondSetupKey.SecretName(),
|
||||||
|
Namespace: nn.Namespace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(&secondSecret), &secondSecret)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(k8sClient.Delete(ctx, &secondSecret)).To(Succeed())
|
||||||
|
|
||||||
|
Expect(setupKeyStore).To(HaveLen(1))
|
||||||
|
Expect(*firstSetupKey.Status.SetupKeyID).ToNot(Equal(*secondSetupKey.Status.SetupKeyID))
|
||||||
|
Expect(firstSecret.Data[SetupKeySecretKey]).ToNot(BeEquivalentTo(secondSecret.Data[SetupKeySecretKey]))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -35,6 +35,7 @@ import (
|
|||||||
foobarv1 "k8s.io/api/core/v1"
|
foobarv1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
netbirdiov1 "github.com/netbirdio/kubernetes-operator/api/v1"
|
||||||
|
netbirdiov1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
// +kubebuilder:scaffold:imports
|
// +kubebuilder:scaffold:imports
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -67,6 +68,9 @@ var _ = BeforeSuite(func() {
|
|||||||
err = foobarv1.AddToScheme(scheme.Scheme)
|
err = foobarv1.AddToScheme(scheme.Scheme)
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = netbirdiov1alpha1.AddToScheme(scheme.Scheme)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
// +kubebuilder:scaffold:scheme
|
// +kubebuilder:scaffold:scheme
|
||||||
|
|
||||||
By("bootstrapping test environment")
|
By("bootstrapping test environment")
|
||||||
@@ -85,7 +89,8 @@ var _ = BeforeSuite(func() {
|
|||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(cfg).NotTo(BeNil())
|
Expect(cfg).NotTo(BeNil())
|
||||||
|
|
||||||
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
|
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme, FieldOwner: "netbird-operator"})
|
||||||
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
Expect(k8sClient).NotTo(BeNil())
|
Expect(k8sClient).NotTo(BeNil())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package ssautil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
metav1ac "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OwnerReference(owner client.Object, scheme *runtime.Scheme) (*metav1ac.OwnerReferenceApplyConfiguration, error) {
|
||||||
|
gvk, err := apiutil.GVKForObject(owner, scheme)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return metav1ac.OwnerReference().
|
||||||
|
WithAPIVersion(gvk.GroupVersion().String()).
|
||||||
|
WithKind(gvk.Kind).
|
||||||
|
WithName(owner.GetName()).
|
||||||
|
WithUID(owner.GetUID()).
|
||||||
|
WithController(true).
|
||||||
|
WithBlockOwnerDeletion(true), nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,232 @@
|
|||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetupKeyApplyConfiguration represents a declarative configuration of the SetupKey type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// SetupKey is the Schema for the setupkeys API
|
||||||
|
type SetupKeyApplyConfiguration struct {
|
||||||
|
v1.TypeMetaApplyConfiguration `json:",inline"`
|
||||||
|
// metadata is a standard object metadata
|
||||||
|
*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
|
||||||
|
// spec defines the desired state of SetupKey
|
||||||
|
Spec *SetupKeySpecApplyConfiguration `json:"spec,omitempty"`
|
||||||
|
// status defines the observed state of SetupKey
|
||||||
|
Status *SetupKeyStatusApplyConfiguration `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupKey constructs a declarative configuration of the SetupKey type for use with
|
||||||
|
// apply.
|
||||||
|
func SetupKey(name, namespace string) *SetupKeyApplyConfiguration {
|
||||||
|
b := &SetupKeyApplyConfiguration{}
|
||||||
|
b.WithName(name)
|
||||||
|
b.WithNamespace(namespace)
|
||||||
|
b.WithKind("SetupKey")
|
||||||
|
b.WithAPIVersion("netbird.io/v1alpha1")
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b SetupKeyApplyConfiguration) 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 *SetupKeyApplyConfiguration) WithKind(value string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithAPIVersion(value string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithName(value string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithGenerateName(value string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithNamespace(value string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithUID(value types.UID) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithResourceVersion(value string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithGeneration(value int64) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithCreationTimestamp(value metav1.Time) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithLabels(entries map[string]string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithAnnotations(entries map[string]string) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithFinalizers(values ...string) *SetupKeyApplyConfiguration {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
for i := range values {
|
||||||
|
b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *SetupKeyApplyConfiguration) 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 *SetupKeyApplyConfiguration) WithSpec(value *SetupKeySpecApplyConfiguration) *SetupKeyApplyConfiguration {
|
||||||
|
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 *SetupKeyApplyConfiguration) WithStatus(value *SetupKeyStatusApplyConfiguration) *SetupKeyApplyConfiguration {
|
||||||
|
b.Status = value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetKind retrieves the value of the Kind field in the declarative configuration.
|
||||||
|
func (b *SetupKeyApplyConfiguration) GetKind() *string {
|
||||||
|
return b.TypeMetaApplyConfiguration.Kind
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
|
||||||
|
func (b *SetupKeyApplyConfiguration) GetAPIVersion() *string {
|
||||||
|
return b.TypeMetaApplyConfiguration.APIVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName retrieves the value of the Name field in the declarative configuration.
|
||||||
|
func (b *SetupKeyApplyConfiguration) GetName() *string {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
return b.ObjectMetaApplyConfiguration.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
|
||||||
|
func (b *SetupKeyApplyConfiguration) GetNamespace() *string {
|
||||||
|
b.ensureObjectMetaApplyConfigurationExists()
|
||||||
|
return b.ObjectMetaApplyConfiguration.Namespace
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetupKeySpecApplyConfiguration represents a declarative configuration of the SetupKeySpec type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// SetupKeySpec defines the desired state of SetupKey
|
||||||
|
type SetupKeySpecApplyConfiguration struct {
|
||||||
|
// Ephemeral decides if peers added with the key are ephemeral or not.
|
||||||
|
Ephemeral *bool `json:"ephemeral,omitempty"`
|
||||||
|
// Duration sets how long the setup key is valid for.
|
||||||
|
Duration *v1.Duration `json:"duration,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupKeySpecApplyConfiguration constructs a declarative configuration of the SetupKeySpec type for use with
|
||||||
|
// apply.
|
||||||
|
func SetupKeySpec() *SetupKeySpecApplyConfiguration {
|
||||||
|
return &SetupKeySpecApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// If called multiple times, the Ephemeral field is set to the value of the last call.
|
||||||
|
func (b *SetupKeySpecApplyConfiguration) WithEphemeral(value bool) *SetupKeySpecApplyConfiguration {
|
||||||
|
b.Ephemeral = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDuration sets the Duration 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 Duration field is set to the value of the last call.
|
||||||
|
func (b *SetupKeySpecApplyConfiguration) WithDuration(value v1.Duration) *SetupKeySpecApplyConfiguration {
|
||||||
|
b.Duration = &value
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package v1alpha1
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetupKeyStatusApplyConfiguration represents a declarative configuration of the SetupKeyStatus type for use
|
||||||
|
// with apply.
|
||||||
|
//
|
||||||
|
// SetupKeyStatus defines the observed state of SetupKey.
|
||||||
|
type SetupKeyStatusApplyConfiguration struct {
|
||||||
|
// SetupKeyID of the setup key.
|
||||||
|
SetupKeyID *string `json:"setupKeyID,omitempty"`
|
||||||
|
// The status of each condition is one of True, False, or Unknown.
|
||||||
|
Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupKeyStatusApplyConfiguration constructs a declarative configuration of the SetupKeyStatus type for use with
|
||||||
|
// apply.
|
||||||
|
func SetupKeyStatus() *SetupKeyStatusApplyConfiguration {
|
||||||
|
return &SetupKeyStatusApplyConfiguration{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSetupKeyID sets the SetupKeyID 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 SetupKeyID field is set to the value of the last call.
|
||||||
|
func (b *SetupKeyStatusApplyConfiguration) WithSetupKeyID(value string) *SetupKeyStatusApplyConfiguration {
|
||||||
|
b.SetupKeyID = &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 *SetupKeyStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *SetupKeyStatusApplyConfiguration {
|
||||||
|
for i := range values {
|
||||||
|
if values[i] == nil {
|
||||||
|
panic("nil value passed to WithConditions")
|
||||||
|
}
|
||||||
|
b.Conditions = append(b.Conditions, *values[i])
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
fmt "fmt"
|
||||||
|
sync "sync"
|
||||||
|
|
||||||
|
typed "sigs.k8s.io/structured-merge-diff/v6/typed"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Parser() *typed.Parser {
|
||||||
|
parserOnce.Do(func() {
|
||||||
|
var err error
|
||||||
|
parser, err = typed.NewParser(schemaYAML)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Failed to parse schema: %v", err))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return parser
|
||||||
|
}
|
||||||
|
|
||||||
|
var parserOnce sync.Once
|
||||||
|
var parser *typed.Parser
|
||||||
|
var schemaYAML = typed.YAMLObject(`types:
|
||||||
|
- name: __untyped_atomic_
|
||||||
|
scalar: untyped
|
||||||
|
list:
|
||||||
|
elementType:
|
||||||
|
namedType: __untyped_atomic_
|
||||||
|
elementRelationship: atomic
|
||||||
|
map:
|
||||||
|
elementType:
|
||||||
|
namedType: __untyped_atomic_
|
||||||
|
elementRelationship: atomic
|
||||||
|
- name: __untyped_deduced_
|
||||||
|
scalar: untyped
|
||||||
|
list:
|
||||||
|
elementType:
|
||||||
|
namedType: __untyped_atomic_
|
||||||
|
elementRelationship: atomic
|
||||||
|
map:
|
||||||
|
elementType:
|
||||||
|
namedType: __untyped_deduced_
|
||||||
|
elementRelationship: separable
|
||||||
|
`)
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// Code generated by controller-gen. DO NOT EDIT.
|
||||||
|
|
||||||
|
package applyconfigurations
|
||||||
|
|
||||||
|
import (
|
||||||
|
v1alpha1 "github.com/netbirdio/kubernetes-operator/api/v1alpha1"
|
||||||
|
apiv1alpha1 "github.com/netbirdio/kubernetes-operator/pkg/applyconfigurations/api/v1alpha1"
|
||||||
|
internal "github.com/netbirdio/kubernetes-operator/pkg/applyconfigurations/internal"
|
||||||
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
|
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
managedfields "k8s.io/apimachinery/pkg/util/managedfields"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ForKind returns an apply configuration type for the given GroupVersionKind, or nil if no
|
||||||
|
// apply configuration type exists for the given GroupVersionKind.
|
||||||
|
func ForKind(kind schema.GroupVersionKind) interface{} {
|
||||||
|
switch kind {
|
||||||
|
// Group=netbird.io, Version=v1alpha1
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("SetupKey"):
|
||||||
|
return &apiv1alpha1.SetupKeyApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("SetupKeySpec"):
|
||||||
|
return &apiv1alpha1.SetupKeySpecApplyConfiguration{}
|
||||||
|
case v1alpha1.SchemeGroupVersion.WithKind("SetupKeyStatus"):
|
||||||
|
return &apiv1alpha1.SetupKeyStatusApplyConfiguration{}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTypeConverter(scheme *runtime.Scheme) managedfields.TypeConverter {
|
||||||
|
return managedfields.NewSchemeTypeConverter(scheme, internal.Parser())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user