external interfaces

This commit is contained in:
Stavros kois
2023-02-11 15:45:17 +02:00
parent 5c41cef570
commit 4c83b97371
9 changed files with 465 additions and 16 deletions

View File

@@ -0,0 +1,220 @@
suite: externalInterface metadata test
templates:
- common.yaml
release:
name: release-name
tests:
- it: should generate correct annotations without selector
set:
# Simulate middleware injection
ixExternalInterfacesConfiguration:
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens3s0", "ipam": {"type": "dhcp"}}'
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens4s0", "ipam": {"type": "dhcp"}}'
ixExternalInterfacesConfigurationNames:
- ix-release-name-0
- ix-release-name-1
scaleExternalInterface:
- hostInterface: enp0s3
ipam:
type: dhcp
- hostInterface: enp0s4
ipam:
type: dhcp
workload:
workload-name1:
enabled: true
primary: true
type: Deployment
podSpec:
containers:
container-name1:
enabled: true
primary: true
imageSelector: image
workload-name2:
enabled: true
primary: false
type: StatefulSet
podSpec:
containers:
container-name1:
enabled: true
primary: true
imageSelector: image
asserts:
- documentIndex: &deploymentDoc 2
isKind:
of: Deployment
- documentIndex: *deploymentDoc
isAPIVersion:
of: apps/v1
- documentIndex: *deploymentDoc
equal:
path: metadata.name
value: release-name-common-test
- documentIndex: *deploymentDoc
isSubset:
path: spec.template.metadata.annotations
content:
k8s.v1.cni.cncf.io/networks: ix-release-name-0, ix-release-name-1
- documentIndex: &statefulSetDoc 3
isKind:
of: StatefulSet
- documentIndex: *statefulSetDoc
isAPIVersion:
of: apps/v1
- documentIndex: *statefulSetDoc
equal:
path: metadata.name
value: release-name-common-test-workload-name2
- documentIndex: *statefulSetDoc
isNotSubset:
path: spec.template.metadata.annotations
content:
k8s.v1.cni.cncf.io/networks: ix-release-name-0, ix-release-name-1
- it: should generate correct annotations with targetSelectAll
set:
# Simulate middleware injection
ixExternalInterfacesConfiguration:
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens3s0", "ipam": {"type": "dhcp"}}'
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens4s0", "ipam": {"type": "dhcp"}}'
ixExternalInterfacesConfigurationNames:
- ix-release-name-0
- ix-release-name-1
scaleExternalInterface:
- hostInterface: enp0s3
ipam:
type: dhcp
targetSelectAll: true
- hostInterface: enp0s4
ipam:
type: dhcp
targetSelectAll: true
workload:
workload-name1:
enabled: true
primary: true
type: DaemonSet
podSpec:
containers:
container-name1:
enabled: true
primary: true
imageSelector: image
workload-name2:
enabled: true
primary: false
type: Job
podSpec:
containers:
container-name1:
enabled: true
primary: true
imageSelector: image
asserts:
- documentIndex: &daemonSetDoc 2
isKind:
of: DaemonSet
- documentIndex: *daemonSetDoc
isAPIVersion:
of: apps/v1
- documentIndex: *daemonSetDoc
equal:
path: metadata.name
value: release-name-common-test
- documentIndex: *daemonSetDoc
isSubset:
path: spec.template.metadata.annotations
content:
k8s.v1.cni.cncf.io/networks: ix-release-name-0, ix-release-name-1
- documentIndex: &jobDoc 3
isKind:
of: Job
- documentIndex: *jobDoc
isAPIVersion:
of: batch/v1
- documentIndex: *jobDoc
equal:
path: metadata.name
value: release-name-common-test-workload-name2
- documentIndex: *jobDoc
isSubset:
path: spec.template.metadata.annotations
content:
k8s.v1.cni.cncf.io/networks: ix-release-name-0, ix-release-name-1
- it: should generate correct annotations with targetSelector
set:
# Simulate middleware injection
ixExternalInterfacesConfiguration:
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens3s0", "ipam": {"type": "dhcp"}}'
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens4s0", "ipam": {"type": "dhcp"}}'
ixExternalInterfacesConfigurationNames:
- ix-release-name-0
- ix-release-name-1
scaleExternalInterface:
- hostInterface: enp0s3
ipam:
type: dhcp
targetSelector:
- workload-name1
- workload-name2
- hostInterface: enp0s4
ipam:
type: dhcp
targetSelector:
- workload-name1
workload:
workload-name1:
enabled: true
primary: true
type: DaemonSet
podSpec:
containers:
container-name1:
enabled: true
primary: true
imageSelector: image
workload-name2:
enabled: true
primary: false
type: CronJob
schedule: "*/1 * * * *"
podSpec:
containers:
container-name1:
enabled: true
primary: true
imageSelector: image
asserts:
- documentIndex: &daemonSetDoc 2
isKind:
of: DaemonSet
- documentIndex: *daemonSetDoc
isAPIVersion:
of: apps/v1
- documentIndex: *daemonSetDoc
equal:
path: metadata.name
value: release-name-common-test
- documentIndex: *daemonSetDoc
isSubset:
path: spec.template.metadata.annotations
content:
k8s.v1.cni.cncf.io/networks: ix-release-name-0, ix-release-name-1
- documentIndex: &cronJobDoc 3
isKind:
of: CronJob
- documentIndex: *cronJobDoc
isAPIVersion:
of: batch/v1
- documentIndex: *cronJobDoc
equal:
path: metadata.name
value: release-name-common-test-workload-name2
- documentIndex: *cronJobDoc
isSubset:
path: spec.jobTemplate.spec.template.metadata.annotations
content:
k8s.v1.cni.cncf.io/networks: ix-release-name-0

