mirror of
https://github.com/kairos-io/entangle.git
synced 2025-11-27 19:12:52 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2250450b88 | ||
|
|
b4a78705dd | ||
|
|
b25f31d789 | ||
|
|
daab27404c | ||
|
|
1da47ac24f | ||
|
|
297f557a04 | ||
|
|
c3cd5f5654 |
7
Makefile
7
Makefile
@@ -275,4 +275,9 @@ unit-tests: test_deps
|
|||||||
e2e-tests:
|
e2e-tests:
|
||||||
KUBE_VERSION=${KUBE_VERSION} $(ROOT_DIR)/script/test.sh
|
KUBE_VERSION=${KUBE_VERSION} $(ROOT_DIR)/script/test.sh
|
||||||
|
|
||||||
kind-e2e-tests: kind-setup install undeploy-dev deploy-dev e2e-tests
|
kind-e2e-tests: kind-setup install undeploy-dev deploy-dev e2e-tests
|
||||||
|
|
||||||
|
kubesplit: manifests kustomize
|
||||||
|
rm -rf helm-chart
|
||||||
|
mkdir helm-chart
|
||||||
|
$(KUSTOMIZE) build config/default | kubesplit -helm helm-chart
|
||||||
91
README.md
91
README.md
@@ -1,80 +1,33 @@
|
|||||||
# entangle
|
# entangle
|
||||||
// TODO(user): Add simple overview of use/purpose
|
|
||||||
|
|
||||||
## Description
|
| :exclamation: | This is experimental! |
|
||||||
// TODO(user): An in-depth paragraph about your project and overview of use
|
|-|:-|
|
||||||
|
|
||||||
## Getting Started
|
This is the Kairos entangle Kubernetes Native Extension.
|
||||||
You’ll need a Kubernetes cluster to run against. You can use [KIND](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster.
|
|
||||||
**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).
|
|
||||||
|
|
||||||
### Running on the cluster
|
To install, use helm:
|
||||||
1. Install Instances of Custom Resources:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
kubectl apply -f config/samples/
|
|
||||||
```
|
```
|
||||||
|
# Adds the kairos repo to helm
|
||||||
|
$ helm repo add kairos https://kairos-io.github.io/helm-charts
|
||||||
|
"kairos" has been added to your repositories
|
||||||
|
$ helm repo update
|
||||||
|
Hang tight while we grab the latest from your chart repositories...
|
||||||
|
...Successfully got an update from the "kairos" chart repository
|
||||||
|
Update Complete. ⎈Happy Helming!⎈
|
||||||
|
|
||||||
2. Build and push your image to the location specified by `IMG`:
|
# Install the CRD chart
|
||||||
|
$ helm install kairos-crd kairos/kairos-crds
|
||||||
```sh
|
NAME: kairos-crd
|
||||||
make docker-build docker-push IMG=<some-registry>/entangle:tag
|
LAST DEPLOYED: Tue Sep 6 20:35:34 2022
|
||||||
|
NAMESPACE: default
|
||||||
|
STATUS: deployed
|
||||||
|
REVISION: 1
|
||||||
|
TEST SUITE: None
|
||||||
|
|
||||||
|
# Installs entangle
|
||||||
|
$ helm install kairos-entangle kairos/entangle
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Deploy the controller to the cluster with the image specified by `IMG`:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make deploy IMG=<some-registry>/entangle:tag
|
|
||||||
```
|
|
||||||
|
|
||||||
### Uninstall CRDs
|
|
||||||
To delete the CRDs from the cluster:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make uninstall
|
|
||||||
```
|
|
||||||
|
|
||||||
### Undeploy controller
|
|
||||||
UnDeploy the controller to the cluster:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make undeploy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
// TODO(user): Add detailed information on how you would like others to contribute to this project
|
|
||||||
|
|
||||||
### How it works
|
|
||||||
This project aims to follow the Kubernetes [Operator pattern](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)
|
|
||||||
|
|
||||||
It uses [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/)
|
|
||||||
which provides a reconcile function responsible for synchronizing resources untile the desired state is reached on the cluster
|
|
||||||
|
|
||||||
### Test It Out
|
|
||||||
1. Install the CRDs into the cluster:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Run your controller (this will run in the foreground, so switch to a new terminal if you want to leave it running):
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make run
|
|
||||||
```
|
|
||||||
|
|
||||||
**NOTE:** You can also run this in one step by running: `make install run`
|
|
||||||
|
|
||||||
### Modifying the API definitions
|
|
||||||
If you are editing the API definitions, generate the manifests such as CRs or CRDs using:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make manifests
|
|
||||||
```
|
|
||||||
|
|
||||||
**NOTE:** Run `make --help` for more information on all potential `make` targets
|
|
||||||
|
|
||||||
More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,14 @@ type EntanglementSpec struct {
|
|||||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
// Important: Run "make" to regenerate code after modifying this file
|
||||||
|
|
||||||
ServiceUUID string `json:"serviceUUID,omitempty"`
|
ServiceUUID string `json:"serviceUUID,omitempty"`
|
||||||
ServiceRef *string `json:"serviceRef,omitempty"`
|
ServiceRef *string `json:"serviceRef,omitempty"`
|
||||||
SecretRef *string `json:"secretRef,omitempty"`
|
SecretRef *string `json:"secretRef,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host string `json:"host,omitempty"`
|
||||||
Port string `json:"port,omitempty"`
|
Port string `json:"port,omitempty"`
|
||||||
HostNetwork bool `json:"hostNetwork,omitempty"`
|
HostNetwork bool `json:"hostNetwork,omitempty"`
|
||||||
Inbound bool `json:"inbound,omitempty"`
|
Inbound bool `json:"inbound,omitempty"`
|
||||||
|
Envs []v1.EnvVar `json:"env,omitempty"`
|
||||||
// +kubebuilder:validation:Optional
|
// +kubebuilder:validation:Optional
|
||||||
ServiceSpec *v1.ServiceSpec `json:"serviceSpec,omitEmpty"`
|
ServiceSpec *v1.ServiceSpec `json:"serviceSpec,omitEmpty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,13 @@ func (in *EntanglementSpec) DeepCopyInto(out *EntanglementSpec) {
|
|||||||
*out = new(string)
|
*out = new(string)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.Envs != nil {
|
||||||
|
in, out := &in.Envs, &out.Envs
|
||||||
|
*out = make([]v1.EnvVar, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
if in.ServiceSpec != nil {
|
if in.ServiceSpec != nil {
|
||||||
in, out := &in.ServiceSpec, &out.ServiceSpec
|
in, out := &in.ServiceSpec, &out.ServiceSpec
|
||||||
*out = new(v1.ServiceSpec)
|
*out = new(v1.ServiceSpec)
|
||||||
|
|||||||
@@ -35,6 +35,110 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
description: EntanglementSpec defines the desired state of Entanglement
|
description: EntanglementSpec defines the desired state of Entanglement
|
||||||
properties:
|
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
|
||||||
host:
|
host:
|
||||||
type: string
|
type: string
|
||||||
hostNetwork:
|
hostNetwork:
|
||||||
@@ -22,7 +22,7 @@ func genOwner(ent entanglev1alpha1.Entanglement) []metav1.OwnerReference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *EntanglementReconciler) genDeployment(ent entanglev1alpha1.Entanglement) (*appsv1.Deployment, error) {
|
func (r *EntanglementReconciler) genDeployment(ent entanglev1alpha1.Entanglement, logLevel string) (*appsv1.Deployment, error) {
|
||||||
objMeta := metav1.ObjectMeta{
|
objMeta := metav1.ObjectMeta{
|
||||||
Name: ent.Name,
|
Name: ent.Name,
|
||||||
Namespace: ent.Namespace,
|
Namespace: ent.Namespace,
|
||||||
@@ -40,25 +40,26 @@ func (r *EntanglementReconciler) genDeployment(ent entanglev1alpha1.Entanglement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := ent.Spec.Envs
|
||||||
|
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{
|
expose := v1.Container{
|
||||||
ImagePullPolicy: v1.PullAlways,
|
ImagePullPolicy: v1.PullAlways,
|
||||||
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
|
SecurityContext: &v1.SecurityContext{Privileged: &privileged},
|
||||||
Name: "entanglement",
|
Name: "entanglement",
|
||||||
Image: r.EntangleServiceImage,
|
Image: r.EntangleServiceImage,
|
||||||
Env: []v1.EnvVar{
|
Env: v,
|
||||||
{
|
Command: []string{"/usr/bin/edgevpn"},
|
||||||
Name: "EDGEVPNTOKEN",
|
|
||||||
ValueFrom: &v1.EnvVarSource{
|
|
||||||
SecretKeyRef: &v1.SecretKeySelector{
|
|
||||||
Key: "network_token",
|
|
||||||
LocalObjectReference: v1.LocalObjectReference{
|
|
||||||
Name: *ent.Spec.SecretRef,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Command: []string{"/usr/bin/edgevpn"},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := "service-add"
|
cmd := "service-add"
|
||||||
@@ -96,9 +97,9 @@ func (r *EntanglementReconciler) genDeployment(ent entanglev1alpha1.Entanglement
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ent.Spec.ServiceRef != nil {
|
if ent.Spec.ServiceRef != nil {
|
||||||
expose.Args = []string{cmd, "--log-level", "debug", ent.Spec.ServiceUUID, fmt.Sprintf("%s:%s", fmt.Sprintf("%s.svc.cluster.local", svc.Name), ent.Spec.Port)}
|
expose.Args = []string{cmd, "--log-level", logLevel, ent.Spec.ServiceUUID, fmt.Sprintf("%s:%s", fmt.Sprintf("%s.svc.cluster.local", svc.Name), ent.Spec.Port)}
|
||||||
} else {
|
} else {
|
||||||
expose.Args = []string{cmd, "--log-level", "debug", ent.Spec.ServiceUUID, fmt.Sprintf("%s:%s", ent.Spec.Host, ent.Spec.Port)}
|
expose.Args = []string{cmd, "--log-level", logLevel, ent.Spec.ServiceUUID, fmt.Sprintf("%s:%s", ent.Spec.Host, ent.Spec.Port)}
|
||||||
}
|
}
|
||||||
|
|
||||||
pod := v1.PodSpec{
|
pod := v1.PodSpec{
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ import (
|
|||||||
type EntanglementReconciler struct {
|
type EntanglementReconciler struct {
|
||||||
clientSet *kubernetes.Clientset
|
clientSet *kubernetes.Clientset
|
||||||
client.Client
|
client.Client
|
||||||
Scheme *runtime.Scheme
|
Scheme *runtime.Scheme
|
||||||
EntangleServiceImage string
|
EntangleServiceImage, LogLevel string
|
||||||
}
|
}
|
||||||
|
|
||||||
//+kubebuilder:rbac:groups=entangle.kairos.io,resources=entanglements,verbs=get;list;watch;create;update;patch;delete
|
//+kubebuilder:rbac:groups=entangle.kairos.io,resources=entanglements,verbs=get;list;watch;create;update;patch;delete
|
||||||
@@ -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)
|
desiredDeployment, err := r.genDeployment(ent,r.LogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -24,7 +25,7 @@ type Webhook struct {
|
|||||||
clientSet *kubernetes.Clientset
|
clientSet *kubernetes.Clientset
|
||||||
Scheme *runtime.Scheme
|
Scheme *runtime.Scheme
|
||||||
|
|
||||||
SidecarImage string
|
SidecarImage, LogLevel string
|
||||||
}
|
}
|
||||||
|
|
||||||
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
|
//+kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
|
||||||
@@ -34,8 +35,10 @@ var (
|
|||||||
EntanglementNameLabel = "entanglement.kairos.io/name"
|
EntanglementNameLabel = "entanglement.kairos.io/name"
|
||||||
EntanglementServiceLabel = "entanglement.kairos.io/service"
|
EntanglementServiceLabel = "entanglement.kairos.io/service"
|
||||||
EntanglementDirectionLabel = "entanglement.kairos.io/direction"
|
EntanglementDirectionLabel = "entanglement.kairos.io/direction"
|
||||||
|
EntanglementNetHost = "entanglement.kairos.io/nethost"
|
||||||
EntanglementPortLabel = "entanglement.kairos.io/target_port"
|
EntanglementPortLabel = "entanglement.kairos.io/target_port"
|
||||||
EntanglementHostLabel = "entanglement.kairos.io/host"
|
EntanglementHostLabel = "entanglement.kairos.io/host"
|
||||||
|
EnvPrefix = "entanglement.kairos.io/env."
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *Webhook) SetupWebhookWithManager(mgr manager.Manager) error {
|
func (w *Webhook) SetupWebhookWithManager(mgr manager.Manager) error {
|
||||||
@@ -55,34 +58,77 @@ func (w *Webhook) Mutate(ctx context.Context, request admission.Request, object
|
|||||||
_ = log.FromContext(ctx)
|
_ = log.FromContext(ctx)
|
||||||
|
|
||||||
pod := object.(*corev1.Pod)
|
pod := object.(*corev1.Pod)
|
||||||
entanglementName, exists := pod.Labels[EntanglementNameLabel]
|
|
||||||
|
// Let user use both label and annotations
|
||||||
|
info := make(map[string]string)
|
||||||
|
|
||||||
|
// Annotations take precedence
|
||||||
|
for k, v := range pod.Labels {
|
||||||
|
info[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// Annotations take precedence
|
||||||
|
for k, v := range pod.Annotations {
|
||||||
|
info[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
entanglementName, exists := info[EntanglementNameLabel]
|
||||||
if !exists {
|
if !exists {
|
||||||
return admission.Allowed("")
|
return admission.Allowed("")
|
||||||
}
|
}
|
||||||
|
|
||||||
entanglementPort, exists := pod.Labels[EntanglementPortLabel]
|
envs := []corev1.EnvVar{
|
||||||
|
{
|
||||||
|
Name: "EDGEVPNTOKEN",
|
||||||
|
ValueFrom: &corev1.EnvVarSource{
|
||||||
|
SecretKeyRef: &corev1.SecretKeySelector{
|
||||||
|
Key: "network_token",
|
||||||
|
LocalObjectReference: corev1.LocalObjectReference{
|
||||||
|
Name: entanglementName,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
|
||||||
|
for k, v := range info {
|
||||||
|
if strings.HasPrefix(k, EnvPrefix) {
|
||||||
|
env := strings.ReplaceAll(k, EnvPrefix, "")
|
||||||
|
envs = append(envs, corev1.EnvVar{Name: env, Value: v})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entanglementPort, exists := info[EntanglementPortLabel]
|
||||||
if !exists {
|
if !exists {
|
||||||
return admission.Allowed("")
|
return admission.Allowed("")
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := "service-connect"
|
cmd := "service-connect"
|
||||||
entanglementDirection, exists := pod.Labels[EntanglementDirectionLabel]
|
entanglementDirection, exists := info[EntanglementDirectionLabel]
|
||||||
if exists && entanglementDirection == "entangle" {
|
if exists && entanglementDirection == "entangle" {
|
||||||
cmd = "service-add"
|
cmd = "service-add"
|
||||||
}
|
}
|
||||||
|
|
||||||
host := "127.0.0.1"
|
host := "127.0.0.1"
|
||||||
entanglementHost, exists := pod.Labels[EntanglementHostLabel]
|
entanglementHost, exists := info[EntanglementHostLabel]
|
||||||
if exists && entanglementHost != "" {
|
if exists && entanglementHost != "" {
|
||||||
host = entanglementHost
|
host = entanglementHost
|
||||||
}
|
}
|
||||||
|
|
||||||
entanglementService, exists := pod.Labels[EntanglementServiceLabel]
|
entanglementService, exists := info[EntanglementServiceLabel]
|
||||||
if !exists {
|
if !exists {
|
||||||
return admission.Allowed("")
|
return admission.Allowed("")
|
||||||
}
|
}
|
||||||
|
|
||||||
podCopy := pod.DeepCopy()
|
podCopy := pod.DeepCopy()
|
||||||
|
|
||||||
|
hostNetwork, exists := info[EntanglementNetHost]
|
||||||
|
// By default it injects hostnetwork, however if set to false it does enforces it to false
|
||||||
|
if exists && hostNetwork == "false" {
|
||||||
|
podCopy.Spec.HostNetwork = false
|
||||||
|
} else {
|
||||||
|
podCopy.Spec.HostNetwork = true
|
||||||
|
}
|
||||||
|
|
||||||
secret, err := w.clientSet.CoreV1().Secrets(request.Namespace).Get(context.Background(), entanglementName, v1.GetOptions{})
|
secret, err := w.clientSet.CoreV1().Secrets(request.Namespace).Get(context.Background(), entanglementName, v1.GetOptions{})
|
||||||
if err != nil || secret == nil {
|
if err != nil || secret == nil {
|
||||||
return admission.Denied("entanglement secret not found: " + entanglementName + err.Error())
|
return admission.Denied("entanglement secret not found: " + entanglementName + err.Error())
|
||||||
@@ -99,20 +145,8 @@ func (w *Webhook) Mutate(ctx context.Context, request admission.Request, object
|
|||||||
servingContainer := corev1.Container{
|
servingContainer := corev1.Container{
|
||||||
ImagePullPolicy: corev1.PullAlways,
|
ImagePullPolicy: corev1.PullAlways,
|
||||||
Command: []string{"/usr/bin/edgevpn"},
|
Command: []string{"/usr/bin/edgevpn"},
|
||||||
Args: []string{cmd, entanglementService, fmt.Sprintf("%s:%s", host, entanglementPort)},
|
Args: []string{cmd, entanglementService, fmt.Sprintf("%s:%s", host, entanglementPort), "--log-level", w.LogLevel},
|
||||||
Env: []corev1.EnvVar{
|
Env: envs,
|
||||||
{
|
|
||||||
Name: "EDGEVPNTOKEN",
|
|
||||||
ValueFrom: &corev1.EnvVarSource{
|
|
||||||
SecretKeyRef: &corev1.SecretKeySelector{
|
|
||||||
Key: "network_token",
|
|
||||||
LocalObjectReference: corev1.LocalObjectReference{
|
|
||||||
Name: entanglementName,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SecurityContext: &corev1.SecurityContext{Privileged: &privileged},
|
SecurityContext: &corev1.SecurityContext{Privileged: &privileged},
|
||||||
Name: "entanglement",
|
Name: "entanglement",
|
||||||
Image: w.SidecarImage,
|
Image: w.SidecarImage,
|
||||||
|
|||||||
11
main.go
11
main.go
@@ -57,8 +57,13 @@ func main() {
|
|||||||
var metricsAddr string
|
var metricsAddr string
|
||||||
var enableLeaderElection bool
|
var enableLeaderElection bool
|
||||||
var probeAddr string
|
var probeAddr string
|
||||||
|
var serviceImage string
|
||||||
|
var logLevel string
|
||||||
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
|
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
|
||||||
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
|
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
|
||||||
|
flag.StringVar(&serviceImage, "service-image", defaultImage, "The image used to create services.")
|
||||||
|
flag.StringVar(&logLevel, "service-log-level", "debug", "The log level of the sidecar container.")
|
||||||
|
|
||||||
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
|
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
|
||||||
"Enable leader election for controller manager. "+
|
"Enable leader election for controller manager. "+
|
||||||
"Enabling this will ensure there is only one active controller manager.")
|
"Enabling this will ensure there is only one active controller manager.")
|
||||||
@@ -97,15 +102,17 @@ func main() {
|
|||||||
if err = (&controllers.EntanglementReconciler{
|
if err = (&controllers.EntanglementReconciler{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
Scheme: mgr.GetScheme(),
|
Scheme: mgr.GetScheme(),
|
||||||
EntangleServiceImage: defaultImage,
|
EntangleServiceImage: serviceImage,
|
||||||
|
LogLevel: logLevel,
|
||||||
}).SetupWithManager(mgr); err != nil {
|
}).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "Entanglement")
|
setupLog.Error(err, "unable to create controller", "controller", "Entanglement")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if err = (&webhooks.Webhook{
|
if err = (&webhooks.Webhook{
|
||||||
Client: mgr.GetClient(),
|
Client: mgr.GetClient(),
|
||||||
SidecarImage: defaultImage,
|
SidecarImage: serviceImage,
|
||||||
Scheme: mgr.GetScheme(),
|
Scheme: mgr.GetScheme(),
|
||||||
|
LogLevel: logLevel,
|
||||||
}).SetupWebhookWithManager(mgr); err != nil {
|
}).SetupWebhookWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create webhook", "webhook", "Pod")
|
setupLog.Error(err, "unable to create webhook", "webhook", "Pod")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user