feat!: drop support for legacy parameters (#7663)

This commit is contained in:
Marcin Tojek 2023-06-02 11:16:46 +02:00 committed by GitHub
parent 2b63492649
commit a7366a8b76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
106 changed files with 1153 additions and 8553 deletions

View File

@ -6,61 +6,9 @@ import (
"strings" "strings"
"github.com/coder/coder/cli/clibase" "github.com/coder/coder/cli/clibase"
"github.com/coder/coder/coderd/parameter"
"github.com/coder/coder/codersdk" "github.com/coder/coder/codersdk"
) )
func ParameterSchema(inv *clibase.Invocation, parameterSchema codersdk.ParameterSchema) (string, error) {
_, _ = fmt.Fprintln(inv.Stdout, Styles.Bold.Render("var."+parameterSchema.Name))
if parameterSchema.Description != "" {
_, _ = fmt.Fprintln(inv.Stdout, " "+strings.TrimSpace(strings.Join(strings.Split(parameterSchema.Description, "\n"), "\n "))+"\n")
}
var err error
var options []string
if parameterSchema.ValidationCondition != "" {
options, _, err = parameter.Contains(parameterSchema.ValidationCondition)
if err != nil {
return "", err
}
}
var value string
if len(options) > 0 {
// Move the cursor up a single line for nicer display!
_, _ = fmt.Fprint(inv.Stdout, "\033[1A")
value, err = Select(inv, SelectOptions{
Options: options,
Default: parameterSchema.DefaultSourceValue,
HideSearch: true,
})
if err == nil {
_, _ = fmt.Fprintln(inv.Stdout)
_, _ = fmt.Fprintln(inv.Stdout, " "+Styles.Prompt.String()+Styles.Field.Render(value))
}
} else {
text := "Enter a value"
if parameterSchema.DefaultSourceValue != "" {
text += fmt.Sprintf(" (default: %q)", parameterSchema.DefaultSourceValue)
}
text += ":"
value, err = Prompt(inv, PromptOptions{
Text: Styles.Bold.Render(text),
})
value = strings.TrimSpace(value)
}
if err != nil {
return "", err
}
// If they didn't specify anything, use the default value if set.
if len(options) == 0 && value == "" {
value = parameterSchema.DefaultSourceValue
}
return value, nil
}
func RichParameter(inv *clibase.Invocation, templateVersionParameter codersdk.TemplateVersionParameter) (string, error) { func RichParameter(inv *clibase.Invocation, templateVersionParameter codersdk.TemplateVersionParameter) (string, error) {
label := templateVersionParameter.Name label := templateVersionParameter.Name
if templateVersionParameter.DisplayName != "" { if templateVersionParameter.DisplayName != "" {

View File

@ -18,7 +18,6 @@ import (
func (r *RootCmd) create() *clibase.Cmd { func (r *RootCmd) create() *clibase.Cmd {
var ( var (
parameterFile string
richParameterFile string richParameterFile string
templateName string templateName string
startAt string startAt string
@ -122,8 +121,6 @@ func (r *RootCmd) create() *clibase.Cmd {
buildParams, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{ buildParams, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{
Template: template, Template: template,
ExistingParams: []codersdk.Parameter{},
ParameterFile: parameterFile,
RichParameterFile: richParameterFile, RichParameterFile: richParameterFile,
NewWorkspaceName: workspaceName, NewWorkspaceName: workspaceName,
}) })
@ -151,7 +148,6 @@ func (r *RootCmd) create() *clibase.Cmd {
Name: workspaceName, Name: workspaceName,
AutostartSchedule: schedSpec, AutostartSchedule: schedSpec,
TTLMillis: ttlMillis, TTLMillis: ttlMillis,
ParameterValues: buildParams.parameters,
RichParameterValues: buildParams.richParameters, RichParameterValues: buildParams.richParameters,
}) })
if err != nil { if err != nil {
@ -175,12 +171,6 @@ func (r *RootCmd) create() *clibase.Cmd {
Description: "Specify a template name.", Description: "Specify a template name.",
Value: clibase.StringOf(&templateName), Value: clibase.StringOf(&templateName),
}, },
clibase.Option{
Flag: "parameter-file",
Env: "CODER_PARAMETER_FILE",
Description: "Specify a file path with parameter values.",
Value: clibase.StringOf(&parameterFile),
},
clibase.Option{ clibase.Option{
Flag: "rich-parameter-file", Flag: "rich-parameter-file",
Env: "CODER_RICH_PARAMETER_FILE", Env: "CODER_RICH_PARAMETER_FILE",
@ -207,8 +197,6 @@ func (r *RootCmd) create() *clibase.Cmd {
type prepWorkspaceBuildArgs struct { type prepWorkspaceBuildArgs struct {
Template codersdk.Template Template codersdk.Template
ExistingParams []codersdk.Parameter
ParameterFile string
ExistingRichParams []codersdk.WorkspaceBuildParameter ExistingRichParams []codersdk.WorkspaceBuildParameter
RichParameterFile string RichParameterFile string
NewWorkspaceName string NewWorkspaceName string
@ -218,8 +206,6 @@ type prepWorkspaceBuildArgs struct {
} }
type buildParameters struct { type buildParameters struct {
// Parameters contains legacy parameters stored in /parameters.
parameters []codersdk.CreateParameterRequest
// Rich parameters stores values for build parameters annotated with description, icon, type, etc. // Rich parameters stores values for build parameters annotated with description, icon, type, etc.
richParameters []codersdk.WorkspaceBuildParameter richParameters []codersdk.WorkspaceBuildParameter
} }
@ -229,90 +215,19 @@ type buildParameters struct {
func prepWorkspaceBuild(inv *clibase.Invocation, client *codersdk.Client, args prepWorkspaceBuildArgs) (*buildParameters, error) { func prepWorkspaceBuild(inv *clibase.Invocation, client *codersdk.Client, args prepWorkspaceBuildArgs) (*buildParameters, error) {
ctx := inv.Context() ctx := inv.Context()
var useRichParameters bool
if len(args.ExistingRichParams) > 0 && len(args.RichParameterFile) > 0 {
useRichParameters = true
}
var useLegacyParameters bool
if len(args.ExistingParams) > 0 || len(args.ParameterFile) > 0 {
useLegacyParameters = true
}
if useRichParameters && useLegacyParameters {
return nil, xerrors.Errorf("Rich parameters can't be used together with legacy parameters.")
}
templateVersion, err := client.TemplateVersion(ctx, args.Template.ActiveVersionID) templateVersion, err := client.TemplateVersion(ctx, args.Template.ActiveVersionID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Legacy parameters
parameterSchemas, err := client.TemplateVersionSchema(ctx, templateVersion.ID)
if err != nil {
return nil, err
}
// parameterMapFromFile can be nil if parameter file is not specified
var parameterMapFromFile map[string]string
useParamFile := false
if args.ParameterFile != "" {
useParamFile = true
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("Attempting to read the variables from the parameter file.")+"\r\n")
parameterMapFromFile, err = createParameterMapFromFile(args.ParameterFile)
if err != nil {
return nil, err
}
}
disclaimerPrinted := false
legacyParameters := make([]codersdk.CreateParameterRequest, 0)
PromptParamLoop:
for _, parameterSchema := range parameterSchemas {
if !parameterSchema.AllowOverrideSource {
continue
}
if !disclaimerPrinted {
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("This template has customizable parameters. Values can be changed after create, but may have unintended side effects (like data loss).")+"\r\n")
disclaimerPrinted = true
}
// Param file is all or nothing
if !useParamFile {
for _, e := range args.ExistingParams {
if e.Name == parameterSchema.Name {
// If the param already exists, we do not need to prompt it again.
// The workspace scope will reuse params for each build.
continue PromptParamLoop
}
}
}
parameterValue, err := getParameterValueFromMapOrInput(inv, parameterMapFromFile, parameterSchema)
if err != nil {
return nil, err
}
legacyParameters = append(legacyParameters, codersdk.CreateParameterRequest{
Name: parameterSchema.Name,
SourceValue: parameterValue,
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: parameterSchema.DefaultDestinationScheme,
})
}
if disclaimerPrinted {
_, _ = fmt.Fprintln(inv.Stdout)
}
// Rich parameters // Rich parameters
templateVersionParameters, err := client.TemplateVersionRichParameters(inv.Context(), templateVersion.ID) templateVersionParameters, err := client.TemplateVersionRichParameters(inv.Context(), templateVersion.ID)
if err != nil { if err != nil {
return nil, xerrors.Errorf("get template version rich parameters: %w", err) return nil, xerrors.Errorf("get template version rich parameters: %w", err)
} }
parameterMapFromFile = map[string]string{} parameterMapFromFile := map[string]string{}
useParamFile = false useParamFile := false
if args.RichParameterFile != "" { if args.RichParameterFile != "" {
useParamFile = true useParamFile = true
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("Attempting to read the variables from the rich parameter file.")+"\r\n") _, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("Attempting to read the variables from the rich parameter file.")+"\r\n")
@ -321,7 +236,7 @@ PromptParamLoop:
return nil, err return nil, err
} }
} }
disclaimerPrinted = false disclaimerPrinted := false
richParameters := make([]codersdk.WorkspaceBuildParameter, 0) richParameters := make([]codersdk.WorkspaceBuildParameter, 0)
PromptRichParamLoop: PromptRichParamLoop:
for _, templateVersionParameter := range templateVersionParameters { for _, templateVersionParameter := range templateVersionParameters {
@ -379,7 +294,6 @@ PromptRichParamLoop:
// Run a dry-run with the given parameters to check correctness // Run a dry-run with the given parameters to check correctness
dryRun, err := client.CreateTemplateVersionDryRun(inv.Context(), templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{ dryRun, err := client.CreateTemplateVersionDryRun(inv.Context(), templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{
WorkspaceName: args.NewWorkspaceName, WorkspaceName: args.NewWorkspaceName,
ParameterValues: legacyParameters,
RichParameterValues: richParameters, RichParameterValues: richParameters,
}) })
if err != nil { if err != nil {
@ -421,7 +335,6 @@ PromptRichParamLoop:
} }
return &buildParameters{ return &buildParameters{
parameters: legacyParameters,
richParameters: richParameters, richParameters: richParameters,
}, nil }, nil
} }

View File

@ -2,7 +2,6 @@ package cli_test
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"os" "os"
"regexp" "regexp"
@ -181,181 +180,6 @@ func TestCreate(t *testing.T) {
assert.Nil(t, ws.AutostartSchedule, "expected workspace autostart schedule to be nil") assert.Nil(t, ws.AutostartSchedule, "expected workspace autostart schedule to be nil")
} }
}) })
t.Run("WithParameter", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
defaultValue := "something"
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: createTestParseResponseWithDefault(defaultValue),
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
inv, root := clitest.New(t, "create", "")
clitest.SetupConfig(t, client, root)
doneChan := make(chan struct{})
pty := ptytest.New(t).Attach(inv)
go func() {
defer close(doneChan)
err := inv.Run()
assert.NoError(t, err)
}()
matches := []string{
"Specify a name", "my-workspace",
fmt.Sprintf("Enter a value (default: %q):", defaultValue), "bingo",
"Enter a value:", "boingo",
"Confirm create?", "yes",
}
for i := 0; i < len(matches); i += 2 {
match := matches[i]
value := matches[i+1]
pty.ExpectMatch(match)
pty.WriteLine(value)
}
<-doneChan
})
t.Run("WithParameterFileContainingTheValue", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
defaultValue := "something"
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: createTestParseResponseWithDefault(defaultValue),
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
tempDir := t.TempDir()
removeTmpDirUntilSuccessAfterTest(t, tempDir)
parameterFile, _ := os.CreateTemp(tempDir, "testParameterFile*.yaml")
_, _ = parameterFile.WriteString("region: \"bingo\"\nusername: \"boingo\"")
inv, root := clitest.New(t, "create", "", "--parameter-file", parameterFile.Name())
clitest.SetupConfig(t, client, root)
doneChan := make(chan struct{})
pty := ptytest.New(t).Attach(inv)
go func() {
defer close(doneChan)
err := inv.Run()
assert.NoError(t, err)
}()
matches := []string{
"Specify a name", "my-workspace",
"Confirm create?", "yes",
}
for i := 0; i < len(matches); i += 2 {
match := matches[i]
value := matches[i+1]
pty.ExpectMatch(match)
pty.WriteLine(value)
}
<-doneChan
})
t.Run("WithParameterFileNotContainingTheValue", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
defaultValue := "something"
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: createTestParseResponseWithDefault(defaultValue),
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
tempDir := t.TempDir()
removeTmpDirUntilSuccessAfterTest(t, tempDir)
parameterFile, _ := os.CreateTemp(tempDir, "testParameterFile*.yaml")
_, _ = parameterFile.WriteString("username: \"boingo\"")
inv, root := clitest.New(t, "create", "", "--parameter-file", parameterFile.Name())
clitest.SetupConfig(t, client, root)
doneChan := make(chan struct{})
pty := ptytest.New(t).Attach(inv)
go func() {
defer close(doneChan)
err := inv.Run()
assert.NoError(t, err)
}()
matches := []struct {
match string
write string
}{
{
match: "Specify a name",
write: "my-workspace",
},
{
match: fmt.Sprintf("Enter a value (default: %q):", defaultValue),
write: "bingo",
},
{
match: "Confirm create?",
write: "yes",
},
}
for _, m := range matches {
pty.ExpectMatch(m.match)
pty.WriteLine(m.write)
}
<-doneChan
})
t.Run("FailedDryRun", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: echo.ParameterSuccess,
},
},
}},
ProvisionPlan: []*proto.Provision_Response{
{
Type: &proto.Provision_Response_Complete{
Complete: &proto.Provision_Complete{},
},
},
},
})
tempDir := t.TempDir()
parameterFile, err := os.CreateTemp(tempDir, "testParameterFile*.yaml")
require.NoError(t, err)
defer parameterFile.Close()
_, _ = parameterFile.WriteString(fmt.Sprintf("%s: %q", echo.ParameterExecKey, echo.ParameterError("fail")))
// The template import job should end up failed, but we need it to be
// succeeded so the dry-run can begin.
version = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
require.Equal(t, codersdk.ProvisionerJobSucceeded, version.Job.Status, "job is not failed")
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
inv, root := clitest.New(t, "create", "test", "--parameter-file", parameterFile.Name(), "-y")
clitest.SetupConfig(t, client, root)
ptytest.New(t).Attach(inv)
err = inv.Run()
require.Error(t, err)
require.ErrorContains(t, err, "dry-run workspace")
})
} }
func TestCreateWithRichParameters(t *testing.T) { func TestCreateWithRichParameters(t *testing.T) {
@ -751,39 +575,3 @@ func TestCreateWithGitAuth(t *testing.T) {
pty.ExpectMatch("Confirm create?") pty.ExpectMatch("Confirm create?")
pty.WriteLine("yes") pty.WriteLine("yes")
} }
func createTestParseResponseWithDefault(defaultValue string) []*proto.Parse_Response {
return []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{
{
AllowOverrideSource: true,
Name: "region",
Description: "description 1",
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: defaultValue,
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
{
AllowOverrideSource: true,
Name: "username",
Description: "description 2",
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
// No default value
Value: "",
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
},
},
},
}}
}

View File

@ -49,29 +49,6 @@ func createParameterMapFromFile(parameterFile string) (map[string]string, error)
return nil, xerrors.Errorf("Parameter file name is not specified") return nil, xerrors.Errorf("Parameter file name is not specified")
} }
// Returns a parameter value from a given map, if the map does not exist or does not contain the item, it takes input from the user.
// Throws an error if there are any errors with the users input.
func getParameterValueFromMapOrInput(inv *clibase.Invocation, parameterMap map[string]string, parameterSchema codersdk.ParameterSchema) (string, error) {
var parameterValue string
var err error
if parameterMap != nil {
var ok bool
parameterValue, ok = parameterMap[parameterSchema.Name]
if !ok {
parameterValue, err = cliui.ParameterSchema(inv, parameterSchema)
if err != nil {
return "", err
}
}
} else {
parameterValue, err = cliui.ParameterSchema(inv, parameterSchema)
if err != nil {
return "", err
}
}
return parameterValue, nil
}
func getWorkspaceBuildParameterValueFromMapOrInput(inv *clibase.Invocation, parameterMap map[string]string, templateVersionParameter codersdk.TemplateVersionParameter) (*codersdk.WorkspaceBuildParameter, error) { func getWorkspaceBuildParameterValueFromMapOrInput(inv *clibase.Invocation, parameterMap map[string]string, templateVersionParameter codersdk.TemplateVersionParameter) (*codersdk.WorkspaceBuildParameter, error) {
var parameterValue string var parameterValue string
var err error var err error

View File

@ -1,28 +0,0 @@
package cli
import (
"github.com/coder/coder/cli/clibase"
)
func (r *RootCmd) parameters() *clibase.Cmd {
cmd := &clibase.Cmd{
Short: "List parameters for a given scope",
Long: formatExamples(
example{
Command: "coder parameters list workspace my-workspace",
},
),
Use: "parameters",
// Currently hidden as this shows parameter values, not parameter
// schemes. Until we have a good way to distinguish the two, it's better
// not to add confusion or lock ourselves into a certain api.
// This cmd is still valuable debugging tool for devs to avoid
// constructing curl requests.
Hidden: true,
Aliases: []string{"params"},
Children: []*clibase.Cmd{
r.parameterList(),
},
}
return cmd
}

View File

@ -1,88 +0,0 @@
package cli
import (
"fmt"
"github.com/google/uuid"
"golang.org/x/xerrors"
"github.com/coder/coder/cli/clibase"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/codersdk"
)
func (r *RootCmd) parameterList() *clibase.Cmd {
formatter := cliui.NewOutputFormatter(
cliui.TableFormat([]codersdk.Parameter{}, []string{"name", "scope", "destination scheme"}),
cliui.JSONFormat(),
)
client := new(codersdk.Client)
cmd := &clibase.Cmd{
Use: "list",
Aliases: []string{"ls"},
Middleware: clibase.Chain(
clibase.RequireNArgs(2),
r.InitClient(client),
),
Handler: func(inv *clibase.Invocation) error {
scope, name := inv.Args[0], inv.Args[1]
organization, err := CurrentOrganization(inv, client)
if err != nil {
return xerrors.Errorf("get current organization: %w", err)
}
var scopeID uuid.UUID
switch codersdk.ParameterScope(scope) {
case codersdk.ParameterWorkspace:
workspace, err := namedWorkspace(inv.Context(), client, name)
if err != nil {
return err
}
scopeID = workspace.ID
case codersdk.ParameterTemplate:
template, err := client.TemplateByName(inv.Context(), organization.ID, name)
if err != nil {
return xerrors.Errorf("get workspace template: %w", err)
}
scopeID = template.ID
case codersdk.ParameterImportJob, "template_version":
scope = string(codersdk.ParameterImportJob)
scopeID, err = uuid.Parse(name)
if err != nil {
return xerrors.Errorf("%q must be a uuid for this scope type", name)
}
// Could be a template_version id or a job id. Check for the
// version id.
tv, err := client.TemplateVersion(inv.Context(), scopeID)
if err == nil {
scopeID = tv.Job.ID
}
default:
return xerrors.Errorf("%q is an unsupported scope, use %v", scope, []codersdk.ParameterScope{
codersdk.ParameterWorkspace, codersdk.ParameterTemplate, codersdk.ParameterImportJob,
})
}
params, err := client.Parameters(inv.Context(), codersdk.ParameterScope(scope), scopeID)
if err != nil {
return xerrors.Errorf("fetch params: %w", err)
}
out, err := formatter.Format(inv.Context(), params)
if err != nil {
return xerrors.Errorf("render output: %w", err)
}
_, err = fmt.Fprintln(inv.Stdout, out)
return err
},
}
formatter.AttachOptions(&cmd.Options)
return cmd
}

View File

@ -94,7 +94,6 @@ func (r *RootCmd) Core() []*clibase.Cmd {
r.create(), r.create(),
r.deleteWorkspace(), r.deleteWorkspace(),
r.list(), r.list(),
r.parameters(),
r.ping(), r.ping(),
r.rename(), r.rename(),
r.scaletest(), r.scaletest(),

View File

@ -472,10 +472,8 @@ func (r *RootCmd) scaletestCleanup() *clibase.Cmd {
func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd { func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
var ( var (
count int64 count int64
template string template string
parametersFile string
parameters []string // key=value
noPlan bool noPlan bool
noCleanup bool noCleanup bool
@ -571,51 +569,11 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
return xerrors.Errorf("get template version %q: %w", tpl.ActiveVersionID, err) return xerrors.Errorf("get template version %q: %w", tpl.ActiveVersionID, err)
} }
parameterSchemas, err := client.TemplateVersionSchema(ctx, templateVersion.ID)
if err != nil {
return xerrors.Errorf("get template version schema %q: %w", templateVersion.ID, err)
}
paramsMap := map[string]string{}
if parametersFile != "" {
fileMap, err := createParameterMapFromFile(parametersFile)
if err != nil {
return xerrors.Errorf("read parameters file %q: %w", parametersFile, err)
}
paramsMap = fileMap
}
for _, p := range parameters {
parts := strings.SplitN(p, "=", 2)
if len(parts) != 2 {
return xerrors.Errorf("invalid parameter %q", p)
}
paramsMap[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
}
params := []codersdk.CreateParameterRequest{}
for _, p := range parameterSchemas {
value, ok := paramsMap[p.Name]
if !ok {
value = ""
}
params = append(params, codersdk.CreateParameterRequest{
Name: p.Name,
SourceValue: value,
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: p.DefaultDestinationScheme,
})
}
// Do a dry-run to ensure the template and parameters are valid // Do a dry-run to ensure the template and parameters are valid
// before we start creating users and workspaces. // before we start creating users and workspaces.
if !noPlan { if !noPlan {
dryRun, err := client.CreateTemplateVersionDryRun(ctx, templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{ dryRun, err := client.CreateTemplateVersionDryRun(ctx, templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{
WorkspaceName: "scaletest", WorkspaceName: "scaletest",
ParameterValues: params,
}) })
if err != nil { if err != nil {
return xerrors.Errorf("start dry run workspace creation: %w", err) return xerrors.Errorf("start dry run workspace creation: %w", err)
@ -667,8 +625,7 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
OrganizationID: me.OrganizationIDs[0], OrganizationID: me.OrganizationIDs[0],
// UserID is set by the test automatically. // UserID is set by the test automatically.
Request: codersdk.CreateWorkspaceRequest{ Request: codersdk.CreateWorkspaceRequest{
TemplateID: tpl.ID, TemplateID: tpl.ID,
ParameterValues: params,
}, },
NoWaitForAgents: noWaitForAgents, NoWaitForAgents: noWaitForAgents,
}, },
@ -787,18 +744,6 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
Description: "Required: Name or ID of the template to use for workspaces.", Description: "Required: Name or ID of the template to use for workspaces.",
Value: clibase.StringOf(&template), Value: clibase.StringOf(&template),
}, },
{
Flag: "parameters-file",
Env: "CODER_SCALETEST_PARAMETERS_FILE",
Description: "Path to a YAML file containing the parameters to use for each workspace.",
Value: clibase.StringOf(&parametersFile),
},
{
Flag: "parameter",
Env: "CODER_SCALETEST_PARAMETERS",
Description: "Parameters to use for each workspace. Can be specified multiple times. Overrides any existing parameters with the same name from --parameters-file. Format: key=value.",
Value: clibase.StringArrayOf(&parameters),
},
{ {
Flag: "no-plan", Flag: "no-plan",
Env: "CODER_SCALETEST_NO_PLAN", Env: "CODER_SCALETEST_NO_PLAN",

View File

@ -105,6 +105,23 @@ func (r *RootCmd) ssh() *clibase.Cmd {
return err return err
} }
templateVersion, err := client.TemplateVersion(ctx, workspace.LatestBuild.TemplateVersionID)
if err != nil {
return err
}
var unsupportedWorkspace bool
for _, warning := range templateVersion.Warnings {
if warning == codersdk.TemplateVersionWarningUnsupportedWorkspaces {
unsupportedWorkspace = true
break
}
}
if unsupportedWorkspace && isTTYErr(inv) {
_, _ = fmt.Fprintln(inv.Stderr, "👋 Your workspace uses legacy parameters which are not supported anymore. Contact your administrator for assistance.")
}
updateWorkspaceBanner, outdated := verifyWorkspaceOutdated(client, workspace) updateWorkspaceBanner, outdated := verifyWorkspaceOutdated(client, workspace)
if outdated && isTTYErr(inv) { if outdated && isTTYErr(inv) {
_, _ = fmt.Fprintln(inv.Stderr, updateWorkspaceBanner) _, _ = fmt.Fprintln(inv.Stderr, updateWorkspaceBanner)

View File

@ -26,7 +26,6 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
var ( var (
provisioner string provisioner string
provisionerTags []string provisionerTags []string
parameterFile string
variablesFile string variablesFile string
variables []string variables []string
defaultTTL time.Duration defaultTTL time.Duration
@ -98,12 +97,11 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
return err return err
} }
job, _, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{ job, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{
Client: client, Client: client,
Organization: organization, Organization: organization,
Provisioner: database.ProvisionerType(provisioner), Provisioner: database.ProvisionerType(provisioner),
FileID: resp.ID, FileID: resp.ID,
ParameterFile: parameterFile,
ProvisionerTags: tags, ProvisionerTags: tags,
VariablesFile: variablesFile, VariablesFile: variablesFile,
Variables: variables, Variables: variables,
@ -146,11 +144,6 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
}, },
} }
cmd.Options = clibase.OptionSet{ cmd.Options = clibase.OptionSet{
{
Flag: "parameter-file",
Description: "Specify a file path with parameter values.",
Value: clibase.StringOf(&parameterFile),
},
{ {
Flag: "variables-file", Flag: "variables-file",
Description: "Specify a file path with values for Terraform-managed variables.", Description: "Specify a file path with values for Terraform-managed variables.",
@ -198,12 +191,11 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
} }
type createValidTemplateVersionArgs struct { type createValidTemplateVersionArgs struct {
Name string Name string
Client *codersdk.Client Client *codersdk.Client
Organization codersdk.Organization Organization codersdk.Organization
Provisioner database.ProvisionerType Provisioner database.ProvisionerType
FileID uuid.UUID FileID uuid.UUID
ParameterFile string
VariablesFile string VariablesFile string
Variables []string Variables []string
@ -217,17 +209,17 @@ type createValidTemplateVersionArgs struct {
ProvisionerTags map[string]string ProvisionerTags map[string]string
} }
func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplateVersionArgs, parameters ...codersdk.CreateParameterRequest) (*codersdk.TemplateVersion, []codersdk.CreateParameterRequest, error) { func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplateVersionArgs) (*codersdk.TemplateVersion, error) {
client := args.Client client := args.Client
variableValues, err := loadVariableValuesFromFile(args.VariablesFile) variableValues, err := loadVariableValuesFromFile(args.VariablesFile)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
variableValuesFromKeyValues, err := loadVariableValuesFromOptions(args.Variables) variableValuesFromKeyValues, err := loadVariableValuesFromOptions(args.Variables)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
variableValues = append(variableValues, variableValuesFromKeyValues...) variableValues = append(variableValues, variableValuesFromKeyValues...)
@ -236,7 +228,6 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
StorageMethod: codersdk.ProvisionerStorageMethodFile, StorageMethod: codersdk.ProvisionerStorageMethodFile,
FileID: args.FileID, FileID: args.FileID,
Provisioner: codersdk.ProvisionerType(args.Provisioner), Provisioner: codersdk.ProvisionerType(args.Provisioner),
ParameterValues: parameters,
ProvisionerTags: args.ProvisionerTags, ProvisionerTags: args.ProvisionerTags,
UserVariableValues: variableValues, UserVariableValues: variableValues,
} }
@ -245,7 +236,7 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
} }
version, err := client.CreateTemplateVersion(inv.Context(), args.Organization.ID, req) version, err := client.CreateTemplateVersion(inv.Context(), args.Organization.ID, req)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
err = cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{ err = cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{
@ -263,115 +254,21 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
if err != nil { if err != nil {
var jobErr *cliui.ProvisionerJobError var jobErr *cliui.ProvisionerJobError
if errors.As(err, &jobErr) && !provisionerd.IsMissingParameterErrorCode(string(jobErr.Code)) { if errors.As(err, &jobErr) && !provisionerd.IsMissingParameterErrorCode(string(jobErr.Code)) {
return nil, nil, err return nil, err
} }
} }
version, err = client.TemplateVersion(inv.Context(), version.ID) version, err = client.TemplateVersion(inv.Context(), version.ID)
if err != nil { if err != nil {
return nil, nil, err return nil, err
}
parameterSchemas, err := client.TemplateVersionSchema(inv.Context(), version.ID)
if err != nil {
return nil, nil, err
}
parameterValues, err := client.TemplateVersionParameters(inv.Context(), version.ID)
if err != nil {
return nil, nil, err
}
// lastParameterValues are pulled from the current active template version if
// templateID is provided. This allows pulling params from the last
// version instead of prompting if we are updating template versions.
lastParameterValues := make(map[string]codersdk.Parameter)
if args.ReuseParameters && args.Template != nil {
activeVersion, err := client.TemplateVersion(inv.Context(), args.Template.ActiveVersionID)
if err != nil {
return nil, nil, xerrors.Errorf("Fetch current active template version: %w", err)
}
// We don't want to compute the params, we only want to copy from this scope
values, err := client.Parameters(inv.Context(), codersdk.ParameterImportJob, activeVersion.Job.ID)
if err != nil {
return nil, nil, xerrors.Errorf("Fetch previous version parameters: %w", err)
}
for _, value := range values {
lastParameterValues[value.Name] = value
}
}
if provisionerd.IsMissingParameterErrorCode(string(version.Job.ErrorCode)) {
valuesBySchemaID := map[string]codersdk.ComputedParameter{}
for _, parameterValue := range parameterValues {
valuesBySchemaID[parameterValue.SchemaID.String()] = parameterValue
}
// parameterMapFromFile can be nil if parameter file is not specified
var parameterMapFromFile map[string]string
if args.ParameterFile != "" {
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("Attempting to read the variables from the parameter file.")+"\r\n")
parameterMapFromFile, err = createParameterMapFromFile(args.ParameterFile)
if err != nil {
return nil, nil, err
}
}
// pulled params come from the last template version
pulled := make([]string, 0)
missingSchemas := make([]codersdk.ParameterSchema, 0)
for _, parameterSchema := range parameterSchemas {
_, ok := valuesBySchemaID[parameterSchema.ID.String()]
if ok {
continue
}
// The file values are handled below. So don't handle them here,
// just check if a value is present in the file.
_, fileOk := parameterMapFromFile[parameterSchema.Name]
if inherit, ok := lastParameterValues[parameterSchema.Name]; ok && !fileOk {
// If the value is not in the param file, and can be pulled from the last template version,
// then don't mark it as missing.
parameters = append(parameters, codersdk.CreateParameterRequest{
CloneID: inherit.ID,
})
pulled = append(pulled, fmt.Sprintf("%q", parameterSchema.Name))
continue
}
missingSchemas = append(missingSchemas, parameterSchema)
}
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("This template has required variables! They are scoped to the template, and not viewable after being set."))
if len(pulled) > 0 {
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render(fmt.Sprintf("The following parameter values are being pulled from the latest template version: %s.", strings.Join(pulled, ", "))))
_, _ = fmt.Fprintln(inv.Stdout, cliui.Styles.Paragraph.Render("Use \"--always-prompt\" flag to change the values."))
}
_, _ = fmt.Fprint(inv.Stdout, "\r\n")
for _, parameterSchema := range missingSchemas {
parameterValue, err := getParameterValueFromMapOrInput(inv, parameterMapFromFile, parameterSchema)
if err != nil {
return nil, nil, err
}
parameters = append(parameters, codersdk.CreateParameterRequest{
Name: parameterSchema.Name,
SourceValue: parameterValue,
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: parameterSchema.DefaultDestinationScheme,
})
_, _ = fmt.Fprintln(inv.Stdout)
}
// This recursion is only 1 level deep in practice.
// The first pass populates the missing parameters, so it does not enter this `if` block again.
return createValidTemplateVersion(inv, args, parameters...)
} }
if version.Job.Status != codersdk.ProvisionerJobSucceeded { if version.Job.Status != codersdk.ProvisionerJobSucceeded {
return nil, nil, xerrors.New(version.Job.Error) return nil, xerrors.New(version.Job.Error)
} }
resources, err := client.TemplateVersionResources(inv.Context(), version.ID) resources, err := client.TemplateVersionResources(inv.Context(), version.ID)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
// Only display the resources on the start transition, to avoid listing them more than once. // Only display the resources on the start transition, to avoid listing them more than once.
@ -387,10 +284,10 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
Title: "Template Preview", Title: "Template Preview",
}) })
if err != nil { if err != nil {
return nil, nil, xerrors.Errorf("preview template resources: %w", err) return nil, xerrors.Errorf("preview template resources: %w", err)
} }
return &version, parameters, nil return &version, nil
} }
// prettyDirectoryPath returns a prettified path when inside the users // prettyDirectoryPath returns a prettified path when inside the users

View File

@ -108,108 +108,6 @@ func TestTemplateCreate(t *testing.T) {
require.NoError(t, inv.Run()) require.NoError(t, inv.Run())
}) })
t.Run("WithParameter", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
Parse: createTestParseResponse(),
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
inv, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
clitest.SetupConfig(t, client, root)
pty := ptytest.New(t).Attach(inv)
clitest.Start(t, inv)
matches := []struct {
match string
write string
}{
{match: "Upload", write: "yes"},
{match: "Enter a value:", write: "bananas"},
{match: "Confirm create?", write: "yes"},
}
for _, m := range matches {
pty.ExpectMatch(m.match)
pty.WriteLine(m.write)
}
})
t.Run("WithParameterFileContainingTheValue", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
Parse: createTestParseResponse(),
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
tempDir := t.TempDir()
removeTmpDirUntilSuccessAfterTest(t, tempDir)
parameterFile, _ := os.CreateTemp(tempDir, "testParameterFile*.yaml")
_, _ = parameterFile.WriteString("region: \"bananas\"")
inv, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--parameter-file", parameterFile.Name())
clitest.SetupConfig(t, client, root)
pty := ptytest.New(t).Attach(inv)
clitest.Start(t, inv)
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)
}
})
t.Run("WithParameterFileNotContainingTheValue", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
Parse: createTestParseResponse(),
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
tempDir := t.TempDir()
removeTmpDirUntilSuccessAfterTest(t, tempDir)
parameterFile, _ := os.CreateTemp(tempDir, "testParameterFile*.yaml")
_, _ = parameterFile.WriteString("zone: \"bananas\"")
inv, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--parameter-file", parameterFile.Name())
clitest.SetupConfig(t, client, root)
pty := ptytest.New(t).Attach(inv)
clitest.Start(t, inv)
matches := []struct {
match string
write string
}{
{
match: "Upload",
write: "yes",
},
{
match: "Enter a value:",
write: "bingo",
},
{
match: "Confirm create?",
write: "yes",
},
}
for _, m := range matches {
pty.ExpectMatch(m.match)
pty.WriteLine(m.write)
}
})
t.Run("Recreate template with same name (create, delete, create)", func(t *testing.T) { t.Run("Recreate template with same name (create, delete, create)", func(t *testing.T) {
t.Parallel() t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
@ -254,16 +152,6 @@ func TestTemplateCreate(t *testing.T) {
require.NoError(t, err, "Template must be recreated without error") require.NoError(t, err, "Template must be recreated without error")
}) })
t.Run("WithParameterExceedingCharLimit", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
coderdtest.CreateFirstUser(t, client)
inv, root := clitest.New(t, "templates", "create", "1234567890123456789012345678901234567891", "--test.provisioner", string(database.ProvisionerTypeEcho))
clitest.SetupConfig(t, client, root)
clitest.StartWithWaiter(t, inv).RequireContains("Template name must be less than 32 characters")
})
t.Run("WithVariablesFileWithoutRequiredValue", func(t *testing.T) { t.Run("WithVariablesFileWithoutRequiredValue", func(t *testing.T) {
t.Parallel() t.Parallel()
@ -414,23 +302,6 @@ func TestTemplateCreate(t *testing.T) {
}) })
} }
func createTestParseResponse() []*proto.Parse_Response {
return []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{{
AllowOverrideSource: true,
Name: "region",
Description: "description",
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}},
},
},
}}
}
// Need this for Windows because of a known issue with Go: // Need this for Windows because of a known issue with Go:
// https://github.com/golang/go/issues/52986 // https://github.com/golang/go/issues/52986
func removeTmpDirUntilSuccessAfterTest(t *testing.T, tempDir string) { func removeTmpDirUntilSuccessAfterTest(t *testing.T, tempDir string) {

View File

@ -110,7 +110,6 @@ func (r *RootCmd) templatePush() *clibase.Cmd {
versionName string versionName string
provisioner string provisioner string
workdir string workdir string
parameterFile string
variablesFile string variablesFile string
variables []string variables []string
alwaysPrompt bool alwaysPrompt bool
@ -153,13 +152,12 @@ func (r *RootCmd) templatePush() *clibase.Cmd {
return err return err
} }
job, _, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{ job, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{
Name: versionName, Name: versionName,
Client: client, Client: client,
Organization: organization, Organization: organization,
Provisioner: database.ProvisionerType(provisioner), Provisioner: database.ProvisionerType(provisioner),
FileID: resp.ID, FileID: resp.ID,
ParameterFile: parameterFile,
VariablesFile: variablesFile, VariablesFile: variablesFile,
Variables: variables, Variables: variables,
Template: &template, Template: &template,
@ -203,11 +201,6 @@ func (r *RootCmd) templatePush() *clibase.Cmd {
// This is for testing! // This is for testing!
Hidden: true, Hidden: true,
}, },
{
Flag: "parameter-file",
Description: "Specify a file path with parameter values.",
Value: clibase.StringOf(&parameterFile),
},
{ {
Flag: "variables-file", Flag: "variables-file",
Description: "Specify a file path with values for Terraform-managed variables.", Description: "Specify a file path with values for Terraform-managed variables.",

View File

@ -8,7 +8,6 @@ import (
"runtime" "runtime"
"testing" "testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -23,92 +22,6 @@ import (
func TestTemplatePush(t *testing.T) { func TestTemplatePush(t *testing.T) {
t.Parallel() t.Parallel()
// NewParameter will:
// 1. Create a template version with 0 params
// 2. Create a new version with 1 param
// 2a. Expects 1 param prompt, fills in value
// 3. Assert 1 param value in new version
// 4. Creates a new version with same param
// 4a. Expects 0 prompts as the param value is carried over
// 5. Assert 1 param value in new version
// 6. Creates a new version with 0 params
// 7. Asset 0 params in new version
t.Run("NewParameter", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
// Create initial template version to update
lastActiveVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
_ = coderdtest.AwaitTemplateVersionJob(t, client, lastActiveVersion.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, lastActiveVersion.ID)
// Create new template version with a new parameter
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
Parse: createTestParseResponse(),
ProvisionApply: echo.ProvisionComplete,
})
inv, root := clitest.New(t, "templates", "push", template.Name, "-y", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
clitest.SetupConfig(t, client, root)
pty := ptytest.New(t).Attach(inv)
execDone := make(chan error)
go func() {
execDone <- inv.Run()
}()
matches := []struct {
match string
write string
}{
// Expect to be prompted for the new param
{match: "Enter a value:", write: "peter-pan"},
}
for _, m := range matches {
pty.ExpectMatch(m.match)
pty.WriteLine(m.write)
}
require.NoError(t, <-execDone)
// Assert template version changed and we have the new param
latestTV, latestParams := latestTemplateVersion(t, client, template.ID)
assert.NotEqual(t, lastActiveVersion.ID, latestTV.ID)
require.Len(t, latestParams, 1, "expect 1 param")
lastActiveVersion = latestTV
// Second update of the same source requires no prompt since the params
// are carried over.
inv, root = clitest.New(t, "templates", "push", template.Name, "-y", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
clitest.SetupConfig(t, client, root)
go func() {
execDone <- inv.Run()
}()
require.NoError(t, <-execDone)
// Assert template version changed and we have the carried over param
latestTV, latestParams = latestTemplateVersion(t, client, template.ID)
assert.NotEqual(t, lastActiveVersion.ID, latestTV.ID)
require.Len(t, latestParams, 1, "expect 1 param")
lastActiveVersion = latestTV
// Remove the param
source = clitest.CreateTemplateVersionSource(t, &echo.Responses{
Parse: echo.ParseComplete,
ProvisionApply: echo.ProvisionComplete,
})
inv, root = clitest.New(t, "templates", "push", template.Name, "-y", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho))
clitest.SetupConfig(t, client, root)
go func() {
execDone <- inv.Run()
}()
require.NoError(t, <-execDone)
// Assert template version changed and the param was removed
latestTV, latestParams = latestTemplateVersion(t, client, template.ID)
assert.NotEqual(t, lastActiveVersion.ID, latestTV.ID)
require.Len(t, latestParams, 0, "expect 0 param")
lastActiveVersion = latestTV
})
t.Run("OK", func(t *testing.T) { t.Run("OK", func(t *testing.T) {
t.Parallel() t.Parallel()
@ -495,20 +408,6 @@ func TestTemplatePush(t *testing.T) {
}) })
} }
func latestTemplateVersion(t *testing.T, client *codersdk.Client, templateID uuid.UUID) (codersdk.TemplateVersion, []codersdk.Parameter) {
t.Helper()
ctx := context.Background()
newTemplate, err := client.Template(ctx, templateID)
require.NoError(t, err)
tv, err := client.TemplateVersion(ctx, newTemplate.ActiveVersionID)
require.NoError(t, err)
params, err := client.Parameters(ctx, codersdk.ParameterImportJob, tv.Job.ID)
require.NoError(t, err)
return tv, params
}
func createEchoResponsesWithTemplateVariables(templateVariables []*proto.TemplateVariable) *echo.Responses { func createEchoResponsesWithTemplateVariables(templateVariables []*proto.TemplateVariable) *echo.Responses {
return &echo.Responses{ return &echo.Responses{
Parse: []*proto.Parse_Response{ Parse: []*proto.Parse_Response{

View File

@ -3,9 +3,6 @@ Usage: coder create [flags] [name]
Create a workspace Create a workspace
Options Options
--parameter-file string, $CODER_PARAMETER_FILE
Specify a file path with parameter values.
--rich-parameter-file string, $CODER_RICH_PARAMETER_FILE --rich-parameter-file string, $CODER_RICH_PARAMETER_FILE
Specify a file path with values for rich parameters defined in the Specify a file path with values for rich parameters defined in the
template. template.

View File

@ -61,15 +61,6 @@ It is recommended that all rate limits are disabled on the server before running
Output format specs in the format "<format>[:<path>]". Not specifying Output format specs in the format "<format>[:<path>]". Not specifying
a path will default to stdout. Available formats: text, json. a path will default to stdout. Available formats: text, json.
--parameter string-array, $CODER_SCALETEST_PARAMETERS
Parameters to use for each workspace. Can be specified multiple times.
Overrides any existing parameters with the same name from
--parameters-file. Format: key=value.
--parameters-file string, $CODER_SCALETEST_PARAMETERS_FILE
Path to a YAML file containing the parameters to use for each
workspace.
--run-command string, $CODER_SCALETEST_RUN_COMMAND --run-command string, $CODER_SCALETEST_RUN_COMMAND
Command to run inside each workspace using reconnecting-pty (i.e. web Command to run inside each workspace using reconnecting-pty (i.e. web
terminal protocol). If not specified, no command will be run. terminal protocol). If not specified, no command will be run.

View File

@ -17,9 +17,6 @@ Create a template from the current directory or as specified by flag
Specify an inactivity TTL for workspaces created from this template. Specify an inactivity TTL for workspaces created from this template.
This licensed feature's default is 0h (off). This licensed feature's default is 0h (off).
--parameter-file string
Specify a file path with parameter values.
--provisioner-tag string-array --provisioner-tag string-array
Specify a set of tags to target provisioner daemons. Specify a set of tags to target provisioner daemons.

View File

@ -14,9 +14,6 @@ Push a new template version from the current directory or as specified by flag
Specify a name for the new template version. It will be automatically Specify a name for the new template version. It will be automatically
generated if not provided. generated if not provided.
--parameter-file string
Specify a file path with parameter values.
--provisioner-tag string-array --provisioner-tag string-array
Specify a set of tags to target provisioner daemons. Specify a set of tags to target provisioner daemons.

View File

@ -9,9 +9,6 @@ Use --always-prompt to change the parameter values of the workspace.
Always prompt all parameters. Does not pull parameter values from Always prompt all parameters. Does not pull parameter values from
existing workspace. existing workspace.
--parameter-file string, $CODER_PARAMETER_FILE
Specify a file path with parameter values.
--rich-parameter-file string, $CODER_RICH_PARAMETER_FILE --rich-parameter-file string, $CODER_RICH_PARAMETER_FILE
Specify a file path with values for rich parameters defined in the Specify a file path with values for rich parameters defined in the
template. template.

View File

@ -9,7 +9,6 @@ import (
func (r *RootCmd) update() *clibase.Cmd { func (r *RootCmd) update() *clibase.Cmd {
var ( var (
parameterFile string
richParameterFile string richParameterFile string
alwaysPrompt bool alwaysPrompt bool
) )
@ -38,14 +37,8 @@ func (r *RootCmd) update() *clibase.Cmd {
return nil return nil
} }
var existingParams []codersdk.Parameter
var existingRichParams []codersdk.WorkspaceBuildParameter var existingRichParams []codersdk.WorkspaceBuildParameter
if !alwaysPrompt { if !alwaysPrompt {
existingParams, err = client.Parameters(inv.Context(), codersdk.ParameterWorkspace, workspace.ID)
if err != nil {
return nil
}
existingRichParams, err = client.WorkspaceBuildParameters(inv.Context(), workspace.LatestBuild.ID) existingRichParams, err = client.WorkspaceBuildParameters(inv.Context(), workspace.LatestBuild.ID)
if err != nil { if err != nil {
return nil return nil
@ -54,8 +47,6 @@ func (r *RootCmd) update() *clibase.Cmd {
buildParams, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{ buildParams, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{
Template: template, Template: template,
ExistingParams: existingParams,
ParameterFile: parameterFile,
ExistingRichParams: existingRichParams, ExistingRichParams: existingRichParams,
RichParameterFile: richParameterFile, RichParameterFile: richParameterFile,
NewWorkspaceName: workspace.Name, NewWorkspaceName: workspace.Name,
@ -70,7 +61,6 @@ func (r *RootCmd) update() *clibase.Cmd {
build, err := client.CreateWorkspaceBuild(inv.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{ build, err := client.CreateWorkspaceBuild(inv.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: template.ActiveVersionID, TemplateVersionID: template.ActiveVersionID,
Transition: codersdk.WorkspaceTransitionStart, Transition: codersdk.WorkspaceTransitionStart,
ParameterValues: buildParams.parameters,
RichParameterValues: buildParams.richParameters, RichParameterValues: buildParams.richParameters,
}) })
if err != nil { if err != nil {
@ -99,12 +89,6 @@ func (r *RootCmd) update() *clibase.Cmd {
Value: clibase.BoolOf(&alwaysPrompt), Value: clibase.BoolOf(&alwaysPrompt),
}, },
{
Flag: "parameter-file",
Description: "Specify a file path with parameter values.",
Env: "CODER_PARAMETER_FILE",
Value: clibase.StringOf(&parameterFile),
},
{ {
Flag: "rich-parameter-file", Flag: "rich-parameter-file",
Description: "Specify a file path with values for rich parameters defined in the template.", Description: "Specify a file path with values for rich parameters defined in the template.",

View File

@ -76,69 +76,6 @@ func TestUpdate(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, version2.ID.String(), ws.LatestBuild.TemplateVersionID.String()) require.Equal(t, version2.ID.String(), ws.LatestBuild.TemplateVersionID.String())
}) })
t.Run("WithParameter", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
version1 := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJob(t, client, version1.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version1.ID)
inv, root := clitest.New(t, "create",
"my-workspace",
"--template", template.Name,
"-y",
)
clitest.SetupConfig(t, client, root)
err := inv.Run()
require.NoError(t, err)
ws, err := client.WorkspaceByOwnerAndName(context.Background(), "testuser", "my-workspace", codersdk.WorkspaceOptions{})
require.NoError(t, err)
require.Equal(t, version1.ID.String(), ws.LatestBuild.TemplateVersionID.String())
defaultValue := "something"
version2 := coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: createTestParseResponseWithDefault(defaultValue),
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
}, template.ID)
coderdtest.AwaitTemplateVersionJob(t, client, version2.ID)
err = client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{
ID: version2.ID,
})
require.NoError(t, err)
inv, root = clitest.New(t, "update", ws.Name)
clitest.SetupConfig(t, client, root)
pty := ptytest.New(t).Attach(inv)
doneChan := make(chan struct{})
go func() {
defer close(doneChan)
err := inv.Run()
assert.NoError(t, err)
}()
matches := []string{
fmt.Sprintf("Enter a value (default: %q):", defaultValue), "bingo",
"Enter a value:", "boingo",
}
for i := 0; i < len(matches); i += 2 {
match := matches[i]
value := matches[i+1]
pty.ExpectMatch(match)
pty.WriteLine(value)
}
<-doneChan
})
} }
func TestUpdateWithRichParameters(t *testing.T) { func TestUpdateWithRichParameters(t *testing.T) {

531
coderd/apidoc/docs.go generated
View File

@ -1595,167 +1595,6 @@ const docTemplate = `{
} }
} }
}, },
"/parameters/{scope}/{id}": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Parameters"
],
"summary": "Get parameters",
"operationId": "get-parameters",
"parameters": [
{
"enum": [
"template",
"workspace",
"import_job"
],
"type": "string",
"description": "Scope",
"name": "scope",
"in": "path",
"required": true
},
{
"type": "string",
"format": "uuid",
"description": "ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.Parameter"
}
}
}
}
},
"post": {
"security": [
{
"CoderSessionToken": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Parameters"
],
"summary": "Create parameter",
"operationId": "create-parameter",
"parameters": [
{
"description": "Parameter request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
{
"enum": [
"template",
"workspace",
"import_job"
],
"type": "string",
"description": "Scope",
"name": "scope",
"in": "path",
"required": true
},
{
"type": "string",
"format": "uuid",
"description": "ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/codersdk.Parameter"
}
}
}
}
},
"/parameters/{scope}/{id}/{name}": {
"delete": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Parameters"
],
"summary": "Delete parameter",
"operationId": "delete-parameter",
"parameters": [
{
"enum": [
"template",
"workspace",
"import_job"
],
"type": "string",
"description": "Scope",
"name": "scope",
"in": "path",
"required": true
},
{
"type": "string",
"format": "uuid",
"description": "ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Name",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.Response"
}
}
}
}
},
"/regions": { "/regions": {
"get": { "get": {
"security": [ "security": [
@ -2764,14 +2603,11 @@ const docTemplate = `{
"CoderSessionToken": [] "CoderSessionToken": []
} }
], ],
"produces": [
"application/json"
],
"tags": [ "tags": [
"Templates" "Templates"
], ],
"summary": "Get parameters by template version", "summary": "Removed: Get parameters by template version",
"operationId": "get-parameters-by-template-version", "operationId": "removed-get-parameters-by-template-version",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
@ -2784,13 +2620,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/parameter.ComputedValue"
}
}
} }
} }
} }
@ -2878,14 +2708,11 @@ const docTemplate = `{
"CoderSessionToken": [] "CoderSessionToken": []
} }
], ],
"produces": [
"application/json"
],
"tags": [ "tags": [
"Templates" "Templates"
], ],
"summary": "Get schema by template version", "summary": "Removed: Get schema by template version",
"operationId": "get-schema-by-template-version", "operationId": "removed-get-schema-by-template-version",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
@ -2898,13 +2725,7 @@ const docTemplate = `{
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.ParameterSchema"
}
}
} }
} }
} }
@ -6810,52 +6631,6 @@ const docTemplate = `{
} }
} }
}, },
"codersdk.CreateParameterRequest": {
"description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.",
"type": "object",
"required": [
"destination_scheme",
"name",
"source_scheme",
"source_value"
],
"properties": {
"copy_from_parameter": {
"description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.",
"type": "string",
"format": "uuid"
},
"destination_scheme": {
"enum": [
"none",
"environment_variable",
"provisioner_variable"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
}
]
},
"name": {
"type": "string"
},
"source_scheme": {
"enum": [
"none",
"data"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
}
]
},
"source_value": {
"type": "string"
}
}
},
"codersdk.CreateTemplateRequest": { "codersdk.CreateTemplateRequest": {
"type": "object", "type": "object",
"required": [ "required": [
@ -6907,12 +6682,6 @@ const docTemplate = `{
"description": "Name is the name of the template.", "description": "Name is the name of the template.",
"type": "string" "type": "string"
}, },
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"template_version_id": { "template_version_id": {
"description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.",
"type": "string", "type": "string",
@ -6923,12 +6692,6 @@ const docTemplate = `{
"codersdk.CreateTemplateVersionDryRunRequest": { "codersdk.CreateTemplateVersionDryRunRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": { "rich_parameter_values": {
"type": "array", "type": "array",
"items": { "items": {
@ -6963,13 +6726,6 @@ const docTemplate = `{
"name": { "name": {
"type": "string" "type": "string"
}, },
"parameter_values": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.",
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"provisioner": { "provisioner": {
"type": "string", "type": "string",
"enum": [ "enum": [
@ -7137,14 +6893,8 @@ const docTemplate = `{
"description": "Orphan may be set for the Destroy transition.", "description": "Orphan may be set for the Destroy transition.",
"type": "boolean" "type": "boolean"
}, },
"parameter_values": {
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": { "rich_parameter_values": {
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter" "$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
@ -7205,14 +6955,8 @@ const docTemplate = `{
"name": { "name": {
"type": "string" "type": "string"
}, },
"parameter_values": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": { "rich_parameter_values": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter" "$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
@ -8063,186 +7807,6 @@ const docTemplate = `{
} }
} }
}, },
"codersdk.Parameter": {
"description": "Parameter represents a set value for the scope.",
"type": "object",
"properties": {
"created_at": {
"type": "string",
"format": "date-time"
},
"destination_scheme": {
"enum": [
"none",
"environment_variable",
"provisioner_variable"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
}
]
},
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"scope": {
"enum": [
"template",
"workspace",
"import_job"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterScope"
}
]
},
"scope_id": {
"type": "string",
"format": "uuid"
},
"source_scheme": {
"enum": [
"none",
"data"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
}
]
},
"source_value": {
"type": "string"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"codersdk.ParameterDestinationScheme": {
"type": "string",
"enum": [
"none",
"environment_variable",
"provisioner_variable"
],
"x-enum-varnames": [
"ParameterDestinationSchemeNone",
"ParameterDestinationSchemeEnvironmentVariable",
"ParameterDestinationSchemeProvisionerVariable"
]
},
"codersdk.ParameterSchema": {
"type": "object",
"properties": {
"allow_override_destination": {
"type": "boolean"
},
"allow_override_source": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"default_destination_scheme": {
"enum": [
"none",
"environment_variable",
"provisioner_variable"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
}
]
},
"default_refresh": {
"type": "string"
},
"default_source_scheme": {
"enum": [
"none",
"data"
],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
}
]
},
"default_source_value": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "string",
"format": "uuid"
},
"job_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"redisplay_value": {
"type": "boolean"
},
"validation_condition": {
"type": "string"
},
"validation_contains": {
"description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.",
"type": "array",
"items": {
"type": "string"
}
},
"validation_error": {
"type": "string"
},
"validation_type_system": {
"type": "string"
},
"validation_value_type": {
"type": "string"
}
}
},
"codersdk.ParameterScope": {
"type": "string",
"enum": [
"template",
"workspace",
"import_job"
],
"x-enum-varnames": [
"ParameterTemplate",
"ParameterWorkspace",
"ParameterImportJob"
]
},
"codersdk.ParameterSourceScheme": {
"type": "string",
"enum": [
"none",
"data"
],
"x-enum-varnames": [
"ParameterSourceSchemeNone",
"ParameterSourceSchemeData"
]
},
"codersdk.PatchTemplateVersionRequest": { "codersdk.PatchTemplateVersionRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -9250,10 +8814,10 @@ const docTemplate = `{
"codersdk.TemplateVersionWarning": { "codersdk.TemplateVersionWarning": {
"type": "string", "type": "string",
"enum": [ "enum": [
"DEPRECATED_PARAMETERS" "UNSUPPORTED_WORKSPACES"
], ],
"x-enum-varnames": [ "x-enum-varnames": [
"TemplateVersionWarningDeprecatedParameters" "TemplateVersionWarningUnsupportedWorkspaces"
] ]
}, },
"codersdk.TokenConfig": { "codersdk.TokenConfig": {
@ -10265,43 +9829,6 @@ const docTemplate = `{
} }
} }
}, },
"database.ParameterDestinationScheme": {
"type": "string",
"enum": [
"none",
"environment_variable",
"provisioner_variable"
],
"x-enum-varnames": [
"ParameterDestinationSchemeNone",
"ParameterDestinationSchemeEnvironmentVariable",
"ParameterDestinationSchemeProvisionerVariable"
]
},
"database.ParameterScope": {
"type": "string",
"enum": [
"template",
"import_job",
"workspace"
],
"x-enum-varnames": [
"ParameterScopeTemplate",
"ParameterScopeImportJob",
"ParameterScopeWorkspace"
]
},
"database.ParameterSourceScheme": {
"type": "string",
"enum": [
"none",
"data"
],
"x-enum-varnames": [
"ParameterSourceSchemeNone",
"ParameterSourceSchemeData"
]
},
"derp.ServerInfoMessage": { "derp.ServerInfoMessage": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -10572,44 +10099,6 @@ const docTemplate = `{
} }
} }
}, },
"parameter.ComputedValue": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"default_source_value": {
"type": "boolean"
},
"destination_scheme": {
"$ref": "#/definitions/database.ParameterDestinationScheme"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"schema_id": {
"type": "string"
},
"scope": {
"$ref": "#/definitions/database.ParameterScope"
},
"scope_id": {
"type": "string"
},
"source_scheme": {
"$ref": "#/definitions/database.ParameterSourceScheme"
},
"source_value": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"sql.NullTime": { "sql.NullTime": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -1391,141 +1391,6 @@
} }
} }
}, },
"/parameters/{scope}/{id}": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["Parameters"],
"summary": "Get parameters",
"operationId": "get-parameters",
"parameters": [
{
"enum": ["template", "workspace", "import_job"],
"type": "string",
"description": "Scope",
"name": "scope",
"in": "path",
"required": true
},
{
"type": "string",
"format": "uuid",
"description": "ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.Parameter"
}
}
}
}
},
"post": {
"security": [
{
"CoderSessionToken": []
}
],
"consumes": ["application/json"],
"produces": ["application/json"],
"tags": ["Parameters"],
"summary": "Create parameter",
"operationId": "create-parameter",
"parameters": [
{
"description": "Parameter request",
"name": "request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
{
"enum": ["template", "workspace", "import_job"],
"type": "string",
"description": "Scope",
"name": "scope",
"in": "path",
"required": true
},
{
"type": "string",
"format": "uuid",
"description": "ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"201": {
"description": "Created",
"schema": {
"$ref": "#/definitions/codersdk.Parameter"
}
}
}
}
},
"/parameters/{scope}/{id}/{name}": {
"delete": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["Parameters"],
"summary": "Delete parameter",
"operationId": "delete-parameter",
"parameters": [
{
"enum": ["template", "workspace", "import_job"],
"type": "string",
"description": "Scope",
"name": "scope",
"in": "path",
"required": true
},
{
"type": "string",
"format": "uuid",
"description": "ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Name",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.Response"
}
}
}
}
},
"/regions": { "/regions": {
"get": { "get": {
"security": [ "security": [
@ -2426,10 +2291,9 @@
"CoderSessionToken": [] "CoderSessionToken": []
} }
], ],
"produces": ["application/json"],
"tags": ["Templates"], "tags": ["Templates"],
"summary": "Get parameters by template version", "summary": "Removed: Get parameters by template version",
"operationId": "get-parameters-by-template-version", "operationId": "removed-get-parameters-by-template-version",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
@ -2442,13 +2306,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/parameter.ComputedValue"
}
}
} }
} }
} }
@ -2528,10 +2386,9 @@
"CoderSessionToken": [] "CoderSessionToken": []
} }
], ],
"produces": ["application/json"],
"tags": ["Templates"], "tags": ["Templates"],
"summary": "Get schema by template version", "summary": "Removed: Get schema by template version",
"operationId": "get-schema-by-template-version", "operationId": "removed-get-schema-by-template-version",
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
@ -2544,13 +2401,7 @@
], ],
"responses": { "responses": {
"200": { "200": {
"description": "OK", "description": "OK"
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.ParameterSchema"
}
}
} }
} }
} }
@ -6054,45 +5905,6 @@
} }
} }
}, },
"codersdk.CreateParameterRequest": {
"description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.",
"type": "object",
"required": [
"destination_scheme",
"name",
"source_scheme",
"source_value"
],
"properties": {
"copy_from_parameter": {
"description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.",
"type": "string",
"format": "uuid"
},
"destination_scheme": {
"enum": ["none", "environment_variable", "provisioner_variable"],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
}
]
},
"name": {
"type": "string"
},
"source_scheme": {
"enum": ["none", "data"],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
}
]
},
"source_value": {
"type": "string"
}
}
},
"codersdk.CreateTemplateRequest": { "codersdk.CreateTemplateRequest": {
"type": "object", "type": "object",
"required": ["name", "template_version_id"], "required": ["name", "template_version_id"],
@ -6141,12 +5953,6 @@
"description": "Name is the name of the template.", "description": "Name is the name of the template.",
"type": "string" "type": "string"
}, },
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"template_version_id": { "template_version_id": {
"description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.",
"type": "string", "type": "string",
@ -6157,12 +5963,6 @@
"codersdk.CreateTemplateVersionDryRunRequest": { "codersdk.CreateTemplateVersionDryRunRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": { "rich_parameter_values": {
"type": "array", "type": "array",
"items": { "items": {
@ -6194,13 +5994,6 @@
"name": { "name": {
"type": "string" "type": "string"
}, },
"parameter_values": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.",
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"provisioner": { "provisioner": {
"type": "string", "type": "string",
"enum": ["terraform", "echo"] "enum": ["terraform", "echo"]
@ -6342,14 +6135,8 @@
"description": "Orphan may be set for the Destroy transition.", "description": "Orphan may be set for the Destroy transition.",
"type": "boolean" "type": "boolean"
}, },
"parameter_values": {
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": { "rich_parameter_values": {
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter" "$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
@ -6400,14 +6187,8 @@
"name": { "name": {
"type": "string" "type": "string"
}, },
"parameter_values": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": { "rich_parameter_values": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter" "$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
@ -7212,157 +6993,6 @@
} }
} }
}, },
"codersdk.Parameter": {
"description": "Parameter represents a set value for the scope.",
"type": "object",
"properties": {
"created_at": {
"type": "string",
"format": "date-time"
},
"destination_scheme": {
"enum": ["none", "environment_variable", "provisioner_variable"],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
}
]
},
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"scope": {
"enum": ["template", "workspace", "import_job"],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterScope"
}
]
},
"scope_id": {
"type": "string",
"format": "uuid"
},
"source_scheme": {
"enum": ["none", "data"],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
}
]
},
"source_value": {
"type": "string"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
}
},
"codersdk.ParameterDestinationScheme": {
"type": "string",
"enum": ["none", "environment_variable", "provisioner_variable"],
"x-enum-varnames": [
"ParameterDestinationSchemeNone",
"ParameterDestinationSchemeEnvironmentVariable",
"ParameterDestinationSchemeProvisionerVariable"
]
},
"codersdk.ParameterSchema": {
"type": "object",
"properties": {
"allow_override_destination": {
"type": "boolean"
},
"allow_override_source": {
"type": "boolean"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"default_destination_scheme": {
"enum": ["none", "environment_variable", "provisioner_variable"],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
}
]
},
"default_refresh": {
"type": "string"
},
"default_source_scheme": {
"enum": ["none", "data"],
"allOf": [
{
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
}
]
},
"default_source_value": {
"type": "string"
},
"description": {
"type": "string"
},
"id": {
"type": "string",
"format": "uuid"
},
"job_id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string"
},
"redisplay_value": {
"type": "boolean"
},
"validation_condition": {
"type": "string"
},
"validation_contains": {
"description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.",
"type": "array",
"items": {
"type": "string"
}
},
"validation_error": {
"type": "string"
},
"validation_type_system": {
"type": "string"
},
"validation_value_type": {
"type": "string"
}
}
},
"codersdk.ParameterScope": {
"type": "string",
"enum": ["template", "workspace", "import_job"],
"x-enum-varnames": [
"ParameterTemplate",
"ParameterWorkspace",
"ParameterImportJob"
]
},
"codersdk.ParameterSourceScheme": {
"type": "string",
"enum": ["none", "data"],
"x-enum-varnames": [
"ParameterSourceSchemeNone",
"ParameterSourceSchemeData"
]
},
"codersdk.PatchTemplateVersionRequest": { "codersdk.PatchTemplateVersionRequest": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -8309,8 +7939,8 @@
}, },
"codersdk.TemplateVersionWarning": { "codersdk.TemplateVersionWarning": {
"type": "string", "type": "string",
"enum": ["DEPRECATED_PARAMETERS"], "enum": ["UNSUPPORTED_WORKSPACES"],
"x-enum-varnames": ["TemplateVersionWarningDeprecatedParameters"] "x-enum-varnames": ["TemplateVersionWarningUnsupportedWorkspaces"]
}, },
"codersdk.TokenConfig": { "codersdk.TokenConfig": {
"type": "object", "type": "object",
@ -9261,32 +8891,6 @@
} }
} }
}, },
"database.ParameterDestinationScheme": {
"type": "string",
"enum": ["none", "environment_variable", "provisioner_variable"],
"x-enum-varnames": [
"ParameterDestinationSchemeNone",
"ParameterDestinationSchemeEnvironmentVariable",
"ParameterDestinationSchemeProvisionerVariable"
]
},
"database.ParameterScope": {
"type": "string",
"enum": ["template", "import_job", "workspace"],
"x-enum-varnames": [
"ParameterScopeTemplate",
"ParameterScopeImportJob",
"ParameterScopeWorkspace"
]
},
"database.ParameterSourceScheme": {
"type": "string",
"enum": ["none", "data"],
"x-enum-varnames": [
"ParameterSourceSchemeNone",
"ParameterSourceSchemeData"
]
},
"derp.ServerInfoMessage": { "derp.ServerInfoMessage": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -9557,44 +9161,6 @@
} }
} }
}, },
"parameter.ComputedValue": {
"type": "object",
"properties": {
"created_at": {
"type": "string"
},
"default_source_value": {
"type": "boolean"
},
"destination_scheme": {
"$ref": "#/definitions/database.ParameterDestinationScheme"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"schema_id": {
"type": "string"
},
"scope": {
"$ref": "#/definitions/database.ParameterScope"
},
"scope_id": {
"type": "string"
},
"source_scheme": {
"$ref": "#/definitions/database.ParameterSourceScheme"
},
"source_value": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"sql.NullTime": { "sql.NullTime": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -551,14 +551,6 @@ func New(options *Options) *API {
}) })
}) })
}) })
r.Route("/parameters/{scope}/{id}", func(r chi.Router) {
r.Use(apiKeyMiddleware)
r.Post("/", api.postParameter)
r.Get("/", api.parameters)
r.Route("/{name}", func(r chi.Router) {
r.Delete("/", api.deleteParameter)
})
})
r.Route("/templates/{template}", func(r chi.Router) { r.Route("/templates/{template}", func(r chi.Router) {
r.Use( r.Use(
apiKeyMiddleware, apiKeyMiddleware,
@ -582,8 +574,10 @@ func New(options *Options) *API {
r.Get("/", api.templateVersion) r.Get("/", api.templateVersion)
r.Patch("/", api.patchTemplateVersion) r.Patch("/", api.patchTemplateVersion)
r.Patch("/cancel", api.patchCancelTemplateVersion) r.Patch("/cancel", api.patchCancelTemplateVersion)
r.Get("/schema", api.templateVersionSchema) // Old agents may expect a non-error response from /schema and /parameters endpoints.
r.Get("/parameters", api.templateVersionParameters) // The idea is to return an empty [], so that the coder CLI won't get blocked accidentally.
r.Get("/schema", templateVersionSchemaDeprecated)
r.Get("/parameters", templateVersionParametersDeprecated)
r.Get("/rich-parameters", api.templateVersionRichParameters) r.Get("/rich-parameters", api.templateVersionRichParameters)
r.Get("/gitauth", api.templateVersionGitAuth) r.Get("/gitauth", api.templateVersionGitAuth)
r.Get("/variables", api.templateVersionVariables) r.Get("/variables", api.templateVersionVariables)

View File

@ -356,6 +356,6 @@ func assertProduce(t *testing.T, comment SwaggerComment) {
return // Exception: HTTP 200 is returned without response entity return // Exception: HTTP 200 is returned without response entity
} }
assert.True(t, comment.produce == "", "Response model is undefined, so we can't predict the content type", comment) assert.Truef(t, comment.produce == "", "Response model is undefined, so we can't predict the content type: %v", comment)
} }
} }

View File

@ -77,28 +77,6 @@ func TemplateVersionParameter(param database.TemplateVersionParameter) (codersdk
}, nil }, nil
} }
func Parameters(params []database.ParameterValue) []codersdk.Parameter {
out := make([]codersdk.Parameter, len(params))
for i, p := range params {
out[i] = Parameter(p)
}
return out
}
func Parameter(parameterValue database.ParameterValue) codersdk.Parameter {
return codersdk.Parameter{
ID: parameterValue.ID,
CreatedAt: parameterValue.CreatedAt,
UpdatedAt: parameterValue.UpdatedAt,
Scope: codersdk.ParameterScope(parameterValue.Scope),
ScopeID: parameterValue.ScopeID,
Name: parameterValue.Name,
SourceScheme: codersdk.ParameterSourceScheme(parameterValue.SourceScheme),
DestinationScheme: codersdk.ParameterDestinationScheme(parameterValue.DestinationScheme),
SourceValue: parameterValue.SourceValue,
}
}
func ProvisionerJobStatus(provisionerJob database.ProvisionerJob) codersdk.ProvisionerJobStatus { func ProvisionerJobStatus(provisionerJob database.ProvisionerJob) codersdk.ProvisionerJobStatus {
switch { switch {
case provisionerJob.CanceledAt.Valid: case provisionerJob.CanceledAt.Valid:

View File

@ -526,100 +526,6 @@ func (q *querier) canAssignRoles(ctx context.Context, orgID *uuid.UUID, added, r
return nil return nil
} }
func (q *querier) parameterRBACResource(ctx context.Context, scope database.ParameterScope, scopeID uuid.UUID) (rbac.Objecter, error) {
var resource rbac.Objecter
var err error
switch scope {
case database.ParameterScopeWorkspace:
return q.db.GetWorkspaceByID(ctx, scopeID)
case database.ParameterScopeImportJob:
var version database.TemplateVersion
version, err = q.db.GetTemplateVersionByJobID(ctx, scopeID)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, err
}
resource = version.RBACObjectNoTemplate()
var template database.Template
template, err = q.db.GetTemplateByID(ctx, version.TemplateID.UUID)
if err == nil {
resource = version.RBACObject(template)
} else if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
return nil, err
}
return resource, nil
case database.ParameterScopeTemplate:
return q.db.GetTemplateByID(ctx, scopeID)
default:
return nil, xerrors.Errorf("Parameter scope %q unsupported", scope)
}
}
func (q *querier) InsertParameterValue(ctx context.Context, arg database.InsertParameterValueParams) (database.ParameterValue, error) {
resource, err := q.parameterRBACResource(ctx, arg.Scope, arg.ScopeID)
if err != nil {
return database.ParameterValue{}, err
}
err = q.authorizeContext(ctx, rbac.ActionUpdate, resource)
if err != nil {
return database.ParameterValue{}, err
}
return q.db.InsertParameterValue(ctx, arg)
}
func (q *querier) ParameterValue(ctx context.Context, id uuid.UUID) (database.ParameterValue, error) {
parameter, err := q.db.ParameterValue(ctx, id)
if err != nil {
return database.ParameterValue{}, err
}
resource, err := q.parameterRBACResource(ctx, parameter.Scope, parameter.ScopeID)
if err != nil {
return database.ParameterValue{}, err
}
err = q.authorizeContext(ctx, rbac.ActionRead, resource)
if err != nil {
return database.ParameterValue{}, err
}
return parameter, nil
}
// ParameterValues is implemented as an all or nothing query. If the user is not
// able to read a single parameter value, then the entire query is denied.
// This should likely be revisited and see if the usage of this function cannot be changed.
func (q *querier) ParameterValues(ctx context.Context, arg database.ParameterValuesParams) ([]database.ParameterValue, error) {
// This is a bit of a special case. Each parameter value returned might have a different scope. This could likely
// be implemented in a more efficient manner.
values, err := q.db.ParameterValues(ctx, arg)
if err != nil {
return nil, err
}
cached := make(map[uuid.UUID]bool)
for _, value := range values {
// If we already checked this scopeID, then we can skip it.
// All scope ids are uuids of objects and universally unique.
if allowed := cached[value.ScopeID]; allowed {
continue
}
rbacObj, err := q.parameterRBACResource(ctx, value.Scope, value.ScopeID)
if err != nil {
return nil, err
}
err = q.authorizeContext(ctx, rbac.ActionRead, rbacObj)
if err != nil {
return nil, err
}
cached[value.ScopeID] = true
}
return values, nil
}
func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]database.ParameterSchema, error) { func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]database.ParameterSchema, error) {
version, err := q.db.GetTemplateVersionByJobID(ctx, jobID) version, err := q.db.GetTemplateVersionByJobID(ctx, jobID)
if err != nil { if err != nil {
@ -641,40 +547,6 @@ func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUI
return q.db.GetParameterSchemasByJobID(ctx, jobID) return q.db.GetParameterSchemasByJobID(ctx, jobID)
} }
func (q *querier) GetParameterValueByScopeAndName(ctx context.Context, arg database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
resource, err := q.parameterRBACResource(ctx, arg.Scope, arg.ScopeID)
if err != nil {
return database.ParameterValue{}, err
}
err = q.authorizeContext(ctx, rbac.ActionRead, resource)
if err != nil {
return database.ParameterValue{}, err
}
return q.db.GetParameterValueByScopeAndName(ctx, arg)
}
func (q *querier) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
parameter, err := q.db.ParameterValue(ctx, id)
if err != nil {
return err
}
resource, err := q.parameterRBACResource(ctx, parameter.Scope, parameter.ScopeID)
if err != nil {
return err
}
// A deleted param is still updating the underlying resource for the scope.
err = q.authorizeContext(ctx, rbac.ActionUpdate, resource)
if err != nil {
return err
}
return q.db.DeleteParameterValueByID(ctx, id)
}
func (q *querier) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) { func (q *querier) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
// An actor can read the previous template version if they can read the related template. // An actor can read the previous template version if they can read the related template.
// If no linked template exists, we check if the actor can read *a* template. // If no linked template exists, we check if the actor can read *a* template.

View File

@ -468,106 +468,6 @@ func (s *MethodTestSuite) TestWorkspaceProxy() {
})) }))
} }
func (s *MethodTestSuite) TestParameters() {
s.Run("Workspace/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
w := dbgen.Workspace(s.T(), db, database.Workspace{})
check.Args(database.InsertParameterValueParams{
ScopeID: w.ID,
Scope: database.ParameterScopeWorkspace,
SourceScheme: database.ParameterSourceSchemeNone,
DestinationScheme: database.ParameterDestinationSchemeNone,
}).Asserts(w, rbac.ActionUpdate)
}))
s.Run("TemplateVersionNoTemplate/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{JobID: j.ID, TemplateID: uuid.NullUUID{Valid: false}})
check.Args(database.InsertParameterValueParams{
ScopeID: j.ID,
Scope: database.ParameterScopeImportJob,
SourceScheme: database.ParameterSourceSchemeNone,
DestinationScheme: database.ParameterDestinationSchemeNone,
}).Asserts(v.RBACObjectNoTemplate(), rbac.ActionUpdate)
}))
s.Run("TemplateVersionTemplate/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
tpl := dbgen.Template(s.T(), db, database.Template{})
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
JobID: j.ID,
TemplateID: uuid.NullUUID{
UUID: tpl.ID,
Valid: true,
},
},
)
check.Args(database.InsertParameterValueParams{
ScopeID: j.ID,
Scope: database.ParameterScopeImportJob,
SourceScheme: database.ParameterSourceSchemeNone,
DestinationScheme: database.ParameterDestinationSchemeNone,
}).Asserts(v.RBACObject(tpl), rbac.ActionUpdate)
}))
s.Run("Template/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
tpl := dbgen.Template(s.T(), db, database.Template{})
check.Args(database.InsertParameterValueParams{
ScopeID: tpl.ID,
Scope: database.ParameterScopeTemplate,
SourceScheme: database.ParameterSourceSchemeNone,
DestinationScheme: database.ParameterDestinationSchemeNone,
}).Asserts(tpl, rbac.ActionUpdate)
}))
s.Run("Template/ParameterValue", s.Subtest(func(db database.Store, check *expects) {
tpl := dbgen.Template(s.T(), db, database.Template{})
pv := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
ScopeID: tpl.ID,
Scope: database.ParameterScopeTemplate,
})
check.Args(pv.ID).Asserts(tpl, rbac.ActionRead).Returns(pv)
}))
s.Run("ParameterValues", s.Subtest(func(db database.Store, check *expects) {
tpl := dbgen.Template(s.T(), db, database.Template{})
a := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
ScopeID: tpl.ID,
Scope: database.ParameterScopeTemplate,
})
w := dbgen.Workspace(s.T(), db, database.Workspace{})
b := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
ScopeID: w.ID,
Scope: database.ParameterScopeWorkspace,
})
check.Args(database.ParameterValuesParams{
IDs: []uuid.UUID{a.ID, b.ID},
}).Asserts(tpl, rbac.ActionRead, w, rbac.ActionRead).Returns(slice.New(a, b))
}))
s.Run("GetParameterSchemasByJobID", s.Subtest(func(db database.Store, check *expects) {
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
tpl := dbgen.Template(s.T(), db, database.Template{})
tv := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{JobID: j.ID, TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true}})
a := dbgen.ParameterSchema(s.T(), db, database.ParameterSchema{JobID: j.ID})
check.Args(j.ID).Asserts(tv.RBACObject(tpl), rbac.ActionRead).
Returns([]database.ParameterSchema{a})
}))
s.Run("Workspace/GetParameterValueByScopeAndName", s.Subtest(func(db database.Store, check *expects) {
w := dbgen.Workspace(s.T(), db, database.Workspace{})
v := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
Scope: database.ParameterScopeWorkspace,
ScopeID: w.ID,
})
check.Args(database.GetParameterValueByScopeAndNameParams{
Scope: v.Scope,
ScopeID: v.ScopeID,
Name: v.Name,
}).Asserts(w, rbac.ActionRead).Returns(v)
}))
s.Run("Workspace/DeleteParameterValueByID", s.Subtest(func(db database.Store, check *expects) {
w := dbgen.Workspace(s.T(), db, database.Workspace{})
v := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
Scope: database.ParameterScopeWorkspace,
ScopeID: w.ID,
})
check.Args(v.ID).Asserts(w, rbac.ActionUpdate).Returns()
}))
}
func (s *MethodTestSuite) TestTemplate() { func (s *MethodTestSuite) TestTemplate() {
s.Run("GetPreviousTemplateVersion", s.Subtest(func(db database.Store, check *expects) { s.Run("GetPreviousTemplateVersion", s.Subtest(func(db database.Store, check *expects) {
tvid := uuid.New() tvid := uuid.New()

View File

@ -314,13 +314,6 @@ func (q *querier) GetWorkspacesEligibleForAutoStartStop(ctx context.Context, now
return q.db.GetWorkspacesEligibleForAutoStartStop(ctx, now) return q.db.GetWorkspacesEligibleForAutoStartStop(ctx, now)
} }
func (q *querier) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ParameterSchema, error) {
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
return nil, err
}
return q.db.GetParameterSchemasCreatedAfter(ctx, createdAt)
}
// TODO: We need to create a ProvisionerJob resource type // TODO: We need to create a ProvisionerJob resource type
func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ProvisionerJob, error) { func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ProvisionerJob, error) {
// if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil { // if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
@ -432,13 +425,6 @@ func (q *querier) InsertWorkspaceResource(ctx context.Context, arg database.Inse
return q.db.InsertWorkspaceResource(ctx, arg) return q.db.InsertWorkspaceResource(ctx, arg)
} }
func (q *querier) InsertParameterSchema(ctx context.Context, arg database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
return database.ParameterSchema{}, err
}
return q.db.InsertParameterSchema(ctx, arg)
}
func (q *querier) GetWorkspaceProxyByHostname(ctx context.Context, params database.GetWorkspaceProxyByHostnameParams) (database.WorkspaceProxy, error) { func (q *querier) GetWorkspaceProxyByHostname(ctx context.Context, params database.GetWorkspaceProxyByHostnameParams) (database.WorkspaceProxy, error) {
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil { if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
return database.WorkspaceProxy{}, err return database.WorkspaceProxy{}, err

View File

@ -133,10 +133,6 @@ func (s *MethodTestSuite) TestSystemFunctions() {
s.Run("DeleteOldWorkspaceAgentStats", s.Subtest(func(db database.Store, check *expects) { s.Run("DeleteOldWorkspaceAgentStats", s.Subtest(func(db database.Store, check *expects) {
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionDelete) check.Args().Asserts(rbac.ResourceSystem, rbac.ActionDelete)
})) }))
s.Run("GetParameterSchemasCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
_ = dbgen.ParameterSchema(s.T(), db, database.ParameterSchema{CreatedAt: time.Now().Add(-time.Hour)})
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
}))
s.Run("GetProvisionerJobsCreatedAfter", s.Subtest(func(db database.Store, check *expects) { s.Run("GetProvisionerJobsCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
// TODO: add provisioner job resource type // TODO: add provisioner job resource type
_ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{CreatedAt: time.Now().Add(-time.Hour)}) _ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{CreatedAt: time.Now().Add(-time.Hour)})
@ -297,12 +293,4 @@ func (s *MethodTestSuite) TestSystemFunctions() {
Transition: database.WorkspaceTransitionStart, Transition: database.WorkspaceTransitionStart,
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate) }).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
})) }))
s.Run("InsertParameterSchema", s.Subtest(func(db database.Store, check *expects) {
check.Args(database.InsertParameterSchemaParams{
ID: uuid.New(),
DefaultSourceScheme: database.ParameterSourceSchemeNone,
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
ValidationTypeSystem: database.ParameterTypeSystemNone,
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
}))
} }

View File

@ -55,7 +55,6 @@ func New() database.Store {
files: make([]database.File, 0), files: make([]database.File, 0),
gitSSHKey: make([]database.GitSSHKey, 0), gitSSHKey: make([]database.GitSSHKey, 0),
parameterSchemas: make([]database.ParameterSchema, 0), parameterSchemas: make([]database.ParameterSchema, 0),
parameterValues: make([]database.ParameterValue, 0),
provisionerDaemons: make([]database.ProvisionerDaemon, 0), provisionerDaemons: make([]database.ProvisionerDaemon, 0),
workspaceAgents: make([]database.WorkspaceAgent, 0), workspaceAgents: make([]database.WorkspaceAgent, 0),
provisionerJobLogs: make([]database.ProvisionerJobLog, 0), provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
@ -124,7 +123,6 @@ type data struct {
groups []database.Group groups []database.Group
licenses []database.License licenses []database.License
parameterSchemas []database.ParameterSchema parameterSchemas []database.ParameterSchema
parameterValues []database.ParameterValue
provisionerDaemons []database.ProvisionerDaemon provisionerDaemons []database.ProvisionerDaemon
provisionerJobLogs []database.ProvisionerJobLog provisionerJobLogs []database.ProvisionerJobLog
provisionerJobs []database.ProvisionerJob provisionerJobs []database.ProvisionerJob
@ -575,34 +573,6 @@ func (q *fakeQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg datab
return row, nil return row, nil
} }
func (q *fakeQuerier) ParameterValue(_ context.Context, id uuid.UUID) (database.ParameterValue, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
for _, parameterValue := range q.parameterValues {
if parameterValue.ID != id {
continue
}
return parameterValue, nil
}
return database.ParameterValue{}, sql.ErrNoRows
}
func (q *fakeQuerier) DeleteParameterValueByID(_ context.Context, id uuid.UUID) error {
q.mutex.Lock()
defer q.mutex.Unlock()
for index, parameterValue := range q.parameterValues {
if parameterValue.ID != id {
continue
}
q.parameterValues[index] = q.parameterValues[len(q.parameterValues)-1]
q.parameterValues = q.parameterValues[:len(q.parameterValues)-1]
return nil
}
return sql.ErrNoRows
}
func (q *fakeQuerier) GetAPIKeyByID(_ context.Context, id string) (database.APIKey, error) { func (q *fakeQuerier) GetAPIKeyByID(_ context.Context, id string) (database.APIKey, error) {
q.mutex.RLock() q.mutex.RLock()
defer q.mutex.RUnlock() defer q.mutex.RUnlock()
@ -1893,40 +1863,6 @@ func (q *fakeQuerier) GetOrganizationsByUserID(_ context.Context, userID uuid.UU
return organizations, nil return organizations, nil
} }
func (q *fakeQuerier) ParameterValues(_ context.Context, arg database.ParameterValuesParams) ([]database.ParameterValue, error) {
if err := validateDatabaseType(arg); err != nil {
return nil, err
}
q.mutex.RLock()
defer q.mutex.RUnlock()
parameterValues := make([]database.ParameterValue, 0)
for _, parameterValue := range q.parameterValues {
if len(arg.Scopes) > 0 {
if !slice.Contains(arg.Scopes, parameterValue.Scope) {
continue
}
}
if len(arg.ScopeIds) > 0 {
if !slice.Contains(arg.ScopeIds, parameterValue.ScopeID) {
continue
}
}
if len(arg.IDs) > 0 {
if !slice.Contains(arg.IDs, parameterValue.ID) {
continue
}
}
parameterValues = append(parameterValues, parameterValue)
}
if len(parameterValues) == 0 {
return nil, sql.ErrNoRows
}
return parameterValues, nil
}
func (q *fakeQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (database.Template, error) { func (q *fakeQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (database.Template, error) {
q.mutex.RLock() q.mutex.RLock()
defer q.mutex.RUnlock() defer q.mutex.RUnlock()
@ -2329,42 +2265,6 @@ func (q *fakeQuerier) GetParameterSchemasByJobID(_ context.Context, jobID uuid.U
return parameters, nil return parameters, nil
} }
func (q *fakeQuerier) GetParameterSchemasCreatedAfter(_ context.Context, after time.Time) ([]database.ParameterSchema, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
parameters := make([]database.ParameterSchema, 0)
for _, parameterSchema := range q.parameterSchemas {
if parameterSchema.CreatedAt.After(after) {
parameters = append(parameters, parameterSchema)
}
}
return parameters, nil
}
func (q *fakeQuerier) GetParameterValueByScopeAndName(_ context.Context, arg database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
if err := validateDatabaseType(arg); err != nil {
return database.ParameterValue{}, err
}
q.mutex.RLock()
defer q.mutex.RUnlock()
for _, parameterValue := range q.parameterValues {
if parameterValue.Scope != arg.Scope {
continue
}
if parameterValue.ScopeID != arg.ScopeID {
continue
}
if parameterValue.Name != arg.Name {
continue
}
return parameterValue, nil
}
return database.ParameterValue{}, sql.ErrNoRows
}
func (q *fakeQuerier) GetTemplates(_ context.Context) ([]database.Template, error) { func (q *fakeQuerier) GetTemplates(_ context.Context) ([]database.Template, error) {
q.mutex.RLock() q.mutex.RLock()
defer q.mutex.RUnlock() defer q.mutex.RUnlock()
@ -2977,30 +2877,6 @@ func (q *fakeQuerier) InsertOrganizationMember(_ context.Context, arg database.I
return organizationMember, nil return organizationMember, nil
} }
func (q *fakeQuerier) InsertParameterValue(_ context.Context, arg database.InsertParameterValueParams) (database.ParameterValue, error) {
if err := validateDatabaseType(arg); err != nil {
return database.ParameterValue{}, err
}
q.mutex.Lock()
defer q.mutex.Unlock()
//nolint:gosimple
parameterValue := database.ParameterValue{
ID: arg.ID,
Name: arg.Name,
CreatedAt: arg.CreatedAt,
UpdatedAt: arg.UpdatedAt,
Scope: arg.Scope,
ScopeID: arg.ScopeID,
SourceScheme: arg.SourceScheme,
SourceValue: arg.SourceValue,
DestinationScheme: arg.DestinationScheme,
}
q.parameterValues = append(q.parameterValues, parameterValue)
return parameterValue, nil
}
func (q *fakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTemplateParams) (database.Template, error) { func (q *fakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTemplateParams) (database.Template, error) {
if err := validateDatabaseType(arg); err != nil { if err := validateDatabaseType(arg); err != nil {
return database.Template{}, err return database.Template{}, err
@ -3139,38 +3015,6 @@ func (q *fakeQuerier) InsertProvisionerJobLogs(_ context.Context, arg database.I
return logs, nil return logs, nil
} }
func (q *fakeQuerier) InsertParameterSchema(_ context.Context, arg database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
if err := validateDatabaseType(arg); err != nil {
return database.ParameterSchema{}, err
}
q.mutex.Lock()
defer q.mutex.Unlock()
//nolint:gosimple
param := database.ParameterSchema{
ID: arg.ID,
CreatedAt: arg.CreatedAt,
JobID: arg.JobID,
Name: arg.Name,
Description: arg.Description,
DefaultSourceScheme: arg.DefaultSourceScheme,
DefaultSourceValue: arg.DefaultSourceValue,
AllowOverrideSource: arg.AllowOverrideSource,
DefaultDestinationScheme: arg.DefaultDestinationScheme,
AllowOverrideDestination: arg.AllowOverrideDestination,
DefaultRefresh: arg.DefaultRefresh,
RedisplayValue: arg.RedisplayValue,
ValidationError: arg.ValidationError,
ValidationCondition: arg.ValidationCondition,
ValidationTypeSystem: arg.ValidationTypeSystem,
ValidationValueType: arg.ValidationValueType,
Index: arg.Index,
}
q.parameterSchemas = append(q.parameterSchemas, param)
return param, nil
}
func (q *fakeQuerier) InsertProvisionerDaemon(_ context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) { func (q *fakeQuerier) InsertProvisionerDaemon(_ context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
if err := validateDatabaseType(arg); err != nil { if err := validateDatabaseType(arg); err != nil {
return database.ProvisionerDaemon{}, err return database.ProvisionerDaemon{}, err

View File

@ -439,46 +439,6 @@ func TemplateVersionVariable(t testing.TB, db database.Store, orig database.Temp
return version return version
} }
func ParameterSchema(t testing.TB, db database.Store, seed database.ParameterSchema) database.ParameterSchema {
scheme, err := db.InsertParameterSchema(context.Background(), database.InsertParameterSchemaParams{
ID: takeFirst(seed.ID, uuid.New()),
JobID: takeFirst(seed.JobID, uuid.New()),
CreatedAt: takeFirst(seed.CreatedAt, database.Now()),
Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)),
Description: takeFirst(seed.Description, namesgenerator.GetRandomName(1)),
DefaultSourceScheme: takeFirst(seed.DefaultSourceScheme, database.ParameterSourceSchemeNone),
DefaultSourceValue: takeFirst(seed.DefaultSourceValue, ""),
AllowOverrideSource: takeFirst(seed.AllowOverrideSource, false),
DefaultDestinationScheme: takeFirst(seed.DefaultDestinationScheme, database.ParameterDestinationSchemeNone),
AllowOverrideDestination: takeFirst(seed.AllowOverrideDestination, false),
DefaultRefresh: takeFirst(seed.DefaultRefresh, ""),
RedisplayValue: takeFirst(seed.RedisplayValue, false),
ValidationError: takeFirst(seed.ValidationError, ""),
ValidationCondition: takeFirst(seed.ValidationCondition, ""),
ValidationTypeSystem: takeFirst(seed.ValidationTypeSystem, database.ParameterTypeSystemNone),
ValidationValueType: takeFirst(seed.ValidationValueType, ""),
Index: takeFirst(seed.Index, 1),
})
require.NoError(t, err, "insert parameter scheme")
return scheme
}
func ParameterValue(t testing.TB, db database.Store, seed database.ParameterValue) database.ParameterValue {
scheme, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
ID: takeFirst(seed.ID, uuid.New()),
Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)),
CreatedAt: takeFirst(seed.CreatedAt, database.Now()),
UpdatedAt: takeFirst(seed.UpdatedAt, database.Now()),
Scope: takeFirst(seed.Scope, database.ParameterScopeWorkspace),
ScopeID: takeFirst(seed.ScopeID, uuid.New()),
SourceScheme: takeFirst(seed.SourceScheme, database.ParameterSourceSchemeNone),
SourceValue: takeFirst(seed.SourceValue, ""),
DestinationScheme: takeFirst(seed.DestinationScheme, database.ParameterDestinationSchemeNone),
})
require.NoError(t, err, "insert parameter value")
return scheme
}
func WorkspaceAgentStat(t testing.TB, db database.Store, orig database.WorkspaceAgentStat) database.WorkspaceAgentStat { func WorkspaceAgentStat(t testing.TB, db database.Store, orig database.WorkspaceAgentStat) database.WorkspaceAgentStat {
if orig.ConnectionsByProto == nil { if orig.ConnectionsByProto == nil {
orig.ConnectionsByProto = json.RawMessage([]byte("{}")) orig.ConnectionsByProto = json.RawMessage([]byte("{}"))

View File

@ -153,24 +153,6 @@ func TestGenerator(t *testing.T) {
require.Equal(t, exp, must(db.GetTemplateVersionByID(context.Background(), exp.ID))) require.Equal(t, exp, must(db.GetTemplateVersionByID(context.Background(), exp.ID)))
}) })
t.Run("ParameterSchema", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
exp := dbgen.ParameterSchema(t, db, database.ParameterSchema{})
require.Equal(t, []database.ParameterSchema{exp}, must(db.GetParameterSchemasByJobID(context.Background(), exp.JobID)))
})
t.Run("ParameterValue", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
exp := dbgen.ParameterValue(t, db, database.ParameterValue{})
require.Equal(t, exp, must(db.GetParameterValueByScopeAndName(context.Background(), database.GetParameterValueByScopeAndNameParams{
Scope: exp.Scope,
ScopeID: exp.ScopeID,
Name: exp.Name,
})))
})
t.Run("WorkspaceBuild", func(t *testing.T) { t.Run("WorkspaceBuild", func(t *testing.T) {
t.Parallel() t.Parallel()
db := dbfake.New() db := dbfake.New()

View File

@ -154,13 +154,6 @@ func (m metricsStore) DeleteOldWorkspaceAgentStats(ctx context.Context) error {
return err return err
} }
func (m metricsStore) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
start := time.Now()
err := m.s.DeleteParameterValueByID(ctx, id)
m.queryLatencies.WithLabelValues("DeleteParameterValueByID").Observe(time.Since(start).Seconds())
return err
}
func (m metricsStore) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error { func (m metricsStore) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error {
start := time.Now() start := time.Now()
err := m.s.DeleteReplicasUpdatedBefore(ctx, updatedAt) err := m.s.DeleteReplicasUpdatedBefore(ctx, updatedAt)
@ -441,20 +434,6 @@ func (m metricsStore) GetParameterSchemasByJobID(ctx context.Context, jobID uuid
return schemas, err return schemas, err
} }
func (m metricsStore) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ParameterSchema, error) {
start := time.Now()
schemas, err := m.s.GetParameterSchemasCreatedAfter(ctx, createdAt)
m.queryLatencies.WithLabelValues("GetParameterSchemasCreatedAfter").Observe(time.Since(start).Seconds())
return schemas, err
}
func (m metricsStore) GetParameterValueByScopeAndName(ctx context.Context, arg database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
start := time.Now()
value, err := m.s.GetParameterValueByScopeAndName(ctx, arg)
m.queryLatencies.WithLabelValues("GetParameterValueByScopeAndName").Observe(time.Since(start).Seconds())
return value, err
}
func (m metricsStore) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) { func (m metricsStore) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
start := time.Now() start := time.Now()
version, err := m.s.GetPreviousTemplateVersion(ctx, arg) version, err := m.s.GetPreviousTemplateVersion(ctx, arg)
@ -1022,20 +1001,6 @@ func (m metricsStore) InsertOrganizationMember(ctx context.Context, arg database
return member, err return member, err
} }
func (m metricsStore) InsertParameterSchema(ctx context.Context, arg database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
start := time.Now()
schema, err := m.s.InsertParameterSchema(ctx, arg)
m.queryLatencies.WithLabelValues("InsertParameterSchema").Observe(time.Since(start).Seconds())
return schema, err
}
func (m metricsStore) InsertParameterValue(ctx context.Context, arg database.InsertParameterValueParams) (database.ParameterValue, error) {
start := time.Now()
value, err := m.s.InsertParameterValue(ctx, arg)
m.queryLatencies.WithLabelValues("InsertParameterValue").Observe(time.Since(start).Seconds())
return value, err
}
func (m metricsStore) InsertProvisionerDaemon(ctx context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) { func (m metricsStore) InsertProvisionerDaemon(ctx context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
start := time.Now() start := time.Now()
daemon, err := m.s.InsertProvisionerDaemon(ctx, arg) daemon, err := m.s.InsertProvisionerDaemon(ctx, arg)
@ -1190,20 +1155,6 @@ func (m metricsStore) InsertWorkspaceResourceMetadata(ctx context.Context, arg d
return metadata, err return metadata, err
} }
func (m metricsStore) ParameterValue(ctx context.Context, id uuid.UUID) (database.ParameterValue, error) {
start := time.Now()
value, err := m.s.ParameterValue(ctx, id)
m.queryLatencies.WithLabelValues("ParameterValue").Observe(time.Since(start).Seconds())
return value, err
}
func (m metricsStore) ParameterValues(ctx context.Context, arg database.ParameterValuesParams) ([]database.ParameterValue, error) {
start := time.Now()
values, err := m.s.ParameterValues(ctx, arg)
m.queryLatencies.WithLabelValues("ParameterValues").Observe(time.Since(start).Seconds())
return values, err
}
func (m metricsStore) RegisterWorkspaceProxy(ctx context.Context, arg database.RegisterWorkspaceProxyParams) (database.WorkspaceProxy, error) { func (m metricsStore) RegisterWorkspaceProxy(ctx context.Context, arg database.RegisterWorkspaceProxyParams) (database.WorkspaceProxy, error) {
start := time.Now() start := time.Now()
proxy, err := m.s.RegisterWorkspaceProxy(ctx, arg) proxy, err := m.s.RegisterWorkspaceProxy(ctx, arg)

View File

@ -209,20 +209,6 @@ func (mr *MockStoreMockRecorder) DeleteOldWorkspaceAgentStats(arg0 interface{})
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOldWorkspaceAgentStats", reflect.TypeOf((*MockStore)(nil).DeleteOldWorkspaceAgentStats), arg0) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOldWorkspaceAgentStats", reflect.TypeOf((*MockStore)(nil).DeleteOldWorkspaceAgentStats), arg0)
} }
// DeleteParameterValueByID mocks base method.
func (m *MockStore) DeleteParameterValueByID(arg0 context.Context, arg1 uuid.UUID) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteParameterValueByID", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteParameterValueByID indicates an expected call of DeleteParameterValueByID.
func (mr *MockStoreMockRecorder) DeleteParameterValueByID(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteParameterValueByID", reflect.TypeOf((*MockStore)(nil).DeleteParameterValueByID), arg0, arg1)
}
// DeleteReplicasUpdatedBefore mocks base method. // DeleteReplicasUpdatedBefore mocks base method.
func (m *MockStore) DeleteReplicasUpdatedBefore(arg0 context.Context, arg1 time.Time) error { func (m *MockStore) DeleteReplicasUpdatedBefore(arg0 context.Context, arg1 time.Time) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@ -867,36 +853,6 @@ func (mr *MockStoreMockRecorder) GetParameterSchemasByJobID(arg0, arg1 interface
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterSchemasByJobID", reflect.TypeOf((*MockStore)(nil).GetParameterSchemasByJobID), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterSchemasByJobID", reflect.TypeOf((*MockStore)(nil).GetParameterSchemasByJobID), arg0, arg1)
} }
// GetParameterSchemasCreatedAfter mocks base method.
func (m *MockStore) GetParameterSchemasCreatedAfter(arg0 context.Context, arg1 time.Time) ([]database.ParameterSchema, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetParameterSchemasCreatedAfter", arg0, arg1)
ret0, _ := ret[0].([]database.ParameterSchema)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetParameterSchemasCreatedAfter indicates an expected call of GetParameterSchemasCreatedAfter.
func (mr *MockStoreMockRecorder) GetParameterSchemasCreatedAfter(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterSchemasCreatedAfter", reflect.TypeOf((*MockStore)(nil).GetParameterSchemasCreatedAfter), arg0, arg1)
}
// GetParameterValueByScopeAndName mocks base method.
func (m *MockStore) GetParameterValueByScopeAndName(arg0 context.Context, arg1 database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetParameterValueByScopeAndName", arg0, arg1)
ret0, _ := ret[0].(database.ParameterValue)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetParameterValueByScopeAndName indicates an expected call of GetParameterValueByScopeAndName.
func (mr *MockStoreMockRecorder) GetParameterValueByScopeAndName(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterValueByScopeAndName", reflect.TypeOf((*MockStore)(nil).GetParameterValueByScopeAndName), arg0, arg1)
}
// GetPreviousTemplateVersion mocks base method. // GetPreviousTemplateVersion mocks base method.
func (m *MockStore) GetPreviousTemplateVersion(arg0 context.Context, arg1 database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) { func (m *MockStore) GetPreviousTemplateVersion(arg0 context.Context, arg1 database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@ -2153,36 +2109,6 @@ func (mr *MockStoreMockRecorder) InsertOrganizationMember(arg0, arg1 interface{}
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertOrganizationMember", reflect.TypeOf((*MockStore)(nil).InsertOrganizationMember), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertOrganizationMember", reflect.TypeOf((*MockStore)(nil).InsertOrganizationMember), arg0, arg1)
} }
// InsertParameterSchema mocks base method.
func (m *MockStore) InsertParameterSchema(arg0 context.Context, arg1 database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertParameterSchema", arg0, arg1)
ret0, _ := ret[0].(database.ParameterSchema)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertParameterSchema indicates an expected call of InsertParameterSchema.
func (mr *MockStoreMockRecorder) InsertParameterSchema(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertParameterSchema", reflect.TypeOf((*MockStore)(nil).InsertParameterSchema), arg0, arg1)
}
// InsertParameterValue mocks base method.
func (m *MockStore) InsertParameterValue(arg0 context.Context, arg1 database.InsertParameterValueParams) (database.ParameterValue, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertParameterValue", arg0, arg1)
ret0, _ := ret[0].(database.ParameterValue)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// InsertParameterValue indicates an expected call of InsertParameterValue.
func (mr *MockStoreMockRecorder) InsertParameterValue(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertParameterValue", reflect.TypeOf((*MockStore)(nil).InsertParameterValue), arg0, arg1)
}
// InsertProvisionerDaemon mocks base method. // InsertProvisionerDaemon mocks base method.
func (m *MockStore) InsertProvisionerDaemon(arg0 context.Context, arg1 database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) { func (m *MockStore) InsertProvisionerDaemon(arg0 context.Context, arg1 database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
@ -2510,36 +2436,6 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceResourceMetadata(arg0, arg1 inte
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceResourceMetadata", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceResourceMetadata), arg0, arg1) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceResourceMetadata", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceResourceMetadata), arg0, arg1)
} }
// ParameterValue mocks base method.
func (m *MockStore) ParameterValue(arg0 context.Context, arg1 uuid.UUID) (database.ParameterValue, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ParameterValue", arg0, arg1)
ret0, _ := ret[0].(database.ParameterValue)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ParameterValue indicates an expected call of ParameterValue.
func (mr *MockStoreMockRecorder) ParameterValue(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParameterValue", reflect.TypeOf((*MockStore)(nil).ParameterValue), arg0, arg1)
}
// ParameterValues mocks base method.
func (m *MockStore) ParameterValues(arg0 context.Context, arg1 database.ParameterValuesParams) ([]database.ParameterValue, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ParameterValues", arg0, arg1)
ret0, _ := ret[0].([]database.ParameterValue)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ParameterValues indicates an expected call of ParameterValues.
func (mr *MockStoreMockRecorder) ParameterValues(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParameterValues", reflect.TypeOf((*MockStore)(nil).ParameterValues), arg0, arg1)
}
// Ping mocks base method. // Ping mocks base method.
func (m *MockStore) Ping(arg0 context.Context) (time.Duration, error) { func (m *MockStore) Ping(arg0 context.Context) (time.Duration, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@ -38,7 +38,6 @@ type sqlcQuerier interface {
// Logs can take up a lot of space, so it's important we clean up frequently. // Logs can take up a lot of space, so it's important we clean up frequently.
DeleteOldWorkspaceAgentStartupLogs(ctx context.Context) error DeleteOldWorkspaceAgentStartupLogs(ctx context.Context) error
DeleteOldWorkspaceAgentStats(ctx context.Context) error DeleteOldWorkspaceAgentStats(ctx context.Context) error
DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error
DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error) GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
// there is no unique constraint on empty token names // there is no unique constraint on empty token names
@ -86,8 +85,6 @@ type sqlcQuerier interface {
GetOrganizations(ctx context.Context) ([]Organization, error) GetOrganizations(ctx context.Context) ([]Organization, error)
GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error) GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error)
GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error)
GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]ParameterSchema, error)
GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error)
GetPreviousTemplateVersion(ctx context.Context, arg GetPreviousTemplateVersionParams) (TemplateVersion, error) GetPreviousTemplateVersion(ctx context.Context, arg GetPreviousTemplateVersionParams) (TemplateVersion, error)
GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error) GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error)
GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error)
@ -183,8 +180,6 @@ type sqlcQuerier interface {
InsertLicense(ctx context.Context, arg InsertLicenseParams) (License, error) InsertLicense(ctx context.Context, arg InsertLicenseParams) (License, error)
InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error) InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error)
InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error) InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error)
InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error)
InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error)
InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error) InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error)
InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error) InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error)
InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error) InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error)
@ -208,8 +203,6 @@ type sqlcQuerier interface {
InsertWorkspaceProxy(ctx context.Context, arg InsertWorkspaceProxyParams) (WorkspaceProxy, error) InsertWorkspaceProxy(ctx context.Context, arg InsertWorkspaceProxyParams) (WorkspaceProxy, error)
InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error)
InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) ([]WorkspaceResourceMetadatum, error) InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) ([]WorkspaceResourceMetadatum, error)
ParameterValue(ctx context.Context, id uuid.UUID) (ParameterValue, error)
ParameterValues(ctx context.Context, arg ParameterValuesParams) ([]ParameterValue, error)
RegisterWorkspaceProxy(ctx context.Context, arg RegisterWorkspaceProxyParams) (WorkspaceProxy, error) RegisterWorkspaceProxy(ctx context.Context, arg RegisterWorkspaceProxyParams) (WorkspaceProxy, error)
// Non blocking lock. Returns true if the lock was acquired, false otherwise. // Non blocking lock. Returns true if the lock was acquired, false otherwise.
// //

View File

@ -1935,358 +1935,6 @@ func (q *sqlQuerier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.
return items, nil return items, nil
} }
const getParameterSchemasCreatedAfter = `-- name: GetParameterSchemasCreatedAfter :many
SELECT id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index FROM parameter_schemas WHERE created_at > $1
`
func (q *sqlQuerier) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]ParameterSchema, error) {
rows, err := q.db.QueryContext(ctx, getParameterSchemasCreatedAfter, createdAt)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ParameterSchema
for rows.Next() {
var i ParameterSchema
if err := rows.Scan(
&i.ID,
&i.CreatedAt,
&i.JobID,
&i.Name,
&i.Description,
&i.DefaultSourceScheme,
&i.DefaultSourceValue,
&i.AllowOverrideSource,
&i.DefaultDestinationScheme,
&i.AllowOverrideDestination,
&i.DefaultRefresh,
&i.RedisplayValue,
&i.ValidationError,
&i.ValidationCondition,
&i.ValidationTypeSystem,
&i.ValidationValueType,
&i.Index,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const insertParameterSchema = `-- name: InsertParameterSchema :one
INSERT INTO
parameter_schemas (
id,
created_at,
job_id,
"name",
description,
default_source_scheme,
default_source_value,
allow_override_source,
default_destination_scheme,
allow_override_destination,
default_refresh,
redisplay_value,
validation_error,
validation_condition,
validation_type_system,
validation_value_type,
index
)
VALUES
(
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12,
$13,
$14,
$15,
$16,
$17
) RETURNING id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index
`
type InsertParameterSchemaParams struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
JobID uuid.UUID `db:"job_id" json:"job_id"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
DefaultSourceScheme ParameterSourceScheme `db:"default_source_scheme" json:"default_source_scheme"`
DefaultSourceValue string `db:"default_source_value" json:"default_source_value"`
AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"`
DefaultDestinationScheme ParameterDestinationScheme `db:"default_destination_scheme" json:"default_destination_scheme"`
AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"`
DefaultRefresh string `db:"default_refresh" json:"default_refresh"`
RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"`
ValidationError string `db:"validation_error" json:"validation_error"`
ValidationCondition string `db:"validation_condition" json:"validation_condition"`
ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"`
ValidationValueType string `db:"validation_value_type" json:"validation_value_type"`
Index int32 `db:"index" json:"index"`
}
func (q *sqlQuerier) InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error) {
row := q.db.QueryRowContext(ctx, insertParameterSchema,
arg.ID,
arg.CreatedAt,
arg.JobID,
arg.Name,
arg.Description,
arg.DefaultSourceScheme,
arg.DefaultSourceValue,
arg.AllowOverrideSource,
arg.DefaultDestinationScheme,
arg.AllowOverrideDestination,
arg.DefaultRefresh,
arg.RedisplayValue,
arg.ValidationError,
arg.ValidationCondition,
arg.ValidationTypeSystem,
arg.ValidationValueType,
arg.Index,
)
var i ParameterSchema
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.JobID,
&i.Name,
&i.Description,
&i.DefaultSourceScheme,
&i.DefaultSourceValue,
&i.AllowOverrideSource,
&i.DefaultDestinationScheme,
&i.AllowOverrideDestination,
&i.DefaultRefresh,
&i.RedisplayValue,
&i.ValidationError,
&i.ValidationCondition,
&i.ValidationTypeSystem,
&i.ValidationValueType,
&i.Index,
)
return i, err
}
const deleteParameterValueByID = `-- name: DeleteParameterValueByID :exec
DELETE FROM
parameter_values
WHERE
id = $1
`
func (q *sqlQuerier) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
_, err := q.db.ExecContext(ctx, deleteParameterValueByID, id)
return err
}
const getParameterValueByScopeAndName = `-- name: GetParameterValueByScopeAndName :one
SELECT
id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
FROM
parameter_values
WHERE
scope = $1
AND scope_id = $2
AND NAME = $3
LIMIT
1
`
type GetParameterValueByScopeAndNameParams struct {
Scope ParameterScope `db:"scope" json:"scope"`
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
Name string `db:"name" json:"name"`
}
func (q *sqlQuerier) GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error) {
row := q.db.QueryRowContext(ctx, getParameterValueByScopeAndName, arg.Scope, arg.ScopeID, arg.Name)
var i ParameterValue
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.Scope,
&i.ScopeID,
&i.Name,
&i.SourceScheme,
&i.SourceValue,
&i.DestinationScheme,
)
return i, err
}
const insertParameterValue = `-- name: InsertParameterValue :one
INSERT INTO
parameter_values (
id,
"name",
created_at,
updated_at,
scope,
scope_id,
source_scheme,
source_value,
destination_scheme
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
`
type InsertParameterValueParams struct {
ID uuid.UUID `db:"id" json:"id"`
Name string `db:"name" json:"name"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Scope ParameterScope `db:"scope" json:"scope"`
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
SourceScheme ParameterSourceScheme `db:"source_scheme" json:"source_scheme"`
SourceValue string `db:"source_value" json:"source_value"`
DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"`
}
func (q *sqlQuerier) InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error) {
row := q.db.QueryRowContext(ctx, insertParameterValue,
arg.ID,
arg.Name,
arg.CreatedAt,
arg.UpdatedAt,
arg.Scope,
arg.ScopeID,
arg.SourceScheme,
arg.SourceValue,
arg.DestinationScheme,
)
var i ParameterValue
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.Scope,
&i.ScopeID,
&i.Name,
&i.SourceScheme,
&i.SourceValue,
&i.DestinationScheme,
)
return i, err
}
const parameterValue = `-- name: ParameterValue :one
SELECT id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme FROM
parameter_values
WHERE
id = $1
`
func (q *sqlQuerier) ParameterValue(ctx context.Context, id uuid.UUID) (ParameterValue, error) {
row := q.db.QueryRowContext(ctx, parameterValue, id)
var i ParameterValue
err := row.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.Scope,
&i.ScopeID,
&i.Name,
&i.SourceScheme,
&i.SourceValue,
&i.DestinationScheme,
)
return i, err
}
const parameterValues = `-- name: ParameterValues :many
SELECT
id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
FROM
parameter_values
WHERE
CASE
WHEN cardinality($1 :: parameter_scope[]) > 0 THEN
scope = ANY($1 :: parameter_scope[])
ELSE true
END
AND CASE
WHEN cardinality($2 :: uuid[]) > 0 THEN
scope_id = ANY($2 :: uuid[])
ELSE true
END
AND CASE
WHEN cardinality($3 :: uuid[]) > 0 THEN
id = ANY($3 :: uuid[])
ELSE true
END
AND CASE
WHEN cardinality($4 :: text[]) > 0 THEN
"name" = ANY($4 :: text[])
ELSE true
END
`
type ParameterValuesParams struct {
Scopes []ParameterScope `db:"scopes" json:"scopes"`
ScopeIds []uuid.UUID `db:"scope_ids" json:"scope_ids"`
IDs []uuid.UUID `db:"ids" json:"ids"`
Names []string `db:"names" json:"names"`
}
func (q *sqlQuerier) ParameterValues(ctx context.Context, arg ParameterValuesParams) ([]ParameterValue, error) {
rows, err := q.db.QueryContext(ctx, parameterValues,
pq.Array(arg.Scopes),
pq.Array(arg.ScopeIds),
pq.Array(arg.IDs),
pq.Array(arg.Names),
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ParameterValue
for rows.Next() {
var i ParameterValue
if err := rows.Scan(
&i.ID,
&i.CreatedAt,
&i.UpdatedAt,
&i.Scope,
&i.ScopeID,
&i.Name,
&i.SourceScheme,
&i.SourceValue,
&i.DestinationScheme,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getProvisionerDaemons = `-- name: GetProvisionerDaemons :many const getProvisionerDaemons = `-- name: GetProvisionerDaemons :many
SELECT SELECT
id, created_at, updated_at, name, provisioners, replica_id, tags id, created_at, updated_at, name, provisioners, replica_id, tags

View File

@ -7,48 +7,3 @@ WHERE
job_id = $1 job_id = $1
ORDER BY ORDER BY
index; index;
-- name: GetParameterSchemasCreatedAfter :many
SELECT * FROM parameter_schemas WHERE created_at > $1;
-- name: InsertParameterSchema :one
INSERT INTO
parameter_schemas (
id,
created_at,
job_id,
"name",
description,
default_source_scheme,
default_source_value,
allow_override_source,
default_destination_scheme,
allow_override_destination,
default_refresh,
redisplay_value,
validation_error,
validation_condition,
validation_type_system,
validation_value_type,
index
)
VALUES
(
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10,
$11,
$12,
$13,
$14,
$15,
$16,
$17
) RETURNING *;

View File

@ -1,68 +0,0 @@
-- name: ParameterValue :one
SELECT * FROM
parameter_values
WHERE
id = $1;
-- name: DeleteParameterValueByID :exec
DELETE FROM
parameter_values
WHERE
id = $1;
-- name: ParameterValues :many
SELECT
*
FROM
parameter_values
WHERE
CASE
WHEN cardinality(@scopes :: parameter_scope[]) > 0 THEN
scope = ANY(@scopes :: parameter_scope[])
ELSE true
END
AND CASE
WHEN cardinality(@scope_ids :: uuid[]) > 0 THEN
scope_id = ANY(@scope_ids :: uuid[])
ELSE true
END
AND CASE
WHEN cardinality(@ids :: uuid[]) > 0 THEN
id = ANY(@ids :: uuid[])
ELSE true
END
AND CASE
WHEN cardinality(@names :: text[]) > 0 THEN
"name" = ANY(@names :: text[])
ELSE true
END
;
-- name: GetParameterValueByScopeAndName :one
SELECT
*
FROM
parameter_values
WHERE
scope = $1
AND scope_id = $2
AND NAME = $3
LIMIT
1;
-- name: InsertParameterValue :one
INSERT INTO
parameter_values (
id,
"name",
created_at,
updated_at,
scope,
scope_id,
source_scheme,
source_value,
destination_scheme
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING *;

29
coderd/deprecated.go Normal file
View File

@ -0,0 +1,29 @@
package coderd
import (
"net/http"
"github.com/coder/coder/coderd/httpapi"
)
// @Summary Removed: Get parameters by template version
// @ID removed-get-parameters-by-template-version
// @Security CoderSessionToken
// @Tags Templates
// @Param templateversion path string true "Template version ID" format(uuid)
// @Success 200
// @Router /templateversions/{templateversion}/parameters [get]
func templateVersionParametersDeprecated(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(r.Context(), rw, http.StatusOK, []struct{}{})
}
// @Summary Removed: Get schema by template version
// @ID removed-get-schema-by-template-version
// @Security CoderSessionToken
// @Tags Templates
// @Param templateversion path string true "Template version ID" format(uuid)
// @Success 200
// @Router /templateversions/{templateversion}/schema [get]
func templateVersionSchemaDeprecated(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(r.Context(), rw, http.StatusOK, []struct{}{})
}

View File

@ -1,204 +0,0 @@
package parameter
import (
"context"
"database/sql"
"errors"
"github.com/google/uuid"
"golang.org/x/exp/slices"
"golang.org/x/xerrors"
"github.com/coder/coder/coderd/database"
)
// ComputeScope targets identifiers to pull parameters from.
type ComputeScope struct {
TemplateImportJobID uuid.UUID
TemplateID uuid.NullUUID
WorkspaceID uuid.NullUUID
AdditionalParameterValues []database.ParameterValue
}
type ComputeOptions struct {
// HideRedisplayValues removes the value from parameters that
// come from schemas with RedisplayValue set to false.
HideRedisplayValues bool
}
// ComputedValue represents a computed parameter value.
type ComputedValue struct {
database.ParameterValue
SchemaID uuid.UUID `json:"schema_id"`
DefaultSourceValue bool `json:"default_source_value"`
index int32 // Track parameter schema index for sorting.
}
// Compute accepts a scope in which parameter values are sourced.
// These sources are iterated in a hierarchical fashion to determine
// the runtime parameter values for schemas provided.
func Compute(ctx context.Context, db database.Store, scope ComputeScope, options *ComputeOptions) ([]ComputedValue, error) {
if options == nil {
options = &ComputeOptions{}
}
compute := &compute{
options: options,
db: db,
computedParameterByName: map[string]ComputedValue{},
parameterSchemasByName: map[string]database.ParameterSchema{},
}
// All parameters for the import job ID!
parameterSchemas, err := db.GetParameterSchemasByJobID(ctx, scope.TemplateImportJobID)
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
return nil, xerrors.Errorf("get template parameters: %w", err)
}
for _, parameterSchema := range parameterSchemas {
compute.parameterSchemasByName[parameterSchema.Name] = parameterSchema
}
// Job parameters come second!
err = compute.injectScope(ctx, database.ParameterValuesParams{
Scopes: []database.ParameterScope{database.ParameterScopeImportJob},
ScopeIds: []uuid.UUID{scope.TemplateImportJobID},
})
if err != nil {
return nil, err
}
// Default template parameter values come second!
for _, parameterSchema := range parameterSchemas {
if parameterSchema.DefaultSourceScheme == database.ParameterSourceSchemeNone {
continue
}
if _, ok := compute.computedParameterByName[parameterSchema.Name]; ok {
// We already have a value! No need to use the default.
continue
}
switch parameterSchema.DefaultSourceScheme {
case database.ParameterSourceSchemeData:
// Inject a default value scoped to the import job ID.
// This doesn't need to be inserted into the database,
// because it's a dynamic value associated with the schema.
err = compute.injectSingle(database.ParameterValue{
ID: uuid.New(),
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
SourceScheme: database.ParameterSourceSchemeData,
Name: parameterSchema.Name,
DestinationScheme: parameterSchema.DefaultDestinationScheme,
SourceValue: parameterSchema.DefaultSourceValue,
Scope: database.ParameterScopeImportJob,
ScopeID: scope.TemplateImportJobID,
}, true)
if err != nil {
return nil, xerrors.Errorf("insert default value: %w", err)
}
default:
return nil, xerrors.Errorf("unsupported source scheme for template version parameter %q: %q", parameterSchema.Name, string(parameterSchema.DefaultSourceScheme))
}
}
if scope.TemplateID.Valid {
// Template parameters come third!
err = compute.injectScope(ctx, database.ParameterValuesParams{
Scopes: []database.ParameterScope{database.ParameterScopeTemplate},
ScopeIds: []uuid.UUID{scope.TemplateID.UUID},
})
if err != nil {
return nil, err
}
}
if scope.WorkspaceID.Valid {
// Workspace parameters come last!
err = compute.injectScope(ctx, database.ParameterValuesParams{
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
ScopeIds: []uuid.UUID{scope.WorkspaceID.UUID},
})
if err != nil {
return nil, err
}
}
// Finally, any additional parameter values declared in the input
for _, v := range scope.AdditionalParameterValues {
err = compute.injectSingle(v, false)
if err != nil {
return nil, xerrors.Errorf("inject single parameter value: %w", err)
}
}
values := make([]ComputedValue, 0, len(compute.computedParameterByName))
for _, value := range compute.computedParameterByName {
values = append(values, value)
}
slices.SortFunc(values, func(a, b ComputedValue) bool {
return a.index < b.index
})
return values, nil
}
type compute struct {
options *ComputeOptions
db database.Store
computedParameterByName map[string]ComputedValue
parameterSchemasByName map[string]database.ParameterSchema
}
// Validates and computes the value for parameters; setting the value on "parameterByName".
func (c *compute) injectScope(ctx context.Context, scopeParams database.ParameterValuesParams) error {
scopedParameters, err := c.db.ParameterValues(ctx, scopeParams)
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
return xerrors.Errorf("get %s parameters: %w", scopeParams.Scopes, err)
}
for _, scopedParameter := range scopedParameters {
err = c.injectSingle(scopedParameter, false)
if err != nil {
return xerrors.Errorf("inject single %q: %w", scopedParameter.Name, err)
}
}
return nil
}
func (c *compute) injectSingle(scopedParameter database.ParameterValue, defaultValue bool) error {
parameterSchema, hasParameterSchema := c.parameterSchemasByName[scopedParameter.Name]
if !hasParameterSchema {
// Don't inject parameters that aren't defined by the template.
return nil
}
_, hasParameterValue := c.computedParameterByName[scopedParameter.Name]
if hasParameterValue {
if !parameterSchema.AllowOverrideSource &&
// Workspaces cannot override anything on a template!
scopedParameter.Scope == database.ParameterScopeWorkspace {
return nil
}
}
switch scopedParameter.SourceScheme {
case database.ParameterSourceSchemeData:
value := ComputedValue{
ParameterValue: scopedParameter,
SchemaID: parameterSchema.ID,
DefaultSourceValue: defaultValue,
index: parameterSchema.Index,
}
if c.options.HideRedisplayValues && !parameterSchema.RedisplayValue {
value.SourceValue = ""
}
c.computedParameterByName[scopedParameter.Name] = value
default:
return xerrors.Errorf("unsupported source scheme: %q", string(parameterSchema.DefaultSourceScheme))
}
return nil
}

View File

@ -1,173 +0,0 @@
package parameter_test
import (
"context"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/database/dbfake"
"github.com/coder/coder/coderd/database/dbgen"
"github.com/coder/coder/coderd/parameter"
)
func TestCompute(t *testing.T) {
t.Parallel()
generateScope := func() parameter.ComputeScope {
return parameter.ComputeScope{
TemplateImportJobID: uuid.New(),
TemplateID: uuid.NullUUID{
UUID: uuid.New(),
Valid: true,
},
WorkspaceID: uuid.NullUUID{
UUID: uuid.New(),
Valid: true,
},
}
}
type parameterOptions struct {
AllowOverrideSource bool
AllowOverrideDestination bool
DefaultDestinationScheme database.ParameterDestinationScheme
TemplateImportJobID uuid.UUID
}
generateParameter := func(t *testing.T, db database.Store, opts parameterOptions) database.ParameterSchema {
if opts.DefaultDestinationScheme == "" {
opts.DefaultDestinationScheme = database.ParameterDestinationSchemeEnvironmentVariable
}
param := dbgen.ParameterSchema(t, db, database.ParameterSchema{
JobID: opts.TemplateImportJobID,
DefaultSourceScheme: database.ParameterSourceSchemeData,
AllowOverrideSource: opts.AllowOverrideSource,
AllowOverrideDestination: opts.AllowOverrideDestination,
DefaultDestinationScheme: opts.DefaultDestinationScheme,
ValidationTypeSystem: database.ParameterTypeSystemNone,
})
return param
}
t.Run("NoValue", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
scope := generateScope()
_ = dbgen.ParameterSchema(t, db, database.ParameterSchema{
JobID: scope.TemplateImportJobID,
DefaultSourceScheme: database.ParameterSourceSchemeNone,
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
ValidationTypeSystem: database.ParameterTypeSystemNone,
})
computed, err := parameter.Compute(context.Background(), db, scope, nil)
require.NoError(t, err)
require.Len(t, computed, 0)
})
t.Run("UseDefaultTemplateValue", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
scope := generateScope()
parameterSchema := generateParameter(t, db, parameterOptions{
TemplateImportJobID: scope.TemplateImportJobID,
DefaultDestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
})
computed, err := parameter.Compute(context.Background(), db, scope, nil)
require.NoError(t, err)
require.Len(t, computed, 1)
computedValue := computed[0]
require.True(t, computedValue.DefaultSourceValue)
require.Equal(t, database.ParameterScopeImportJob, computedValue.Scope)
require.Equal(t, scope.TemplateImportJobID, computedValue.ScopeID)
require.Equal(t, computedValue.SourceValue, parameterSchema.DefaultSourceValue)
})
t.Run("TemplateOverridesTemplateDefault", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
scope := generateScope()
parameterSchema := generateParameter(t, db, parameterOptions{
TemplateImportJobID: scope.TemplateImportJobID,
})
value := dbgen.ParameterValue(t, db, database.ParameterValue{
Name: parameterSchema.Name,
Scope: database.ParameterScopeTemplate,
ScopeID: scope.TemplateID.UUID,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: "nop",
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
})
computed, err := parameter.Compute(context.Background(), db, scope, nil)
require.NoError(t, err)
require.Len(t, computed, 1)
require.Equal(t, false, computed[0].DefaultSourceValue)
require.Equal(t, value.SourceValue, computed[0].SourceValue)
})
t.Run("WorkspaceCannotOverwriteTemplateDefault", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
scope := generateScope()
parameterSchema := generateParameter(t, db, parameterOptions{
TemplateImportJobID: scope.TemplateImportJobID,
})
_ = dbgen.ParameterValue(t, db, database.ParameterValue{
Name: parameterSchema.Name,
Scope: database.ParameterScopeWorkspace,
ScopeID: scope.WorkspaceID.UUID,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: "nop",
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
})
computed, err := parameter.Compute(context.Background(), db, scope, nil)
require.NoError(t, err)
require.Len(t, computed, 1)
require.Equal(t, true, computed[0].DefaultSourceValue)
})
t.Run("WorkspaceOverwriteTemplateDefault", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
scope := generateScope()
parameterSchema := generateParameter(t, db, parameterOptions{
AllowOverrideSource: true,
TemplateImportJobID: scope.TemplateImportJobID,
})
_ = dbgen.ParameterValue(t, db, database.ParameterValue{
Name: parameterSchema.Name,
Scope: database.ParameterScopeWorkspace,
ScopeID: scope.WorkspaceID.UUID,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: "nop",
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
})
computed, err := parameter.Compute(context.Background(), db, scope, nil)
require.NoError(t, err)
require.Len(t, computed, 1)
require.Equal(t, false, computed[0].DefaultSourceValue)
})
t.Run("HideRedisplay", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
scope := generateScope()
_ = generateParameter(t, db, parameterOptions{
TemplateImportJobID: scope.TemplateImportJobID,
DefaultDestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
})
computed, err := parameter.Compute(context.Background(), db, scope, &parameter.ComputeOptions{
HideRedisplayValues: true,
})
require.NoError(t, err)
require.Len(t, computed, 1)
computedValue := computed[0]
require.True(t, computedValue.DefaultSourceValue)
require.Equal(t, computedValue.SourceValue, "")
})
}

View File

@ -1,43 +0,0 @@
package parameter
import (
"sort"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"golang.org/x/xerrors"
)
// Contains parses possible values for a conditional.
func Contains(condition string) ([]string, bool, error) {
if condition == "" {
return nil, false, nil
}
expression, diags := hclsyntax.ParseExpression([]byte(condition), "", hcl.InitialPos)
if len(diags) > 0 {
return nil, false, xerrors.Errorf("parse condition: %s", diags.Error())
}
functionCallExpression, valid := expression.(*hclsyntax.FunctionCallExpr)
if !valid {
return nil, false, nil
}
if functionCallExpression.Name != "contains" {
return nil, false, nil
}
if len(functionCallExpression.Args) < 2 {
return nil, false, nil
}
value, diags := functionCallExpression.Args[0].Value(&hcl.EvalContext{})
if len(diags) > 0 {
return nil, false, xerrors.Errorf("parse value: %s", diags.Error())
}
possible := make([]string, 0)
for _, subValue := range value.AsValueSlice() {
if subValue.Type().FriendlyName() != "string" {
continue
}
possible = append(possible, subValue.AsString())
}
sort.Strings(possible)
return possible, true, nil
}

View File

@ -1,20 +0,0 @@
package parameter_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/coder/coder/coderd/parameter"
)
func TestValidate(t *testing.T) {
t.Parallel()
t.Run("Contains", func(t *testing.T) {
t.Parallel()
values, valid, err := parameter.Contains(`contains(["us-east1-a", "us-central1-a"], var.region)`)
require.NoError(t, err)
require.True(t, valid)
require.Len(t, values, 2)
})
}

View File

@ -1,241 +0,0 @@
package coderd
import (
"context"
"database/sql"
"errors"
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"golang.org/x/xerrors"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/httpapi"
"github.com/coder/coder/coderd/parameter"
"github.com/coder/coder/codersdk"
)
// @Summary Create parameter
// @ID create-parameter
// @Security CoderSessionToken
// @Accept json
// @Produce json
// @Tags Parameters
// @Param request body codersdk.CreateParameterRequest true "Parameter request"
// @Param scope path string true "Scope" Enums(template,workspace,import_job)
// @Param id path string true "ID" format(uuid)
// @Success 201 {object} codersdk.Parameter
// @Router /parameters/{scope}/{id} [post]
func (api *API) postParameter(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
scope, scopeID, valid := readScopeAndID(ctx, rw, r)
if !valid {
return
}
var createRequest codersdk.CreateParameterRequest
if !httpapi.Read(ctx, rw, r, &createRequest) {
return
}
_, err := api.Database.GetParameterValueByScopeAndName(ctx, database.GetParameterValueByScopeAndNameParams{
Scope: scope,
ScopeID: scopeID,
Name: createRequest.Name,
})
if err == nil {
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{
Message: fmt.Sprintf("Parameter already exists in scope %q and name %q.", scope, createRequest.Name),
})
return
}
if !errors.Is(err, sql.ErrNoRows) {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching parameter.",
Detail: err.Error(),
})
return
}
parameterValue, err := api.Database.InsertParameterValue(ctx, database.InsertParameterValueParams{
ID: uuid.New(),
Name: createRequest.Name,
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
Scope: scope,
ScopeID: scopeID,
SourceScheme: database.ParameterSourceScheme(createRequest.SourceScheme),
SourceValue: createRequest.SourceValue,
DestinationScheme: database.ParameterDestinationScheme(createRequest.DestinationScheme),
})
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error inserting parameter.",
Detail: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusCreated, convertParameterValue(parameterValue))
}
// @Summary Get parameters
// @ID get-parameters
// @Security CoderSessionToken
// @Produce json
// @Tags Parameters
// @Param scope path string true "Scope" Enums(template,workspace,import_job)
// @Param id path string true "ID" format(uuid)
// @Success 200 {array} codersdk.Parameter
// @Router /parameters/{scope}/{id} [get]
func (api *API) parameters(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
scope, scopeID, valid := readScopeAndID(ctx, rw, r)
if !valid {
return
}
parameterValues, err := api.Database.ParameterValues(ctx, database.ParameterValuesParams{
Scopes: []database.ParameterScope{scope},
ScopeIds: []uuid.UUID{scopeID},
})
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching parameter scope values.",
Detail: err.Error(),
})
return
}
apiParameterValues := make([]codersdk.Parameter, 0, len(parameterValues))
for _, parameterValue := range parameterValues {
apiParameterValues = append(apiParameterValues, convertParameterValue(parameterValue))
}
httpapi.Write(ctx, rw, http.StatusOK, apiParameterValues)
}
// @Summary Delete parameter
// @ID delete-parameter
// @Security CoderSessionToken
// @Produce json
// @Tags Parameters
// @Param scope path string true "Scope" Enums(template,workspace,import_job)
// @Param id path string true "ID" format(uuid)
// @Param name path string true "Name"
// @Success 200 {object} codersdk.Response
// @Router /parameters/{scope}/{id}/{name} [delete]
func (api *API) deleteParameter(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
scope, scopeID, valid := readScopeAndID(ctx, rw, r)
if !valid {
return
}
name := chi.URLParam(r, "name")
parameterValue, err := api.Database.GetParameterValueByScopeAndName(ctx, database.GetParameterValueByScopeAndNameParams{
Scope: scope,
ScopeID: scopeID,
Name: name,
})
if httpapi.Is404Error(err) {
httpapi.ResourceNotFound(rw)
return
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching parameter.",
Detail: err.Error(),
})
return
}
err = api.Database.DeleteParameterValueByID(ctx, parameterValue.ID)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error deleting parameter.",
Detail: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusOK, codersdk.Response{
Message: "Parameter deleted.",
})
}
func convertParameterSchema(parameterSchema database.ParameterSchema) (codersdk.ParameterSchema, error) {
contains := []string{}
if parameterSchema.ValidationCondition != "" {
var err error
contains, _, err = parameter.Contains(parameterSchema.ValidationCondition)
if err != nil {
return codersdk.ParameterSchema{}, xerrors.Errorf("parse validation condition for %q: %w", parameterSchema.Name, err)
}
}
return codersdk.ParameterSchema{
ID: parameterSchema.ID,
CreatedAt: parameterSchema.CreatedAt,
JobID: parameterSchema.JobID,
Name: parameterSchema.Name,
Description: parameterSchema.Description,
DefaultSourceScheme: codersdk.ParameterSourceScheme(parameterSchema.DefaultSourceScheme),
DefaultSourceValue: parameterSchema.DefaultSourceValue,
AllowOverrideSource: parameterSchema.AllowOverrideSource,
DefaultDestinationScheme: codersdk.ParameterDestinationScheme(parameterSchema.DefaultDestinationScheme),
AllowOverrideDestination: parameterSchema.AllowOverrideDestination,
DefaultRefresh: parameterSchema.DefaultRefresh,
RedisplayValue: parameterSchema.RedisplayValue,
ValidationError: parameterSchema.ValidationError,
ValidationCondition: parameterSchema.ValidationCondition,
ValidationTypeSystem: string(parameterSchema.ValidationTypeSystem),
ValidationValueType: parameterSchema.ValidationValueType,
ValidationContains: contains,
}, nil
}
func convertParameterValue(parameterValue database.ParameterValue) codersdk.Parameter {
return codersdk.Parameter{
ID: parameterValue.ID,
CreatedAt: parameterValue.CreatedAt,
UpdatedAt: parameterValue.UpdatedAt,
Scope: codersdk.ParameterScope(parameterValue.Scope),
ScopeID: parameterValue.ScopeID,
Name: parameterValue.Name,
SourceScheme: codersdk.ParameterSourceScheme(parameterValue.SourceScheme),
DestinationScheme: codersdk.ParameterDestinationScheme(parameterValue.DestinationScheme),
SourceValue: parameterValue.SourceValue,
}
}
func readScopeAndID(ctx context.Context, rw http.ResponseWriter, r *http.Request) (database.ParameterScope, uuid.UUID, bool) {
scope := database.ParameterScope(chi.URLParam(r, "scope"))
switch scope {
case database.ParameterScopeTemplate, database.ParameterScopeImportJob, database.ParameterScopeWorkspace:
default:
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: fmt.Sprintf("Invalid scope %q.", scope),
Validations: []codersdk.ValidationError{
{Field: "scope", Detail: "invalid scope"},
},
})
return scope, uuid.Nil, false
}
id := chi.URLParam(r, "id")
uid, err := uuid.Parse(id)
if err != nil {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: fmt.Sprintf("Invalid UUID %q.", id),
Detail: err.Error(),
Validations: []codersdk.ValidationError{
{Field: "id", Detail: "Invalid UUID"},
},
})
return scope, uuid.Nil, false
}
return scope, uid, true
}

View File

@ -1,181 +0,0 @@
package coderd_test
import (
"context"
"net/http"
"testing"
"github.com/coder/coder/provisioner/echo"
"github.com/coder/coder/provisionersdk/proto"
"github.com/coder/coder/testutil"
"github.com/stretchr/testify/require"
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/codersdk"
)
func TestPostParameter(t *testing.T) {
t.Parallel()
t.Run("BadScope", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.CreateParameter(ctx, codersdk.ParameterScope("something"), user.OrganizationID, codersdk.CreateParameterRequest{
Name: "example",
SourceValue: "tomato",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
})
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
})
t.Run("Create", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
template := createTemplate(t, client, user)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
Name: "example",
SourceValue: "tomato",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
})
require.NoError(t, err)
})
t.Run("AlreadyExists", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
template := createTemplate(t, client, user)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
Name: "example",
SourceValue: "tomato",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
})
require.NoError(t, err)
_, err = client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
Name: "example",
SourceValue: "tomato",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
})
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
})
}
func TestParameters(t *testing.T) {
t.Parallel()
t.Run("ListEmpty", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
template := createTemplate(t, client, user)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.Parameters(ctx, codersdk.ParameterTemplate, template.ID)
require.NoError(t, err)
})
t.Run("List", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
template := createTemplate(t, client, user)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
Name: "example",
SourceValue: "tomato",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
})
require.NoError(t, err)
params, err := client.Parameters(ctx, codersdk.ParameterTemplate, template.ID)
require.NoError(t, err)
require.Len(t, params, 1)
})
}
func TestDeleteParameter(t *testing.T) {
t.Parallel()
t.Run("NotExist", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
template := createTemplate(t, client, user)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
err := client.DeleteParameter(ctx, codersdk.ParameterTemplate, template.ID, "something")
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
})
t.Run("Delete", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
template := createTemplate(t, client, user)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
param, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
Name: "example",
SourceValue: "tomato",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
})
require.NoError(t, err)
err = client.DeleteParameter(ctx, codersdk.ParameterTemplate, template.ID, param.Name)
require.NoError(t, err)
})
}
func createTemplate(t *testing.T, client *codersdk.Client, user codersdk.CreateFirstUserResponse) codersdk.Template {
instanceID := "instanceidentifier"
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: echo.ParseComplete,
ProvisionApply: []*proto.Provision_Response{{
Type: &proto.Provision_Response_Complete{
Complete: &proto.Provision_Complete{
Resources: []*proto.Resource{{
Name: "somename",
Type: "someinstance",
Agents: []*proto.Agent{{
Auth: &proto.Agent_InstanceId{
InstanceId: instanceID,
},
}},
}},
},
},
}},
})
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
return template
}

View File

@ -33,7 +33,6 @@ import (
"github.com/coder/coder/coderd/database/dbauthz" "github.com/coder/coder/coderd/database/dbauthz"
"github.com/coder/coder/coderd/gitauth" "github.com/coder/coder/coderd/gitauth"
"github.com/coder/coder/coderd/httpmw" "github.com/coder/coder/coderd/httpmw"
"github.com/coder/coder/coderd/parameter"
"github.com/coder/coder/coderd/schedule" "github.com/coder/coder/coderd/schedule"
"github.com/coder/coder/coderd/telemetry" "github.com/coder/coder/coderd/telemetry"
"github.com/coder/coder/coderd/tracing" "github.com/coder/coder/coderd/tracing"
@ -209,27 +208,6 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
} }
} }
// Compute parameters for the workspace to consume.
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
TemplateImportJobID: templateVersion.JobID,
TemplateID: uuid.NullUUID{
UUID: template.ID,
Valid: true,
},
WorkspaceID: uuid.NullUUID{
UUID: workspace.ID,
Valid: true,
},
}, nil)
if err != nil {
return nil, failJob(fmt.Sprintf("compute parameters: %s", err))
}
// Convert types to their corresponding protobuf types.
protoParameters, err := convertComputedParameterValues(parameters)
if err != nil {
return nil, failJob(fmt.Sprintf("convert computed parameters to protobuf: %s", err))
}
transition, err := convertWorkspaceTransition(workspaceBuild.Transition) transition, err := convertWorkspaceTransition(workspaceBuild.Transition)
if err != nil { if err != nil {
return nil, failJob(fmt.Sprintf("convert workspace transition: %s", err)) return nil, failJob(fmt.Sprintf("convert workspace transition: %s", err))
@ -287,7 +265,6 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
WorkspaceBuildId: workspaceBuild.ID.String(), WorkspaceBuildId: workspaceBuild.ID.String(),
WorkspaceName: workspace.Name, WorkspaceName: workspace.Name,
State: workspaceBuild.ProvisionerState, State: workspaceBuild.ProvisionerState,
ParameterValues: protoParameters,
RichParameterValues: convertRichParameterValues(workspaceBuildParameters), RichParameterValues: convertRichParameterValues(workspaceBuildParameters),
VariableValues: asVariableValues(templateVariables), VariableValues: asVariableValues(templateVariables),
GitAuthProviders: gitAuthProviders, GitAuthProviders: gitAuthProviders,
@ -323,26 +300,8 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
return nil, failJob(fmt.Sprintf("get template version variables: %s", err)) return nil, failJob(fmt.Sprintf("get template version variables: %s", err))
} }
// Compute parameters for the dry-run to consume.
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
TemplateImportJobID: templateVersion.JobID,
TemplateID: templateVersion.TemplateID,
WorkspaceID: uuid.NullUUID{},
AdditionalParameterValues: input.ParameterValues,
}, nil)
if err != nil {
return nil, failJob(fmt.Sprintf("compute parameters: %s", err))
}
// Convert types to their corresponding protobuf types.
protoParameters, err := convertComputedParameterValues(parameters)
if err != nil {
return nil, failJob(fmt.Sprintf("convert computed parameters to protobuf: %s", err))
}
protoJob.Type = &proto.AcquiredJob_TemplateDryRun_{ protoJob.Type = &proto.AcquiredJob_TemplateDryRun_{
TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{ TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{
ParameterValues: protoParameters,
RichParameterValues: convertRichParameterValues(input.RichParameterValues), RichParameterValues: convertRichParameterValues(input.RichParameterValues),
VariableValues: asVariableValues(templateVariables), VariableValues: asVariableValues(templateVariables),
Metadata: &sdkproto.Provision_Metadata{ Metadata: &sdkproto.Provision_Metadata{
@ -617,91 +576,6 @@ func (server *Server) UpdateJob(ctx context.Context, request *proto.UpdateJobReq
}, nil }, nil
} }
if len(request.ParameterSchemas) > 0 {
for index, protoParameter := range request.ParameterSchemas {
validationTypeSystem, err := convertValidationTypeSystem(protoParameter.ValidationTypeSystem)
if err != nil {
return nil, xerrors.Errorf("convert validation type system for %q: %w", protoParameter.Name, err)
}
parameterSchema := database.InsertParameterSchemaParams{
ID: uuid.New(),
CreatedAt: database.Now(),
JobID: job.ID,
Name: protoParameter.Name,
Description: protoParameter.Description,
RedisplayValue: protoParameter.RedisplayValue,
ValidationError: protoParameter.ValidationError,
ValidationCondition: protoParameter.ValidationCondition,
ValidationValueType: protoParameter.ValidationValueType,
ValidationTypeSystem: validationTypeSystem,
DefaultSourceScheme: database.ParameterSourceSchemeNone,
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
AllowOverrideDestination: protoParameter.AllowOverrideDestination,
AllowOverrideSource: protoParameter.AllowOverrideSource,
Index: int32(index),
}
// It's possible a parameter doesn't define a default source!
if protoParameter.DefaultSource != nil {
parameterSourceScheme, err := convertParameterSourceScheme(protoParameter.DefaultSource.Scheme)
if err != nil {
return nil, xerrors.Errorf("convert parameter source scheme: %w", err)
}
parameterSchema.DefaultSourceScheme = parameterSourceScheme
parameterSchema.DefaultSourceValue = protoParameter.DefaultSource.Value
}
// It's possible a parameter doesn't define a default destination!
if protoParameter.DefaultDestination != nil {
parameterDestinationScheme, err := convertParameterDestinationScheme(protoParameter.DefaultDestination.Scheme)
if err != nil {
return nil, xerrors.Errorf("convert parameter destination scheme: %w", err)
}
parameterSchema.DefaultDestinationScheme = parameterDestinationScheme
}
_, err = server.Database.InsertParameterSchema(ctx, parameterSchema)
if err != nil {
return nil, xerrors.Errorf("insert parameter schema: %w", err)
}
}
var templateID uuid.NullUUID
if job.Type == database.ProvisionerJobTypeTemplateVersionImport {
templateVersion, err := server.Database.GetTemplateVersionByJobID(ctx, job.ID)
if err != nil {
return nil, xerrors.Errorf("get template version by job id: %w", err)
}
templateID = templateVersion.TemplateID
}
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
TemplateImportJobID: job.ID,
TemplateID: templateID,
}, nil)
if err != nil {
return nil, xerrors.Errorf("compute parameters: %w", err)
}
// Convert parameters to the protobuf type.
protoParameters := make([]*sdkproto.ParameterValue, 0, len(parameters))
for _, computedParameter := range parameters {
converted, err := convertComputedParameterValue(computedParameter)
if err != nil {
return nil, xerrors.Errorf("convert parameter: %s", err)
}
protoParameters = append(protoParameters, converted)
}
return &proto.UpdateJobResponse{
Canceled: job.CanceledAt.Valid,
ParameterValues: protoParameters,
}, nil
}
return &proto.UpdateJobResponse{ return &proto.UpdateJobResponse{
Canceled: job.CanceledAt.Valid, Canceled: job.CanceledAt.Valid,
}, nil }, nil
@ -1545,37 +1419,6 @@ func obtainOIDCAccessToken(ctx context.Context, db database.Store, oidcConfig ht
return link.OAuthAccessToken, nil return link.OAuthAccessToken, nil
} }
func convertValidationTypeSystem(typeSystem sdkproto.ParameterSchema_TypeSystem) (database.ParameterTypeSystem, error) {
switch typeSystem {
case sdkproto.ParameterSchema_None:
return database.ParameterTypeSystemNone, nil
case sdkproto.ParameterSchema_HCL:
return database.ParameterTypeSystemHCL, nil
default:
return database.ParameterTypeSystem(""), xerrors.Errorf("unknown type system: %d", typeSystem)
}
}
func convertParameterSourceScheme(sourceScheme sdkproto.ParameterSource_Scheme) (database.ParameterSourceScheme, error) {
switch sourceScheme {
case sdkproto.ParameterSource_DATA:
return database.ParameterSourceSchemeData, nil
default:
return database.ParameterSourceScheme(""), xerrors.Errorf("unknown parameter source scheme: %d", sourceScheme)
}
}
func convertParameterDestinationScheme(destinationScheme sdkproto.ParameterDestination_Scheme) (database.ParameterDestinationScheme, error) {
switch destinationScheme {
case sdkproto.ParameterDestination_ENVIRONMENT_VARIABLE:
return database.ParameterDestinationSchemeEnvironmentVariable, nil
case sdkproto.ParameterDestination_PROVISIONER_VARIABLE:
return database.ParameterDestinationSchemeProvisionerVariable, nil
default:
return database.ParameterDestinationScheme(""), xerrors.Errorf("unknown parameter destination scheme: %d", destinationScheme)
}
}
func convertLogLevel(logLevel sdkproto.LogLevel) (database.LogLevel, error) { func convertLogLevel(logLevel sdkproto.LogLevel) (database.LogLevel, error) {
switch logLevel { switch logLevel {
case sdkproto.LogLevel_TRACE: case sdkproto.LogLevel_TRACE:
@ -1627,37 +1470,6 @@ func convertVariableValues(variableValues []codersdk.VariableValue) []*sdkproto.
return protoVariableValues return protoVariableValues
} }
func convertComputedParameterValues(parameters []parameter.ComputedValue) ([]*sdkproto.ParameterValue, error) {
protoParameters := make([]*sdkproto.ParameterValue, len(parameters))
for i, computedParameter := range parameters {
converted, err := convertComputedParameterValue(computedParameter)
if err != nil {
return nil, xerrors.Errorf("convert parameter: %w", err)
}
protoParameters[i] = converted
}
return protoParameters, nil
}
func convertComputedParameterValue(param parameter.ComputedValue) (*sdkproto.ParameterValue, error) {
var scheme sdkproto.ParameterDestination_Scheme
switch param.DestinationScheme {
case database.ParameterDestinationSchemeEnvironmentVariable:
scheme = sdkproto.ParameterDestination_ENVIRONMENT_VARIABLE
case database.ParameterDestinationSchemeProvisionerVariable:
scheme = sdkproto.ParameterDestination_PROVISIONER_VARIABLE
default:
return nil, xerrors.Errorf("unrecognized destination scheme: %q", param.DestinationScheme)
}
return &sdkproto.ParameterValue{
DestinationScheme: scheme,
Name: param.Name,
Value: param.SourceValue,
}, nil
}
func convertWorkspaceTransition(transition database.WorkspaceTransition) (sdkproto.WorkspaceTransition, error) { func convertWorkspaceTransition(transition database.WorkspaceTransition) (sdkproto.WorkspaceTransition, error) {
switch transition { switch transition {
case database.WorkspaceTransitionStart: case database.WorkspaceTransitionStart:
@ -1700,7 +1512,6 @@ type WorkspaceProvisionJob struct {
type TemplateVersionDryRunJob struct { type TemplateVersionDryRunJob struct {
TemplateVersionID uuid.UUID `json:"template_version_id"` TemplateVersionID uuid.UUID `json:"template_version_id"`
WorkspaceName string `json:"workspace_name"` WorkspaceName string `json:"workspace_name"`
ParameterValues []database.ParameterValue `json:"parameter_values"`
RichParameterValues []database.WorkspaceBuildParameter `json:"rich_parameter_values"` RichParameterValues []database.WorkspaceBuildParameter `json:"rich_parameter_values"`
} }

View File

@ -242,7 +242,6 @@ func TestAcquireJob(t *testing.T) {
WorkspaceBuild: &proto.AcquiredJob_WorkspaceBuild{ WorkspaceBuild: &proto.AcquiredJob_WorkspaceBuild{
WorkspaceBuildId: build.ID.String(), WorkspaceBuildId: build.ID.String(),
WorkspaceName: workspace.Name, WorkspaceName: workspace.Name,
ParameterValues: []*sdkproto.ParameterValue{},
VariableValues: []*sdkproto.VariableValue{ VariableValues: []*sdkproto.VariableValue{
{ {
Name: "first", Name: "first",
@ -339,7 +338,6 @@ func TestAcquireJob(t *testing.T) {
Input: must(json.Marshal(provisionerdserver.TemplateVersionDryRunJob{ Input: must(json.Marshal(provisionerdserver.TemplateVersionDryRunJob{
TemplateVersionID: version.ID, TemplateVersionID: version.ID,
WorkspaceName: "testing", WorkspaceName: "testing",
ParameterValues: []database.ParameterValue{},
})), })),
}) })
@ -351,7 +349,6 @@ func TestAcquireJob(t *testing.T) {
want, err := json.Marshal(&proto.AcquiredJob_TemplateDryRun_{ want, err := json.Marshal(&proto.AcquiredJob_TemplateDryRun_{
TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{ TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{
ParameterValues: []*sdkproto.ParameterValue{},
Metadata: &sdkproto.Provision_Metadata{ Metadata: &sdkproto.Provision_Metadata{
CoderUrl: srv.AccessURL.String(), CoderUrl: srv.AccessURL.String(),
WorkspaceName: "testing", WorkspaceName: "testing",

View File

@ -308,22 +308,6 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
} }
return nil return nil
}) })
eg.Go(func() error {
schemas, err := r.options.Database.GetParameterSchemasCreatedAfter(ctx, createdAfter)
if err != nil {
return xerrors.Errorf("get parameter schemas: %w", err)
}
snapshot.ParameterSchemas = make([]ParameterSchema, 0, len(schemas))
for _, schema := range schemas {
snapshot.ParameterSchemas = append(snapshot.ParameterSchemas, ParameterSchema{
ID: schema.ID,
JobID: schema.JobID,
Name: schema.Name,
ValidationCondition: schema.ValidationCondition,
})
}
return nil
})
eg.Go(func() error { eg.Go(func() error {
jobs, err := r.options.Database.GetProvisionerJobsCreatedAfter(ctx, createdAfter) jobs, err := r.options.Database.GetProvisionerJobsCreatedAfter(ctx, createdAfter)
if err != nil { if err != nil {
@ -688,7 +672,6 @@ type Snapshot struct {
DeploymentID string `json:"deployment_id"` DeploymentID string `json:"deployment_id"`
APIKeys []APIKey `json:"api_keys"` APIKeys []APIKey `json:"api_keys"`
ParameterSchemas []ParameterSchema `json:"parameter_schemas"`
ProvisionerJobs []ProvisionerJob `json:"provisioner_jobs"` ProvisionerJobs []ProvisionerJob `json:"provisioner_jobs"`
Licenses []License `json:"licenses"` Licenses []License `json:"licenses"`
Templates []Template `json:"templates"` Templates []Template `json:"templates"`

View File

@ -39,11 +39,6 @@ func TestTelemetry(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitMedium) ctx := testutil.Context(t, testutil.WaitMedium)
_, _ = dbgen.APIKey(t, db, database.APIKey{}) _, _ = dbgen.APIKey(t, db, database.APIKey{})
_ = dbgen.ParameterSchema(t, db, database.ParameterSchema{
DefaultSourceScheme: database.ParameterSourceSchemeNone,
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
ValidationTypeSystem: database.ParameterTypeSystemNone,
})
_ = dbgen.ProvisionerJob(t, db, database.ProvisionerJob{ _ = dbgen.ProvisionerJob(t, db, database.ProvisionerJob{
Provisioner: database.ProvisionerTypeTerraform, Provisioner: database.ProvisionerTypeTerraform,
StorageMethod: database.ProvisionerStorageMethodFile, StorageMethod: database.ProvisionerStorageMethodFile,
@ -87,7 +82,6 @@ func TestTelemetry(t *testing.T) {
}) })
assert.NoError(t, err) assert.NoError(t, err)
_, snapshot := collectSnapshot(t, db) _, snapshot := collectSnapshot(t, db)
require.Len(t, snapshot.ParameterSchemas, 1)
require.Len(t, snapshot.ProvisionerJobs, 1) require.Len(t, snapshot.ProvisionerJobs, 1)
require.Len(t, snapshot.Licenses, 1) require.Len(t, snapshot.Licenses, 1)
require.Len(t, snapshot.Templates, 1) require.Len(t, snapshot.Templates, 1)

View File

@ -334,23 +334,6 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
} }
templateVersionAudit.New = newTemplateVersion templateVersionAudit.New = newTemplateVersion
for _, parameterValue := range createTemplate.ParameterValues {
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
ID: uuid.New(),
Name: parameterValue.Name,
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
Scope: database.ParameterScopeTemplate,
ScopeID: template.ID,
SourceScheme: database.ParameterSourceScheme(parameterValue.SourceScheme),
SourceValue: parameterValue.SourceValue,
DestinationScheme: database.ParameterDestinationScheme(parameterValue.DestinationScheme),
})
if err != nil {
return xerrors.Errorf("insert parameter value: %w", err)
}
}
createdByNameMap, err := getCreatedByNamesByTemplateIDs(ctx, tx, []database.Template{dbTemplate}) createdByNameMap, err := getCreatedByNamesByTemplateIDs(ctx, tx, []database.Template{dbTemplate})
if err != nil { if err != nil {
return xerrors.Errorf("get creator name: %w", err) return xerrors.Errorf("get creator name: %w", err)

View File

@ -74,7 +74,12 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) {
return return
} }
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas)) var warnings []codersdk.TemplateVersionWarning
if len(schemas) > 0 {
warnings = append(warnings, codersdk.TemplateVersionWarningUnsupportedWorkspaces)
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, warnings))
} }
// @Summary Patch template version by ID // @Summary Patch template version by ID
@ -168,19 +173,7 @@ func (api *API) patchTemplateVersion(rw http.ResponseWriter, r *http.Request) {
return return
} }
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user, nil))
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error listing parameter schemas.",
Detail: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user, schemas))
} }
// @Summary Cancel template version by ID // @Summary Cancel template version by ID
@ -239,58 +232,6 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque
}) })
} }
// @Summary Get schema by template version
// @ID get-schema-by-template-version
// @Security CoderSessionToken
// @Produce json
// @Tags Templates
// @Param templateversion path string true "Template version ID" format(uuid)
// @Success 200 {array} codersdk.ParameterSchema
// @Router /templateversions/{templateversion}/schema [get]
func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
templateVersion := httpmw.TemplateVersionParam(r)
job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching provisioner job.",
Detail: err.Error(),
})
return
}
if !job.CompletedAt.Valid {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Template version job hasn't completed!",
})
return
}
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID)
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error listing parameter schemas.",
Detail: err.Error(),
})
return
}
apiSchemas := make([]codersdk.ParameterSchema, 0)
for _, schema := range schemas {
apiSchema, err := convertParameterSchema(schema)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: fmt.Sprintf("Internal error converting schema %s.", schema.Name),
Detail: err.Error(),
})
return
}
apiSchemas = append(apiSchemas, apiSchema)
}
httpapi.Write(ctx, rw, http.StatusOK, apiSchemas)
}
// @Summary Get rich parameters by template version // @Summary Get rich parameters by template version
// @ID get-rich-parameters-by-template-version // @ID get-rich-parameters-by-template-version
// @Security CoderSessionToken // @Security CoderSessionToken
@ -470,52 +411,6 @@ func (api *API) templateVersionVariables(rw http.ResponseWriter, r *http.Request
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersionVariables(dbTemplateVersionVariables)) httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersionVariables(dbTemplateVersionVariables))
} }
// @Summary Get parameters by template version
// @ID get-parameters-by-template-version
// @Security CoderSessionToken
// @Produce json
// @Tags Templates
// @Param templateversion path string true "Template version ID" format(uuid)
// @Success 200 {array} parameter.ComputedValue
// @Router /templateversions/{templateversion}/parameters [get]
func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
templateVersion := httpmw.TemplateVersionParam(r)
job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching provisioner job.",
Detail: err.Error(),
})
return
}
if !job.CompletedAt.Valid {
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
Message: "Job hasn't completed!",
})
return
}
values, err := parameter.Compute(ctx, api.Database, parameter.ComputeScope{
TemplateImportJobID: job.ID,
}, &parameter.ComputeOptions{
// We *never* want to send the client secret parameter values.
HideRedisplayValues: true,
})
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error computing values.",
Detail: err.Error(),
})
return
}
if values == nil {
values = []parameter.ComputedValue{}
}
httpapi.Write(ctx, rw, http.StatusOK, values)
}
// @Summary Create template version dry-run // @Summary Create template version dry-run
// @ID create-template-version-dry-run // @ID create-template-version-dry-run
// @Security CoderSessionToken // @Security CoderSessionToken
@ -561,20 +456,6 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques
return return
} }
// Convert parameters from request to parameters for the job
parameterValues := make([]database.ParameterValue, len(req.ParameterValues))
for i, v := range req.ParameterValues {
parameterValues[i] = database.ParameterValue{
ID: uuid.Nil,
Scope: database.ParameterScopeWorkspace,
ScopeID: uuid.Nil,
Name: v.Name,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: v.SourceValue,
DestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
}
}
richParameterValues := make([]database.WorkspaceBuildParameter, len(req.RichParameterValues)) richParameterValues := make([]database.WorkspaceBuildParameter, len(req.RichParameterValues))
for i, v := range req.RichParameterValues { for i, v := range req.RichParameterValues {
richParameterValues[i] = database.WorkspaceBuildParameter{ richParameterValues[i] = database.WorkspaceBuildParameter{
@ -589,7 +470,6 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques
input, err := json.Marshal(provisionerdserver.TemplateVersionDryRunJob{ input, err := json.Marshal(provisionerdserver.TemplateVersionDryRunJob{
TemplateVersionID: templateVersion.ID, TemplateVersionID: templateVersion.ID,
WorkspaceName: req.WorkspaceName, WorkspaceName: req.WorkspaceName,
ParameterValues: parameterValues,
RichParameterValues: richParameterValues, RichParameterValues: richParameterValues,
}) })
if err != nil { if err != nil {
@ -911,18 +791,7 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque
}) })
return err return err
} }
schemas, err := store.GetParameterSchemasByJobID(ctx, job.ID) apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user, nil))
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error listing parameter schemas.",
Detail: err.Error(),
})
return err
}
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user, schemas))
} }
return nil return nil
@ -986,19 +855,7 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
return return
} }
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, nil))
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error listing parameter schemas.",
Detail: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas))
} }
// @Summary Get template version by organization, template, and name // @Summary Get template version by organization, template, and name
@ -1072,19 +929,7 @@ func (api *API) templateVersionByOrganizationTemplateAndName(rw http.ResponseWri
return return
} }
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, nil))
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error listing parameter schemas.",
Detail: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas))
} }
// @Summary Get previous template version by organization, template, and name // @Summary Get previous template version by organization, template, and name
@ -1179,19 +1024,7 @@ func (api *API) previousTemplateVersionByOrganizationTemplateAndName(rw http.Res
return return
} }
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID) httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user, nil))
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error listing parameter schemas.",
Detail: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user, schemas))
} }
// @Summary Update active template version by template ID // @Summary Update active template version by template ID
@ -1423,68 +1256,6 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
var provisionerJob database.ProvisionerJob var provisionerJob database.ProvisionerJob
err = api.Database.InTx(func(tx database.Store) error { err = api.Database.InTx(func(tx database.Store) error {
jobID := uuid.New() jobID := uuid.New()
inherits := make([]uuid.UUID, 0)
for _, parameterValue := range req.ParameterValues {
if parameterValue.CloneID != uuid.Nil {
inherits = append(inherits, parameterValue.CloneID)
}
}
// Expand inherited params
if len(inherits) > 0 {
if req.TemplateID == uuid.Nil {
return xerrors.Errorf("cannot inherit parameters if template_id is not set")
}
inheritedParams, err := tx.ParameterValues(ctx, database.ParameterValuesParams{
IDs: inherits,
})
if err != nil {
return xerrors.Errorf("fetch inherited params: %w", err)
}
for _, copy := range inheritedParams {
// This is a bit inefficient, as we make a new db call for each
// param.
version, err := tx.GetTemplateVersionByJobID(ctx, copy.ScopeID)
if err != nil {
return xerrors.Errorf("fetch template version for param %q: %w", copy.Name, err)
}
if !version.TemplateID.Valid || version.TemplateID.UUID != req.TemplateID {
return xerrors.Errorf("cannot inherit parameters from other templates")
}
if copy.Scope != database.ParameterScopeImportJob {
return xerrors.Errorf("copy parameter scope is %q, must be %q", copy.Scope, database.ParameterScopeImportJob)
}
// Add the copied param to the list to process
req.ParameterValues = append(req.ParameterValues, codersdk.CreateParameterRequest{
Name: copy.Name,
SourceValue: copy.SourceValue,
SourceScheme: codersdk.ParameterSourceScheme(copy.SourceScheme),
DestinationScheme: codersdk.ParameterDestinationScheme(copy.DestinationScheme),
})
}
}
for _, parameterValue := range req.ParameterValues {
if parameterValue.CloneID != uuid.Nil {
continue
}
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
ID: uuid.New(),
Name: parameterValue.Name,
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
Scope: database.ParameterScopeImportJob,
ScopeID: jobID,
SourceScheme: database.ParameterSourceScheme(parameterValue.SourceScheme),
SourceValue: parameterValue.SourceValue,
DestinationScheme: database.ParameterDestinationScheme(parameterValue.DestinationScheme),
})
if err != nil {
return xerrors.Errorf("insert parameter value: %w", err)
}
}
templateVersionID := uuid.New() templateVersionID := uuid.New()
jobInput, err := json.Marshal(provisionerdserver.TemplateVersionImportJob{ jobInput, err := json.Marshal(provisionerdserver.TemplateVersionImportJob{
@ -1565,19 +1336,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
return return
} }
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, provisionerJob.ID) httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user, nil))
if errors.Is(err, sql.ErrNoRows) {
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error listing parameter schemas.",
Detail: err.Error(),
})
return
}
httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user, schemas))
} }
// templateVersionResources returns the workspace agent resources associated // templateVersionResources returns the workspace agent resources associated
@ -1644,7 +1403,7 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) {
api.provisionerJobLogs(rw, r, job) api.provisionerJobLogs(rw, r, job)
} }
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User, schemas []database.ParameterSchema) codersdk.TemplateVersion { func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User, warnings []codersdk.TemplateVersionWarning) codersdk.TemplateVersion {
createdBy := codersdk.User{ createdBy := codersdk.User{
ID: user.ID, ID: user.ID,
Username: user.Username, Username: user.Username,
@ -1655,11 +1414,6 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi
AvatarURL: user.AvatarURL.String, AvatarURL: user.AvatarURL.String,
} }
var warnings []codersdk.TemplateVersionWarning
if len(schemas) > 0 {
warnings = append(warnings, codersdk.TemplateVersionWarningDeprecatedParameters)
}
return codersdk.TemplateVersion{ return codersdk.TemplateVersion{
ID: version.ID, ID: version.ID,
TemplateID: &version.TemplateID.UUID, TemplateID: &version.TemplateID.UUID,

View File

@ -124,12 +124,6 @@ func TestPostTemplateVersionsByOrganization(t *testing.T) {
StorageMethod: codersdk.ProvisionerStorageMethodFile, StorageMethod: codersdk.ProvisionerStorageMethodFile,
FileID: file.ID, FileID: file.ID,
Provisioner: codersdk.ProvisionerTypeEcho, Provisioner: codersdk.ProvisionerTypeEcho,
ParameterValues: []codersdk.CreateParameterRequest{{
Name: "example",
SourceValue: "value",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
}},
}) })
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "bananas", version.Name) require.Equal(t, "bananas", version.Name)
@ -296,153 +290,6 @@ func TestPatchCancelTemplateVersion(t *testing.T) {
}) })
} }
func TestTemplateVersionSchema(t *testing.T) {
t.Parallel()
t.Run("ListRunning", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.TemplateVersionSchema(ctx, version.ID)
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
})
t.Run("List", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{{
Name: "example",
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}},
},
},
}},
ProvisionApply: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
schemas, err := client.TemplateVersionSchema(ctx, version.ID)
require.NoError(t, err)
require.NotNil(t, schemas)
require.Len(t, schemas, 1)
})
t.Run("ListContains", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{{
Name: "example",
ValidationTypeSystem: proto.ParameterSchema_HCL,
ValidationValueType: "string",
ValidationCondition: `contains(["first", "second"], var.example)`,
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}},
},
},
}},
ProvisionApply: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
schemas, err := client.TemplateVersionSchema(ctx, version.ID)
require.NoError(t, err)
require.NotNil(t, schemas)
require.Len(t, schemas, 1)
require.Equal(t, []string{"first", "second"}, schemas[0].ValidationContains)
})
}
func TestTemplateVersionParameters(t *testing.T) {
t.Parallel()
t.Run("ListRunning", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.TemplateVersionParameters(ctx, version.ID)
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
})
t.Run("List", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{
{
Name: "example",
RedisplayValue: true,
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: "hello",
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
{
Name: "abcd",
RedisplayValue: true,
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: "world",
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
},
},
},
}},
ProvisionApply: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
params, err := client.TemplateVersionParameters(ctx, version.ID)
require.NoError(t, err)
require.NotNil(t, params)
require.Len(t, params, 2)
require.Equal(t, "hello", params[0].SourceValue)
require.Equal(t, "world", params[1].SourceValue)
})
}
func TestTemplateVersionsGitAuth(t *testing.T) { func TestTemplateVersionsGitAuth(t *testing.T) {
t.Parallel() t.Parallel()
t.Run("Empty", func(t *testing.T) { t.Run("Empty", func(t *testing.T) {
@ -757,9 +604,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel() defer cancel()
// Create template version dry-run // Create template version dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
ParameterValues: []codersdk.CreateParameterRequest{},
})
require.NoError(t, err) require.NoError(t, err)
// Fetch template version dry-run // Fetch template version dry-run
@ -815,9 +660,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel() defer cancel()
_, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ _, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
ParameterValues: []codersdk.CreateParameterRequest{},
})
var apiErr *codersdk.Error var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr) require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode()) require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
@ -858,9 +701,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel() defer cancel()
// Create the dry-run // Create the dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
ParameterValues: []codersdk.CreateParameterRequest{},
})
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, codersdk.ProvisionerJobPending, job.Status) require.Equal(t, codersdk.ProvisionerJobPending, job.Status)
err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID) err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID)
@ -881,9 +722,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel() defer cancel()
// Create the dry-run // Create the dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
ParameterValues: []codersdk.CreateParameterRequest{},
})
require.NoError(t, err) require.NoError(t, err)
require.Eventually(t, func() bool { require.Eventually(t, func() bool {
@ -933,9 +772,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel() defer cancel()
// Create the dry-run // Create the dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
ParameterValues: []codersdk.CreateParameterRequest{},
})
require.NoError(t, err) require.NoError(t, err)
err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID) err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID)
@ -1454,45 +1291,3 @@ func TestTemplateVersionPatch(t *testing.T) {
require.Error(t, err) require.Error(t, err)
}) })
} }
func TestTemplateVersionWarnings(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{
{
AllowOverrideSource: true,
Name: "example",
Description: "description 1",
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: "tomato",
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
},
},
},
}},
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
templateVersion, err := client.TemplateVersion(ctx, template.ActiveVersionID)
require.NoError(t, err)
require.Contains(t, templateVersion.Warnings, codersdk.TemplateVersionWarningDeprecatedParameters)
}

View File

@ -313,7 +313,6 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
builder := wsbuilder.New(workspace, database.WorkspaceTransition(createBuild.Transition)). builder := wsbuilder.New(workspace, database.WorkspaceTransition(createBuild.Transition)).
Initiator(apiKey.UserID). Initiator(apiKey.UserID).
LegacyParameterValues(createBuild.ParameterValues).
RichParameterValues(createBuild.RichParameterValues). RichParameterValues(createBuild.RichParameterValues).
LogLevel(string(createBuild.LogLevel)) LogLevel(string(createBuild.LogLevel))

View File

@ -637,173 +637,6 @@ func TestWorkspaceBuildStatus(t *testing.T) {
require.EqualValues(t, codersdk.WorkspaceStatusDeleted, workspace.LatestBuild.Status) require.EqualValues(t, codersdk.WorkspaceStatusDeleted, workspace.LatestBuild.Status)
} }
func TestMigrateLegacyToRichParameters(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user := coderdtest.CreateFirstUser(t, client)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
// 1. Prepare a template with legacy parameters.
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
Parse: []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{
{
AllowOverrideSource: true,
Name: "example",
Description: "description 1",
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: "tomato",
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
},
},
},
}},
ProvisionApply: echo.ProvisionComplete,
ProvisionPlan: echo.ProvisionComplete,
})
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
// Create a workspace
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
cwr.ParameterValues = []codersdk.CreateParameterRequest{
{
Name: "example",
SourceValue: "carrot",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeEnvironmentVariable,
},
}
})
workspaceBuild := coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
require.Equal(t, codersdk.WorkspaceStatusRunning, workspaceBuild.Status)
// 2. Upload the template with legacy and rich parameters.
templateWithParameters := &echo.Responses{
Parse: []*proto.Parse_Response{{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{
{
AllowOverrideSource: true,
Name: "example",
Description: "description 1",
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: "tomato",
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
},
},
},
}},
ProvisionPlan: []*proto.Provision_Response{
{
Type: &proto.Provision_Response_Complete{
Complete: &proto.Provision_Complete{
Parameters: []*proto.RichParameter{
{
Name: "new_example",
Type: "string",
Mutable: true,
Required: true,
LegacyVariableName: "example",
},
},
},
},
},
},
ProvisionApply: echo.ProvisionComplete,
}
templateVersion = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, templateWithParameters, template.ID)
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
// Check if rich parameters are expected
richParameters, err := client.TemplateVersionRichParameters(ctx, templateVersion.ID)
require.NoError(t, err)
require.Len(t, richParameters, 1)
require.Equal(t, "new_example", richParameters[0].Name)
// Update workspace to use rich parameters and template variables
workspaceBuild, err = client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: templateVersion.ID,
Transition: codersdk.WorkspaceTransitionStart,
})
require.NoError(t, err)
require.Eventually(t, func() bool {
workspaceBuild = coderdtest.AwaitWorkspaceBuildJob(t, client, workspaceBuild.ID)
return codersdk.WorkspaceStatusRunning == workspaceBuild.Status
}, testutil.WaitLong, testutil.IntervalFast)
// Check if variable value has been imported
buildParameters, err := client.WorkspaceBuildParameters(ctx, workspaceBuild.ID)
require.NoError(t, err)
require.Len(t, buildParameters, 1)
require.Equal(t, "carrot", buildParameters[0].Value)
// 3. Upload the template with rich parameters only
templateWithParameters = &echo.Responses{
Parse: echo.ParseComplete,
ProvisionPlan: []*proto.Provision_Response{
{
Type: &proto.Provision_Response_Complete{
Complete: &proto.Provision_Complete{
Parameters: []*proto.RichParameter{
{
Name: "new_example",
Type: "string",
Mutable: true,
Required: true,
LegacyVariableName: "example",
},
},
},
},
},
},
ProvisionApply: echo.ProvisionComplete,
}
templateVersion = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, templateWithParameters, template.ID)
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
// Check if rich parameters are expected
richParameters, err = client.TemplateVersionRichParameters(ctx, templateVersion.ID)
require.NoError(t, err)
require.Len(t, richParameters, 1)
require.Equal(t, "new_example", richParameters[0].Name)
// Update workspace to use rich parameters and template variables
workspaceBuild, err = client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: templateVersion.ID,
Transition: codersdk.WorkspaceTransitionStart,
})
require.NoError(t, err)
require.Eventually(t, func() bool {
workspaceBuild = coderdtest.AwaitWorkspaceBuildJob(t, client, workspaceBuild.ID)
return codersdk.WorkspaceStatusRunning == workspaceBuild.Status
}, testutil.WaitLong, testutil.IntervalFast)
// Check if build parameters have been pulled from last build
buildParameters, err = client.WorkspaceBuildParameters(ctx, workspaceBuild.ID)
require.NoError(t, err)
require.Len(t, buildParameters, 1)
require.Equal(t, "carrot", buildParameters[0].Value)
}
func TestWorkspaceBuildDebugMode(t *testing.T) { func TestWorkspaceBuildDebugMode(t *testing.T) {
t.Parallel() t.Parallel()

View File

@ -425,7 +425,6 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
Reason(database.BuildReasonInitiator). Reason(database.BuildReasonInitiator).
Initiator(apiKey.UserID). Initiator(apiKey.UserID).
ActiveVersion(). ActiveVersion().
LegacyParameterValues(createWorkspace.ParameterValues).
RichParameterValues(createWorkspace.RichParameterValues) RichParameterValues(createWorkspace.RichParameterValues)
workspaceBuild, provisionerJob, err = builder.Build( workspaceBuild, provisionerJob, err = builder.Build(
ctx, db, func(action rbac.Action, object rbac.Objecter) bool { ctx, db, func(action rbac.Action, object rbac.Objecter) bool {

View File

@ -34,15 +34,14 @@ import (
// build, job, err := b.Build(...) // build, job, err := b.Build(...)
type Builder struct { type Builder struct {
// settings that control the kind of build you get // settings that control the kind of build you get
workspace database.Workspace workspace database.Workspace
trans database.WorkspaceTransition trans database.WorkspaceTransition
version versionTarget version versionTarget
state stateTarget state stateTarget
logLevel string logLevel string
legacyParameterValues []codersdk.CreateParameterRequest richParameterValues []codersdk.WorkspaceBuildParameter
richParameterValues []codersdk.WorkspaceBuildParameter initiator uuid.UUID
initiator uuid.UUID reason database.BuildReason
reason database.BuildReason
// used during build, makes function arguments less verbose // used during build, makes function arguments less verbose
ctx context.Context ctx context.Context
@ -56,8 +55,9 @@ type Builder struct {
lastBuild *database.WorkspaceBuild lastBuild *database.WorkspaceBuild
lastBuildErr *error lastBuildErr *error
lastBuildParameters *[]database.WorkspaceBuildParameter lastBuildParameters *[]database.WorkspaceBuildParameter
lastParameterValues *[]database.ParameterValue
lastBuildJob *database.ProvisionerJob lastBuildJob *database.ProvisionerJob
verifyNoLegacyParametersOnce bool
} }
type Option func(Builder) Builder type Option func(Builder) Builder
@ -140,12 +140,6 @@ func (b Builder) Reason(r database.BuildReason) Builder {
return b return b
} }
func (b Builder) LegacyParameterValues(p []codersdk.CreateParameterRequest) Builder {
// nolint: revive
b.legacyParameterValues = p
return b
}
func (b Builder) RichParameterValues(p []codersdk.WorkspaceBuildParameter) Builder { func (b Builder) RichParameterValues(p []codersdk.WorkspaceBuildParameter) Builder {
// nolint: revive // nolint: revive
b.richParameterValues = p b.richParameterValues = p
@ -271,15 +265,6 @@ func (b *Builder) buildTx(authFunc func(action rbac.Action, object rbac.Objecter
} }
} }
legacyParameters, err := b.getLastParameterValues()
if err != nil {
return nil, nil, BuildError{
http.StatusInternalServerError,
"failed to fetch previous legacy parameters.",
err,
}
}
// if we haven't been told specifically who initiated, default to owner // if we haven't been told specifically who initiated, default to owner
if b.initiator == uuid.Nil { if b.initiator == uuid.Nil {
b.initiator = b.workspace.OwnerID b.initiator = b.workspace.OwnerID
@ -289,45 +274,6 @@ func (b *Builder) buildTx(authFunc func(action rbac.Action, object rbac.Objecter
b.reason = database.BuildReasonInitiator b.reason = database.BuildReasonInitiator
} }
// Write/Update any new params
now := database.Now()
for _, param := range b.legacyParameterValues {
for _, exists := range legacyParameters {
// If the param exists, delete the old param before inserting the new one
if exists.Name == param.Name {
err = b.store.DeleteParameterValueByID(b.ctx, exists.ID)
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
return nil, nil, BuildError{
http.StatusInternalServerError,
fmt.Sprintf("Failed to delete old param %q", exists.Name),
err,
}
}
}
}
// If the value is empty, we don't want to save it on database so
// Terraform can use the default value
if param.SourceValue == "" {
continue
}
_, err = b.store.InsertParameterValue(b.ctx, database.InsertParameterValueParams{
ID: uuid.New(),
Name: param.Name,
CreatedAt: now,
UpdatedAt: now,
Scope: database.ParameterScopeWorkspace,
ScopeID: b.workspace.ID,
SourceScheme: database.ParameterSourceScheme(param.SourceScheme),
SourceValue: param.SourceValue,
DestinationScheme: database.ParameterDestinationScheme(param.DestinationScheme),
})
if err != nil {
return nil, nil, BuildError{http.StatusInternalServerError, "insert parameter value", err}
}
}
workspaceBuildID := uuid.New() workspaceBuildID := uuid.New()
input, err := json.Marshal(provisionerdserver.WorkspaceProvisionJob{ input, err := json.Marshal(provisionerdserver.WorkspaceProvisionJob{
WorkspaceBuildID: workspaceBuildID, WorkspaceBuildID: workspaceBuildID,
@ -346,6 +292,7 @@ func (b *Builder) buildTx(authFunc func(action rbac.Action, object rbac.Objecter
} }
tags := provisionerdserver.MutateTags(b.workspace.OwnerID, templateVersionJob.Tags) tags := provisionerdserver.MutateTags(b.workspace.OwnerID, templateVersionJob.Tags)
now := database.Now()
provisionerJob, err := b.store.InsertProvisionerJob(b.ctx, database.InsertProvisionerJobParams{ provisionerJob, err := b.store.InsertProvisionerJob(b.ctx, database.InsertProvisionerJobParams{
ID: uuid.New(), ID: uuid.New(),
CreatedAt: now, CreatedAt: now,
@ -536,13 +483,12 @@ func (b *Builder) getParameters() (names, values []string, err error) {
if err != nil { if err != nil {
return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch last build parameters", err} return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch last build parameters", err}
} }
lastParameterValues, err := b.getLastParameterValues() err = b.verifyNoLegacyParameters()
if err != nil { if err != nil {
return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch last parameter values", err} return nil, nil, BuildError{http.StatusBadRequest, "Unable to build workspace with unsupported parameters", err}
} }
resolver := codersdk.ParameterResolver{ resolver := codersdk.ParameterResolver{
Rich: db2sdk.WorkspaceBuildParameters(lastBuildParameters), Rich: db2sdk.WorkspaceBuildParameters(lastBuildParameters),
Legacy: db2sdk.Parameters(lastParameterValues),
} }
for _, templateVersionParameter := range templateVersionParameters { for _, templateVersionParameter := range templateVersionParameters {
tvp, err := db2sdk.TemplateVersionParameter(templateVersionParameter) tvp, err := db2sdk.TemplateVersionParameter(templateVersionParameter)
@ -611,19 +557,36 @@ func (b *Builder) getTemplateVersionParameters() ([]database.TemplateVersionPara
return tvp, nil return tvp, nil
} }
func (b *Builder) getLastParameterValues() ([]database.ParameterValue, error) { // verifyNoLegacyParameters verifies that initiator can't start the workspace build
if b.lastParameterValues != nil { // if it uses legacy parameters (database.ParameterSchemas).
return *b.lastParameterValues, nil func (b *Builder) verifyNoLegacyParameters() error {
if b.verifyNoLegacyParametersOnce {
return nil
} }
pv, err := b.store.ParameterValues(b.ctx, database.ParameterValuesParams{ b.verifyNoLegacyParametersOnce = true
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
ScopeIds: []uuid.UUID{b.workspace.ID}, // Block starting the workspace with legacy parameters.
}) if b.trans != database.WorkspaceTransitionStart {
if err != nil && !xerrors.Is(err, sql.ErrNoRows) { return nil
return nil, xerrors.Errorf("get workspace %w parameter values: %w", b.workspace.ID, err)
} }
b.lastParameterValues = &pv
return pv, nil templateVersionJob, err := b.getTemplateVersionJob()
if err != nil {
return xerrors.Errorf("failed to fetch template version job: %w", err)
}
parameterSchemas, err := b.store.GetParameterSchemasByJobID(b.ctx, templateVersionJob.ID)
if xerrors.Is(err, sql.ErrNoRows) {
return nil
}
if err != nil {
return xerrors.Errorf("failed to get parameter schemas: %w", err)
}
if len(parameterSchemas) > 0 {
return xerrors.Errorf("Legacy parameters in use on this version are not supported anymore. Contact your administrator for assistance.")
}
return nil
} }
func (b *Builder) getLastBuildJob() (*database.ProvisionerJob, error) { func (b *Builder) getLastBuildJob() (*database.ProvisionerJob, error) {

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"testing" "testing"
"time" "time"
@ -24,21 +23,19 @@ import (
var ( var (
// use fixed IDs so logs are easier to read // use fixed IDs so logs are easier to read
templateID = uuid.MustParse("12341234-0000-0000-0001-000000000000") templateID = uuid.MustParse("12341234-0000-0000-0001-000000000000")
activeVersionID = uuid.MustParse("12341234-0000-0000-0002-000000000000") activeVersionID = uuid.MustParse("12341234-0000-0000-0002-000000000000")
inactiveVersionID = uuid.MustParse("12341234-0000-0000-0003-000000000000") inactiveVersionID = uuid.MustParse("12341234-0000-0000-0003-000000000000")
activeJobID = uuid.MustParse("12341234-0000-0000-0004-000000000000") activeJobID = uuid.MustParse("12341234-0000-0000-0004-000000000000")
inactiveJobID = uuid.MustParse("12341234-0000-0000-0005-000000000000") inactiveJobID = uuid.MustParse("12341234-0000-0000-0005-000000000000")
orgID = uuid.MustParse("12341234-0000-0000-0006-000000000000") orgID = uuid.MustParse("12341234-0000-0000-0006-000000000000")
workspaceID = uuid.MustParse("12341234-0000-0000-0007-000000000000") workspaceID = uuid.MustParse("12341234-0000-0000-0007-000000000000")
userID = uuid.MustParse("12341234-0000-0000-0008-000000000000") userID = uuid.MustParse("12341234-0000-0000-0008-000000000000")
activeFileID = uuid.MustParse("12341234-0000-0000-0009-000000000000") activeFileID = uuid.MustParse("12341234-0000-0000-0009-000000000000")
inactiveFileID = uuid.MustParse("12341234-0000-0000-000a-000000000000") inactiveFileID = uuid.MustParse("12341234-0000-0000-000a-000000000000")
lastBuildID = uuid.MustParse("12341234-0000-0000-000b-000000000000") lastBuildID = uuid.MustParse("12341234-0000-0000-000b-000000000000")
lastBuildJobID = uuid.MustParse("12341234-0000-0000-000c-000000000000") lastBuildJobID = uuid.MustParse("12341234-0000-0000-000c-000000000000")
otherUserID = uuid.MustParse("12341234-0000-0000-000d-000000000000") otherUserID = uuid.MustParse("12341234-0000-0000-000d-000000000000")
notReplacedParamID = uuid.MustParse("12341234-0000-0000-000e-000000000000")
replacedParamID = uuid.MustParse("12341234-0000-0000-000f-000000000000")
) )
func TestBuilder_NoOptions(t *testing.T) { func TestBuilder_NoOptions(t *testing.T) {
@ -56,7 +53,8 @@ func TestBuilder_NoOptions(t *testing.T) {
withTemplate, withTemplate,
withInactiveVersion(nil), withInactiveVersion(nil),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil), withRichParameters(nil), withRichParameters(nil),
withParameterSchemas(inactiveJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) { expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
@ -104,7 +102,8 @@ func TestBuilder_Initiator(t *testing.T) {
withTemplate, withTemplate,
withInactiveVersion(nil), withInactiveVersion(nil),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil), withRichParameters(nil), withRichParameters(nil),
withParameterSchemas(inactiveJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) { expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
@ -136,7 +135,8 @@ func TestBuilder_Reason(t *testing.T) {
withTemplate, withTemplate,
withInactiveVersion(nil), withInactiveVersion(nil),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil), withRichParameters(nil), withRichParameters(nil),
withParameterSchemas(inactiveJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) { expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
@ -167,7 +167,7 @@ func TestBuilder_ActiveVersion(t *testing.T) {
withTemplate, withTemplate,
withActiveVersion(nil), withActiveVersion(nil),
withLastBuildNotFound, withLastBuildNotFound,
withLegacyParameters(nil), withParameterSchemas(activeJobID, nil),
// previous rich parameters are not queried because there is no previous build. // previous rich parameters are not queried because there is no previous build.
// Outputs // Outputs
@ -190,47 +190,6 @@ func TestBuilder_ActiveVersion(t *testing.T) {
req.NoError(err) req.NoError(err)
} }
func TestBuilder_LegacyParams(t *testing.T) {
t.Parallel()
req := require.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
oldParams := []database.ParameterValue{
{Name: "not-replaced", SourceValue: "nr", ID: notReplacedParamID},
{Name: "replaced", SourceValue: "r", ID: replacedParamID},
}
newParams := []codersdk.CreateParameterRequest{
{Name: "replaced", SourceValue: "s"},
{Name: "new", SourceValue: "n"},
}
mDB := expectDB(t,
// Inputs
withTemplate,
withActiveVersion(nil),
withLastBuildFound,
withLegacyParameters(oldParams),
withRichParameters(nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
}),
expectBuild(func(bld database.InsertWorkspaceBuildParams) {
}),
expectBuildParameters(func(params database.InsertWorkspaceBuildParametersParams) {
}),
expectReplacedParam(replacedParamID, "replaced", "s"),
expectInsertedParam("new", "n"),
)
ws := database.Workspace{ID: workspaceID, TemplateID: templateID, OwnerID: userID}
uut := wsbuilder.New(ws, database.WorkspaceTransitionStart).ActiveVersion().LegacyParameterValues(newParams)
_, _, err := uut.Build(ctx, mDB, nil)
req.NoError(err)
}
func TestWorkspaceBuildWithRichParameters(t *testing.T) { func TestWorkspaceBuildWithRichParameters(t *testing.T) {
t.Parallel() t.Parallel()
@ -285,8 +244,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate, withTemplate,
withInactiveVersion(richParameters), withInactiveVersion(richParameters),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters), withRichParameters(initialBuildParameters),
withParameterSchemas(inactiveJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}), expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -326,8 +285,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate, withTemplate,
withInactiveVersion(richParameters), withInactiveVersion(richParameters),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters), withRichParameters(initialBuildParameters),
withParameterSchemas(inactiveJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}), expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -348,6 +307,47 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
req.NoError(err) req.NoError(err)
}) })
t.Run("StartWorkspaceWithLegacyParameterValues", func(t *testing.T) {
t.Parallel()
req := require.New(t)
asrt := assert.New(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
schemas := []database.ParameterSchema{
{
Name: "not-replaced",
DefaultDestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
},
{
Name: "replaced",
DefaultDestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
},
}
mDB := expectDB(t,
// Inputs
withTemplate,
withInactiveVersion(richParameters),
withLastBuildFound,
withRichParameters(nil),
withParameterSchemas(inactiveJobID, schemas),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
expectBuild(func(bld database.InsertWorkspaceBuildParams) {}),
)
ws := database.Workspace{ID: workspaceID, TemplateID: templateID, OwnerID: userID}
uut := wsbuilder.New(ws, database.WorkspaceTransitionStart)
_, _, err := uut.Build(ctx, mDB, nil)
bldErr := wsbuilder.BuildError{}
req.ErrorAs(err, &bldErr)
asrt.Equal(http.StatusBadRequest, bldErr.Status)
})
t.Run("DoNotModifyImmutables", func(t *testing.T) { t.Run("DoNotModifyImmutables", func(t *testing.T) {
t.Parallel() t.Parallel()
@ -366,8 +366,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate, withTemplate,
withInactiveVersion(richParameters), withInactiveVersion(richParameters),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters), withRichParameters(initialBuildParameters),
withParameterSchemas(inactiveJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}), expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -418,8 +418,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate, withTemplate,
withActiveVersion(version2params), withActiveVersion(version2params),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters), withRichParameters(initialBuildParameters),
withParameterSchemas(activeJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}), expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -476,8 +476,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate, withTemplate,
withActiveVersion(version2params), withActiveVersion(version2params),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters), withRichParameters(initialBuildParameters),
withParameterSchemas(activeJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}), expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -532,8 +532,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate, withTemplate,
withActiveVersion(version2params), withActiveVersion(version2params),
withLastBuildFound, withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters), withRichParameters(initialBuildParameters),
withParameterSchemas(activeJobID, nil),
// Outputs // Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}), expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -710,17 +710,14 @@ func withLastBuildNotFound(mTx *dbmock.MockStore) {
Return(database.WorkspaceBuild{}, sql.ErrNoRows) Return(database.WorkspaceBuild{}, sql.ErrNoRows)
} }
func withLegacyParameters(params []database.ParameterValue) func(mTx *dbmock.MockStore) { func withParameterSchemas(jobID uuid.UUID, schemas []database.ParameterSchema) func(mTx *dbmock.MockStore) {
return func(mTx *dbmock.MockStore) { return func(mTx *dbmock.MockStore) {
c := mTx.EXPECT().ParameterValues( c := mTx.EXPECT().GetParameterSchemasByJobID(
gomock.Any(), gomock.Any(),
database.ParameterValuesParams{ jobID).
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
ScopeIds: []uuid.UUID{workspaceID},
}).
Times(1) Times(1)
if len(params) > 0 { if len(schemas) > 0 {
c.Return(params, nil) c.Return(schemas, nil)
} else { } else {
c.Return(nil, sql.ErrNoRows) c.Return(nil, sql.ErrNoRows)
} }
@ -797,43 +794,3 @@ func expectBuildParameters(
) )
} }
} }
type insertParameterMatcher struct {
name string
value string
}
func (m insertParameterMatcher) Matches(x interface{}) bool {
p, ok := x.(database.InsertParameterValueParams)
if !ok {
return false
}
if p.Name != m.name {
return false
}
return p.SourceValue == m.value
}
func (m insertParameterMatcher) String() string {
return fmt.Sprintf("ParameterValue %s=%s", m.name, m.value)
}
func expectReplacedParam(oldID uuid.UUID, name, newValue string) func(store *dbmock.MockStore) {
return func(mTx *dbmock.MockStore) {
del := mTx.EXPECT().DeleteParameterValueByID(gomock.Any(), oldID).
Times(1).
Return(nil)
mTx.EXPECT().InsertParameterValue(gomock.Any(), insertParameterMatcher{name, newValue}).
Times(1).
After(del).
Return(database.ParameterValue{}, nil)
}
}
func expectInsertedParam(name, newValue string) func(store *dbmock.MockStore) {
return func(mTx *dbmock.MockStore) {
mTx.EXPECT().InsertParameterValue(gomock.Any(), insertParameterMatcher{name, newValue}).
Times(1).
Return(database.ParameterValue{}, nil)
}
}

View File

@ -51,10 +51,6 @@ type CreateTemplateVersionRequest struct {
Provisioner ProvisionerType `json:"provisioner" validate:"oneof=terraform echo,required"` Provisioner ProvisionerType `json:"provisioner" validate:"oneof=terraform echo,required"`
ProvisionerTags map[string]string `json:"tags"` ProvisionerTags map[string]string `json:"tags"`
// ParameterValues allows for additional parameters to be provided
// during the dry-run provision stage.
ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"`
UserVariableValues []VariableValue `json:"user_variable_values,omitempty"` UserVariableValues []VariableValue `json:"user_variable_values,omitempty"`
} }
@ -82,8 +78,7 @@ type CreateTemplateRequest struct {
// This is required on creation to enable a user-flow of validating a // This is required on creation to enable a user-flow of validating a
// template works. There is no reason the data-model cannot support empty // template works. There is no reason the data-model cannot support empty
// templates, but it doesn't make sense for users. // templates, but it doesn't make sense for users.
VersionID uuid.UUID `json:"template_version_id" validate:"required" format:"uuid"` VersionID uuid.UUID `json:"template_version_id" validate:"required" format:"uuid"`
ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"`
// DefaultTTLMillis allows optionally specifying the default TTL // DefaultTTLMillis allows optionally specifying the default TTL
// for all workspaces created from this template. // for all workspaces created from this template.
@ -123,7 +118,6 @@ type CreateWorkspaceRequest struct {
TTLMillis *int64 `json:"ttl_ms,omitempty"` TTLMillis *int64 `json:"ttl_ms,omitempty"`
// ParameterValues allows for additional parameters to be provided // ParameterValues allows for additional parameters to be provided
// during the initial provision. // during the initial provision.
ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"`
RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values,omitempty"` RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values,omitempty"`
} }

View File

@ -1,148 +0,0 @@
package codersdk
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
"github.com/google/uuid"
)
type ParameterScope string
const (
ParameterTemplate ParameterScope = "template"
ParameterWorkspace ParameterScope = "workspace"
ParameterImportJob ParameterScope = "import_job"
)
type ParameterSourceScheme string
const (
ParameterSourceSchemeNone ParameterSourceScheme = "none"
ParameterSourceSchemeData ParameterSourceScheme = "data"
)
type ParameterDestinationScheme string
const (
ParameterDestinationSchemeNone ParameterDestinationScheme = "none"
ParameterDestinationSchemeEnvironmentVariable ParameterDestinationScheme = "environment_variable"
ParameterDestinationSchemeProvisionerVariable ParameterDestinationScheme = "provisioner_variable"
)
type ParameterTypeSystem string
const (
ParameterTypeSystemNone ParameterTypeSystem = "none"
ParameterTypeSystemHCL ParameterTypeSystem = "hcl"
)
type ComputedParameter struct {
Parameter
SchemaID uuid.UUID `json:"schema_id" format:"uuid"`
DefaultSourceValue bool `json:"default_source_value"`
}
// Parameter represents a set value for the scope.
//
// @Description Parameter represents a set value for the scope.
type Parameter struct {
ID uuid.UUID `json:"id" table:"id" format:"uuid"`
Scope ParameterScope `json:"scope" table:"scope" enums:"template,workspace,import_job"`
ScopeID uuid.UUID `json:"scope_id" table:"scope id" format:"uuid"`
Name string `json:"name" table:"name,default_sort"`
SourceScheme ParameterSourceScheme `json:"source_scheme" table:"source scheme" validate:"ne=none" enums:"none,data"`
DestinationScheme ParameterDestinationScheme `json:"destination_scheme" table:"destination scheme" validate:"ne=none" enums:"none,environment_variable,provisioner_variable"`
CreatedAt time.Time `json:"created_at" table:"created at" format:"date-time"`
UpdatedAt time.Time `json:"updated_at" table:"updated at" format:"date-time"`
SourceValue string `json:"source_value"`
}
type ParameterSchema struct {
ID uuid.UUID `json:"id" format:"uuid"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
JobID uuid.UUID `json:"job_id" format:"uuid"`
Name string `json:"name"`
Description string `json:"description"`
DefaultSourceScheme ParameterSourceScheme `json:"default_source_scheme" enums:"none,data"`
DefaultSourceValue string `json:"default_source_value"`
AllowOverrideSource bool `json:"allow_override_source"`
DefaultDestinationScheme ParameterDestinationScheme `json:"default_destination_scheme" enums:"none,environment_variable,provisioner_variable"`
AllowOverrideDestination bool `json:"allow_override_destination"`
DefaultRefresh string `json:"default_refresh"`
RedisplayValue bool `json:"redisplay_value"`
ValidationError string `json:"validation_error"`
ValidationCondition string `json:"validation_condition"`
ValidationTypeSystem string `json:"validation_type_system"`
ValidationValueType string `json:"validation_value_type"`
// This is a special array of items provided if the validation condition
// explicitly states the value must be one of a set.
ValidationContains []string `json:"validation_contains,omitempty"`
}
// CreateParameterRequest is a structure used to create a new parameter value for a scope.
//
// @Description CreateParameterRequest is a structure used to create a new parameter value for a scope.
type CreateParameterRequest struct {
// CloneID allows copying the value of another parameter.
// The other param must be related to the same template_id for this to
// succeed.
// No other fields are required if using this, as all fields will be copied
// from the other parameter.
CloneID uuid.UUID `json:"copy_from_parameter,omitempty" validate:"" format:"uuid"`
Name string `json:"name" validate:"required"`
SourceValue string `json:"source_value" validate:"required"`
SourceScheme ParameterSourceScheme `json:"source_scheme" validate:"oneof=data,required" enums:"none,data"`
DestinationScheme ParameterDestinationScheme `json:"destination_scheme" validate:"oneof=environment_variable provisioner_variable,required" enums:"none,environment_variable,provisioner_variable"`
}
func (c *Client) CreateParameter(ctx context.Context, scope ParameterScope, id uuid.UUID, req CreateParameterRequest) (Parameter, error) {
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/parameters/%s/%s", scope, id.String()), req)
if err != nil {
return Parameter{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return Parameter{}, ReadBodyAsError(res)
}
var param Parameter
return param, json.NewDecoder(res.Body).Decode(&param)
}
func (c *Client) DeleteParameter(ctx context.Context, scope ParameterScope, id uuid.UUID, name string) error {
res, err := c.Request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/parameters/%s/%s/%s", scope, id.String(), name), nil)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return ReadBodyAsError(res)
}
_, _ = io.Copy(io.Discard, res.Body)
return nil
}
func (c *Client) Parameters(ctx context.Context, scope ParameterScope, id uuid.UUID) ([]Parameter, error) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/parameters/%s/%s", scope, id.String()), nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, ReadBodyAsError(res)
}
var parameters []Parameter
return parameters, json.NewDecoder(res.Body).Decode(&parameters)
}

View File

@ -131,8 +131,7 @@ func validationEnabled(param TemplateVersionParameter) bool {
// correctly validates. // correctly validates.
// @typescript-ignore ParameterResolver // @typescript-ignore ParameterResolver
type ParameterResolver struct { type ParameterResolver struct {
Legacy []Parameter Rich []WorkspaceBuildParameter
Rich []WorkspaceBuildParameter
} }
// ValidateResolve checks the provided value, v, against the parameter, p, and the previous build. If v is nil, it also // ValidateResolve checks the provided value, v, against the parameter, p, and the previous build. If v is nil, it also
@ -173,16 +172,5 @@ func (r *ParameterResolver) findLastValue(p TemplateVersionParameter) *Workspace
return &rp return &rp
} }
} }
// For migration purposes, we also support using a legacy variable
if p.LegacyVariableName != "" {
for _, lp := range r.Legacy {
if lp.Name == p.LegacyVariableName {
return &WorkspaceBuildParameter{
Name: p.Name,
Value: lp.SourceValue,
}
}
}
}
return nil return nil
} }

View File

@ -137,45 +137,6 @@ func TestParameterResolver_ValidateResolve_Immutable(t *testing.T) {
require.Equal(t, "", v) require.Equal(t, "", v)
} }
func TestParameterResolver_ValidateResolve_Legacy(t *testing.T) {
t.Parallel()
uut := codersdk.ParameterResolver{
Legacy: []codersdk.Parameter{
{Name: "l", SourceValue: "5"},
{Name: "n", SourceValue: "6"},
},
}
p := codersdk.TemplateVersionParameter{
Name: "n",
Type: "number",
Required: true,
LegacyVariableName: "l",
}
v, err := uut.ValidateResolve(p, nil)
require.NoError(t, err)
require.Equal(t, "5", v)
}
func TestParameterResolver_ValidateResolve_PreferRichOverLegacy(t *testing.T) {
t.Parallel()
uut := codersdk.ParameterResolver{
Rich: []codersdk.WorkspaceBuildParameter{{Name: "n", Value: "7"}},
Legacy: []codersdk.Parameter{
{Name: "l", SourceValue: "5"},
{Name: "n", SourceValue: "6"},
},
}
p := codersdk.TemplateVersionParameter{
Name: "n",
Type: "number",
Required: true,
LegacyVariableName: "l",
}
v, err := uut.ValidateResolve(p, nil)
require.NoError(t, err)
require.Equal(t, "7", v)
}
func TestRichParameterValidation(t *testing.T) { func TestRichParameterValidation(t *testing.T) {
t.Parallel() t.Parallel()

View File

@ -14,7 +14,7 @@ import (
type TemplateVersionWarning string type TemplateVersionWarning string
const ( const (
TemplateVersionWarningDeprecatedParameters TemplateVersionWarning = "DEPRECATED_PARAMETERS" TemplateVersionWarningUnsupportedWorkspaces TemplateVersionWarning = "UNSUPPORTED_WORKSPACES"
) )
// TemplateVersion represents a single version of a template. // TemplateVersion represents a single version of a template.
@ -144,34 +144,6 @@ func (c *Client) TemplateVersionGitAuth(ctx context.Context, version uuid.UUID)
return gitAuth, json.NewDecoder(res.Body).Decode(&gitAuth) return gitAuth, json.NewDecoder(res.Body).Decode(&gitAuth)
} }
// TemplateVersionSchema returns schemas for a template version by ID.
func (c *Client) TemplateVersionSchema(ctx context.Context, version uuid.UUID) ([]ParameterSchema, error) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/schema", version), nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, ReadBodyAsError(res)
}
var params []ParameterSchema
return params, json.NewDecoder(res.Body).Decode(&params)
}
// TemplateVersionParameters returns computed parameters for a template version.
func (c *Client) TemplateVersionParameters(ctx context.Context, version uuid.UUID) ([]ComputedParameter, error) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/parameters", version), nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, ReadBodyAsError(res)
}
var params []ComputedParameter
return params, json.NewDecoder(res.Body).Decode(&params)
}
// TemplateVersionResources returns resources a template version declares. // TemplateVersionResources returns resources a template version declares.
func (c *Client) TemplateVersionResources(ctx context.Context, version uuid.UUID) ([]WorkspaceResource, error) { func (c *Client) TemplateVersionResources(ctx context.Context, version uuid.UUID) ([]WorkspaceResource, error) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/resources", version), nil) res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/resources", version), nil)
@ -209,7 +181,6 @@ func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID
// CreateTemplateVersionDryRun. // CreateTemplateVersionDryRun.
type CreateTemplateVersionDryRunRequest struct { type CreateTemplateVersionDryRunRequest struct {
WorkspaceName string `json:"workspace_name"` WorkspaceName string `json:"workspace_name"`
ParameterValues []CreateParameterRequest `json:"parameter_values"`
RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values"` RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values"`
UserVariableValues []VariableValue `json:"user_variable_values,omitempty"` UserVariableValues []VariableValue `json:"user_variable_values,omitempty"`
} }

View File

@ -67,7 +67,6 @@ type CreateWorkspaceBuildRequest struct {
// ParameterValues are optional. It will write params to the 'workspace' scope. // ParameterValues are optional. It will write params to the 'workspace' scope.
// This will overwrite any existing parameters with the same name. // This will overwrite any existing parameters with the same name.
// This will not delete old params not included in this list. // This will not delete old params not included in this list.
ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"`
RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values,omitempty"` RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values,omitempty"`
// Log level changes the default logging verbosity of a provider ("info" if empty). // Log level changes the default logging verbosity of a provider ("info" if empty).

View File

@ -1177,15 +1177,6 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
"dry_run": true, "dry_run": true,
"log_level": "debug", "log_level": "debug",
"orphan": true, "orphan": true,
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"rich_parameter_values": [ "rich_parameter_values": [
{ {
"name": "string", "name": "string",

View File

@ -1,209 +0,0 @@
# Parameters
## Get parameters
### Code samples
```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/parameters/{scope}/{id} \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY'
```
`GET /parameters/{scope}/{id}`
### Parameters
| Name | In | Type | Required | Description |
| ------- | ---- | ------------ | -------- | ----------- |
| `scope` | path | string | true | Scope |
| `id` | path | string(uuid) | true | ID |
#### Enumerated Values
| Parameter | Value |
| --------- | ------------ |
| `scope` | `template` |
| `scope` | `workspace` |
| `scope` | `import_job` |
### Example responses
> 200 Response
```json
[
{
"created_at": "2019-08-24T14:15:22Z",
"destination_scheme": "none",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"scope": "template",
"scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f",
"source_scheme": "none",
"source_value": "string",
"updated_at": "2019-08-24T14:15:22Z"
}
]
```
### Responses
| Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------- |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.Parameter](schemas.md#codersdkparameter) |
<h3 id="get-parameters-responseschema">Response Schema</h3>
Status Code **200**
| Name | Type | Required | Restrictions | Description |
| ---------------------- | ------------------------------------------------------------------------------------ | -------- | ------------ | ------------------------------------------------- |
| `[array item]` | array | false | | [Parameter represents a set value for the scope.] |
| `» created_at` | string(date-time) | false | | |
| `» destination_scheme` | [codersdk.ParameterDestinationScheme](schemas.md#codersdkparameterdestinationscheme) | false | | |
| `» id` | string(uuid) | false | | |
| `» name` | string | false | | |
| `» scope` | [codersdk.ParameterScope](schemas.md#codersdkparameterscope) | false | | |
| `» scope_id` | string(uuid) | false | | |
| `» source_scheme` | [codersdk.ParameterSourceScheme](schemas.md#codersdkparametersourcescheme) | false | | |
| `» source_value` | string | false | | |
| `» updated_at` | string(date-time) | false | | |
#### Enumerated Values
| Property | Value |
| -------------------- | ---------------------- |
| `destination_scheme` | `none` |
| `destination_scheme` | `environment_variable` |
| `destination_scheme` | `provisioner_variable` |
| `scope` | `template` |
| `scope` | `workspace` |
| `scope` | `import_job` |
| `source_scheme` | `none` |
| `source_scheme` | `data` |
To perform this operation, you must be authenticated. [Learn more](authentication.md).
## Create parameter
### Code samples
```shell
# Example request using curl
curl -X POST http://coder-server:8080/api/v2/parameters/{scope}/{id} \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY'
```
`POST /parameters/{scope}/{id}`
> Body parameter
```json
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
```
### Parameters
| Name | In | Type | Required | Description |
| ------- | ---- | ---------------------------------------------------------------------------- | -------- | ----------------- |
| `scope` | path | string | true | Scope |
| `id` | path | string(uuid) | true | ID |
| `body` | body | [codersdk.CreateParameterRequest](schemas.md#codersdkcreateparameterrequest) | true | Parameter request |
#### Enumerated Values
| Parameter | Value |
| --------- | ------------ |
| `scope` | `template` |
| `scope` | `workspace` |
| `scope` | `import_job` |
### Example responses
> 201 Response
```json
{
"created_at": "2019-08-24T14:15:22Z",
"destination_scheme": "none",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"scope": "template",
"scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f",
"source_scheme": "none",
"source_value": "string",
"updated_at": "2019-08-24T14:15:22Z"
}
```
### Responses
| Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------------ | ----------- | -------------------------------------------------- |
| 201 | [Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) | Created | [codersdk.Parameter](schemas.md#codersdkparameter) |
To perform this operation, you must be authenticated. [Learn more](authentication.md).
## Delete parameter
### Code samples
```shell
# Example request using curl
curl -X DELETE http://coder-server:8080/api/v2/parameters/{scope}/{id}/{name} \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY'
```
`DELETE /parameters/{scope}/{id}/{name}`
### Parameters
| Name | In | Type | Required | Description |
| ------- | ---- | ------------ | -------- | ----------- |
| `scope` | path | string | true | Scope |
| `id` | path | string(uuid) | true | ID |
| `name` | path | string | true | Name |
#### Enumerated Values
| Parameter | Value |
| --------- | ------------ |
| `scope` | `template` |
| `scope` | `workspace` |
| `scope` | `import_job` |
### Example responses
> 200 Response
```json
{
"detail": "string",
"message": "string",
"validations": [
{
"detail": "string",
"field": "string"
}
]
}
```
### Responses
| Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | ------------------------------------------------ |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [codersdk.Response](schemas.md#codersdkresponse) |
To perform this operation, you must be authenticated. [Learn more](authentication.md).

View File

@ -1334,40 +1334,6 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
| ------ | ------ | -------- | ------------ | ----------- | | ------ | ------ | -------- | ------------ | ----------- |
| `name` | string | true | | | | `name` | string | true | | |
## codersdk.CreateParameterRequest
```json
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
```
CreateParameterRequest is a structure used to create a new parameter value for a scope.
### Properties
| Name | Type | Required | Restrictions | Description |
| --------------------- | -------------------------------------------------------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `copy_from_parameter` | string | false | | Copy from parameter allows copying the value of another parameter. The other param must be related to the same template_id for this to succeed. No other fields are required if using this, as all fields will be copied from the other parameter. |
| `destination_scheme` | [codersdk.ParameterDestinationScheme](#codersdkparameterdestinationscheme) | true | | |
| `name` | string | true | | |
| `source_scheme` | [codersdk.ParameterSourceScheme](#codersdkparametersourcescheme) | true | | |
| `source_value` | string | true | | |
#### Enumerated Values
| Property | Value |
| -------------------- | ---------------------- |
| `destination_scheme` | `none` |
| `destination_scheme` | `environment_variable` |
| `destination_scheme` | `provisioner_variable` |
| `source_scheme` | `none` |
| `source_scheme` | `data` |
## codersdk.CreateTemplateRequest ## codersdk.CreateTemplateRequest
```json ```json
@ -1383,51 +1349,32 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"inactivity_ttl_ms": 0, "inactivity_ttl_ms": 0,
"max_ttl_ms": 0, "max_ttl_ms": 0,
"name": "string", "name": "string",
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1"
} }
``` ```
### Properties ### Properties
| Name | Type | Required | Restrictions | Description | | Name | Type | Required | Restrictions | Description |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allow_user_autostart` | boolean | false | | Allow user autostart allows users to set a schedule for autostarting their workspace. By default this is true. This can only be disabled when using an enterprise license. | | `allow_user_autostart` | boolean | false | | Allow user autostart allows users to set a schedule for autostarting their workspace. By default this is true. This can only be disabled when using an enterprise license. |
| `allow_user_autostop` | boolean | false | | Allow user autostop allows users to set a custom workspace TTL to use in place of the template's DefaultTTL field. By default this is true. If false, the DefaultTTL will always be used. This can only be disabled when using an enterprise license. | | `allow_user_autostop` | boolean | false | | Allow user autostop allows users to set a custom workspace TTL to use in place of the template's DefaultTTL field. By default this is true. If false, the DefaultTTL will always be used. This can only be disabled when using an enterprise license. |
| `allow_user_cancel_workspace_jobs` | boolean | false | | Allow users to cancel in-progress workspace jobs. \*bool as the default value is "true". | | `allow_user_cancel_workspace_jobs` | boolean | false | | Allow users to cancel in-progress workspace jobs. \*bool as the default value is "true". |
| `default_ttl_ms` | integer | false | | Default ttl ms allows optionally specifying the default TTL for all workspaces created from this template. | | `default_ttl_ms` | integer | false | | Default ttl ms allows optionally specifying the default TTL for all workspaces created from this template. |
| `description` | string | false | | Description is a description of what the template contains. It must be less than 128 bytes. | | `description` | string | false | | Description is a description of what the template contains. It must be less than 128 bytes. |
| `display_name` | string | false | | Display name is the displayed name of the template. | | `display_name` | string | false | | Display name is the displayed name of the template. |
| `failure_ttl_ms` | integer | false | | Failure ttl ms allows optionally specifying the max lifetime before Coder stops all resources for failed workspaces created from this template. | | `failure_ttl_ms` | integer | false | | Failure ttl ms allows optionally specifying the max lifetime before Coder stops all resources for failed workspaces created from this template. |
| `icon` | string | false | | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard. | | `icon` | string | false | | Icon is a relative path or external URL that specifies an icon to be displayed in the dashboard. |
| `inactivity_ttl_ms` | integer | false | | Inactivity ttl ms allows optionally specifying the max lifetime before Coder deletes inactive workspaces created from this template. | | `inactivity_ttl_ms` | integer | false | | Inactivity ttl ms allows optionally specifying the max lifetime before Coder deletes inactive workspaces created from this template. |
| `max_ttl_ms` | integer | false | | Max ttl ms allows optionally specifying the max lifetime for workspaces created from this template. | | `max_ttl_ms` | integer | false | | Max ttl ms allows optionally specifying the max lifetime for workspaces created from this template. |
| `name` | string | true | | Name is the name of the template. | | `name` | string | true | | Name is the name of the template. |
| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values is a structure used to create a new parameter value for a scope.] | | `template_version_id` | string | true | | Template version ID is an in-progress or completed job to use as an initial version of the template. |
| `template_version_id` | string | true | | Template version ID is an in-progress or completed job to use as an initial version of the template. |
| This is required on creation to enable a user-flow of validating a template works. There is no reason the data-model cannot support empty templates, but it doesn't make sense for users. | | This is required on creation to enable a user-flow of validating a template works. There is no reason the data-model cannot support empty templates, but it doesn't make sense for users. |
## codersdk.CreateTemplateVersionDryRunRequest ## codersdk.CreateTemplateVersionDryRunRequest
```json ```json
{ {
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"rich_parameter_values": [ "rich_parameter_values": [
{ {
"name": "string", "name": "string",
@ -1446,12 +1393,11 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties ### Properties
| Name | Type | Required | Restrictions | Description | | Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------- | | ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | ----------- |
| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values is a structure used to create a new parameter value for a scope.] | | `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | |
| `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | | | `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | |
| `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | | | `workspace_name` | string | false | | |
| `workspace_name` | string | false | | |
## codersdk.CreateTemplateVersionRequest ## codersdk.CreateTemplateVersionRequest
@ -1460,15 +1406,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"example_id": "string", "example_id": "string",
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
"name": "string", "name": "string",
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"provisioner": "terraform", "provisioner": "terraform",
"storage_method": "file", "storage_method": "file",
"tags": { "tags": {
@ -1487,18 +1424,17 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties ### Properties
| Name | Type | Required | Restrictions | Description | | Name | Type | Required | Restrictions | Description |
| ---------------------- | --------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------- | | ---------------------- | ---------------------------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------ |
| `example_id` | string | false | | | | `example_id` | string | false | | |
| `file_id` | string | false | | | | `file_id` | string | false | | |
| `name` | string | false | | | | `name` | string | false | | |
| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values allows for additional parameters to be provided during the dry-run provision stage. | | `provisioner` | string | true | | |
| `provisioner` | string | true | | | | `storage_method` | [codersdk.ProvisionerStorageMethod](#codersdkprovisionerstoragemethod) | true | | |
| `storage_method` | [codersdk.ProvisionerStorageMethod](#codersdkprovisionerstoragemethod) | true | | | | `tags` | object | false | | |
| `tags` | object | false | | | | » `[any property]` | string | false | | |
| » `[any property]` | string | false | | | | `template_id` | string | false | | Template ID optionally associates a version with a template. |
| `template_id` | string | false | | Template ID optionally associates a version with a template. | | `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | |
| `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | |
#### Enumerated Values #### Enumerated Values
@ -1604,15 +1540,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"dry_run": true, "dry_run": true,
"log_level": "debug", "log_level": "debug",
"orphan": true, "orphan": true,
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"rich_parameter_values": [ "rich_parameter_values": [
{ {
"name": "string", "name": "string",
@ -1627,16 +1554,15 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties ### Properties
| Name | Type | Required | Restrictions | Description | | Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dry_run` | boolean | false | | | | `dry_run` | boolean | false | | |
| `log_level` | [codersdk.ProvisionerLogLevel](#codersdkprovisionerloglevel) | false | | Log level changes the default logging verbosity of a provider ("info" if empty). | | `log_level` | [codersdk.ProvisionerLogLevel](#codersdkprovisionerloglevel) | false | | Log level changes the default logging verbosity of a provider ("info" if empty). |
| `orphan` | boolean | false | | Orphan may be set for the Destroy transition. | | `orphan` | boolean | false | | Orphan may be set for the Destroy transition. |
| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values are optional. It will write params to the 'workspace' scope. This will overwrite any existing parameters with the same name. This will not delete old params not included in this list. | | `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | Rich parameter values are optional. It will write params to the 'workspace' scope. This will overwrite any existing parameters with the same name. This will not delete old params not included in this list. |
| `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | | | `state` | array of integer | false | | |
| `state` | array of integer | false | | | | `template_version_id` | string | false | | |
| `template_version_id` | string | false | | | | `transition` | [codersdk.WorkspaceTransition](#codersdkworkspacetransition) | true | | |
| `transition` | [codersdk.WorkspaceTransition](#codersdkworkspacetransition) | true | | |
#### Enumerated Values #### Enumerated Values
@ -1672,15 +1598,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
{ {
"autostart_schedule": "string", "autostart_schedule": "string",
"name": "string", "name": "string",
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"rich_parameter_values": [ "rich_parameter_values": [
{ {
"name": "string", "name": "string",
@ -1694,14 +1611,13 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties ### Properties
| Name | Type | Required | Restrictions | Description | | Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------- | | ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | --------------------------------------------------------------------------------------------------- |
| `autostart_schedule` | string | false | | | | `autostart_schedule` | string | false | | |
| `name` | string | true | | | | `name` | string | true | | |
| `parameter_values` | array of [codersdk.CreateParameterRequest](#codersdkcreateparameterrequest) | false | | Parameter values allows for additional parameters to be provided during the initial provision. | | `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | Rich parameter values allows for additional parameters to be provided during the initial provision. |
| `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | | | `template_id` | string | true | | |
| `template_id` | string | true | | | | `ttl_ms` | integer | false | | |
| `ttl_ms` | integer | false | | |
## codersdk.DAUEntry ## codersdk.DAUEntry
@ -3104,154 +3020,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
| `updated_at` | string | false | | | | `updated_at` | string | false | | |
| `user_id` | string | false | | | | `user_id` | string | false | | |
## codersdk.Parameter
```json
{
"created_at": "2019-08-24T14:15:22Z",
"destination_scheme": "none",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"scope": "template",
"scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f",
"source_scheme": "none",
"source_value": "string",
"updated_at": "2019-08-24T14:15:22Z"
}
```
Parameter represents a set value for the scope.
### Properties
| Name | Type | Required | Restrictions | Description |
| -------------------- | -------------------------------------------------------------------------- | -------- | ------------ | ----------- |
| `created_at` | string | false | | |
| `destination_scheme` | [codersdk.ParameterDestinationScheme](#codersdkparameterdestinationscheme) | false | | |
| `id` | string | false | | |
| `name` | string | false | | |
| `scope` | [codersdk.ParameterScope](#codersdkparameterscope) | false | | |
| `scope_id` | string | false | | |
| `source_scheme` | [codersdk.ParameterSourceScheme](#codersdkparametersourcescheme) | false | | |
| `source_value` | string | false | | |
| `updated_at` | string | false | | |
#### Enumerated Values
| Property | Value |
| -------------------- | ---------------------- |
| `destination_scheme` | `none` |
| `destination_scheme` | `environment_variable` |
| `destination_scheme` | `provisioner_variable` |
| `scope` | `template` |
| `scope` | `workspace` |
| `scope` | `import_job` |
| `source_scheme` | `none` |
| `source_scheme` | `data` |
## codersdk.ParameterDestinationScheme
```json
"none"
```
### Properties
#### Enumerated Values
| Value |
| ---------------------- |
| `none` |
| `environment_variable` |
| `provisioner_variable` |
## codersdk.ParameterSchema
```json
{
"allow_override_destination": true,
"allow_override_source": true,
"created_at": "2019-08-24T14:15:22Z",
"default_destination_scheme": "none",
"default_refresh": "string",
"default_source_scheme": "none",
"default_source_value": "string",
"description": "string",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
"name": "string",
"redisplay_value": true,
"validation_condition": "string",
"validation_contains": ["string"],
"validation_error": "string",
"validation_type_system": "string",
"validation_value_type": "string"
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ---------------------------- | -------------------------------------------------------------------------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `allow_override_destination` | boolean | false | | |
| `allow_override_source` | boolean | false | | |
| `created_at` | string | false | | |
| `default_destination_scheme` | [codersdk.ParameterDestinationScheme](#codersdkparameterdestinationscheme) | false | | |
| `default_refresh` | string | false | | |
| `default_source_scheme` | [codersdk.ParameterSourceScheme](#codersdkparametersourcescheme) | false | | |
| `default_source_value` | string | false | | |
| `description` | string | false | | |
| `id` | string | false | | |
| `job_id` | string | false | | |
| `name` | string | false | | |
| `redisplay_value` | boolean | false | | |
| `validation_condition` | string | false | | |
| `validation_contains` | array of string | false | | This is a special array of items provided if the validation condition explicitly states the value must be one of a set. |
| `validation_error` | string | false | | |
| `validation_type_system` | string | false | | |
| `validation_value_type` | string | false | | |
#### Enumerated Values
| Property | Value |
| ---------------------------- | ---------------------- |
| `default_destination_scheme` | `none` |
| `default_destination_scheme` | `environment_variable` |
| `default_destination_scheme` | `provisioner_variable` |
| `default_source_scheme` | `none` |
| `default_source_scheme` | `data` |
## codersdk.ParameterScope
```json
"template"
```
### Properties
#### Enumerated Values
| Value |
| ------------ |
| `template` |
| `workspace` |
| `import_job` |
## codersdk.ParameterSourceScheme
```json
"none"
```
### Properties
#### Enumerated Values
| Value |
| ------ |
| `none` |
| `data` |
## codersdk.PatchTemplateVersionRequest ## codersdk.PatchTemplateVersionRequest
```json ```json
@ -4142,7 +3910,7 @@ Parameter represents a set value for the scope.
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
``` ```
@ -4300,16 +4068,16 @@ Parameter represents a set value for the scope.
## codersdk.TemplateVersionWarning ## codersdk.TemplateVersionWarning
```json ```json
"DEPRECATED_PARAMETERS" "UNSUPPORTED_WORKSPACES"
``` ```
### Properties ### Properties
#### Enumerated Values #### Enumerated Values
| Value | | Value |
| ----------------------- | | ------------------------ |
| `DEPRECATED_PARAMETERS` | | `UNSUPPORTED_WORKSPACES` |
## codersdk.TokenConfig ## codersdk.TokenConfig
@ -5796,53 +5564,6 @@ Parameter represents a set value for the scope.
| `count` | integer | false | | | | `count` | integer | false | | |
| `workspaces` | array of [codersdk.Workspace](#codersdkworkspace) | false | | | | `workspaces` | array of [codersdk.Workspace](#codersdkworkspace) | false | | |
## database.ParameterDestinationScheme
```json
"none"
```
### Properties
#### Enumerated Values
| Value |
| ---------------------- |
| `none` |
| `environment_variable` |
| `provisioner_variable` |
## database.ParameterScope
```json
"template"
```
### Properties
#### Enumerated Values
| Value |
| ------------ |
| `template` |
| `import_job` |
| `workspace` |
## database.ParameterSourceScheme
```json
"none"
```
### Properties
#### Enumerated Values
| Value |
| ------ |
| `none` |
| `data` |
## derp.ServerInfoMessage ## derp.ServerInfoMessage
```json ```json
@ -6500,40 +6221,6 @@ Parameter represents a set value for the scope.
| `udp` | boolean | false | | a UDP STUN round trip completed | | `udp` | boolean | false | | a UDP STUN round trip completed |
| `upnP` | string | false | | Upnp is whether UPnP appears present on the LAN. Empty means not checked. | | `upnP` | string | false | | Upnp is whether UPnP appears present on the LAN. Empty means not checked. |
## parameter.ComputedValue
```json
{
"created_at": "string",
"default_source_value": true,
"destination_scheme": "none",
"id": "string",
"name": "string",
"schema_id": "string",
"scope": "template",
"scope_id": "string",
"source_scheme": "none",
"source_value": "string",
"updated_at": "string"
}
```
### Properties
| Name | Type | Required | Restrictions | Description |
| ---------------------- | -------------------------------------------------------------------------- | -------- | ------------ | ----------- |
| `created_at` | string | false | | |
| `default_source_value` | boolean | false | | |
| `destination_scheme` | [database.ParameterDestinationScheme](#databaseparameterdestinationscheme) | false | | |
| `id` | string | false | | |
| `name` | string | false | | |
| `schema_id` | string | false | | |
| `scope` | [database.ParameterScope](#databaseparameterscope) | false | | |
| `scope_id` | string | false | | |
| `source_scheme` | [database.ParameterSourceScheme](#databaseparametersourcescheme) | false | | |
| `source_value` | string | false | | |
| `updated_at` | string | false | | |
## sql.NullTime ## sql.NullTime
```json ```json

View File

@ -135,15 +135,6 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
"inactivity_ttl_ms": 0, "inactivity_ttl_ms": 0,
"max_ttl_ms": 0, "max_ttl_ms": 0,
"name": "string", "name": "string",
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1" "template_version_id": "0ba39c92-1f1b-4c32-aa3e-9925d7713eb1"
} }
``` ```
@ -395,7 +386,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
``` ```
@ -473,7 +464,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
``` ```
@ -506,15 +497,6 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
"example_id": "string", "example_id": "string",
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767", "file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
"name": "string", "name": "string",
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"provisioner": "terraform", "provisioner": "terraform",
"storage_method": "file", "storage_method": "file",
"tags": { "tags": {
@ -583,7 +565,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
``` ```
@ -882,7 +864,7 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions \
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
] ]
``` ```
@ -1071,7 +1053,7 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/versions/{templ
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
] ]
``` ```
@ -1204,7 +1186,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion} \
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
``` ```
@ -1290,7 +1272,7 @@ curl -X PATCH http://coder-server:8080/api/v2/templateversions/{templateversion}
"readme": "string", "readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc", "template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"updated_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z",
"warnings": ["DEPRECATED_PARAMETERS"] "warnings": ["UNSUPPORTED_WORKSPACES"]
} }
``` ```
@ -1364,15 +1346,6 @@ curl -X POST http://coder-server:8080/api/v2/templateversions/{templateversion}/
```json ```json
{ {
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"rich_parameter_values": [ "rich_parameter_values": [
{ {
"name": "string", "name": "string",
@ -1949,14 +1922,13 @@ Status Code **200**
To perform this operation, you must be authenticated. [Learn more](authentication.md). To perform this operation, you must be authenticated. [Learn more](authentication.md).
## Get parameters by template version ## Removed: Get parameters by template version
### Code samples ### Code samples
```shell ```shell
# Example request using curl # Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/parameters \ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/parameters \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY' -H 'Coder-Session-Token: API_KEY'
``` ```
@ -1968,65 +1940,11 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/p
| ----------------- | ---- | ------------ | -------- | ------------------- | | ----------------- | ---- | ------------ | -------- | ------------------- |
| `templateversion` | path | string(uuid) | true | Template version ID | | `templateversion` | path | string(uuid) | true | Template version ID |
### Example responses
> 200 Response
```json
[
{
"created_at": "string",
"default_source_value": true,
"destination_scheme": "none",
"id": "string",
"name": "string",
"schema_id": "string",
"scope": "template",
"scope_id": "string",
"source_scheme": "none",
"source_value": "string",
"updated_at": "string"
}
]
```
### Responses ### Responses
| Status | Meaning | Description | Schema | | Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------- | | ------ | ------------------------------------------------------- | ----------- | ------ |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [parameter.ComputedValue](schemas.md#parametercomputedvalue) | | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | |
<h3 id="get-parameters-by-template-version-responseschema">Response Schema</h3>
Status Code **200**
| Name | Type | Required | Restrictions | Description |
| ------------------------ | ------------------------------------------------------------------------------------ | -------- | ------------ | ----------- |
| `[array item]` | array | false | | |
| `» created_at` | string | false | | |
| `» default_source_value` | boolean | false | | |
| `» destination_scheme` | [database.ParameterDestinationScheme](schemas.md#databaseparameterdestinationscheme) | false | | |
| `» id` | string | false | | |
| `» name` | string | false | | |
| `» schema_id` | string | false | | |
| `» scope` | [database.ParameterScope](schemas.md#databaseparameterscope) | false | | |
| `» scope_id` | string | false | | |
| `» source_scheme` | [database.ParameterSourceScheme](schemas.md#databaseparametersourcescheme) | false | | |
| `» source_value` | string | false | | |
| `» updated_at` | string | false | | |
#### Enumerated Values
| Property | Value |
| -------------------- | ---------------------- |
| `destination_scheme` | `none` |
| `destination_scheme` | `environment_variable` |
| `destination_scheme` | `provisioner_variable` |
| `scope` | `template` |
| `scope` | `import_job` |
| `scope` | `workspace` |
| `source_scheme` | `none` |
| `source_scheme` | `data` |
To perform this operation, you must be authenticated. [Learn more](authentication.md). To perform this operation, you must be authenticated. [Learn more](authentication.md).
@ -2345,14 +2263,13 @@ Status Code **200**
To perform this operation, you must be authenticated. [Learn more](authentication.md). To perform this operation, you must be authenticated. [Learn more](authentication.md).
## Get schema by template version ## Removed: Get schema by template version
### Code samples ### Code samples
```shell ```shell
# Example request using curl # Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/schema \ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/schema \
-H 'Accept: application/json' \
-H 'Coder-Session-Token: API_KEY' -H 'Coder-Session-Token: API_KEY'
``` ```
@ -2364,74 +2281,11 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/s
| ----------------- | ---- | ------------ | -------- | ------------------- | | ----------------- | ---- | ------------ | -------- | ------------------- |
| `templateversion` | path | string(uuid) | true | Template version ID | | `templateversion` | path | string(uuid) | true | Template version ID |
### Example responses
> 200 Response
```json
[
{
"allow_override_destination": true,
"allow_override_source": true,
"created_at": "2019-08-24T14:15:22Z",
"default_destination_scheme": "none",
"default_refresh": "string",
"default_source_scheme": "none",
"default_source_value": "string",
"description": "string",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"job_id": "453bd7d7-5355-4d6d-a38e-d9e7eb218c3f",
"name": "string",
"redisplay_value": true,
"validation_condition": "string",
"validation_contains": ["string"],
"validation_error": "string",
"validation_type_system": "string",
"validation_value_type": "string"
}
]
```
### Responses ### Responses
| Status | Meaning | Description | Schema | | Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- | | ------ | ------------------------------------------------------- | ----------- | ------ |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ParameterSchema](schemas.md#codersdkparameterschema) | | 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | |
<h3 id="get-schema-by-template-version-responseschema">Response Schema</h3>
Status Code **200**
| Name | Type | Required | Restrictions | Description |
| ------------------------------ | ------------------------------------------------------------------------------------ | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `[array item]` | array | false | | |
| `» allow_override_destination` | boolean | false | | |
| `» allow_override_source` | boolean | false | | |
| `» created_at` | string(date-time) | false | | |
| `» default_destination_scheme` | [codersdk.ParameterDestinationScheme](schemas.md#codersdkparameterdestinationscheme) | false | | |
| `» default_refresh` | string | false | | |
| `» default_source_scheme` | [codersdk.ParameterSourceScheme](schemas.md#codersdkparametersourcescheme) | false | | |
| `» default_source_value` | string | false | | |
| `» description` | string | false | | |
| `» id` | string(uuid) | false | | |
| `» job_id` | string(uuid) | false | | |
| `» name` | string | false | | |
| `» redisplay_value` | boolean | false | | |
| `» validation_condition` | string | false | | |
| `» validation_contains` | array | false | | This is a special array of items provided if the validation condition explicitly states the value must be one of a set. |
| `» validation_error` | string | false | | |
| `» validation_type_system` | string | false | | |
| `» validation_value_type` | string | false | | |
#### Enumerated Values
| Property | Value |
| ---------------------------- | ---------------------- |
| `default_destination_scheme` | `none` |
| `default_destination_scheme` | `environment_variable` |
| `default_destination_scheme` | `provisioner_variable` |
| `default_source_scheme` | `none` |
| `default_source_scheme` | `data` |
To perform this operation, you must be authenticated. [Learn more](authentication.md). To perform this operation, you must be authenticated. [Learn more](authentication.md).

View File

@ -20,15 +20,6 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member
{ {
"autostart_schedule": "string", "autostart_schedule": "string",
"name": "string", "name": "string",
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"rich_parameter_values": [ "rich_parameter_values": [
{ {
"name": "string", "name": "string",

View File

@ -12,15 +12,6 @@ coder create [flags] [name]
## Options ## Options
### --parameter-file
| | |
| ----------- | ---------------------------------- |
| Type | <code>string</code> |
| Environment | <code>$CODER_PARAMETER_FILE</code> |
Specify a file path with parameter values.
### --rich-parameter-file ### --rich-parameter-file
| | | | | |

View File

@ -164,24 +164,6 @@ Do not wait for agents to start before marking the test as succeeded. This can b
Output format specs in the format "<format>[:<path>]". Not specifying a path will default to stdout. Available formats: text, json. Output format specs in the format "<format>[:<path>]". Not specifying a path will default to stdout. Available formats: text, json.
### --parameter
| | |
| ----------- | ---------------------------------------- |
| Type | <code>string-array</code> |
| Environment | <code>$CODER_SCALETEST_PARAMETERS</code> |
Parameters to use for each workspace. Can be specified multiple times. Overrides any existing parameters with the same name from --parameters-file. Format: key=value.
### --parameters-file
| | |
| ----------- | --------------------------------------------- |
| Type | <code>string</code> |
| Environment | <code>$CODER_SCALETEST_PARAMETERS_FILE</code> |
Path to a YAML file containing the parameters to use for each workspace.
### --run-command ### --run-command
| | | | | |

View File

@ -48,14 +48,6 @@ Specify a failure TTL for workspaces created from this template. This licensed f
Specify an inactivity TTL for workspaces created from this template. This licensed feature's default is 0h (off). Specify an inactivity TTL for workspaces created from this template. This licensed feature's default is 0h (off).
### --parameter-file
| | |
| ---- | ------------------- |
| Type | <code>string</code> |
Specify a file path with parameter values.
### --provisioner-tag ### --provisioner-tag
| | | | | |

View File

@ -37,14 +37,6 @@ Specify the directory to create from, use '-' to read tar from stdin.
Specify a name for the new template version. It will be automatically generated if not provided. Specify a name for the new template version. It will be automatically generated if not provided.
### --parameter-file
| | |
| ---- | ------------------- |
| Type | <code>string</code> |
Specify a file path with parameter values.
### --provisioner-tag ### --provisioner-tag
| | | | | |

View File

@ -26,15 +26,6 @@ Use --always-prompt to change the parameter values of the workspace.
Always prompt all parameters. Does not pull parameter values from existing workspace. Always prompt all parameters. Does not pull parameter values from existing workspace.
### --parameter-file
| | |
| ----------- | ---------------------------------- |
| Type | <code>string</code> |
| Environment | <code>$CODER_PARAMETER_FILE</code> |
Specify a file path with parameter values.
### --rich-parameter-file ### --rich-parameter-file
| | | | | |

View File

@ -457,10 +457,6 @@
"title": "Organizations", "title": "Organizations",
"path": "./api/organizations.md" "path": "./api/organizations.md"
}, },
{
"title": "Parameters",
"path": "./api/parameters.md"
},
{ {
"title": "Schemas", "title": "Schemas",
"path": "./api/schemas.md" "path": "./api/schemas.md"

View File

@ -72,21 +72,6 @@ var (
Complete: &proto.Provision_Complete{}, Complete: &proto.Provision_Complete{},
}, },
}} }}
ParameterSuccess = []*proto.ParameterSchema{
{
AllowOverrideSource: true,
Name: ParameterExecKey,
Description: "description 1",
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: formatExecValue(successKey, ""),
},
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
},
}
) )
// Serve starts the echo provisioner. // Serve starts the echo provisioner.
@ -151,22 +136,6 @@ func (e *echo) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
return nil return nil
} }
for _, param := range msg.GetPlan().GetParameterValues() {
if param.Name == ParameterExecKey {
toks := strings.Split(param.Value, "=")
if len(toks) < 2 {
break
}
switch toks[0] {
case errorKey:
return xerrors.Errorf("returning error: %v", toks[1])
default:
// Do nothing
}
}
}
for index := 0; ; index++ { for index := 0; ; index++ {
var extension string var extension string
if msg.GetPlan() != nil { if msg.GetPlan() != nil {

View File

@ -49,11 +49,7 @@ func TestEcho(t *testing.T) {
}, },
}, { }, {
Type: &proto.Parse_Response_Complete{ Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{ Complete: &proto.Parse_Complete{},
ParameterSchemas: []*proto.ParameterSchema{{
Name: "parameter-schema",
}},
},
}, },
}} }}
data, err := echo.Tar(&echo.Responses{ data, err := echo.Tar(&echo.Responses{
@ -69,8 +65,7 @@ func TestEcho(t *testing.T) {
require.Equal(t, responses[0].GetLog().Output, log.GetLog().Output) require.Equal(t, responses[0].GetLog().Output, log.GetLog().Output)
complete, err := client.Recv() complete, err := client.Recv()
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, responses[1].GetComplete().ParameterSchemas[0].Name, require.NotNil(t, complete)
complete.GetComplete().ParameterSchemas[0].Name)
}) })
t.Run("Provision", func(t *testing.T) { t.Run("Provision", func(t *testing.T) {

View File

@ -64,7 +64,6 @@ func (s *server) Parse(request *proto.Parse_Request, stream proto.DRPCProvisione
return compareSourcePos(variables[i].Pos, variables[j].Pos) return compareSourcePos(variables[i].Pos, variables[j].Pos)
}) })
var parameters []*proto.ParameterSchema
var templateVariables []*proto.TemplateVariable var templateVariables []*proto.TemplateVariable
useManagedVariables := flags != nil && flags[featureUseManagedVariables] useManagedVariables := flags != nil && flags[featureUseManagedVariables]
@ -76,20 +75,12 @@ func (s *server) Parse(request *proto.Parse_Request, stream proto.DRPCProvisione
} }
templateVariables = append(templateVariables, mv) templateVariables = append(templateVariables, mv)
} }
} else { } else if len(variables) > 0 {
for _, v := range variables { return xerrors.Errorf("legacy parameters are not supported anymore, use %q flag to enable managed Terraform variables", featureUseManagedVariables)
schema, err := convertVariableToParameter(v)
if err != nil {
return xerrors.Errorf("convert variable %q: %w", v.Name, err)
}
parameters = append(parameters, schema)
}
} }
return stream.Send(&proto.Parse_Response{ return stream.Send(&proto.Parse_Response{
Type: &proto.Parse_Response_Complete{ Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{ Complete: &proto.Parse_Complete{
ParameterSchemas: parameters,
TemplateVariables: templateVariables, TemplateVariables: templateVariables,
}, },
}, },
@ -164,51 +155,6 @@ func parseFeatures(hclFilepath string) (map[string]bool, bool, hcl.Diagnostics)
return flags, found, diags return flags, found, diags
} }
// Converts a Terraform variable to a provisioner parameter.
func convertVariableToParameter(variable *tfconfig.Variable) (*proto.ParameterSchema, error) {
schema := &proto.ParameterSchema{
Name: variable.Name,
Description: variable.Description,
RedisplayValue: !variable.Sensitive,
AllowOverrideSource: !variable.Sensitive,
ValidationValueType: variable.Type,
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}
if variable.Default != nil {
defaultData, valid := variable.Default.(string)
if !valid {
defaultDataRaw, err := json.Marshal(variable.Default)
if err != nil {
return nil, xerrors.Errorf("parse variable %q default: %w", variable.Name, err)
}
defaultData = string(defaultDataRaw)
}
schema.DefaultSource = &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: defaultData,
}
}
if len(variable.Validations) > 0 && variable.Validations[0].Condition != nil {
// Terraform can contain multiple validation blocks, but it's used sparingly
// from what it appears.
validation := variable.Validations[0]
filedata, err := os.ReadFile(variable.Pos.Filename)
if err != nil {
return nil, xerrors.Errorf("read file %q: %w", variable.Pos.Filename, err)
}
schema.ValidationCondition = string(filedata[validation.Condition.Range().Start.Byte:validation.Condition.Range().End.Byte])
schema.ValidationError = validation.ErrorMessage
schema.ValidationTypeSystem = proto.ParameterSchema_HCL
}
return schema, nil
}
// Converts a Terraform variable to a managed variable. // Converts a Terraform variable to a managed variable.
func convertTerraformVariableToManagedVariable(variable *tfconfig.Variable) (*proto.TemplateVariable, error) { func convertTerraformVariableToManagedVariable(variable *tfconfig.Variable) (*proto.TemplateVariable, error) {
var defaultData string var defaultData string

View File

@ -31,20 +31,20 @@ func TestParse(t *testing.T) {
Files: map[string]string{ Files: map[string]string{
"main.tf": `variable "A" { "main.tf": `variable "A" {
description = "Testing!" description = "Testing!"
}`, }
provider "coder" { feature_use_managed_variables = "true" }`,
}, },
Response: &proto.Parse_Response{ Response: &proto.Parse_Response{
Type: &proto.Parse_Response_Complete{ Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{ Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{{ TemplateVariables: []*proto.TemplateVariable{
Name: "A", {
RedisplayValue: true, Name: "A",
AllowOverrideSource: true, Description: "Testing!",
Description: "Testing!", Required: true,
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
}, },
}}, },
}, },
}, },
}, },
@ -54,23 +54,19 @@ func TestParse(t *testing.T) {
Files: map[string]string{ Files: map[string]string{
"main.tf": `variable "A" { "main.tf": `variable "A" {
default = "wow" default = "wow"
}`, }
provider "coder" { feature_use_managed_variables = "true" }`,
}, },
Response: &proto.Parse_Response{ Response: &proto.Parse_Response{
Type: &proto.Parse_Response_Complete{ Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{ Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{{ TemplateVariables: []*proto.TemplateVariable{
Name: "A", {
RedisplayValue: true, Name: "A",
AllowOverrideSource: true, DefaultValue: "wow",
DefaultSource: &proto.ParameterSource{
Scheme: proto.ParameterSource_DATA,
Value: "wow",
}, },
DefaultDestination: &proto.ParameterDestination{ },
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}},
}, },
}, },
}, },
@ -82,21 +78,19 @@ func TestParse(t *testing.T) {
validation { validation {
condition = var.A == "value" condition = var.A == "value"
} }
}`, }
provider "coder" { feature_use_managed_variables = "true" }`,
}, },
Response: &proto.Parse_Response{ Response: &proto.Parse_Response{
Type: &proto.Parse_Response_Complete{ Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{ Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{{ TemplateVariables: []*proto.TemplateVariable{
Name: "A", {
RedisplayValue: true, Name: "A",
ValidationCondition: `var.A == "value"`, Required: true,
ValidationTypeSystem: proto.ParameterSchema_HCL,
AllowOverrideSource: true,
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
}, },
}}, },
}, },
}, },
}, },
@ -112,49 +106,31 @@ func TestParse(t *testing.T) {
Name: "multiple-variables", Name: "multiple-variables",
Files: map[string]string{ Files: map[string]string{
"main1.tf": `variable "foo" { } "main1.tf": `variable "foo" { }
variable "bar" { }`, variable "bar" { }
provider "coder" { feature_use_managed_variables = "true" }`,
"main2.tf": `variable "baz" { } "main2.tf": `variable "baz" { }
variable "quux" { }`, variable "quux" { }`,
}, },
Response: &proto.Parse_Response{ Response: &proto.Parse_Response{
Type: &proto.Parse_Response_Complete{ Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{ Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{ TemplateVariables: []*proto.TemplateVariable{
{ {
Name: "foo", Name: "foo",
RedisplayValue: true, Required: true,
AllowOverrideSource: true,
Description: "",
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}, },
{ {
Name: "bar", Name: "bar",
RedisplayValue: true, Required: true,
AllowOverrideSource: true,
Description: "",
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}, },
{ {
Name: "baz", Name: "baz",
RedisplayValue: true, Required: true,
AllowOverrideSource: true,
Description: "",
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}, },
{ {
Name: "quux", Name: "quux",
RedisplayValue: true, Required: true,
AllowOverrideSource: true,
Description: "",
DefaultDestination: &proto.ParameterDestination{
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
},
}, },
}, },
}, },

View File

@ -140,7 +140,7 @@ func (s *server) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
return xerrors.Errorf("initialize terraform: %w", err) return xerrors.Errorf("initialize terraform: %w", err)
} }
s.logger.Debug(ctx, "ran initialization") s.logger.Debug(ctx, "ran initialization")
env, err := provisionEnv(config, request.GetPlan().GetParameterValues(), request.GetPlan().GetRichParameterValues(), request.GetPlan().GetGitAuthProviders()) env, err := provisionEnv(config, request.GetPlan().GetRichParameterValues(), request.GetPlan().GetGitAuthProviders())
if err != nil { if err != nil {
return err return err
} }
@ -193,23 +193,13 @@ func (s *server) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
func planVars(plan *proto.Provision_Plan) ([]string, error) { func planVars(plan *proto.Provision_Plan) ([]string, error) {
vars := []string{} vars := []string{}
for _, param := range plan.ParameterValues {
switch param.DestinationScheme {
case proto.ParameterDestination_ENVIRONMENT_VARIABLE:
continue
case proto.ParameterDestination_PROVISIONER_VARIABLE:
vars = append(vars, fmt.Sprintf("%s=%s", param.Name, param.Value))
default:
return nil, xerrors.Errorf("unsupported parameter type %q for %q", param.DestinationScheme, param.Name)
}
}
for _, variable := range plan.VariableValues { for _, variable := range plan.VariableValues {
vars = append(vars, fmt.Sprintf("%s=%s", variable.Name, variable.Value)) vars = append(vars, fmt.Sprintf("%s=%s", variable.Name, variable.Value))
} }
return vars, nil return vars, nil
} }
func provisionEnv(config *proto.Provision_Config, params []*proto.ParameterValue, richParams []*proto.RichParameterValue, gitAuth []*proto.GitAuthProvider) ([]string, error) { func provisionEnv(config *proto.Provision_Config, richParams []*proto.RichParameterValue, gitAuth []*proto.GitAuthProvider) ([]string, error) {
env := safeEnviron() env := safeEnviron()
env = append(env, env = append(env,
"CODER_AGENT_URL="+config.Metadata.CoderUrl, "CODER_AGENT_URL="+config.Metadata.CoderUrl,
@ -225,16 +215,6 @@ func provisionEnv(config *proto.Provision_Config, params []*proto.ParameterValue
for key, value := range provisionersdk.AgentScriptEnv() { for key, value := range provisionersdk.AgentScriptEnv() {
env = append(env, key+"="+value) env = append(env, key+"="+value)
} }
for _, param := range params {
switch param.DestinationScheme {
case proto.ParameterDestination_ENVIRONMENT_VARIABLE:
env = append(env, fmt.Sprintf("%s=%s", param.Name, param.Value))
case proto.ParameterDestination_PROVISIONER_VARIABLE:
continue
default:
return nil, xerrors.Errorf("unsupported parameter type %q for %q", param.DestinationScheme, param.Name)
}
}
for _, param := range richParams { for _, param := range richParams {
env = append(env, provider.ParameterEnvironmentVariable(param.Name)+"="+param.Value) env = append(env, provider.ParameterEnvironmentVariable(param.Name)+"="+param.Value)
} }

View File

@ -203,27 +203,6 @@ func TestProvision(t *testing.T) {
ExpectLogContains string ExpectLogContains string
Apply bool Apply bool
}{ }{
{
Name: "single-variable",
Files: map[string]string{
"main.tf": `variable "A" {
description = "Testing!"
}`,
},
Request: &proto.Provision_Plan{
ParameterValues: []*proto.ParameterValue{{
DestinationScheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
Name: "A",
Value: "example",
}},
},
Response: &proto.Provision_Response{
Type: &proto.Provision_Response_Complete{
Complete: &proto.Provision_Complete{},
},
},
Apply: true,
},
{ {
Name: "missing-variable", Name: "missing-variable",
Files: map[string]string{ Files: map[string]string{
@ -305,22 +284,6 @@ func TestProvision(t *testing.T) {
}, },
ExpectLogContains: "nothing to do", ExpectLogContains: "nothing to do",
}, },
{
Name: "unsupported-parameter-scheme",
Files: map[string]string{
"main.tf": "",
},
Request: &proto.Provision_Plan{
ParameterValues: []*proto.ParameterValue{
{
DestinationScheme: 88,
Name: "UNSUPPORTED",
Value: "sadface",
},
},
},
ErrorContains: "unsupported parameter type",
},
{ {
Name: "rich-parameter-with-value", Name: "rich-parameter-with-value",
Files: map[string]string{ Files: map[string]string{
@ -462,7 +425,6 @@ func TestProvision(t *testing.T) {
if planRequest.GetPlan().GetConfig() == nil { if planRequest.GetPlan().GetConfig() == nil {
planRequest.GetPlan().Config = &proto.Provision_Config{} planRequest.GetPlan().Config = &proto.Provision_Config{}
} }
planRequest.GetPlan().ParameterValues = testCase.Request.ParameterValues
planRequest.GetPlan().RichParameterValues = testCase.Request.RichParameterValues planRequest.GetPlan().RichParameterValues = testCase.Request.RichParameterValues
planRequest.GetPlan().GitAuthProviders = testCase.Request.GitAuthProviders planRequest.GetPlan().GitAuthProviders = testCase.Request.GitAuthProviders
if testCase.Request.Config != nil { if testCase.Request.Config != nil {

View File

@ -564,7 +564,6 @@ type UpdateJobRequest struct {
JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"` JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
Logs []*Log `protobuf:"bytes,2,rep,name=logs,proto3" json:"logs,omitempty"` Logs []*Log `protobuf:"bytes,2,rep,name=logs,proto3" json:"logs,omitempty"`
ParameterSchemas []*proto.ParameterSchema `protobuf:"bytes,3,rep,name=parameter_schemas,json=parameterSchemas,proto3" json:"parameter_schemas,omitempty"`
TemplateVariables []*proto.TemplateVariable `protobuf:"bytes,4,rep,name=template_variables,json=templateVariables,proto3" json:"template_variables,omitempty"` TemplateVariables []*proto.TemplateVariable `protobuf:"bytes,4,rep,name=template_variables,json=templateVariables,proto3" json:"template_variables,omitempty"`
UserVariableValues []*proto.VariableValue `protobuf:"bytes,5,rep,name=user_variable_values,json=userVariableValues,proto3" json:"user_variable_values,omitempty"` UserVariableValues []*proto.VariableValue `protobuf:"bytes,5,rep,name=user_variable_values,json=userVariableValues,proto3" json:"user_variable_values,omitempty"`
Readme []byte `protobuf:"bytes,6,opt,name=readme,proto3" json:"readme,omitempty"` Readme []byte `protobuf:"bytes,6,opt,name=readme,proto3" json:"readme,omitempty"`
@ -616,13 +615,6 @@ func (x *UpdateJobRequest) GetLogs() []*Log {
return nil return nil
} }
func (x *UpdateJobRequest) GetParameterSchemas() []*proto.ParameterSchema {
if x != nil {
return x.ParameterSchemas
}
return nil
}
func (x *UpdateJobRequest) GetTemplateVariables() []*proto.TemplateVariable { func (x *UpdateJobRequest) GetTemplateVariables() []*proto.TemplateVariable {
if x != nil { if x != nil {
return x.TemplateVariables return x.TemplateVariables
@ -649,11 +641,8 @@ type UpdateJobResponse struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Canceled bool `protobuf:"varint,1,opt,name=canceled,proto3" json:"canceled,omitempty"` Canceled bool `protobuf:"varint,1,opt,name=canceled,proto3" json:"canceled,omitempty"`
// If parameter schemas are sent, the job will respond VariableValues []*proto.VariableValue `protobuf:"bytes,3,rep,name=variable_values,json=variableValues,proto3" json:"variable_values,omitempty"`
// with resolved parameter values.
ParameterValues []*proto.ParameterValue `protobuf:"bytes,2,rep,name=parameter_values,json=parameterValues,proto3" json:"parameter_values,omitempty"`
VariableValues []*proto.VariableValue `protobuf:"bytes,3,rep,name=variable_values,json=variableValues,proto3" json:"variable_values,omitempty"`
} }
func (x *UpdateJobResponse) Reset() { func (x *UpdateJobResponse) Reset() {
@ -695,13 +684,6 @@ func (x *UpdateJobResponse) GetCanceled() bool {
return false return false
} }
func (x *UpdateJobResponse) GetParameterValues() []*proto.ParameterValue {
if x != nil {
return x.ParameterValues
}
return nil
}
func (x *UpdateJobResponse) GetVariableValues() []*proto.VariableValue { func (x *UpdateJobResponse) GetVariableValues() []*proto.VariableValue {
if x != nil { if x != nil {
return x.VariableValues return x.VariableValues
@ -834,7 +816,6 @@ type AcquiredJob_WorkspaceBuild struct {
WorkspaceBuildId string `protobuf:"bytes,1,opt,name=workspace_build_id,json=workspaceBuildId,proto3" json:"workspace_build_id,omitempty"` WorkspaceBuildId string `protobuf:"bytes,1,opt,name=workspace_build_id,json=workspaceBuildId,proto3" json:"workspace_build_id,omitempty"`
WorkspaceName string `protobuf:"bytes,2,opt,name=workspace_name,json=workspaceName,proto3" json:"workspace_name,omitempty"` WorkspaceName string `protobuf:"bytes,2,opt,name=workspace_name,json=workspaceName,proto3" json:"workspace_name,omitempty"`
ParameterValues []*proto.ParameterValue `protobuf:"bytes,3,rep,name=parameter_values,json=parameterValues,proto3" json:"parameter_values,omitempty"`
RichParameterValues []*proto.RichParameterValue `protobuf:"bytes,4,rep,name=rich_parameter_values,json=richParameterValues,proto3" json:"rich_parameter_values,omitempty"` RichParameterValues []*proto.RichParameterValue `protobuf:"bytes,4,rep,name=rich_parameter_values,json=richParameterValues,proto3" json:"rich_parameter_values,omitempty"`
VariableValues []*proto.VariableValue `protobuf:"bytes,5,rep,name=variable_values,json=variableValues,proto3" json:"variable_values,omitempty"` VariableValues []*proto.VariableValue `protobuf:"bytes,5,rep,name=variable_values,json=variableValues,proto3" json:"variable_values,omitempty"`
GitAuthProviders []*proto.GitAuthProvider `protobuf:"bytes,6,rep,name=git_auth_providers,json=gitAuthProviders,proto3" json:"git_auth_providers,omitempty"` GitAuthProviders []*proto.GitAuthProvider `protobuf:"bytes,6,rep,name=git_auth_providers,json=gitAuthProviders,proto3" json:"git_auth_providers,omitempty"`
@ -889,13 +870,6 @@ func (x *AcquiredJob_WorkspaceBuild) GetWorkspaceName() string {
return "" return ""
} }
func (x *AcquiredJob_WorkspaceBuild) GetParameterValues() []*proto.ParameterValue {
if x != nil {
return x.ParameterValues
}
return nil
}
func (x *AcquiredJob_WorkspaceBuild) GetRichParameterValues() []*proto.RichParameterValue { func (x *AcquiredJob_WorkspaceBuild) GetRichParameterValues() []*proto.RichParameterValue {
if x != nil { if x != nil {
return x.RichParameterValues return x.RichParameterValues
@ -998,7 +972,6 @@ type AcquiredJob_TemplateDryRun struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
ParameterValues []*proto.ParameterValue `protobuf:"bytes,1,rep,name=parameter_values,json=parameterValues,proto3" json:"parameter_values,omitempty"`
RichParameterValues []*proto.RichParameterValue `protobuf:"bytes,2,rep,name=rich_parameter_values,json=richParameterValues,proto3" json:"rich_parameter_values,omitempty"` RichParameterValues []*proto.RichParameterValue `protobuf:"bytes,2,rep,name=rich_parameter_values,json=richParameterValues,proto3" json:"rich_parameter_values,omitempty"`
VariableValues []*proto.VariableValue `protobuf:"bytes,3,rep,name=variable_values,json=variableValues,proto3" json:"variable_values,omitempty"` VariableValues []*proto.VariableValue `protobuf:"bytes,3,rep,name=variable_values,json=variableValues,proto3" json:"variable_values,omitempty"`
Metadata *proto.Provision_Metadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"` Metadata *proto.Provision_Metadata `protobuf:"bytes,4,opt,name=metadata,proto3" json:"metadata,omitempty"`
@ -1036,13 +1009,6 @@ func (*AcquiredJob_TemplateDryRun) Descriptor() ([]byte, []int) {
return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{1, 2} return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{1, 2}
} }
func (x *AcquiredJob_TemplateDryRun) GetParameterValues() []*proto.ParameterValue {
if x != nil {
return x.ParameterValues
}
return nil
}
func (x *AcquiredJob_TemplateDryRun) GetRichParameterValues() []*proto.RichParameterValue { func (x *AcquiredJob_TemplateDryRun) GetRichParameterValues() []*proto.RichParameterValue {
if x != nil { if x != nil {
return x.RichParameterValues return x.RichParameterValues
@ -1369,7 +1335,7 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
0x6f, 0x6e, 0x65, 0x72, 0x64, 0x1a, 0x26, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x1a, 0x26, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x76,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a,
0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xaf, 0x0c, 0x0a, 0x0b, 0x41, 0x63, 0x71, 0x75, 0x69, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xab, 0x0b, 0x0a, 0x0b, 0x41, 0x63, 0x71, 0x75, 0x69,
0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x1d, 0x0a,
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
@ -1402,230 +1368,214 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69,
0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x63, 0x65,
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x83, 0x04, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xc1, 0x03, 0x0a, 0x0e, 0x57, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72,
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65,
0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69,
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56,
0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a,
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72,
0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69,
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x67, 0x69,
0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73,
0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x47, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76,
0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x69, 0x64, 0x65, 0x72, 0x52, 0x10, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f,
0x65, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x67, 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x47, 0x69, 0x74, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x10, 0x67, 0x69, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01,
0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67,
0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x1a, 0x9b, 0x01, 0x0a,
0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12,
0x74, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x09, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x1a, 0x9b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x01, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4c, 0x0a, 0x14,
0x74, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61,
0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69,
0x0a, 0x14, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0xed, 0x01, 0x0a, 0x0e, 0x54,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x53, 0x0a,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f,
0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70,
0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0xaf, 0x02, 0x0a, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50,
0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72,
0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75,
0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72,
0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61,
0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0x40, 0x0a, 0x12, 0x54, 0x72,
0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04,
0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x74, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x03, 0x0a, 0x09, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a,
0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72,
0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x40, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12,
0x0a, 0x12, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x51, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69,
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64,
0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x03, 0x0a, 0x09, 0x46, 0x61, 0x69, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69,
0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x6c, 0x64, 0x12, 0x51, 0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72,
0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65,
0x72, 0x6f, 0x72, 0x12, 0x51, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70,
0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x52, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x65, 0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x51, 0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
0x74, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46,
0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x52, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65,
0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0x26, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b,
0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x1d, 0x0a, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f,
0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x72, 0x74, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72,
0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0x26, 0x0a, 0x0e, 0x79, 0x52, 0x75, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xd8, 0x05, 0x0a,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a,
0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a,
0x74, 0x61, 0x74, 0x65, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e,
0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d,
0x22, 0xd8, 0x05, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b,
0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x74, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20,
0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00,
0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x54, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74,
0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x12, 0x55, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x79,
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f,
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44,
0x72, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x70, 0x6f, 0x72, 0x74, 0x12, 0x55, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x5b, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12,
0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x5b, 0x0a, 0x0e, 0x57, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x81, 0x02, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74,
0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52,
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x81, 0x02, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x70, 0x5f,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x0f, 0x73, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x6f,
0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61,
0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a,
0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63,
0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x72, 0x69, 0x63, 0x68,
0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x69,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x69, 0x63, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73,
0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x45, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70,
0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65,
0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e,
0x0a, 0x12, 0x67, 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f,
0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x41, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x42,
0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x45, 0x0a, 0x0e, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12,
0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x33, 0x2f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c,
0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x12, 0x2b, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x63, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f,
0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a,
0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05,
0x75, 0x72, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61,
0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01,
0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x10, 0x55,
0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02,
0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xcf, 0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x4c, 0x0a,
0x02, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x12, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62,
0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x14, 0x75,
0x73, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x73, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c,
0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61,
0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x4c, 0x0a, 0x12, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61,
0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x64, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d,
0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x65, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x7a, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08,
0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x14, 0x75, 0x73, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69,
0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4a, 0x04, 0x08,
0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x02, 0x10, 0x03, 0x22, 0x4a, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f,
0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62,
0x22, 0xbc, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02,
0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x73, 0x74, 0x22,
0x65, 0x64, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x68, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74,
0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x05, 0x52, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x2a, 0x34, 0x0a, 0x09, 0x4c, 0x6f, 0x67,
0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53,
0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0f,
0x4a, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x32,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0xec, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x44,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x0a, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65,
0x64, 0x61, 0x69, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x4a, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x52, 0x09, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x68, 0x0a, 0x13, 0x43, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x4a, 0x6f, 0x62, 0x12, 0x52, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f,
0x6f, 0x6b, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x74, 0x61, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x71,
0x65, 0x64, 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52,
0x75, 0x64, 0x67, 0x65, 0x74, 0x2a, 0x34, 0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74,
0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71,
0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x32, 0xec, 0x02, 0x0a, 0x11, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73,
0x6e, 0x12, 0x3c, 0x0a, 0x0a, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x4a, 0x6f, 0x62,
0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e,
0x52, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a, 0x2e,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d,
0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x2b,
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64,
0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x74, 0x6f, 0x33,
0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c,
0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3e, 0x0a, 0x0b, 0x43, 0x6f,
0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74,
0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63,
0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -1664,15 +1614,13 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{
(*CompletedJob_TemplateImport)(nil), // 18: provisionerd.CompletedJob.TemplateImport (*CompletedJob_TemplateImport)(nil), // 18: provisionerd.CompletedJob.TemplateImport
(*CompletedJob_TemplateDryRun)(nil), // 19: provisionerd.CompletedJob.TemplateDryRun (*CompletedJob_TemplateDryRun)(nil), // 19: provisionerd.CompletedJob.TemplateDryRun
(proto.LogLevel)(0), // 20: provisioner.LogLevel (proto.LogLevel)(0), // 20: provisioner.LogLevel
(*proto.ParameterSchema)(nil), // 21: provisioner.ParameterSchema (*proto.TemplateVariable)(nil), // 21: provisioner.TemplateVariable
(*proto.TemplateVariable)(nil), // 22: provisioner.TemplateVariable (*proto.VariableValue)(nil), // 22: provisioner.VariableValue
(*proto.VariableValue)(nil), // 23: provisioner.VariableValue (*proto.RichParameterValue)(nil), // 23: provisioner.RichParameterValue
(*proto.ParameterValue)(nil), // 24: provisioner.ParameterValue (*proto.GitAuthProvider)(nil), // 24: provisioner.GitAuthProvider
(*proto.RichParameterValue)(nil), // 25: provisioner.RichParameterValue (*proto.Provision_Metadata)(nil), // 25: provisioner.Provision.Metadata
(*proto.GitAuthProvider)(nil), // 26: provisioner.GitAuthProvider (*proto.Resource)(nil), // 26: provisioner.Resource
(*proto.Provision_Metadata)(nil), // 27: provisioner.Provision.Metadata (*proto.RichParameter)(nil), // 27: provisioner.RichParameter
(*proto.Resource)(nil), // 28: provisioner.Resource
(*proto.RichParameter)(nil), // 29: provisioner.RichParameter
} }
var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{ var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{
10, // 0: provisionerd.AcquiredJob.workspace_build:type_name -> provisionerd.AcquiredJob.WorkspaceBuild 10, // 0: provisionerd.AcquiredJob.workspace_build:type_name -> provisionerd.AcquiredJob.WorkspaceBuild
@ -1688,42 +1636,38 @@ var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{
0, // 10: provisionerd.Log.source:type_name -> provisionerd.LogSource 0, // 10: provisionerd.Log.source:type_name -> provisionerd.LogSource
20, // 11: provisionerd.Log.level:type_name -> provisioner.LogLevel 20, // 11: provisionerd.Log.level:type_name -> provisioner.LogLevel
5, // 12: provisionerd.UpdateJobRequest.logs:type_name -> provisionerd.Log 5, // 12: provisionerd.UpdateJobRequest.logs:type_name -> provisionerd.Log
21, // 13: provisionerd.UpdateJobRequest.parameter_schemas:type_name -> provisioner.ParameterSchema 21, // 13: provisionerd.UpdateJobRequest.template_variables:type_name -> provisioner.TemplateVariable
22, // 14: provisionerd.UpdateJobRequest.template_variables:type_name -> provisioner.TemplateVariable 22, // 14: provisionerd.UpdateJobRequest.user_variable_values:type_name -> provisioner.VariableValue
23, // 15: provisionerd.UpdateJobRequest.user_variable_values:type_name -> provisioner.VariableValue 22, // 15: provisionerd.UpdateJobResponse.variable_values:type_name -> provisioner.VariableValue
24, // 16: provisionerd.UpdateJobResponse.parameter_values:type_name -> provisioner.ParameterValue 23, // 16: provisionerd.AcquiredJob.WorkspaceBuild.rich_parameter_values:type_name -> provisioner.RichParameterValue
23, // 17: provisionerd.UpdateJobResponse.variable_values:type_name -> provisioner.VariableValue 22, // 17: provisionerd.AcquiredJob.WorkspaceBuild.variable_values:type_name -> provisioner.VariableValue
24, // 18: provisionerd.AcquiredJob.WorkspaceBuild.parameter_values:type_name -> provisioner.ParameterValue 24, // 18: provisionerd.AcquiredJob.WorkspaceBuild.git_auth_providers:type_name -> provisioner.GitAuthProvider
25, // 19: provisionerd.AcquiredJob.WorkspaceBuild.rich_parameter_values:type_name -> provisioner.RichParameterValue 25, // 19: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata
23, // 20: provisionerd.AcquiredJob.WorkspaceBuild.variable_values:type_name -> provisioner.VariableValue 25, // 20: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata
26, // 21: provisionerd.AcquiredJob.WorkspaceBuild.git_auth_providers:type_name -> provisioner.GitAuthProvider 22, // 21: provisionerd.AcquiredJob.TemplateImport.user_variable_values:type_name -> provisioner.VariableValue
27, // 22: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata 23, // 22: provisionerd.AcquiredJob.TemplateDryRun.rich_parameter_values:type_name -> provisioner.RichParameterValue
27, // 23: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata 22, // 23: provisionerd.AcquiredJob.TemplateDryRun.variable_values:type_name -> provisioner.VariableValue
23, // 24: provisionerd.AcquiredJob.TemplateImport.user_variable_values:type_name -> provisioner.VariableValue 25, // 24: provisionerd.AcquiredJob.TemplateDryRun.metadata:type_name -> provisioner.Provision.Metadata
24, // 25: provisionerd.AcquiredJob.TemplateDryRun.parameter_values:type_name -> provisioner.ParameterValue 26, // 25: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource
25, // 26: provisionerd.AcquiredJob.TemplateDryRun.rich_parameter_values:type_name -> provisioner.RichParameterValue 26, // 26: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource
23, // 27: provisionerd.AcquiredJob.TemplateDryRun.variable_values:type_name -> provisioner.VariableValue 26, // 27: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource
27, // 28: provisionerd.AcquiredJob.TemplateDryRun.metadata:type_name -> provisioner.Provision.Metadata 27, // 28: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter
28, // 29: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource 26, // 29: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource
28, // 30: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource 1, // 30: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty
28, // 31: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource 8, // 31: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest
29, // 32: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter 6, // 32: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest
28, // 33: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource 3, // 33: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob
1, // 34: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty 4, // 34: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob
8, // 35: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest 2, // 35: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob
6, // 36: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest 9, // 36: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse
3, // 37: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob 7, // 37: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse
4, // 38: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob 1, // 38: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty
2, // 39: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob 1, // 39: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty
9, // 40: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse 35, // [35:40] is the sub-list for method output_type
7, // 41: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse 30, // [30:35] is the sub-list for method input_type
1, // 42: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty 30, // [30:30] is the sub-list for extension type_name
1, // 43: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty 30, // [30:30] is the sub-list for extension extendee
39, // [39:44] is the sub-list for method output_type 0, // [0:30] is the sub-list for field type_name
34, // [34:39] is the sub-list for method input_type
34, // [34:34] is the sub-list for extension type_name
34, // [34:34] is the sub-list for extension extendee
0, // [0:34] is the sub-list for field type_name
} }
func init() { file_provisionerd_proto_provisionerd_proto_init() } func init() { file_provisionerd_proto_provisionerd_proto_init() }

View File

@ -12,9 +12,10 @@ message Empty {}
// AcquiredJob is returned when a provisioner daemon has a job locked. // AcquiredJob is returned when a provisioner daemon has a job locked.
message AcquiredJob { message AcquiredJob {
message WorkspaceBuild { message WorkspaceBuild {
reserved 3;
string workspace_build_id = 1; string workspace_build_id = 1;
string workspace_name = 2; string workspace_name = 2;
repeated provisioner.ParameterValue parameter_values = 3;
repeated provisioner.RichParameterValue rich_parameter_values = 4; repeated provisioner.RichParameterValue rich_parameter_values = 4;
repeated provisioner.VariableValue variable_values = 5; repeated provisioner.VariableValue variable_values = 5;
repeated provisioner.GitAuthProvider git_auth_providers = 6; repeated provisioner.GitAuthProvider git_auth_providers = 6;
@ -27,7 +28,8 @@ message AcquiredJob {
repeated provisioner.VariableValue user_variable_values = 2; repeated provisioner.VariableValue user_variable_values = 2;
} }
message TemplateDryRun { message TemplateDryRun {
repeated provisioner.ParameterValue parameter_values = 1; reserved 1;
repeated provisioner.RichParameterValue rich_parameter_values = 2; repeated provisioner.RichParameterValue rich_parameter_values = 2;
repeated provisioner.VariableValue variable_values = 3; repeated provisioner.VariableValue variable_values = 3;
provisioner.Provision.Metadata metadata = 4; provisioner.Provision.Metadata metadata = 4;
@ -106,19 +108,19 @@ message Log {
// This message should be sent periodically as a heartbeat. // This message should be sent periodically as a heartbeat.
message UpdateJobRequest { message UpdateJobRequest {
reserved 3;
string job_id = 1; string job_id = 1;
repeated Log logs = 2; repeated Log logs = 2;
repeated provisioner.ParameterSchema parameter_schemas = 3;
repeated provisioner.TemplateVariable template_variables = 4; repeated provisioner.TemplateVariable template_variables = 4;
repeated provisioner.VariableValue user_variable_values = 5; repeated provisioner.VariableValue user_variable_values = 5;
bytes readme = 6; bytes readme = 6;
} }
message UpdateJobResponse { message UpdateJobResponse {
reserved 2;
bool canceled = 1; bool canceled = 1;
// If parameter schemas are sent, the job will respond
// with resolved parameter values.
repeated provisioner.ParameterValue parameter_values = 2;
repeated provisioner.VariableValue variable_values = 3; repeated provisioner.VariableValue variable_values = 3;
} }

View File

@ -371,18 +371,6 @@ func TestProvisionerd(t *testing.T) {
completeChan = make(chan struct{}) completeChan = make(chan struct{})
completeOnce sync.Once completeOnce sync.Once
parameterValues = []*sdkproto.ParameterValue{
{
DestinationScheme: sdkproto.ParameterDestination_PROVISIONER_VARIABLE,
Name: "test_var",
Value: "dean was here",
},
{
DestinationScheme: sdkproto.ParameterDestination_PROVISIONER_VARIABLE,
Name: "test_var_2",
Value: "1234",
},
}
metadata = &sdkproto.Provision_Metadata{} metadata = &sdkproto.Provision_Metadata{}
) )
@ -402,8 +390,7 @@ func TestProvisionerd(t *testing.T) {
}), }),
Type: &proto.AcquiredJob_TemplateDryRun_{ Type: &proto.AcquiredJob_TemplateDryRun_{
TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{ TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{
ParameterValues: parameterValues, Metadata: metadata,
Metadata: metadata,
}, },
}, },
}, nil }, nil

View File

@ -344,7 +344,6 @@ func (r *Runner) update(ctx context.Context, u *proto.UpdateJobRequest) (*proto.
span.SetAttributes( span.SetAttributes(
attribute.Int64("logs_len", int64(len(u.Logs))), attribute.Int64("logs_len", int64(len(u.Logs))),
attribute.Int64("parameter_schemas_len", int64(len(u.ParameterSchemas))),
attribute.Int64("template_variables_len", int64(len(u.TemplateVariables))), attribute.Int64("template_variables_len", int64(len(u.TemplateVariables))),
attribute.Int64("user_variable_values_len", int64(len(u.UserVariableValues))), attribute.Int64("user_variable_values_len", int64(len(u.UserVariableValues))),
attribute.Int64("readme_len", int64(len(u.Readme))), attribute.Int64("readme_len", int64(len(u.Readme))),
@ -500,7 +499,6 @@ func (r *Runner) do(ctx context.Context) (*proto.CompletedJob, *proto.FailedJob)
case *proto.AcquiredJob_TemplateDryRun_: case *proto.AcquiredJob_TemplateDryRun_:
r.logger.Debug(context.Background(), "acquired job is template dry-run", r.logger.Debug(context.Background(), "acquired job is template dry-run",
slog.F("workspace_name", jobType.TemplateDryRun.Metadata.WorkspaceName), slog.F("workspace_name", jobType.TemplateDryRun.Metadata.WorkspaceName),
slog.F("parameters", jobType.TemplateDryRun.ParameterValues),
slog.F("rich_parameter_values", jobType.TemplateDryRun.RichParameterValues), slog.F("rich_parameter_values", jobType.TemplateDryRun.RichParameterValues),
slog.F("variable_values", redactVariableValues(jobType.TemplateDryRun.VariableValues)), slog.F("variable_values", redactVariableValues(jobType.TemplateDryRun.VariableValues)),
) )
@ -509,7 +507,6 @@ func (r *Runner) do(ctx context.Context) (*proto.CompletedJob, *proto.FailedJob)
r.logger.Debug(context.Background(), "acquired job is workspace provision", r.logger.Debug(context.Background(), "acquired job is workspace provision",
slog.F("workspace_name", jobType.WorkspaceBuild.WorkspaceName), slog.F("workspace_name", jobType.WorkspaceBuild.WorkspaceName),
slog.F("state_length", len(jobType.WorkspaceBuild.State)), slog.F("state_length", len(jobType.WorkspaceBuild.State)),
slog.F("parameters", jobType.WorkspaceBuild.ParameterValues),
slog.F("rich_parameter_values", jobType.WorkspaceBuild.RichParameterValues), slog.F("rich_parameter_values", jobType.WorkspaceBuild.RichParameterValues),
slog.F("variable_values", redactVariableValues(jobType.WorkspaceBuild.VariableValues)), slog.F("variable_values", redactVariableValues(jobType.WorkspaceBuild.VariableValues)),
) )
@ -617,7 +614,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
Stage: "Parsing template parameters", Stage: "Parsing template parameters",
CreatedAt: time.Now().UnixMilli(), CreatedAt: time.Now().UnixMilli(),
}) })
parameterSchemas, templateVariables, err := r.runTemplateImportParse(ctx) templateVariables, err := r.runTemplateImportParse(ctx)
if err != nil { if err != nil {
return nil, r.failedJobf("run parse: %s", err) return nil, r.failedJobf("run parse: %s", err)
} }
@ -626,7 +623,6 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
// to store in database and filter valid ones. // to store in database and filter valid ones.
updateResponse, err := r.update(ctx, &proto.UpdateJobRequest{ updateResponse, err := r.update(ctx, &proto.UpdateJobRequest{
JobId: r.job.JobId, JobId: r.job.JobId,
ParameterSchemas: parameterSchemas,
TemplateVariables: templateVariables, TemplateVariables: templateVariables,
UserVariableValues: r.job.GetTemplateImport().GetUserVariableValues(), UserVariableValues: r.job.GetTemplateImport().GetUserVariableValues(),
}) })
@ -634,17 +630,6 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
return nil, r.failedJobf("update job: %s", err) return nil, r.failedJobf("update job: %s", err)
} }
valueByName := map[string]*sdkproto.ParameterValue{}
for _, parameterValue := range updateResponse.ParameterValues {
valueByName[parameterValue.Name] = parameterValue
}
for _, parameterSchema := range parameterSchemas {
_, ok := valueByName[parameterSchema.Name]
if !ok {
return nil, r.failedJobf("%s: %s", missingParameterErrorText, parameterSchema.Name)
}
}
// Determine persistent resources // Determine persistent resources
r.queueLog(ctx, &proto.Log{ r.queueLog(ctx, &proto.Log{
Source: proto.LogSource_PROVISIONER_DAEMON, Source: proto.LogSource_PROVISIONER_DAEMON,
@ -652,7 +637,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
Stage: "Detecting persistent resources", Stage: "Detecting persistent resources",
CreatedAt: time.Now().UnixMilli(), CreatedAt: time.Now().UnixMilli(),
}) })
startProvision, err := r.runTemplateImportProvision(ctx, updateResponse.ParameterValues, updateResponse.VariableValues, &sdkproto.Provision_Metadata{ startProvision, err := r.runTemplateImportProvision(ctx, updateResponse.VariableValues, &sdkproto.Provision_Metadata{
CoderUrl: r.job.GetTemplateImport().Metadata.CoderUrl, CoderUrl: r.job.GetTemplateImport().Metadata.CoderUrl,
WorkspaceTransition: sdkproto.WorkspaceTransition_START, WorkspaceTransition: sdkproto.WorkspaceTransition_START,
}) })
@ -667,7 +652,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
Stage: "Detecting ephemeral resources", Stage: "Detecting ephemeral resources",
CreatedAt: time.Now().UnixMilli(), CreatedAt: time.Now().UnixMilli(),
}) })
stopProvision, err := r.runTemplateImportProvision(ctx, updateResponse.ParameterValues, updateResponse.VariableValues, &sdkproto.Provision_Metadata{ stopProvision, err := r.runTemplateImportProvision(ctx, updateResponse.VariableValues, &sdkproto.Provision_Metadata{
CoderUrl: r.job.GetTemplateImport().Metadata.CoderUrl, CoderUrl: r.job.GetTemplateImport().Metadata.CoderUrl,
WorkspaceTransition: sdkproto.WorkspaceTransition_STOP, WorkspaceTransition: sdkproto.WorkspaceTransition_STOP,
}) })
@ -689,7 +674,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
} }
// Parses template variables and parameter schemas from source. // Parses template variables and parameter schemas from source.
func (r *Runner) runTemplateImportParse(ctx context.Context) ([]*sdkproto.ParameterSchema, []*sdkproto.TemplateVariable, error) { func (r *Runner) runTemplateImportParse(ctx context.Context) ([]*sdkproto.TemplateVariable, error) {
ctx, span := r.startTrace(ctx, tracing.FuncName()) ctx, span := r.startTrace(ctx, tracing.FuncName())
defer span.End() defer span.End()
@ -697,13 +682,13 @@ func (r *Runner) runTemplateImportParse(ctx context.Context) ([]*sdkproto.Parame
Directory: r.workDirectory, Directory: r.workDirectory,
}) })
if err != nil { if err != nil {
return nil, nil, xerrors.Errorf("parse source: %w", err) return nil, xerrors.Errorf("parse source: %w", err)
} }
defer stream.Close() defer stream.Close()
for { for {
msg, err := stream.Recv() msg, err := stream.Recv()
if err != nil { if err != nil {
return nil, nil, xerrors.Errorf("recv parse source: %w", err) return nil, xerrors.Errorf("recv parse source: %w", err)
} }
switch msgType := msg.Type.(type) { switch msgType := msg.Type.(type) {
case *sdkproto.Parse_Response_Log: case *sdkproto.Parse_Response_Log:
@ -721,13 +706,12 @@ func (r *Runner) runTemplateImportParse(ctx context.Context) ([]*sdkproto.Parame
}) })
case *sdkproto.Parse_Response_Complete: case *sdkproto.Parse_Response_Complete:
r.logger.Info(context.Background(), "parse complete", r.logger.Info(context.Background(), "parse complete",
slog.F("parameter_schemas", msgType.Complete.ParameterSchemas),
slog.F("template_variables", msgType.Complete.TemplateVariables), slog.F("template_variables", msgType.Complete.TemplateVariables),
) )
return msgType.Complete.ParameterSchemas, msgType.Complete.TemplateVariables, nil return msgType.Complete.TemplateVariables, nil
default: default:
return nil, nil, xerrors.Errorf("invalid message type %q received from provisioner", return nil, xerrors.Errorf("invalid message type %q received from provisioner",
reflect.TypeOf(msg.Type).String()) reflect.TypeOf(msg.Type).String())
} }
} }
@ -742,13 +726,13 @@ type templateImportProvision struct {
// Performs a dry-run provision when importing a template. // Performs a dry-run provision when importing a template.
// This is used to detect resources that would be provisioned for a workspace in various states. // This is used to detect resources that would be provisioned for a workspace in various states.
// It doesn't define values for rich parameters as they're unknown during template import. // It doesn't define values for rich parameters as they're unknown during template import.
func (r *Runner) runTemplateImportProvision(ctx context.Context, values []*sdkproto.ParameterValue, variableValues []*sdkproto.VariableValue, metadata *sdkproto.Provision_Metadata) (*templateImportProvision, error) { func (r *Runner) runTemplateImportProvision(ctx context.Context, variableValues []*sdkproto.VariableValue, metadata *sdkproto.Provision_Metadata) (*templateImportProvision, error) {
return r.runTemplateImportProvisionWithRichParameters(ctx, values, variableValues, nil, metadata) return r.runTemplateImportProvisionWithRichParameters(ctx, variableValues, nil, metadata)
} }
// Performs a dry-run provision with provided rich parameters. // Performs a dry-run provision with provided rich parameters.
// This is used to detect resources that would be provisioned for a workspace in various states. // This is used to detect resources that would be provisioned for a workspace in various states.
func (r *Runner) runTemplateImportProvisionWithRichParameters(ctx context.Context, values []*sdkproto.ParameterValue, variableValues []*sdkproto.VariableValue, richParameterValues []*sdkproto.RichParameterValue, metadata *sdkproto.Provision_Metadata) (*templateImportProvision, error) { func (r *Runner) runTemplateImportProvisionWithRichParameters(ctx context.Context, variableValues []*sdkproto.VariableValue, richParameterValues []*sdkproto.RichParameterValue, metadata *sdkproto.Provision_Metadata) (*templateImportProvision, error) {
ctx, span := r.startTrace(ctx, tracing.FuncName()) ctx, span := r.startTrace(ctx, tracing.FuncName())
defer span.End() defer span.End()
@ -785,7 +769,6 @@ func (r *Runner) runTemplateImportProvisionWithRichParameters(ctx context.Contex
Directory: r.workDirectory, Directory: r.workDirectory,
Metadata: metadata, Metadata: metadata,
}, },
ParameterValues: values,
RichParameterValues: richParameterValues, RichParameterValues: richParameterValues,
VariableValues: variableValues, VariableValues: variableValues,
}, },
@ -874,7 +857,6 @@ func (r *Runner) runTemplateDryRun(ctx context.Context) (*proto.CompletedJob, *p
// Run the template import provision task since it's already a dry run. // Run the template import provision task since it's already a dry run.
provision, err := r.runTemplateImportProvisionWithRichParameters(ctx, provision, err := r.runTemplateImportProvisionWithRichParameters(ctx,
r.job.GetTemplateDryRun().GetParameterValues(),
r.job.GetTemplateDryRun().GetVariableValues(), r.job.GetTemplateDryRun().GetVariableValues(),
r.job.GetTemplateDryRun().GetRichParameterValues(), r.job.GetTemplateDryRun().GetRichParameterValues(),
metadata, metadata,
@ -1052,7 +1034,6 @@ func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *p
Type: &sdkproto.Provision_Request_Plan{ Type: &sdkproto.Provision_Request_Plan{
Plan: &sdkproto.Provision_Plan{ Plan: &sdkproto.Provision_Plan{
Config: config, Config: config,
ParameterValues: r.job.GetWorkspaceBuild().ParameterValues,
RichParameterValues: r.job.GetWorkspaceBuild().RichParameterValues, RichParameterValues: r.job.GetWorkspaceBuild().RichParameterValues,
VariableValues: r.job.GetWorkspaceBuild().VariableValues, VariableValues: r.job.GetWorkspaceBuild().VariableValues,
GitAuthProviders: r.job.GetWorkspaceBuild().GitAuthProviders, GitAuthProviders: r.job.GetWorkspaceBuild().GitAuthProviders,

File diff suppressed because it is too large Load Diff

View File

@ -7,51 +7,6 @@ package provisioner;
// Empty indicates a successful request/response. // Empty indicates a successful request/response.
message Empty {} message Empty {}
// ParameterSource represents the source location for a parameter to get it's value from.
message ParameterSource {
enum Scheme {
DATA = 0;
}
Scheme scheme = 1;
string value = 2;
}
// ParameterDestination represents the target location for a provisioner to set the value.
message ParameterDestination {
enum Scheme {
ENVIRONMENT_VARIABLE = 0;
PROVISIONER_VARIABLE = 1;
}
Scheme scheme = 1;
}
// ParameterValue represents the resolved source and destination of a parameter.
message ParameterValue {
ParameterDestination.Scheme destination_scheme = 1;
string name = 2;
string value = 3;
}
// ParameterSchema represents validation and type information for a parsed parameter.
message ParameterSchema {
string name = 1;
string description = 2;
ParameterSource default_source = 3;
bool allow_override_source = 4;
ParameterDestination default_destination = 5;
bool allow_override_destination = 6;
bool redisplay_value = 7;
enum TypeSystem {
None = 0;
HCL = 1;
}
TypeSystem validation_type_system = 8;
string validation_value_type = 9;
string validation_error = 10;
string validation_condition = 11;
}
// TemplateVariable represents a Terraform variable. // TemplateVariable represents a Terraform variable.
message TemplateVariable { message TemplateVariable {
string name = 1; string name = 1;
@ -99,7 +54,7 @@ message RichParameterValue {
message VariableValue { message VariableValue {
string name = 1; string name = 1;
string value = 2; string value = 2;
bool sensitive = 3; bool sensitive = 3;
} }
// LogLevel represents severity of the log. // LogLevel represents severity of the log.
@ -210,8 +165,9 @@ message Parse {
string directory = 1; string directory = 1;
} }
message Complete { message Complete {
reserved 2;
repeated TemplateVariable template_variables = 1; repeated TemplateVariable template_variables = 1;
repeated ParameterSchema parameter_schemas = 2;
} }
message Response { message Response {
oneof type { oneof type {
@ -255,8 +211,9 @@ message Provision {
} }
message Plan { message Plan {
reserved 2;
Config config = 1; Config config = 1;
repeated ParameterValue parameter_values = 2;
repeated RichParameterValue rich_parameter_values = 3; repeated RichParameterValue rich_parameter_values = 3;
repeated VariableValue variable_values = 4; repeated VariableValue variable_values = 4;
repeated GitAuthProvider git_auth_providers = 5; repeated GitAuthProvider git_auth_providers = 5;
@ -279,9 +236,9 @@ message Provision {
bytes state = 1; bytes state = 1;
string error = 2; string error = 2;
repeated Resource resources = 3; repeated Resource resources = 3;
repeated RichParameter parameters = 4; repeated RichParameter parameters = 4;
repeated string git_auth_providers = 5; repeated string git_auth_providers = 5;
bytes plan = 6; bytes plan = 6;
} }
message Response { message Response {
oneof type { oneof type {

View File

@ -239,15 +239,6 @@ export const getTemplateVersion = async (
return response.data return response.data
} }
export const getTemplateVersionSchema = async (
versionId: string,
): Promise<TypesGen.ParameterSchema[]> => {
const response = await axios.get<TypesGen.ParameterSchema[]>(
`/api/v2/templateversions/${versionId}/schema`,
)
return response.data
}
export const getTemplateVersionResources = async ( export const getTemplateVersionResources = async (
versionId: string, versionId: string,
): Promise<TypesGen.WorkspaceResource[]> => { ): Promise<TypesGen.WorkspaceResource[]> => {
@ -335,15 +326,6 @@ export const getTemplateVersionGitAuth = async (
return response.data return response.data
} }
export const getTemplateVersionParameters = async (
versionId: string,
): Promise<TypesGen.ComputedParameter[]> => {
const response = await axios.get(
`/api/v2/templateversions/${versionId}/parameters`,
)
return response.data
}
export const getTemplateVersionRichParameters = async ( export const getTemplateVersionRichParameters = async (
versionId: string, versionId: string,
): Promise<TypesGen.TemplateVersionParameter[]> => { ): Promise<TypesGen.TemplateVersionParameter[]> => {

View File

@ -139,12 +139,6 @@ export interface BuildInfoResponse {
readonly workspace_proxy: boolean readonly workspace_proxy: boolean
} }
// From codersdk/parameters.go
export interface ComputedParameter extends Parameter {
readonly schema_id: string
readonly default_source_value: boolean
}
// From codersdk/users.go // From codersdk/users.go
export interface CreateFirstUserRequest { export interface CreateFirstUserRequest {
readonly email: string readonly email: string
@ -171,15 +165,6 @@ export interface CreateOrganizationRequest {
readonly name: string readonly name: string
} }
// From codersdk/parameters.go
export interface CreateParameterRequest {
readonly copy_from_parameter?: string
readonly name: string
readonly source_value: string
readonly source_scheme: ParameterSourceScheme
readonly destination_scheme: ParameterDestinationScheme
}
// From codersdk/organizations.go // From codersdk/organizations.go
export interface CreateTemplateRequest { export interface CreateTemplateRequest {
readonly name: string readonly name: string
@ -187,7 +172,6 @@ export interface CreateTemplateRequest {
readonly description?: string readonly description?: string
readonly icon?: string readonly icon?: string
readonly template_version_id: string readonly template_version_id: string
readonly parameter_values?: CreateParameterRequest[]
readonly default_ttl_ms?: number readonly default_ttl_ms?: number
readonly max_ttl_ms?: number readonly max_ttl_ms?: number
readonly allow_user_cancel_workspace_jobs?: boolean readonly allow_user_cancel_workspace_jobs?: boolean
@ -200,7 +184,6 @@ export interface CreateTemplateRequest {
// From codersdk/templateversions.go // From codersdk/templateversions.go
export interface CreateTemplateVersionDryRunRequest { export interface CreateTemplateVersionDryRunRequest {
readonly workspace_name: string readonly workspace_name: string
readonly parameter_values: CreateParameterRequest[]
readonly rich_parameter_values: WorkspaceBuildParameter[] readonly rich_parameter_values: WorkspaceBuildParameter[]
readonly user_variable_values?: VariableValue[] readonly user_variable_values?: VariableValue[]
} }
@ -214,7 +197,6 @@ export interface CreateTemplateVersionRequest {
readonly example_id?: string readonly example_id?: string
readonly provisioner: ProvisionerType readonly provisioner: ProvisionerType
readonly tags: Record<string, string> readonly tags: Record<string, string>
readonly parameter_values?: CreateParameterRequest[]
readonly user_variable_values?: VariableValue[] readonly user_variable_values?: VariableValue[]
} }
@ -251,7 +233,6 @@ export interface CreateWorkspaceBuildRequest {
readonly dry_run?: boolean readonly dry_run?: boolean
readonly state?: string readonly state?: string
readonly orphan?: boolean readonly orphan?: boolean
readonly parameter_values?: CreateParameterRequest[]
readonly rich_parameter_values?: WorkspaceBuildParameter[] readonly rich_parameter_values?: WorkspaceBuildParameter[]
readonly log_level?: ProvisionerLogLevel readonly log_level?: ProvisionerLogLevel
} }
@ -269,7 +250,6 @@ export interface CreateWorkspaceRequest {
readonly name: string readonly name: string
readonly autostart_schedule?: string readonly autostart_schedule?: string
readonly ttl_ms?: number readonly ttl_ms?: number
readonly parameter_values?: CreateParameterRequest[]
readonly rich_parameter_values?: WorkspaceBuildParameter[] readonly rich_parameter_values?: WorkspaceBuildParameter[]
} }
@ -585,40 +565,6 @@ export interface Pagination {
readonly offset?: number readonly offset?: number
} }
// From codersdk/parameters.go
export interface Parameter {
readonly id: string
readonly scope: ParameterScope
readonly scope_id: string
readonly name: string
readonly source_scheme: ParameterSourceScheme
readonly destination_scheme: ParameterDestinationScheme
readonly created_at: string
readonly updated_at: string
readonly source_value: string
}
// From codersdk/parameters.go
export interface ParameterSchema {
readonly id: string
readonly created_at: string
readonly job_id: string
readonly name: string
readonly description: string
readonly default_source_scheme: ParameterSourceScheme
readonly default_source_value: string
readonly allow_override_source: boolean
readonly default_destination_scheme: ParameterDestinationScheme
readonly allow_override_destination: boolean
readonly default_refresh: string
readonly redisplay_value: boolean
readonly validation_error: string
readonly validation_condition: string
readonly validation_type_system: string
readonly validation_value_type: string
readonly validation_contains?: string[]
}
// From codersdk/groups.go // From codersdk/groups.go
export interface PatchGroupRequest { export interface PatchGroupRequest {
readonly add_users: string[] readonly add_users: string[]
@ -1450,33 +1396,6 @@ export const LogSources: LogSource[] = ["provisioner", "provisioner_daemon"]
export type LoginType = "github" | "oidc" | "password" | "token" export type LoginType = "github" | "oidc" | "password" | "token"
export const LoginTypes: LoginType[] = ["github", "oidc", "password", "token"] export const LoginTypes: LoginType[] = ["github", "oidc", "password", "token"]
// From codersdk/parameters.go
export type ParameterDestinationScheme =
| "environment_variable"
| "none"
| "provisioner_variable"
export const ParameterDestinationSchemes: ParameterDestinationScheme[] = [
"environment_variable",
"none",
"provisioner_variable",
]
// From codersdk/parameters.go
export type ParameterScope = "import_job" | "template" | "workspace"
export const ParameterScopes: ParameterScope[] = [
"import_job",
"template",
"workspace",
]
// From codersdk/parameters.go
export type ParameterSourceScheme = "data" | "none"
export const ParameterSourceSchemes: ParameterSourceScheme[] = ["data", "none"]
// From codersdk/parameters.go
export type ParameterTypeSystem = "hcl" | "none"
export const ParameterTypeSystems: ParameterTypeSystem[] = ["hcl", "none"]
// From codersdk/provisionerdaemons.go // From codersdk/provisionerdaemons.go
export type ProvisionerJobStatus = export type ProvisionerJobStatus =
| "canceled" | "canceled"
@ -1604,9 +1523,9 @@ export type TemplateRole = "" | "admin" | "use"
export const TemplateRoles: TemplateRole[] = ["", "admin", "use"] export const TemplateRoles: TemplateRole[] = ["", "admin", "use"]
// From codersdk/templateversions.go // From codersdk/templateversions.go
export type TemplateVersionWarning = "DEPRECATED_PARAMETERS" export type TemplateVersionWarning = "UNSUPPORTED_WORKSPACES"
export const TemplateVersionWarnings: TemplateVersionWarning[] = [ export const TemplateVersionWarnings: TemplateVersionWarning[] = [
"DEPRECATED_PARAMETERS", "UNSUPPORTED_WORKSPACES",
] ]
// From codersdk/users.go // From codersdk/users.go

View File

@ -1,71 +0,0 @@
import { Story } from "@storybook/react"
import { ParameterSchema } from "../../api/typesGenerated"
import { ParameterInput, ParameterInputProps } from "./ParameterInput"
export default {
title: "components/ParameterInput",
component: ParameterInput,
}
const Template: Story<ParameterInputProps> = (args: ParameterInputProps) => (
<ParameterInput {...args} />
)
const createParameterSchema = (
partial: Partial<ParameterSchema>,
): ParameterSchema => {
return {
id: "000000",
job_id: "000000",
allow_override_destination: false,
allow_override_source: true,
created_at: "",
default_destination_scheme: "none",
default_refresh: "",
default_source_scheme: "data",
default_source_value: "default-value",
name: "parameter name",
description: "Some description!",
redisplay_value: false,
validation_condition: "",
validation_contains: [],
validation_error: "",
validation_type_system: "",
validation_value_type: "",
...partial,
}
}
export const Basic = Template.bind({})
Basic.args = {
schema: createParameterSchema({
name: "project_name",
description:
"Customize the name of a Google Cloud project that will be created!",
}),
}
export const Boolean = Template.bind({})
Boolean.args = {
schema: createParameterSchema({
name: "disable_docker",
description: "Disable Docker?",
validation_value_type: "bool",
default_source_value: "false",
}),
}
export const Contains = Template.bind({})
Contains.args = {
schema: createParameterSchema({
name: "region",
default_source_value: "🏈 US Central",
description: "Where would you like your workspace to live?",
validation_contains: [
"🏈 US Central",
"⚽ Brazil East",
"💶 EU West",
"🦘 Australia South",
],
}),
}

View File

@ -1,155 +0,0 @@
import FormControlLabel from "@mui/material/FormControlLabel"
import MenuItem from "@mui/material/MenuItem"
import Radio from "@mui/material/Radio"
import RadioGroup from "@mui/material/RadioGroup"
import { makeStyles } from "@mui/styles"
import TextField from "@mui/material/TextField"
import { Stack } from "components/Stack/Stack"
import { FC } from "react"
import { ParameterSchema } from "../../api/typesGenerated"
const isBoolean = (schema: ParameterSchema) => {
return schema.validation_value_type === "bool"
}
const ParameterLabel: React.FC<{ schema: ParameterSchema }> = ({ schema }) => {
const styles = useStyles()
if (schema.name && schema.description) {
return (
<label htmlFor={schema.name}>
<span className={styles.labelName}>var.{schema.name}</span>
<span className={styles.labelDescription}>{schema.description}</span>
</label>
)
}
return (
<label htmlFor={schema.name}>
<span className={styles.labelDescription}>var.{schema.name}</span>
</label>
)
}
export interface ParameterInputProps {
disabled?: boolean
schema: ParameterSchema
onChange: (value: string) => void
defaultValue?: string
}
export const ParameterInput: FC<ParameterInputProps> = ({
disabled,
onChange,
schema,
defaultValue,
}) => {
const styles = useStyles()
return (
<Stack direction="column" spacing={2}>
<ParameterLabel schema={schema} />
<div className={styles.input}>
<ParameterField
disabled={disabled}
onChange={onChange}
schema={schema}
defaultValue={defaultValue}
/>
</div>
</Stack>
)
}
const ParameterField: React.FC<ParameterInputProps> = ({
disabled,
onChange,
schema,
defaultValue,
}) => {
if (schema.validation_contains && schema.validation_contains.length > 0) {
return (
<TextField
id={schema.name}
defaultValue={defaultValue ?? schema.default_source_value}
placeholder={schema.default_source_value}
disabled={disabled}
onChange={(event) => {
onChange(event.target.value)
}}
select
fullWidth
>
{schema.validation_contains.map((item) => (
<MenuItem key={item} value={item}>
{item}
</MenuItem>
))}
</TextField>
)
}
if (isBoolean(schema)) {
return (
<RadioGroup
id={schema.name}
defaultValue={schema.default_source_value}
onChange={(event) => {
onChange(event.target.value)
}}
>
<FormControlLabel
disabled={disabled}
value="true"
control={<Radio />}
label="True"
/>
<FormControlLabel
disabled={disabled}
value="false"
control={<Radio />}
label="False"
/>
</RadioGroup>
)
}
// A text field can technically handle all cases!
// As other cases become more prominent (like filtering for numbers),
// we should break this out into more finely scoped input fields.
return (
<TextField
id={schema.name}
disabled={disabled}
placeholder={schema.default_source_value}
defaultValue={defaultValue ?? schema.default_source_value}
onChange={(event) => {
onChange(event.target.value)
}}
/>
)
}
const useStyles = makeStyles((theme) => ({
labelName: {
fontSize: 14,
color: theme.palette.text.secondary,
display: "block",
},
labelDescription: {
fontSize: 16,
color: theme.palette.text.primary,
display: "block",
fontWeight: 600,
lineHeight: "24px", // Keep the same as ParameterInput
},
input: {
display: "flex",
flexDirection: "column",
},
checkbox: {
display: "flex",
alignItems: "center",
gap: theme.spacing(1),
},
}))

View File

@ -13,7 +13,7 @@ const Template: Story<TemplateVersionWarningsProps> = (args) => (
<TemplateVersionWarnings {...args} /> <TemplateVersionWarnings {...args} />
) )
export const DeprecatedParameters = Template.bind({}) export const UnsupportedWorkspaces = Template.bind({})
DeprecatedParameters.args = { UnsupportedWorkspaces.args = {
warnings: ["DEPRECATED_PARAMETERS"], warnings: ["UNSUPPORTED_WORKSPACES"],
} }

View File

@ -2,7 +2,6 @@ import { FC } from "react"
import * as TypesGen from "api/typesGenerated" import * as TypesGen from "api/typesGenerated"
import { Alert } from "components/Alert/Alert" import { Alert } from "components/Alert/Alert"
import { Maybe } from "components/Conditionals/Maybe" import { Maybe } from "components/Conditionals/Maybe"
import Link from "@mui/material/Link"
export interface TemplateVersionWarningsProps { export interface TemplateVersionWarningsProps {
warnings?: TypesGen.TemplateVersionWarning[] warnings?: TypesGen.TemplateVersionWarning[]
@ -16,15 +15,11 @@ export const TemplateVersionWarnings: FC<
} }
return ( return (
<Maybe condition={Boolean(warnings.includes("DEPRECATED_PARAMETERS"))}> <Maybe condition={Boolean(warnings.includes("UNSUPPORTED_WORKSPACES"))}>
<div data-testid="warning-deprecated-parameters"> <div data-testid="error-unsupported-workspaces">
<Alert severity="warning"> <Alert severity="error">
This template uses legacy parameters which will be deprecated in the This template uses legacy parameters which are not supported anymore.
next Coder release. Learn how to migrate in{" "} Contact your administrator for assistance.
<Link href="https://coder.com/docs/v2/latest/templates/parameters#migration">
our documentation
</Link>
.
</Alert> </Alert>
</div> </div>
</Maybe> </Maybe>

View File

@ -697,9 +697,9 @@ function makeFailedBuildLogs(): ProvisionerJobLog[] {
] ]
} }
export const WithDeprecatedParameters: Story = { export const UnsupportedWorkspace: Story = {
args: { args: {
...Running.args, ...Running.args,
templateWarnings: ["DEPRECATED_PARAMETERS"], templateWarnings: ["UNSUPPORTED_WORKSPACES"],
}, },
} }

View File

@ -1,6 +1,5 @@
import { ComponentMeta, Story } from "@storybook/react" import { ComponentMeta, Story } from "@storybook/react"
import { import {
MockParameterSchemas,
MockTemplateExample, MockTemplateExample,
MockTemplateVersionVariable1, MockTemplateVersionVariable1,
MockTemplateVersionVariable2, MockTemplateVersionVariable2,
@ -33,11 +32,6 @@ WithStarterTemplate.args = {
starterTemplate: MockTemplateExample, starterTemplate: MockTemplateExample,
} }
export const WithParameters = Template.bind({})
WithParameters.args = {
parameters: MockParameterSchemas,
}
export const WithVariables = Template.bind({}) export const WithVariables = Template.bind({})
WithVariables.args = { WithVariables.args = {
variables: [ variables: [

View File

@ -2,13 +2,11 @@ import Checkbox from "@mui/material/Checkbox"
import { makeStyles } from "@mui/styles" import { makeStyles } from "@mui/styles"
import TextField from "@mui/material/TextField" import TextField from "@mui/material/TextField"
import { import {
ParameterSchema,
ProvisionerJobLog, ProvisionerJobLog,
Template, Template,
TemplateExample, TemplateExample,
TemplateVersionVariable, TemplateVersionVariable,
} from "api/typesGenerated" } from "api/typesGenerated"
import { ParameterInput } from "components/ParameterInput/ParameterInput"
import { Stack } from "components/Stack/Stack" import { Stack } from "components/Stack/Stack"
import { import {
TemplateUpload, TemplateUpload,
@ -112,7 +110,6 @@ const defaultInitialValues: CreateTemplateData = {
type GetInitialValuesParams = { type GetInitialValuesParams = {
fromExample?: TemplateExample fromExample?: TemplateExample
fromCopy?: Template fromCopy?: Template
parameters?: ParameterSchema[]
variables?: TemplateVersionVariable[] variables?: TemplateVersionVariable[]
allowAdvancedScheduling: boolean allowAdvancedScheduling: boolean
} }
@ -122,7 +119,6 @@ const getInitialValues = ({
fromCopy, fromCopy,
allowAdvancedScheduling, allowAdvancedScheduling,
variables, variables,
parameters,
}: GetInitialValuesParams) => { }: GetInitialValuesParams) => {
let initialValues = defaultInitialValues let initialValues = defaultInitialValues
@ -166,16 +162,6 @@ const getInitialValues = ({
}) })
} }
if (parameters) {
parameters.forEach((parameter) => {
if (!initialValues.parameter_values_by_name) {
initialValues.parameter_values_by_name = {}
}
initialValues.parameter_values_by_name[parameter.name] =
parameter.default_source_value
})
}
return initialValues return initialValues
} }
@ -185,7 +171,6 @@ export interface CreateTemplateFormProps {
isSubmitting: boolean isSubmitting: boolean
upload: TemplateUploadProps upload: TemplateUploadProps
starterTemplate?: TemplateExample starterTemplate?: TemplateExample
parameters?: ParameterSchema[]
variables?: TemplateVersionVariable[] variables?: TemplateVersionVariable[]
error?: unknown error?: unknown
jobError?: string jobError?: string
@ -199,7 +184,6 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = ({
onSubmit, onSubmit,
starterTemplate, starterTemplate,
copiedTemplate, copiedTemplate,
parameters,
variables, variables,
isSubmitting, isSubmitting,
upload, upload,
@ -215,7 +199,6 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = ({
fromExample: starterTemplate, fromExample: starterTemplate,
fromCopy: copiedTemplate, fromCopy: copiedTemplate,
variables, variables,
parameters,
}), }),
validationSchema, validationSchema,
onSubmit, onSubmit,
@ -439,30 +422,6 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = ({
</FormFields> </FormFields>
</FormSection> </FormSection>
{/* Parameters */}
{parameters && parameters.length > 0 && (
<FormSection
title={t("form.parameters.title")}
description={t("form.parameters.description")}
>
<FormFields>
{parameters.map((schema) => (
<ParameterInput
schema={schema}
disabled={isSubmitting}
key={schema.id}
onChange={async (value) => {
await form.setFieldValue(
`parameter_values_by_name.${schema.name}`,
value,
)
}}
/>
))}
</FormFields>
</FormSection>
)}
{/* Variables */} {/* Variables */}
{variables && variables.length > 0 && ( {variables && variables.length > 0 && (
<FormSection <FormSection

View File

@ -95,7 +95,6 @@ test("Create template with variables", async () => {
) )
expect(API.createTemplateVersion).toHaveBeenCalledWith(MockOrganization.id, { expect(API.createTemplateVersion).toHaveBeenCalledWith(MockOrganization.id, {
file_id: MockProvisionerJob.file_id, file_id: MockProvisionerJob.file_id,
parameter_values: [],
provisioner: "terraform", provisioner: "terraform",
storage_method: "file", storage_method: "file",
tags: {}, tags: {},

View File

@ -33,15 +33,8 @@ const CreateTemplatePage: FC = () => {
}, },
}) })
const { const { starterTemplate, error, file, jobError, jobLogs, variables } =
starterTemplate, state.context
parameters,
error,
file,
jobError,
jobLogs,
variables,
} = state.context
const shouldDisplayForm = !state.hasTag("loading") const shouldDisplayForm = !state.hasTag("loading")
const { entitlements } = useDashboard() const { entitlements } = useDashboard()
const allowAdvancedScheduling = const allowAdvancedScheduling =
@ -75,7 +68,6 @@ const CreateTemplatePage: FC = () => {
starterTemplate={starterTemplate} starterTemplate={starterTemplate}
isSubmitting={state.hasTag("submitting")} isSubmitting={state.hasTag("submitting")}
variables={variables} variables={variables}
parameters={parameters}
onCancel={onCancel} onCancel={onCancel}
onSubmit={(data) => { onSubmit={(data) => {
send({ send({

View File

@ -3,7 +3,6 @@ import userEvent from "@testing-library/user-event"
import * as API from "api/api" import * as API from "api/api"
import i18next from "i18next" import i18next from "i18next"
import { import {
mockParameterSchema,
MockTemplate, MockTemplate,
MockUser, MockUser,
MockWorkspace, MockWorkspace,
@ -79,7 +78,6 @@ describe("CreateWorkspacePage", () => {
}) })
it("succeeds with default owner", async () => { it("succeeds with default owner", async () => {
jest.spyOn(API, "getTemplateVersionSchema").mockResolvedValueOnce([])
jest jest
.spyOn(API, "getUsers") .spyOn(API, "getUsers")
.mockResolvedValueOnce({ users: [MockUser], count: 1 }) .mockResolvedValueOnce({ users: [MockUser], count: 1 })
@ -114,39 +112,9 @@ describe("CreateWorkspacePage", () => {
) )
}) })
it("uses default param values passed from the URL", async () => {
const param = "dotfile_uri"
const paramValue = "localhost:3000"
jest.spyOn(API, "getTemplateVersionSchema").mockResolvedValueOnce([
mockParameterSchema({
name: param,
redisplay_value: true,
default_source_value: "",
}),
])
jest
.spyOn(API, "getTemplateVersionRichParameters")
.mockResolvedValueOnce([MockTemplateVersionParameter1])
renderWithAuth(<CreateWorkspacePage />, {
route:
"/templates/" +
MockTemplate.name +
`/workspace?param.${param}=${paramValue}`,
path: "/templates/:template/workspace",
}),
await screen.findByDisplayValue(paramValue)
})
it("uses default rich param values passed from the URL", async () => { it("uses default rich param values passed from the URL", async () => {
const param = "first_parameter" const param = "first_parameter"
const paramValue = "It works!" const paramValue = "It works!"
jest.spyOn(API, "getTemplateVersionSchema").mockResolvedValueOnce([
mockParameterSchema({
name: param,
default_source_value: "",
}),
])
jest jest
.spyOn(API, "getTemplateVersionRichParameters") .spyOn(API, "getTemplateVersionRichParameters")
.mockResolvedValueOnce([MockTemplateVersionParameter1]) .mockResolvedValueOnce([MockTemplateVersionParameter1])

View File

@ -32,10 +32,8 @@ const CreateWorkspacePage: FC = () => {
const { const {
templates, templates,
templateParameters, templateParameters,
templateSchema,
templateGitAuth, templateGitAuth,
selectedTemplate, selectedTemplate,
getTemplateSchemaError,
getTemplateGitAuthError, getTemplateGitAuthError,
getTemplatesError, getTemplatesError,
createWorkspaceError, createWorkspaceError,
@ -55,21 +53,15 @@ const CreateWorkspacePage: FC = () => {
name={name} name={name}
defaultParameterValues={defaultParameterValues} defaultParameterValues={defaultParameterValues}
loadingTemplates={createWorkspaceState.matches("gettingTemplates")} loadingTemplates={createWorkspaceState.matches("gettingTemplates")}
loadingTemplateSchema={createWorkspaceState.matches(
"gettingTemplateSchema",
)}
creatingWorkspace={createWorkspaceState.matches("creatingWorkspace")} creatingWorkspace={createWorkspaceState.matches("creatingWorkspace")}
hasTemplateErrors={createWorkspaceState.matches("error")} hasTemplateErrors={createWorkspaceState.matches("error")}
templateName={templateName} templateName={templateName}
templates={templates} templates={templates}
selectedTemplate={selectedTemplate} selectedTemplate={selectedTemplate}
templateParameters={orderedTemplateParameters(templateParameters)} templateParameters={orderedTemplateParameters(templateParameters)}
templateSchema={templateSchema}
templateGitAuth={templateGitAuth} templateGitAuth={templateGitAuth}
createWorkspaceErrors={{ createWorkspaceErrors={{
[CreateWorkspaceErrors.GET_TEMPLATES_ERROR]: getTemplatesError, [CreateWorkspaceErrors.GET_TEMPLATES_ERROR]: getTemplatesError,
[CreateWorkspaceErrors.GET_TEMPLATE_SCHEMA_ERROR]:
getTemplateSchemaError,
[CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR]: createWorkspaceError, [CreateWorkspaceErrors.CREATE_WORKSPACE_ERROR]: createWorkspaceError,
[CreateWorkspaceErrors.GET_TEMPLATE_GITAUTH_ERROR]: [CreateWorkspaceErrors.GET_TEMPLATE_GITAUTH_ERROR]:
getTemplateGitAuthError, getTemplateGitAuthError,

View File

@ -1,8 +1,6 @@
import { ComponentMeta, Story } from "@storybook/react" import { ComponentMeta, Story } from "@storybook/react"
import { import {
mockApiError, mockApiError,
mockParameterSchema,
MockParameterSchemas,
MockTemplate, MockTemplate,
MockTemplateVersionParameter1, MockTemplateVersionParameter1,
MockTemplateVersionParameter2, MockTemplateVersionParameter2,
@ -27,7 +25,6 @@ export const NoParameters = Template.bind({})
NoParameters.args = { NoParameters.args = {
templates: [MockTemplate], templates: [MockTemplate],
selectedTemplate: MockTemplate, selectedTemplate: MockTemplate,
templateSchema: [],
createWorkspaceErrors: {}, createWorkspaceErrors: {},
} }
@ -35,7 +32,6 @@ export const Parameters = Template.bind({})
Parameters.args = { Parameters.args = {
templates: [MockTemplate], templates: [MockTemplate],
selectedTemplate: MockTemplate, selectedTemplate: MockTemplate,
templateSchema: MockParameterSchemas,
createWorkspaceErrors: {}, createWorkspaceErrors: {},
} }
@ -43,41 +39,6 @@ export const RedisplayParameters = Template.bind({})
RedisplayParameters.args = { RedisplayParameters.args = {
templates: [MockTemplate], templates: [MockTemplate],
selectedTemplate: MockTemplate, selectedTemplate: MockTemplate,
templateSchema: [
mockParameterSchema({
name: "region",
default_source_value: "🏈 US Central",
description: "Where would you like your workspace to live?",
redisplay_value: false,
validation_contains: [
"🏈 US Central",
"⚽ Brazil East",
"💶 EU West",
"🦘 Australia South",
],
}),
mockParameterSchema({
name: "instance_size",
default_source_value: "Big",
description: "How large should you instance be?",
validation_contains: ["Small", "Medium", "Big"],
redisplay_value: false,
}),
mockParameterSchema({
name: "instance_size",
default_source_value: "Big",
description: "How large should your instance be?",
validation_contains: ["Small", "Medium", "Big"],
redisplay_value: true,
}),
mockParameterSchema({
name: "disable_docker",
description: "Disable Docker?",
validation_value_type: "bool",
default_source_value: "false",
redisplay_value: true,
}),
],
createWorkspaceErrors: {}, createWorkspaceErrors: {},
} }
@ -93,18 +54,6 @@ GetTemplatesError.args = {
hasTemplateErrors: true, hasTemplateErrors: true,
} }
export const GetTemplateSchemaError = Template.bind({})
GetTemplateSchemaError.args = {
...Parameters.args,
createWorkspaceErrors: {
[CreateWorkspaceErrors.GET_TEMPLATE_SCHEMA_ERROR]: mockApiError({
message: 'Failed to fetch template schema for "docker-amd64".',
detail: "You do not have permission to access this resource.",
}),
},
hasTemplateErrors: true,
}
export const CreateWorkspaceError = Template.bind({}) export const CreateWorkspaceError = Template.bind({})
CreateWorkspaceError.args = { CreateWorkspaceError.args = {
...Parameters.args, ...Parameters.args,

Some files were not shown because too many files have changed in this diff Show More