View File

@@ -0,0 +1,43 @@
suite: externalInterface name test
templates:
- common.yaml
release:
name: release-name
tests:
- it: should generate correct name NetworkAttachmentDefinition
set:
# Simulate middleware injection
ixExternalInterfacesConfiguration:
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens3s0", "ipam": {"type": "dhcp"}}'
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens4s0", "ipam": {"type": "dhcp"}}'
ixExternalInterfacesConfigurationNames:
- ix-release-name-0
- ix-release-name-1
scaleExternalInterface:
- hostInterface: enp0s3
ipam:
type: dhcp
- hostInterface: enp0s4
ipam:
type: dhcp
asserts:
- documentIndex: &networkDoc 0
isKind:
of: NetworkAttachmentDefinition
- documentIndex: *networkDoc
isAPIVersion:
of: k8s.cni.cncf.io/v1
- documentIndex: *networkDoc
equal:
path: metadata.name
value: ix-release-name-0
- documentIndex: &otherNetworkDoc 1
isKind:
of: NetworkAttachmentDefinition
- documentIndex: *otherNetworkDoc
isAPIVersion:
of: k8s.cni.cncf.io/v1
- documentIndex: *otherNetworkDoc
equal:
path: metadata.name
value: ix-release-name-1

View File

@@ -1,6 +1,8 @@
suite: external interface validation test
templates:
- common.yaml
release:
name: release-name
tests:
- it: should fail with targetSelector not a list
set:
@@ -112,3 +114,24 @@ tests:
asserts:
- failedTemplate:
errorMessage: External Interface - Expected non-empty <destination> in <staticRoutes>
- it: should fail with empty ixExternalInterfaceConfigurationNames when interface is defined
set:
# Simulate middleware injection
ixExternalInterfacesConfiguration:
- '{"cniVersion": "0.3.1", "name": "ix-release-name-0", "type": "macvlan", "master": "ens3s0", "ipam": {"type": "dhcp"}}'
ixExternalInterfaceConfigurationNames: []
scaleExternalInterface:
- hostInterface: enp0s3
ipam:
type: dhcp
workload:
workload-name1:
enabled: true
primary: true
type: CronJob
schedule: "*/1 * * * *"
podSpec: {}
asserts:
- failedTemplate:
errorMessage: External Interface - Expected non empty <ixExternalInterfaceConfigurationNames>

View File

@@ -17,6 +17,7 @@
- Containers: `$ContainerName`
- ConfigMap: `$FullName-$ConfigMapName`
- Secret: `$FullName-$SecretName`
- Scale External Interface: `ix-$ReleaseName-$index`
> Full name -> `$ReleaseName-$ChartName`
> Any name that exceeds 63 characters, will throw an error

View File

