From 3a15f73bfb08c0d3e00dcd85e2f3496170aca76d Mon Sep 17 00:00:00 2001 From: Lachlan Plant Date: Thu, 25 Oct 2018 12:15:01 -0500 Subject: [PATCH] Create HELM chart for nova-api-proxy New helm chart created for nova-api-proxy New module added to helm overrides to configure nova-api-proxy.conf Turned of yamllint for helm charts, openstack helm charts are yaml files but not proper yaml syntax Story: 2004007 Task: 26953 Change-Id: Ic45d6cb801e142ddd7fc7da1638ba0e65cbacc22 Signed-off-by: Lachlan Plant --- .../helm-charts/nova-api-proxy/Chart.yaml | 5 + .../charts/helm-toolkit-0.1.0.tgz | Bin 0 -> 22590 bytes .../nova-api-proxy/requirements.yaml | 10 + .../templates/bin/_nova-api-proxy.sh.tpl | 13 + .../templates/configmap-bin.yaml | 19 ++ .../templates/configmap-etc.yaml | 55 ++++ .../nova-api-proxy/templates/deployment.yaml | 88 +++++ .../templates/image_repo_sync.yaml | 13 + .../nova-api-proxy/templates/ingress.yaml | 12 + .../templates/job-ks-endpoints.yaml | 12 + .../templates/secret-ingress-tls.yaml | 11 + .../templates/secret-keystone.yaml | 22 ++ .../nova-api-proxy/templates/service.yaml | 31 ++ .../helm-charts/nova-api-proxy/values.yaml | 306 ++++++++++++++++++ .../sysinv/sysinv/sysinv/common/constants.py | 4 +- sysinv/sysinv/sysinv/sysinv/helm/base.py | 6 + sysinv/sysinv/sysinv/sysinv/helm/helm.py | 4 +- .../sysinv/sysinv/helm/nova_api_proxy.py | 79 +++++ tox.ini | 2 +- 19 files changed, 689 insertions(+), 3 deletions(-) create mode 100644 kubernetes/helm-charts/nova-api-proxy/Chart.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/charts/helm-toolkit-0.1.0.tgz create mode 100644 kubernetes/helm-charts/nova-api-proxy/requirements.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/bin/_nova-api-proxy.sh.tpl create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/configmap-bin.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/configmap-etc.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/deployment.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/image_repo_sync.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/ingress.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/job-ks-endpoints.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/secret-ingress-tls.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/secret-keystone.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/templates/service.yaml create mode 100644 kubernetes/helm-charts/nova-api-proxy/values.yaml create mode 100644 sysinv/sysinv/sysinv/sysinv/helm/nova_api_proxy.py diff --git a/kubernetes/helm-charts/nova-api-proxy/Chart.yaml b/kubernetes/helm-charts/nova-api-proxy/Chart.yaml new file mode 100644 index 0000000000..0a92ed3823 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "1.0" +description: StarlingX-Helm nova-api-proxy +name: nova-api-proxy +version: 0.1.0 diff --git a/kubernetes/helm-charts/nova-api-proxy/charts/helm-toolkit-0.1.0.tgz b/kubernetes/helm-charts/nova-api-proxy/charts/helm-toolkit-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..65f25969d2942bbc8a9260d99e87b3bc5112b861 GIT binary patch literal 22590 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

8eDzYF@o^k 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

