Skip to content

Commit

Permalink
add TLSCert and TLSKey to configoption dep resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
laverya authored and emosbaugh committed Jul 31, 2020
1 parent 5ed3eea commit a403649
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 11 deletions.
61 changes: 54 additions & 7 deletions pkg/template/depgraph.go
Expand Up @@ -12,6 +12,8 @@ import (

type depGraph struct {
Dependencies map[string]map[string]struct{}
CertItems map[string]map[string]struct{} // items that use the TLSCert template function. map of certnames to configoptions that provide the certname
KeyItems map[string]map[string]struct{} // items that use the TLSKey template function. map of configoptions to the certnames they use
}

// these config functions are used to add their dependencies to the depGraph
Expand All @@ -21,12 +23,24 @@ func (d *depGraph) funcMap(parent string) template.FuncMap {
return dep
}

addCertFunc := func(certName string, _ ...string) string {
d.AddCert(parent, certName)
return certName
}

addKeyFunc := func(certName string, _ ...string) string {
d.AddKey(parent, certName)
return certName
}

return template.FuncMap{
"ConfigOption": addDepFunc,
"ConfigOptionIndex": addDepFunc,
"ConfigOptionData": addDepFunc,
"ConfigOptionEquals": addDepFunc,
"ConfigOptionNotEquals": addDepFunc,
"TLSCert": addCertFunc,
"TLSKey": addKeyFunc,
}
}

Expand All @@ -46,6 +60,40 @@ func (d *depGraph) AddDep(source, newDependency string) {
d.Dependencies[source][newDependency] = struct{}{}
}

func (d *depGraph) AddCert(source, certName string) {
if d.CertItems == nil {
d.CertItems = make(map[string]map[string]struct{})
}
if _, ok := d.CertItems[certName]; !ok {
d.CertItems[certName] = make(map[string]struct{})
}

d.CertItems[certName][source] = struct{}{}
}

func (d *depGraph) AddKey(source, certName string) {
if d.KeyItems == nil {
d.KeyItems = make(map[string]map[string]struct{})
}
if _, ok := d.KeyItems[source]; !ok {
d.KeyItems[source] = make(map[string]struct{})
}

d.KeyItems[source][certName] = struct{}{}
}

func (d *depGraph) resolveCertKeys() {
for source, certNameMap := range d.KeyItems {
for certName, _ := range certNameMap {
for certProvider, _ := range d.CertItems[certName] {
if certProvider != source {
d.AddDep(source, certProvider)
}
}
}
}
}

