mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: Update CLI to handle managed variables (#6220)
* WIP * hcl * useManagedVariables * fix * Fix * Fix * fix * go:build * Fix * fix: bool flag * Insert template variables * API * fix * Expose via API * More wiring * CLI for testing purposes * WIP * Delete FIXME * planVars * WIP * WIP * UserVariableValues * no dry run * Dry run * Done FIXME * Fix * Fix: CLI * Fix: migration * API tests * Test info * Tests * More tests * fix: lint * Fix: authz * Address PR comments * Fix * fix * fix * CLI: create * unit tests: create templates with variables * Use last variables * Fix * Fix * Fix * Push tests * fix: variable is required if Default is nil * WIP * Redact sensitive values * Fixes * Fixes * Fix: arg description * Fix * Variable param * Fix: gen * Fix * Fix: goldens
This commit is contained in:
+17
-4
@@ -25,6 +25,8 @@ func templateCreate() *cobra.Command {
|
||||
provisioner string
|
||||
provisionerTags []string
|
||||
parameterFile string
|
||||
variablesFile string
|
||||
variables []string
|
||||
defaultTTL time.Duration
|
||||
|
||||
uploadFlags templateUploadFlags
|
||||
@@ -76,6 +78,8 @@ func templateCreate() *cobra.Command {
|
||||
FileID: resp.ID,
|
||||
ParameterFile: parameterFile,
|
||||
ProvisionerTags: tags,
|
||||
VariablesFile: variablesFile,
|
||||
Variables: variables,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -113,6 +117,8 @@ func templateCreate() *cobra.Command {
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(¶meterFile, "parameter-file", "", "", "Specify a file path with parameter values.")
|
||||
cmd.Flags().StringVarP(&variablesFile, "variables-file", "", "", "Specify a file path with values for Terraform-managed variables.")
|
||||
cmd.Flags().StringArrayVarP(&variables, "variable", "", []string{}, "Specify a set of values for Terraform-managed variables.")
|
||||
cmd.Flags().StringArrayVarP(&provisionerTags, "provisioner-tag", "", []string{}, "Specify a set of tags to target provisioner daemons.")
|
||||
cmd.Flags().DurationVarP(&defaultTTL, "default-ttl", "", 24*time.Hour, "Specify a default TTL for workspaces created from this template.")
|
||||
uploadFlags.register(cmd.Flags())
|
||||
@@ -133,7 +139,10 @@ type createValidTemplateVersionArgs struct {
|
||||
Provisioner database.ProvisionerType
|
||||
FileID uuid.UUID
|
||||
ParameterFile string
|
||||
ValuesFile string
|
||||
|
||||
VariablesFile string
|
||||
Variables []string
|
||||
|
||||
// Template is only required if updating a template's active version.
|
||||
Template *codersdk.Template
|
||||
// ReuseParameters will attempt to reuse params from the Template field
|
||||
@@ -146,13 +155,17 @@ type createValidTemplateVersionArgs struct {
|
||||
func createValidTemplateVersion(cmd *cobra.Command, args createValidTemplateVersionArgs, parameters ...codersdk.CreateParameterRequest) (*codersdk.TemplateVersion, []codersdk.CreateParameterRequest, error) {
|
||||
client := args.Client
|
||||
|
||||
// FIXME(mtojek): I will iterate on CLI experience in the follow-up.
|
||||
// see: https://github.com/coder/coder/issues/5980
|
||||
variableValues, err := loadVariableValues(args.ValuesFile)
|
||||
variableValues, err := loadVariableValuesFromFile(args.VariablesFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
variableValuesFromKeyValues, err := loadVariableValuesFromOptions(args.Variables)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
variableValues = append(variableValues, variableValuesFromKeyValues...)
|
||||
|
||||
req := codersdk.CreateTemplateVersionRequest{
|
||||
Name: args.Name,
|
||||
StorageMethod: codersdk.ProvisionerStorageMethodFile,
|
||||
|
||||
@@ -299,6 +299,161 @@ func TestTemplateCreate(t *testing.T) {
|
||||
|
||||
require.EqualError(t, <-execDone, "Template name must be less than 32 characters")
|
||||
})
|
||||
|
||||
t.Run("WithVariablesFileWithoutRequiredValue", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateVariables := []*proto.TemplateVariable{
|
||||
{
|
||||
Name: "first_variable",
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
{
|
||||
Name: "second_variable",
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
DefaultValue: "abc",
|
||||
Required: false,
|
||||
Sensitive: true,
|
||||
},
|
||||
}
|
||||
source := clitest.CreateTemplateVersionSource(t,
|
||||
createEchoResponsesWithTemplateVariables(templateVariables))
|
||||
tempDir := t.TempDir()
|
||||
removeTmpDirUntilSuccessAfterTest(t, tempDir)
|
||||
variablesFile, _ := os.CreateTemp(tempDir, "variables*.yaml")
|
||||
_, _ = variablesFile.WriteString(`second_variable: foobar`)
|
||||
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--variables-file", variablesFile.Name())
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
execDone := make(chan error)
|
||||
go func() {
|
||||
execDone <- cmd.Execute()
|
||||
}()
|
||||
|
||||
matches := []struct {
|
||||
match string
|
||||
write string
|
||||
}{
|
||||
{match: "Upload", write: "yes"},
|
||||
}
|
||||
for _, m := range matches {
|
||||
pty.ExpectMatch(m.match)
|
||||
if len(m.write) > 0 {
|
||||
pty.WriteLine(m.write)
|
||||
}
|
||||
}
|
||||
|
||||
require.Error(t, <-execDone)
|
||||
})
|
||||
|
||||
t.Run("WithVariablesFileWithTheRequiredValue", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateVariables := []*proto.TemplateVariable{
|
||||
{
|
||||
Name: "first_variable",
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
{
|
||||
Name: "second_variable",
|
||||
Description: "This is the second variable",
|
||||
Type: "string",
|
||||
DefaultValue: "abc",
|
||||
Required: false,
|
||||
Sensitive: true,
|
||||
},
|
||||
}
|
||||
source := clitest.CreateTemplateVersionSource(t,
|
||||
createEchoResponsesWithTemplateVariables(templateVariables))
|
||||
tempDir := t.TempDir()
|
||||
removeTmpDirUntilSuccessAfterTest(t, tempDir)
|
||||
variablesFile, _ := os.CreateTemp(tempDir, "variables*.yaml")
|
||||
_, _ = variablesFile.WriteString(`first_variable: foobar`)
|
||||
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--variables-file", variablesFile.Name())
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
execDone := make(chan error)
|
||||
go func() {
|
||||
execDone <- cmd.Execute()
|
||||
}()
|
||||
|
||||
matches := []struct {
|
||||
match string
|
||||
write string
|
||||
}{
|
||||
{match: "Upload", write: "yes"},
|
||||
{match: "Confirm create?", write: "yes"},
|
||||
}
|
||||
for _, m := range matches {
|
||||
pty.ExpectMatch(m.match)
|
||||
if len(m.write) > 0 {
|
||||
pty.WriteLine(m.write)
|
||||
}
|
||||
}
|
||||
|
||||
require.NoError(t, <-execDone)
|
||||
})
|
||||
t.Run("WithVariableOption", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateVariables := []*proto.TemplateVariable{
|
||||
{
|
||||
Name: "first_variable",
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
Sensitive: true,
|
||||
},
|
||||
}
|
||||
source := clitest.CreateTemplateVersionSource(t,
|
||||
createEchoResponsesWithTemplateVariables(templateVariables))
|
||||
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--variable", "first_variable=foobar")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
execDone := make(chan error)
|
||||
go func() {
|
||||
execDone <- cmd.Execute()
|
||||
}()
|
||||
|
||||
matches := []struct {
|
||||
match string
|
||||
write string
|
||||
}{
|
||||
{match: "Upload", write: "yes"},
|
||||
{match: "Confirm create?", write: "yes"},
|
||||
}
|
||||
for _, m := range matches {
|
||||
pty.ExpectMatch(m.match)
|
||||
pty.WriteLine(m.write)
|
||||
}
|
||||
|
||||
require.NoError(t, <-execDone)
|
||||
})
|
||||
}
|
||||
|
||||
func createTestParseResponse() []*proto.Parse_Response {
|
||||
|
||||
+6
-3
@@ -93,7 +93,8 @@ func templatePush() *cobra.Command {
|
||||
versionName string
|
||||
provisioner string
|
||||
parameterFile string
|
||||
valuesFile string
|
||||
variablesFile string
|
||||
variables []string
|
||||
alwaysPrompt bool
|
||||
provisionerTags []string
|
||||
uploadFlags templateUploadFlags
|
||||
@@ -140,7 +141,8 @@ func templatePush() *cobra.Command {
|
||||
Provisioner: database.ProvisionerType(provisioner),
|
||||
FileID: resp.ID,
|
||||
ParameterFile: parameterFile,
|
||||
ValuesFile: valuesFile,
|
||||
VariablesFile: variablesFile,
|
||||
Variables: variables,
|
||||
Template: &template,
|
||||
ReuseParameters: !alwaysPrompt,
|
||||
ProvisionerTags: tags,
|
||||
@@ -167,7 +169,8 @@ func templatePush() *cobra.Command {
|
||||
|
||||
cmd.Flags().StringVarP(&provisioner, "test.provisioner", "", "terraform", "Customize the provisioner backend")
|
||||
cmd.Flags().StringVarP(¶meterFile, "parameter-file", "", "", "Specify a file path with parameter values.")
|
||||
cmd.Flags().StringVarP(&valuesFile, "values-file", "", "", "Specify a file path with values for managed variables.")
|
||||
cmd.Flags().StringVarP(&variablesFile, "variables-file", "", "", "Specify a file path with values for Terraform-managed variables.")
|
||||
cmd.Flags().StringArrayVarP(&variables, "variable", "", []string{}, "Specify a set of values for Terraform-managed variables.")
|
||||
cmd.Flags().StringVarP(&versionName, "name", "", "", "Specify a name for the new template version. It will be automatically generated if not provided.")
|
||||
cmd.Flags().StringArrayVarP(&provisionerTags, "provisioner-tag", "", []string{}, "Specify a set of tags to target provisioner daemons.")
|
||||
cmd.Flags().BoolVar(&alwaysPrompt, "always-prompt", false, "Always prompt all parameters. Does not pull parameter values from active template version")
|
||||
|
||||
@@ -3,6 +3,7 @@ package cli_test
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/codersdk"
|
||||
"github.com/coder/coder/provisioner/echo"
|
||||
"github.com/coder/coder/provisionersdk/proto"
|
||||
"github.com/coder/coder/pty/ptytest"
|
||||
)
|
||||
|
||||
@@ -250,6 +252,250 @@ func TestTemplatePush(t *testing.T) {
|
||||
assert.Len(t, templateVersions, 2)
|
||||
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
||||
})
|
||||
|
||||
t.Run("Variables", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
initialTemplateVariables := []*proto.TemplateVariable{
|
||||
{
|
||||
Name: "first_variable",
|
||||
Description: "This is the first variable",
|
||||
Type: "string",
|
||||
DefaultValue: "abc",
|
||||
Required: false,
|
||||
Sensitive: true,
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("VariableIsRequired", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
||||
_ = coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
|
||||
|
||||
// Test the cli command.
|
||||
modifiedTemplateVariables := append(initialTemplateVariables,
|
||||
&proto.TemplateVariable{
|
||||
Name: "second_variable",
|
||||
Description: "This is the second variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
},
|
||||
)
|
||||
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
||||
tempDir := t.TempDir()
|
||||
removeTmpDirUntilSuccessAfterTest(t, tempDir)
|
||||
variablesFile, _ := os.CreateTemp(tempDir, "variables*.yaml")
|
||||
_, _ = variablesFile.WriteString(`second_variable: foobar`)
|
||||
cmd, root := clitest.New(t, "templates", "push", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--name", "example", "--variables-file", variablesFile.Name())
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
execDone := make(chan error)
|
||||
go func() {
|
||||
execDone <- cmd.Execute()
|
||||
}()
|
||||
|
||||
matches := []struct {
|
||||
match string
|
||||
write string
|
||||
}{
|
||||
{match: "Upload", write: "yes"},
|
||||
}
|
||||
for _, m := range matches {
|
||||
pty.ExpectMatch(m.match)
|
||||
pty.WriteLine(m.write)
|
||||
}
|
||||
|
||||
require.NoError(t, <-execDone)
|
||||
|
||||
// Assert that the template version changed.
|
||||
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
||||
TemplateID: template.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, templateVersions, 2)
|
||||
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
||||
require.Equal(t, "example", templateVersions[1].Name)
|
||||
|
||||
templateVariables, err := client.TemplateVersionVariables(context.Background(), templateVersions[1].ID)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, templateVariables, 2)
|
||||
require.Equal(t, "second_variable", templateVariables[1].Name)
|
||||
require.Equal(t, "foobar", templateVariables[1].Value)
|
||||
})
|
||||
|
||||
t.Run("VariableIsRequiredButNotProvided", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
||||
_ = coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
|
||||
|
||||
// Test the cli command.
|
||||
modifiedTemplateVariables := append(initialTemplateVariables,
|
||||
&proto.TemplateVariable{
|
||||
Name: "second_variable",
|
||||
Description: "This is the second variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
},
|
||||
)
|
||||
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
||||
cmd, root := clitest.New(t, "templates", "push", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--name", "example")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
execDone := make(chan error)
|
||||
go func() {
|
||||
execDone <- cmd.Execute()
|
||||
}()
|
||||
|
||||
matches := []struct {
|
||||
match string
|
||||
write string
|
||||
}{
|
||||
{match: "Upload", write: "yes"},
|
||||
}
|
||||
for _, m := range matches {
|
||||
pty.ExpectMatch(m.match)
|
||||
pty.WriteLine(m.write)
|
||||
}
|
||||
|
||||
wantErr := <-execDone
|
||||
require.Error(t, wantErr)
|
||||
require.Contains(t, wantErr.Error(), "required template variables need values")
|
||||
})
|
||||
|
||||
t.Run("VariableIsOptionalButNotProvided", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
||||
_ = coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
|
||||
|
||||
// Test the cli command.
|
||||
modifiedTemplateVariables := append(initialTemplateVariables,
|
||||
&proto.TemplateVariable{
|
||||
Name: "second_variable",
|
||||
Description: "This is the second variable",
|
||||
Type: "string",
|
||||
DefaultValue: "abc",
|
||||
Required: true,
|
||||
},
|
||||
)
|
||||
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
||||
cmd, root := clitest.New(t, "templates", "push", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--name", "example")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
execDone := make(chan error)
|
||||
go func() {
|
||||
execDone <- cmd.Execute()
|
||||
}()
|
||||
|
||||
matches := []struct {
|
||||
match string
|
||||
write string
|
||||
}{
|
||||
{match: "Upload", write: "yes"},
|
||||
}
|
||||
for _, m := range matches {
|
||||
pty.ExpectMatch(m.match)
|
||||
pty.WriteLine(m.write)
|
||||
}
|
||||
|
||||
require.NoError(t, <-execDone)
|
||||
|
||||
// Assert that the template version changed.
|
||||
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
||||
TemplateID: template.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, templateVersions, 2)
|
||||
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
||||
require.Equal(t, "example", templateVersions[1].Name)
|
||||
|
||||
templateVariables, err := client.TemplateVersionVariables(context.Background(), templateVersions[1].ID)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, templateVariables, 2)
|
||||
require.Equal(t, "second_variable", templateVariables[1].Name)
|
||||
require.Equal(t, "abc", templateVariables[1].Value)
|
||||
require.Equal(t, templateVariables[1].DefaultValue, templateVariables[1].Value)
|
||||
})
|
||||
|
||||
t.Run("WithVariableOption", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
||||
_ = coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
|
||||
|
||||
// Test the cli command.
|
||||
modifiedTemplateVariables := append(initialTemplateVariables,
|
||||
&proto.TemplateVariable{
|
||||
Name: "second_variable",
|
||||
Description: "This is the second variable",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
},
|
||||
)
|
||||
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
||||
cmd, root := clitest.New(t, "templates", "push", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--name", "example", "--variable", "second_variable=foobar")
|
||||
clitest.SetupConfig(t, client, root)
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
||||
cmd.SetOut(pty.Output())
|
||||
|
||||
execDone := make(chan error)
|
||||
go func() {
|
||||
execDone <- cmd.Execute()
|
||||
}()
|
||||
|
||||
matches := []struct {
|
||||
match string
|
||||
write string
|
||||
}{
|
||||
{match: "Upload", write: "yes"},
|
||||
}
|
||||
for _, m := range matches {
|
||||
pty.ExpectMatch(m.match)
|
||||
pty.WriteLine(m.write)
|
||||
}
|
||||
|
||||
require.NoError(t, <-execDone)
|
||||
|
||||
// Assert that the template version changed.
|
||||
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
||||
TemplateID: template.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, templateVersions, 2)
|
||||
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
||||
require.Equal(t, "example", templateVersions[1].Name)
|
||||
|
||||
templateVariables, err := client.TemplateVersionVariables(context.Background(), templateVersions[1].ID)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, templateVariables, 2)
|
||||
require.Equal(t, "second_variable", templateVariables[1].Name)
|
||||
require.Equal(t, "foobar", templateVariables[1].Value)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func latestTemplateVersion(t *testing.T, client *codersdk.Client, templateID uuid.UUID) (codersdk.TemplateVersion, []codersdk.Parameter) {
|
||||
@@ -265,3 +511,19 @@ func latestTemplateVersion(t *testing.T, client *codersdk.Client, templateID uui
|
||||
|
||||
return tv, params
|
||||
}
|
||||
|
||||
func createEchoResponsesWithTemplateVariables(templateVariables []*proto.TemplateVariable) *echo.Responses {
|
||||
return &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{
|
||||
{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
TemplateVariables: templateVariables,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ProvisionPlan: echo.ProvisionComplete,
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package cli
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
"gopkg.in/yaml.v3"
|
||||
@@ -9,7 +10,7 @@ import (
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
func loadVariableValues(variablesFile string) ([]codersdk.VariableValue, error) {
|
||||
func loadVariableValuesFromFile(variablesFile string) ([]codersdk.VariableValue, error) {
|
||||
var values []codersdk.VariableValue
|
||||
if variablesFile == "" {
|
||||
return values, nil
|
||||
@@ -48,3 +49,19 @@ func createVariablesMapFromFile(variablesFile string) (map[string]string, error)
|
||||
}
|
||||
return variablesMap, nil
|
||||
}
|
||||
|
||||
func loadVariableValuesFromOptions(variables []string) ([]codersdk.VariableValue, error) {
|
||||
var values []codersdk.VariableValue
|
||||
for _, keyValue := range variables {
|
||||
split := strings.SplitN(keyValue, "=", 2)
|
||||
if len(split) < 2 {
|
||||
return nil, xerrors.Errorf("format key=value expected, but got %s", keyValue)
|
||||
}
|
||||
|
||||
values = append(values, codersdk.VariableValue{
|
||||
Name: split[0],
|
||||
Value: split[1],
|
||||
})
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ Flags:
|
||||
-h, --help help for create
|
||||
--parameter-file string Specify a file path with parameter values.
|
||||
--provisioner-tag stringArray Specify a set of tags to target provisioner daemons.
|
||||
--variable stringArray Specify a set of values for Terraform-managed variables.
|
||||
--variables-file string Specify a file path with values for Terraform-managed
|
||||
variables.
|
||||
-y, --yes Bypass prompts
|
||||
|
||||
Global Flags:
|
||||
|
||||
+3
-1
@@ -13,7 +13,9 @@ Flags:
|
||||
automatically generated if not provided.
|
||||
--parameter-file string Specify a file path with parameter values.
|
||||
--provisioner-tag stringArray Specify a set of tags to target provisioner daemons.
|
||||
--values-file string Specify a file path with values for managed variables.
|
||||
--variable stringArray Specify a set of values for Terraform-managed variables.
|
||||
--variables-file string Specify a file path with values for Terraform-managed
|
||||
variables.
|
||||
-y, --yes Bypass prompts
|
||||
|
||||
Global Flags:
|
||||
|
||||
Reference in New Issue
Block a user