Add helm chart, may need rmr edits 71/271/9
authorTommy Carpenter <tommy@research.att.com>
Tue, 4 Jun 2019 14:20:30 +0000 (10:20 -0400)
committerTommy Carpenter <tommy@research.att.com>
Thu, 6 Jun 2019 18:23:52 +0000 (14:23 -0400)
Change-Id: Id1822239494dfa40c35a62b2414652a2a927e5d8
Signed-off-by: Tommy Carpenter <tommy@research.att.com>
18 files changed:
.gitignore
a1mediator/.helmignore [new file with mode: 0644]
a1mediator/Chart.yaml [new file with mode: 0644]
a1mediator/files/ricmanifest.json [new file with mode: 0644]
a1mediator/files/rmr_string_int_mapping.txt [new file with mode: 0644]
a1mediator/templates/_helpers.tpl [new file with mode: 0644]
a1mediator/templates/config.yaml [new file with mode: 0644]
a1mediator/templates/deployment.yaml [new file with mode: 0644]
a1mediator/templates/helper.yaml [new file with mode: 0644]
a1mediator/templates/ingress.yaml [new file with mode: 0644]
a1mediator/templates/secrets.yaml [new file with mode: 0644]
a1mediator/templates/service.yaml [new file with mode: 0644]
a1mediator/templates/tests/test-connection.yaml [new file with mode: 0644]
a1mediator/values.yaml [new file with mode: 0644]
docs/developer-guide.rst
docs/index.rst
integration_tests/docker-compose-only-tests.yml [new file with mode: 0644]
tox-integration.ini

index 4f07413..2cb6a1c 100644 (file)
@@ -1,3 +1,4 @@
+NOTES.txt
 .pytest_cache/
 xunit-results.xml
 .DS_Store
diff --git a/a1mediator/.helmignore b/a1mediator/.helmignore
new file mode 100644 (file)
index 0000000..50af031
--- /dev/null
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/a1mediator/Chart.yaml b/a1mediator/Chart.yaml
new file mode 100644 (file)
index 0000000..3f8cbde
--- /dev/null
@@ -0,0 +1,4 @@
+apiVersion: v1
+description: A1 Helm chart for Kubernetes
+name: a1mediator
+version: 0.8.2
diff --git a/a1mediator/files/ricmanifest.json b/a1mediator/files/ricmanifest.json
new file mode 100644 (file)
index 0000000..211a115
--- /dev/null
@@ -0,0 +1,63 @@
+{
+  "controls":[
+    {
+      "name":"control_admission_time",
+      "description":"time period to allow dual connection",
+      "message_receives_rmr_type":"DC_ADMISSION_INTERVAL_CONTROL",
+      "message_receives_payload_schema":{
+        "$schema":"http://json-schema.org/draft-07/schema#",
+        "type":"object",
+        "properties":{
+          "dc_admission_start_time":{
+            "type":"string",
+            "pattern":"^[0-9]{2}:[0-9]{2}:[0-9]{2}$"
+          },
+          "dc_admission_end_time":{
+            "type":"string",
+            "pattern":"^[0-9]{2}:[0-9]{2}:[0-9]{2}$"
+          }
+        },
+        "required":[
+          "dc_admission_start_time",
+          "dc_admission_end_time"
+        ]
+      },
+      "message_sends_rmr_type":"DC_ADMISSION_INTERVAL_CONTROL_ACK",
+      "message_sends_payload_schema":{
+        "$schema":"http://json-schema.org/draft-07/schema#",
+        "type":"object",
+        "properties":{
+          "status":{
+            "type":"string",
+            "enum":[
+              "SUCCESS",
+              "FAIL"
+            ]
+          },
+          "message":{
+            "type":"string"
+          }
+        }
+      }
+    },
+    {
+      "name":"test_policy",
+      "description":"for the purposes of testing",
+      "message_receives_rmr_type":"TEST_REQ",
+      "message_sends_rmr_type":"TEST_ACK",
+      "message_sends_payload_schema":{
+        "$schema":"http://json-schema.org/draft-07/schema#",
+        "type":"object",
+        "properties":{
+          "status":{
+            "type":"string",
+            "enum":[
+              "SUCCESS",
+              "FAIL"
+            ]
+          }
+        }
+      }
+    }
+  ]
+}
diff --git a/a1mediator/files/rmr_string_int_mapping.txt b/a1mediator/files/rmr_string_int_mapping.txt
new file mode 100644 (file)
index 0000000..ff1479d
--- /dev/null
@@ -0,0 +1,4 @@
+DC_ADMISSION_INTERVAL_CONTROL:20000
+DC_ADMISSION_INTERVAL_CONTROL_ACK:20001
+TEST_REQ:10000
+TEST_ACK:10001
diff --git a/a1mediator/templates/_helpers.tpl b/a1mediator/templates/_helpers.tpl
new file mode 100644 (file)
index 0000000..fa46bab
--- /dev/null
@@ -0,0 +1,45 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "a1mediator.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "a1mediator.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "a1mediator.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "a1mediator.labels" -}}
+app.kubernetes.io/name: {{ include "a1mediator.name" . }}
+helm.sh/chart: {{ include "a1mediator.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
diff --git a/a1mediator/templates/config.yaml b/a1mediator/templates/config.yaml
new file mode 100644 (file)
index 0000000..05f1630
--- /dev/null
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: a1conf
+data:
+  local.rt: |
+    newrt|start
+    rte|10000|rmr_delay_receiver:4563
+    rte|20000|rmr_receiver:4560
+    rte|10001|{{ .Values.rmrservice.name }}:{{ .Values.rmrservice.port }}
+    rte|20001|{{ .Values.rmrservice.name }}:{{ .Values.rmrservice.port }}
+    newrt|end
+  rmr_string_int_mapping.txt: {{ tpl (.Files.Get "files/rmr_string_int_mapping.txt") . | quote }}
+  ricmanifest.json: {{ tpl (.Files.Get "files/ricmanifest.json") . | quote }}
diff --git a/a1mediator/templates/deployment.yaml b/a1mediator/templates/deployment.yaml
new file mode 100644 (file)
index 0000000..a73ec1b
--- /dev/null
@@ -0,0 +1,73 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "a1mediator.fullname" . }}
+  labels:
+{{ include "a1mediator.labels" . | indent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "a1mediator.name" . }}
+      app.kubernetes.io/instance: {{ .Release.Name }}
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: {{ include "a1mediator.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+      imagePullSecrets:
+        - name: "{{ .Values.lf_docker_reg_secret }}"
+      containers:
+        - name: {{ .Chart.Name }}
+          volumeMounts:
+          - name: a1conf
+            mountPath: /opt/ricmanifest.json
+            subPath: ricmanifest.json
+          - name: a1conf
+            mountPath: /opt/rmr_string_int_mapping.txt
+            subPath: rmr_string_int_mapping.txt
+          - name: a1conf
+            mountPath: /opt/route/local.rt
+            subPath: local.rt
+          env:
+          - name: PYTHONUNBUFFERED
+            value: "0"
+          - name: RMR_RCV_RETRY_INTERVAL
+            value: "{{ .Values.rmr_timeout_config.rcv_retry_interval_ms }}"
+          - name: RMR_RETRY_TIMES
+            value: "{{ .Values.rmr_timeout_config.rcv_retry_times }}"
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.httpservice.port }}
+              protocol: TCP
+
+          livenessProbe:
+            httpGet:
+              path: /ui
+              port: http
+          readinessProbe:
+            httpGet:
+              path: /ui
+              port: http
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+      volumes:
+        - name: "a1conf"
+          configMap:
+            name: "a1conf"
+
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+    {{- end }}
diff --git a/a1mediator/templates/helper.yaml b/a1mediator/templates/helper.yaml
new file mode 100644 (file)
index 0000000..c036840
--- /dev/null
@@ -0,0 +1,3 @@
+{{- define "imagePullSecret" }}
+{{- printf "{\"auths\": {\"%s\": {\"auth\": \"%s\"}}}" .Values.imageCredentials.registry (printf "%s:%s" .Values.imageCredentials.username .Values.imageCredentials.password | b64enc) | b64enc }}
+{{- end }}
diff --git a/a1mediator/templates/ingress.yaml b/a1mediator/templates/ingress.yaml
new file mode 100644 (file)
index 0000000..f1362d9
--- /dev/null
@@ -0,0 +1,36 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "a1mediator.fullname" . -}}
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+  name: {{ $fullName }}
+  labels:
+{{ include "a1mediator.labels" . | indent 4 }}
+  {{- with .Values.ingress.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+  tls:
+  {{- range .Values.ingress.tls }}
+    - hosts:
+      {{- range .hosts }}
+        - {{ . | quote }}
+      {{- end }}
+      secretName: {{ .secretName }}
+  {{- end }}
+{{- end }}
+  rules:
+  {{- range .Values.ingress.hosts }}
+    - host: {{ .host | quote }}
+      http:
+        paths:
+        {{- range .paths }}
+          - path: {{ . }}
+            backend:
+              serviceName: {{ $fullName }}
+              servicePort: http
+        {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/a1mediator/templates/secrets.yaml b/a1mediator/templates/secrets.yaml
new file mode 100644 (file)
index 0000000..4afe4ec
--- /dev/null
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: lfhelper
+type: kubernetes.io/dockerconfigjson
+data:
+  .dockerconfigjson: {{ template "imagePullSecret" . }}
diff --git a/a1mediator/templates/service.yaml b/a1mediator/templates/service.yaml
new file mode 100644 (file)
index 0000000..fc67fc1
--- /dev/null
@@ -0,0 +1,36 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "a1mediator.fullname" . }}
+  labels:
+{{ include "a1mediator.labels" . | indent 4 }}
+
+spec:
+  type: {{ .Values.httpservice.type }}
+  ports:
+    - port: {{ .Values.httpservice.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+  selector:
+    app.kubernetes.io/name: {{ include "a1mediator.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
+
+---
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ .Values.rmrservice.name }}
+  labels:
+{{ include "a1mediator.labels" . | indent 4 }}
+
+spec:
+  type: {{ .Values.rmrservice.type }}
+  ports:
+    - port: {{ .Values.rmrservice.port }}
+      targetPort: {{ .Values.rmrservice.port }}
+      protocol: TCP
+  selector:
+    app.kubernetes.io/name: {{ include "a1mediator.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
diff --git a/a1mediator/templates/tests/test-connection.yaml b/a1mediator/templates/tests/test-connection.yaml
new file mode 100644 (file)
index 0000000..ca68368
--- /dev/null
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "a1mediator.fullname" . }}-test-connection"
+  labels:
+{{ include "a1mediator.labels" . | indent 4 }}
+  annotations:
+    "helm.sh/hook": test-success
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args:  ['{{ include "a1mediator.fullname" . }}:{{ .Values.httpservice.port }}']
+  restartPolicy: Never
diff --git a/a1mediator/values.yaml b/a1mediator/values.yaml
new file mode 100644 (file)
index 0000000..4375422
--- /dev/null
@@ -0,0 +1,43 @@
+replicaCount: 1
+
+image:
+  repository: nexus3.o-ran-sc.org:10004/ric-plt-a1
+  tag: 0.8.2
+  pullPolicy: IfNotPresent
+
+# name of the secret that allows for privagte registry docker pulls.
+# if the value is "lfhelper", there is a helper function included in this chart, and it uses imageCredentials .
+# imageCredentials is referenced in secrets.yaml, and uses a helper function to formulate the docker reg username and password into a valid dockerconfig.json.
+# Note, if the value of lf_docker_reg_secret is changed, these image credentials are ignored and not used.
+lf_docker_reg_secret: lfhelper
+imageCredentials:
+  registry: nexus3.o-ran-sc.org:10004/ric-plt-a1
+  username:
+  password:
+
+httpservice:
+  port: 10000 ## dont change this!!
+  type: ClusterIP
+
+rmrservice:
+  name: rmrservice
+  port: 4562 ## dont change this!!
+  type: ClusterIP
+
+rmr_timeout_config:
+  rcv_retry_interval_ms: 500
+  rcv_retry_times: 20
+
+ingress:
+  enabled: false
+  annotations: {}
+    # kubernetes.io/ingress.class: nginx
+    # kubernetes.io/tls-acme: "true"
+  hosts:
+    - host: chart-example.local
+      paths: []
+
+  tls: []
+  #  - secretName: chart-example-tls
+  #    hosts:
+  #      - chart-example.local
index a2562ad..9dea8dd 100644 (file)
@@ -37,7 +37,11 @@ This project follows semver. When changes are made, the versions are in:
 
 3) ``container-tag.yaml``
 
-4) ``a1/openapi.yml``
+4) ``a1mediator/values.yaml``
+
+5) ``a1mediator/Chart.yaml``
+
+6) ``a1/openapi.yml``
 
 Running locally
 ===============
