Merge pull request #6490 from bacongobbler/port-create-enhancements

fix(chartutil): port over enhancements to `helm create` from Helm 2
pull/6584/head
Matthew Fisher 5 years ago committed by GitHub
commit 29765f4afe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -36,12 +36,13 @@ directories used in a chart.
For example, 'helm create foo' will create a directory structure that looks For example, 'helm create foo' will create a directory structure that looks
something like this: something like this:
foo/ foo/
.helmignore # Contains patterns to ignore when packaging Helm charts. .helmignore # Contains patterns to ignore when packaging Helm charts.
Chart.yaml # Information about your chart Chart.yaml # Information about your chart
values.yaml # The default values for your templates values.yaml # The default values for your templates
charts/ # Charts that this chart depends on charts/ # Charts that this chart depends on
templates/ # The template files templates/ # The template files
tests/ # The test files
'helm create' takes a path for an argument. If directories in the given path 'helm create' takes a path for an argument. If directories in the given path
do not exist, Helm will attempt to create them as it goes. If the given do not exist, Helm will attempt to create them as it goes. If the given

@ -106,8 +106,9 @@ func TestCreateStarterCmd(t *testing.T) {
t.Errorf("Wrong API version: %q", c.Metadata.APIVersion) t.Errorf("Wrong API version: %q", c.Metadata.APIVersion)
} }
if l := len(c.Templates); l != 6 { expectedNumberOfTemplates := 8
t.Errorf("Expected 5 templates, got %d", l) if l := len(c.Templates); l != expectedNumberOfTemplates {
t.Errorf("Expected %d templates, got %d", expectedNumberOfTemplates, l)
} }
found := false found := false
@ -173,8 +174,9 @@ func TestCreateStarterAbsoluteCmd(t *testing.T) {
t.Errorf("Wrong API version: %q", c.Metadata.APIVersion) t.Errorf("Wrong API version: %q", c.Metadata.APIVersion)
} }
if l := len(c.Templates); l != 6 { expectedNumberOfTemplates := 8
t.Errorf("Expected 5 templates, got %d", l) if l := len(c.Templates); l != expectedNumberOfTemplates {
t.Errorf("Expected %d templates, got %d", expectedNumberOfTemplates, l)
} }
found := false found := false

