Skip to content

Commit

Permalink
allow namespace specification via parameter in templates
Browse files Browse the repository at this point in the history
  • Loading branch information
bparees committed Feb 9, 2017
1 parent ac76284 commit 39c9e59
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 8 deletions.
17 changes: 9 additions & 8 deletions pkg/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,16 @@ func (p *Processor) Process(template *api.Template) field.ErrorList {
item = decodedObj
}

newItem, err := p.SubstituteParameters(paramMap, item)
if err != nil {
templateErrors = append(templateErrors, field.Invalid(idxPath.Child("parameters"), template.Parameters, err.Error()))
}
// If an object definition's metadata includes a namespace field, the field will be stripped out of
// the definition during template instantiation. This is necessary because all objects created during
// instantiation are placed into the target namespace, so it would be invalid for the object to declare
//a different namespace.
stripNamespace(newItem)
stripNamespace(item)

newItem, err := p.SubstituteParameters(paramMap, item)
if err != nil {
templateErrors = append(templateErrors, field.Invalid(idxPath.Child("parameters"), template.Parameters, err.Error()))
}
if err := util.AddObjectLabels(newItem, template.ObjectLabels); err != nil {
templateErrors = append(templateErrors, field.Invalid(idxPath.Child("labels"),
template.ObjectLabels, fmt.Sprintf("label could not be applied: %v", err)))
Expand All @@ -86,21 +87,21 @@ func (p *Processor) Process(template *api.Template) field.ErrorList {

func stripNamespace(obj runtime.Object) {
// Remove namespace from the item
if itemMeta, err := meta.Accessor(obj); err == nil && len(itemMeta.GetNamespace()) > 0 {
if itemMeta, err := meta.Accessor(obj); err == nil && len(itemMeta.GetNamespace()) > 0 && !stringParameterExp.MatchString(itemMeta.GetNamespace()) {
itemMeta.SetNamespace("")
return
}
// TODO: allow meta.Accessor to handle runtime.Unstructured
if unstruct, ok := obj.(*runtime.Unstructured); ok && unstruct.Object != nil {
if obj, ok := unstruct.Object["metadata"]; ok {
if m, ok := obj.(map[string]interface{}); ok {
if _, ok := m["namespace"]; ok {
if _, ok := m["namespace"]; ok && !stringParameterExp.MatchString(m["namespace"].(string)) {
m["namespace"] = ""
}
}
return
}
if _, ok := unstruct.Object["namespace"]; ok {
if _, ok := unstruct.Object["namespace"]; ok && stringParameterExp.MatchString(unstruct.Object["namespace"].(string)) {
unstruct.Object["namespace"] = ""
return
}
Expand Down
10 changes: 10 additions & 0 deletions test/cmd/newapp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ os::cmd::expect_failure 'oc get dc/mysql'
os::cmd::expect_failure 'oc get dc/php'
os::cmd::expect_success_and_text 'oc new-app -f test/testdata/template-without-app-label.json -o yaml' 'app: ruby-helloworld-sample'

# check object namespace handling
# hardcoded values should be stripped
os::cmd::expect_success_and_not_text 'oc new-app -f test/testdata/template-with-namespaces.json -o yaml' 'namespace: STRIPPED'
# normal parameterized values should be substituted and retained
os::cmd::expect_success_and_text 'oc new-app -f test/testdata/template-with-namespaces.json -o yaml' 'namespace: substituted'
os::cmd::expect_success_and_text 'oc new-app -f test/testdata/template-with-namespaces.json -o yaml' 'namespace: pre_substituted'
# non-string parameterized values should be stripped
os::cmd::expect_success_and_not_text 'oc new-app -f test/testdata/template-with-namespaces.json -o yaml' 'namespace: ${{SUBSTITUTED}}'
os::cmd::expect_success_and_not_text 'oc new-app -f test/testdata/template-with-namespaces.json -o yaml' 'namespace: pre_${{SUBSTITUTED}}'

# ensure non-duplicate invalid label errors show up
os::cmd::expect_failure_and_text 'oc new-app nginx -l qwer1345%$$#=self' 'error: ImageStream "nginx" is invalid'
os::cmd::expect_failure_and_text 'oc new-app nginx -l qwer1345%$$#=self' 'DeploymentConfig "nginx" is invalid'
Expand Down
129 changes: 129 additions & 0 deletions test/testdata/template-with-namespaces.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"kind": "Template",
"apiVersion": "v1",
"metadata": {
"name": "ruby-helloworld-sample",
"creationTimestamp": null,
"annotations": {
"description": "some objects in this template declare their own namespace via a parameter confirm new-app will tolerate it",
"iconClass": "icon-ruby",
"tags": "instant-app,ruby,mysql"
}
},
"objects": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "frontend",
"namespace": "STRIPPED"
},
"spec": {
"ports": [
{
"name": "web",
"protocol": "TCP",
"port": 5432,
"targetPort": 8080,
"nodePort": 0
}
],
"selector": {
"name": "frontend"
},
"type": "ClusterIP",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Route",
"apiVersion": "v1",
"metadata": {
"name": "route-edge",
"namespace": "${SUBSTITUTED}"
},
"spec": {
"host": "www.example.com",
"to": {
"kind": "Service",
"name": "frontend"
},
"tls": {
"termination": "edge"
}
},
"status": {}
},
{
"kind": "Route",
"apiVersion": "v1",
"metadata": {
"name": "route-edge2",
"namespace": "${{SUBSTITUTED}}"
},
"spec": {
"host": "www.example.com",
"to": {
"kind": "Service",
"name": "frontend"
},
"tls": {
"termination": "edge"
}
},
"status": {}
},
{
"kind": "Route",
"apiVersion": "v1",
"metadata": {
"name": "route-edge3",
"namespace": "pre_${SUBSTITUTED}"
},
"spec": {
"host": "www.example.com",
"to": {
"kind": "Service",
"name": "frontend"
},
"tls": {
"termination": "edge"
}
},
"status": {}
},
{
"kind": "Route",
"apiVersion": "v1",
"metadata": {
"name": "route-edge4",
"namespace": "pre_${{SUBSTITUTED}}"
},
"spec": {
"host": "www.example.com",
"to": {
"kind": "Service",
"name": "frontend"
},
"tls": {
"termination": "edge"
}
},
"status": {}
}
],
"parameters": [
{
"name": "SUBSTITUTED",
"description": "namespace value",
"value": "substituted",
"required": true
}
],
"labels": {
"template": "application-template-stibuild"
}
}

0 comments on commit 39c9e59

Please sign in to comment.