feat(*): add Values namespace to templates

This adds the .Values namespace qualifier to all values
pull/873/head
Matt Butcher 9 years ago
parent 1dc95be105
commit 22ac61469f

@ -238,13 +238,17 @@ func (s *releaseServer) InstallRelease(c ctx.Context, req *services.InstallRelea
// Render the templates // Render the templates
// TODO: Fix based on whether chart has `engine: SOMETHING` set. // TODO: Fix based on whether chart has `engine: SOMETHING` set.
vals, err := chartutil.CoalesceValues(req.Chart, req.Values, overrides) //vals, err := chartutil.CoalesceValues(req.Chart, req.Values, overrides)
vals, err := chartutil.CoalesceValues(req.Chart, req.Values, nil)
if err != nil { if err != nil {
return nil, err return nil, err
} }
overrides["Values"] = vals
renderer := s.engine(req.Chart) renderer := s.engine(req.Chart)
files, err := renderer.Render(req.Chart, vals) files, err := renderer.Render(req.Chart, overrides)
//files, err := renderer.Render(req.Chart, vals)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -1,7 +1,7 @@
apiVersion: v1 apiVersion: v1
kind: Pod kind: Pod
metadata: metadata:
name: "{{.Release.Name}}-{{.Chart.Name}}" name: "{{.Release.Name}}-{{.Values.Name}}"
labels: labels:
# The "heritage" label is used to track which tool deployed a given chart. # The "heritage" label is used to track which tool deployed a given chart.
# It is useful for admins who want to see what releases a particular tool # It is useful for admins who want to see what releases a particular tool
@ -19,7 +19,7 @@ spec:
# called restartPolicy. If it is not found, it will use the default value. # called restartPolicy. If it is not found, it will use the default value.
# {{default "Never" .restartPolicy}} is a slightly optimized version of the # {{default "Never" .restartPolicy}} is a slightly optimized version of the
# more conventional syntax: {{.restartPolicy | default "Never"}} # more conventional syntax: {{.restartPolicy | default "Never"}}
restartPolicy: {{default "Never" .restartPolicy}} restartPolicy: {{default "Never" .Values.restartPolicy}}
containers: containers:
- name: waiter - name: waiter
image: "alpine:3.3" image: "alpine:3.3"

@ -2,7 +2,7 @@
{{/* {{/*
Expand the name of the chart. Expand the name of the chart.
*/}} */}}
{{define "name"}}{{default "nginx" .nameOverride | trunc 24 }}{{end}} {{define "name"}}{{default "nginx" .Values.nameOverride | trunc 24 }}{{end}}
{{/* {{/*
Create a default fully qualified app name. Create a default fully qualified app name.
@ -10,4 +10,4 @@ Create a default fully qualified app name.
We truncate at 24 chars because some Kubernetes name fields are limited to this We truncate at 24 chars because some Kubernetes name fields are limited to this
(by the DNS naming spec). (by the DNS naming spec).
*/}} */}}
{{define "fullname"}}{{.Release.Name}}-{{default "nginx" .nameOverride | trunc 24 }}{{end}} {{define "fullname"}}{{.Release.Name}}-{{default "nginx" .Values.nameOverride | trunc 24 }}{{end}}

@ -11,5 +11,5 @@ metadata:
data: data:
# When the config map is mounted as a volume, these will be created as # When the config map is mounted as a volume, these will be created as
# files. # files.
index.html: {{ default "Hello" .index | quote }} index.html: {{default "Hello" .Values.index | quote}}
test.txt: test test.txt: test

@ -15,7 +15,7 @@ metadata:
# This makes it easy to audit chart usage. # This makes it easy to audit chart usage.
chart: "{{.Chart.Name}}-{{.Chart.Version}}" chart: "{{.Chart.Name}}-{{.Chart.Version}}"
spec: spec:
replicas: {{ default 1 .replicaCount | quote }} replicas: {{default 1 .Values.replicaCount | quote}}
template: template:
metadata: metadata:
labels: labels:
@ -28,8 +28,8 @@ spec:
# is a nice option for the user. Especially in the strange cases like # is a nice option for the user. Especially in the strange cases like
# nginx where the base distro is determined by the tag. Using :latest # nginx where the base distro is determined by the tag. Using :latest
# is frowned upon, using :stable isn't that great either. # is frowned upon, using :stable isn't that great either.
image: "{{default "nginx" .image}}:{{default "stable-alpine" .imageTag}}" image: "{{default "nginx" .Values.image}}:{{default "stable-alpine" .Values.imageTag}}"
imagePullPolicy: {{default "IfNotPresent" .pullPolicy}} imagePullPolicy: {{default "IfNotPresent" .Values.pullPolicy}}
ports: ports:
- containerPort: 80 - containerPort: 80
# This (and the volumes section below) mount the config map as a volume. # This (and the volumes section below) mount the config map as a volume.

@ -10,7 +10,7 @@ metadata:
chart: "{{.Chart.Name}}-{{.Chart.Version}}" chart: "{{.Chart.Name}}-{{.Chart.Version}}"
spec: spec:
ports: ports:
- port: {{ default 80 .httpPort | quote }} - port: {{default 80 .Values.httpPort | quote}}
targetPort: 80 targetPort: 80
protocol: TCP protocol: TCP
name: http name: http