index 316ef9e..19bce13 100644 (file)
@@ -64,6 +64,18 @@ which is an initial delay until the first rcv is tried. 2)
 timeouts and send failures should be retried before A1 gives up and
 returns a 503. The default is ``4``.
 
+K8S
+---
+The helm chart is in the folder `a1mediator`.
+
+There are two files in `a1mediator/files` that should be replaced with the "real" files for deployment. The ones included there, and referenced in the configmap, are only samples. To deploy A1 correctly, make sure these files are correct.
+
+::
+
+    helm install --devel a1mediator/ --name a1 --set imageCredentials.username=xxx --set imageCredentials.password=xxx
+
+The username and password here are the credentials to the registry defined in `a1mediator/values.yaml`. Currently this is the LF docker registry.
+
 Docker
 ------
 
diff --git a/integration_tests/docker-compose-only-tests.yml b/integration_tests/docker-compose-only-tests.yml
new file mode 100644 (file)
index 0000000..34facae
--- /dev/null
@@ -0,0 +1,38 @@
+# ==================================================================================
+#       Copyright (c) 2019 Nokia
+#       Copyright (c) 2018-2019 AT&T Intellectual Property.
+#
+#   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.
+# ==================================================================================
+version: '3'
+services:
+
+    rmr_receiver:
+        build: .
+        hostname: "rmr_receiver"
+        volumes:
+          - ./test_docker.rt:/opt/route/local.rt
+
+    rmr_delay_receiver:
+        build: .
+        hostname: "rmr_delay_receiver"
+        volumes:
+          - ./test_docker.rt:/opt/route/local.rt
+        environment:
+            # https://github.com/docker/compose/issues/3878
+            RMR_RCV_RETRY_INTERVAL: 500
+            RMR_RETRY_TIMES: 10
+            TEST_RCV_PORT: 4563
+            TEST_RCV_RETURN_MINT: 10001
+            TEST_RCV_SEC_DELAY: 5
+            TEST_RCV_RETURN_PAYLOAD: '{"ACK_FROM": "DELAYED_TEST", "status": "SUCCESS"}'
index e636aed..539da92 100644 (file)
@@ -30,6 +30,7 @@ commands_pre=
     docker-compose up --build -d
     sleep 2
 commands=
+# helm lint a1mediator/
     pytest -n 2
     ab -n 100 -c 10 -u putdata -T application/json http://localhost:10000/ric/policies/control_admission_time
 commands_post=