@@ -0,0 +1,47 @@
# Scale External Interface
| Key | Type | Required | Helm Template | Default | Description |
| :------------------------------------------------ | :-------: | :-----------------------------: | :-----------: | :-----: | :------------------------------------------------------------------------------ |
| scaleExternalInterface | `list` | ❌ | ❌ | `[]` | Define the external interfaces as list |
| scaleExternalInterface.targetSelectAll | `boolean` | ❌ | ❌ | `false` | Whether to add the annotation for this external interface to all workloads |
| scaleExternalInterface.targetSelector | `list` | ❌ | ❌ | `[]` | Which workloads to add the annotations |
| scaleExternalInterface.hostInterface | `string` | ✅ | ❌ | `""` | Define the hostInterface, (options in GUI populated from Middleware references) |
| scaleExternalInterface.ipam | `dict` | ✅ | ❌ | `{}` | Define the ipam |
| scaleExternalInterface.ipam.type | `string` | ✅ | ❌ | `""` | Define the ipam type (dchp, static) |
| scaleExternalInterface.staticIPConfiguration | `list` | ✅ (Only when static ipam type) | ❌ | `[]` | Define static IP Configuration (Only with static ipam type) |
| scaleExternalInterface.staticIPConfiguration.[IP] | `string` | ✅ | ❌ | `""` | Define the static IP (Only with static ipam type) |
| scaleExternalInterface.staticRoutes | `list` | ❌ | ❌ | `[]` | Define static routes (Only with static ipam type) |
| scaleExternalInterface.staticRoutes.destination | `string` | ✅ | ❌ | `""` | Define the static destination (Only with static ipam type) |
| scaleExternalInterface.staticRoutes.gateway | `string` | ✅ | ❌ | `""` | Define the static gateway (Only with static ipam type) |
> When `targetSelectAll` is `true`, it will add the annotations to all pods (`targetSelector` is ignored in this case)
> When `targetSelector` is a list, each entry is a string, referencing the pod(s) name that will add the annotations
> When `targetSelector` is a empty, it will add the annotations to the primary pod
---
Appears in:
- `.Values.scaleExternalInterface`
---
Naming scheme:
- `ix-$ReleaseName-$index` (ix-release-name-0)
---
Examples:
```yaml
scaleExternalInterface:
- hostInterface: ""
ipam:
type: ""
staticRoutes: []
staticIPConfigurations: []
# targetSelectAll: false
targetSelector:
- workload-name
```

View File