!{^`4r!ek9lOa7!m=QqPyV@!+-6mn2m0TUbm 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 literal 0 HcmV?d00001 diff --git a/kubernetes/helm-charts/nova-api-proxy/requirements.yaml b/kubernetes/helm-charts/nova-api-proxy/requirements.yaml new file mode 100644 index 0000000000..cb3c0440f9 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/requirements.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +dependencies: + - name: helm-toolkit + repository: http://localhost:8879/charts + version: 0.1.0 diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/bin/_nova-api-proxy.sh.tpl b/kubernetes/helm-charts/nova-api-proxy/templates/bin/_nova-api-proxy.sh.tpl new file mode 100644 index 0000000000..63d20deb58 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/bin/_nova-api-proxy.sh.tpl @@ -0,0 +1,13 @@ +#!/bin/bash + +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +set -ex + +nova-api-proxy --config-file=/etc/proxy/nova-api-proxy.conf diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/configmap-bin.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/configmap-bin.yaml new file mode 100644 index 0000000000..9124010690 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/configmap-bin.yaml @@ -0,0 +1,19 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if .Values.manifests.configmap_bin }} +{{- $envAll := . }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nova-api-proxy-bin +data: + nova-api-proxy.sh: | +{{ tuple "bin/_nova-api-proxy.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/configmap-etc.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/configmap-etc.yaml new file mode 100644 index 0000000000..68e1e46891 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/configmap-etc.yaml @@ -0,0 +1,55 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- define "nova_proxy.configmap.etc" }} +{{- $envAll := index . 1 }} +{{- with $envAll }} + +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.auth_uri -}} +{{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova_api_proxy.keystone_authtoken "auth_uri" -}} +{{- end -}} +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.auth_url -}} +{{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.nova_api_proxy.keystone_authtoken "auth_url" -}} +{{- end -}} + +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.region_name -}} +{{- $_ := set .Values.conf.nova_api_proxy.keystone_authtoken "region_name" .Values.endpoints.identity.auth.nova.region_name -}} +{{- end -}} +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.project_name -}} +{{- $_ := set .Values.conf.nova_api_proxy.keystone_authtoken "project_name" .Values.endpoints.identity.auth.nova.project_name -}} +{{- end -}} +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.project_domain_name -}} +{{- $_ := set .Values.conf.nova_api_proxy.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.nova.project_domain_name -}} +{{- end -}} +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.user_domain_name -}} +{{- $_ := set .Values.conf.nova_api_proxy.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.nova.user_domain_name -}} +{{- end -}} +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.username -}} +{{- $_ := set .Values.conf.nova_api_proxy.keystone_authtoken "username" .Values.endpoints.identity.auth.nova.username -}} +{{- end -}} +{{- if empty .Values.conf.nova_api_proxy.keystone_authtoken.password -}} +{{- $_ := set .Values.conf.nova_api_proxy.keystone_authtoken "password" .Values.endpoints.identity.auth.nova.password -}} +{{- end -}} + + +apiVersion: v1 +kind: ConfigMap +metadata: + name: nova-api-proxy-etc +data: + nova-api-proxy.conf: | +{{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.nova_api_proxy | indent 4 }} + api-proxy-paste.ini: | +{{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.paste | indent 4 }} + logging.conf: | +{{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | indent 4 }} +{{- end }} +{{- end }} +{{- if .Values.manifests.configmap_etc }} +{{- list "nova-proxy-etc" . | include "nova_proxy.configmap.etc" }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/deployment.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/deployment.yaml new file mode 100644 index 0000000000..c997277949 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/deployment.yaml @@ -0,0 +1,88 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if .Values.manifests.deployment_api_proxy }} +{{- $envAll := . }} + +{{- $mounts_nova_api_proxy := .Values.pod.mounts.nova_api_proxy.nova_api_proxy }} +{{- $mounts_nova_api_proxy_init := .Values.pod.mounts.nova_api_proxy.init_container }} + +{{- $serviceAccountName := "nova-api-proxy" }} +{{ tuple $envAll "proxy" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nova-api-proxy + labels: +{{ tuple $envAll "nova" "api-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + replicas: {{ .Values.pod.replicas.proxy }} + selector: + matchLabels: +{{ tuple $envAll "nova" "api-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} +{{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} + template: + metadata: + labels: +{{ tuple $envAll "nova" "api-proxy" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + annotations: + configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} + configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} + spec: + serviceAccountName: {{ $serviceAccountName }} + affinity: +{{ tuple $envAll "nova" "api-proxy" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ .Values.labels.api_proxy.node_selector_key }}: {{ .Values.labels.api_proxy.node_selector_value }} + terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api_proxy.timeout | default "30" }} + initContainers: +{{ tuple $envAll "api" $mounts_nova_api_proxy_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: nova-api-proxy +{{ tuple $envAll "nova_api_proxy" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.api_proxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + securityContext: + runAsUser: {{ .Values.pod.user.nova_api_proxy.uid }} + command: + - /tmp/nova-api-proxy.sh + ports: + - name: n-api + containerPort: {{ tuple "compute" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + readinessProbe: + tcpSocket: + port: {{ tuple "compute" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + volumeMounts: + - name: nova-api-proxy-bin + mountPath: /tmp/nova-api-proxy.sh + subPath: nova-api-proxy.sh + readOnly: true + - name: nova-api-proxy-etc + mountPath: /etc/proxy/nova-api-proxy.conf + subPath: nova-api-proxy.conf + readOnly: true + - name: nova-api-proxy-etc + mountPath: /etc/proxy/logging.conf + subPath: logging.conf + readOnly: true + - name: nova-api-proxy-etc + mountPath: /etc/proxy/api-proxy-paste.ini + subPath: api-proxy-paste.ini + readOnly: true +{{ if $mounts_nova_api_proxy.volumeMounts }}{{ toYaml $mounts_nova_api_proxy.volumeMounts | indent 12 }}{{ end }} + volumes: + - name: nova-api-proxy-bin + configMap: + name: nova-api-proxy-bin + defaultMode: 0777 + - name: nova-api-proxy-etc + configMap: + name: nova-api-proxy-etc + defaultMode: 0777 +{{ if $mounts_nova_api_proxy.volumes}}{{ toYaml $mounts_nova_api_proxy.volumes | indent 8 }}{{ end }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/image_repo_sync.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/image_repo_sync.yaml new file mode 100644 index 0000000000..c41c530fb7 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/image_repo_sync.yaml @@ -0,0 +1,13 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} +{{- $imageRepoSyncJob := dict "envAll" . "serviceName" "nova-api-proxy" -}} +{{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} +{{- end }} + diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/ingress.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/ingress.yaml new file mode 100644 index 0000000000..3fd8de5d9a --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/ingress.yaml @@ -0,0 +1,12 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if and .Values.manifests.ingress .Values.network.api_proxy.ingress.public }} +{{- $ingressOpts := dict "envAll" . "backendServiceType" "compute" "backendPort" "n-api-proxy" -}} +{{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/job-ks-endpoints.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/job-ks-endpoints.yaml new file mode 100644 index 0000000000..0c8524dec2 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/job-ks-endpoints.yaml @@ -0,0 +1,12 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if .Values.manifests.job_ks_endpoints }} +{{- $ksServiceJob := dict "envAll" . "serviceName" "nova" "serviceTypes" ( tuple "compute" ) -}} +{{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/secret-ingress-tls.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/secret-ingress-tls.yaml new file mode 100644 index 0000000000..71fc3060be --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/secret-ingress-tls.yaml @@ -0,0 +1,11 @@ +{{/* +# +#Copyright (c) 2018 Wind River Systems, Inc. +# +#SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if .Values.manifests.secret_ingress_tls }} +{{ include "helm-toolkit.manifests.secret_ingress_tls" ( dict "envAll" . "backendService" "osapi" "backendServiceType" "compute" ) }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/secret-keystone.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/secret-keystone.yaml new file mode 100644 index 0000000000..62dde02fe9 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/secret-keystone.yaml @@ -0,0 +1,22 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if .Values.manifests.secret_keystone }} +{{- $envAll := . }} +{{- range $key1, $userClass := tuple "admin" "nova" "test" }} +{{- $secretName := index $envAll.Values.secrets.identity $userClass }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} +type: Opaque +data: +{{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} +{{- end }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/templates/service.yaml b/kubernetes/helm-charts/nova-api-proxy/templates/service.yaml new file mode 100644 index 0000000000..0d8584b07e --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/templates/service.yaml @@ -0,0 +1,31 @@ +{{/* +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +*/}} + +{{- if .Values.manifests.service_api }} +{{- $envAll := . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ tuple "nova" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} +spec: + ports: + - name: n-api-proxy + port: {{ tuple "compute" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + {{ if .Values.network.api.node_port.enabled }} + nodePort: {{ .Values.network.api.node_port.port }} + {{ end }} + selector: +{{ tuple $envAll "nova" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} + {{ if .Values.network.api.node_port.enabled }} + type: NodePort + {{ if .Values.network.api.external_policy_local }} + externalTrafficPolicy: Local + {{ end }} + {{ end }} +{{- end }} diff --git a/kubernetes/helm-charts/nova-api-proxy/values.yaml b/kubernetes/helm-charts/nova-api-proxy/values.yaml new file mode 100644 index 0000000000..33ed6642b3 --- /dev/null +++ b/kubernetes/helm-charts/nova-api-proxy/values.yaml @@ -0,0 +1,306 @@ +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Default values for nova-api-proxy. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +labels: + api_proxy: + node_selector_key: openstack-control-plane + node_selector_value: enabled + job: + node_selector_key: openstack-control-plane + node_selector_value: enabled + +images: + tags: + nova_api_proxy: 128.224.186.231:9001/abailey/stx-nova-api-proxy:latest + ks_endpoints: docker.io/openstackhelm/heat:pike + dep_check: quay.io/stackanetes/kubernetes-entrypoint:v0.3.1 + pullPolicy: IfNotPresent + local_registry: + active: false + exclude: + - dep_check + - image_repo_sync + +network: + api_proxy: + ingress: + public: true + classes: + namespace: "nginx" + cluster: "nginx-cluster" + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + external_policy_local: false + node_port: + enabled: false + port: 8774 + +conf: + nova_api_proxy: + DEFAULT: + log_config_append: /etc/proxy/logging.conf + api_paste_config: api-proxy-paste.ini + auth_strategy: keystone + debug: False + use_syslog: False + show_request_body: False + pool_size: 256 + osapi_proxy_listen: 0.0.0.0 + osapi_proxy_listen_port: 8774 + osapi_compute_listen: nova-api.openstack.svc.cluster.local + osapi_compute_listen_port: 8774 + nfvi_compute_listen_port: 30003 + nfvi_compute_listen: 0.0.0.0 + keystone_authtoken: + auth_type: password + auth_version: v3 + + paste: + pipeline:nova-api-proxy: + pipeline: version authtoken acceptor proxyapp + filter:debug_header: + paste.filter_factory: nova_api_proxy.apps.acceptor:DebugHeaders.factory + filter:version: + paste.filter_factory: nova_api_proxy.apps.acceptor:VersionAcceptor.factory + filter:authtoken: + paste.filter_factory: keystonemiddleware.auth_token:filter_factory + filter:acceptor: + paste.filter_factory: nova_api_proxy.apps.acceptor:Acceptor.factory + app:proxyapp: + paste.app_factory: nova_api_proxy.apps.proxy:Proxy.factory + + logging: + loggers: + keys: + - root + - nova_api_proxy + - keystonemiddleware + handlers: + keys: + - stdout + - stderr + - "null" + formatters: + keys: + - context + - default + logger_root: + level: WARNING + handlers: null + logger_nova_api_proxy: + level: INFO + handlers: + - stdout + qualname: nova_api_proxy + logger_keystonemiddleware: + level: INFO + handlers: + - stdout + qualname: keystonemiddleware + logger_amqp: + level: WARNING + handlers: stderr + qualname: amqp + logger_amqplib: + level: WARNING + handlers: stderr + qualname: amqplib + logger_eventletwsgi: + level: WARNING + handlers: stderr + qualname: eventlet.wsgi.server + logger_sqlalchemy: + level: WARNING + handlers: stderr + qualname: sqlalchemy + logger_boto: + level: WARNING + handlers: stderr + qualname: boto + handler_null: + class: logging.NullHandler + formatter: default + args: () + handler_stdout: + class: StreamHandler + args: (sys.stdout,) + formatter: context + handler_stderr: + class: StreamHandler + args: (sys.stderr,) + formatter: context + formatter_context: + class: oslo_log.formatters.ContextFormatter + formatter_default: + format: "%(message)s" + +dependencies: + dynamic: + common: + local_image_registry: + jobs: + - image-repo-sync + services: + - endpoint: node + service: local_image_registry + static: + ks_endpoints: + jobs: + - nova-ks-service + services: + - endpoint: internal + service: identity + + +endpoints: + cluster_domain_suffix: cluster.local + local_image_registry: + name: docker-registry + namespace: docker-registry + hosts: + default: localhost + internal: docker-registry + node: localhost + host_fqdn_override: + default: null + port: + registry: + node: 5000 + identity: + name: keystone + auth: + admin: + region_name: RegionOne + username: admin + password: password + project_name: admin + user_domain_name: default + project_domain_name: default + nova: + role: admin + region_name: RegionOne + username: nova + password: password + project_name: service + user_domain_name: service + project_domain_name: service + hosts: + default: keystone-api + public: keystone + host_fqdn_override: + default: null + path: + default: /v3 + scheme: + default: http + port: + admin: + default: 35357 + api: + default: 80 + compute: + name: nova + hosts: + default: nova-api-proxy + public: nova-api-proxy + host_fqdn_override: + default: null + # NOTE(portdirect): this chart supports TLS for fqdn over-ridden public + # endpoints using the following format: + # public: + # host: null + # tls: + # crt: null + # key: null + path: + default: "/v2.1/%(tenant_id)s" + scheme: + default: 'http' + port: + api: + default: 8774 + public: 80 + +pod: + user: + nova_api_proxy: + uid: 42424 + affinity: + anti: + type: + default: preferredDuringSchedulingIgnoredDuringExecution + topologyKey: + default: kubernetes.io/hostname + mounts: + nova_api_proxy: + init_container: null + nova_api_proxy: + replicas: + proxy: 1 + lifecycle: + upgrades: + deployments: + revision_history: 3 + pod_replacement_strategy: RollingUpdate + rolling_update: + max_unavailable: 1 + max_surge: 3 + daemonsets: + pod_replacement_strategy: RollingUpdate + compute: + enabled: true + min_ready_seconds: 0 + max_unavailable: 1 + disruption_budget: + api_proxy: + min_available: 0 + termination_grace_period: + api_proxy: + timeout: 30 + resources: + enabled: false + api_proxy: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + jobs: + ks_endpoints: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + +secrets: + identity: + admin: nova-keystone-admin + nova: nova-keystone-user + + +manifests: + configmap_bin: true + configmap_etc: true + deployment_api_proxy: true + ingress_api: true + job_ks_endpoints: false + +resources: {} + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/sysinv/sysinv/sysinv/sysinv/common/constants.py b/sysinv/sysinv/sysinv/sysinv/common/constants.py index 3f49d12686..97cde38eb9 100644 --- a/sysinv/sysinv/sysinv/sysinv/common/constants.py +++ b/sysinv/sysinv/sysinv/sysinv/common/constants.py @@ -1368,11 +1368,11 @@ HELM_CHART_MEMCACHED = 'memcached' HELM_CHART_NEUTRON = 'neutron' HELM_CHART_NFS_PROVISIONER = 'nfs-provisioner' HELM_CHART_NOVA = 'nova' +HELM_CHART_NOVA_API_PROXY = 'nova-api-proxy' HELM_CHART_OPENVSWITCH = 'openvswitch' HELM_CHART_RABBITMQ = 'rabbitmq' HELM_CHART_RBD_PROVISIONER = 'rbd-provisioner' - SUPPORTED_HELM_CHARTS = [ HELM_CHART_BARBICAN, HELM_CHART_CEILOMETER, @@ -1391,6 +1391,7 @@ SUPPORTED_HELM_CHARTS = [ HELM_CHART_NEUTRON, HELM_CHART_NFS_PROVISIONER, HELM_CHART_NOVA, + HELM_CHART_NOVA_API_PROXY, HELM_CHART_OPENVSWITCH, HELM_CHART_RABBITMQ, HELM_CHART_RBD_PROVISIONER, @@ -1426,6 +1427,7 @@ SUPPORTED_HELM_APP_CHARTS = { HELM_CHART_LIBVIRT, HELM_CHART_NEUTRON, HELM_CHART_NOVA, + HELM_CHART_NOVA_API_PROXY, HELM_CHART_CINDER, HELM_CHART_GNOCCHI, HELM_CHART_CEILOMETER, diff --git a/sysinv/sysinv/sysinv/sysinv/helm/base.py b/sysinv/sysinv/sysinv/sysinv/helm/base.py index 8e764e91ce..1069c48d2a 100644 --- a/sysinv/sysinv/sysinv/sysinv/helm/base.py +++ b/sysinv/sysinv/sysinv/sysinv/helm/base.py @@ -12,6 +12,7 @@ from sysinv.common import constants from sysinv.common import exception from sysinv.common import utils from sysinv.common.storage_backend_conf import StorageBackendConfig + from sysinv.openstack.common import log as logging from . import common @@ -176,3 +177,8 @@ class BaseHelm(object): utils._format_ceph_mon_address(mon, port) for mon in monitor_ips ] return formatted_monitor_ips + + def _get_management_address(self): + address = self._get_address_by_name( + constants.CONTROLLER_HOSTNAME, constants.NETWORK_TYPE_MGMT) + return address.address diff --git a/sysinv/sysinv/sysinv/sysinv/helm/helm.py b/sysinv/sysinv/sysinv/sysinv/helm/helm.py index b1708f61f7..92109b08ec 100644 --- a/sysinv/sysinv/sysinv/sysinv/helm/helm.py +++ b/sysinv/sysinv/sysinv/sysinv/helm/helm.py @@ -45,7 +45,7 @@ from . import rabbitmq # Chart source: Custom from . import rbd_provisioner - +from . import nova_api_proxy LOG = logging.getLogger(__name__) @@ -104,6 +104,8 @@ class HelmOperator(object): constants.HELM_CHART_NFS_PROVISIONER: nfs_provisioner.NfsProvisionerHelm(self), constants.HELM_CHART_NOVA: nova.NovaHelm(self), + constants.HELM_CHART_NOVA_API_PROXY: + nova_api_proxy.NovaApiProxyHelm(self), constants.HELM_CHART_OPENVSWITCH: openvswitch.OpenvswitchHelm(self), constants.HELM_CHART_RABBITMQ: rabbitmq.RabbitmqHelm(self), diff --git a/sysinv/sysinv/sysinv/sysinv/helm/nova_api_proxy.py b/sysinv/sysinv/sysinv/sysinv/helm/nova_api_proxy.py new file mode 100644 index 0000000000..c95dc028de --- /dev/null +++ b/sysinv/sysinv/sysinv/sysinv/helm/nova_api_proxy.py @@ -0,0 +1,79 @@ +# +# Copyright (c) 2018 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from sysinv.common import constants +from sysinv.common import exception +from sysinv.openstack.common import log as logging +from . import common +from . import openstack + +LOG = logging.getLogger(__name__) + + +class NovaApiProxyHelm(openstack.OpenstackBaseHelm): + """Class to encapsulate helm operations for the nova chart""" + + CHART = constants.HELM_CHART_NOVA_API_PROXY + SUPPORTED_NAMESPACES = [ + common.HELM_NS_OPENSTACK + ] + + SERVICE_NAME = 'nova' + AUTH_USERS = ['nova'] + + def get_namespaces(self): + return self.SUPPORTED_NAMESPACES + + def get_overrides(self, namespace=None): + + overrides = { + common.HELM_NS_OPENSTACK: { + 'pod': { + 'user': { + 'nova_api_proxy': { + 'uid': 0 + } + } + }, + 'conf': { + 'nova_api_proxy': { + 'DEFAULT': { + 'nfvi_compute_listen': self._get_management_address() + }, + } + }, + 'endpoints': self._get_endpoints_overrides(), + } + } + + if namespace in self.SUPPORTED_NAMESPACES: + return overrides[namespace] + elif namespace: + raise exception.InvalidHelmNamespace(chart=self.CHART, + namespace=namespace) + else: + return overrides + + def _get_endpoints_identity_users_overrides(self): + overrides = {} + overrides.update(self._get_common_users_overrides(self.SERVICE_NAME)) + + for user in self.AUTH_USERS: + overrides.update({ + user: { + 'region_name': self._region_name(), + 'password': self._get_keyring_password(self.SERVICE_NAME, user) + } + }) + return overrides + + def _get_endpoints_identity_overrides(self): + return {'auth': self._get_endpoints_identity_users_overrides()} + + def _get_endpoints_overrides(self): + return { + 'identity': self._get_endpoints_identity_overrides(), + } diff --git a/tox.ini b/tox.ini index 9e05b053cd..48cee9974e 100644 --- a/tox.ini +++ b/tox.ini @@ -26,7 +26,7 @@ commands = -i E006,E010" bash -c "find {toxinidir} \ - \( -name .tox -prune \) \ + \( -name .tox -o -path {toxinidir}/kubernetes/helm-charts -prune \) \ -o -type f -name '*.yaml' \ -print0 | xargs -0 yamllint -f parsable \ -c {toxinidir}/.yamllint"