Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c47146e

Browse files
committedDec 8, 2016
new-app/new-build/process: read envvars/params from file
test/cmd/process.sh has been merged into test/cmd/templates.sh since they test the same functionality.
1 parent 7128035 commit c47146e

28 files changed

+408
-214
lines changed
 

‎contrib/completions/bash/oc

+16
Original file line numberDiff line numberDiff line change
@@ -10434,6 +10434,10 @@ _oc_new-app()
1043410434
flags+=("--env=")
1043510435
two_word_flags+=("-e")
1043610436
local_nonpersistent_flags+=("--env=")
10437+
flags+=("--env-file=")
10438+
flags_with_completion+=("--env-file")
10439+
flags_completion+=("_filedir")
10440+
local_nonpersistent_flags+=("--env-file=")
1043710441
flags+=("--file=")
1043810442
flags_with_completion+=("--file")
1043910443
flags_completion+=("__handle_filename_extension_flag yaml|yml|json")
@@ -10468,6 +10472,10 @@ _oc_new-app()
1046810472
flags+=("--param=")
1046910473
two_word_flags+=("-p")
1047010474
local_nonpersistent_flags+=("--param=")
10475+
flags+=("--param-file=")
10476+
flags_with_completion+=("--param-file")
10477+
flags_completion+=("_filedir")
10478+
local_nonpersistent_flags+=("--param-file=")
1047110479
flags+=("--search")
1047210480
flags+=("-S")
1047310481
local_nonpersistent_flags+=("--search")
@@ -10540,6 +10548,10 @@ _oc_new-build()
1054010548
flags+=("--env=")
1054110549
two_word_flags+=("-e")
1054210550
local_nonpersistent_flags+=("--env=")
10551+
flags+=("--env-file=")
10552+
flags_with_completion+=("--env-file")
10553+
flags_completion+=("_filedir")
10554+
local_nonpersistent_flags+=("--env-file=")
1054310555
flags+=("--image-stream=")
1054410556
two_word_flags+=("-i")
1054510557
local_nonpersistent_flags+=("--image-stream=")
@@ -11512,6 +11524,10 @@ _oc_process()
1151211524
flags+=("--param=")
1151311525
two_word_flags+=("-p")
1151411526
local_nonpersistent_flags+=("--param=")
11527+
flags+=("--param-file=")
11528+
flags_with_completion+=("--param-file")
11529+
flags_completion+=("_filedir")
11530+
local_nonpersistent_flags+=("--param-file=")
1151511531
flags+=("--parameters")
1151611532
local_nonpersistent_flags+=("--parameters")
1151711533
flags+=("--raw")

‎contrib/completions/bash/openshift

+16
Original file line numberDiff line numberDiff line change
@@ -15080,6 +15080,10 @@ _openshift_cli_new-app()
1508015080
flags+=("--env=")
1508115081
two_word_flags+=("-e")
1508215082
local_nonpersistent_flags+=("--env=")
15083+
flags+=("--env-file=")
15084+
flags_with_completion+=("--env-file")
15085+
flags_completion+=("_filedir")
15086+
local_nonpersistent_flags+=("--env-file=")
1508315087
flags+=("--file=")
1508415088
flags_with_completion+=("--file")
1508515089
flags_completion+=("__handle_filename_extension_flag yaml|yml|json")
@@ -15114,6 +15118,10 @@ _openshift_cli_new-app()
1511415118
flags+=("--param=")
1511515119
two_word_flags+=("-p")
1511615120
local_nonpersistent_flags+=("--param=")
15121+
flags+=("--param-file=")
15122+
flags_with_completion+=("--param-file")
15123+
flags_completion+=("_filedir")
15124+
local_nonpersistent_flags+=("--param-file=")
1511715125
flags+=("--search")
1511815126
flags+=("-S")
1511915127
local_nonpersistent_flags+=("--search")
@@ -15187,6 +15195,10 @@ _openshift_cli_new-build()
1518715195
flags+=("--env=")
1518815196
two_word_flags+=("-e")
1518915197
local_nonpersistent_flags+=("--env=")
15198+
flags+=("--env-file=")
15199+
flags_with_completion+=("--env-file")
15200+
flags_completion+=("_filedir")
15201+
local_nonpersistent_flags+=("--env-file=")
1519015202
flags+=("--image-stream=")
1519115203
two_word_flags+=("-i")
1519215204
local_nonpersistent_flags+=("--image-stream=")
@@ -16174,6 +16186,10 @@ _openshift_cli_process()
1617416186
flags+=("--param=")
1617516187
two_word_flags+=("-p")
1617616188
local_nonpersistent_flags+=("--param=")
16189+
flags+=("--param-file=")
16190+
flags_with_completion+=("--param-file")
16191+
flags_completion+=("_filedir")
16192+
local_nonpersistent_flags+=("--param-file=")
1617716193
flags+=("--parameters")
1617816194
local_nonpersistent_flags+=("--parameters")
1617916195
flags+=("--raw")

‎contrib/completions/zsh/oc

+16
Original file line numberDiff line numberDiff line change
@@ -10595,6 +10595,10 @@ _oc_new-app()
1059510595
flags+=("--env=")
1059610596
two_word_flags+=("-e")
1059710597
local_nonpersistent_flags+=("--env=")
10598+
flags+=("--env-file=")
10599+
flags_with_completion+=("--env-file")
10600+
flags_completion+=("_filedir")
10601+
local_nonpersistent_flags+=("--env-file=")
1059810602
flags+=("--file=")
1059910603
flags_with_completion+=("--file")
1060010604
flags_completion+=("__handle_filename_extension_flag yaml|yml|json")
@@ -10629,6 +10633,10 @@ _oc_new-app()
1062910633
flags+=("--param=")
1063010634
two_word_flags+=("-p")
1063110635
local_nonpersistent_flags+=("--param=")
10636+
flags+=("--param-file=")
10637+
flags_with_completion+=("--param-file")
10638+
flags_completion+=("_filedir")
10639+
local_nonpersistent_flags+=("--param-file=")
1063210640
flags+=("--search")
1063310641
flags+=("-S")
1063410642
local_nonpersistent_flags+=("--search")
@@ -10701,6 +10709,10 @@ _oc_new-build()
1070110709
flags+=("--env=")
1070210710
two_word_flags+=("-e")
1070310711
local_nonpersistent_flags+=("--env=")
10712+
flags+=("--env-file=")
10713+
flags_with_completion+=("--env-file")
10714+
flags_completion+=("_filedir")
10715+
local_nonpersistent_flags+=("--env-file=")
1070410716
flags+=("--image-stream=")
1070510717
two_word_flags+=("-i")
1070610718
local_nonpersistent_flags+=("--image-stream=")
@@ -11673,6 +11685,10 @@ _oc_process()
1167311685
flags+=("--param=")
1167411686
two_word_flags+=("-p")
1167511687
local_nonpersistent_flags+=("--param=")
11688+
flags+=("--param-file=")
11689+
flags_with_completion+=("--param-file")
11690+
flags_completion+=("_filedir")
11691+
local_nonpersistent_flags+=("--param-file=")
1167611692
flags+=("--parameters")
1167711693
local_nonpersistent_flags+=("--parameters")
1167811694
flags+=("--raw")

‎contrib/completions/zsh/openshift