@@ -0,0 +1,34 @@
{{/* Network Attachment Definition Class */}}
{{/* Call this template:
{{ include "ix.v1.common.class.networkAttachmentDefinition" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the template. It is used to access the global context.
objectData:
name: The name of the Network Attachment Definition.
labels: The labels of the Network Attachment Definition.
annotations: The annotations of the Network Attachment Definition.
config: The config of the interface
*/}}
{{- define "ix.v1.common.class.networkAttachmentDefinition" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData }}
---
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: {{ $objectData.name }}
{{- $labels := (include "ix.v1.common.lib.metadata.allLabels" $rootCtx | fromYaml) | default dict -}}
{{- with (include "ix.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "labels" $labels) | trim) }}
labels:
{{- . | nindent 4 }}
{{- end -}}
{{- $annotations := (include "ix.v1.common.lib.metadata.allAnnotations" $rootCtx | fromYaml) | default dict -}}
{{- with (include "ix.v1.common.lib.metadata.render" (dict "rootCtx" $rootCtx "annotations" $annotations) | trim) }}
annotations:
{{- . | nindent 4 }}
{{- end }}
spec:
config: {{ $objectData.config | squote }}
{{- end -}}

View File

@@ -0,0 +1,52 @@
{{/* External Interface Annotations that are added to podSpec */}}
{{/* Call this template:
{{ include "ix.v1.common.lib.metadata.externalInterfacePodAnnotations" (dict "rootCtx" $ "podShortName" $podShortName) }}
rootCtx is the root context of the chart
objectData is object containing the data of the pod
*/}}
{{- define "ix.v1.common.lib.metadata.externalInterfacePodAnnotations" -}}
{{- $objectData := .objectData -}}
{{- $rootCtx := .rootCtx -}}
{{- $ifaceIndexes := list -}}
{{- range $index, $iface := $rootCtx.Values.scaleExternalInterface -}}
{{/* If targetSelectAll is set append the index */}}
{{- if .targetSelectAll -}}
{{- $ifaceIndexes = mustAppend $ifaceIndexes $index -}}
{{/* Else If targetSelector is set and pod is selected append the index */}}
{{- else if and .targetSelector (mustHas $objectData.shortName .targetSelector) -}}
{{- $ifaceIndexes = mustAppend $ifaceIndexes $index -}}
{{/* Else If none of the above, but pod is primary append the index */}}
{{- else if $objectData.primary -}}
{{- $ifaceIndexes = mustAppend $ifaceIndexes $index -}}
{{- end -}}
{{- end -}}
{{- $ifaceNames := list -}}
{{- if $rootCtx.Values.ixExternalInterfacesConfiguration -}}
{{- with $rootCtx.Values.ixExternalInterfacesConfigurationNames -}}
{{- range $ifaceName := . -}}
{{/* Get the index by splitting the iFaceName (ix-RELEASE-NAME-0) */}}
{{- $index := splitList "-" $ifaceName -}}
{{/* And pick the last item on the list */}}
{{- $index = mustLast $index -}}
{{/* If the index is in the list of indexes to be added, append the name */}}
{{- if mustHas (int $index) $ifaceIndexes -}}
{{- $ifaceNames = mustAppend $ifaceNames $ifaceName -}}
{{- end -}}
{{- end -}}
{{- else -}}
{{- fail "External Interface - Expected non empty <ixExternalInterfaceConfigurationNames>" -}}
{{- end -}}
{{- end -}}
{{/* If we have ifaceNames, then add the annotations to the pod calling this template */}}
{{- if $ifaceNames }}
k8s.v1.cni.cncf.io/networks: {{ join ", " $ifaceNames }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,32 @@
{{/* External Interface Spawwner */}}
{{/* Call this template:
{{ include "ix.v1.common.spawner.externalInterface" $ -}}
*/}}
{{- define "ix.v1.common.spawner.externalInterface" -}}
{{- range $iface := .Values.scaleExternalInterface -}}
{{- include "ix.v1.common.lib.externalInterface.validation" (dict "objectData" $iface) -}}
{{- end -}}
{{/* Now we have validated interfaces, render the objects */}}
{{- range $index, $interface := .Values.ixExternalInterfacesConfiguration -}}
{{- $objectData := dict -}}
{{/* Create a copy of the interface and put it in objectData.config */}}
{{- $_ := set $objectData "config" (mustDeepCopy $interface) -}}
{{- $objectName := (printf "ix-%s-%v" $.Release.Name $index) -}}
{{/* Perform validations */}}
{{- include "ix.v1.common.lib.chart.names.validation" (dict "name" $objectName) -}}
{{/* Set the name of the object to objectData.name */}}
{{- $_ := set $objectData "name" $objectName -}}
{{/* Call class to create the object */}}
{{- include "ix.v1.common.class.networkAttachmentDefinition" (dict "rootCtx" $ "objectData" $objectData) -}}
{{- end -}}
{{- end -}}

View File

@@ -1,3 +1,4 @@
# TODO: Docs
# -- Global values
global:
# -- Set additional global labels
@@ -11,6 +12,7 @@ global:
# -- Minimum nodePort value
minNodePort: 9000
# TODO: Docs
fallbackDefaults:
# -- Define a storageClassName that will be used for all PVCs
# Can be overruled per PVC
@@ -42,6 +44,7 @@ ixCertificates: []
# Only for reference here
ixVolumes: []
# TODO: Docs
# -- Image values
image:
# -- Image repository
@@ -51,8 +54,9 @@ image:
# -- Image pull policy
pullPolicy: IfNotPresent
# TODO: Docs
TZ: UTC
# TODO: Docs
# -- Security Context
securityContext:
# -- Container security context for all containers
@@ -78,6 +82,7 @@ securityContext:
supplementalGroups: []
sysctls: []
# TODO: Docs
containerOptions:
# -- Resources
# Can be overruled per container
@@ -97,7 +102,7 @@ containerOptions:
NVIDIA_CAPS:
- all
# -- Options for all pods
# -- Options for all pods # TODO: Docs
# Can be overruled per pod
podOptions:
enableServiceLinks: false
@@ -288,19 +293,11 @@ scaleGPU:
pod-name:
- container-name
# -- SCALE External Interfaces
scaleExternalInterfaces:
- hostInterface: ""
ipam:
type: ""
staticRoutes: []
staticIPConfigurations: []
# targetSelector: all
targetSelector:
- pod-name
# -- (docs/scaleExternalInterface.md)
scaleExternalInterface: []
# -- SCALE Certificates
scaleCerts:
# -- SCALE Certificate
scaleCert:
# -- Certificate name
cert-name:
# -- Enables the certificate
@@ -320,8 +317,8 @@ scaleCerts:
certPath: ""
keyPath: ""
# -- Devices
devices:
# -- Device
device:
# -- Device name
device-name:
# -- Enables the device