Skip to content

Commit 1c784e0

Browse files
author
OpenShift Bot
authored
Merge pull request #9708 from jupierce/dev/jupierce/feature/template_feedback
Merged by openshift-bot
2 parents e7d0a44 + 34a3c56 commit 1c784e0

File tree

10 files changed

+77
-32
lines changed

10 files changed

+77
-32
lines changed

api/swagger-spec/oapi-v1.json

+7-3
Original file line numberDiff line numberDiff line change
@@ -24900,23 +24900,27 @@
2490024900
"$ref": "v1.ObjectMeta",
2490124901
"description": "Standard object's metadata."
2490224902
},
24903+
"message": {
24904+
"type": "string",
24905+
"description": "message is an optional instructional message that will be displayed when this template is instantiated. This field should inform the user how to utilize the newly created resources. Parameter substitution will be performed on the message before being displayed so that generated credentials and other parameters can be included in the output."
24906+
},
2490324907
"objects": {
2490424908
"type": "array",
2490524909
"items": {
2490624910
"$ref": "runtime.RawExtension"
2490724911
},
24908-
"description": "Objects is an array of objects to include in this template. Required."
24912+
"description": "objects is an array of resources to include in this template."
2490924913
},
2491024914
"parameters": {
2491124915
"type": "array",
2491224916
"items": {
2491324917
"$ref": "v1.Parameter"
2491424918
},
24915-
"description": "Optional: Parameters is an array of Parameters used during the Template to Config transformation."
24919+
"description": "parameters is an optional array of Parameters used during the Template to Config transformation."
2491624920
},
2491724921
"labels": {
2491824922
"type": "object",
24919-
"description": "Labels is a set of labels that are applied to every object during the Template to Config transformation. Optional"
24923+
"description": "labels is a optional set of labels that are applied to every object during the Template to Config transformation."
2492024924
}
2492124925
}
2492224926
},

pkg/cmd/cli/describe/describer.go

+11
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,15 @@ type TemplateDescriber struct {
870870
kctl.ObjectDescriber
871871
}
872872