+16
Original file line numberDiff line numberDiff line change
@@ -15241,6 +15241,10 @@ _openshift_cli_new-app()
1524115241
flags+=("--env=")
1524215242
two_word_flags+=("-e")
1524315243
local_nonpersistent_flags+=("--env=")
15244+
flags+=("--env-file=")
15245+
flags_with_completion+=("--env-file")
15246+
flags_completion+=("_filedir")
15247+
local_nonpersistent_flags+=("--env-file=")
1524415248
flags+=("--file=")
1524515249
flags_with_completion+=("--file")
1524615250
flags_completion+=("__handle_filename_extension_flag yaml|yml|json")
@@ -15275,6 +15279,10 @@ _openshift_cli_new-app()
1527515279
flags+=("--param=")
1527615280
two_word_flags+=("-p")
1527715281
local_nonpersistent_flags+=("--param=")
15282+
flags+=("--param-file=")
15283+
flags_with_completion+=("--param-file")
15284+
flags_completion+=("_filedir")
15285+
local_nonpersistent_flags+=("--param-file=")
1527815286
flags+=("--search")
1527915287
flags+=("-S")
1528015288
local_nonpersistent_flags+=("--search")
@@ -15348,6 +15356,10 @@ _openshift_cli_new-build()
1534815356
flags+=("--env=")
1534915357
two_word_flags+=("-e")
1535015358
local_nonpersistent_flags+=("--env=")
15359+
flags+=("--env-file=")
15360+
flags_with_completion+=("--env-file")
15361+
flags_completion+=("_filedir")
15362+
local_nonpersistent_flags+=("--env-file=")
1535115363
flags+=("--image-stream=")
1535215364
two_word_flags+=("-i")
1535315365
local_nonpersistent_flags+=("--image-stream=")
@@ -16335,6 +16347,10 @@ _openshift_cli_process()
1633516347
flags+=("--param=")
1633616348
two_word_flags+=("-p")
1633716349
local_nonpersistent_flags+=("--param=")
16350+
flags+=("--param-file=")
16351+
flags_with_completion+=("--param-file")
16352+
flags_completion+=("_filedir")
16353+
local_nonpersistent_flags+=("--param-file=")
1633816354
flags+=("--parameters")
1633916355
local_nonpersistent_flags+=("--parameters")
1634016356
flags+=("--raw")

‎docs/man/man1/oc-new-app.1

+8
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ If you provide source code, a new build will be automatically triggered. You can
5858
\fB\-e\fP, \fB\-\-env\fP=[]
5959
Specify a key\-value pair for an environment variable to set into each container.
6060

61+
.PP
62+
\fB\-\-env\-file\fP=""
63+
File containing key\-value pairs of environment variables to set into each container.
64+
6165
.PP
6266
\fB\-f\fP, \fB\-\-file\fP=[]
6367
Path to a template file to use for the app.
@@ -110,6 +114,10 @@ If you provide source code, a new build will be automatically triggered. You can
110114
\fB\-p\fP, \fB\-\-param\fP=[]
111115
Specify a key\-value pair (e.g., \-p FOO=BAR) to set/override a parameter value in the template.
112116

117+
.PP
118+
\fB\-\-param\-file\fP=""
119+
File containing environment parameter values to set/override in the template.
120+
113121
.PP
114122
\fB\-S\fP, \fB\-\-search\fP=false
115123
Search all templates, image streams, and Docker images that match the arguments provided.

‎docs/man/man1/oc-new-build.1

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Once the build configuration is created a new build will be automatically trigge
6666
\fB\-e\fP, \fB\-\-env\fP=[]
6767
Specify a key\-value pair for an environment variable to set into resulting image.
6868

69+
.PP
70+
\fB\-\-env\-file\fP=""
71+
File containing key\-value pairs of environment variables to set into each container.
72+
6973
.PP
7074
\fB\-\-image\fP=[]
7175
Name of an image stream to to use as a builder. (deprecated)

‎docs/man/man1/oc-process.1

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ The output of the process command is always a list of one or more resources. You
4343
\fB\-p\fP, \fB\-\-param\fP=[]
4444
Specify a key\-value pair (eg. \-p FOO=BAR) to set/override a parameter value in the template.
4545

46+
.PP
47+
\fB\-\-param\-file\fP=""
48+
File containing template parameter values to set/override in the template.
49+
4650
.PP
4751
\fB\-\-parameters\fP=false
4852
Do not process but only print available parameters

‎docs/man/man1/openshift-cli-new-app.1

+8
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ If you provide source code, a new build will be automatically triggered. You can
5858
\fB\-e\fP, \fB\-\-env\fP=[]
5959
Specify a key\-value pair for an environment variable to set into each container.
6060

61+
.PP
62+
\fB\-\-env\-file\fP=""
63+
File containing key\-value pairs of environment variables to set into each container.
64+
6165
.PP
6266
\fB\-f\fP, \fB\-\-file\fP=[]
6367
Path to a template file to use for the app.
@@ -110,6 +114,10 @@ If you provide source code, a new build will be automatically triggered. You can
110114
\fB\-p\fP, \fB\-\-param\fP=[]
111115
Specify a key\-value pair (e.g., \-p FOO=BAR) to set/override a parameter value in the template.
112116

117+
.PP
118+
\fB\-\-param\-file\fP=""
119+
File containing environment parameter values to set/override in the template.
120+
113121
.PP
114122
\fB\-S\fP, \fB\-\-search\fP=false
115123
Search all templates, image streams, and Docker images that match the arguments provided.

‎docs/man/man1/openshift-cli-new-build.1

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ Once the build configuration is created a new build will be automatically trigge
6666
\fB\-e\fP, \fB\-\-env\fP=[]
6767
Specify a key\-value pair for an environment variable to set into resulting image.
6868

69+
.PP
70+
\fB\-\-env\-file\fP=""
71+
File containing key\-value pairs of environment variables to set into each container.
72+
6973
.PP
7074
\fB\-\-image\fP=[]
7175
Name of an image stream to to use as a builder. (deprecated)

‎docs/man/man1/openshift-cli-process.1

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ The output of the process command is always a list of one or more resources. You
4343
\fB\-p\fP, \fB\-\-param\fP=[]
4444
Specify a key\-value pair (eg. \-p FOO=BAR) to set/override a parameter value in the template.
4545

46+
.PP
47+
\fB\-\-param\-file\fP=""
48+
File containing template parameter values to set/override in the template.
49+
4650
.PP
4751
\fB\-\-parameters\fP=false
4852
Do not process but only print available parameters

‎pkg/cmd/cli/cli.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) *
9595
cmd.NewCmdTypes(fullName, f, out),
9696
loginCmd,
9797
cmd.NewCmdRequestProject(cmd.RequestProjectRecommendedCommandName, fullName, f, out, errout),
98-
cmd.NewCmdNewApplication(cmd.NewAppRecommendedCommandName, fullName, f, out, errout),
98+
cmd.NewCmdNewApplication(cmd.NewAppRecommendedCommandName, fullName, f, in, out, errout),
9999
cmd.NewCmdStatus(cmd.StatusRecommendedName, fullName, fullName+" "+cmd.StatusRecommendedName, f, out),
100100
cmd.NewCmdProject(fullName+" project", f, out),
101101
cmd.NewCmdProjects(fullName, f, out),
@@ -156,7 +156,7 @@ func NewCommandCLI(name, fullName string, in io.Reader, out, errout io.Writer) *
156156
cmd.NewCmdReplace(fullName, f, out),
157157
cmd.NewCmdApply(fullName, f, out),
158158
cmd.NewCmdPatch(fullName, f, out),
159-
cmd.NewCmdProcess(fullName, f, out, errout),
159+
cmd.NewCmdProcess(fullName, f, in, out, errout),
160160
cmd.NewCmdExport(fullName, f, in, out),
161161
cmd.NewCmdExtract(fullName, f, in, out, errout),
162162
observe.NewCmdObserve(fullName, f, out, errout),

‎pkg/cmd/cli/cmd/dockerbuild/dockerbuild.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/openshift/origin/pkg/cmd/templates"
2121
cmdutil "github.com/openshift/origin/pkg/cmd/util"
2222
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
23+
"github.com/openshift/origin/pkg/generate/app"
2324
)
2425

