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
557db8c6
Commit
557db8c6
authored
Aug 24, 2016
by
Matt Butcher
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(tiller): verify apiVersions before install
parent
64b73081
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
92 additions
and
7 deletions
+92
-7
environment.go
cmd/tiller/environment/environment.go
+2
-2
hooks.go
cmd/tiller/hooks.go
+23
-2
hooks_test.go
cmd/tiller/hooks_test.go
+22
-2
release_server.go
cmd/tiller/release_server.go
+31
-1
release_server_test.go
cmd/tiller/release_server_test.go
+14
-0
No files found.
cmd/tiller/environment/environment.go
View file @
557db8c6
...
...
@@ -23,7 +23,6 @@ These dependencies are expressed as interfaces so that alternate implementations
package
environment
import
(
"errors"
"io"
"k8s.io/helm/pkg/chartutil"
...
...
@@ -33,6 +32,7 @@ import (
"k8s.io/helm/pkg/storage"
"k8s.io/helm/pkg/storage/driver"
"k8s.io/kubernetes/pkg/client/unversioned"
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
)
// TillerNamespace is the namespace tiller is running in.
...
...
@@ -150,7 +150,7 @@ type PrintingKubeClient struct {
// The printing client does not have access to a Kubernetes client at all. So it
// will always return an error if the client is accessed.
func
(
p
*
PrintingKubeClient
)
APIClient
()
(
unversioned
.
Interface
,
error
)
{
return
nil
,
errors
.
New
(
"no API client found"
)
return
testclient
.
NewSimpleFake
(),
nil
}
// Create prints the values of what would be created with a real KubeClient.
...
...
cmd/tiller/hooks.go
View file @
557db8c6
...
...
@@ -48,6 +48,7 @@ var events = map[string]release.Hook_Event{
}
type
simpleHead
struct
{
Version
string
`json:"apiVersion"`
Kind
string
`json:"kind,omitempty"`
Metadata
*
struct
{
Name
string
`json:"name"`
...
...
@@ -55,7 +56,22 @@ type simpleHead struct {
}
`json:"metadata,omitempty"`
}
// sortHooks takes a map of filename/YAML contents and sorts them into hook types.
type
versionSet
map
[
string
]
struct
{}
func
newVersionSet
(
apiVersions
...
string
)
versionSet
{
vs
:=
versionSet
{}
for
_
,
v
:=
range
apiVersions
{
vs
[
v
]
=
struct
{}{}
}
return
vs
}
func
(
v
versionSet
)
Has
(
apiVersion
string
)
bool
{
_
,
ok
:=
v
[
apiVersion
]
return
ok
}
// sortManifests takes a map of filename/YAML contents and sorts them into hook types.
//
// The resulting hooks struct will be populated with all of the generated hooks.
// Any file that does not declare one of the hook types will be placed in the
...
...
@@ -64,6 +80,7 @@ type simpleHead struct {
// To determine hook type, this looks for a YAML structure like this:
//
// kind: SomeKind
// apiVersion: v1
// metadata:
// annotations:
// helm.sh/hook: pre-install
...
...
@@ -75,7 +92,7 @@ type simpleHead struct {
//
// Files that do not parse into the expected format are simply placed into a map and
// returned.
func
sort
Hooks
(
files
map
[
string
]
string
)
([]
*
release
.
Hook
,
map
[
string
]
string
,
error
)
{
func
sort
Manifests
(
files
map
[
string
]
string
,
apis
versionSet
)
([]
*
release
.
Hook
,
map
[
string
]
string
,
error
)
{
hs
:=
[]
*
release
.
Hook
{}
generic
:=
map
[
string
]
string
{}
...
...
@@ -99,6 +116,10 @@ func sortHooks(files map[string]string) ([]*release.Hook, map[string]string, err
return
hs
,
generic
,
e
}
if
sh
.
Version
!=
""
&&
!
apis
.
Has
(
sh
.
Version
)
{
return
hs
,
generic
,
fmt
.
Errorf
(
"apiVersion %q in %s is not available"
,
sh
.
Version
,
n
)
}
if
sh
.
Metadata
==
nil
||
sh
.
Metadata
.
Annotations
==
nil
||
len
(
sh
.
Metadata
.
Annotations
)
==
0
{
generic
[
n
]
=
c
continue
...
...
cmd/tiller/hooks_test.go
View file @
557db8c6
...
...
@@ -22,7 +22,7 @@ import (
"k8s.io/helm/pkg/proto/hapi/release"
)
func
TestSort
Hook
s
(
t
*
testing
.
T
)
{
func
TestSort
Manifest
s
(
t
*
testing
.
T
)
{
data
:=
[]
struct
{
name
string
...
...
@@ -52,6 +52,7 @@ metadata:
kind
:
"ReplicaSet"
,
hooks
:
[]
release
.
Hook_Event
{
release
.
Hook_POST_INSTALL
},
manifest
:
`kind: ReplicaSet
apiVersion: v1beta1
metadata:
name: second
annotations:
...
...
@@ -63,6 +64,7 @@ metadata:
kind
:
"ReplicaSet"
,
hooks
:
[]
release
.
Hook_Event
{},
manifest
:
`kind: ReplicaSet
apiVersion: v1beta1
metadata:
name: third
annotations:
...
...
@@ -74,6 +76,7 @@ metadata:
kind
:
"Pod"
,
hooks
:
[]
release
.
Hook_Event
{},
manifest
:
`kind: Pod
apiVersion: v1
metadata:
name: fourth
annotations:
...
...
@@ -85,6 +88,7 @@ metadata:
kind
:
"ReplicaSet"
,
hooks
:
[]
release
.
Hook_Event
{
release
.
Hook_POST_DELETE
,
release
.
Hook_POST_INSTALL
},
manifest
:
`kind: ReplicaSet
apiVersion: v1beta1
metadata:
name: fifth
annotations:
...
...
@@ -112,7 +116,7 @@ metadata:
manifests
[
o
.
path
]
=
o
.
manifest
}
hs
,
generic
,
err
:=
sort
Hooks
(
manifests
)
hs
,
generic
,
err
:=
sort
Manifests
(
manifests
,
newVersionSet
(
"v1"
,
"v1beta1"
)
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %s"
,
err
)
}
...
...
@@ -153,3 +157,19 @@ metadata:
}
}
func
TestVersionSet
(
t
*
testing
.
T
)
{
vs
:=
newVersionSet
(
"v1"
,
"v1beta1"
,
"extensions/alpha5"
,
"batch/v1"
)
if
l
:=
len
(
vs
);
l
!=
4
{
t
.
Errorf
(
"Expected 4, got %d"
,
l
)
}
if
!
vs
.
Has
(
"extensions/alpha5"
)
{
t
.
Error
(
"No match for alpha5"
)
}
if
vs
.
Has
(
"nosuch/extension"
)
{
t
.
Error
(
"Found nonexistent extension"
)
}
}
cmd/tiller/release_server.go
View file @
557db8c6
...
...
@@ -35,6 +35,7 @@ import (
"k8s.io/helm/pkg/proto/hapi/services"
"k8s.io/helm/pkg/storage/driver"
"k8s.io/helm/pkg/timeconv"
"k8s.io/kubernetes/pkg/api/unversioned"
)
var
srv
*
releaseServer
...
...
@@ -399,6 +400,31 @@ func (s *releaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
return
rel
,
nil
}
func
(
s
*
releaseServer
)
getVersionSet
()
(
versionSet
,
error
)
{
defVersions
:=
newVersionSet
(
"v1"
)
cli
,
err
:=
s
.
env
.
KubeClient
.
APIClient
()
if
err
!=
nil
{
log
.
Printf
(
"API Client for Kubernetes is missing: %s."
,
err
)
return
defVersions
,
err
}
groups
,
err
:=
cli
.
Discovery
()
.
ServerGroups
()
if
err
!=
nil
{
return
defVersions
,
err
}
// FIXME: The Kubernetes test fixture for cli appears to always return nil
// for calls to Discovery().ServerGroups(). So in this case, we return
// the default API list. This is also a safe value to return in any other
// odd-ball case.
if
groups
==
nil
{
return
defVersions
,
nil
}
versions
:=
unversioned
.
ExtractGroupVersions
(
groups
)
return
newVersionSet
(
versions
...
),
nil
}
func
(
s
*
releaseServer
)
renderResources
(
ch
*
chart
.
Chart
,
values
chartutil
.
Values
)
([]
*
release
.
Hook
,
*
bytes
.
Buffer
,
error
)
{
renderer
:=
s
.
engine
(
ch
)
files
,
err
:=
renderer
.
Render
(
ch
,
values
)
...
...
@@ -409,7 +435,11 @@ func (s *releaseServer) renderResources(ch *chart.Chart, values chartutil.Values
// Sort hooks, manifests, and partials. Only hooks and manifests are returned,
// as partials are not used after renderer.Render. Empty manifests are also
// removed here.
hooks
,
manifests
,
err
:=
sortHooks
(
files
)
vs
,
err
:=
s
.
getVersionSet
()
if
err
!=
nil
{
return
nil
,
nil
,
fmt
.
Errorf
(
"Could not get apiVersions from Kubernetes: %s"
,
err
)
}
hooks
,
manifests
,
err
:=
sortManifests
(
files
,
vs
)
if
err
!=
nil
{
// By catching parse errors here, we can prevent bogus releases from going
// to Kubernetes.
...
...
cmd/tiller/release_server_test.go
View file @
557db8c6
...
...
@@ -108,6 +108,20 @@ func releaseStub() *release.Release {
}
}
func
TestGetVersionSet
(
t
*
testing
.
T
)
{
rs
:=
rsFixture
()
vs
,
err
:=
rs
.
getVersionSet
()
if
err
!=
nil
{
t
.
Error
(
err
)
}
if
!
vs
.
Has
(
"v1"
)
{
t
.
Errorf
(
"Expected supported versions to at least include v1."
)
}
if
vs
.
Has
(
"nosuchversion/v1"
)
{
t
.
Error
(
"Non-existent version is reported found."
)
}
}
func
TestUniqName
(
t
*
testing
.
T
)
{
rs
:=
rsFixture
()
...
...
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