func (d *depGraph) ResolveDep(resolvedDependency string) {
for _, depMap := range d.Dependencies {
delete(depMap, resolvedDependency)
Expand Down Expand Up @@ -87,31 +135,28 @@ func (d *depGraph) Copy() (depGraph, error) {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
dec := json.NewDecoder(&buf)
err := enc.Encode(d.Dependencies)
err := enc.Encode(d)
if err != nil {
return depGraph{}, err
}
var depCopy map[string]map[string]struct{}
depCopy := depGraph{}
err = dec.Decode(&depCopy)
if err != nil {
return depGraph{}, err
}

return depGraph{
Dependencies: depCopy,
}, nil
return depCopy, nil

}

func (d *depGraph) ParseConfigGroup(configGroups []kotsv1beta1.ConfigGroup) error {
staticCtx := &StaticCtx{}
for _, configGroup := range configGroups {
for _, configItem := range configGroup.Items {
// add this to the dependency graph
d.AddNode(configItem.Name)

depBuilder := Builder{
Ctx: []Ctx{staticCtx},
Ctx: []Ctx{},
Functs: d.funcMap(configItem.Name),
}

Expand All @@ -122,5 +167,7 @@ func (d *depGraph) ParseConfigGroup(configGroups []kotsv1beta1.ConfigGroup) erro
}
}

d.resolveCertKeys()

return nil
}
73 changes: 69 additions & 4 deletions pkg/template/depgraph_test.go
Expand Up @@ -12,6 +12,8 @@ import (

type depGraphTestCase struct {
dependencies map[string][]string
testCerts map[string][]string
testKeys map[string][]string
resolveOrder []string
expectError bool //expect an error fetching head nodes
expectNotFound string //expect this dependency not to be part of the head nodes
Expand Down Expand Up @@ -113,6 +115,41 @@ func TestDepGraph(t *testing.T) {
expectError: true,
name: "does_not_exist",
},
{
dependencies: map[string][]string{
"alpha": {},
"bravo": {"alpha"},
"charlie": {"bravo"},
"delta": {"alpha", "charlie"},
"echo": {},
},
testCerts: map[string][]string{
"echo": {"certA"},
},
testKeys: map[string][]string{
"delta": {"certA"},
},
resolveOrder: []string{"alpha", "bravo", "charlie", "echo", "delta"},
name: "basic_certs",
},
{
dependencies: map[string][]string{
"alpha": {},
"bravo": {"alpha"},
"charlie": {"bravo"},
"delta": {"alpha", "charlie"},
"echo": {},
},
testCerts: map[string][]string{
"echo": {"certA"},
},
testKeys: map[string][]string{
"delta": {"certA"},
},
resolveOrder: []string{"alpha", "bravo", "charlie", "delta", "echo"},
name: "basic_certs_original_order",
expectNotFound: "delta",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
Expand All @@ -126,6 +163,18 @@ func TestDepGraph(t *testing.T) {
graph.AddDep(source, dep)
}
}
for source, certNames := range test.testCerts {
for _, certName := range certNames {
graph.AddCert(source, certName)
}
}
for source, keys := range test.testKeys {
for _, key := range keys {
graph.AddKey(source, key)
}
}
graph.resolveCertKeys()

runGraphTests(t, test, graph)
})

Expand All @@ -135,7 +184,7 @@ func TestDepGraph(t *testing.T) {

graph := depGraph{}

groups := buildTestConfigGroups(test.dependencies, "templateStringStart", "templateStringEnd", true)
groups := buildTestConfigGroups(test.dependencies, test.testCerts, test.testKeys, "templateStringStart", "templateStringEnd", true)

err := graph.ParseConfigGroup(groups)
require.NoError(t, err)
Expand All @@ -146,7 +195,7 @@ func TestDepGraph(t *testing.T) {
}

// this makes sure that we test with each of the configOption types, in both Value and Default
func buildTestConfigGroups(dependencies map[string][]string, prefix string, suffix string, rotate bool) []kotsv1beta1.ConfigGroup {
func buildTestConfigGroups(dependencies, certs, keys map[string][]string, prefix string, suffix string, rotate bool) []kotsv1beta1.ConfigGroup {
group := kotsv1beta1.ConfigGroup{}
group.Items = make([]kotsv1beta1.ConfigItem, 0)
counter := 0
Expand All @@ -166,12 +215,28 @@ func buildTestConfigGroups(dependencies map[string][]string, prefix string, suff
}
}

totalDepItems := 0

for source, deps := range dependencies {
newItem := kotsv1beta1.ConfigItem{Type: "text", Name: source}
depString := prefix
for i, dep := range deps {
depString += fmt.Sprintf(templateFuncs[i%len(templateFuncs)], dep)
for _, dep := range deps {
depString += fmt.Sprintf(templateFuncs[totalDepItems%len(templateFuncs)], dep)
totalDepItems++
}

if certNames, ok := certs[source]; ok {
for _, certName := range certNames {
depString += fmt.Sprintf("{{repl TLSCert \"%s\" }}", certName)
}
}

if certNames, ok := keys[source]; ok {
for _, certName := range certNames {
depString += fmt.Sprintf("{{repl TLSKey \"%s\" }}", certName)
}
}

depString += suffix

if counter%2 == 0 {
Expand Down

0 comments on commit a403649

Please sign in to comment.