Compare commits

...

6 Commits

Author SHA1 Message Date
Itxaka
f008a35bcd
Merge pull request #11 from kairos-io/go122 2024-07-11 12:01:05 +02:00
Itxaka
594e67734f Bump to go1.22
Signed-off-by: Itxaka <itxaka@kairos.io>
2024-07-11 11:34:42 +02:00
Mauro Morales
ef614e73da
Update issue templates
relates to https://github.com/kairos-io/kairos/issues/1483
2023-06-13 12:24:46 +02:00
Ettore Di Giacinto
c77904aaf7
📖 Update README 2023-02-07 12:16:52 +01:00
mudler
737bae9d77 🌱 Add daemonset
Signed-off-by: mudler <mudler@c3os.io>
2022-12-28 19:40:55 +01:00
mudler
ca06cf47e4 Change default failurePolicy to Fail 2022-12-27 13:59:14 +01:00
24 changed files with 763 additions and 7 deletions

View File

@ -0,0 +1,12 @@
---
name: File issues on main Kairos repo
about: 'Tell users to file their issues on the main Kairos repo title: '''''
title: ''
labels: ''
assignees: ''
---
:warning: All Kairos issues are tracked in our main repo, please file your issue there, thanks! :warning:
https://github.com/kairos-io/kairos/issues

View File

@ -1,5 +1,5 @@
# Build the manager binary # Build the manager binary
FROM golang:1.18 as builder FROM golang:1.22 as builder
WORKDIR /workspace WORKDIR /workspace
# Copy the Go Modules manifests # Copy the Go Modules manifests

View File

@ -19,4 +19,13 @@ resources:
webhooks: webhooks:
defaulting: true defaulting: true
webhookVersion: v1 webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
controller: true
domain: kairos.io
group: entangle
kind: VPN
path: github.com/kairos-io/entangle/api/v1alpha1
version: v1alpha1
version: "3" version: "3"

View File

@ -1,9 +1,64 @@
# entangle <h1 align="center">
<br>
<img width="184" alt="kairos-white-column 5bc2fe34" src="https://user-images.githubusercontent.com/2420543/193010398-72d4ba6e-7efe-4c2e-b7ba-d3a826a55b7d.png"><br>
Entangle
<br>
</h1>
<h3 align="center">Entangle kubernetes connections running on remote clusters, also behind NAT </h3>
<p align="center">
<a href="https://opensource.org/licenses/">
<img src="https://img.shields.io/badge/licence-APL2-brightgreen"
alt="license">
</a>
<a href="https://github.com/kairos-io/entangle/issues"><img src="https://img.shields.io/github/issues/kairos-io/entangle"></a>
<a href="https://kairos.io/docs/" target=_blank> <img src="https://img.shields.io/badge/Documentation-blue"
alt="docs"></a>
<img src="https://img.shields.io/badge/made%20with-Go-blue">
<img src="https://goreportcard.com/badge/github.com/kairos-io/entangle" alt="go report card" />
</p>
With Kairos you can build immutable, bootable Kubernetes and OS images for your edge devices as easily as writing a Dockerfile. Optional P2P mesh with distributed ledger automates node bootstrapping and coordination. Updating nodes is as easy as CI/CD: push a new image to your container registry and let secure, risk-free A/B atomic upgrades do the rest.
<table>
<tr>
<th align="center">
<img width="640" height="1px">
<p>
<small>
Documentation
</small>
</p>
</th>
<th align="center">
<img width="640" height="1">
<p>
<small>
Contribute
</small>
</p>
</th>
</tr>
<tr>
<td>
📚 [Getting started with Kairos](https://kairos.io/docs/getting-started) <br> :bulb: [Examples](https://kairos.io/docs/examples) <br> :movie_camera: [Video](https://kairos.io/docs/media/) <br> :open_hands:[Engage with the Community](https://kairos.io/community/)
</td>
<td>
🙌[ CONTRIBUTING.md ]( https://github.com/kairos-io/kairos/blob/master/CONTRIBUTING.md ) <br> :raising_hand: [ GOVERNANCE ]( https://github.com/kairos-io/kairos/blob/master/GOVERNANCE.md ) <br>:construction_worker:[Code of conduct](https://github.com/kairos-io/kairos/blob/master/CODE_OF_CONDUCT.md)
</td>
</tr>
</table>
| :exclamation: | This is experimental! | | :exclamation: | This is experimental! |
|-|:-| |-|:-|
This is the Kairos entangle Kubernetes Native Extension. ## Installation
To install, use helm: To install, use helm:
@ -29,6 +84,8 @@ TEST SUITE: None
$ helm install kairos-entangle kairos/entangle $ helm install kairos-entangle kairos/entangle
``` ```
Documentation is available at: https://kairos.io/docs/reference/entangle/
## License ## License
Copyright 2022. Copyright 2022.

62
api/v1alpha1/vpn_types.go Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha1
import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// VPNSpec defines the desired state of VPN
type VPNSpec struct {
SecretRef *string `json:"secretRef,omitempty"`
Env []v1.EnvVar `json:"env,omitempty"`
}
// VPNStatus defines the observed state of VPN
type VPNStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// VPN is the Schema for the vpns API
type VPN struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec VPNSpec `json:"spec,omitempty"`
Status VPNStatus `json:"status,omitempty"`
}
//+kubebuilder:object:root=true
// VPNList contains a list of VPN
type VPNList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []VPN `json:"items"`
}
func init() {
SchemeBuilder.Register(&VPN{}, &VPNList{})
}

View File

@ -136,3 +136,104 @@ func (in *EntanglementStatus) DeepCopy() *EntanglementStatus {
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 *VPN) DeepCopyInto(out *VPN) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPN.
func (in *VPN) DeepCopy() *VPN {
if in == nil {
return nil
}
out := new(VPN)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *VPN) 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 *VPNList) DeepCopyInto(out *VPNList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]VPN, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPNList.
func (in *VPNList) DeepCopy() *VPNList {
if in == nil {
return nil
}
out := new(VPNList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *VPNList) 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 *VPNSpec) DeepCopyInto(out *VPNSpec) {
*out = *in
if in.SecretRef != nil {
in, out := &in.SecretRef, &out.SecretRef
*out = new(string)
**out = **in
}
if in.Env != nil {
in, out := &in.Env, &out.Env
*out = make([]v1.EnvVar, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPNSpec.
func (in *VPNSpec) DeepCopy() *VPNSpec {
if in == nil {
return nil
}
out := new(VPNSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *VPNStatus) DeepCopyInto(out *VPNStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VPNStatus.
func (in *VPNStatus) DeepCopy() *VPNStatus {
if in == nil {
return nil
}
out := new(VPNStatus)
in.DeepCopyInto(out)
return out
}

View File

@ -0,0 +1,152 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
name: vpns.entangle.kairos.io
spec:
group: entangle.kairos.io
names:
kind: VPN
listKind: VPNList
plural: vpns
singular: vpn
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: VPN is the Schema for the vpns 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: VPNSpec defines the desired state of VPN
properties:
env:
items:
description: EnvVar represents an environment variable present in
a Container.
properties:
name:
description: Name of the environment variable. Must be a C_IDENTIFIER.
type: string
value:
description: 'Variable references $(VAR_NAME) are expanded using
the previously defined environment variables in the container
and any service environment variables. If a variable cannot
be resolved, the reference in the input string will be unchanged.
Double $$ are reduced to a single $, which allows for escaping
the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the
string literal "$(VAR_NAME)". Escaped references will never
be expanded, regardless of whether the variable exists or
not. Defaults to "".'
type: string
valueFrom:
description: Source for the environment variable's value. Cannot
be used if value is not empty.
properties:
configMapKeyRef:
description: Selects a key of a ConfigMap.
properties:
key:
description: The key to select.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
optional:
description: Specify whether the ConfigMap or its key
must be defined
type: boolean
required:
- key
type: object
fieldRef:
description: 'Selects a field of the pod: supports metadata.name,
metadata.namespace, `metadata.labels[''<KEY>'']`, `metadata.annotations[''<KEY>'']`,
spec.nodeName, spec.serviceAccountName, status.hostIP,
status.podIP, status.podIPs.'
properties:
apiVersion:
description: Version of the schema the FieldPath is
written in terms of, defaults to "v1".
type: string
fieldPath:
description: Path of the field to select in the specified
API version.
type: string
required:
- fieldPath
type: object
resourceFieldRef:
description: 'Selects a resource of the container: only
resources limits and requests (limits.cpu, limits.memory,
limits.ephemeral-storage, requests.cpu, requests.memory
and requests.ephemeral-storage) are currently supported.'
properties:
containerName:
description: 'Container name: required for volumes,
optional for env vars'
type: string
divisor:
anyOf:
- type: integer
- type: string
description: Specifies the output format of the exposed
resources, defaults to "1"
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
resource:
description: 'Required: resource to select'
type: string
required:
- resource
type: object
secretKeyRef:
description: Selects a key of a secret in the pod's namespace
properties:
key:
description: The key of the secret to select from. Must
be a valid secret key.
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?'
type: string
optional:
description: Specify whether the Secret or its key must
be defined
type: boolean
required:
- key
type: object
type: object
required:
- name
type: object
type: array
secretRef:
type: string
type: object
status:
description: VPNStatus defines the observed state of VPN
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -3,17 +3,20 @@
# It should be run by config/default # It should be run by config/default
resources: resources:
- bases/entangle.kairos.io_entanglements.yaml - bases/entangle.kairos.io_entanglements.yaml
- bases/entangle.kairos.io_vpns.yaml
#+kubebuilder:scaffold:crdkustomizeresource #+kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge: patchesStrategicMerge:
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
# patches here are for enabling the conversion webhook for each CRD # patches here are for enabling the conversion webhook for each CRD
#- patches/webhook_in_entanglements.yaml #- patches/webhook_in_entanglements.yaml
#- patches/webhook_in_vpns.yaml
#+kubebuilder:scaffold:crdkustomizewebhookpatch #+kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
# patches here are for enabling the CA injection for each CRD # patches here are for enabling the CA injection for each CRD
#- patches/cainjection_in_entanglements.yaml #- patches/cainjection_in_entanglements.yaml
#- patches/cainjection_in_vpns.yaml
#+kubebuilder:scaffold:crdkustomizecainjectionpatch #+kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs. # the following config is for teaching kustomize how to do kustomization for CRDs.

View File

@ -0,0 +1,7 @@
# The following patch adds a directive for certmanager to inject CA into the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
name: vpns.entangle.kairos.io

View File

@ -0,0 +1,16 @@
# The following patch enables a conversion webhook for the CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: vpns.entangle.kairos.io
spec:
conversion:
strategy: Webhook
webhook:
clientConfig:
service:
namespace: system
name: webhook-service
path: /convert
conversionReviewVersions:
- v1

View File

@ -23,6 +23,18 @@ rules:
- get - get
- list - list
- watch - watch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups: - apiGroups:
- apps - apps
resources: resources:
@ -61,3 +73,29 @@ rules:
- get - get
- patch - patch
- update - update
- apiGroups:
- entangle.kairos.io
resources:
- vpns
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- entangle.kairos.io
resources:
- vpns/finalizers
verbs:
- update
- apiGroups:
- entangle.kairos.io
resources:
- vpns/status
verbs:
- get
- patch
- update

View File

@ -0,0 +1,31 @@
# permissions for end users to edit vpns.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: vpn-editor-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: entangle
app.kubernetes.io/part-of: entangle
app.kubernetes.io/managed-by: kustomize
name: vpn-editor-role
rules:
- apiGroups:
- entangle.kairos.io
resources:
- vpns
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- entangle.kairos.io
resources:
- vpns/status
verbs:
- get

View File

@ -0,0 +1,27 @@
# permissions for end users to view vpns.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/name: clusterrole
app.kubernetes.io/instance: vpn-viewer-role
app.kubernetes.io/component: rbac
app.kubernetes.io/created-by: entangle
app.kubernetes.io/part-of: entangle
app.kubernetes.io/managed-by: kustomize
name: vpn-viewer-role
rules:
- apiGroups:
- entangle.kairos.io
resources:
- vpns
verbs:
- get
- list
- watch
- apiGroups:
- entangle.kairos.io
resources:
- vpns/status
verbs:
- get

View File

@ -0,0 +1,12 @@
apiVersion: entangle.kairos.io/v1alpha1
kind: VPN
metadata:
labels:
app.kubernetes.io/name: vpn
app.kubernetes.io/instance: vpn-sample
app.kubernetes.io/part-of: entangle
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/created-by: entangle
name: vpn-sample
spec:
# TODO(user): Add fields here

View File

@ -1,4 +1,5 @@
## Append samples you want in your CSV to this file as resources ## ## Append samples you want in your CSV to this file as resources ##
resources: resources:
- entangle_v1alpha1_entanglement.yaml - entangle_v1alpha1_entanglement.yaml
- entangle_v1alpha1_vpn.yaml
#+kubebuilder:scaffold:manifestskustomizesamples #+kubebuilder:scaffold:manifestskustomizesamples

View File

@ -13,7 +13,7 @@ webhooks:
name: webhook-service name: webhook-service
namespace: system namespace: system
path: /mutate-entangle-kairos-x-io-v1alpha1-entanglement path: /mutate-entangle-kairos-x-io-v1alpha1-entanglement
failurePolicy: Ignore failurePolicy: Fail
name: mentanglement.kb.io name: mentanglement.kb.io
rules: rules:
- apiGroups: - apiGroups:

87
controllers/daemonset.go Normal file
View File

@ -0,0 +1,87 @@
package controllers
import (
entanglev1alpha1 "github.com/kairos-io/entangle/api/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
func genDaemonsetOwner(ent entanglev1alpha1.VPN) []metav1.OwnerReference {
return []metav1.OwnerReference{
*metav1.NewControllerRef(&ent.ObjectMeta, schema.GroupVersionKind{
Group: entanglev1alpha1.GroupVersion.Group,
Version: entanglev1alpha1.GroupVersion.Version,
Kind: "VPN",
}),
}
}
func (r *VPNReconciler) genDaemonset(ent entanglev1alpha1.VPN) (*appsv1.DaemonSet, error) {
objMeta := metav1.ObjectMeta{
Name: ent.Name,
Namespace: ent.Namespace,
OwnerReferences: genDaemonsetOwner(ent),
}
privileged := true
serviceAccount := false
v := ent.Spec.Env
v = append(v, v1.EnvVar{
Name: "EDGEVPNTOKEN",
ValueFrom: &v1.EnvVarSource{
SecretKeyRef: &v1.SecretKeySelector{
Key: "network_token",
LocalObjectReference: v1.LocalObjectReference{
Name: *ent.Spec.SecretRef,
},
},
},
})
expose := v1.Container{
SecurityContext: &v1.SecurityContext{
Privileged: &privileged,
Capabilities: &v1.Capabilities{
Add: []v1.Capability{"NET_ADMIN"},
},
},
ImagePullPolicy: v1.PullAlways,
Name: "vpn",
Image: r.EntangleServiceImage,
Env: v,
Command: []string{"/usr/bin/edgevpn"},
VolumeMounts: []v1.VolumeMount{v1.VolumeMount{Name: "dev-net-tun", MountPath: "/dev/net/tun"}},
}
pod := v1.PodSpec{
Containers: []v1.Container{expose},
AutomountServiceAccountToken: &serviceAccount,
HostNetwork: true,
Volumes: []v1.Volume{v1.Volume{Name: "dev-net-tun", VolumeSource: v1.VolumeSource{HostPath: &v1.HostPathVolumeSource{Path: "/dev/net/tun"}}}},
}
deploymentLabels := getnDaemonsetLabel(ent.Name)
return &appsv1.DaemonSet{
ObjectMeta: objMeta,
Spec: appsv1.DaemonSetSpec{
Selector: &metav1.LabelSelector{MatchLabels: deploymentLabels},
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: deploymentLabels,
},
Spec: pod,
},
},
}, nil
}
func getnDaemonsetLabel(s string) map[string]string {
return map[string]string{
"vpn.kairos.io": s,
}
}

View File

@ -70,7 +70,7 @@ func (r *EntanglementReconciler) Reconcile(ctx context.Context, req ctrl.Request
return ctrl.Result{}, err return ctrl.Result{}, err
} }
desiredDeployment, err := r.genDeployment(ent,r.LogLevel) desiredDeployment, err := r.genDeployment(ent, r.LogLevel)
if err != nil { if err != nil {
return ctrl.Result{}, err return ctrl.Result{}, err
} }

View File

@ -0,0 +1,114 @@
/*
Copyright 2022.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers
import (
"context"
"fmt"
apierrors "k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
entanglev1alpha1 "github.com/kairos-io/entangle/api/v1alpha1"
)
// VPNReconciler reconciles a VPN object
type VPNReconciler struct {
client.Client
Scheme *runtime.Scheme
clientSet *kubernetes.Clientset
EntangleServiceImage string
}
//+kubebuilder:rbac:groups=entangle.kairos.io,resources=vpns,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=entangle.kairos.io,resources=vpns/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=entangle.kairos.io,resources=vpns/finalizers,verbs=update
//+kubebuilder:rbac:groups=apps,resources=daemonsets,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups="",resources=secrets,verbs=create;get;list;watch
// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
// TODO(user): Modify the Reconcile function to compare the state specified by
// the VPN object against the actual cluster state, and then
// perform operations to make the cluster state reflect the state specified by
// the user.
//
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.13.0/pkg/reconcile
func (r *VPNReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := log.FromContext(ctx)
// Creates a deployment targeting a service
// TODO(user): your logic here
var ent entanglev1alpha1.VPN
if err := r.Get(ctx, req.NamespacedName, &ent); err != nil {
if apierrors.IsNotFound(err) {
return ctrl.Result{}, nil
}
return ctrl.Result{}, err
}
desiredDaemonset, err := r.genDaemonset(ent)
if err != nil {
return ctrl.Result{}, err
}
daemonset, err := r.clientSet.AppsV1().DaemonSets(req.Namespace).Get(ctx, desiredDaemonset.Name, v1.GetOptions{})
if daemonset == nil || apierrors.IsNotFound(err) {
logger.Info(fmt.Sprintf("Creating Daemonset %v", daemonset))
daemonset, err = r.clientSet.AppsV1().DaemonSets(req.Namespace).Create(ctx, desiredDaemonset, v1.CreateOptions{})
if err != nil {
logger.Error(err, "Failed while creating daemonset")
return ctrl.Result{}, nil
}
return ctrl.Result{Requeue: true}, nil
}
if err != nil {
return ctrl.Result{Requeue: true}, err
}
// // If args or env are missing, update it
// if desiredDaemonset.{
// deployment, err = r.clientSet.AppsV1().Deployments(req.Namespace).Update(ctx, desiredDeployment, v1.UpdateOptions{})
// if err != nil {
// logger.Error(err, "Failed while updating deployment")
// return ctrl.Result{}, nil
// }
// }
return ctrl.Result{}, nil
}
// SetupWithManager sets up the controller with the Manager.
func (r *VPNReconciler) SetupWithManager(mgr ctrl.Manager) error {
clientset, err := kubernetes.NewForConfig(mgr.GetConfig())
if err != nil {
return err
}
r.clientSet = clientset
return ctrl.NewControllerManagedBy(mgr).
For(&entanglev1alpha1.VPN{}).
Complete(r)
}

View File

@ -29,7 +29,7 @@ type Webhook struct {
} }
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch //+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
//+kubebuilder:webhook:verbs=create;update,path=/mutate-entangle-kairos-x-io-v1alpha1-entanglement,mutating=true,failurePolicy=ignore,sideEffects=None,groups=core,resources=pods,versions=v1,name=mentanglement.kb.io,admissionReviewVersions={v1,v1alpha1} //+kubebuilder:webhook:verbs=create;update,path=/mutate-entangle-kairos-x-io-v1alpha1-entanglement,mutating=true,failurePolicy=fail,sideEffects=None,groups=core,resources=pods,versions=v1,name=mentanglement.kb.io,admissionReviewVersions={v1,v1alpha1}
var ( var (
EntanglementNameLabel = "entanglement.kairos.io/name" EntanglementNameLabel = "entanglement.kairos.io/name"

2
go.mod
View File

@ -1,6 +1,6 @@
module github.com/kairos-io/entangle module github.com/kairos-io/entangle
go 1.18 go 1.22
require ( require (
github.com/onsi/ginkgo v1.16.5 github.com/onsi/ginkgo v1.16.5

3
go.sum
View File

@ -197,6 +197,7 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -370,6 +371,7 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= 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 v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
@ -503,6 +505,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=

View File

@ -118,6 +118,14 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if err = (&controllers.VPNReconciler{
Client: mgr.GetClient(),
EntangleServiceImage: serviceImage,
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "VPN")
os.Exit(1)
}
//+kubebuilder:scaffold:builder //+kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {

16
tests/fixtures/vpn.yaml vendored Normal file
View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: entangle-system
type: Opaque
stringData:
network_token: b3RwOgogIGRodDoKICAgIGludGVydmFsOiA5MDAwCiAgICBrZXk6IFVSRDVaMkcySDNKSFVESVpYT1VXQkVPN1VEU0g2TUpGUzJGV01QM1dBRVhaMjZRUTJGUkEKICAgIGxlbmd0aDogMzIKICBjcnlwdG86CiAgICBpbnRlcnZhbDogOTAwMAogICAga2V5OiBKTVJKWVZKN0xFR0lZQktFVFNERzVSRFhESkFKM0dTWVJOUTNUTVRQUkpMUkwzWEZYUVpBCiAgICBsZW5ndGg6IDMyCnJvb206IFJYWlZSNURCN1VWVERGRDc0UzRBTEFKNllHRVFDVlQ0WE5VWExFQTRVM0FDN05ESFFLTVEKcmVuZGV6dm91czogYk9PR21WV0lCV1ptbXBtaW9PcXdhc0dyWExlaXpnTVkKbWRuczogUnN4ZWd6eGZTcFlRRUtqQk1lUEFQelROWUV5ZGRlemEKbWF4X21lc3NhZ2Vfc2l6ZTogMjA5NzE1MjAK
---
apiVersion: entangle.kairos.io/v1alpha1
kind: VPN
metadata:
name: test2
namespace: entangle-system
spec:
secretRef: "mysecret"