2526
var (
@@ -55,7 +56,7 @@ type DockerbuildOptions struct {
5556
DockerfilePath string
5657
AllowPull bool
5758
Keyring credentialprovider.DockerKeyring
58-
Arguments cmdutil.Environment
59+
Arguments app.Environment
5960
}
6061

6162
func NewCmdDockerbuild(fullName string, f *clientcmd.Factory, out, errOut io.Writer) *cobra.Command {
@@ -97,7 +98,7 @@ func (o *DockerbuildOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command,
9798
if len(paths) != 2 {
9899
return kcmdutil.UsageError(cmd, "the directory to build and tag must be specified")
99100
}
100-
o.Arguments, _, _ = cmdutil.ParseEnvironmentArguments(envArgs)
101+
o.Arguments, _, _ = app.ParseEnvironment(envArgs...)
101102
o.Directory = paths[0]
102103
o.Tag = paths[1]
103104
if len(o.DockerfilePath) == 0 {

‎pkg/cmd/cli/cmd/newapp.go

+10-7
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ import (
4545
// NewAppRecommendedCommandName is the recommended command name.
4646
const NewAppRecommendedCommandName = "new-app"
4747

48-
type usage interface {
49-
UsageError(baseName string) string
50-
}
51-
5248
var (
5349
newAppLong = templates.LongDesc(`
5450
Create a new application by specifying source code, templates, and/or images
@@ -129,14 +125,15 @@ type NewAppOptions struct {
129125
CommandPath string
130126
CommandName string
131127

128+
In io.Reader
132129
Out, ErrOut io.Writer
133130
Output string
134131
PrintObject func(obj runtime.Object) error
135132
LogsForObject LogsForObjectFunc
136133
}
137134

138135
// NewCmdNewApplication implements the OpenShift cli new-app command.
139-
func NewCmdNewApplication(name, baseName string, f *clientcmd.Factory, out, errout io.Writer) *cobra.Command {
136+
func NewCmdNewApplication(name, baseName string, f *clientcmd.Factory, in io.Reader, out, errout io.Writer) *cobra.Command {
140137
config := newcmd.NewAppConfig()
141138
config.Deploy = true
142139
o := &NewAppOptions{Config: config}
@@ -148,7 +145,7 @@ func NewCmdNewApplication(name, baseName string, f *clientcmd.Factory, out, erro
148145
Example: fmt.Sprintf(newAppExample, baseName, name),
149146
SuggestFor: []string{"app", "application"},
150147
Run: func(c *cobra.Command, args []string) {
151-
kcmdutil.CheckErr(o.Complete(baseName, name, f, c, args, out, errout))
148+
kcmdutil.CheckErr(o.Complete(baseName, name, f, c, args, in, out, errout))
152149
err := o.RunNewApp()
153150
if err == cmdutil.ErrExit {
154151
os.Exit(1)
@@ -168,8 +165,12 @@ func NewCmdNewApplication(name, baseName string, f *clientcmd.Factory, out, erro
168165
cmd.Flags().StringSliceVarP(&config.TemplateFiles, "file", "f", config.TemplateFiles, "Path to a template file to use for the app.")
169166
cmd.MarkFlagFilename("file", "yaml", "yml", "json")
170167
cmd.Flags().StringArrayVarP(&config.TemplateParameters, "param", "p", config.TemplateParameters, "Specify a key-value pair (e.g., -p FOO=BAR) to set/override a parameter value in the template.")
168+
cmd.Flags().StringArrayVar(&config.TemplateParameterFiles, "param-file", config.TemplateParameterFiles, "File containing parameter values to set/override in the template.")
169+
cmd.MarkFlagFilename("param-file")
171170
cmd.Flags().StringSliceVar(&config.Groups, "group", config.Groups, "Indicate components that should be grouped together as <comp1>+<comp2>.")
172171
cmd.Flags().StringArrayVarP(&config.Environment, "env", "e", config.Environment, "Specify a key-value pair for an environment variable to set into each container.")
172+
cmd.Flags().StringArrayVar(&config.EnvironmentFiles, "env-file", config.EnvironmentFiles, "File containing key-value pairs of environment variables to set into each container.")
173+
cmd.MarkFlagFilename("env-file")
173174
cmd.Flags().StringVar(&config.Name, "name", "", "Set name to use for generated application artifacts")
174175
cmd.Flags().Var(&config.Strategy, "strategy", "Specify the build strategy to use if you don't want to detect (docker|pipeline|source).")
175176
cmd.Flags().StringP("labels", "l", "", "Label to set in all resources for this application.")
@@ -188,12 +189,14 @@ func NewCmdNewApplication(name, baseName string, f *clientcmd.Factory, out, erro
188189
}
189190

190191
// Complete sets any default behavior for the command
191-
func (o *NewAppOptions) Complete(baseName, name string, f *clientcmd.Factory, c *cobra.Command, args []string, out, errout io.Writer) error {
192+
func (o *NewAppOptions) Complete(baseName, name string, f *clientcmd.Factory, c *cobra.Command, args []string, in io.Reader, out, errout io.Writer) error {
193+
o.In = in
192194
o.Out = out
193195
o.ErrOut = errout
194196
o.Output = kcmdutil.GetFlagString(c, "output")
195197
// Only output="" should print descriptions of intermediate steps. Everything
196198
// else should print only some specific output (json, yaml, go-template, ...)
199+
o.Config.In = o.In
197200
if len(o.Output) == 0 {
198201
o.Config.Out = o.Out
199202
} else {

‎pkg/cmd/cli/cmd/newapp_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ func TestNewAppDefaultFlags(t *testing.T) {
112112
},
113113
}
114114

115-
cmd := NewCmdNewApplication("oc", NewAppRecommendedCommandName, nil, nil, nil)
115+
cmd := NewCmdNewApplication("oc", NewAppRecommendedCommandName, nil, nil, nil, nil)
116116

117117
for _, v := range tests {
118118
f := cmd.Flag(v.flagName)

‎pkg/cmd/cli/cmd/newbuild.go

+5
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ type NewBuildOptions struct {
9090
CommandPath string
9191
CommandName string
9292

93+
In io.Reader
9394
Out, ErrOut io.Writer
9495
Output string
9596
PrintObject func(obj runtime.Object) error
@@ -129,6 +130,8 @@ func NewCmdNewBuild(name, baseName string, f *clientcmd.Factory, in io.Reader, o
129130
cmd.Flags().StringVar(&config.To, "to", "", "Push built images to this image stream tag (or Docker image repository if --to-docker is set).")
130131
cmd.Flags().BoolVar(&config.OutputDocker, "to-docker", false, "Have the build output push to a Docker repository.")
131132
cmd.Flags().StringArrayVarP(&config.Environment, "env", "e", config.Environment, "Specify a key-value pair for an environment variable to set into resulting image.")
133+
cmd.Flags().StringArrayVar(&config.EnvironmentFiles, "env-file", config.EnvironmentFiles, "File containing key-value pairs of environment variables to set into each container.")
134+
cmd.MarkFlagFilename("env-file")
132135
cmd.Flags().Var(&config.Strategy, "strategy", "Specify the build strategy to use if you don't want to detect (docker|pipeline|source).")
133136
cmd.Flags().StringVarP(&config.Dockerfile, "dockerfile", "D", "", "Specify the contents of a Dockerfile to build directly, implies --strategy=docker. Pass '-' to read from STDIN.")
134137
cmd.Flags().BoolVar(&config.BinaryBuild, "binary", false, "Instead of expecting a source URL, set the build to expect binary contents. Will disable triggers.")
@@ -148,11 +151,13 @@ func NewCmdNewBuild(name, baseName string, f *clientcmd.Factory, in io.Reader, o
148151

149152
// Complete sets any default behavior for the command
150153
func (o *NewBuildOptions) Complete(baseName, commandName string, f *clientcmd.Factory, c *cobra.Command, args []string, out, errout io.Writer, in io.Reader) error {
154+
o.In = in
151155
o.Out = out
152156
o.ErrOut = errout
153157
o.Output = kcmdutil.GetFlagString(c, "output")
154158
// Only output="" should print descriptions of intermediate steps. Everything
155159
// else should print only some specific output (json, yaml, go-template, ...)
160+
o.Config.In = in
156161
if len(o.Output) == 0 {
157162
o.Config.Out = o.Out
158163
} else {

‎pkg/cmd/cli/cmd/process.go

+28-45
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/openshift/origin/pkg/cmd/templates"
2323
cmdutil "github.com/openshift/origin/pkg/cmd/util"
2424
"github.com/openshift/origin/pkg/cmd/util/clientcmd"
25+
"github.com/openshift/origin/pkg/generate/app"
2526
"github.com/openshift/origin/pkg/template"
2627
templateapi "github.com/openshift/origin/pkg/template/api"
2728
)
@@ -58,14 +59,14 @@ var (
5859
)
5960

6061
// NewCmdProcess implements the OpenShift cli process command
61-
func NewCmdProcess(fullName string, f *clientcmd.Factory, out, errout io.Writer) *cobra.Command {
62+
func NewCmdProcess(fullName string, f *clientcmd.Factory, in io.Reader, out, errout io.Writer) *cobra.Command {
6263
cmd := &cobra.Command{
6364
Use: "process (TEMPLATE | -f FILENAME) [-v=KEY=VALUE]",
6465
Short: "Process a template into list of resources",
6566
Long: processLong,
6667
Example: fmt.Sprintf(processExample, fullName),
6768
Run: func(cmd *cobra.Command, args []string) {
68-
err := RunProcess(f, out, errout, cmd, args)
69+
err := RunProcess(f, in, out, errout, cmd, args)
6970
kcmdutil.CheckErr(err)
7071
},
7172
}
@@ -75,6 +76,8 @@ func NewCmdProcess(fullName string, f *clientcmd.Factory, out, errout io.Writer)
7576
cmd.Flags().MarkDeprecated("value", "Use -p, --param instead.")
7677
cmd.Flags().MarkHidden("value")
7778
cmd.Flags().StringArrayVarP(params, "param", "p", nil, "Specify a key-value pair (eg. -p FOO=BAR) to set/override a parameter value in the template.")
79+
cmd.Flags().StringArray("param-file", []string{}, "File containing template parameter values to set/override in the template.")
80+
cmd.MarkFlagFilename("param-file")
7881
cmd.Flags().BoolP("parameters", "", false, "Do not process but only print available parameters")
7982
cmd.Flags().StringP("labels", "l", "", "Label to set in all resources for this template")
8083

@@ -87,47 +90,37 @@ func NewCmdProcess(fullName string, f *clientcmd.Factory, out, errout io.Writer)
8790
}
8891

8992
// RunProcess contains all the necessary functionality for the OpenShift cli process command
90-
func RunProcess(f *clientcmd.Factory, out, errout io.Writer, cmd *cobra.Command, args []string) error {
91-
templateName, valueArgs := "", []string{}
93+
func RunProcess(f *clientcmd.Factory, in io.Reader, out, errout io.Writer, cmd *cobra.Command, args []string) error {
94+
templateName, templateParams := "", []string{}
9295
for _, s := range args {
9396
isValue := strings.Contains(s, "=")
9497
switch {
9598
case isValue:
96-
valueArgs = append(valueArgs, s)
99+
templateParams = append(templateParams, s)
97100
case !isValue && len(templateName) == 0:
98101
templateName = s
99102
case !isValue && len(templateName) > 0:
100103
return kcmdutil.UsageError(cmd, "template name must be specified only once: %s", s)
101104
}
102105
}
103106

104-
keys := sets.NewString()
105-
duplicatedKeys := sets.NewString()
106-
107-
var flagValues []string
108107
if cmd.Flag("value").Changed || cmd.Flag("param").Changed {
109-
flagValues = getFlagStringArray(cmd, "param")
108+
flagValues := getFlagStringArray(cmd, "param")
110109
cmdutil.WarnAboutCommaSeparation(errout, flagValues, "--param")
110+
templateParams = append(templateParams, flagValues...)
111111
}
112112

113-
for _, value := range flagValues {
114-
key := strings.Split(value, "=")[0]
115-
if keys.Has(key) {
116-
duplicatedKeys.Insert(key)
117-
}
118-
keys.Insert(key)
119-
}
120-
121-
for _, value := range valueArgs {
122-
key := strings.Split(value, "=")[0]
123-
if keys.Has(key) {
113+
duplicatedKeys := sets.NewString()
114+
params, paramErrs := app.ParseAndCombineEnvironment(templateParams, getFlagStringArray(cmd, "param-file"), in, func(key, file string) error {
115+
if file == "" {
124116
duplicatedKeys.Insert(key)
117+
} else {
118+
fmt.Fprintf(errout, "warning: Template parameter %q already defined, ignoring value from file %q", key, file)
125119
}
126-
keys.Insert(key)
127-
}
128-
120+
return nil
121+
})
129122
if len(duplicatedKeys) != 0 {
130-
return kcmdutil.UsageError(cmd, fmt.Sprintf("The following values were provided more than once: %s", strings.Join(duplicatedKeys.List(), ", ")))
123+
return kcmdutil.UsageError(cmd, fmt.Sprintf("The following parameters were provided more than once: %s", strings.Join(duplicatedKeys.List(), ", ")))
131124
}
132125

133126
filename := kcmdutil.GetFlagString(cmd, "filename")
@@ -240,16 +233,11 @@ func RunProcess(f *clientcmd.Factory, out, errout io.Writer, cmd *cobra.Command,
240233
}
241234
}
242235

243-
// Override the parameter values for the current template parameters
244-
// when user specifies --param
245-
if cmd.Flag("value").Changed || cmd.Flag("param").Changed {
246-
values := getFlagStringArray(cmd, "param")
247-
if errs := injectUserVars(values, obj); errs != nil {
248-
return kerrors.NewAggregate(errs)
249-
}
236+
// Raise parameter parsing errors here after we had chance to return UsageErrors first
237+
if len(paramErrs) > 0 {
238+
return kerrors.NewAggregate(paramErrs)
250239
}
251-
252-
if errs := injectUserVars(valueArgs, obj); errs != nil {
240+
if errs := injectUserVars(params, obj); errs != nil {
253241
return kerrors.NewAggregate(errs)
254242
}
255243

@@ -299,19 +287,14 @@ func RunProcess(f *clientcmd.Factory, out, errout io.Writer, cmd *cobra.Command,
299287
}
300288

301289
// injectUserVars injects user specified variables into the Template
302-
func injectUserVars(values []string, t *templateapi.Template) []error {
290+
func injectUserVars(values app.Environment, t *templateapi.Template) []error {
303291
var errors []error
304-
for _, keypair := range values {
305-
p := strings.SplitN(keypair, "=", 2)
306-
if len(p) != 2 {
307-
errors = append(errors, fmt.Errorf("invalid parameter assignment in %q: %q\n", t.Name, keypair))
292+
for param, val := range values {
293+
if v := template.GetParameterByName(t, param); v != nil {
294+
v.Value = val
295+
v.Generate = ""
308296
} else {
309-
if v := template.GetParameterByName(t, p[0]); v != nil {
310-
v.Value = p[1]
311-
v.Generate = ""
312-
} else {
313-
errors = append(errors, fmt.Errorf("unknown parameter name %q\n", p[0]))
314-
}
297+
errors = append(errors, fmt.Errorf("unknown parameter name %q\n", param))
315298
}
316299
}
317300
return errors

‎pkg/cmd/cli/cmd/process_test.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ func TestInjectUserVars(t *testing.T) {
1313
{Name: "parameter_foo_bar_2", Value: "value_foo_bar_2"}},
1414
}
1515
oldParameterNum := len(template.Parameters)
16-
testParam := []string{"parameter_foo_bar_exist=value_foo_bar_exist_new",
17-
"parameter_foo_bar_no_exist=value_foo_bar_no_exist",
18-
"parameter_foo_bar_error=value_foo_bar_error=value_foo_bar_error"}
16+
testParam := map[string]string{
17+
"parameter_foo_bar_exist": "value_foo_bar_exist_new",
18+
"parameter_foo_bar_no_exist": "value_foo_bar_no_exist",
19+
"parameter_foo_bar_error": "value_foo_bar_error=value_foo_bar_error",
20+
}
1921

2022
errors := injectUserVars(testParam, template)
2123
if len(errors) != 2 {

‎pkg/cmd/util/env.go

-21
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ func GetEnv(key string) (string, bool) {
3939
return val, true
4040
}
4141

42-
type Environment map[string]string
43-
4442
var argumentEnvironment = regexp.MustCompile("(?ms)^(.+)\\=(.*)$")
4543
var validArgumentEnvironment = regexp.MustCompile("(?ms)^(\\w+)\\=(.*)$")
4644

@@ -72,25 +70,6 @@ func SplitEnvironmentFromResources(args []string) (resources, envArgs []string,
7270
return resources, envArgs, true
7371
}
7472

75-
func ParseEnvironmentArguments(s []string) (Environment, []string, []error) {
76-
errs := []error{}
77-
duplicates := []string{}
78-
env := make(Environment)
79-
for _, s := range s {
80-
switch matches := validArgumentEnvironment.FindStringSubmatch(s); len(matches) {
81-
case 3:
82-
k, v := matches[1], matches[2]
83-
if exist, ok := env[k]; ok {
84-
duplicates = append(duplicates, fmt.Sprintf("%s=%s", k, exist))
85-
}
86-
env[k] = v
87-
default:
88-
errs = append(errs, fmt.Errorf("environment variables must be of the form key=value: %s", s))
89-
}
90-
}
91-
return env, duplicates, errs
92-
}
93-
9473
// ParseEnv parses the list of environment variables into kubernetes EnvVar
9574
func ParseEnv(spec []string, defaultReader io.Reader) ([]kapi.EnvVar, []string, error) {
9675
env := []kapi.EnvVar{}

‎pkg/generate/app/cmd/newapp.go

+24-30
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ type GenerationInputs struct {
5454
Environment []string
5555
Labels map[string]string
5656

57+
TemplateParameterFiles []string
58+
EnvironmentFiles []string
59+
5760
AddEnvironmentToBuild bool
5861

5962
InsecureRegistry bool
@@ -100,6 +103,7 @@ type AppConfig struct {
100103
AsList bool
101104
DryRun bool
102105

106+
In io.Reader
103107
Out io.Writer
104108
ErrOut io.Writer
105109

@@ -115,16 +119,6 @@ type AppConfig struct {
115119
OriginNamespace string
116120
}
117121

118-
// UsageError is an interface for printing usage errors
119-
type UsageError interface {
120-
UsageError(commandName string) string
121-
}
122-
123-
// TODO: replace with upstream converting [1]error to error
124-
type errlist interface {
125-
Errors() []error
126-
}
127-
128122
type ErrRequiresExplicitAccess struct {
129123
Match app.ComponentMatch
130124
Input app.GeneratorInput
@@ -579,27 +573,29 @@ func (c *AppConfig) RunQuery() (*QueryResult, error) {
579573
}, nil
580574
}
581575

582-
func (c *AppConfig) validate() (cmdutil.Environment, cmdutil.Environment, error) {
583-
var errs []error
584-
585-
env, duplicateEnv, envErrs := cmdutil.ParseEnvironmentArguments(c.Environment)
586-
for _, s := range duplicateEnv {
587-
fmt.Fprintf(c.ErrOut, "warning: The environment variable %q was overwritten", s)
588-
}
589-
errs = append(errs, envErrs...)
590-
591-
params, duplicateParams, paramsErrs := cmdutil.ParseEnvironmentArguments(c.TemplateParameters)
592-
for _, s := range duplicateParams {
593-
fmt.Fprintf(c.ErrOut, "warning: The template parameter %q was overwritten", s)
594-
}
595-
errs = append(errs, paramsErrs...)
596-
597-
return env, params, kutilerrors.NewAggregate(errs)
576+
func (c *AppConfig) validate() (app.Environment, app.Environment, error) {
577+
env, envErrs := app.ParseAndCombineEnvironment(c.Environment, c.EnvironmentFiles, c.In, func(key, file string) error {
578+
if file == "" {
579+
fmt.Fprintf(c.ErrOut, "warning: Environment variable %q was overwritten\n", key)
580+
} else {
581+
fmt.Fprintf(c.ErrOut, "warning: Environment variable %q already defined, ignoring value from file %q\n", key, file)
582+
}
583+
return nil
584+
})
585+
params, paramErrs := app.ParseAndCombineEnvironment(c.TemplateParameters, c.TemplateParameterFiles, c.In, func(key, file string) error {
586+
if file == "" {
587+
fmt.Fprintf(c.ErrOut, "warning: Template parameter %q was overwritten\n", key)
588+
} else {
589+
fmt.Fprintf(c.ErrOut, "warning: Template parameter %q already defined, ignoring value from file %q\n", key, file)
590+
}
591+
return nil
592+
})
593+
return env, params, kutilerrors.NewAggregate(append(envErrs, paramErrs...))
598594
}
599595

600596
// Run executes the provided config to generate objects.
601597
func (c *AppConfig) Run() (*AppResult, error) {
602-
environment, parameters, err := c.validate()
598+
env, parameters, err := c.validate()
603599
if err != nil {
604600
return nil, err
605601
}
@@ -645,8 +641,6 @@ func (c *AppConfig) Run() (*AppResult, error) {
645641
return nil, errors.New("only one component with source can be used when specifying an output image reference")
646642
}
647643

648-
env := app.Environment(environment)
649-
650644
// identify if there are installable components in the input provided by the user
651645
installables, name, err := c.installComponents(components, env)
652646
if err != nil {
@@ -680,7 +674,7 @@ func (c *AppConfig) Run() (*AppResult, error) {
680674

681675
objects = app.AddServices(objects, false)
682676

683-
templateName, templateObjects, err := c.buildTemplates(components.TemplateComponentRefs(), app.Environment(parameters), app.Environment(environment))
677+
templateName, templateObjects, err := c.buildTemplates(components.TemplateComponentRefs(), parameters, env)
684678
if err != nil {
685679
return nil, err
686680
}

‎pkg/generate/app/env.go

+106-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
package app
22

33
import (
4+
"fmt"
5+
"io"
6+
"io/ioutil"
7+
"os"
48
"sort"
59
"strings"
610

11+
"github.com/joho/godotenv"
712
kapi "k8s.io/kubernetes/pkg/api"
813
)
914

1015
// Environment holds environment variables for new-app
1116
type Environment map[string]string
1217

13-
// ParseEnvironment converts the provided strings in key=value form into environment
14-
// entries.
15-
func ParseEnvironment(vals ...string) Environment {
18+
// ParseEnvironmentAllowEmpty converts the provided strings in key=value form
19+
// into environment entries. In case there's no equals sign in a string, it's
20+
// considered as a key with empty value.
21+
func ParseEnvironmentAllowEmpty(vals ...string) Environment {
1622
env := make(Environment)
1723
for _, s := range vals {
1824
if i := strings.Index(s, "="); i == -1 {
@@ -24,6 +30,26 @@ func ParseEnvironment(vals ...string) Environment {
2430
return env
2531
}
2632

33+
func ParseEnvironment(vals ...string) (Environment, []string, []error) {
34+
errs := []error{}
35+
duplicates := []string{}
36+
env := make(Environment)
37+
for _, s := range vals {
38+
p := strings.SplitN(s, "=", 2)
39+
if len(p) != 2 {
40+
errs = append(errs, fmt.Errorf("invalid parameter assignment in %q", s))
41+
continue
42+
}
43+
key, val := p[0], p[1]
44+
if _, exists := env[key]; exists {
45+
duplicates = append(duplicates, key)
46+
continue
47+
}
48+
env[key] = val
49+
}
50+
return env, duplicates, errs
51+
}
52+
2753
// NewEnvironment returns a new set of environment variables based on all
2854
// the provided environment variables
2955
func NewEnvironment(envs ...map[string]string) Environment {
@@ -44,6 +70,22 @@ func (e Environment) Add(envs ...map[string]string) {
4470
}
4571
}
4672

73+
// AddIfNotPresent adds the environment variables to the current environment.
74+
// In case of key conflict the old value is kept. Conflicting keys are returned
75+
// as a slice.
76+
func (e Environment) AddIfNotPresent(more Environment) []string {
77+
duplicates := []string{}
78+
for k, v := range more {
79+
if _, exists := e[k]; exists {
80+
duplicates = append(duplicates, k)
81+
} else {
82+
e[k] = v
83+
}
84+
}
85+
86+
return duplicates
87+
}
88+
4789
// List sorts and returns all the environment variables
4890
func (e Environment) List() []kapi.EnvVar {
4991
env := []kapi.EnvVar{}
@@ -82,3 +124,64 @@ func JoinEnvironment(a, b []kapi.EnvVar) (out []kapi.EnvVar) {
82124
}
83125
return out
84126
}
127+
128+
func LoadEnvironmentFile(filename string, stdin io.Reader) (Environment, error) {
129+
errorFilename := filename
130+
131+
if filename == "-" && stdin != nil {
132+
//once https://github.com/joho/godotenv/pull/20 is merged we can get rid of using tempfile
133+
temp, err := ioutil.TempFile("", "origin-env-stdin")
134+
if err != nil {
135+
return nil, fmt.Errorf("Cannot create temporary file: %s", err)
136+
}
137+
138+
filename = temp.Name()
139+
errorFilename = "stdin"
140+
defer os.Remove(filename)
141+
142+
if _, err = io.Copy(temp, stdin); err != nil {
143+
return nil, fmt.Errorf("Cannot write to temporary file %q: %s", filename, err)
144+
}
145+
temp.Close()
146+
}
147+
148+
env, err := godotenv.Read(filename)
149+
if err != nil {
150+
return nil, fmt.Errorf("Cannot read variables from file %s: %s", errorFilename, err)
151+
}
152+
return env, nil
153+
}
154+
155+
// ParseAndCombineEnvironment parses key-value records from the command line
156+
// and from given files and combines them into single map.
157+
//
158+
// The dupfn function is called for all duplicate keys that encountered. If the
159+
// functions returns an error it is added to the list of errors returned by
160+
// ParseAndCombineEnvironment.
161+
//
162+
// If a file is "-" the file contents will be read from argument stdin (unless
163+
// it's nil).
164+
func ParseAndCombineEnvironment(cmdline []string, filenames []string, stdin io.Reader, dupfn func(string, string) error) (Environment, []error) {
165+
vars, duplicates, errs := ParseEnvironment(cmdline...)
166+
for _, s := range duplicates {
167+
if dupErr := dupfn(s, ""); dupErr != nil {
168+
errs = append(errs, dupErr)
169+
}
170+
}
171+
172+
for _, fname := range filenames {
173+
fileVars, fileErr := LoadEnvironmentFile(fname, stdin)
174+
if fileErr != nil {
175+
errs = append(errs, fileErr)
176+
}
177+
178+
duplicates = vars.AddIfNotPresent(fileVars)
179+
for _, s := range duplicates {
180+
if dupErr := dupfn(s, fname); dupErr != nil {
181+
errs = append(errs, dupErr)
182+
}
183+
}
184+
}
185+
186+
return vars, errs
187+
}

‎pkg/generate/dockercompose/generate.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ func Generate(paths ...string) (*templateapi.Template, error) {
280280
if len(v.WorkingDir) > 0 {
281281
c.WorkingDir = v.WorkingDir
282282
}
283-
c.Env = append(c.Env, app.ParseEnvironment(v.Environment.Slice()...).List()...)
283+
c.Env = append(c.Env, app.ParseEnvironmentAllowEmpty(v.Environment.Slice()...).List()...)
284284
if uid, err := strconv.Atoi(v.User); err == nil {
285285
uid64 := int64(uid)
286286
if c.SecurityContext == nil {

‎test/cmd/newapp.sh

+20
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@ os::cmd::expect_success_and_not_text 'oc new-app ruby-helloworld-sample --param
8282
os::cmd::expect_success_and_text 'oc new-app php PASS=one,two=three -o yaml' 'value: one,two=three'
8383
os::cmd::expect_success_and_not_text 'oc new-app php PASS=one,two=three -o yaml' 'no longer accepts comma-separated list'
8484

85+
# check that we can populate template parameters from file
86+
param_file="${OS_ROOT}/test/testdata/test-cmd-newapp-params.env"
87+
os::cmd::expect_success_and_text "oc new-app ruby-helloworld-sample --param-file ${param_file} -o jsonpath='{.items[?(@.kind==\"DeploymentConfig\")].spec.template.spec.containers[0].env[?(@.name==\"MYSQL_PASSWORD\")].value}'" 'thisisapassword'
88+
os::cmd::expect_success_and_text "oc new-app ruby-helloworld-sample --param-file ${param_file} --param MYSQL_PASSWORD=otherpass -o jsonpath='{.items[?(@.kind==\"DeploymentConfig\")].spec.template.spec.containers[0].env[?(@.name==\"MYSQL_PASSWORD\")].value}'" 'otherpass'
89+
os::cmd::expect_success_and_text "oc new-app ruby-helloworld-sample --param-file ${param_file} --param MYSQL_PASSWORD=otherpass -o yaml" 'ignoring value from file'
90+
os::cmd::expect_success_and_text "cat ${param_file} | oc new-app ruby-helloworld-sample --param-file - -o jsonpath='{.items[?(@.kind==\"DeploymentConfig\")].spec.template.spec.containers[0].env[?(@.name==\"MYSQL_PASSWORD\")].value}'" 'thisisapassword'
91+
92+
# check that we can set environment variables from env file
93+
env_file="${OS_ROOT}/test/testdata/test-cmd-newapp-env.env"
94+
os::cmd::expect_success_and_text "oc new-app php --env-file ${env_file} -o jsonpath='{.items[?(@.kind==\"DeploymentConfig\")].spec.template.spec.containers[0].env[?(@.name==\"SOME_VAR\")].value}'" 'envvarfromfile'
95+
os::cmd::expect_success_and_text "oc new-app php --env-file ${env_file} --env SOME_VAR=fromcmdline -o jsonpath='{.items[?(@.kind==\"DeploymentConfig\")].spec.template.spec.containers[0].env[?(@.name==\"SOME_VAR\")].value}'" 'fromcmdline'
96+
os::cmd::expect_success_and_text "oc new-app php --env-file ${env_file} --env SOME_VAR=fromcmdline -o yaml" 'ignoring value from file'
97+
os::cmd::expect_success_and_text "cat ${env_file} | oc new-app php --env-file - -o jsonpath='{.items[?(@.kind==\"DeploymentConfig\")].spec.template.spec.containers[0].env[?(@.name==\"SOME_VAR\")].value}'" 'envvarfromfile'
98+
8599
# new-build
86100
# check that env vars are not split on commas and warning is printed where they previously have
87101
os::cmd::expect_success_and_text 'oc new-build --binary php --env X=Y,Z=W -o yaml' 'value: Y,Z=W'
@@ -92,6 +106,12 @@ os::cmd::expect_success_and_not_text 'oc new-build --binary php --env X=Y -o yam
92106
os::cmd::expect_success_and_text 'oc new-build --binary php X=Y,Z=W -o yaml' 'value: Y,Z=W'
93107
os::cmd::expect_success_and_not_text 'oc new-build --binary php X=Y,Z=W -o yaml' 'no longer accepts comma-separated list'
94108

109+
# new-build - load envvars from file
110+
os::cmd::expect_success_and_text "oc new-build --binary php --env-file ${env_file} -o jsonpath='{.items[?(@.kind==\"BuildConfig\")].spec.strategy.sourceStrategy.env[?(@.name==\"SOME_VAR\")].value}'" 'envvarfromfile'
111+
os::cmd::expect_success_and_text "oc new-build --binary php --env-file ${env_file} --env SOME_VAR=fromcmdline -o jsonpath='{.items[?(@.kind==\"BuildConfig\")].spec.strategy.sourceStrategy.env[?(@.name==\"SOME_VAR\")].value}'" 'fromcmdline'
112+
os::cmd::expect_success_and_text "oc new-build --binary php --env-file ${env_file} --env SOME_VAR=fromcmdline -o yaml" 'ignoring value from file'
113+
os::cmd::expect_success_and_text "cat ${env_file} | oc new-build --binary php --env-file ${env_file} -o jsonpath='{.items[?(@.kind==\"BuildConfig\")].spec.strategy.sourceStrategy.env[?(@.name==\"SOME_VAR\")].value}'" 'envvarfromfile'
114+
95115
# verify we can create from a template when some objects in the template declare an app label
96116
# the app label will not be applied to any objects in the template.
97117
os::cmd::expect_success_and_not_text 'oc new-app -f test/testdata/template-with-app-label.json -o yaml' 'app: ruby-helloworld-sample'

‎test/cmd/process.sh

-93
This file was deleted.

‎test/cmd/templates.sh

+99-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ trap os::test::junit::reconcile_output EXIT
88
oc delete all,templates --all
99
oc delete template/ruby-helloworld-sample -n openshift
1010
oc delete project test-template-project
11+
oc delete user someval someval=moreval someval=moreval2 someval=moreval3
1112
exit 0
1213
) &>/dev/null
1314

@@ -30,24 +31,41 @@ echo "templates: ok"
3031
os::test::junit::declare_suite_end
3132

3233
os::test::junit::declare_suite_start "cmd/templates/config"
33-
os::cmd::expect_success 'oc process -f test/templates/testdata/guestbook.json -l app=guestbook | oc create -f -'
34+
guestbook_template="${OS_ROOT}/test/templates/testdata/guestbook.json"
35+
os::cmd::expect_success "oc process -f '${guestbook_template}' -l app=guestbook | oc create -f -"
3436
os::cmd::expect_success_and_text 'oc status' 'frontend-service'
3537
echo "template+config: ok"
3638
os::test::junit::declare_suite_end
3739

3840
os::test::junit::declare_suite_start "cmd/templates/parameters"
41+
guestbook_params="${OS_ROOT}/test/templates/testdata/guestbook.env"
3942
# Individually specified parameter values are honored
40-
os::cmd::expect_success_and_text 'oc process -f test/templates/testdata/guestbook.json -p ADMIN_USERNAME=myuser -p ADMIN_PASSWORD=mypassword' '"myuser"'
41-
os::cmd::expect_success_and_text 'oc process -f test/templates/testdata/guestbook.json -p ADMIN_USERNAME=myuser -p ADMIN_PASSWORD=mypassword' '"mypassword"'
43+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' -p ADMIN_USERNAME=myuser -p ADMIN_PASSWORD=mypassword" '"myuser"'
44+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' -p ADMIN_USERNAME=myuser -p ADMIN_PASSWORD=mypassword" '"mypassword"'
4245
# Argument values are honored
43-
os::cmd::expect_success_and_text 'oc process ADMIN_USERNAME=myuser ADMIN_PASSWORD=mypassword -f test/templates/testdata/guestbook.json' '"myuser"'
44-
os::cmd::expect_success_and_text 'oc process -f test/templates/testdata/guestbook.json ADMIN_USERNAME=myuser ADMIN_PASSWORD=mypassword' '"mypassword"'
46+
os::cmd::expect_success_and_text "oc process ADMIN_USERNAME=myuser ADMIN_PASSWORD=mypassword -f '${guestbook_template}'" '"myuser"'
47+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' ADMIN_USERNAME=myuser ADMIN_PASSWORD=mypassword" '"mypassword"'
4548
# Argument values with commas are honored
4649
os::cmd::expect_success 'oc create -f examples/sample-app/application-template-stibuild.json'
4750
os::cmd::expect_success_and_text 'oc process ruby-helloworld-sample MYSQL_USER=myself MYSQL_PASSWORD=my,1%pa=s' '"myself"'
4851
os::cmd::expect_success_and_text 'oc process MYSQL_USER=myself MYSQL_PASSWORD=my,1%pa=s ruby-helloworld-sample' '"my,1%pa=s"'
4952
os::cmd::expect_success_and_text 'oc process ruby-helloworld-sample -p MYSQL_USER=myself -p MYSQL_PASSWORD=my,1%pa=s' '"myself"'
5053
os::cmd::expect_success_and_text 'oc process -p MYSQL_USER=myself -p MYSQL_PASSWORD=my,1%pa=s ruby-helloworld-sample' '"my,1%pa=s"'
54+
# Argument values can be read from file
55+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' --param-file='${guestbook_params}'" '"root"'
56+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' --param-file='${guestbook_params}'" '"adminpass"'
57+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' --param-file='${guestbook_params}'" '"redispass"'
58+
# Argument values can be read from stdin
59+
os::cmd::expect_success_and_text "cat '${guestbook_params}' | oc process -f '${guestbook_template}' --param-file=-" '"root"'
60+
os::cmd::expect_success_and_text "cat '${guestbook_params}' | oc process -f '${guestbook_template}' --param-file=-" '"adminpass"'
61+
os::cmd::expect_success_and_text "cat '${guestbook_params}' | oc process -f '${guestbook_template}' --param-file=-" '"redispass"'
62+
# Argument values from command line have precedence over those from file
63+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' --param-file='${guestbook_params}' -p ADMIN_USERNAME=myuser" 'ignoring value from file'
64+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' --param-file='${guestbook_params}' -p ADMIN_USERNAME=myuser" '"myuser"'
65+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' --param-file='${guestbook_params}' -p ADMIN_PASSWORD=mypassword" '"mypassword"'
66+
os::cmd::expect_success_and_text "oc process -f '${guestbook_template}' --param-file='${guestbook_params}' -p REDIS_PASSWORD=rrr" '"rrr"'
67+
# Set template parameters from parameter file with multiline values
68+
os::cmd::expect_success_and_text "oc process -f test/testdata/template_required_params.yaml --param-file=test/testdata/template_required_params.env -o yaml" 'first$'
5169
os::cmd::expect_success 'oc delete template ruby-helloworld-sample'
5270
echo "template+parameters: ok"
5371
os::test::junit::declare_suite_end
@@ -81,6 +99,7 @@ os::cmd::expect_success 'oc create -f examples/sample-app/application-template-d
8199
os::cmd::expect_success 'oc policy add-role-to-user admin test-user'
82100
new="$(mktemp -d)/tempconfig"
83101
os::cmd::expect_success "oc config view --raw > ${new}"
102+
old="${KUBECONFIG}"
84103
export KUBECONFIG=${new}
85104
os::cmd::expect_success 'oc login -u test-user -p password'
86105
os::cmd::expect_success 'oc new-project test-template-project'
@@ -91,7 +110,81 @@ os::cmd::expect_success 'oc process template/ruby-helloworld-sample'
91110
os::cmd::expect_success 'oc process templates/ruby-helloworld-sample'
92111
os::cmd::expect_success 'oc process openshift//ruby-helloworld-sample'
93112
os::cmd::expect_success 'oc process openshift/template/ruby-helloworld-sample'
113+
export KUBECONFIG=${old}
94114
echo "processing templates in different namespace: ok"
95115
os::test::junit::declare_suite_end
96116

97-
os::test::junit::declare_suite_end
117+
os::test::junit::declare_suite_start "cmd/templates/process"
118+
# This test validates oc process
119+
# fail to process two templates by name
120+
os::cmd::expect_failure_and_text 'oc process name1 name2' 'template name must be specified only once'
121+
# fail to pass a filename or template by name
122+
os::cmd::expect_failure_and_text 'oc process' 'Must pass a filename or name of stored template'
123+
# can't ask for parameters and try process the template (include tests for deprecated -v/--value)
124+
os::cmd::expect_failure_and_text 'oc process template-name --parameters --value=someval' '\-\-parameters flag does not process the template, can.t be used with \-\-value'
125+
os::cmd::expect_failure_and_text 'oc process template-name --parameters -v someval' '\-\-parameters flag does not process the template, can.t be used with \-\-value'
126+
os::cmd::expect_failure_and_text 'oc process template-name --parameters --param=someval' '\-\-parameters flag does not process the template, can.t be used with \-\-param'
127+
os::cmd::expect_failure_and_text 'oc process template-name --parameters -p someval' '\-\-parameters flag does not process the template, can.t be used with \-\-param'
128+
os::cmd::expect_failure_and_text 'oc process template-name --parameters --labels=someval' '\-\-parameters flag does not process the template, can.t be used with \-\-labels'
129+
os::cmd::expect_failure_and_text 'oc process template-name --parameters -l someval' '\-\-parameters flag does not process the template, can.t be used with \-\-labels'
130+
os::cmd::expect_failure_and_text 'oc process template-name --parameters --output=someval' '\-\-parameters flag does not process the template, can.t be used with \-\-output'
131+
os::cmd::expect_failure_and_text 'oc process template-name --parameters -o someval' '\-\-parameters flag does not process the template, can.t be used with \-\-output'
132+
os::cmd::expect_failure_and_text 'oc process template-name --parameters --output-version=someval' '\-\-parameters flag does not process the template, can.t be used with \-\-output-version'
133+
os::cmd::expect_failure_and_text 'oc process template-name --parameters --raw' '\-\-parameters flag does not process the template, can.t be used with \-\-raw'
134+
os::cmd::expect_failure_and_text 'oc process template-name --parameters --template=someval' '\-\-parameters flag does not process the template, can.t be used with \-\-template'
135+
os::cmd::expect_failure_and_text 'oc process template-name --parameters -t someval' '\-\-parameters flag does not process the template, can.t be used with \-\-template'
136+
# providing a value more than once should fail (include tests for deprecated -v/--value)
137+
os::cmd::expect_failure_and_text 'oc process template-name key=value key=value' 'provided more than once: key'
138+
os::cmd::expect_failure_and_text 'oc process template-name --value=key=value --value=key=value' 'provided more than once: key'
139+
os::cmd::expect_failure_and_text 'oc process template-name --param=key=value --param=key=value' 'provided more than once: key'
140+
os::cmd::expect_failure_and_text 'oc process template-name key=value --value=key=value' 'provided more than once: key'
141+
os::cmd::expect_failure_and_text 'oc process template-name key=value --param=key=value' 'provided more than once: key'
142+
os::cmd::expect_failure_and_text 'oc process template-name key=value other=foo --value=key=value --value=other=baz' 'provided more than once: key, other'
143+
os::cmd::expect_failure_and_text 'oc process template-name key=value other=foo --param=key=value --param=other=baz' 'provided more than once: key, other'
144+
required_params="${OS_ROOT}/test/testdata/template_required_params.yaml"
145+
# providing something other than a template is not OK
146+
os::cmd::expect_failure_and_text "oc process -f '${OS_ROOT}/test/testdata/basic-users-binding.json'" 'not a valid Template but'
147+
# not providing required parameter should fail
148+
os::cmd::expect_failure_and_text "oc process -f '${required_params}'" 'parameter required_param is required and must be specified'
149+
# not providing an optional param is OK
150+
os::cmd::expect_success "oc process -f '${required_params}' --value=required_param=someval"
151+
os::cmd::expect_success "oc process -f '${required_params}' -v required_param=someval"
152+
os::cmd::expect_success "oc process -f '${required_params}' --param=required_param=someval"
153+
os::cmd::expect_success "oc process -f '${required_params}' -p required_param=someval | oc create -f -"
154+
# parameters with multiple equal signs are OK
155+
os::cmd::expect_success "oc process -f '${required_params}' required_param=someval=moreval | oc create -f -"
156+
os::cmd::expect_success "oc process -f '${required_params}' -v required_param=someval=moreval2 | oc create -f -"
157+
os::cmd::expect_success "oc process -f '${required_params}' -p required_param=someval=moreval3 | oc create -f -"
158+
# we should have overwritten the template param
159+
os::cmd::expect_success_and_text 'oc get user someval -o jsonpath={.Name}' 'someval'
160+
os::cmd::expect_success_and_text 'oc get user someval=moreval -o jsonpath={.Name}' 'someval=moreval'
161+
os::cmd::expect_success_and_text 'oc get user someval=moreval2 -o jsonpath={.Name}' 'someval=moreval2'
162+
os::cmd::expect_success_and_text 'oc get user someval=moreval3 -o jsonpath={.Name}' 'someval=moreval3'
163+
# providing a value not in the template should fail
164+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --value=required_param=someval --value=other_param=otherval" 'unknown parameter name "other_param"'
165+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --param=required_param=someval --param=other_param=otherval" 'unknown parameter name "other_param"'
166+
# failure on values fails the entire call
167+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --value=required_param=someval --value=optional_param" 'invalid parameter assignment in'
168+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --param=required_param=someval --param=optional_param" 'invalid parameter assignment in'
169+
# failure on labels fails the entire call
170+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --value=required_param=someval --labels======" 'error parsing labels'
171+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --param=required_param=someval --labels======" 'error parsing labels'
172+
# values are not split on commas, required parameter is not recognized
173+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --value=optional_param=a,required_param=b" 'parameter required_param is required and must be specified'
174+
os::cmd::expect_failure_and_text "oc process -f '${required_params}' --param=optional_param=a,required_param=b" 'parameter required_param is required and must be specified'
175+
# warning is printed iff --value/--param looks like two k-v pairs separated by comma
176+
os::cmd::expect_success_and_text "oc process -f '${required_params}' --value=required_param=a,b=c,d" 'no longer accepts comma-separated list'
177+
os::cmd::expect_success_and_not_text "oc process -f '${required_params}' --value=required_param=a_b_c_d" 'no longer accepts comma-separated list'
178+
os::cmd::expect_success_and_not_text "oc process -f '${required_params}' --value=required_param=a,b,c,d" 'no longer accepts comma-separated list'
179+
os::cmd::expect_success_and_text "oc process -f '${required_params}' --param=required_param=a,b=c,d" 'no longer accepts comma-separated list'
180+
os::cmd::expect_success_and_not_text "oc process -f '${required_params}' --param=required_param=a_b_c_d" 'no longer accepts comma-separated list'
181+
os::cmd::expect_success_and_not_text "oc process -f '${required_params}' --param=required_param=a,b,c,d" 'no longer accepts comma-separated list'
182+
# warning is not printed for template values passed as positional arguments
183+
os::cmd::expect_success_and_not_text "oc process -f '${required_params}' required_param=a,b=c,d" 'no longer accepts comma-separated list'
184+
# set template parameter to contents of file
185+
os::cmd::expect_success_and_text "oc process -f '${required_params}' --value=required_param='`cat ${OS_ROOT}/test/testdata/multiline.txt`'" 'also,with=commas'
186+
os::cmd::expect_success_and_text "oc process -f '${required_params}' --param=required_param='`cat ${OS_ROOT}/test/testdata/multiline.txt`'" 'also,with=commas'
187+
echo "process: ok"
188+
os::test::junit::declare_suite_end
189+
190+
os::test::junit::declare_suite_end

‎test/templates/testdata/guestbook.env

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
ADMIN_USERNAME=root
2+
ADMIN_PASSWORD="adminpass"
3+
REDIS_PASSWORD='redispass'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
required_param="first\nsecond"
2+
optional_param=foo

‎test/testdata/test-cmd-newapp-env.env

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SOME_VAR=envvarfromfile
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
MYSQL_USER='mysql'
2+
MYSQL_PASSWORD="thisisapassword"

0 commit comments

Comments
 (0)
Please sign in to comment.