refactor(cli): load template variables (#11234)

This commit is contained in:
Marcin Tojek
2023-12-15 14:55:24 +01:00
committed by GitHub
parent fa91992976
commit 58c2ce17da
3 changed files with 98 additions and 69 deletions

View File

@ -5,8 +5,6 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"os"
"path/filepath"
"strings" "strings"
"time" "time"
"unicode/utf8" "unicode/utf8"
@ -27,7 +25,7 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
provisioner string provisioner string
provisionerTags []string provisionerTags []string
variablesFile string variablesFile string
variables []string commandLineVariables []string
disableEveryone bool disableEveryone bool
requireActiveVersion bool requireActiveVersion bool
@ -129,15 +127,21 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
return err return err
} }
userVariableValues, err := ParseUserVariableValues(
variablesFile,
commandLineVariables)
if err != nil {
return err
}
job, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{ job, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{
Message: message, Message: message,
Client: client, Client: client,
Organization: organization, Organization: organization,
Provisioner: codersdk.ProvisionerType(provisioner), Provisioner: codersdk.ProvisionerType(provisioner),
FileID: resp.ID, FileID: resp.ID,
ProvisionerTags: tags, ProvisionerTags: tags,
VariablesFile: variablesFile, UserVariableValues: userVariableValues,
Variables: variables,
}) })
if err != nil { if err != nil {
return err return err
@ -197,12 +201,12 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
{ {
Flag: "variable", Flag: "variable",
Description: "Specify a set of values for Terraform-managed variables.", Description: "Specify a set of values for Terraform-managed variables.",
Value: clibase.StringArrayOf(&variables), Value: clibase.StringArrayOf(&commandLineVariables),
}, },
{ {
Flag: "var", Flag: "var",
Description: "Alias of --variable.", Description: "Alias of --variable.",
Value: clibase.StringArrayOf(&variables), Value: clibase.StringArrayOf(&commandLineVariables),
}, },
{ {
Flag: "provisioner-tag", Flag: "provisioner-tag",
@ -267,32 +271,19 @@ type createValidTemplateVersionArgs struct {
Provisioner codersdk.ProvisionerType Provisioner codersdk.ProvisionerType
FileID uuid.UUID FileID uuid.UUID
VariablesFile string
Variables []string
// Template is only required if updating a template's active version. // Template is only required if updating a template's active version.
Template *codersdk.Template Template *codersdk.Template
// ReuseParameters will attempt to reuse params from the Template field // ReuseParameters will attempt to reuse params from the Template field
// before prompting the user. Set to false to always prompt for param // before prompting the user. Set to false to always prompt for param
// values. // values.
ReuseParameters bool ReuseParameters bool
ProvisionerTags map[string]string ProvisionerTags map[string]string
UserVariableValues []codersdk.VariableValue
} }
func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplateVersionArgs) (*codersdk.TemplateVersion, error) { func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplateVersionArgs) (*codersdk.TemplateVersion, error) {
client := args.Client client := args.Client
variableValues, err := loadVariableValuesFromFile(args.VariablesFile)
if err != nil {
return nil, err
}
variableValuesFromKeyValues, err := loadVariableValuesFromOptions(args.Variables)
if err != nil {
return nil, err
}
variableValues = append(variableValues, variableValuesFromKeyValues...)
req := codersdk.CreateTemplateVersionRequest{ req := codersdk.CreateTemplateVersionRequest{
Name: args.Name, Name: args.Name,
Message: args.Message, Message: args.Message,
@ -300,7 +291,7 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
FileID: args.FileID, FileID: args.FileID,
Provisioner: args.Provisioner, Provisioner: args.Provisioner,
ProvisionerTags: args.ProvisionerTags, ProvisionerTags: args.ProvisionerTags,
UserVariableValues: variableValues, UserVariableValues: args.UserVariableValues,
} }
if args.Template != nil { if args.Template != nil {
req.TemplateID = args.Template.ID req.TemplateID = args.Template.ID
@ -364,23 +355,6 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
return &version, nil return &version, nil
} }
// prettyDirectoryPath returns a prettified path when inside the users
// home directory. Falls back to dir if the users home directory cannot
// discerned. This function calls filepath.Clean on the result.
func prettyDirectoryPath(dir string) string {
dir = filepath.Clean(dir)
homeDir, err := os.UserHomeDir()
if err != nil {
return dir
}
prettyDir := dir
if strings.HasPrefix(prettyDir, homeDir) {
prettyDir = strings.TrimPrefix(prettyDir, homeDir)
prettyDir = "~" + prettyDir
}
return prettyDir
}
func ParseProvisionerTags(rawTags []string) (map[string]string, error) { func ParseProvisionerTags(rawTags []string) (map[string]string, error) {
tags := map[string]string{} tags := map[string]string{}
for _, rawTag := range rawTags { for _, rawTag := range rawTags {

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"fmt" "fmt"
"io" "io"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
"time" "time"
@ -155,16 +156,16 @@ func (pf *templateUploadFlags) templateName(args []string) (string, error) {
func (r *RootCmd) templatePush() *clibase.Cmd { func (r *RootCmd) templatePush() *clibase.Cmd {
var ( var (
versionName string versionName string
provisioner string provisioner string
workdir string workdir string
variablesFile string variablesFile string
variables []string commandLineVariables []string
alwaysPrompt bool alwaysPrompt bool
provisionerTags []string provisionerTags []string
uploadFlags templateUploadFlags uploadFlags templateUploadFlags
activate bool activate bool
create bool create bool
) )
client := new(codersdk.Client) client := new(codersdk.Client)
cmd := &clibase.Cmd{ cmd := &clibase.Cmd{
@ -213,15 +214,21 @@ func (r *RootCmd) templatePush() *clibase.Cmd {
return err return err
} }
userVariableValues, err := ParseUserVariableValues(
variablesFile,
commandLineVariables)
if err != nil {
return err
}
args := createValidTemplateVersionArgs{ args := createValidTemplateVersionArgs{
Message: message, Message: message,
Client: client, Client: client,
Organization: organization, Organization: organization,
Provisioner: codersdk.ProvisionerType(provisioner), Provisioner: codersdk.ProvisionerType(provisioner),
FileID: resp.ID, FileID: resp.ID,
ProvisionerTags: tags, ProvisionerTags: tags,
VariablesFile: variablesFile, UserVariableValues: userVariableValues,
Variables: variables,
} }
if !createTemplate { if !createTemplate {
@ -291,12 +298,12 @@ func (r *RootCmd) templatePush() *clibase.Cmd {
{ {
Flag: "variable", Flag: "variable",
Description: "Specify a set of values for Terraform-managed variables.", Description: "Specify a set of values for Terraform-managed variables.",
Value: clibase.StringArrayOf(&variables), Value: clibase.StringArrayOf(&commandLineVariables),
}, },
{ {
Flag: "var", Flag: "var",
Description: "Alias of --variable.", Description: "Alias of --variable.",
Value: clibase.StringArrayOf(&variables), Value: clibase.StringArrayOf(&commandLineVariables),
}, },
{ {
Flag: "provisioner-tag", Flag: "provisioner-tag",
@ -330,3 +337,20 @@ func (r *RootCmd) templatePush() *clibase.Cmd {
cmd.Options = append(cmd.Options, uploadFlags.options()...) cmd.Options = append(cmd.Options, uploadFlags.options()...)
return cmd return cmd
} }
// prettyDirectoryPath returns a prettified path when inside the users
// home directory. Falls back to dir if the users home directory cannot
// discerned. This function calls filepath.Clean on the result.
func prettyDirectoryPath(dir string) string {
dir = filepath.Clean(dir)
homeDir, err := os.UserHomeDir()
if err != nil {
return dir
}
prettyDir := dir
if strings.HasPrefix(prettyDir, homeDir) {
prettyDir = strings.TrimPrefix(prettyDir, homeDir)
prettyDir = "~" + prettyDir
}
return prettyDir
}

View File

@ -10,7 +10,21 @@ import (
"github.com/coder/coder/v2/codersdk" "github.com/coder/coder/v2/codersdk"
) )
func loadVariableValuesFromFile(variablesFile string) ([]codersdk.VariableValue, error) { func ParseUserVariableValues(variablesFile string, commandLineVariables []string) ([]codersdk.VariableValue, error) {
fromFile, err := parseVariableValuesFromFile(variablesFile)
if err != nil {
return nil, err
}
fromCommandLine, err := parseVariableValuesFromCommandLine(commandLineVariables)
if err != nil {
return nil, err
}
return combineVariableValues(fromFile, fromCommandLine), nil
}
func parseVariableValuesFromFile(variablesFile string) ([]codersdk.VariableValue, error) {
var values []codersdk.VariableValue var values []codersdk.VariableValue
if variablesFile == "" { if variablesFile == "" {
return values, nil return values, nil
@ -50,7 +64,7 @@ func createVariablesMapFromFile(variablesFile string) (map[string]string, error)
return variablesMap, nil return variablesMap, nil
} }
func loadVariableValuesFromOptions(variables []string) ([]codersdk.VariableValue, error) { func parseVariableValuesFromCommandLine(variables []string) ([]codersdk.VariableValue, error) {
var values []codersdk.VariableValue var values []codersdk.VariableValue
for _, keyValue := range variables { for _, keyValue := range variables {
split := strings.SplitN(keyValue, "=", 2) split := strings.SplitN(keyValue, "=", 2)
@ -65,3 +79,20 @@ func loadVariableValuesFromOptions(variables []string) ([]codersdk.VariableValue
} }
return values, nil return values, nil
} }
func combineVariableValues(valuesSets ...[]codersdk.VariableValue) []codersdk.VariableValue {
combinedValues := make(map[string]string)
for _, values := range valuesSets {
for _, v := range values {
combinedValues[v.Name] = v.Value
}
}
var result []codersdk.VariableValue
for name, value := range combinedValues {
result = append(result, codersdk.VariableValue{Name: name, Value: value})
}
return result
}