@ -39,6 +39,8 @@ const (
TemplatesDir = "templates" TemplatesDir = "templates"
// ChartsDir is the relative directory name for charts dependencies. // ChartsDir is the relative directory name for charts dependencies.
ChartsDir = "charts" ChartsDir = "charts"
// TemplatesTestsDir is the relative directory name for tests.
TemplatesTestsDir = TemplatesDir + sep + "tests"
// IgnorefileName is the name of the Helm ignore file. // IgnorefileName is the name of the Helm ignore file.
IgnorefileName = ".helmignore" IgnorefileName = ".helmignore"
// IngressFileName is the name of the example ingress file. // IngressFileName is the name of the example ingress file.
@ -47,10 +49,14 @@ const (
DeploymentName = TemplatesDir + sep + "deployment.yaml" DeploymentName = TemplatesDir + sep + "deployment.yaml"
// ServiceName is the name of the example service file. // ServiceName is the name of the example service file.
ServiceName = TemplatesDir + sep + "service.yaml" ServiceName = TemplatesDir + sep + "service.yaml"
// ServiceAccountName is the name of the example serviceaccount file.
ServiceAccountName = TemplatesDir + sep + "serviceaccount.yaml"
// NotesName is the name of the example NOTES.txt file. // NotesName is the name of the example NOTES.txt file.
NotesName = TemplatesDir + sep + "NOTES.txt" NotesName = TemplatesDir + sep + "NOTES.txt"
// HelpersName is the name of the example NOTES.txt file. // HelpersName is the name of the example helpers file.
HelpersName = TemplatesDir + sep + "_helpers.tpl" HelpersName = TemplatesDir + sep + "_helpers.tpl"
// TestConnectionName is the name of the example test file.
TestConnectionName = TemplatesTestsDir + sep + "test-connection.yaml"
) )
const sep = string(filepath.Separator) const sep = string(filepath.Separator)
@ -88,9 +94,28 @@ image:
repository: nginx repository: nginx
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
imagePullSecrets: []
nameOverride: "" nameOverride: ""
fullnameOverride: "" 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: service:
type: ClusterIP type: ClusterIP
port: 80 port: 80
@ -103,11 +128,10 @@ ingress:
hosts: hosts:
- host: chart-example.local - host: chart-example.local
paths: [] paths: []
tls: [] tls: []
# - secretName: chart-example-tls # - secretName: chart-example-tls
# hosts: # hosts:
# - chart-example.local # - chart-example.local
resources: {} resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious # We usually recommend not to specify default resources and to leave this as a conscious
@ -149,16 +173,13 @@ const defaultIgnore = `# Patterns to ignore when building packages.
.project .project
.idea/ .idea/
*.tmproj *.tmproj
.vscode/
` `
const defaultIngress = `{{- if .Values.ingress.enabled -}} const defaultIngress = `{{- if .Values.ingress.enabled -}}
{{- $fullName := include "<CHARTNAME>.fullname" . -}} {{- $fullName := include "<CHARTNAME>.fullname" . -}}
{{- $svcPort := .Values.service.port -}} {{- $svcPort := .Values.service.port -}}
{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress kind: Ingress
metadata: metadata:
name: {{ $fullName }} name: {{ $fullName }}
@ -210,8 +231,17 @@ spec:
labels: labels:
{{- include "<CHARTNAME>.selectorLabels" . | nindent 8 }} {{- include "<CHARTNAME>.selectorLabels" . | nindent 8 }}
spec: spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "<CHARTNAME>.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers: containers:
- name: {{ .Chart.Name }} - name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}" image: "{{ .Values.image.repository }}:{{ .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }} imagePullPolicy: {{ .Values.image.pullPolicy }}
ports: ports:
@ -228,10 +258,10 @@ spec:
port: http port: http
resources: resources:
{{- toYaml .Values.resources | nindent 12 }} {{- toYaml .Values.resources | nindent 12 }}
{{- with .Values.nodeSelector }} {{- with .Values.nodeSelector }}
nodeSelector: nodeSelector:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
{{- end }} {{- end }}
{{- with .Values.affinity }} {{- with .Values.affinity }}
affinity: affinity:
{{- toYaml . | nindent 8 }} {{- toYaml . | nindent 8 }}
@ -259,6 +289,16 @@ spec:
{{- include "<CHARTNAME>.selectorLabels" . | nindent 4 }} {{- include "<CHARTNAME>.selectorLabels" . | nindent 4 }}
` `
const defaultServiceAccount = `{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "<CHARTNAME>.serviceAccountName" . }}
labels:
{{ include "<CHARTNAME>.labels" . | nindent 4 }}
{{- end -}}
`
const defaultNotes = `1. Get the application URL by running these commands: const defaultNotes = `1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }} {{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }} {{- range $host := .Values.ingress.hosts }}
@ -267,16 +307,16 @@ const defaultNotes = `1. Get the application URL by running these commands:
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- else if contains "NodePort" .Values.service.type }} {{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "<CHARTNAME>.fullname" . }}) export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "<CHARTNAME>.fullname" . }})
export NODE_IP=$(kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}") export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }} {{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available. NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ include "<CHARTNAME>.fullname" . }}' You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "<CHARTNAME>.fullname" . }}'
export SERVICE_IP=$(kubectl get svc {{ include "<CHARTNAME>.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "<CHARTNAME>.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }} echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }} {{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods -l "app.kubernetes.io/name={{ include "<CHARTNAME>.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "<CHARTNAME>.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" echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80 kubectl port-forward $POD_NAME 8080:80
{{- end }} {{- end }}
@ -334,6 +374,34 @@ Selector labels
app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }} app.kubernetes.io/name: {{ include "<CHARTNAME>.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}} {{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "<CHARTNAME>.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "<CHARTNAME>.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
`
const defaultTestConnection = `apiVersion: v1
kind: Pod
metadata:
name: "{{ include "<CHARTNAME>.fullname" . }}-test-connection"
labels:
{{ include "<CHARTNAME>.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test-success
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "<CHARTNAME>.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never
` `
// CreateFrom creates a new chart, but scaffolds it from the src chart. // CreateFrom creates a new chart, but scaffolds it from the src chart.
@ -431,6 +499,11 @@ func Create(name, dir string) (string, error) {
path: filepath.Join(cdir, ServiceName), path: filepath.Join(cdir, ServiceName),
content: transform(defaultService, name), content: transform(defaultService, name),
}, },
{
// serviceaccount.yaml
path: filepath.Join(cdir, ServiceAccountName),
content: transform(defaultServiceAccount, name),
},
{ {
// NOTES.txt // NOTES.txt
path: filepath.Join(cdir, NotesName), path: filepath.Join(cdir, NotesName),
@ -441,6 +514,11 @@ func Create(name, dir string) (string, error) {
path: filepath.Join(cdir, HelpersName), path: filepath.Join(cdir, HelpersName),
content: transform(defaultHelpers, name), content: transform(defaultHelpers, name),
}, },
{
// test-connection.yaml
path: filepath.Join(cdir, TestConnectionName),
content: transform(defaultTestConnection, name),
},
} }
for _, file := range files { for _, file := range files {

@ -55,8 +55,11 @@ func TestCreate(t *testing.T) {
HelpersName, HelpersName,
IgnorefileName, IgnorefileName,
NotesName, NotesName,
ServiceAccountName,
ServiceName, ServiceName,
TemplatesDir, TemplatesDir,
TemplatesTestsDir,
TestConnectionName,
ValuesfileName, ValuesfileName,
} { } {
if _, err := os.Stat(filepath.Join(dir, f)); err != nil { if _, err := os.Stat(filepath.Join(dir, f)); err != nil {

Loading…
Cancel
Save