diff --git a/.github/linters/ct.yaml b/.github/linters/ct.yaml index c70d05d..fcff038 100644 --- a/.github/linters/ct.yaml +++ b/.github/linters/ct.yaml @@ -6,3 +6,5 @@ charts: - . namespace: default release-label: app.kubernetes.io/namespace +additional-commands: + - helm unittest --strict . diff --git a/.github/workflows/lint-test.yaml b/.github/workflows/lint-test.yaml index 6120341..34ec758 100644 --- a/.github/workflows/lint-test.yaml +++ b/.github/workflows/lint-test.yaml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 @@ -27,7 +27,7 @@ jobs: - name: install helm unittest plugin run: | helm env - helm plugin install https://github.com/quintush/helm-unittest.git --version 0.2.8 + helm plugin install https://github.com/helm-unittest/helm-unittest.git - name: Run chart-testing (lint) run: ct lint --config .github/linters/ct.yaml diff --git a/Chart.yaml b/Chart.yaml index c551cb4..4a9d606 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -7,7 +7,7 @@ description: A Helm chart template for byzanteam application # chart 类型 type: application # chart 版本 -version: 1.3.1 +version: 1.4.0 # 项目源码的URL列表 sources: - https://github.com/Byzanteam/application-chart-template/ diff --git a/README.md b/README.md index f39eccf..68706d8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # application-chart-template -![Version: 1.1.0](https://img.shields.io/badge/Version-1.1.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.0.0](https://img.shields.io/badge/AppVersion-1.0.0-informational?style=flat-square) +![Version: 1.4.0](https://img.shields.io/badge/Version-1.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.0.0](https://img.shields.io/badge/AppVersion-1.0.0-informational?style=flat-square) A Helm chart template for byzanteam application @@ -18,7 +18,7 @@ A Helm chart template for byzanteam application | Key | Type | Default | Description | |-----|------|---------|-------------| -| appIngressroute | list | `[]` | | +| appIngressroutes | list | `[]` | | | applicationHosts | list | `[]` | | | applicationTLS | object | `{}` | | | corsSettings | object | `{}` | | @@ -36,8 +36,9 @@ A Helm chart template for byzanteam application | nameOverride | string | `""` | | | replicaCount | int | `1` | | | restartPolicy | string | `"Always"` | | -| service.name | string | `"http"` | | -| service.port | int | `80` | | +| service.ports[].name | string | `"http"` | | +| service.ports[].port | int | `80` | | +| service.ports[].protocol | string | `TCP` | | | service.type | string | `"ClusterIP"` | | | volumeMounts | list | `[]` | | | volumes | list | `[]` | | @@ -73,11 +74,13 @@ applicationHosts: ``` ### 4. 设置反向代理对应 path 规则 ```yaml -appIngressroute: +appIngressroutes: - name: example-name path: /example-path + servicePortName: 0 ``` ### 5. 设置外部服务代理规则 + ```yaml externalIngressroute: - name: "external-name" diff --git a/templates/NOTES.txt b/templates/NOTES.txt new file mode 100644 index 0000000..6325990 --- /dev/null +++ b/templates/NOTES.txt @@ -0,0 +1,21 @@ +{{ include "application-chart-template.fullname" . }} has been Installed! +{{- if .Values.appIngressroute }} +Use the link below to access the app: + {{- range $host := .Values.applicationHosts }} + {{- range $ingress := $.Values.appIngressroute }} + {{ empty $.Values.applicationTLS | ternary "http" "https" }}://{{ $host }}{{ $ingress.path }} + {{- end }} + {{- end }} +Warnig: Migrate the `.Values.appIngressroute` variable to `.Values.appIngressroutes` +{{- end }} +{{- if .Values.appIngressroutes }} +Use the link below to access the app: + {{- range $host := .Values.applicationHosts }} + {{- range $ingress := $.Values.appIngressroute }} + {{ empty $.Values.applicationTLS | ternary "http" "https" }}://{{ $host }}{{ $ingress.path }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.service.port }} +Warnig: Migrate the `.Values.service.port` (object) variable to `.Values.service.ports` (list) +{{- end }} diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index f59031b..d4546f4 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -60,19 +60,6 @@ Return the imagePullSecret {{- end }} {{- end }} -{{/* -Host for access rule -*/}} -{{- define "application-chart-template.applicationHosts" -}} -{{- $hosts := .Values.applicationHosts }} -{{- $orOperator := " || " }} -{{- $ruleHosts := list }} -{{- range $_, $host := $hosts }} - {{- $ruleHosts = append $ruleHosts (printf "Host(`%s`)" $host) }} -{{- end }} -{{- printf "(%s)" (join $orOperator $ruleHosts) }} -{{- end }} - {/* Build secret keys */} diff --git a/templates/_ingressroute.tpl b/templates/_ingressroute.tpl new file mode 100644 index 0000000..92a2bbe --- /dev/null +++ b/templates/_ingressroute.tpl @@ -0,0 +1,58 @@ +{{/* +Host for access rule +*/}} +{{- define "application-chart-template.applicationHosts" -}} +{{- $hosts := .Values.applicationHosts }} +{{- $orOperator := " || " }} +{{- $ruleHosts := list }} +{{- range $_, $host := $hosts }} + {{- $ruleHosts = append $ruleHosts (printf "Host(`%s`)" $host) }} +{{- end }} +{{- printf "(%s)" (join $orOperator $ruleHosts) }} +{{- end }} + +{{/* +Middlewares for web ingress-routes +*/}} +{{- define "application-chart-template.webMiddlewares" -}} +{{- $webMiddlewares := list "compress" "strip-prefix" }} +{{- if $.Values.applicationTLS }} +{{- $webMiddlewares = append $webMiddlewares "redirect-to-https" }} +{{- end }} +{{- if $.Values.corsSettings }} +{{- $webMiddlewares = append $webMiddlewares "cors" }} +{{- end }} +{{- range $webMiddlewares }} +- name: {{ include "application-chart-template.fullname" $ }}-{{ . }} +{{- end }} +{{- end }} + +{{/* +Middlewares for websecure ingress-routes +*/}} +{{- define "application-chart-template.websecureMiddlewares" -}} +{{- $websecureMiddlewares := list "compress" "strip-prefix" }} +{{- if $.Values.corsSettings }} +{{- $websecureMiddlewares = append $websecureMiddlewares "cors" }} +{{- end }} +{{- range $websecureMiddlewares }} +- name: {{ include "application-chart-template.fullname" $ }}-{{ . }} +{{- end }} +{{- end }} + +{{/* +Renders the ingress service port value +*/}} +{{- define "application-chart-template.ingressServicePort" -}} +{{- $portName := "" -}} +{{- range $port := .ports -}} + {{- if eq $.servicePortName $port.name -}} + {{- $portName = $.servicePortName -}} + {{- end -}} +{{- end -}} +{{- if $portName -}} +{{- printf "%s" $portName -}} +{{- else -}} +{{- fail "The same service port name could not be found!" -}} +{{- end -}} +{{- end -}} diff --git a/templates/deployment.yaml b/templates/deployment.yaml index d90c3c3..c8028ef 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -39,9 +39,19 @@ spec: {{ .Values.command | toYaml | nindent 12 }} {{- end }} ports: + # TODO: 1. Update multiple service ports. Input multiple service ports using list. + # 2. Delete this after the version 2.0.0 + {{- if .Values.service.port }} - name: {{ .Values.service.name }} containerPort: {{ .Values.service.port }} protocol: TCP + {{- else }} + {{- range .Values.service.ports }} + - name: {{ .name }} + containerPort: {{ .port }} + protocol: {{ .protocol }} + {{- end }} + {{- end }} volumeMounts: {{- .Values.volumeMounts | toYaml | nindent 12 }} restartPolicy: {{ .Values.restartPolicy }} diff --git a/templates/service.yaml b/templates/service.yaml index 41a3f06..4d4f5a5 100644 --- a/templates/service.yaml +++ b/templates/service.yaml @@ -6,11 +6,24 @@ metadata: {{- include "application-chart-template.labels" . | nindent 4 }} namespace: {{ .Release.Namespace }} spec: + # TODO: 1. Update multiple service ports. Input multiple service ports using list. + # 2. Delete this after the version 2.0.0 + {{- if .Values.service.port }} type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: {{ .Values.service.name }} protocol: TCP name: {{ .Values.service.name }} + {{- else }} + type: {{ .Values.service.type }} + ports: + {{- range .Values.service.ports }} + - port: {{ .port }} + targetPort: {{ .name }} + protocol: {{ .protocol }} + name: {{ .name }} + {{- end }} + {{- end }} selector: {{- include "application-chart-template.selectorLabels" . | nindent 4 }} diff --git a/templates/traefik/ingress-route.yaml b/templates/traefik/ingress-route.yaml index e7168f5..df06e7a 100644 --- a/templates/traefik/ingress-route.yaml +++ b/templates/traefik/ingress-route.yaml @@ -1,14 +1,78 @@ +# TODO: 1. Change `appIngressroute` to `appIngressroutes` +# 2. Delete this after the version 2.0.0 {{- range .Values.appIngressroute }} --- -{{/* Middlewares for web ingress-routes */}} -{{- $webMiddlewares := list "compress" "strip-prefix" }} -{{- if $.Values.applicationTLS | empty | not }} -{{- $webMiddlewares = append $webMiddlewares "redirect-to-https" }} +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: {{ include "application-chart-template.fullname" $ }}-{{ .name }}-web + namespace: {{ $.Values.namespace }} +spec: + entryPoints: + - web + routes: + # TODO: 1. Update multiple service ports. Input multiple service ports using list. + # 2. Delete this after the version 2.0.0 + {{- if $.Values.service.port }} + - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) + kind: Rule + services: + - name: {{ include "application-chart-template.fullname" $ }} + port: {{ $.Values.service.port }} + middlewares: + {{- include "application-chart-template.webMiddlewares" $ | nindent 8}} + {{- else }} + - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) + kind: Rule + services: + - name: {{ include "application-chart-template.fullname" $ }} + port: {{ include "application-chart-template.ingressServicePort" (dict "ports" $.Values.service.ports "servicePortName" .servicePortName) }} + middlewares: + {{- include "application-chart-template.webMiddlewares" $ | nindent 8}} + {{- end }} + +--- +{{- if $.Values.applicationTLS }} + +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: {{ include "application-chart-template.fullname" $ }}-{{ .name }}-websecure + namespace: {{ $.Values.namespace }} +spec: + entryPoints: + - websecure + routes: + # TODO: 1. Update multiple service ports. Input multiple service ports using list. + # 2. Delete this after the version 2.0.0 + {{- if $.Values.service.port }} + - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) + kind: Rule + services: + - name: {{ include "application-chart-template.fullname" $ }} + port: {{ $.Values.service.port }} + middlewares: + {{- include "application-chart-template.websecureMiddlewares" $ | nindent 8}} + {{- else }} + - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) + kind: Rule + services: + - name: {{ include "application-chart-template.fullname" $ }} + port: {{ include "application-chart-template.ingressServicePort" (dict "ports" $.Values.service.ports "servicePortName" .servicePortName) }} + middlewares: + {{- include "application-chart-template.websecureMiddlewares" $ | nindent 8}} + {{- end }} + tls: + {{- if $.Values.applicationTLS.certResolver }} + certResolver: {{ $.Values.applicationTLS.certResolver }} + {{- else if $.Values.applicationTLS.TLSSecret }} + secretName: {{ include "application-chart-template.fullname" $ }}-tls-secret + {{- end }} {{- end }} -{{- if $.Values.corsSettings | empty | not }} -{{- $webMiddlewares = append $webMiddlewares "cors" }} {{- end }} +{{- range .Values.appIngressroutes }} +--- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: @@ -18,23 +82,28 @@ spec: entryPoints: - web routes: + # TODO: 1. Update multiple service ports. Input multiple service ports using list. + # 2. Delete this after the version 2.0.0 + {{- if $.Values.service.port }} - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) kind: Rule services: - name: {{ include "application-chart-template.fullname" $ }} port: {{ $.Values.service.port }} middlewares: - {{- range $webMiddlewares }} - - name: {{ include "application-chart-template.fullname" $ }}-{{ . }} - {{- end }} ---- -{{- if $.Values.applicationTLS | empty | not }} + {{- include "application-chart-template.webMiddlewares" $ | nindent 8}} + {{- else }} + - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) + kind: Rule + services: + - name: {{ include "application-chart-template.fullname" $ }} + port: {{ include "application-chart-template.ingressServicePort" (dict "ports" $.Values.service.ports "servicePortName" .servicePortName) }} + middlewares: + {{- include "application-chart-template.webMiddlewares" $ | nindent 8}} + {{- end }} -{{/* Middlewares for websecure ingress-routes */}} -{{- $websecureMiddlewares := list "compress" "strip-prefix" }} -{{- if $.Values.corsSettings | empty | not }} -{{- $websecureMiddlewares = append $websecureMiddlewares "cors" }} -{{- end }} +--- +{{- if $.Values.applicationTLS }} apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute @@ -45,19 +114,29 @@ spec: entryPoints: - websecure routes: + # TODO: 1. Update multiple service ports. Input multiple service ports using list. + # 2. Delete this after the version 2.0.0 + {{- if $.Values.service.port }} - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) kind: Rule services: - name: {{ include "application-chart-template.fullname" $ }} port: {{ $.Values.service.port }} middlewares: - {{- range $websecureMiddlewares }} - - name: {{ include "application-chart-template.fullname" $ }}-{{ . }} - {{- end }} + {{- include "application-chart-template.websecureMiddlewares" $ | nindent 8}} + {{- else }} + - match: {{ include "application-chart-template.applicationHosts" $ }} && PathPrefix(`{{ .path }}`) + kind: Rule + services: + - name: {{ include "application-chart-template.fullname" $ }} + port: {{ include "application-chart-template.ingressServicePort" (dict "ports" $.Values.service.ports "servicePortName" .servicePortName) }} + middlewares: + {{- include "application-chart-template.websecureMiddlewares" $ | nindent 8}} + {{- end }} tls: - {{- if $.Values.applicationTLS.certResolver | empty | not }} + {{- if $.Values.applicationTLS.certResolver }} certResolver: {{ $.Values.applicationTLS.certResolver }} - {{- else if $.Values.applicationTLS.TLSSecret | empty | not }} + {{- else if $.Values.applicationTLS.TLSSecret }} secretName: {{ include "application-chart-template.fullname" $ }}-tls-secret {{- end }} {{- end }} diff --git a/tests/application_ingressroute_test.yaml b/tests/application_ingressroute_test.yaml index 671d9f3..fc56b27 100644 --- a/tests/application_ingressroute_test.yaml +++ b/tests/application_ingressroute_test.yaml @@ -20,11 +20,59 @@ tests: value: (Host(`192.168.0.1`) || Host(`172.16.0.1`)) && PathPrefix(`/imag`) documentIndex: 2 + - it: should render multiple services port + set: + appIngressroutes: + - name: app + path: /app + servicePortName: product + - name: api + path: /api + servicePortName: product + - name: example + path: /example + servicePortName: example + service: + ports: + - port: 80 + name: product + - port: 8080 + name: example + asserts: + - hasDocuments: + count: 3 + - isSubset: + path: spec.routes[0] + content: + services: + - name: RELEASE-NAME-application-chart-template + port: product + documentIndex: 0 + - isSubset: + path: spec.routes[0] + content: + services: + - name: RELEASE-NAME-application-chart-template + port: product + documentIndex: 1 + - isSubset: + path: spec.routes[0] + content: + services: + - name: RELEASE-NAME-application-chart-template + port: example + documentIndex: 2 + - it: should render middleware by default set: - appIngressroute: + appIngressroutes: - name: app path: /app + servicePortName: app + service: + ports: + - port: 80 + name: app asserts: - equal: path: spec.routes[0].middlewares[0].name diff --git a/values.yaml b/values.yaml index 943f8ee..6c9b9c5 100644 --- a/values.yaml +++ b/values.yaml @@ -56,9 +56,11 @@ externalIngressroute: [] # 应用服务配置 service: - name: http type: ClusterIP - port: 80 + ports: + - name: http + port: 80 + protocol: TCP # 覆盖 image command command: [] @@ -78,9 +80,10 @@ applicationTLS: {} # key: base64 encoding key-file # traefik 代理应用的匹配规则 -appIngressroute: [] +appIngressroutes: [] # - name: web # path: / + # servicePortName: http # 跨域相关设置 corsSettings: {}