internal/helm: add helpers to load chart metadata
This commits adds `LoadChartMetadataFromArchive` and `LoadChartMetadataFromDir` helpers to the internal `helm` package to be able to make observations to the Helm metadata file without loading the chart in full. The helpers are compatible with charts of the v1 format (with a separate `requirements.yaml` file), and an additional `LoadChartMetadata` helper is available to automatically call the right `LoadChartMetadataFrom*` version by looking at the file description of the given path. Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
parent
cc2bc5691a
commit
8537a0f8fa
|
@ -17,15 +17,24 @@ limitations under the License.
|
|||
package helm
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bufio"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
helmchart "helm.sh/helm/v3/pkg/chart"
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
// OverwriteChartDefaultValues overwrites the chart default values file with the
|
||||
// given data.
|
||||
// OverwriteChartDefaultValues overwrites the chart default values file with the given data.
|
||||
func OverwriteChartDefaultValues(chart *helmchart.Chart, data []byte) (bool, error) {
|
||||
// Read override values file data
|
||||
values, err := chartutil.ReadValues(data)
|
||||
|
@ -57,3 +66,127 @@ func OverwriteChartDefaultValues(chart *helmchart.Chart, data []byte) (bool, err
|
|||
// This should never happen, helm charts must have a values.yaml file to be valid
|
||||
return false, fmt.Errorf("failed to locate values file: %s", chartutil.ValuesfileName)
|
||||
}
|
||||
|
||||
// LoadChartMetadata attempts to load the chart.Metadata from the "Chart.yaml" file in the directory or archive at the
|
||||
// given chartPath. It takes "requirements.yaml" files into account, and is therefore compatible with the
|
||||
// chart.APIVersionV1 format.
|
||||
func LoadChartMetadata(chartPath string) (*helmchart.Metadata, error) {
|
||||
i, err := os.Stat(chartPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch {
|
||||
case i.IsDir():
|
||||
return LoadChartMetadataFromDir(chartPath)
|
||||
default:
|
||||
return LoadChartMetadataFromArchive(chartPath)
|
||||
}
|
||||
}
|
||||
|
||||
// LoadChartMetadataFromDir loads the chart.Metadata from the "Chart.yaml" file in the directory at the given path.
|
||||
// It takes "requirements.yaml" files into account, and is therefore compatible with the chart.APIVersionV1 format.
|
||||
func LoadChartMetadataFromDir(dir string) (*helmchart.Metadata, error) {
|
||||
m := new(helmchart.Metadata)
|
||||
|
||||
b, err := os.ReadFile(filepath.Join(dir, chartutil.ChartfileName))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = yaml.Unmarshal(b, m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load '%s': %w", chartutil.ChartfileName, err)
|
||||
}
|
||||
if m.APIVersion == "" {
|
||||
m.APIVersion = helmchart.APIVersionV1
|
||||
}
|
||||
|
||||
b, err = os.ReadFile(filepath.Join(dir, "requirements.yaml"))
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return nil, err
|
||||
}
|
||||
if len(b) > 0 {
|
||||
if err = yaml.Unmarshal(b, m); err != nil {
|
||||
return nil, fmt.Errorf("cannot load 'requirements.yaml': %w", err)
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// LoadChartMetadataFromArchive loads the chart.Metadata from the "Chart.yaml" file in the archive at the given path.
|
||||
// It takes "requirements.yaml" files into account, and is therefore compatible with the chart.APIVersionV1 format.
|
||||
func LoadChartMetadataFromArchive(archive string) (*helmchart.Metadata, error) {
|
||||
f, err := os.Open(archive)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
r := bufio.NewReader(f)
|
||||
zr, err := gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tr := tar.NewReader(zr)
|
||||
|
||||
var m *helmchart.Metadata
|
||||
for {
|
||||
hd, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if hd.FileInfo().IsDir() {
|
||||
// Use this instead of hd.Typeflag because we don't have to do any
|
||||
// inference chasing.
|
||||
continue
|
||||
}
|
||||
|
||||
switch hd.Typeflag {
|
||||
// We don't want to process these extension header files.
|
||||
case tar.TypeXGlobalHeader, tar.TypeXHeader:
|
||||
continue
|
||||
}
|
||||
|
||||
// Archive could contain \ if generated on Windows
|
||||
delimiter := "/"
|
||||
if strings.ContainsRune(hd.Name, '\\') {
|
||||
delimiter = "\\"
|
||||
}
|
||||
parts := strings.Split(hd.Name, delimiter)
|
||||
|
||||
// We are only interested in files in the base directory
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Normalize the path to the / delimiter
|
||||
n := strings.Join(parts[1:], delimiter)
|
||||
n = strings.ReplaceAll(n, delimiter, "/")
|
||||
n = path.Clean(n)
|
||||
|
||||
switch parts[1] {
|
||||
case chartutil.ChartfileName, "requirements.yaml":
|
||||
b, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if m == nil {
|
||||
m = new(helmchart.Metadata)
|
||||
}
|
||||
err = yaml.Unmarshal(b, m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load '%s': %w", parts[1], err)
|
||||
}
|
||||
if m.APIVersion == "" {
|
||||
m.APIVersion = helmchart.APIVersionV1
|
||||
}
|
||||
}
|
||||
}
|
||||
if m == nil {
|
||||
return nil, fmt.Errorf("no '%s' found", chartutil.ChartfileName)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
|
|
@ -20,19 +20,20 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
helmchart "helm.sh/helm/v3/pkg/chart"
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
)
|
||||
|
||||
var (
|
||||
originalValuesFixture []byte = []byte("override: original")
|
||||
chartFilesFixture []*helmchart.File = []*helmchart.File{
|
||||
originalValuesFixture = []byte("override: original")
|
||||
chartFilesFixture = []*helmchart.File{
|
||||
{
|
||||
Name: "values.yaml",
|
||||
Data: originalValuesFixture,
|
||||
},
|
||||
}
|
||||
chartFixture helmchart.Chart = helmchart.Chart{
|
||||
chartFixture = helmchart.Chart{
|
||||
Metadata: &helmchart.Metadata{
|
||||
Name: "test",
|
||||
Version: "0.1.0",
|
||||
|
@ -111,3 +112,108 @@ func TestOverwriteChartDefaultValues(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_LoadChartMetadataFromDir(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dir string
|
||||
wantName string
|
||||
wantVersion string
|
||||
wantDependencyCount int
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "Loads from dir",
|
||||
dir: "testdata/charts/helmchart",
|
||||
wantName: "helmchart",
|
||||
wantVersion: "0.1.0",
|
||||
},
|
||||
{
|
||||
name: "Loads from v1 dir including requirements.yaml",
|
||||
dir: "testdata/charts/helmchartwithdeps-v1",
|
||||
wantName: chartNameV1,
|
||||
wantVersion: chartVersionV1,
|
||||
wantDependencyCount: 1,
|
||||
},
|
||||
{
|
||||
name: "Error if no Chart.yaml",
|
||||
dir: "testdata/charts/",
|
||||
wantErr: "testdata/charts/Chart.yaml: no such file or directory",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
got, err := LoadChartMetadataFromDir(tt.dir)
|
||||
if tt.wantErr != "" {
|
||||
g.Expect(err).To(HaveOccurred())
|
||||
g.Expect(err.Error()).To(ContainSubstring(tt.wantErr))
|
||||
g.Expect(got).To(BeNil())
|
||||
return
|
||||
}
|
||||
|
||||
g.Expect(err).ToNot(HaveOccurred())
|
||||
g.Expect(got).ToNot(BeNil())
|
||||
g.Expect(got.Validate()).To(Succeed())
|
||||
g.Expect(got.Name).To(Equal(tt.wantName))
|
||||
g.Expect(got.Version).To(Equal(tt.wantVersion))
|
||||
g.Expect(got.Dependencies).To(HaveLen(tt.wantDependencyCount))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadChartMetadataFromArchive(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
archive string
|
||||
wantName string
|
||||
wantVersion string
|
||||
wantDependencyCount int
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "Loads from archive",
|
||||
archive: helmPackageFile,
|
||||
wantName: chartName,
|
||||
wantVersion: chartVersion,
|
||||
},
|
||||
{
|
||||
name: "Loads from v1 archive including requirements.yaml",
|
||||
archive: helmPackageV1File,
|
||||
wantName: chartNameV1,
|
||||
wantVersion: chartVersionV1,
|
||||
wantDependencyCount: 1,
|
||||
},
|
||||
{
|
||||
name: "Error on not found",
|
||||
archive: "testdata/invalid.tgz",
|
||||
wantErr: "no such file or directory",
|
||||
},
|
||||
{
|
||||
name: "Error if no Chart.yaml",
|
||||
archive: "testdata/charts/empty.tgz",
|
||||
wantErr: "no 'Chart.yaml' found",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
got, err := LoadChartMetadataFromArchive(tt.archive)
|
||||
if tt.wantErr != "" {
|
||||
g.Expect(err).To(HaveOccurred())
|
||||
g.Expect(err.Error()).To(ContainSubstring(tt.wantErr))
|
||||
g.Expect(got).To(BeNil())
|
||||
return
|
||||
}
|
||||
|
||||
g.Expect(err).ToNot(HaveOccurred())
|
||||
g.Expect(got).ToNot(BeNil())
|
||||
g.Expect(got.Validate()).To(Succeed())
|
||||
g.Expect(got.Name).To(Equal(tt.wantName))
|
||||
g.Expect(got.Version).To(Equal(tt.wantVersion))
|
||||
g.Expect(got.Dependencies).To(HaveLen(tt.wantDependencyCount))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
helmPackageFile = "testdata/charts/helmchart-0.1.0.tgz"
|
||||
|
||||
// helmPackageFile contains the path to a Helm package in the v2 format
|
||||
// without any dependencies
|
||||
helmPackageFile = "testdata/charts/helmchart-0.1.0.tgz"
|
||||
chartName = "helmchart"
|
||||
chartVersion = "0.1.0"
|
||||
chartLocalRepository = "file://../helmchart"
|
||||
|
@ -38,6 +39,12 @@ var (
|
|||
Version: chartVersion,
|
||||
Repository: "https://example.com/charts",
|
||||
}
|
||||
// helmPackageV1File contains the path to a Helm package in the v1 format,
|
||||
// including dependencies in a requirements.yaml file which should be
|
||||
// loaded
|
||||
helmPackageV1File = "testdata/charts/helmchartwithdeps-v1-0.3.0.tgz"
|
||||
chartNameV1 = "helmchartwithdeps-v1"
|
||||
chartVersionV1 = "0.3.0"
|
||||
)
|
||||
|
||||
func TestBuild_WithEmptyDependencies(t *testing.T) {
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
|||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
|
@ -0,0 +1,5 @@
|
|||
apiVersion: v1
|
||||
appVersion: "1.0"
|
||||
description: A legacy Helm chart for Kubernetes
|
||||
name: helmchart-v1
|
||||
version: 0.2.0
|
|
@ -0,0 +1,21 @@
|
|||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helmchart-v1.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helmchart-v1.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helmchart-v1.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helmchart-v1.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl port-forward $POD_NAME 8080:80
|
||||
{{- end }}
|
|
@ -0,0 +1,56 @@
|
|||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "helmchart-v1.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 "helmchart-v1.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 "helmchart-v1.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "helmchart-v1.labels" -}}
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
helm.sh/chart: {{ include "helmchart-v1.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "helmchart-v1.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
{{ default (include "helmchart-v1.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else -}}
|
||||
{{ default "default" .Values.serviceAccount.name }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
|
@ -0,0 +1,57 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "helmchart-v1.fullname" . }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ template "helmchart-v1.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
|
@ -0,0 +1,41 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "helmchart-v1.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ . }}
|
||||
backend:
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,16 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "helmchart-v1.fullname" . }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
|
@ -0,0 +1,8 @@
|
|||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ template "helmchart-v1.serviceAccountName" . }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
{{- end -}}
|
15
internal/helm/testdata/charts/helmchart-v1/templates/tests/test-connection.yaml
vendored
Normal file
15
internal/helm/testdata/charts/helmchart-v1/templates/tests/test-connection.yaml
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "helmchart-v1.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test-success
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "helmchart-v1.fullname" . }}:{{ .Values.service.port }}']
|
||||
restartPolicy: Never
|
|
@ -0,0 +1,68 @@
|
|||
# Default values for helmchart-v1.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: nginx
|
||||
tag: stable
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths: []
|
||||
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
|||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
|
@ -0,0 +1,5 @@
|
|||
apiVersion: v1
|
||||
appVersion: "1.0"
|
||||
description: A legacy Helm chart for Kubernetes
|
||||
name: helmchartwithdeps-v1
|
||||
version: 0.3.0
|
|
@ -0,0 +1,4 @@
|
|||
dependencies:
|
||||
- name: helmchart-v1
|
||||
version: "0.2.0"
|
||||
repository: "file://../helmchart-v1"
|
|
@ -0,0 +1,21 @@
|
|||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "helmchart-v1.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "helmchart-v1.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helmchart-v1.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "helmchart-v1.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl port-forward $POD_NAME 8080:80
|
||||
{{- end }}
|
|
@ -0,0 +1,56 @@
|
|||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "helmchart-v1.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 "helmchart-v1.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 "helmchart-v1.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "helmchart-v1.labels" -}}
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
helm.sh/chart: {{ include "helmchart-v1.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "helmchart-v1.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
{{ default (include "helmchart-v1.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else -}}
|
||||
{{ default "default" .Values.serviceAccount.name }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
57
internal/helm/testdata/charts/helmchartwithdeps-v1/templates/deployment.yaml
vendored
Normal file
57
internal/helm/testdata/charts/helmchartwithdeps-v1/templates/deployment.yaml
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "helmchart-v1.fullname" . }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ template "helmchart-v1.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
|
@ -0,0 +1,41 @@
|
|||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "helmchart-v1.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ . }}
|
||||
backend:
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,16 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "helmchart-v1.fullname" . }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ include "helmchart-v1.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
8
internal/helm/testdata/charts/helmchartwithdeps-v1/templates/serviceaccount.yaml
vendored
Normal file
8
internal/helm/testdata/charts/helmchartwithdeps-v1/templates/serviceaccount.yaml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ template "helmchart-v1.serviceAccountName" . }}
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
{{- end -}}
|
15
internal/helm/testdata/charts/helmchartwithdeps-v1/templates/tests/test-connection.yaml
vendored
Normal file
15
internal/helm/testdata/charts/helmchartwithdeps-v1/templates/tests/test-connection.yaml
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "helmchart-v1.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{ include "helmchart-v1.labels" . | indent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test-success
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "helmchart-v1.fullname" . }}:{{ .Values.service.port }}']
|
||||
restartPolicy: Never
|
|
@ -0,0 +1,68 @@
|
|||
# Default values for helmchart-v1.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: nginx
|
||||
tag: stable
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths: []
|
||||
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
Loading…
Reference in New Issue