mirror of
https://github.com/kairos-io/entangle.git
synced 2025-04-27 19:17:25 +00:00
🌱 Add daemonset
Signed-off-by: mudler <mudler@c3os.io>
This commit is contained in:
parent
ca06cf47e4
commit
737bae9d77
9
PROJECT
9
PROJECT
@ -19,4 +19,13 @@ resources:
|
||||
webhooks:
|
||||
defaulting: true
|
||||
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"
|
||||
|
62
api/v1alpha1/vpn_types.go
Normal file
62
api/v1alpha1/vpn_types.go
Normal 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{})
|
||||
}
|
@ -136,3 +136,104 @@ func (in *EntanglementStatus) DeepCopy() *EntanglementStatus {
|
||||
in.DeepCopyInto(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
|
||||
}
|
||||
|
152
config/crd/bases/entangle.kairos.io_vpns.yaml
Normal file
152
config/crd/bases/entangle.kairos.io_vpns.yaml
Normal 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: {}
|
@ -3,17 +3,20 @@
|
||||
# It should be run by config/default
|
||||
resources:
|
||||
- bases/entangle.kairos.io_entanglements.yaml
|
||||
- bases/entangle.kairos.io_vpns.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizeresource
|
||||
|
||||
patchesStrategicMerge:
|
||||
# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix.
|
||||
# patches here are for enabling the conversion webhook for each CRD
|
||||
#- patches/webhook_in_entanglements.yaml
|
||||
#- patches/webhook_in_vpns.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizewebhookpatch
|
||||
|
||||
# [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix.
|
||||
# patches here are for enabling the CA injection for each CRD
|
||||
#- patches/cainjection_in_entanglements.yaml
|
||||
#- patches/cainjection_in_vpns.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
|
||||
|
||||
# the following config is for teaching kustomize how to do kustomization for CRDs.
|
||||
|
7
config/crd/patches/cainjection_in_vpns.yaml
Normal file
7
config/crd/patches/cainjection_in_vpns.yaml
Normal 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
|
16
config/crd/patches/webhook_in_vpns.yaml
Normal file
16
config/crd/patches/webhook_in_vpns.yaml
Normal 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
|
@ -23,6 +23,18 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
@ -61,3 +73,29 @@ rules:
|
||||
- get
|
||||
- patch
|
||||
- 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
|
||||
|
31
config/rbac/vpn_editor_role.yaml
Normal file
31
config/rbac/vpn_editor_role.yaml
Normal 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
|
27
config/rbac/vpn_viewer_role.yaml
Normal file
27
config/rbac/vpn_viewer_role.yaml
Normal 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
|
12
config/samples/entangle_v1alpha1_vpn.yaml
Normal file
12
config/samples/entangle_v1alpha1_vpn.yaml
Normal 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
|
@ -1,4 +1,5 @@
|
||||
## Append samples you want in your CSV to this file as resources ##
|
||||
resources:
|
||||
- entangle_v1alpha1_entanglement.yaml
|
||||
- entangle_v1alpha1_vpn.yaml
|
||||
#+kubebuilder:scaffold:manifestskustomizesamples
|
||||
|
87
controllers/daemonset.go
Normal file
87
controllers/daemonset.go
Normal 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,
|
||||
}
|
||||
}
|
@ -70,7 +70,7 @@ func (r *EntanglementReconciler) Reconcile(ctx context.Context, req ctrl.Request
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
desiredDeployment, err := r.genDeployment(ent,r.LogLevel)
|
||||
desiredDeployment, err := r.genDeployment(ent, r.LogLevel)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
114
controllers/vpn_controller.go
Normal file
114
controllers/vpn_controller.go
Normal 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)
|
||||
}
|
8
main.go
8
main.go
@ -118,6 +118,14 @@ func main() {
|
||||
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
|
||||
|
||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||
|
16
tests/fixtures/vpn.yaml
vendored
Normal file
16
tests/fixtures/vpn.yaml
vendored
Normal 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"
|
Loading…
Reference in New Issue
Block a user