@ -94,7 +94,8 @@ func tableLookup(v Values, simple string) (Values, error) {
if !ok { if !ok {
return v, ErrNoTable return v, ErrNoTable
} }
vv, ok := v2.(map[string]interface{}) //vv, ok := v2.(map[string]interface{})
vv, ok := v2.(Values)
if !ok { if !ok {
return vv, ErrNoTable return vv, ErrNoTable
} }

@ -19,6 +19,7 @@ package engine
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"log"
"text/template" "text/template"
"github.com/Masterminds/sprig" "github.com/Masterminds/sprig"
@ -71,6 +72,7 @@ func New() *Engine {
func (e *Engine) Render(chrt *chart.Chart, values chartutil.Values) (map[string]string, error) { func (e *Engine) Render(chrt *chart.Chart, values chartutil.Values) (map[string]string, error) {
// Render the charts // Render the charts
tmap := allTemplates(chrt, values) tmap := allTemplates(chrt, values)
fmt.Printf("%v", tmap)
return e.render(tmap) return e.render(tmap)
} }
@ -104,7 +106,7 @@ func (e *Engine) render(tpls map[string]renderable) (map[string]string, error) {
rendered := make(map[string]string, len(files)) rendered := make(map[string]string, len(files))
var buf bytes.Buffer var buf bytes.Buffer
for _, file := range files { for _, file := range files {
// log.Printf("Exec %s with %v (%s)", file, tpls[file].vals, tpls[file].tpl) log.Printf("Exec %s with %v (%s)", file, tpls[file].vals, tpls[file].tpl)
if err := t.ExecuteTemplate(&buf, file, tpls[file].vals); err != nil { if err := t.ExecuteTemplate(&buf, file, tpls[file].vals); err != nil {
return map[string]string{}, fmt.Errorf("render error in %q: %s", file, err) return map[string]string{}, fmt.Errorf("render error in %q: %s", file, err)
} }
@ -137,9 +139,23 @@ func recAllTpls(c *chart.Chart, templates map[string]renderable, parentVals char
} else if c.Metadata != nil && c.Metadata.Name != "" { } else if c.Metadata != nil && c.Metadata.Name != "" {
// An error indicates that the table doesn't exist. So we leave it as // An error indicates that the table doesn't exist. So we leave it as
// an empty map. // an empty map.
tmp, err := parentVals.Table(c.Metadata.Name)
var tmp chartutil.Values
vs, err := parentVals.Table("Values")
if err == nil {
tmp, err = vs.Table(c.Metadata.Name)
} else {
log.Printf(" *** COULD NOT FIND Values; using %s *** %q %v", c.Metadata.Name, err, parentVals)
tmp, err = parentVals.Table(c.Metadata.Name)
}
//tmp, err := parentVals["Values"].(chartutil.Values).Table(c.Metadata.Name)
if err == nil { if err == nil {
cvals = tmp cvals = map[string]interface{}{
"Values": tmp,
"Release": parentVals["Release"],
"Chart": c,
}
} }
} }

@ -219,7 +219,7 @@ func TestRenderNestedValues(t *testing.T) {
deepest := &chart.Chart{ deepest := &chart.Chart{
Metadata: &chart.Metadata{Name: "deepest"}, Metadata: &chart.Metadata{Name: "deepest"},
Templates: []*chart.Template{ Templates: []*chart.Template{
{Name: deepestpath, Data: []byte(`And this same {{.what}} that smiles {{.global.when}}`)}, {Name: deepestpath, Data: []byte(`And this same {{.Values.what}} that smiles {{.Values.global.when}}`)},
}, },
Values: &chart.Config{Raw: `what: "milkshake"`}, Values: &chart.Config{Raw: `what: "milkshake"`},
} }
@ -227,7 +227,7 @@ func TestRenderNestedValues(t *testing.T) {
inner := &chart.Chart{ inner := &chart.Chart{
Metadata: &chart.Metadata{Name: "herrick"}, Metadata: &chart.Metadata{Name: "herrick"},
Templates: []*chart.Template{ Templates: []*chart.Template{
{Name: innerpath, Data: []byte(`Old {{.who}} is still a-flyin'`)}, {Name: innerpath, Data: []byte(`Old {{.Values.who}} is still a-flyin'`)},
}, },
Values: &chart.Config{Raw: `who: "Robert"`}, Values: &chart.Config{Raw: `who: "Robert"`},
Dependencies: []*chart.Chart{deepest}, Dependencies: []*chart.Chart{deepest},
@ -236,7 +236,7 @@ func TestRenderNestedValues(t *testing.T) {
outer := &chart.Chart{ outer := &chart.Chart{
Metadata: &chart.Metadata{Name: "top"}, Metadata: &chart.Metadata{Name: "top"},
Templates: []*chart.Template{ Templates: []*chart.Template{
{Name: outerpath, Data: []byte(`Gather ye {{.what}} while ye may`)}, {Name: outerpath, Data: []byte(`Gather ye {{.Values.what}} while ye may`)},
}, },
Values: &chart.Config{ Values: &chart.Config{
Raw: ` Raw: `
@ -258,11 +258,19 @@ global:
when: to-day`, when: to-day`,
} }
inject, err := chartutil.CoalesceValues(outer, &injValues, map[string]interface{}{}) tmp, err := chartutil.CoalesceValues(outer, &injValues, map[string]interface{}{})
if err != nil { if err != nil {
t.Fatalf("Failed to coalesce values: %s", err) t.Fatalf("Failed to coalesce values: %s", err)
} }
inject := chartutil.Values{
"Values": tmp,
"Chart": outer.Metadata,
"Release": chartutil.Values{
"Name": "Robert",
},
}
t.Logf("Calculated values: %v", inject) t.Logf("Calculated values: %v", inject)
out, err := e.Render(outer, inject) out, err := e.Render(outer, inject)

Loading…
Cancel
Save