Add omec pfcp agent helm chart

Change-Id: I243f2cef484f61658156d0e8bd7bb70ef4c7358a
diff --git a/omec/omec-pfcp-agent/templates/_helpers.tpl b/omec/omec-pfcp-agent/templates/_helpers.tpl
new file mode 100644
index 0000000..e9bbc00
--- /dev/null
+++ b/omec/omec-pfcp-agent/templates/_helpers.tpl
@@ -0,0 +1,48 @@
+{{- /*
+
+# Copyright 2019-present Open Networking Foundation
+#
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+
+*/ -}}
+
+{{/*
+Renders a set of standardised labels.
+*/}}
+{{- define "omec-pfcp-agent.metadata_labels" -}}
+{{- $application := index . 0 -}}
+{{- $context := index . 1 -}}
+release: {{ $context.Release.Name }}
+app: {{ $application }}
+{{- end -}}
+
+{{/*
+Render the given template.
+*/}}
+{{- define "omec-pfcp-agent.template" -}}
+{{- $name := index . 0 -}}
+{{- $context := index . 1 -}}
+{{- $last := base $context.Template.Name }}
+{{- $wtf := $context.Template.Name | replace $last $name -}}
+{{ include $wtf $context }}
+{{- end -}}
+
+{{/*
+Render init container for coredump.
+*/}}
+{{- define "omec-pfcp-agent.coredump_init" -}}
+{{- $pod := index . 0 -}}
+{{- $context := index . 1 -}}
+- name: {{ $pod }}-coredump-init
+  image: {{ $context.Values.images.tags.init | quote }}
+  imagePullPolicy: {{ $context.Values.images.pullPolicy }}
+  securityContext:
+    privileged: true
+    runAsUser: 0
+  command: ["bash", "-xc"]
+  args:
+    - echo '/tmp/coredump/core.%h.%e.%t' > /mnt/host-rootfs/proc/sys/kernel/core_pattern
+  volumeMounts:
+    - name: host-rootfs
+      mountPath: /mnt/host-rootfs
+{{- end -}}
diff --git a/omec/omec-pfcp-agent/templates/bin/_pfcp-agent-run.sh.tpl b/omec/omec-pfcp-agent/templates/bin/_pfcp-agent-run.sh.tpl
new file mode 100644
index 0000000..b39bb56
--- /dev/null
+++ b/omec/omec-pfcp-agent/templates/bin/_pfcp-agent-run.sh.tpl
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# Copyright 2019 Intel Corporation
+# Copyright 2019-present Open Networking Foundation
+#
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+
+set -ex
+
+{{- if .Values.config.coreDump.enabled }}
+cp /bin/ngic_dataplane /tmp/coredump/
+{{- end }}
+
+mkdir -p /opt/dp/config
+cd /opt/dp/config
+cp /etc/dp/config/{cdr.cfg,dp_config.cfg,interface.cfg} .
+
+sed -i "s/DP_ADDR/$POD_IP/g" interface.cfg
+
+source dp_config.cfg
+ngic_dataplane $EAL_ARGS -- $APP_ARGS
diff --git a/omec/omec-pfcp-agent/templates/bin/_pfcp-agent-setup-af-iface.sh.tpl b/omec/omec-pfcp-agent/templates/bin/_pfcp-agent-setup-af-iface.sh.tpl
new file mode 100644
index 0000000..bd65a23
--- /dev/null
+++ b/omec/omec-pfcp-agent/templates/bin/_pfcp-agent-setup-af-iface.sh.tpl
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# Copyright 2019 Intel Corporation
+# Copyright 2019-present Open Networking Foundation
+#
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+
+set -ex
+
+UL_IFACE="{{ .Values.config.pfcpAgent.s1u.device }}-veth"
+DL_IFACE="{{ .Values.config.pfcpAgent.sgi.device }}-veth"
+
+if ! ip link show $UL_IFACE; then
+    s1u_mac=$(ip addr show dev s1u-net | awk '$1=="link/ether"{print $2}')
+    ip link add $UL_IFACE type veth peer name l_$UL_IFACE
+    ip link set $UL_IFACE up
+    ip link set l_$UL_IFACE up
+    ip link set dev $UL_IFACE address $s1u_mac
+fi
+if ! ip link show $DL_IFACE; then
+    sgi_mac=$(ip addr show dev sgi-net | awk '$1=="link/ether"{print $2}')
+    ip link add $DL_IFACE type veth peer name l_$DL_IFACE
+    ip link set $DL_IFACE up
+    ip link set l_$DL_IFACE up
+    ip link set dev $DL_IFACE address $sgi_mac
+fi
+
+if ! ip addr show $UL_IFACE | grep inet; then
+    s1u_ip=$(ip addr show s1u-net | grep inet | grep -v inet6 | awk '{print $2}')
+    ip addr add $s1u_ip dev $UL_IFACE
+fi
+if ! ip addr show $DL_IFACE | grep inet; then
+    sgi_ip=$(ip addr show sgi-net | grep inet | grep -v inet6 | awk '{print $2}')
+    ip addr add $sgi_ip dev $DL_IFACE
+fi
+
+ip a
diff --git a/omec/omec-pfcp-agent/templates/configmap-pfcp-agent.yaml b/omec/omec-pfcp-agent/templates/configmap-pfcp-agent.yaml
new file mode 100644
index 0000000..8d32517
--- /dev/null
+++ b/omec/omec-pfcp-agent/templates/configmap-pfcp-agent.yaml
@@ -0,0 +1,74 @@
+{{/*
+# Copyright 2019-present Open Networking Foundation
+# Copyright 2019 Intel Corporation
+
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+*/}}
+
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: pfcp-agent
+  labels:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+data:
+  dp_config.cfg: |
+    if [ ! -d "/dev/hugepages" ]; then
+        MEMORY="--no-huge -m 1000"
+    fi
+    CORES="-c $(taskset -p $$ | awk '{print $NF}')"
+    EAL_ARGS="${CORES} ${MEMORY} {{ .Values.config.pfcpAgent.pci }}"
+
+    {{- if .Values.config.sriov.enabled }}
+    S1U_DEVNAME={{ .Values.config.pfcpAgent.s1u.device }}
+    {{- else }}
+    S1U_DEVNAME={{ .Values.config.pfcpAgent.s1u.device }}-veth
+    {{- end }}
+    {{- if .Values.config.sriov.enabled }}
+    SGI_DEVNAME={{ .Values.config.pfcpAgent.sgi.device }}
+    {{- else }}
+    SGI_DEVNAME={{ .Values.config.pfcpAgent.sgi.device }}-veth
+    {{- end }}
+
+    S1U_IP=$(ip -4 addr show dev ${S1U_DEVNAME} | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
+    SGI_IP=$(ip -4 addr show dev ${SGI_DEVNAME} | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
+    S1U_MAC=$(ip addr show dev ${S1U_DEVNAME} | awk '$1=="link/ether"{print $2}')
+    SGI_MAC=$(ip addr show dev ${SGI_DEVNAME} | awk '$1=="link/ether"{print $2}')
+
+    S1U="--s1u_ip ${S1U_IP} --s1u_mac ${S1U_MAC} --ul_iface ${S1U_DEVNAME}"
+    SGI="--sgi_ip ${SGI_IP} --sgi_mac ${SGI_MAC} --dl_iface ${SGI_DEVNAME} --sgi_gw_ip {{ .Values.networks.sgi.gateway }} --sgi_mask {{ .Values.networks.sgi.mask }}"
+    IP_POOL="--ip_pool {{ .Values.config.pfcpAgent.ueIpPool.ip }} --ip_pool_mask {{ .Values.config.pfcpAgent.ueIpPool.mask }}"
+    S1U_MASK="--s1u_mask {{ .Values.config.pfcpAgent.ueIpPool.s1u_mask }}"
+    P4RTC_SERVICE_NAME="--p4rtc_service_name {{.Values.config.pfcpAgent.p4rtc_service.name }}"
+    P4RTC_PORT="--p4rtc_port {{.Values.config.pfcpAgent.p4rtc_service.port }}"
+    MISC="--log 1"
+    SPGW_CFG="--spgw_cfg 03"
+
+    APP_ARGS="${S1U} ${SGI} ${IP_POOL} ${S1U_MASK} ${P4RTC_SERVICE_NAME} ${P4RTC_PORT} ${MISC} ${SPGW_CFG}"
+  cdr.cfg: |
+    CDR_PATH=./cdr
+    MASTER_CDR=./cdr/master.csv
+  interface.cfg: |
+    [0]
+    zmq_protocol = udp
+    dp_comm_ip = DP_ADDR
+    dp_comm_port = 8805
+{{- if .Values.config.pfcpAgent.multiUpfs }}
+    cp_nb_ip = {{ .Values.config.pfcpAgent.cpComm.addr }}
+    cp_nb_port = {{ .Values.config.pfcpAgent.cpComm.port }}
+    cp_comm_ip = {{ .Values.config.pfcpAgent.cpComm.addr }}
+    cp_comm_port = {{ .Values.config.pfcpAgent.cpComm.port }}
+    zmq_dp_ip=127.0.0.1
+    zmq_cp_ip=127.0.0.1
+{{- else }}
+    cp_comm_ip = {{ .Values.config.pfcpAgent.cpComm.addr }}
+    cp_comm_port = {{ .Values.config.pfcpAgent.cpComm.port }}
+{{- end }}
+{{- if not .Values.config.sriov.enabled }}
+  setup-af-iface.sh: |
+{{ tuple "bin/_pfcp-agent-setup-af-iface.sh.tpl" . | include "omec-pfcp-agent.template" | indent 4 }}
+{{- end }}
+  run.sh: |
+{{ tuple "bin/_pfcp-agent-run.sh.tpl" . | include "omec-pfcp-agent.template" | indent 4 }}
diff --git a/omec/omec-pfcp-agent/templates/networks.yaml b/omec/omec-pfcp-agent/templates/networks.yaml
new file mode 100644
index 0000000..277f4c3
--- /dev/null
+++ b/omec/omec-pfcp-agent/templates/networks.yaml
@@ -0,0 +1,40 @@
+{{/*
+# Copyright 2018-present Open Networking Foundation
+# Copyright 2018 Intel Corporation
+
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+*/}}
+
+---
+apiVersion: "k8s.cni.cncf.io/v1"
+kind: NetworkAttachmentDefinition
+metadata:
+  name: s1u-net
+{{- if $.Values.config.sriov.enabled }}
+  annotations:
+    k8s.v1.cni.cncf.io/resourceName: intel.com/sriov_vfio_s1u_net
+{{- end }}
+spec:
+  config: '{
+    "type": {{ .Values.networks.cniPlugin | quote }},
+    "ipam": {
+        "type": {{ .Values.networks.ipam | quote }}
+    }
+  }'
+---
+apiVersion: "k8s.cni.cncf.io/v1"
+kind: NetworkAttachmentDefinition
+metadata:
+  name: sgi-net
+{{- if $.Values.config.sriov.enabled }}
+  annotations:
+    k8s.v1.cni.cncf.io/resourceName: intel.com/sriov_vfio_sgi_net
+{{- end }}
+spec:
+  config: '{
+    "type": {{ .Values.networks.cniPlugin | quote }},
+    "ipam": {
+        "type": {{ .Values.networks.ipam | quote }}
+    }
+  }'
diff --git a/omec/omec-pfcp-agent/templates/service-pfcp-agent.yaml b/omec/omec-pfcp-agent/templates/service-pfcp-agent.yaml
new file mode 100644
index 0000000..520d8a2
--- /dev/null
+++ b/omec/omec-pfcp-agent/templates/service-pfcp-agent.yaml
@@ -0,0 +1,63 @@
+{{/*
+# Copyright 2019-present Open Networking Foundation
+# Copyright 2019 Intel Corporation
+
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+*/}}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: pfcp-agent
+  labels:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+spec:
+  selector:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+  ports:
+  - name: dp-comm
+    port: {{ .Values.config.pfcpAgent.dpComm.port }}
+{{- if .Values.config.pfcpAgent.multiUpfs }}
+    protocol: TCP
+{{- else }}
+    protocol: UDP
+{{- end }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: pfcp-headless
+  labels:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+spec:
+  clusterIP: None
+  selector:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+  ports:
+  - name: dp-comm
+    port: {{ .Values.config.pfcpAgent.dpComm.port }}
+{{- if .Values.config.pfcpAgent.multiUpfs }}
+    protocol: TCP
+{{- else }}
+    protocol: UDP
+{{- end }}
+{{- if and (not .Values.config.pfcpAgent.multiUpfs) .Values.config.pfcpAgent.dpComm.nodePort.enabled }}
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: pfcp-external
+  labels:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+spec:
+  selector:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+  type: NodePort
+  ports:
+  - name: dp-comm
+    port: {{ .Values.config.pfcpAgent.dpComm.port }}
+    protocol: UDP
+    nodePort: {{ .Values.config.pfcpAgent.dpComm.nodePort.port }}
+{{- end }}
diff --git a/omec/omec-pfcp-agent/templates/statefulset-pfcp-agent.yaml b/omec/omec-pfcp-agent/templates/statefulset-pfcp-agent.yaml
new file mode 100644
index 0000000..cb89df5
--- /dev/null
+++ b/omec/omec-pfcp-agent/templates/statefulset-pfcp-agent.yaml
@@ -0,0 +1,146 @@
+{{/*
+# Copyright 2018-present Open Networking Foundation
+# Copyright 2018 Intel Corporation
+
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
+*/}}
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: pfcp-agent
+  serviceName: pfcp-headless
+  labels:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 4 }}
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 6 }}
+  template:
+    metadata:
+      labels:
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.metadata_labels" | indent 8 }}
+      annotations:
+        k8s.v1.cni.cncf.io/networks: '[
+          {
+            "name": "s1u-net",
+            "interface": {{ .Values.config.pfcpAgent.s1u.device | quote }},
+            "ips": {{ .Values.config.pfcpAgent.s1u.ip | quote }}
+          },
+          {
+            "name": "sgi-net",
+            "interface": {{ .Values.config.pfcpAgent.sgi.device | quote }},
+            "ips": {{ .Values.config.pfcpAgent.sgi.ip | quote }}
+          }
+        ]'
+    spec:
+    {{- if .Values.nodeSelectors.enabled }}
+      nodeSelector:
+        {{ .Values.nodeSelectors.pfcpAgent.label }}: {{ .Values.nodeSelectors.pfcpAgent.value }}
+    {{- end }}
+    {{- if not .Values.config.sriov.enabled }}
+      initContainers:
+        - name: spgwu-iptables-init
+          image: {{ .Values.images.tags.init | quote }}
+          imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+          command: [ "sh", "-xec"]
+          securityContext:
+            capabilities:
+              add:
+                - NET_ADMIN
+          args:
+            - iptables -I OUTPUT -p icmp --icmp-type destination-unreachable -j DROP;
+        - name: spgwu-af-iface-init
+          image: {{ .Values.images.tags.init | quote }}
+          imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+          securityContext:
+            capabilities:
+              add:
+                - NET_ADMIN
+          command:
+            - /opt/dp/scripts/setup-af-iface.sh
+          volumeMounts:
+            - name: dp-script
+              mountPath: /opt/dp/scripts/setup-af-iface.sh
+              subPath: setup-af-iface.sh
+    {{- end }}
+    {{- if .Values.config.coreDump.enabled }}
+{{ tuple "pfcp-agent" . | include "omec-pfcp-agent.coredump_init" | indent 8 }}
+    {{- end }}
+      containers:
+      - name: pfcp-agent
+        image: {{ .Values.images.tags.pfcpAgent | quote }}
+        imagePullPolicy: {{ .Values.images.pullPolicy | quote }}
+        securityContext:
+      {{- if .Values.config.coreDump.enabled }}
+          privileged: true
+          runAsUser: 0
+      {{- end }}
+          capabilities:
+            add:
+              - IPC_LOCK
+        stdin: true
+        tty: true
+        env:
+        - name: MEM_LIMIT
+          valueFrom:
+            resourceFieldRef:
+              containerName: pfcp-agent
+              resource: limits.memory
+              divisor: 1Mi
+        - name: POD_IP
+          valueFrom:
+            fieldRef:
+              fieldPath: status.podIP
+        - name: DP_NAME
+          value: "{{ .Values.config.pfcpAgent.dpName }}"
+        command: ["bash", "-xc"]
+        args:
+        - ip a;
+          /opt/dp/scripts/run.sh;
+        volumeMounts:
+        - name: dp-script
+          mountPath: /opt/dp/scripts/run.sh
+          subPath: run.sh
+        - name: dp-config
+          mountPath: /etc/dp/config
+      {{- if .Values.config.coreDump.enabled }}
+        - name: coredump
+          mountPath: /tmp/coredump
+      {{- end }}
+        resources:
+          requests:
+          {{- if .Values.resources.enabled }}
+{{ toYaml .Values.resources.pfcpAgent.requests | indent 12 }}
+          {{- end }}
+          {{- if .Values.config.sriov.enabled }}
+            intel.com/sriov_vfio_s1u_net: 1
+            intel.com/sriov_vfio_sgi_net: 1
+          {{- end }}
+          limits:
+          {{- if .Values.resources.enabled }}
+{{ toYaml .Values.resources.pfcpAgent.limits | indent 12 }}
+          {{- end }}
+          {{- if .Values.config.sriov.enabled }}
+            intel.com/sriov_vfio_s1u_net: 1
+            intel.com/sriov_vfio_sgi_net: 1
+          {{- end }}
+      volumes:
+      - name: dp-script
+        configMap:
+          name: pfcp-agent
+          defaultMode: 493
+      - name: dp-config
+        configMap:
+          name: pfcp-agent
+          defaultMode: 420
+    {{- if .Values.config.coreDump.enabled }}
+      - name: host-rootfs
+        hostPath:
+          path: /
+      - name: coredump
+        hostPath:
+          path: {{ .Values.config.coreDump.path }}
+    {{- end }}