Skip to content
This repository has been archived by the owner on Dec 21, 2019. It is now read-only.

Commit

Permalink
feat context: Allow overriding resource set paths
Browse files Browse the repository at this point in the history
Instead of always inferring the path at which files in a resource set
are located, let users override the path by specifying a `path` field.

This makes it possible to add the same resource set multiple times
with different values while still keeping distinct names for
addressability (for example when using include/exclude).

This fixes #70
  • Loading branch information
tazjin committed Jul 13, 2017
1 parent 9d26c17 commit 7607f6d
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 5 deletions.
23 changes: 18 additions & 5 deletions context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

type ResourceSet struct {
Name string `json:"name"`
Path string `json:"path"`
Values map[string]interface{} `json:"values"`

// Fields for resource set collections
Expand Down Expand Up @@ -41,7 +42,7 @@ func LoadContextFromFile(filename string) (*Context, error) {
)
}

c.ResourceSets = flattenResourceSetCollections(&c.ResourceSets)
c.ResourceSets = flattenPrepareResourceSetPaths(&c.ResourceSets)
c.BaseDir = path.Dir(filename)
c.ResourceSets = loadAllDefaultValues(&c)

Expand Down Expand Up @@ -73,19 +74,31 @@ func (ctx *Context) loadImportedVariables() error {
return nil
}

// Flattens resource set collections, i.e. resource sets that themselves have an additional 'include' field set.
// Correctly prepares the file paths for resource sets by inferring implicit paths and flattening resource set
// collections, i.e. resource sets that themselves have an additional 'include' field set.
// Those will be regarded as a short-hand for including multiple resource sets from a subfolder.
// See https://github.com/tazjin/kontemplate/issues/9 for more information.
func flattenResourceSetCollections(rs *[]ResourceSet) []ResourceSet {
func flattenPrepareResourceSetPaths(rs *[]ResourceSet) []ResourceSet {
flattened := make([]ResourceSet, 0)

for _, r := range *rs {
// If a path is not explicitly specified it should default to the resource set name.
// This is also the classic behaviour prior to kontemplate 1.2
if r.Path == "" {
r.Path = r.Name
}

if len(r.Include) == 0 {
flattened = append(flattened, r)
} else {
for _, subResourceSet := range r.Include {
if subResourceSet.Path == "" {
subResourceSet.Path = subResourceSet.Name
}

subResourceSet.Parent = r.Name
subResourceSet.Name = path.Join(r.Name, subResourceSet.Name)
subResourceSet.Path = path.Join(r.Path, subResourceSet.Path)
subResourceSet.Values = *util.Merge(&r.Values, &subResourceSet.Values)
flattened = append(flattened, subResourceSet)
}
Expand Down Expand Up @@ -114,13 +127,13 @@ func loadDefaultValues(rs *ResourceSet, c *Context) *map[string]interface{} {
var defaultVars map[string]interface{}

// Attempt to load YAML values
err := util.LoadJsonOrYaml(path.Join(c.BaseDir, rs.Name, "default.yaml"), &defaultVars)
err := util.LoadJsonOrYaml(path.Join(c.BaseDir, rs.Path, "default.yaml"), &defaultVars)
if err == nil {
return util.Merge(&defaultVars, &rs.Values)
}

// Attempt to load JSON values
err = util.LoadJsonOrYaml(path.Join(c.BaseDir, rs.Name, "default.json"), &defaultVars)
err = util.LoadJsonOrYaml(path.Join(c.BaseDir, rs.Path, "default.json"), &defaultVars)
if err == nil {
return util.Merge(&defaultVars, &rs.Values)
}
Expand Down
68 changes: 68 additions & 0 deletions context/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func TestLoadFlatContextFromFile(t *testing.T) {
ResourceSets: []ResourceSet{
{
Name: "some-api",
Path: "some-api",
Values: map[string]interface{}{
"apiPort": float64(4567), // yep!
"importantFeature": true,
Expand Down Expand Up @@ -55,6 +56,7 @@ func TestLoadContextWithResourceSetCollections(t *testing.T) {
ResourceSets: []ResourceSet{
{
Name: "some-api",
Path: "some-api",
Values: map[string]interface{}{
"apiPort": float64(4567), // yep!
"importantFeature": true,
Expand All @@ -65,6 +67,7 @@ func TestLoadContextWithResourceSetCollections(t *testing.T) {
},
{
Name: "collection/nested",
Path: "collection/nested",
Values: map[string]interface{}{
"lizards": "good",
},
Expand Down Expand Up @@ -95,6 +98,7 @@ func TestSubresourceVariableInheritance(t *testing.T) {
ResourceSets: []ResourceSet{
{
Name: "parent/child",
Path: "parent/child",
Values: map[string]interface{}{
"foo": "bar",
"bar": "baz",
Expand Down Expand Up @@ -125,6 +129,7 @@ func TestSubresourceVariableInheritanceOverride(t *testing.T) {
ResourceSets: []ResourceSet{
{
Name: "parent/child",
Path: "parent/child",
Values: map[string]interface{}{
"foo": "newvalue",
},
Expand Down Expand Up @@ -203,3 +208,66 @@ func TestImportValuesOverride(t *testing.T) {
t.Fail()
}
}

func TestExplicitPathLoading(t *testing.T) {
ctx, err := LoadContextFromFile("testdata/explicit-path.yaml")
if err != nil {
t.Error(err)
t.Fail()
}

expected := Context{
Name: "k8s.prod.mydomain.com",
ResourceSets: []ResourceSet{
{
Name: "some-api-europe",
Path: "some-api",
Values: map[string]interface{}{
"location": "europe",
},
Include: nil,
Parent: "",
},
{
Name: "some-api-asia",
Path: "some-api",
Values: map[string]interface{}{
"location": "asia",
},
Include: nil,
Parent: "",
},
},
BaseDir: "testdata",
}

if !reflect.DeepEqual(*ctx, expected) {
t.Error("Loaded context and expected context did not match")
t.Fail()
}
}

func TestExplicitSubresourcePathLoading(t *testing.T) {
ctx, err := LoadContextFromFile("testdata/explicit-subresource-path.yaml")
if err != nil {
t.Error(err)
t.Fail()
}

expected := Context{
Name: "k8s.prod.mydomain.com",
ResourceSets: []ResourceSet{
{
Name: "parent/child",
Path: "parent-path/child-path",
Parent: "parent",
},
},
BaseDir: "testdata",
}

if !reflect.DeepEqual(*ctx, expected) {
t.Error("Loaded context and expected context did not match")
t.Fail()
}
}
11 changes: 11 additions & 0 deletions context/testdata/explicit-path.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
context: k8s.prod.mydomain.com
include:
- name: some-api-europe
path: some-api
values:
location: europe
- name: some-api-asia
path: some-api
values:
location: asia
8 changes: 8 additions & 0 deletions context/testdata/explicit-subresource-path.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
context: k8s.prod.mydomain.com
include:
- name: parent
path: parent-path
include:
- name: child
path: child-path

0 comments on commit 7607f6d

Please sign in to comment.