873+
// DescribeMessage prints the message that will be parameter substituted and displayed to the
874+
// user when this template is processed.
875+
func (d *TemplateDescriber) DescribeMessage(msg string, out *tabwriter.Writer) {
876+
if len(msg) == 0 {
877+
msg = "<none>"
878+
}
879+
formatString(out, "Message", msg)
880+
}
881+
873882
// DescribeParameters prints out information about the parameters of a template
874883
func (d *TemplateDescriber) DescribeParameters(params []templateapi.Parameter, out *tabwriter.Writer) {
875884
formatString(out, "Parameters", " ")
@@ -954,6 +963,8 @@ func (d *TemplateDescriber) DescribeTemplate(template *templateapi.Template) (st
954963
out.Write([]byte("\n"))
955964
formatString(out, "Object Labels", formatLabels(template.ObjectLabels))
956965
out.Write([]byte("\n"))
966+
d.DescribeMessage(template.Message, out)
967+
out.Write([]byte("\n"))
957968
out.Flush()
958969
d.describeObjects(template.Objects, out)
959970
return nil

pkg/template/api/deep_copy_generated.go

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ func DeepCopy_api_Template(in Template, out *Template, c *conversion.Cloner) err
4040
if err := api.DeepCopy_api_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
4141
return err
4242
}
43+
out.Message = in.Message
4344
if in.Parameters != nil {
4445
in, out := in.Parameters, &out.Parameters
4546
*out = make([]Parameter, len(in))

pkg/template/api/types.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,23 @@ type Template struct {
1313
unversioned.TypeMeta
1414
kapi.ObjectMeta
1515

16-
// Optional: Parameters is an array of Parameters used during the
16+
// message is an optional instructional message that will
17+
// be displayed when this template is instantiated.
18+
// This field should inform the user how to utilize the newly created resources.
19+
// Parameter substitution will be performed on the message before being
20+
// displayed so that generated credentials and other parameters can be
21+
// included in the output.
22+
Message string
23+
24+
// parameters is an optional array of Parameters used during the
1725
// Template to Config transformation.
1826
Parameters []Parameter
1927

20-
// Required: A list of resources to create
28+
// objects is an array of resources to include in this template.
2129
Objects []runtime.Object
2230

23-
// Optional: ObjectLabels is a set of labels that are applied to every
24-
// object during the Template to Config transformation
31+
// objectLabels is an optional set of labels that are applied to every
32+
// object during the Template to Config transformation.
2533
ObjectLabels map[string]string
2634
}
2735

pkg/template/api/v1/deep_copy_generated.go

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func DeepCopy_v1_Template(in Template, out *Template, c *conversion.Cloner) erro
4141
if err := api_v1.DeepCopy_v1_ObjectMeta(in.ObjectMeta, &out.ObjectMeta, c); err != nil {
4242
return err
4343
}
44+
out.Message = in.Message
4445
if in.Objects != nil {
4546
in, out := in.Objects, &out.Objects
4647
*out = make([]runtime.RawExtension, len(in))

pkg/template/api/v1/swagger_doc.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ func (Parameter) SwaggerDoc() map[string]string {
2323
var map_Template = map[string]string{
2424
"": "Template contains the inputs needed to produce a Config.",
2525
"metadata": "Standard object's metadata.",
26-
"objects": "Objects is an array of objects to include in this template. Required.",
27-
"parameters": "Optional: Parameters is an array of Parameters used during the Template to Config transformation.",
28-
"labels": "Labels is a set of labels that are applied to every object during the Template to Config transformation. Optional",
26+
"message": "message is an optional instructional message that will be displayed when this template is instantiated. This field should inform the user how to utilize the newly created resources. Parameter substitution will be performed on the message before being displayed so that generated credentials and other parameters can be included in the output.",
27+
"objects": "objects is an array of resources to include in this template.",
28+
"parameters": "parameters is an optional array of Parameters used during the Template to Config transformation.",
29+
"labels": "labels is a optional set of labels that are applied to every object during the Template to Config transformation.",
2930
}
3031

3132
func (Template) SwaggerDoc() map[string]string {

pkg/template/api/v1/types.go

+12-4
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,23 @@ type Template struct {
1414
// Standard object's metadata.
1515
kapi.ObjectMeta `json:"metadata,omitempty"`
1616

17-
// Objects is an array of objects to include in this template. Required.
17+
// message is an optional instructional message that will
18+
// be displayed when this template is instantiated.
19+
// This field should inform the user how to utilize the newly created resources.
20+
// Parameter substitution will be performed on the message before being
21+
// displayed so that generated credentials and other parameters can be
22+
// included in the output.
23+
Message string `json:"message,omitempty"`
24+
25+
// objects is an array of resources to include in this template.
1826
Objects []runtime.RawExtension `json:"objects"`
1927

20-
// Optional: Parameters is an array of Parameters used during the
28+
// parameters is an optional array of Parameters used during the
2129
// Template to Config transformation.
2230
Parameters []Parameter `json:"parameters,omitempty"`
2331

24-
// Labels is a set of labels that are applied to every
25-
// object during the Template to Config transformation. Optional
32+
// labels is a optional set of labels that are applied to every
33+
// object during the Template to Config transformation.
2634
Labels map[string]string `json:"labels,omitempty"`
2735
}
2836

pkg/template/template.go

+26-17
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ func (p *Processor) Process(template *api.Template) field.ErrorList {
3838
return append(templateErrors, fieldError)
3939
}
4040

41+
// Place parameters into a map for efficient lookup
42+
paramMap := make(map[string]api.Parameter)
43+
for _, param := range template.Parameters {
44+
paramMap[param.Name] = param
45+
}
46+
47+
// Perform parameter substitution on the template's user message. This can be used to
48+
// instruct a user on next steps for the template.
49+
template.Message = p.EvaluateParameterSubstitution(paramMap, template.Message)
50+
4151
itemPath := field.NewPath("item")
4252
for i, item := range template.Objects {
4353
idxPath := itemPath.Index(i)
@@ -51,7 +61,7 @@ func (p *Processor) Process(template *api.Template) field.ErrorList {
5161
item = decodedObj
5262
}
5363

54-
newItem, err := p.SubstituteParameters(template.Parameters, item)
64+
newItem, err := p.SubstituteParameters(paramMap, item)
5565
if err != nil {
5666
templateErrors = append(templateErrors, field.Invalid(idxPath.Child("parameters"), template.Parameters, err.Error()))
5767
}
@@ -114,30 +124,29 @@ func GetParameterByName(t *api.Template, name string) *api.Parameter {
114124
return nil
115125
}
116126

127+
// EvaluateParameterSubstitution replaces escaped parameters in a string with values from the
128+
// provided map.
129+
func (p *Processor) EvaluateParameterSubstitution(params map[string]api.Parameter, in string) string {
130+
for _, match := range parameterExp.FindAllStringSubmatch(in, -1) {
131+
if len(match) > 1 {
132+
if paramValue, found := params[match[1]]; found {
133+
in = strings.Replace(in, match[0], paramValue.Value, 1)
134+
}
135+
}
136+
}
137+
return in
138+
}
139+
117140
// SubstituteParameters loops over all values defined in structured
118141
// and unstructured types that are children of item.
119142
//
120143
// Example of Parameter expression:
121144
// - ${PARAMETER_NAME}
122145
//
123-
func (p *Processor) SubstituteParameters(params []api.Parameter, item runtime.Object) (runtime.Object, error) {
124-
// Make searching for given parameter name/value more effective
125-
paramMap := make(map[string]string, len(params))
126-
for _, param := range params {
127-
paramMap[param.Name] = param.Value
128-
}
129-
146+
func (p *Processor) SubstituteParameters(params map[string]api.Parameter, item runtime.Object) (runtime.Object, error) {
130147
stringreplace.VisitObjectStrings(item, func(in string) string {
131-
for _, match := range parameterExp.FindAllStringSubmatch(in, -1) {
132-
if len(match) > 1 {
133-
if paramValue, found := paramMap[match[1]]; found {
134-
in = strings.Replace(in, match[0], paramValue, 1)
135-
}
136-
}
137-
}
138-
return in
148+
return p.EvaluateParameterSubstitution(params, in)
139149
})
140-
141150
return item, nil
142151
}
143152

test/templates/testdata/guestbook.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"description": "Example shows how to build a simple multi-tier application using Kubernetes and Docker"
99
}
1010
},
11+
"message": "Your admin credentials are ${ADMIN_USERNAME}:${ADMIN_PASSWORD}",
1112
"objects": [
1213
{
1314
"kind": "Route",

test/templates/testdata/guestbook_list.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"description": "Example shows how to build a simple multi-tier application using Kubernetes and Docker"
99
}
1010
},
11+
"message": "Your admin credentials are adminQ3H:dwNJiJwW",
1112
"objects": [
1213
{
1314
"apiVersion": "v1",
@@ -310,4 +311,4 @@
310311
"value": "1"
311312
}
312313
]
313-
}
314+
}

0 commit comments

Comments
 (0)