diff --git a/aci-helm/Chart.yaml b/aci-helm/Chart.yaml new file mode 100644 index 000000000..5000f51b5 --- /dev/null +++ b/aci-helm/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: aci-helm +description: A Helm chart for ACI network plugin installation on kubernetes platform + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.0.1 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "5.2.3.3" diff --git a/aci-helm/LICENSE b/aci-helm/LICENSE new file mode 100644 index 000000000..21c57fae2 --- /dev/null +++ b/aci-helm/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 The Kubernetes Authors All Rights Reserved + + 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. diff --git a/aci-helm/README.md b/aci-helm/README.md new file mode 100644 index 000000000..ef491d3b3 --- /dev/null +++ b/aci-helm/README.md @@ -0,0 +1,4 @@ +To install +----------- + +helm install aci-helm diff --git a/aci-helm/crds/acc-provision-crd.yaml b/aci-helm/crds/acc-provision-crd.yaml new file mode 100644 index 000000000..50c4288ff --- /dev/null +++ b/aci-helm/crds/acc-provision-crd.yaml @@ -0,0 +1,167 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: accprovisioninputs.aci.ctrl +spec: + group: aci.ctrl + names: + kind: AccProvisionInput + listKind: AccProvisionInputList + plural: accprovisioninputs + singular: accprovisioninput + scope: Namespaced + versions: + - name: v1alpha1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: accprovisioninput defines the input configuration for ACI CNI + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + description: AccProvisionInputSpec defines the desired spec for accprovisioninput object + properties: + acc_provision_input: + type: object + properties: + operator_managed_config: + type: object + properties: + enable_updates: + type: boolean + aci_config: + type: object + properties: + sync_login: + type: object + properties: + certfile: + type: string + keyfile: + type: string + client_ssl: + type: boolean + net_config: + type: object + properties: + interface_mtu: + type: integer + service_monitor_interval: + type: integer + pbr_tracking_non_snat: + type: boolean + pod_subnet_chunk_size: + type: integer + disable_wait_for_network: + type: boolean + duration_wait_for_network: + type: integer + registry: + type: object + properties: + image_prefix: + type: string + image_pull_secret: + type: string + aci_containers_operator_version: + type: string + aci_containers_controller_version: + type: string + aci_containers_host_version: + type: string + acc_provision_operator_version: + type: string + aci_cni_operator_version: + type: string + cnideploy_version: + type: string + opflex_agent_version: + type: string + openvswitch_version: + type: string + gbp_version: + type: string + logging: + type: object + properties: + size: + type: integer + controller_log_level: + type: string + hostagent_log_level: + type: string + opflexagent_log_level: + type: string + istio_config: + type: object + properties: + install_istio: + type: boolean + install_profile: + type: string + multus: + type: object + properties: + disable: + type: boolean + drop_log_config: + type: object + properties: + enable: + type: boolean + nodepodif_config: + type: object + properties: + enable: + type: boolean + sriov_config: + type: object + properties: + enable: + type: boolean + kube_config: + type: object + properties: + ovs_memory_limit: + type: string + use_privileged_containers: + type: boolean + image_pull_policy: + type: string + reboot_opflex_with_ovs: + type: string + snat_operator: + type: object + properties: + port_range: + type: object + properties: + start: + type: integer + end: + type: integer + ports_per_node: + type: integer + contract_scope: + type: string + disable_periodic_snat_global_info_sync: + type: boolean + type: object + status: + description: AccProvisionInputStatus defines the successful completion of AccProvisionInput + properties: + status: + type: boolean + type: object + required: + - spec + type: object diff --git a/aci-helm/crds/aci-operators-crd.yaml b/aci-helm/crds/aci-operators-crd.yaml new file mode 100644 index 000000000..89f314710 --- /dev/null +++ b/aci-helm/crds/aci-operators-crd.yaml @@ -0,0 +1,45 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: acicontainersoperators.aci.ctrl +spec: + group: aci.ctrl + names: + kind: AciContainersOperator + listKind: AciContainersOperatorList + plural: acicontainersoperators + singular: acicontainersoperator + scope: Namespaced + versions: + - name: v1alpha1 + served: true + storage: true + subresources: + status: {} + schema: + openAPIV3Schema: + description: acicontainersoperator owns the lifecycle of ACI objects in the cluster + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + description: AciContainersOperatorSpec defines the desired spec for ACI Objects + properties: + flavor: + type: string + config: + type: string + type: object + status: + description: AciContainersOperatorStatus defines the successful completion of AciContainersOperator + properties: + status: + type: boolean + type: object + required: + - spec + type: object diff --git a/aci-helm/templates/NOTES.txt b/aci-helm/templates/NOTES.txt new file mode 100644 index 000000000..5162a27bc --- /dev/null +++ b/aci-helm/templates/NOTES.txt @@ -0,0 +1 @@ +Thank you for installing ACI network plugin diff --git a/aci-helm/templates/_helpers.tpl b/aci-helm/templates/_helpers.tpl new file mode 100644 index 000000000..68f9e0e22 --- /dev/null +++ b/aci-helm/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "charts.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 "charts.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 "charts.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "charts.labels" -}} +helm.sh/chart: {{ include "charts.chart" . }} +{{ include "charts.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "charts.selectorLabels" -}} +app.kubernetes.io/name: {{ include "charts.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "charts.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "charts.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/aci-helm/templates/acc-provision-configmap.yaml b/aci-helm/templates/acc-provision-configmap.yaml new file mode 100644 index 000000000..25550731e --- /dev/null +++ b/aci-helm/templates/acc-provision-configmap.yaml @@ -0,0 +1,203 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: acc-provision-config + namespace: {{ .Values.kubeConfig.system_namespace | default "aci-containers-system" }} + labels: + {{- if (.Values.aciConfig).token }} + aci-containers-config-version: {{ (.Values.aciConfig).token }} + {{- end }} + network-plugin: aci-containers +data: + spec: |- + { + "acc_provision_input": { + "operator_managed_config": { + {{- if (.Values.operatorManagedConfig).enableUpdates }} + "enable_updates": {{ .Values.operatorManagedConfig.enableUpdates|quote | default "False" }} + {{- else }} + "enable_updates": "False" + {{- end }} + + }, + "aci_config": { + "system_id": {{ .Values.aciConfig.systemId|quote }}, + {{- if (.Values.aciConfig).apicHosts }} + "apic_hosts": {{ .Values.aciConfig.apicHosts|quote}}, + {{- end }} + {{- if (.Values.aciConfig).aep }} + "aep": {{ .Values.aciConfig.aep|quote }}, + {{- end }} + {{- if (.Values.aciConfig).apicSubscriptionDelay }} + "apic-subscription-delay": {{ .Values.aciConfig.apicSubscriptionDelay|quote }}, + {{- end }} + {{- if (.Values.aciConfig).apicRefreshtickerAdjust }} + "apic_refreshticker_adjust": {{ .Values.aciConfig.apicRefreshtickerAdjust|quote }}, + {{- end }} + {{- if (.Values.aciConfig).opflexDeviceDeleteTimeout }} + "opflex-device-delete-timeout": {{ .Values.aciConfig.opflexDeviceDeleteTimeout|quote }}, + {{- end }} + {{- if (.Values.aciConfig).tenant }} + "tenant": { + "name": {{ .Values.aciConfig.tenant.name|quote }} + }, + {{- end }} + "vrf": { + "name": {{ .Values.aciConfig.vrf.name|quote }}, + "tenant": {{ .Values.aciConfig.vrf.tenant|quote }} + }, + {{- if (.Values.aciConfig).syncLogin }} + "sync_login": { + {{- $sLogLen := len .Values.aciConfig.syncLogin }} + {{- $sLogCount := 0 | int }} + {{- range $k, $v := .Values.aciConfig.syncLogin }} + {{- $sLogCount = add1 $sLogCount }} + {{ $k | quote}} : {{ $v | quote }}{{- if ne $sLogCount $sLogLen }},{{- end }} + {{- end }} + }, + {{- end }} + {{- if (.Values.aciConfig).clientSsl }} + "client_ssl": {{ .Values.aciConfig.clientSsl | quote }}, + {{- end }} + {{- if (.Values.aciConfig).vmmDomain }} + "vmm_domain": { + {{- if (.Values.aciConfig).vmmDomain.nestedInside }} + "nested_inside": { + "installer_provisioned_lb_ip": {{ .Values.aciConfig.vmmDomain.nestedInside.installerProvisionedLbIp | quote }} + } + {{- end }} + }, + {{- end }} + "l3out": { + "name": {{ (.Values.aciConfig).l3out.name|quote }}, + "external_networks": {{ (.Values.aciConfig).l3out.externalNetworks|quote }} + } + }, + {{- if .Values.registry }} + "registry": { + {{- $regLen := len .Values.registry }} + {{- $regCount := 0 | int }} + {{- range $k, $v := .Values.registry }} + {{- $regCount = add1 $regCount }} + {{ $k | quote}} : {{ $v | quote }}{{- if ne $regCount $regLen }},{{- end }} + {{- end }} + }, + {{- end }} + {{- if .Values.kubeConfig }} + "kube_config": { + {{- $kubeLen := len .Values.kubeConfig }} + {{- $kubeCount := 0 | int }} + {{- range $key, $value := .Values.kubeConfig }} + {{- $kubeCount = add1 $kubeCount }} + {{- if eq $key "snat_operator" }} + "snat_operator": { + {{- $snatLen := len .Values.kubeConfig.snat_operator }} + {{- $snatCount := 0 | int }} + {{- range $snatkey, $snatvalue := .Values.kubeConfig.snat_operator }} + {{- $snatCount = add1 $snatCount }} + {{- if eq $snatkey "port_range" }} + "port_range": { + {{- $portLen := len .Values.kubeConfig.snat_operator.port_range }} + {{- $portCount := 0 | int }} + {{- range $snatportkey, $snatportvalue := .Values.kubeConfig.snat_operator.port_range}} + {{- $portCount = add1 $portCount }} + {{ $snatportkey|quote }}: {{ $snatportvalue|quote }}{{- if ne $portCount $portLen }},{{- end }} + {{- end }} + }{{- if ne $snatCount $snatLen }},{{- end }} + {{- else }} + {{ $snatkey|quote }}: {{ $snatvalue|quote }}{{- if ne $snatCount $snatLen }},{{- end }} + {{- end }} + {{- end }} + } + {{- else }} + {{ $key|quote }}: {{ $value|quote }}{{- if ne $kubeCount $kubeLen }},{{- end }} + {{- end }} + {{- end }} + }, + {{- end }} + {{- if .Values.multus }} + "multus": { + {{- $mulLen := len .Values.multus }} + {{- $mulCount := 0 | int }} + {{- range $key, $value := .Values.multus }} + {{- $mulCount = add1 $mulCount }} + {{ $key|quote }}: {{ $value|quote }}{{- if ne $mulCount $mulLen }},{{- end }} + {{- end }} + }, + {{- end }} + {{- if .Values.dropLogConfig }} + "drop_log_config": { + {{- $dropLen := len .Values.dropLogConfig }} + {{- $dropCount := 0 | int }} + {{- range $key, $value := .Values.dropLogConfig }} + {{- $dropCount = add1 $dropCount }} + {{ $key|quote }}: {{ $value|quote }}{{- if ne $dropCount $dropLen }},{{- end }} + {{- end }} + }, + {{- end }} + {{- if .Values.istioConfig }} + "istio_config": { + {{- $istLen := len .Values.istioConfig }} + {{- $istCount := 0 | int }} + {{- range $key, $value := .Values.istioConfig }} + {{ $key|quote }}: {{ $value|quote }}{{- if ne $istCount $istLen }},{{- end }} + {{- end }} + }, + {{- end }} + {{- if .Values.logging }} + "logging": { + {{- $logLen := len .Values.logging }} + {{- $logCount := 0 | int }} + {{- range $key, $value := .Values.logging }} + {{- $logCount = add1 $logCount }} + {{ $key|quote }}: {{ $value|quote }} {{- if ne $logCount $logLen }},{{- end }} + {{- end }} + }, + {{- end }} + {{- if .Values.netConfig }} + "net_config": { + {{- if .Values.netConfig.infraVlan }} + "infra_vlan": {{ .Values.netConfig.infraVlan|quote }}, + {{- end }} + {{- if .Values.netConfig.serviceVlan }} + "service_vlan": {{ .Values.netConfig.serviceVlan|quote }}, + {{- end }} + {{- if .Values.netConfig.kubeapiVlan }} + "kubeapi_vlan": {{ .Values.netConfig.kubeapiVlan|quote }}, + {{- end }} + {{- if .Values.netConfig.externStatic }} + "extern_static": {{ .Values.netConfig.externStatic|quote }}, + {{- end }} + {{- if .Values.netConfig.externDynamic }} + "extern_dynamic": {{ .Values.netConfig.externDynamic|quote }}, + {{- end }} + {{- if .Values.netConfig.nodeSvcSubnet }} + "node_svc_subnet": {{ .Values.netConfig.nodeSvcSubnet|quote }}, + {{- end }} + {{- if .Values.netConfig.interfaceMtu }} + "interface_mtu": {{ (.Values.netConfig).interfaceMtu|quote }}, + {{- end }} + {{- if .Values.netConfig.interfaceMtuHeadroom }} + "interface-mtu-headroom": {{ (.Values.netConfig).interfaceMtuHeadroom|quote }}, + {{- end }} + {{- if (.Values.netConfig).serviceMonitorInterval }} + "service_monitor_interval": {{ .Values.netConfig.serviceMonitorInterval|quote }}, + {{- end }} + {{- if (.Values.netConfig).pbrTrackingNonSnat }} + "pbr_tracking_non_snat": {{ (.Values.netConfig).pbrTrackingNonSnat|quote }}, + {{- end }} + {{- if (.Values.netConfig).podSubnetChunkSize }} + "pod_subnet_chunk_size": {{ (.Values.netConfig).podSubnetChunkSize|quote }}, + {{- end }} + {{- if (.Values.netConfig).disableWaitForNetwork }} + "disable_wait_for_network": {{ (.Values.netConfig).disableWaitForNetwork|quote }}, + {{- end }} + {{- if (.Values.netConfig).durationWaitForNetwork }} + "duration_wait_for_network": {{ (.Values.netConfig).durationWaitForNetwork|quote }}, + {{- end }} + "node_subnet": {{ .Values.netConfig.nodeSubnet|quote }}, + "pod_subnet": {{ .Values.netConfig.podSubnet|quote }} + } + {{- end }} + } + } diff --git a/aci-helm/templates/aci-operators-configmap.yaml b/aci-helm/templates/aci-operators-configmap.yaml new file mode 100644 index 000000000..c032a2689 --- /dev/null +++ b/aci-helm/templates/aci-operators-configmap.yaml @@ -0,0 +1,15 @@ + +apiVersion: v1 +kind: ConfigMap +metadata: + name: aci-operator-config + namespace: {{ .Values.kubeConfig.system_namespace | default "aci-containers-system" }} + labels: + aci-containers-config-version: {{ (.Values.aciConfig).token }} + network-plugin: aci-containers +data: + spec: |- + { + "flavor": {{ .Values.aciOperatorConfig.flavor|quote }}, + "config": {{ .Values.aciOperatorConfig.config|quote }} + } diff --git a/aci-helm/templates/aci-operators.yaml b/aci-helm/templates/aci-operators.yaml new file mode 100644 index 000000000..62f8b3125 --- /dev/null +++ b/aci-helm/templates/aci-operators.yaml @@ -0,0 +1,251 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: aci-containers-operator + namespace: {{ default "aci-containers-system" (.Values.kubeConfig).system_namespace }} + labels: + aci-containers-config-version: {{ (.Values.aciConfig).token }} +--- +apiVersion: {{ default "rbac.authorization.k8s.io/v1" (.Values.kubeConfig).use_rbac_api }} +kind: ClusterRole +metadata: + labels: + aci-containers-config-version: {{ (.Values.aciConfig).token }} + network-plugin: aci-containers + name: aci-containers-operator +rules: +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - '*' +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - '*' +- apiGroups: + - '' + resources: + - nodes + - namespaces + - configmaps + - secrets + - pods + - services + - serviceaccounts + - serviceaccounts/token + - endpoints + - events + verbs: + - '*' +- apiGroups: + - networking.k8s.io + resources: + - networkpolicies + verbs: + - list + - watch + - get +- apiGroups: + - "monitoring.coreos.com" + resources: + - servicemonitors + verbs: + - get + - create +- apiGroups: + - apps + resources: + - deployments + - replicasets + - daemonsets + - statefulsets + verbs: + - '*' +- apiGroups: + - aci.ctrl + resources: + - acicontainersoperators + - acicontainersoperators/status + - acicontainersoperators/finalizers + verbs: + - '*' +- apiGroups: + - aci.ctrl + resources: + - accprovisioninputs + - accprovisioninputs/status + - accprovisioninputs/finalizers + verbs: + - '*' +- apiGroups: + - scheduling.k8s.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - aci.snat + resources: + - snatpolicies + - snatglobalinfos + - rdconfigs + verbs: + - list + - watch + - get +- apiGroups: + - aci.snat + resources: + - nodeinfos + verbs: + - create + - update + - list + - watch + - get +{{ if eq .Values.flavor "cloud" }} +- apiGroups: + - "aci.aw" + resources: + - podifs + - podifs/status + - gbpsstates + - gbpsstates/status + verbs: + - "*" +{{ end }} +- apiGroups: + - config.openshift.io + - operator.openshift.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - update + - list + - watch + - get +--- +apiVersion: {{ default "rbac.authorization.k8s.io/v1" (.Values.kubeConfig).use_rbac_api }} +kind: ClusterRoleBinding +metadata: + name: aci-containers-operator + labels: + aci-containers-config-version: "{{ (.Values.aciConfig).token }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: aci-containers-operator +subjects: +- kind: ServiceAccount + name: aci-containers-operator + namespace: {{ default "aci-containers-system" (.Values.kubeConfig).system_namespace }} +--- +apiVersion: {{ default "apps/v1" (.Values.kubeConfig).use_apps_api }} +kind: Deployment +metadata: + name: aci-containers-operator + namespace: {{ default "aci-containers-system" (.Values.kubeConfig).system_namespace }} + labels: + aci-containers-config-version: "{{ .Values.registry.configuration_version }}" + name: aci-containers-operator + network-plugin: aci-containers +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + name: aci-containers-operator + network-plugin: aci-containers + strategy: + type: Recreate + template: + metadata: + name: aci-containers-operator + namespace: {{ default "aci-containers-system" (.Values.kubeConfig).system_namespace }} + annotations: + scheduler.alpha.kubernetes.io/critical-pod: "" + labels: + name: aci-containers-operator + network-plugin: aci-containers + spec: + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: preferred-node + operator: In + values: + - aci-containers-operator-2577247291 + weight: 1 + containers: + - image: {{ default "noiro" (.Values.registry).image_prefix }}/aci-containers-operator:{{ default "None" (.Values.registry).aci_containers_operator_version }} + imagePullPolicy: {{ default "Always" (.Values.kubeConfig).image_pull_policy }} + name: aci-containers-operator + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - name: aci-operator-config + mountPath: /usr/local/etc/aci-containers/ + - name: acc-provision-config + mountPath: /usr/local/etc/acc-provision/ + env: + - name: SYSTEM_NAMESPACE + value: {{ default "aci-containers-system" (.Values.kubeConfig).system_amespace}} + - name: ACC_PROVISION_FLAVOR + value: {{ .Values.flavor }} + - env: + - name: ANSIBLE_GATHERING + value: explicit + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ACC_PROVISION_FLAVOR + value: {{ .Values.flavor }} + - name: ACC_PROVISION_INPUT_CR_NAME + value: "accprovisioninput" + image: {{ default "noiro" (.Values.registry).image_prefix }}/acc-provision-operator:{{ default "None" (.Values.registry).acc_provision_operator_version }} + imagePullPolicy: {{ default "Always" (.Values.kubeConfig).image_pull_policy }} + name: acc-provision-operator + resources: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + dnsPolicy: ClusterFirst + hostNetwork: true + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: aci-containers-operator + serviceAccountName: aci-containers-operator + terminationGracePeriodSeconds: 30 + tolerations: + - effect: NoSchedule + operator: Exists + volumes: + - name: aci-operator-config + configMap: + name: aci-operator-config + items: + - key: spec + path: aci-operator.conf + - name: acc-provision-config + configMap: + name: acc-provision-config + items: + - key: spec + path: acc-provision-operator.conf diff --git a/aci-helm/values.yaml b/aci-helm/values.yaml new file mode 100644 index 000000000..6d35b9404 --- /dev/null +++ b/aci-helm/values.yaml @@ -0,0 +1,53 @@ + aciOperatorConfig: + flavor: "" + config: "" + + aciConfig: + systemId: "" + apicHosts: [] + aep: "" + token: "" + vrf: + name: "" + tenant: "" + SyncLogin: + certfile: "" + keyfile: "" + + l3out: + name: "" + externalNetworks: [] + + registry: + image_prefix: "" + image_pull_secret: "" + aci_containers_controller_version: "" + aci_containers_host_version: "" + cnideploy_version: "" + opflex_agent_version: "" + openvswitch_version: "" + aci_containers_operator_version: "" + acc_provision_operator_version: "" + + logging: + controller_log_level: "" + hostagent_log_level: "" + opflexagent_log_level: "" + + netConfig: + infraVlan: "" + serviceVlan: "" + kubeapiVlan: "" + externStatic: "" + externDynamic: "" + nodeSvcSubnet: "" + nodeSubnet: "" + podSubnet: "" + + kubeConfig: + image_pull_policy: "" + ovs_memory_limit: "" + system_namespace: "" + + operatorManagedConfig: + enableUpdates: "" diff --git a/provision/acc_provision/acc_provision.py b/provision/acc_provision/acc_provision.py index f4f4b2a22..b4f4461eb 100755 --- a/provision/acc_provision/acc_provision.py +++ b/provision/acc_provision/acc_provision.py @@ -1296,6 +1296,42 @@ def generate_rancher_1_3_13_yaml(config, operator_output, operator_tar, operator template.stream(config=config).dump(operator_output) +def generate_helm_values_yaml(config, operator_output, operator_tar, operator_cr_output): + kube_objects = [ + "configmap", "secret", "serviceaccount", + "daemonset", "deployment", + ] + if config["kube_config"].get("use_openshift_security_context_constraints", + False): + kube_objects.append("securitycontextconstraints") + if config["kube_config"].get("use_cluster_role", False): + kube_objects.extend(["clusterrolebinding", "clusterrole"]) + + if operator_output and operator_output != "/dev/null": + template = get_jinja_template('aci-containers.yaml') + outname = operator_output + + temp = ''.join(template.stream(config=config)) + # Generate and convert containers deployment to base64 and add + # as configMap entry to the operator deployment. + config["kube_config"]["deployment_base64"] = base64.b64encode(temp.encode('ascii')).decode('ascii') + + template = get_jinja_template('aci-helm-values.yaml') + outname = operator_output + # If no output (-o) values file is provided, print to stdout. + # Else, save to file. + if operator_output == "-": + outname = "" + operator_output = sys.stdout + info("Writing aci operator config and acc provision config values to %s" % outname) + info("Use this values for helm installation") + if operator_output != sys.stdout: + with open(operator_output, "w") as fh: + fh.write(template.render(config=config)) + else: + template.stream(config=config).dump(operator_output) + + def is_calico_flavor(flavor): return SafeDict(FLAVORS[flavor]).get("calico_cni") @@ -1604,6 +1640,9 @@ def parse_args(show_help): parser.add_argument( '--operator-mode', default=False, help=argparse.SUPPRESS, metavar='operator_mode') + parser.add_argument( + '--helm', action='store_true', default=False, + help='generate values file for aci-cni install using helm') # If the input has no arguments, show help output and exit if show_help: parser.print_help(sys.stderr) @@ -1683,6 +1722,7 @@ def provision(args, apic_file, no_random): output_tar = args.output_tar operator_cr_output_file = args.aci_operator_cr upgrade_cluster = args.upgrade + helm_chart_values = args.helm prov_apic = None if args.apic: @@ -1874,6 +1914,12 @@ def provision(args, apic_file, no_random): config["registry"]["aci_containers_operator_version"] = config["registry"]["aci_cni_operator_version"] config["registry"]["acc_provision_operator_version"] = config["registry"]["aci_cni_operator_version"] + # generate values.yaml file for helm + if helm_chart_values: + config["kube_config"]["use_cnideploy_initcontainer"] = True + generate_helm_values_yaml(config, output_file, output_tar, operator_cr_output_file) + return True + if flavor in ["cloud", "aks", "eks"]: if prov_apic is None: return True diff --git a/provision/acc_provision/templates/aci-helm-values.yaml b/provision/acc_provision/templates/aci-helm-values.yaml new file mode 100644 index 000000000..26762de89 --- /dev/null +++ b/provision/acc_provision/templates/aci-helm-values.yaml @@ -0,0 +1,145 @@ + aciOperatorConfig: + flavor: {{ config.flavor|json }} + config: {{ config.kube_config.deployment_base64|json }} + + aciConfig: + systemId: {{ config.aci_config.system_id }} + {% if config.user_config.aci_config.apic_hosts %} + apicHosts: {{config.aci_config.apic_hosts|json|indent(width=16)}} + {% endif %} + {% if config.user_config.aci_config.aep %} + aep: {{config.aci_config.aep|json}} + {% endif %} + {% if config.aci_config.apic_subscription_delay %} + apicSubscriptionDelay: {{ config.aci_config.apic_subscription_delay|json }} + {% endif %} + {% if config.aci_config.apic_refreshticker_adjust %} + apicRefreshtickerAdjust: {{ config.aci_config.apic_refreshticker_adjust|json }} + {% endif %} + {% if config.aci_config.opflex_device_delete_timeout %} + opflexDeviceDeleteTimeout: {{ config.aci_config.opflex_device_delete_timeout|json }} + {% endif %} + {% if config.user_config.aci_config.tenant %} + tenant: + name: {{config.user_config.aci_config.tenant.name|json}} + {% endif %} + {% if config.registry.configuration_version %} + token: {{ config.registry.configuration_version|json }} + {% endif %} + vrf: + name: {{config.aci_config.vrf.name|json}} + tenant: {{config.aci_config.vrf.tenant|json}} + {% if config.user_config.aci_config.sync_login %} + SyncLogin: + {% for key, value in config.user_config.aci_config.sync_login.items() %} + {{ key }}: {{ value|json }} + {% endfor %} + {% endif %} + {% if config.user_config.aci_config.client_ssl %} + clientSsl: {{ config.aci_config.client_ssl|json }} + {% endif %} + {% if ((config.user_config.aci_config.vmm_domain) and (config.user_config.aci_config.vmm_domain.nested_inside) and (config.user_config.aci_config.vmm_domain.nested_inside.installer_provisioned_lb_ip)) %} + vmmDomain: + nestedInside: + installerProvisionedLbIp: {{ config.user_config.aci_config.vmm_domain.nested_inside.installer_provisioned_lb_ip|json|indent(width=20) }} + {% endif %} + l3out: + name: {{ config.aci_config.l3out.name|json}} + externalNetworks: {{ config.aci_config.l3out.external_networks }} + {% if config.user_config.registry %} + registry: + {% for key, value in config.user_config.registry.items() %} + {{ key }}: {{ value|json }} + {% endfor %} + {% endif %} + {% if config.user_config.multus %} + multus: + {% for key, value in config.user_config.multus.items() %} + {{ key }}: {{ value|json }} + {% endfor %} + {% endif %} + {% if config.user_config.drop_log_config %} + dropLogConfig: + {% for key, value in config.user_config.drop_log_config.items() %} + {{ key }}: {{ value|json }} + {% endfor %} + {% endif %} + {% if config.user_config.istio_config %} + istioConfig: + {% for key, value in config.user_config.istio_config.items() %} + {{ key }}: {{ value|json }} + {% endfor %} + {% endif %} + + {% if config.user_config.logging %} + logging: + {% for key, value in config.user_config.logging.items() %} + {{ key }}: {{ value|json }} + {% endfor %} + {% endif %} + + netConfig: + {% if config.user_config.net_config.infra_vlan %} + infraVlan: {{config.net_config.infra_vlan|json}} + {% endif %} + {% if config.user_config.net_config.service_vlan %} + serviceVlan: {{config.net_config.service_vlan|json}} + {% endif %} + {% if config.user_config.net_config.kubeapi_vlan %} + kubeapiVlan: {{config.net_config.kubeapi_vlan|json}} + {% endif %} + {% if config.user_config.net_config.extern_static %} + externStatic: {{config.net_config.extern_static|json}} + {% endif %} + {% if config.user_config.net_config.extern_dynamic %} + externDynamic: {{config.net_config.extern_dynamic|json}} + {% endif %} + {% if config.user_config.net_config.node_svc_subnet %} + nodeSvcSubnet: {{config.net_config.node_svc_subnet|json}} + {% endif %} + {% if config.user_config.net_config.interface_mtu %} + interfaceMtu: {{config.net_config.interface_mtu|json}} + {% endif %} + {% if config.user_config.interface_mtu_headroom %} + interfaceMtuHeadroom: {{ config.user_config.interface_mtu_headroom|json }} + {% endif %} + {% if config.user_config.net_config.service_monitor_interval %} + serviceMonitorInterval: {{config.net_config.service_monitor_interval|json}} + {% endif %} + {% if config.user_config.net_config.pbr_tracking_non_snat %} + pbrTrackingNonSnat: {{config.net_config.pbr_tracking_non_snat|json}} + {% endif %} + {% if config.user_config.net_config.pod_subnet_chunk_size %} + podSubnetChunkSize: {{config.net_config.pod_subnet_chunk_size|json}} + {% endif %} + {% if config.user_config.net_config.disable_wait_for_network %} + disableWaitForNetwork: {{config.net_config.disable_wait_for_network|json}} + {% endif %} + {% if config.user_config.net_config.duration_wait_for_network %} + durationWaitForNetwork: {{config.net_config.duration_wait_for_network|json}} + {% endif %} + nodeSubnet: {{config.net_config.node_subnet|json}} + podSubnet: {{config.net_config.pod_subnet|json}} + + {% if config.user_config.kube_config %} + kubeConfig: + {% for key, value in config.user_config.kube_config.items() %} + {% if key == 'snat_operator' %} + snat_operator: + {% for snatkey, snatvalue in config.user_config.kube_config.snat_operator.items() %} + {% if snatkey == 'port_range' %} + port_range: + {% for snatportkey, snatportvalue in config.user_config.kube_config.snat_operator.port_range.items() %} + {{ snatportkey }}: {{ snatportvalue|json|indent(width=20) }} + {% endfor %} + {% else %} + {{ snatkey }}: {{ snatvalue|json|indent(width=20) }} + {% endif %} + {% endfor %} + {% else %} + {{ key }}: {{ value|json }} + {% endif %} + {% endfor %} + {% endif %} + operatorManagedConfig: + enableUpdates: {{config.operator_managed_config.enable_updates|json}} diff --git a/provision/acc_provision/test_main.py b/provision/acc_provision/test_main.py index 5714eb5bc..4b351e3cf 100644 --- a/provision/acc_provision/test_main.py +++ b/provision/acc_provision/test_main.py @@ -1025,6 +1025,7 @@ def get_args(**overrides): # the APIC "infra_vlan": None, "test_run": True, + "helm": False, } argc = collections.namedtuple('argc', list(arg.keys())) args = argc(**arg) diff --git a/provision/testdata/help.stdout.txt b/provision/testdata/help.stdout.txt index c0f9e10ee..40d76c90f 100644 --- a/provision/testdata/help.stdout.txt +++ b/provision/testdata/help.stdout.txt @@ -2,7 +2,7 @@ usage: acc_provision.py [-h] [-v] [--release] [--debug] [--sample] [-c file] [-o file] [-z file] [-r file] [-a] [-d] [-u name] [-p pass] [-w timeout] [--list-flavors] [-f flavor] [-t token] [--test-data-out file] [--skip-kafka-certs] - [--upgrade] [--disable-multus disable_multus] + [--upgrade] [--disable-multus disable_multus] [--helm] Provision an ACI/Kubernetes installation @@ -37,3 +37,4 @@ optional arguments: upgrade --disable-multus disable_multus true/false to disable/enable multus in cluster + --helm generate values file for aci-cni install using helm