Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
H
helm3
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
helm3
Commits
81ac98ad
Commit
81ac98ad
authored
Jun 23, 2016
by
Miguel Martinez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding support for associated templates
Fixing unit test
parent
03d27779
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
73 additions
and
32 deletions
+73
-32
configmap.yaml
docs/examples/nginx/templates/configmap.yaml
+3
-3
deployment.yaml
docs/examples/nginx/templates/deployment.yaml
+5
-5
svc.yaml
docs/examples/nginx/templates/svc.yaml
+4
-4
template.go
pkg/lint/rules/template.go
+40
-14
template_test.go
pkg/lint/rules/template_test.go
+17
-0
message.go
pkg/lint/support/message.go
+3
-5
message_test.go
pkg/lint/support/message_test.go
+1
-1
No files found.
docs/examples/nginx/templates/configmap.yaml
View file @
81ac98ad
...
...
@@ -5,11 +5,11 @@ kind: ConfigMap
metadata
:
name
:
{{
template "fullname" .
}}
labels
:
release
:
{{
.Release.Name
}}
release
:
{{
.Release.Name | quote
}}
app
:
{{
template "fullname" .
}}
heritage
:
{{
.Release.Service
}}
heritage
:
{{
.Release.Service
| quote
}}
data
:
# When the config map is mounted as a volume, these will be created as
# files.
index.html
:
{{
default "Hello" .index | squote
}}
index.html
:
{{
default "Hello" .index | quote
}}
test.txt
:
test
docs/examples/nginx/templates/deployment.yaml
View file @
81ac98ad
...
...
@@ -9,18 +9,18 @@ metadata:
# 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
# is responsible for.
heritage
:
{{
.Release.Service
}}
heritage
:
{{
.Release.Service | quote
}}
# This makes it easy to search for all components of a release using kubectl.
release
:
{{
.Release.Name
}}
release
:
{{
.Release.Name | quote
}}
# This makes it easy to audit chart usage.
chart
:
{{
.Chart.Name
}}
-{{.Chart.Version}}
chart
:
"
{{.Chart.Name}}-{{.Chart.Version}}"
spec
:
replicas
:
{{
default 1 .replicaCount
}}
replicas
:
{{
default 1 .replicaCount | quote
}}
template
:
metadata
:
labels
:
app
:
{{
template "fullname" .
}}
release
:
{{
.Release.Name
}}
release
:
{{
.Release.Name
| quote
}}
spec
:
containers
:
-
name
:
{{
template "fullname" .
}}
...
...
docs/examples/nginx/templates/svc.yaml
View file @
81ac98ad
...
...
@@ -5,12 +5,12 @@ kind: Service
metadata
:
name
:
{{
template "fullname" .
}}
labels
:
heritage
:
{{
.Release.Service
}}
release
:
{{
.Release.Name
}}
chart
:
{{
.Chart.Name
}}
-{{.Chart.Version}}
heritage
:
{{
.Release.Service | quote
}}
release
:
{{
.Release.Name | quote
}}
chart
:
"
{{.Chart.Name}}-{{.Chart.Version}}"
spec
:
ports
:
-
port
:
{{
default 80 .httpPort
}}
-
port
:
{{
default 80 .httpPort | quote
}}
targetPort
:
80
protocol
:
TCP
name
:
http
...
...
pkg/lint/rules/template.go
View file @
81ac98ad
...
...
@@ -35,7 +35,7 @@ import (
func
Templates
(
linter
*
support
.
Linter
)
{
templatesPath
:=
filepath
.
Join
(
linter
.
ChartDir
,
"templates"
)
templatesDirExist
:=
linter
.
RunLinterRule
(
support
.
WarningSev
,
validateTemplatesDir
(
linter
,
templatesPath
))
templatesDirExist
:=
linter
.
RunLinterRule
(
support
.
WarningSev
,
validateTemplatesDir
(
templatesPath
))
// Templates directory is optional for now
if
!
templatesDirExist
{
...
...
@@ -80,14 +80,15 @@ func Templates(linter *support.Linter) {
for
_
,
template
:=
range
chart
.
Templates
{
fileName
,
preExecutedTemplate
:=
template
.
Name
,
template
.
Data
yamlFile
:=
linter
.
RunLinterRule
(
support
.
ErrorSev
,
validateYamlExtension
(
linter
,
fileName
))
linter
.
RunLinterRule
(
support
.
ErrorSev
,
validateAllowedExtension
(
fileName
))
if
!
yamlFile
{
return
// We only apply the following lint rules to yaml files
if
filepath
.
Ext
(
fileName
)
!=
".yaml"
{
continue
}
// Check that all the templates have a matching value
linter
.
RunLinterRule
(
support
.
WarningSev
,
validateNonMissingValues
(
fileName
,
chartValues
,
preExecutedTemplate
))
linter
.
RunLinterRule
(
support
.
WarningSev
,
validateNonMissingValues
(
fileName
,
templatesPath
,
chartValues
,
preExecutedTemplate
))
linter
.
RunLinterRule
(
support
.
WarningSev
,
validateQuotes
(
fileName
,
string
(
preExecutedTemplate
)))
...
...
@@ -100,7 +101,7 @@ func Templates(linter *support.Linter) {
validYaml
:=
linter
.
RunLinterRule
(
support
.
ErrorSev
,
validateYamlContent
(
fileName
,
err
))
if
!
validYaml
{
return
continue
}
linter
.
RunLinterRule
(
support
.
ErrorSev
,
validateNoNamespace
(
fileName
,
yamlStruct
))
...
...
@@ -108,7 +109,7 @@ func Templates(linter *support.Linter) {
}
// Validation functions
func
validateTemplatesDir
(
linter
*
support
.
Linter
,
templatesPath
string
)
(
lintError
support
.
LintError
)
{
func
validateTemplatesDir
(
templatesPath
string
)
(
lintError
support
.
LintError
)
{
if
fi
,
err
:=
os
.
Stat
(
templatesPath
);
err
!=
nil
{
lintError
=
fmt
.
Errorf
(
"Templates directory not found"
)
}
else
if
err
==
nil
&&
!
fi
.
IsDir
()
{
...
...
@@ -145,22 +146,42 @@ func validateQuotes(templateName string, templateContent string) (lintError supp
return
}
func
validateYamlExtension
(
linter
*
support
.
Linter
,
fileName
string
)
(
lintError
support
.
LintError
)
{
if
filepath
.
Ext
(
fileName
)
!=
".yaml"
{
lintError
=
fmt
.
Errorf
(
"templates:
\"
%s
\"
needs to use the .yaml extension"
,
fileName
)
func
validateAllowedExtension
(
fileName
string
)
(
lintError
support
.
LintError
)
{
ext
:=
filepath
.
Ext
(
fileName
)
validExtensions
:=
[]
string
{
".yaml"
,
".tpl"
}
for
_
,
b
:=
range
validExtensions
{
if
b
==
ext
{
return
}
}
lintError
=
fmt
.
Errorf
(
"templates:
\"
%s
\"
needs to use .yaml or .tpl extensions"
,
fileName
)
return
}
// validateNonMissingValues checks that all the {{}} functions returns a non empty value (<no value> or "")
// and return an error otherwise.
func
validateNonMissingValues
(
fileName
string
,
chartValues
chartutil
.
Values
,
templateContent
[]
byte
)
(
lintError
support
.
LintError
)
{
func
validateNonMissingValues
(
fileName
string
,
templatesPath
string
,
chartValues
chartutil
.
Values
,
templateContent
[]
byte
)
(
lintError
support
.
LintError
)
{
// 1 - Load Main and associated templates
// Main template that we will parse dynamically
tmpl
:=
template
.
New
(
"tpl"
)
.
Funcs
(
sprig
.
TxtFuncMap
())
// If the templatesPath includes any *.tpl files we will parse and import them as associated templates
associatedTemplates
,
err
:=
filepath
.
Glob
(
filepath
.
Join
(
templatesPath
,
"*.tpl"
))
if
len
(
associatedTemplates
)
>
0
{
tmpl
,
err
=
tmpl
.
ParseFiles
(
associatedTemplates
...
)
if
err
!=
nil
{
return
err
}
}
var
buf
bytes
.
Buffer
var
emptyValues
[]
string
// 2 - Extract every function and execute them agains the loaded values
// Supported {{ .Chart.Name }}, {{ .Chart.Name | quote }}
r
,
_
:=
regexp
.
Compile
(
`{{
([\w]|\.*|\s|\|)
+}}`
)
r
,
_
:=
regexp
.
Compile
(
`{{
[\w|\.|\s|\|\"|\']
+}}`
)
functions
:=
r
.
FindAllString
(
string
(
templateContent
),
-
1
)
// Iterate over the {{ FOO }} templates, executing them against the chartValues
...
...
@@ -172,7 +193,12 @@ func validateNonMissingValues(fileName string, chartValues chartutil.Values, tem
return
}
err
=
newtmpl
.
Execute
(
&
buf
,
chartValues
)
err
=
newtmpl
.
ExecuteTemplate
(
&
buf
,
"tpl"
,
chartValues
)
if
err
!=
nil
{
return
err
}
renderedValue
:=
buf
.
String
()
if
renderedValue
==
"<no value>"
||
renderedValue
==
""
{
...
...
@@ -182,7 +208,7 @@ func validateNonMissingValues(fileName string, chartValues chartutil.Values, tem
}
if
len
(
emptyValues
)
>
0
{
lintError
=
fmt
.
Errorf
(
"templates: %s: The following functions are not returning
e
ny value %v"
,
fileName
,
emptyValues
)
lintError
=
fmt
.
Errorf
(
"templates: %s: The following functions are not returning
a
ny value %v"
,
fileName
,
emptyValues
)
}
return
}
...
...
pkg/lint/rules/template_test.go
View file @
81ac98ad
...
...
@@ -24,6 +24,23 @@ import (
const
templateTestBasedir
=
"./testdata/albatross"
func
TestValidateAllowedExtension
(
t
*
testing
.
T
)
{
var
failTest
=
[]
string
{
"/foo"
,
"/test.yml"
,
"/test.toml"
,
"test.yml"
}
for
_
,
test
:=
range
failTest
{
err
:=
validateAllowedExtension
(
test
)
if
err
==
nil
||
!
strings
.
Contains
(
err
.
Error
(),
"needs to use .yaml or .tpl extension"
)
{
t
.
Errorf
(
"validateAllowedExtension('%s') to return
\"
needs to use .yaml or .tpl extension
\"
, got no error"
,
test
)
}
}
var
successTest
=
[]
string
{
"/foo.yaml"
,
"foo.yaml"
,
"foo.tpl"
,
"/foo/bar/baz.yaml"
}
for
_
,
test
:=
range
successTest
{
err
:=
validateAllowedExtension
(
test
)
if
err
!=
nil
{
t
.
Errorf
(
"validateAllowedExtension('%s') to return no error but got
\"
%s
\"
"
,
test
,
err
.
Error
())
}
}
}
func
TestValidateQuotes
(
t
*
testing
.
T
)
{
// add `| quote` lint error
var
failTest
=
[]
string
{
"foo: {{.Release.Service }}"
,
"foo: {{.Release.Service }}"
,
"- {{.Release.Service }}"
,
"foo: {{default 'Never' .restart_policy}}"
,
"- {{.Release.Service }} "
}
...
...
pkg/lint/support/message.go
View file @
81ac98ad
...
...
@@ -19,8 +19,6 @@ package support
import
"fmt"
// Severity indicatest the severity of a Message.
type
Severity
int
const
(
// UnknownSev indicates that the severity of the error is unknown, and should not stop processing.
UnknownSev
=
iota
...
...
@@ -38,7 +36,7 @@ var sev = []string{"UNKNOWN", "INFO", "WARNING", "ERROR"}
// Message is a linting output message
type
Message
struct
{
// Severity is one of the *Sev constants
Severity
Severity
Severity
int
// Text contains the message text
Text
string
}
...
...
@@ -60,9 +58,9 @@ func (m Message) String() string {
}
// Returns true if the validation passed
func
(
l
*
Linter
)
RunLinterRule
(
severity
Severity
,
lintError
LintError
)
bool
{
func
(
l
*
Linter
)
RunLinterRule
(
severity
int
,
lintError
LintError
)
bool
{
// severity is out of bound
if
severity
<
0
||
int
(
severity
)
>=
len
(
sev
)
{
if
severity
<
0
||
severity
>=
len
(
sev
)
{
return
false
}
...
...
pkg/lint/support/message_test.go
View file @
81ac98ad
...
...
@@ -26,7 +26,7 @@ var lintError LintError = fmt.Errorf("Foobar")
func
TestRunLinterRule
(
t
*
testing
.
T
)
{
var
tests
=
[]
struct
{
Severity
Severity
Severity
int
LintError
error
ExpectedMessages
int
ExpectedReturn
bool
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment