added a new chart static-site that build and host static sites. (#64)

Co-authored-by: Youcef Guichi <youcef@gimlet.io>
This commit is contained in:
Laszlo Fogas
2023-03-30 13:54:27 +02:00
committed by GitHub
parent 0b7faf42ac
commit 00becd0fab
18 changed files with 658 additions and 0 deletions
+2
View File
@@ -36,6 +36,8 @@ test:
helm unittest charts/namespaces
helm unittest charts/static-site
package:
helm dependency update charts/onechart
helm package charts/onechart
Binary file not shown.
Binary file not shown.
+23
View File
@@ -0,0 +1,23 @@
# 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
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
+18
View File
@@ -0,0 +1,18 @@
apiVersion: v2
name: static-site
description: Chart to build and deploy static sites
# 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.1.0
+31
View File
@@ -0,0 +1,31 @@
[
{
"schemaIDs": [
"#/properties/gitCloneUrl",
"#/properties/buildImage",
"#/properties/buildTag",
"#/properties/buildScript",
"#/properties/builtAssets"
],
"uiSchema": {
"#/properties/buildScript":{
"ui:widget": "textarea"
}
},
"metaData": {
"name": "Build",
"icon": "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"
}
},
{
"schemaIDs": [
"#/properties/ingress"
],
"uiSchema": {},
"metaData": {
"name": "Ingress",
"icon": "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
}
}
]
+1
View File
@@ -0,0 +1 @@
+71
View File
@@ -0,0 +1,71 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "staticSite.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 "staticSite.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 "staticSite.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "staticSite.labels" -}}
helm.sh/chart: {{ include "staticSite.chart" . }}
{{ include "staticSite.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "staticSite.selectorLabels" -}}
app.kubernetes.io/name: {{ include "staticSite.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "staticSite.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "staticSite.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create robustName that can be used as Kubernetes resource name, and as subdomain as well
\w Latin letters, digits, underscore '_' .
\W all but \w .
*/}}
{{- define "robustName" -}}
{{ regexReplaceAll "\\W+" . "-" | replace "_" "-" | lower | trunc 63 | trimSuffix "-" }}
{{- end }}
@@ -0,0 +1,61 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "robustName" .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "staticSite.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "staticSite.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "staticSite.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "robustName" .Release.Name }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
volumes:
- name: static-files
emptyDir: {}
initContainers:
- name: init-con
image: {{ .Values.buildImage }}:{{ .Values.buildTag }}
{{- if .Values.buildScript }}
command:
- sh
- -c
- |
git clone {{ .Values.gitCloneUrl}} &&
cd {{ regexFind "([^\\/]+$)" .Values.gitCloneUrl | replace ".git" "" }} &&
{{ .Values.buildScript | nindent 12}}
mkdir -p /usr/share/nginx/html &&
cp -r ./{{ .Values.builtAssets }}. /usr/share/nginx/html
{{- end }}
volumeMounts:
- name: static-files
mountPath: /usr/share/nginx/html
containers:
- name: {{ template "robustName" .Release.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
volumeMounts:
- name: static-files
mountPath: /usr/share/nginx/html
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
+52
View File
@@ -0,0 +1,52 @@
{{/* OneChart ingress snippet */}}
{{- define "onechart.ingress" }}
{{- $robustName := include "robustName" .root.Release.Name -}}
{{- $resourceName := $robustName -}}
{{- if .longName }}
{{- $resourceName = printf "%s-%s" $robustName (include "robustName" .ingress.host) -}}
{{- end }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $resourceName }}
namespace: {{ .root.Release.Namespace }}
labels:
{{- include "staticSite.labels" .root | nindent 4 }}
{{- if or (or .root.Values.gitSha .ingress.annotations) .root.Values.gitRepository }}
annotations:
{{- if .ingress.annotations }}
{{- toYaml .ingress.annotations | nindent 4 }}
{{- end }}
{{- end }}
spec:
{{- if .ingress.ingressClassName }}
ingressClassName: {{ .ingress.ingressClassName }}
{{- end }}
{{- if default false .ingress.tlsEnabled }}
tls:
- hosts:
- {{ .ingress.host | quote }}
secretName: {{ printf "tls-%s" $resourceName }}
{{- end }}
rules:
- host: {{ .ingress.host | quote }}
http:
paths:
- path: {{ .ingress.path | default "/" | quote }}
pathType: "Prefix"
backend:
service:
name: {{ $robustName }}
port:
number: {{ .root.Values.service.port }}
{{- end }}
{{- with .Values.ingress }}
{{- template "onechart.ingress" (dict "root" $ "ingress" .) }}
{{- end }}
{{- range .Values.ingresses }}
{{template "onechart.ingress" (dict "root" $ "ingress" . "longName" true) }}
{{- end }}
+15
View File
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "robustName" .Release.Name }}
labels:
{{- include "staticSite.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "staticSite.selectorLabels" . | nindent 4 }}
@@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ template "robustName" .Release.Name }}
labels:
{{- include "staticSite.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
@@ -0,0 +1,15 @@
suite: test deployment
templates:
- deployment.yaml
tests:
- it: Should set image, tag and command
set:
gitCloneUrl: https:/github.com/mycompany/myrepo.git
buildImage: nginx
buildTag: x.y.z
asserts:
- equal:
path: spec.template.spec.initContainers[0].image
value: nginx:x.y.z
@@ -0,0 +1,120 @@
suite: test deployment
templates:
- ingress.yaml
tests:
- it: Should set Ingress host name
set:
ingress:
host: chart-example.local
tlsEnabled: true
asserts:
- equal:
path: spec.tls
value:
- hosts:
- chart-example.local
secretName: tls-release-name
- equal:
path: spec.rules
value:
- host: chart-example.local
http:
paths:
- path: "/"
pathType: "Prefix"
backend:
service:
name: release-name
port:
number: 80
- it: Should pass ingress host name as is, user must sanitize it
set:
ingress:
host: feature/my_branch.local
tlsEnabled: true
asserts:
- equal:
path: spec.tls
value:
- hosts:
- feature/my_branch.local
secretName: tls-release-name
- equal:
path: spec.rules
value:
- host: feature/my_branch.local
http:
paths:
- path: "/"
pathType: "Prefix"
backend:
service:
name: release-name
port:
number: 80
- it: Should set Ingress annotation
set:
ingress:
host: chart-example.local
annotations:
just/a-random: annotation
asserts:
- equal:
path: metadata.annotations
value:
just/a-random: annotation
- it: Should set ingress class
set:
ingress:
host: chart-example.local
ingressClassName: nginx
asserts:
- equal:
path: spec.ingressClassName
value: nginx
- it: Should generate multiple ingresses
set:
ingresses:
- host: chart-example.local
annotations:
kubernetes.io/ingress.class: nginx
- host: another.local
annotations:
kubernetes.io/ingress.class: nginx
asserts:
- hasDocuments:
count: 2
- it: Should generate multiple ingresses
set:
ingress:
host: chart-example.local
annotations:
kubernetes.io/ingress.class: nginx
ingresses:
- host: chart-example.local
annotations:
kubernetes.io/ingress.class: nginx
- host: another.local
annotations:
kubernetes.io/ingress.class: nginx
asserts:
- hasDocuments:
count: 3
- it: Should have unique TLS secret names
set:
ingresses:
- host: chart-example.local
tlsEnabled: true
annotations:
kubernetes.io/ingress.class: nginx
- host: another.local
tlsEnabled: true
annotations:
kubernetes.io/ingress.class: nginx
asserts:
- equal:
path: spec.tls
value:
- hosts:
- chart-example.local
secretName: tls-release-name-chart-example-local
@@ -0,0 +1,21 @@
suite: test ingress
templates:
- ingress.yaml
tests:
- it: Should default
set:
ingress:
host: chart-example.local
asserts:
- equal:
path: spec.rules[0].http.paths[0].path
value: "/"
- it: Should use path
set:
ingress:
host: chart-example.local
path: "/mypath"
asserts:
- equal:
path: spec.rules[0].http.paths[0].path
value: "/mypath"
@@ -0,0 +1,12 @@
suite: test deployment
templates:
- ingress.yaml
tests:
- it: Should use service port
set:
ingress:
host: chart-example.local
asserts:
- equal:
path: spec.rules[0].http.paths[0].backend.service.port.number
value: 1234
+125
View File
@@ -0,0 +1,125 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"title": "The root schema",
"description": "The root schema comprises the entire JSON document.",
"default": {},
"examples": [
{
"gitCloneUrl": "https://github.com/gimlet-io/hugo-site.git",
"buildImage": "node",
"buildTag": "latest",
"buildScript": "npm install && npm install -g gatsby-cli && gatsby build",
"builtAssets": "public/"
}
],
"required": [
"gitCloneUrl",
"buildImage",
"buildTag",
"buildScript",
"builtAssets"
],
"properties": {
"gitCloneUrl": {
"$id": "#/properties/gitCloneUrl",
"type": "string",
"title": "Repo url",
"description": "The static site's git repository",
"default": "https://github.com/gimlet-io/hugo-site.git"
},
"buildImage": {
"$id": "#/properties/buildImage",
"type": "string",
"title": "Build image",
"description": "The image that will be used for the build proccess",
"default":"bitnami/git"
},
"buildTag": {
"$id": "#/properties/buildTag",
"type": "string",
"title": "Image tag",
"default": "latest"
},
"buildScript": {
"$id": "#/properties/buildScript",
"type": "string",
"title": "Build script",
"description": "Commands required for the build to be completed",
"default": "# !/usr/bin/env bash\n# pre -reqs\napt-get update && apt-get install -y wget\n\n# Setting up Hugo \nwget https://github.com/gohugoio/hugo/releases/download/v0.111.3/hugo_0.111.3_Linux-64bit.tar.gz &&\ntar -xzf hugo_0.111.3_Linux-64bit.tar.gz &&\nchmod +x hugo\n\n./hugo"
},
"builtAssets": {
"$id": "#/properties/builtAssets",
"type": "string",
"title": "Built assets",
"description": "The folder containing the build's generated files",
"default": "public/"
},
"ingress": {
"$id": "#/properties/ingress",
"type": "object",
"title": "Incoming traffic",
"description": "",
"default": {},
"examples": [
{
"tlsEnabled": false,
"annotations": {
"kubernetes.io/ingress.class": "nginx"
},
"host": "my-release.mycompany.com"
}
],
"required": [],
"properties": {
"host": {
"$id": "#/properties/ingress/properties/host",
"type": "string",
"title": "Host Name",
"description": "Where your application will be accessible",
"default": "",
"examples": [
"my-release.mycompany.com"
]
},
"path": {
"$id": "#/properties/ingress/properties/ingressPath",
"type": "string",
"title": "Path",
"description": "The API path where your service is accessible",
"default": "/",
"examples": [
"/api/myservice"
]
},
"tlsEnabled": {
"$id": "#/properties/ingress/properties/tlsEnabled",
"type": "boolean",
"title": "HTTPS",
"description": "",
"default": false,
"examples": [
false
]
},
"annotations": {
"$id": "#/properties/ingress/properties/annotations",
"type": "object",
"title": "Annotations",
"description": "Annotations are used to control ingress behavior. See the full list for the Ingress Nginx project at https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/. Use the `cert-manager.io/cluster-issuer:\"letsencrypt\"` one to request TLS certificates, `kubernetes.io/ingress.class: \"nginx\"` to select an ingress controller.",
"default": {},
"examples": [
{
"kubernetes.io/ingress.class": "nginx"
}
],
"additionalProperties": true
}
}
}
},
"additionalProperties": true
}
+79
View File
@@ -0,0 +1,79 @@
# Default values for static-site.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
image:
repository: nginx
tag: latest
pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext:
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
runAsUser: 0
service:
type: ClusterIP
port: 80
# ingress:
# host: dummyapp.127.0.0.1.nip.io
# ingressClassName: nginx
# tlsEnabled: false
# annotations:
# cert-manager.io/cluster-issuer: letsencrypt-staging
resources:
requests:
cpu: 200m
memory: 200Mi
limits:
cpu: 200m
memory: 200Mi
nodeSelector: {}
tolerations: []
affinity: {}
# values to build and deploy static sites
gitCloneUrl: https://github.com/gimlet-io/hugo-site.git
buildImage: bitnami/git # the image must have git installed
buildTag: latest
buildScript: |
# !/usr/bin/env bash
# pre -reqs
apt-get update && apt-get install -y wget
# Setting up Hugo
wget https://github.com/gohugoio/hugo/releases/download/v0.111.3/hugo_0.111.3_Linux-64bit.tar.gz &&
tar -xzf hugo_0.111.3_Linux-64bit.tar.gz &&
chmod +x hugo
./hugo
builtAssets: public/