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"
"github.com/coder/coder/cli/clibase"
"github.com/coder/coder/coderd/parameter"
"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) {
label := templateVersionParameter.Name
if templateVersionParameter.DisplayName != "" {

View File

@ -18,7 +18,6 @@ import (
func (r *RootCmd) create() *clibase.Cmd {
var (
parameterFile string
richParameterFile string
templateName string
startAt string
@ -122,8 +121,6 @@ func (r *RootCmd) create() *clibase.Cmd {
buildParams, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{
Template: template,
ExistingParams: []codersdk.Parameter{},
ParameterFile: parameterFile,
RichParameterFile: richParameterFile,
NewWorkspaceName: workspaceName,
})
@ -151,7 +148,6 @@ func (r *RootCmd) create() *clibase.Cmd {
Name: workspaceName,
AutostartSchedule: schedSpec,
TTLMillis: ttlMillis,
ParameterValues: buildParams.parameters,
RichParameterValues: buildParams.richParameters,
})
if err != nil {
@ -175,12 +171,6 @@ func (r *RootCmd) create() *clibase.Cmd {
Description: "Specify a template name.",
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{
Flag: "rich-parameter-file",
Env: "CODER_RICH_PARAMETER_FILE",
@ -207,8 +197,6 @@ func (r *RootCmd) create() *clibase.Cmd {
type prepWorkspaceBuildArgs struct {
Template codersdk.Template
ExistingParams []codersdk.Parameter
ParameterFile string
ExistingRichParams []codersdk.WorkspaceBuildParameter
RichParameterFile string
NewWorkspaceName string
@ -218,8 +206,6 @@ type prepWorkspaceBuildArgs 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.
richParameters []codersdk.WorkspaceBuildParameter
}
@ -229,90 +215,19 @@ type buildParameters struct {
func prepWorkspaceBuild(inv *clibase.Invocation, client *codersdk.Client, args prepWorkspaceBuildArgs) (*buildParameters, error) {
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)
if err != nil {
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
templateVersionParameters, err := client.TemplateVersionRichParameters(inv.Context(), templateVersion.ID)
if err != nil {
return nil, xerrors.Errorf("get template version rich parameters: %w", err)
}
parameterMapFromFile = map[string]string{}
useParamFile = false
parameterMapFromFile := map[string]string{}
useParamFile := false
if args.RichParameterFile != "" {
useParamFile = true
_, _ = 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
}
}
disclaimerPrinted = false
disclaimerPrinted := false
richParameters := make([]codersdk.WorkspaceBuildParameter, 0)
PromptRichParamLoop:
for _, templateVersionParameter := range templateVersionParameters {
@ -379,7 +294,6 @@ PromptRichParamLoop:
// Run a dry-run with the given parameters to check correctness
dryRun, err := client.CreateTemplateVersionDryRun(inv.Context(), templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{
WorkspaceName: args.NewWorkspaceName,
ParameterValues: legacyParameters,
RichParameterValues: richParameters,
})
if err != nil {
@ -421,7 +335,6 @@ PromptRichParamLoop:
}
return &buildParameters{
parameters: legacyParameters,
richParameters: richParameters,
}, nil
}

View File

@ -2,7 +2,6 @@ package cli_test
import (
"context"
"fmt"
"net/http"
"os"
"regexp"
@ -181,181 +180,6 @@ func TestCreate(t *testing.T) {
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) {
@ -751,39 +575,3 @@ func TestCreateWithGitAuth(t *testing.T) {
pty.ExpectMatch("Confirm create?")
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")
}
// 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) {
var parameterValue string
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.deleteWorkspace(),
r.list(),
r.parameters(),
r.ping(),
r.rename(),
r.scaletest(),

View File

@ -472,10 +472,8 @@ func (r *RootCmd) scaletestCleanup() *clibase.Cmd {
func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
var (
count int64
template string
parametersFile string
parameters []string // key=value
count int64
template string
noPlan bool
noCleanup bool
@ -571,51 +569,11 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
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
// before we start creating users and workspaces.
if !noPlan {
dryRun, err := client.CreateTemplateVersionDryRun(ctx, templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{
WorkspaceName: "scaletest",
ParameterValues: params,
WorkspaceName: "scaletest",
})
if err != nil {
return xerrors.Errorf("start dry run workspace creation: %w", err)
@ -667,8 +625,7 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
OrganizationID: me.OrganizationIDs[0],
// UserID is set by the test automatically.
Request: codersdk.CreateWorkspaceRequest{
TemplateID: tpl.ID,
ParameterValues: params,
TemplateID: tpl.ID,
},
NoWaitForAgents: noWaitForAgents,
},
@ -787,18 +744,6 @@ func (r *RootCmd) scaletestCreateWorkspaces() *clibase.Cmd {
Description: "Required: Name or ID of the template to use for workspaces.",
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",
Env: "CODER_SCALETEST_NO_PLAN",

View File

@ -105,6 +105,23 @@ func (r *RootCmd) ssh() *clibase.Cmd {
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)
if outdated && isTTYErr(inv) {
_, _ = fmt.Fprintln(inv.Stderr, updateWorkspaceBanner)

View File

@ -26,7 +26,6 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
var (
provisioner string
provisionerTags []string
parameterFile string
variablesFile string
variables []string
defaultTTL time.Duration
@ -98,12 +97,11 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
return err
}
job, _, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{
job, err := createValidTemplateVersion(inv, createValidTemplateVersionArgs{
Client: client,
Organization: organization,
Provisioner: database.ProvisionerType(provisioner),
FileID: resp.ID,
ParameterFile: parameterFile,
ProvisionerTags: tags,
VariablesFile: variablesFile,
Variables: variables,
@ -146,11 +144,6 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
},
}
cmd.Options = clibase.OptionSet{
{
Flag: "parameter-file",
Description: "Specify a file path with parameter values.",
Value: clibase.StringOf(&parameterFile),
},
{
Flag: "variables-file",
Description: "Specify a file path with values for Terraform-managed variables.",
@ -198,12 +191,11 @@ func (r *RootCmd) templateCreate() *clibase.Cmd {
}
type createValidTemplateVersionArgs struct {
Name string
Client *codersdk.Client
Organization codersdk.Organization
Provisioner database.ProvisionerType
FileID uuid.UUID
ParameterFile string
Name string
Client *codersdk.Client
Organization codersdk.Organization
Provisioner database.ProvisionerType
FileID uuid.UUID
VariablesFile string
Variables []string
@ -217,17 +209,17 @@ type createValidTemplateVersionArgs struct {
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
variableValues, err := loadVariableValuesFromFile(args.VariablesFile)
if err != nil {
return nil, nil, err
return nil, err
}
variableValuesFromKeyValues, err := loadVariableValuesFromOptions(args.Variables)
if err != nil {
return nil, nil, err
return nil, err
}
variableValues = append(variableValues, variableValuesFromKeyValues...)
@ -236,7 +228,6 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
StorageMethod: codersdk.ProvisionerStorageMethodFile,
FileID: args.FileID,
Provisioner: codersdk.ProvisionerType(args.Provisioner),
ParameterValues: parameters,
ProvisionerTags: args.ProvisionerTags,
UserVariableValues: variableValues,
}
@ -245,7 +236,7 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
}
version, err := client.CreateTemplateVersion(inv.Context(), args.Organization.ID, req)
if err != nil {
return nil, nil, err
return nil, err
}
err = cliui.ProvisionerJob(inv.Context(), inv.Stdout, cliui.ProvisionerJobOptions{
@ -263,115 +254,21 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
if err != nil {
var jobErr *cliui.ProvisionerJobError
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)
if err != nil {
return nil, 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...)
return nil, err
}
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)
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.
@ -387,10 +284,10 @@ func createValidTemplateVersion(inv *clibase.Invocation, args createValidTemplat
Title: "Template Preview",
})
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

View File

@ -108,108 +108,6 @@ func TestTemplateCreate(t *testing.T) {
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.Parallel()
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")
})
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.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:
// https://github.com/golang/go/issues/52986
func removeTmpDirUntilSuccessAfterTest(t *testing.T, tempDir string) {

View File

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

View File

@ -8,7 +8,6 @@ import (
"runtime"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -23,92 +22,6 @@ import (
func TestTemplatePush(t *testing.T) {
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.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 {
return &echo.Responses{
Parse: []*proto.Parse_Response{

View File

@ -3,9 +3,6 @@ Usage: coder create [flags] [name]
Create a workspace
Options
--parameter-file string, $CODER_PARAMETER_FILE
Specify a file path with parameter values.
--rich-parameter-file string, $CODER_RICH_PARAMETER_FILE
Specify a file path with values for rich parameters defined in the
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
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
Command to run inside each workspace using reconnecting-pty (i.e. web
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.
This licensed feature's default is 0h (off).
--parameter-file string
Specify a file path with parameter values.
--provisioner-tag string-array
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
generated if not provided.
--parameter-file string
Specify a file path with parameter values.
--provisioner-tag string-array
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
existing workspace.
--parameter-file string, $CODER_PARAMETER_FILE
Specify a file path with parameter values.
--rich-parameter-file string, $CODER_RICH_PARAMETER_FILE
Specify a file path with values for rich parameters defined in the
template.

View File

@ -9,7 +9,6 @@ import (
func (r *RootCmd) update() *clibase.Cmd {
var (
parameterFile string
richParameterFile string
alwaysPrompt bool
)
@ -38,14 +37,8 @@ func (r *RootCmd) update() *clibase.Cmd {
return nil
}
var existingParams []codersdk.Parameter
var existingRichParams []codersdk.WorkspaceBuildParameter
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)
if err != nil {
return nil
@ -54,8 +47,6 @@ func (r *RootCmd) update() *clibase.Cmd {
buildParams, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{
Template: template,
ExistingParams: existingParams,
ParameterFile: parameterFile,
ExistingRichParams: existingRichParams,
RichParameterFile: richParameterFile,
NewWorkspaceName: workspace.Name,
@ -70,7 +61,6 @@ func (r *RootCmd) update() *clibase.Cmd {
build, err := client.CreateWorkspaceBuild(inv.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: template.ActiveVersionID,
Transition: codersdk.WorkspaceTransitionStart,
ParameterValues: buildParams.parameters,
RichParameterValues: buildParams.richParameters,
})
if err != nil {
@ -99,12 +89,6 @@ func (r *RootCmd) update() *clibase.Cmd {
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",
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.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) {

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": {
"get": {
"security": [
@ -2764,14 +2603,11 @@ const docTemplate = `{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Templates"
],
"summary": "Get parameters by template version",
"operationId": "get-parameters-by-template-version",
"summary": "Removed: Get parameters by template version",
"operationId": "removed-get-parameters-by-template-version",
"parameters": [
{
"type": "string",
@ -2784,13 +2620,7 @@ const docTemplate = `{
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/parameter.ComputedValue"
}
}
"description": "OK"
}
}
}
@ -2878,14 +2708,11 @@ const docTemplate = `{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"Templates"
],
"summary": "Get schema by template version",
"operationId": "get-schema-by-template-version",
"summary": "Removed: Get schema by template version",
"operationId": "removed-get-schema-by-template-version",
"parameters": [
{
"type": "string",
@ -2898,13 +2725,7 @@ const docTemplate = `{
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.ParameterSchema"
}
}
"description": "OK"
}
}
}
@ -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": {
"type": "object",
"required": [
@ -6907,12 +6682,6 @@ const docTemplate = `{
"description": "Name is the name of the template.",
"type": "string"
},
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"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.",
"type": "string",
@ -6923,12 +6692,6 @@ const docTemplate = `{
"codersdk.CreateTemplateVersionDryRunRequest": {
"type": "object",
"properties": {
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": {
"type": "array",
"items": {
@ -6963,13 +6726,6 @@ const docTemplate = `{
"name": {
"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": {
"type": "string",
"enum": [
@ -7137,14 +6893,8 @@ const docTemplate = `{
"description": "Orphan may be set for the Destroy transition.",
"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": {
"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.WorkspaceBuildParameter"
@ -7205,14 +6955,8 @@ const docTemplate = `{
"name": {
"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": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
"type": "array",
"items": {
"$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": {
"type": "object",
"properties": {
@ -9250,10 +8814,10 @@ const docTemplate = `{
"codersdk.TemplateVersionWarning": {
"type": "string",
"enum": [
"DEPRECATED_PARAMETERS"
"UNSUPPORTED_WORKSPACES"
],
"x-enum-varnames": [
"TemplateVersionWarningDeprecatedParameters"
"TemplateVersionWarningUnsupportedWorkspaces"
]
},
"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": {
"type": "object",
"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": {
"type": "object",
"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": {
"get": {
"security": [
@ -2426,10 +2291,9 @@
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["Templates"],
"summary": "Get parameters by template version",
"operationId": "get-parameters-by-template-version",
"summary": "Removed: Get parameters by template version",
"operationId": "removed-get-parameters-by-template-version",
"parameters": [
{
"type": "string",
@ -2442,13 +2306,7 @@
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/parameter.ComputedValue"
}
}
"description": "OK"
}
}
}
@ -2528,10 +2386,9 @@
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["Templates"],
"summary": "Get schema by template version",
"operationId": "get-schema-by-template-version",
"summary": "Removed: Get schema by template version",
"operationId": "removed-get-schema-by-template-version",
"parameters": [
{
"type": "string",
@ -2544,13 +2401,7 @@
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.ParameterSchema"
}
}
"description": "OK"
}
}
}
@ -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": {
"type": "object",
"required": ["name", "template_version_id"],
@ -6141,12 +5953,6 @@
"description": "Name is the name of the template.",
"type": "string"
},
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"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.",
"type": "string",
@ -6157,12 +5963,6 @@
"codersdk.CreateTemplateVersionDryRunRequest": {
"type": "object",
"properties": {
"parameter_values": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.CreateParameterRequest"
}
},
"rich_parameter_values": {
"type": "array",
"items": {
@ -6194,13 +5994,6 @@
"name": {
"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": {
"type": "string",
"enum": ["terraform", "echo"]
@ -6342,14 +6135,8 @@
"description": "Orphan may be set for the Destroy transition.",
"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": {
"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.WorkspaceBuildParameter"
@ -6400,14 +6187,8 @@
"name": {
"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": {
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
"type": "array",
"items": {
"$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": {
"type": "object",
"properties": {
@ -8309,8 +7939,8 @@
},
"codersdk.TemplateVersionWarning": {
"type": "string",
"enum": ["DEPRECATED_PARAMETERS"],
"x-enum-varnames": ["TemplateVersionWarningDeprecatedParameters"]
"enum": ["UNSUPPORTED_WORKSPACES"],
"x-enum-varnames": ["TemplateVersionWarningUnsupportedWorkspaces"]
},
"codersdk.TokenConfig": {
"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": {
"type": "object",
"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": {
"type": "object",
"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.Use(
apiKeyMiddleware,
@ -582,8 +574,10 @@ func New(options *Options) *API {
r.Get("/", api.templateVersion)
r.Patch("/", api.patchTemplateVersion)
r.Patch("/cancel", api.patchCancelTemplateVersion)
r.Get("/schema", api.templateVersionSchema)
r.Get("/parameters", api.templateVersionParameters)
// Old agents may expect a non-error response from /schema and /parameters endpoints.
// 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("/gitauth", api.templateVersionGitAuth)
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
}
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
}
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 {
switch {
case provisionerJob.CanceledAt.Valid:

View File

@ -526,100 +526,6 @@ func (q *querier) canAssignRoles(ctx context.Context, orgID *uuid.UUID, added, r
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) {
version, err := q.db.GetTemplateVersionByJobID(ctx, jobID)
if err != nil {
@ -641,40 +547,6 @@ func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUI
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) {
// 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.

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() {
s.Run("GetPreviousTemplateVersion", s.Subtest(func(db database.Store, check *expects) {
tvid := uuid.New()

View File

@ -314,13 +314,6 @@ func (q *querier) GetWorkspacesEligibleForAutoStartStop(ctx context.Context, 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
func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ProvisionerJob, error) {
// 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)
}
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) {
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
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) {
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) {
// TODO: add provisioner job resource type
_ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{CreatedAt: time.Now().Add(-time.Hour)})
@ -297,12 +293,4 @@ func (s *MethodTestSuite) TestSystemFunctions() {
Transition: database.WorkspaceTransitionStart,
}).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),
gitSSHKey: make([]database.GitSSHKey, 0),
parameterSchemas: make([]database.ParameterSchema, 0),
parameterValues: make([]database.ParameterValue, 0),
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
workspaceAgents: make([]database.WorkspaceAgent, 0),
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
@ -124,7 +123,6 @@ type data struct {
groups []database.Group
licenses []database.License
parameterSchemas []database.ParameterSchema
parameterValues []database.ParameterValue
provisionerDaemons []database.ProvisionerDaemon
provisionerJobLogs []database.ProvisionerJobLog
provisionerJobs []database.ProvisionerJob
@ -575,34 +573,6 @@ func (q *fakeQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg datab
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) {
q.mutex.RLock()
defer q.mutex.RUnlock()
@ -1893,40 +1863,6 @@ func (q *fakeQuerier) GetOrganizationsByUserID(_ context.Context, userID uuid.UU
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) {
q.mutex.RLock()
defer q.mutex.RUnlock()
@ -2329,42 +2265,6 @@ func (q *fakeQuerier) GetParameterSchemasByJobID(_ context.Context, jobID uuid.U
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) {
q.mutex.RLock()
defer q.mutex.RUnlock()
@ -2977,30 +2877,6 @@ func (q *fakeQuerier) InsertOrganizationMember(_ context.Context, arg database.I
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) {
if err := validateDatabaseType(arg); err != nil {
return database.Template{}, err
@ -3139,38 +3015,6 @@ func (q *fakeQuerier) InsertProvisionerJobLogs(_ context.Context, arg database.I
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) {
if err := validateDatabaseType(arg); err != nil {
return database.ProvisionerDaemon{}, err

View File

@ -439,46 +439,6 @@ func TemplateVersionVariable(t testing.TB, db database.Store, orig database.Temp
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 {
if orig.ConnectionsByProto == nil {
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)))
})
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.Parallel()
db := dbfake.New()

View File

@ -154,13 +154,6 @@ func (m metricsStore) DeleteOldWorkspaceAgentStats(ctx context.Context) error {
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 {
start := time.Now()
err := m.s.DeleteReplicasUpdatedBefore(ctx, updatedAt)
@ -441,20 +434,6 @@ func (m metricsStore) GetParameterSchemasByJobID(ctx context.Context, jobID uuid
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) {
start := time.Now()
version, err := m.s.GetPreviousTemplateVersion(ctx, arg)
@ -1022,20 +1001,6 @@ func (m metricsStore) InsertOrganizationMember(ctx context.Context, arg database
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) {
start := time.Now()
daemon, err := m.s.InsertProvisionerDaemon(ctx, arg)
@ -1190,20 +1155,6 @@ func (m metricsStore) InsertWorkspaceResourceMetadata(ctx context.Context, arg d
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) {
start := time.Now()
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)
}
// 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.
func (m *MockStore) DeleteReplicasUpdatedBefore(arg0 context.Context, arg1 time.Time) error {
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)
}
// 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.
func (m *MockStore) GetPreviousTemplateVersion(arg0 context.Context, arg1 database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
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)
}
// 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.
func (m *MockStore) InsertProvisionerDaemon(arg0 context.Context, arg1 database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
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)
}
// 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.
func (m *MockStore) Ping(arg0 context.Context) (time.Duration, error) {
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.
DeleteOldWorkspaceAgentStartupLogs(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
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
// there is no unique constraint on empty token names
@ -86,8 +85,6 @@ type sqlcQuerier interface {
GetOrganizations(ctx context.Context) ([]Organization, error)
GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, 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)
GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, 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)
InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, 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)
InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error)
InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error)
@ -208,8 +203,6 @@ type sqlcQuerier interface {
InsertWorkspaceProxy(ctx context.Context, arg InsertWorkspaceProxyParams) (WorkspaceProxy, error)
InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, 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)
// 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
}
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
SELECT
id, created_at, updated_at, name, provisioners, replica_id, tags

View File

@ -7,48 +7,3 @@ WHERE
job_id = $1
ORDER BY
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/gitauth"
"github.com/coder/coder/coderd/httpmw"
"github.com/coder/coder/coderd/parameter"
"github.com/coder/coder/coderd/schedule"
"github.com/coder/coder/coderd/telemetry"
"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)
if err != nil {
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(),
WorkspaceName: workspace.Name,
State: workspaceBuild.ProvisionerState,
ParameterValues: protoParameters,
RichParameterValues: convertRichParameterValues(workspaceBuildParameters),
VariableValues: asVariableValues(templateVariables),
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))
}
// 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_{
TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{
ParameterValues: protoParameters,
RichParameterValues: convertRichParameterValues(input.RichParameterValues),
VariableValues: asVariableValues(templateVariables),
Metadata: &sdkproto.Provision_Metadata{
@ -617,91 +576,6 @@ func (server *Server) UpdateJob(ctx context.Context, request *proto.UpdateJobReq
}, 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{
Canceled: job.CanceledAt.Valid,
}, nil
@ -1545,37 +1419,6 @@ func obtainOIDCAccessToken(ctx context.Context, db database.Store, oidcConfig ht
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) {
switch logLevel {
case sdkproto.LogLevel_TRACE:
@ -1627,37 +1470,6 @@ func convertVariableValues(variableValues []codersdk.VariableValue) []*sdkproto.
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) {
switch transition {
case database.WorkspaceTransitionStart:
@ -1700,7 +1512,6 @@ type WorkspaceProvisionJob struct {
type TemplateVersionDryRunJob struct {
TemplateVersionID uuid.UUID `json:"template_version_id"`
WorkspaceName string `json:"workspace_name"`
ParameterValues []database.ParameterValue `json:"parameter_values"`
RichParameterValues []database.WorkspaceBuildParameter `json:"rich_parameter_values"`
}

View File

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

View File

@ -308,22 +308,6 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
}
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 {
jobs, err := r.options.Database.GetProvisionerJobsCreatedAfter(ctx, createdAfter)
if err != nil {
@ -688,7 +672,6 @@ type Snapshot struct {
DeploymentID string `json:"deployment_id"`
APIKeys []APIKey `json:"api_keys"`
ParameterSchemas []ParameterSchema `json:"parameter_schemas"`
ProvisionerJobs []ProvisionerJob `json:"provisioner_jobs"`
Licenses []License `json:"licenses"`
Templates []Template `json:"templates"`

View File

@ -39,11 +39,6 @@ func TestTelemetry(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitMedium)
_, _ = 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{
Provisioner: database.ProvisionerTypeTerraform,
StorageMethod: database.ProvisionerStorageMethodFile,
@ -87,7 +82,6 @@ func TestTelemetry(t *testing.T) {
})
assert.NoError(t, err)
_, snapshot := collectSnapshot(t, db)
require.Len(t, snapshot.ParameterSchemas, 1)
require.Len(t, snapshot.ProvisionerJobs, 1)
require.Len(t, snapshot.Licenses, 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
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})
if err != nil {
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
}
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
@ -168,19 +173,7 @@ func (api *API) patchTemplateVersion(rw http.ResponseWriter, r *http.Request) {
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
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user, schemas))
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user, nil))
}
// @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
// @ID get-rich-parameters-by-template-version
// @Security CoderSessionToken
@ -470,52 +411,6 @@ func (api *API) templateVersionVariables(rw http.ResponseWriter, r *http.Request
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
// @ID create-template-version-dry-run
// @Security CoderSessionToken
@ -561,20 +456,6 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques
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))
for i, v := range req.RichParameterValues {
richParameterValues[i] = database.WorkspaceBuildParameter{
@ -589,7 +470,6 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques
input, err := json.Marshal(provisionerdserver.TemplateVersionDryRunJob{
TemplateVersionID: templateVersion.ID,
WorkspaceName: req.WorkspaceName,
ParameterValues: parameterValues,
RichParameterValues: richParameterValues,
})
if err != nil {
@ -911,18 +791,7 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque
})
return err
}
schemas, err := store.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 err
}
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user, schemas))
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user, nil))
}
return nil
@ -986,19 +855,7 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
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
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas))
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, nil))
}
// @Summary Get template version by organization, template, and name
@ -1072,19 +929,7 @@ func (api *API) templateVersionByOrganizationTemplateAndName(rw http.ResponseWri
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
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas))
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, nil))
}
// @Summary Get previous template version by organization, template, and name
@ -1179,19 +1024,7 @@ func (api *API) previousTemplateVersionByOrganizationTemplateAndName(rw http.Res
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
}
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user, schemas))
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user, nil))
}
// @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
err = api.Database.InTx(func(tx database.Store) error {
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()
jobInput, err := json.Marshal(provisionerdserver.TemplateVersionImportJob{
@ -1565,19 +1336,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
return
}
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, provisionerJob.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
}
httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user, schemas))
httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user, nil))
}
// 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)
}
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{
ID: user.ID,
Username: user.Username,
@ -1655,11 +1414,6 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi
AvatarURL: user.AvatarURL.String,
}
var warnings []codersdk.TemplateVersionWarning
if len(schemas) > 0 {
warnings = append(warnings, codersdk.TemplateVersionWarningDeprecatedParameters)
}
return codersdk.TemplateVersion{
ID: version.ID,
TemplateID: &version.TemplateID.UUID,

View File

@ -124,12 +124,6 @@ func TestPostTemplateVersionsByOrganization(t *testing.T) {
StorageMethod: codersdk.ProvisionerStorageMethodFile,
FileID: file.ID,
Provisioner: codersdk.ProvisionerTypeEcho,
ParameterValues: []codersdk.CreateParameterRequest{{
Name: "example",
SourceValue: "value",
SourceScheme: codersdk.ParameterSourceSchemeData,
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
}},
})
require.NoError(t, err)
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) {
t.Parallel()
t.Run("Empty", func(t *testing.T) {
@ -757,9 +604,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel()
// Create template version dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
ParameterValues: []codersdk.CreateParameterRequest{},
})
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
require.NoError(t, err)
// Fetch template version dry-run
@ -815,9 +660,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
_, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
ParameterValues: []codersdk.CreateParameterRequest{},
})
_, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
@ -858,9 +701,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel()
// Create the dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
ParameterValues: []codersdk.CreateParameterRequest{},
})
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
require.NoError(t, err)
require.Equal(t, codersdk.ProvisionerJobPending, job.Status)
err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID)
@ -881,9 +722,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel()
// Create the dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
ParameterValues: []codersdk.CreateParameterRequest{},
})
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
require.NoError(t, err)
require.Eventually(t, func() bool {
@ -933,9 +772,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
defer cancel()
// Create the dry-run
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
ParameterValues: []codersdk.CreateParameterRequest{},
})
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
require.NoError(t, err)
err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID)
@ -1454,45 +1291,3 @@ func TestTemplateVersionPatch(t *testing.T) {
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)).
Initiator(apiKey.UserID).
LegacyParameterValues(createBuild.ParameterValues).
RichParameterValues(createBuild.RichParameterValues).
LogLevel(string(createBuild.LogLevel))

View File

@ -637,173 +637,6 @@ func TestWorkspaceBuildStatus(t *testing.T) {
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) {
t.Parallel()

View File

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

View File

@ -34,15 +34,14 @@ import (
// build, job, err := b.Build(...)
type Builder struct {
// settings that control the kind of build you get
workspace database.Workspace
trans database.WorkspaceTransition
version versionTarget
state stateTarget
logLevel string
legacyParameterValues []codersdk.CreateParameterRequest
richParameterValues []codersdk.WorkspaceBuildParameter
initiator uuid.UUID
reason database.BuildReason
workspace database.Workspace
trans database.WorkspaceTransition
version versionTarget
state stateTarget
logLevel string
richParameterValues []codersdk.WorkspaceBuildParameter
initiator uuid.UUID
reason database.BuildReason
// used during build, makes function arguments less verbose
ctx context.Context
@ -56,8 +55,9 @@ type Builder struct {
lastBuild *database.WorkspaceBuild
lastBuildErr *error
lastBuildParameters *[]database.WorkspaceBuildParameter
lastParameterValues *[]database.ParameterValue
lastBuildJob *database.ProvisionerJob
verifyNoLegacyParametersOnce bool
}
type Option func(Builder) Builder
@ -140,12 +140,6 @@ func (b Builder) Reason(r database.BuildReason) Builder {
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 {
// nolint: revive
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 b.initiator == uuid.Nil {
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
}
// 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()
input, err := json.Marshal(provisionerdserver.WorkspaceProvisionJob{
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)
now := database.Now()
provisionerJob, err := b.store.InsertProvisionerJob(b.ctx, database.InsertProvisionerJobParams{
ID: uuid.New(),
CreatedAt: now,
@ -536,13 +483,12 @@ func (b *Builder) getParameters() (names, values []string, err error) {
if err != nil {
return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch last build parameters", err}
}
lastParameterValues, err := b.getLastParameterValues()
err = b.verifyNoLegacyParameters()
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{
Rich: db2sdk.WorkspaceBuildParameters(lastBuildParameters),
Legacy: db2sdk.Parameters(lastParameterValues),
Rich: db2sdk.WorkspaceBuildParameters(lastBuildParameters),
}
for _, templateVersionParameter := range templateVersionParameters {
tvp, err := db2sdk.TemplateVersionParameter(templateVersionParameter)
@ -611,19 +557,36 @@ func (b *Builder) getTemplateVersionParameters() ([]database.TemplateVersionPara
return tvp, nil
}
func (b *Builder) getLastParameterValues() ([]database.ParameterValue, error) {
if b.lastParameterValues != nil {
return *b.lastParameterValues, nil
// verifyNoLegacyParameters verifies that initiator can't start the workspace build
// if it uses legacy parameters (database.ParameterSchemas).
func (b *Builder) verifyNoLegacyParameters() error {
if b.verifyNoLegacyParametersOnce {
return nil
}
pv, err := b.store.ParameterValues(b.ctx, database.ParameterValuesParams{
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
ScopeIds: []uuid.UUID{b.workspace.ID},
})
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
return nil, xerrors.Errorf("get workspace %w parameter values: %w", b.workspace.ID, err)
b.verifyNoLegacyParametersOnce = true
// Block starting the workspace with legacy parameters.
if b.trans != database.WorkspaceTransitionStart {
return nil
}
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) {

View File

@ -4,7 +4,6 @@ import (
"context"
"database/sql"
"encoding/json"
"fmt"
"net/http"
"testing"
"time"
@ -24,21 +23,19 @@ import (
var (
// use fixed IDs so logs are easier to read
templateID = uuid.MustParse("12341234-0000-0000-0001-000000000000")
activeVersionID = uuid.MustParse("12341234-0000-0000-0002-000000000000")
inactiveVersionID = uuid.MustParse("12341234-0000-0000-0003-000000000000")
activeJobID = uuid.MustParse("12341234-0000-0000-0004-000000000000")
inactiveJobID = uuid.MustParse("12341234-0000-0000-0005-000000000000")
orgID = uuid.MustParse("12341234-0000-0000-0006-000000000000")
workspaceID = uuid.MustParse("12341234-0000-0000-0007-000000000000")
userID = uuid.MustParse("12341234-0000-0000-0008-000000000000")
activeFileID = uuid.MustParse("12341234-0000-0000-0009-000000000000")
inactiveFileID = uuid.MustParse("12341234-0000-0000-000a-000000000000")
lastBuildID = uuid.MustParse("12341234-0000-0000-000b-000000000000")
lastBuildJobID = uuid.MustParse("12341234-0000-0000-000c-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")
templateID = uuid.MustParse("12341234-0000-0000-0001-000000000000")
activeVersionID = uuid.MustParse("12341234-0000-0000-0002-000000000000")
inactiveVersionID = uuid.MustParse("12341234-0000-0000-0003-000000000000")
activeJobID = uuid.MustParse("12341234-0000-0000-0004-000000000000")
inactiveJobID = uuid.MustParse("12341234-0000-0000-0005-000000000000")
orgID = uuid.MustParse("12341234-0000-0000-0006-000000000000")
workspaceID = uuid.MustParse("12341234-0000-0000-0007-000000000000")
userID = uuid.MustParse("12341234-0000-0000-0008-000000000000")
activeFileID = uuid.MustParse("12341234-0000-0000-0009-000000000000")
inactiveFileID = uuid.MustParse("12341234-0000-0000-000a-000000000000")
lastBuildID = uuid.MustParse("12341234-0000-0000-000b-000000000000")
lastBuildJobID = uuid.MustParse("12341234-0000-0000-000c-000000000000")
otherUserID = uuid.MustParse("12341234-0000-0000-000d-000000000000")
)
func TestBuilder_NoOptions(t *testing.T) {
@ -56,7 +53,8 @@ func TestBuilder_NoOptions(t *testing.T) {
withTemplate,
withInactiveVersion(nil),
withLastBuildFound,
withLegacyParameters(nil), withRichParameters(nil),
withRichParameters(nil),
withParameterSchemas(inactiveJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
@ -104,7 +102,8 @@ func TestBuilder_Initiator(t *testing.T) {
withTemplate,
withInactiveVersion(nil),
withLastBuildFound,
withLegacyParameters(nil), withRichParameters(nil),
withRichParameters(nil),
withParameterSchemas(inactiveJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
@ -136,7 +135,8 @@ func TestBuilder_Reason(t *testing.T) {
withTemplate,
withInactiveVersion(nil),
withLastBuildFound,
withLegacyParameters(nil), withRichParameters(nil),
withRichParameters(nil),
withParameterSchemas(inactiveJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
@ -167,7 +167,7 @@ func TestBuilder_ActiveVersion(t *testing.T) {
withTemplate,
withActiveVersion(nil),
withLastBuildNotFound,
withLegacyParameters(nil),
withParameterSchemas(activeJobID, nil),
// previous rich parameters are not queried because there is no previous build.
// Outputs
@ -190,47 +190,6 @@ func TestBuilder_ActiveVersion(t *testing.T) {
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) {
t.Parallel()
@ -285,8 +244,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate,
withInactiveVersion(richParameters),
withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters),
withParameterSchemas(inactiveJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -326,8 +285,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate,
withInactiveVersion(richParameters),
withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters),
withParameterSchemas(inactiveJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -348,6 +307,47 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
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.Parallel()
@ -366,8 +366,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate,
withInactiveVersion(richParameters),
withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters),
withParameterSchemas(inactiveJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -418,8 +418,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate,
withActiveVersion(version2params),
withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters),
withParameterSchemas(activeJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -476,8 +476,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate,
withActiveVersion(version2params),
withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters),
withParameterSchemas(activeJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -532,8 +532,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
withTemplate,
withActiveVersion(version2params),
withLastBuildFound,
withLegacyParameters(nil),
withRichParameters(initialBuildParameters),
withParameterSchemas(activeJobID, nil),
// Outputs
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
@ -710,17 +710,14 @@ func withLastBuildNotFound(mTx *dbmock.MockStore) {
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) {
c := mTx.EXPECT().ParameterValues(
c := mTx.EXPECT().GetParameterSchemasByJobID(
gomock.Any(),
database.ParameterValuesParams{
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
ScopeIds: []uuid.UUID{workspaceID},
}).
jobID).
Times(1)
if len(params) > 0 {
c.Return(params, nil)
if len(schemas) > 0 {
c.Return(schemas, nil)
} else {
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"`
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"`
}
@ -82,8 +78,7 @@ type CreateTemplateRequest struct {
// 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.
VersionID uuid.UUID `json:"template_version_id" validate:"required" format:"uuid"`
ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"`
VersionID uuid.UUID `json:"template_version_id" validate:"required" format:"uuid"`
// DefaultTTLMillis allows optionally specifying the default TTL
// for all workspaces created from this template.
@ -123,7 +118,6 @@ type CreateWorkspaceRequest struct {
TTLMillis *int64 `json:"ttl_ms,omitempty"`
// ParameterValues allows for additional parameters to be provided
// during the initial provision.
ParameterValues []CreateParameterRequest `json:"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.
// @typescript-ignore ParameterResolver
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
@ -173,16 +172,5 @@ func (r *ParameterResolver) findLastValue(p TemplateVersionParameter) *Workspace
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
}

View File

@ -137,45 +137,6 @@ func TestParameterResolver_ValidateResolve_Immutable(t *testing.T) {
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) {
t.Parallel()

View File

@ -14,7 +14,7 @@ import (
type TemplateVersionWarning string
const (
TemplateVersionWarningDeprecatedParameters TemplateVersionWarning = "DEPRECATED_PARAMETERS"
TemplateVersionWarningUnsupportedWorkspaces TemplateVersionWarning = "UNSUPPORTED_WORKSPACES"
)
// 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)
}
// 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.
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)
@ -209,7 +181,6 @@ func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID
// CreateTemplateVersionDryRun.
type CreateTemplateVersionDryRunRequest struct {
WorkspaceName string `json:"workspace_name"`
ParameterValues []CreateParameterRequest `json:"parameter_values"`
RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values"`
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.
// This will overwrite any existing parameters with the same name.
// This will not delete old params not included in this list.
ParameterValues []CreateParameterRequest `json:"parameter_values,omitempty"`
RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values,omitempty"`
// 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,
"log_level": "debug",
"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": [
{
"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 | | |
## 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
```json
@ -1383,51 +1349,32 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"inactivity_ttl_ms": 0,
"max_ttl_ms": 0,
"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"
}
```
### Properties
| 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_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". |
| `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. |
| `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. |
| `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. |
| `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. |
| `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. |
| 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_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". |
| `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. |
| `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. |
| `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. |
| `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. |
| `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. |
## codersdk.CreateTemplateVersionDryRunRequest
```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": [
{
"name": "string",
@ -1446,12 +1393,11 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties
| 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 | | |
| `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | |
| `workspace_name` | string | false | | |
| Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | ----------- |
| `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | |
| `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | |
| `workspace_name` | string | false | | |
## codersdk.CreateTemplateVersionRequest
@ -1460,15 +1406,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"example_id": "string",
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
"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",
"storage_method": "file",
"tags": {
@ -1487,18 +1424,17 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties
| Name | Type | Required | Restrictions | Description |
| ---------------------- | --------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------- |
| `example_id` | string | false | | |
| `file_id` | 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 | | |
| `storage_method` | [codersdk.ProvisionerStorageMethod](#codersdkprovisionerstoragemethod) | true | | |
| `tags` | object | false | | |
| » `[any property]` | string | false | | |
| `template_id` | string | false | | Template ID optionally associates a version with a template. |
| `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | |
| Name | Type | Required | Restrictions | Description |
| ---------------------- | ---------------------------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------ |
| `example_id` | string | false | | |
| `file_id` | string | false | | |
| `name` | string | false | | |
| `provisioner` | string | true | | |
| `storage_method` | [codersdk.ProvisionerStorageMethod](#codersdkprovisionerstoragemethod) | true | | |
| `tags` | object | false | | |
| » `[any property]` | string | false | | |
| `template_id` | string | false | | Template ID optionally associates a version with a template. |
| `user_variable_values` | array of [codersdk.VariableValue](#codersdkvariablevalue) | false | | |
#### Enumerated Values
@ -1604,15 +1540,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
"dry_run": true,
"log_level": "debug",
"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": [
{
"name": "string",
@ -1627,16 +1554,15 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties
| Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dry_run` | boolean | false | | |
| `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. |
| `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 | | |
| `state` | array of integer | false | | |
| `template_version_id` | string | false | | |
| `transition` | [codersdk.WorkspaceTransition](#codersdkworkspacetransition) | true | | |
| Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dry_run` | boolean | false | | |
| `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. |
| `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. |
| `state` | array of integer | false | | |
| `template_version_id` | string | false | | |
| `transition` | [codersdk.WorkspaceTransition](#codersdkworkspacetransition) | true | | |
#### Enumerated Values
@ -1672,15 +1598,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
{
"autostart_schedule": "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": [
{
"name": "string",
@ -1694,14 +1611,13 @@ CreateParameterRequest is a structure used to create a new parameter value for a
### Properties
| Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------- |
| `autostart_schedule` | string | false | | |
| `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 | | |
| `template_id` | string | true | | |
| `ttl_ms` | integer | false | | |
| Name | Type | Required | Restrictions | Description |
| ----------------------- | ----------------------------------------------------------------------------- | -------- | ------------ | --------------------------------------------------------------------------------------------------- |
| `autostart_schedule` | string | false | | |
| `name` | string | true | | |
| `rich_parameter_values` | array of [codersdk.WorkspaceBuildParameter](#codersdkworkspacebuildparameter) | false | | Rich parameter values allows for additional parameters to be provided during the initial provision. |
| `template_id` | string | true | | |
| `ttl_ms` | integer | false | | |
## codersdk.DAUEntry
@ -3104,154 +3020,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a
| `updated_at` | 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
```json
@ -4142,7 +3910,7 @@ Parameter represents a set value for the scope.
"readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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
```json
"DEPRECATED_PARAMETERS"
"UNSUPPORTED_WORKSPACES"
```
### Properties
#### Enumerated Values
| Value |
| ----------------------- |
| `DEPRECATED_PARAMETERS` |
| Value |
| ------------------------ |
| `UNSUPPORTED_WORKSPACES` |
## codersdk.TokenConfig
@ -5796,53 +5564,6 @@ Parameter represents a set value for the scope.
| `count` | integer | 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
```json
@ -6500,40 +6221,6 @@ Parameter represents a set value for the scope.
| `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. |
## 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
```json

View File

@ -135,15 +135,6 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
"inactivity_ttl_ms": 0,
"max_ttl_ms": 0,
"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"
}
```
@ -395,7 +386,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat
"readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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",
"file_id": "8a0cfb4f-ddc9-436d-91bb-75133c583767",
"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",
"storage_method": "file",
"tags": {
@ -583,7 +565,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
"readme": "string",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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",
"template_id": "c6d67e98-83ea-49f0-8812-e4abae2b68bc",
"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
{
"parameter_values": [
{
"copy_from_parameter": "000e07d6-021d-446c-be14-48a9c20bca0b",
"destination_scheme": "none",
"name": "string",
"source_scheme": "none",
"source_value": "string"
}
],
"rich_parameter_values": [
{
"name": "string",
@ -1949,14 +1922,13 @@ Status Code **200**
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
```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/parameters \
-H 'Accept: application/json' \
-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 |
### 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
| Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | --------------------------------------------------------------------- |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [parameter.ComputedValue](schemas.md#parametercomputedvalue) |
<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` |
| Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | ------ |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | |
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).
## Get schema by template version
## Removed: Get schema by template version
### Code samples
```shell
# Example request using curl
curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/schema \
-H 'Accept: application/json' \
-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 |
### 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
| Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | ----------------------------------------------------------------------- |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | array of [codersdk.ParameterSchema](schemas.md#codersdkparameterschema) |
<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` |
| Status | Meaning | Description | Schema |
| ------ | ------------------------------------------------------- | ----------- | ------ |
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | |
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",
"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": [
{
"name": "string",

View File

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

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).
### --parameter-file
| | |
| ---- | ------------------- |
| Type | <code>string</code> |
Specify a file path with parameter values.
### --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.
### --parameter-file
| | |
| ---- | ------------------- |
| Type | <code>string</code> |
Specify a file path with parameter values.
### --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.
### --parameter-file
| | |
| ----------- | ---------------------------------- |
| Type | <code>string</code> |
| Environment | <code>$CODER_PARAMETER_FILE</code> |
Specify a file path with parameter values.
### --rich-parameter-file
| | |

View File

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

View File

@ -72,21 +72,6 @@ var (
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.
@ -151,22 +136,6 @@ func (e *echo) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
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++ {
var extension string
if msg.GetPlan() != nil {

View File

@ -49,11 +49,7 @@ func TestEcho(t *testing.T) {
},
}, {
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: []*proto.ParameterSchema{{
Name: "parameter-schema",
}},
},
Complete: &proto.Parse_Complete{},
},
}}
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)
complete, err := client.Recv()
require.NoError(t, err)
require.Equal(t, responses[1].GetComplete().ParameterSchemas[0].Name,
complete.GetComplete().ParameterSchemas[0].Name)
require.NotNil(t, complete)
})
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)
})
var parameters []*proto.ParameterSchema
var templateVariables []*proto.TemplateVariable
useManagedVariables := flags != nil && flags[featureUseManagedVariables]
@ -76,20 +75,12 @@ func (s *server) Parse(request *proto.Parse_Request, stream proto.DRPCProvisione
}
templateVariables = append(templateVariables, mv)
}
} else {
for _, v := range variables {
schema, err := convertVariableToParameter(v)
if err != nil {
return xerrors.Errorf("convert variable %q: %w", v.Name, err)
}
parameters = append(parameters, schema)
}
} else if len(variables) > 0 {
return xerrors.Errorf("legacy parameters are not supported anymore, use %q flag to enable managed Terraform variables", featureUseManagedVariables)
}
return stream.Send(&proto.Parse_Response{
Type: &proto.Parse_Response_Complete{
Complete: &proto.Parse_Complete{
ParameterSchemas: parameters,
TemplateVariables: templateVariables,
},
},
@ -164,51 +155,6 @@ func parseFeatures(hclFilepath string) (map[string]bool, bool, hcl.Diagnostics)
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.
func convertTerraformVariableToManagedVariable(variable *tfconfig.Variable) (*proto.TemplateVariable, error) {
var defaultData string

View File

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

View File

@ -140,7 +140,7 @@ func (s *server) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
return xerrors.Errorf("initialize terraform: %w", err)
}
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 {
return err
}
@ -193,23 +193,13 @@ func (s *server) Provision(stream proto.DRPCProvisioner_ProvisionStream) error {
func planVars(plan *proto.Provision_Plan) ([]string, error) {
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 {
vars = append(vars, fmt.Sprintf("%s=%s", variable.Name, variable.Value))
}
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 = append(env,
"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() {
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 {
env = append(env, provider.ParameterEnvironmentVariable(param.Name)+"="+param.Value)
}

View File

@ -203,27 +203,6 @@ func TestProvision(t *testing.T) {
ExpectLogContains string
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",
Files: map[string]string{
@ -305,22 +284,6 @@ func TestProvision(t *testing.T) {
},
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",
Files: map[string]string{
@ -462,7 +425,6 @@ func TestProvision(t *testing.T) {
if planRequest.GetPlan().GetConfig() == nil {
planRequest.GetPlan().Config = &proto.Provision_Config{}
}
planRequest.GetPlan().ParameterValues = testCase.Request.ParameterValues
planRequest.GetPlan().RichParameterValues = testCase.Request.RichParameterValues
planRequest.GetPlan().GitAuthProviders = testCase.Request.GitAuthProviders
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"`
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"`
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"`
@ -616,13 +615,6 @@ func (x *UpdateJobRequest) GetLogs() []*Log {
return nil
}
func (x *UpdateJobRequest) GetParameterSchemas() []*proto.ParameterSchema {
if x != nil {
return x.ParameterSchemas
}
return nil
}
func (x *UpdateJobRequest) GetTemplateVariables() []*proto.TemplateVariable {
if x != nil {
return x.TemplateVariables
@ -649,11 +641,8 @@ type UpdateJobResponse struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Canceled bool `protobuf:"varint,1,opt,name=canceled,proto3" json:"canceled,omitempty"`
// If parameter schemas are sent, the job will respond
// 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"`
Canceled bool `protobuf:"varint,1,opt,name=canceled,proto3" json:"canceled,omitempty"`
VariableValues []*proto.VariableValue `protobuf:"bytes,3,rep,name=variable_values,json=variableValues,proto3" json:"variable_values,omitempty"`
}
func (x *UpdateJobResponse) Reset() {
@ -695,13 +684,6 @@ func (x *UpdateJobResponse) GetCanceled() bool {
return false
}
func (x *UpdateJobResponse) GetParameterValues() []*proto.ParameterValue {
if x != nil {
return x.ParameterValues
}
return nil
}
func (x *UpdateJobResponse) GetVariableValues() []*proto.VariableValue {
if x != nil {
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"`
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"`
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"`
@ -889,13 +870,6 @@ func (x *AcquiredJob_WorkspaceBuild) GetWorkspaceName() string {
return ""
}
func (x *AcquiredJob_WorkspaceBuild) GetParameterValues() []*proto.ParameterValue {
if x != nil {
return x.ParameterValues
}
return nil
}
func (x *AcquiredJob_WorkspaceBuild) GetRichParameterValues() []*proto.RichParameterValue {
if x != nil {
return x.RichParameterValues
@ -998,7 +972,6 @@ type AcquiredJob_TemplateDryRun struct {
sizeCache protoimpl.SizeCache
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"`
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"`
@ -1036,13 +1009,6 @@ func (*AcquiredJob_TemplateDryRun) Descriptor() ([]byte, []int) {
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 {
if x != nil {
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,
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,
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,
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,
@ -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,
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,
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,
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,
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,
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,
0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f,
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68,
0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,
0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61,
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a,
0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73,
0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x67, 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x47, 0x69, 0x74,
0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x10, 0x67, 0x69,
0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x3b,
0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73,
0x74, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74,
0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x09,
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x1a, 0x9b,
0x01, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4c,
0x0a, 0x14, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61,
0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61,
0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0xaf, 0x02, 0x0a,
0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12,
0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f,
0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73,
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72,
0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f,
0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18,
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x40,
0x0a, 0x12, 0x54, 0x72, 0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x03, 0x0a, 0x09, 0x46, 0x61, 0x69,
0x6c, 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, 0x14, 0x0a,
0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x12, 0x51, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 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, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42,
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,
0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69,
0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72,
0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69,
0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x67, 0x69,
0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73,
0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x47, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76,
0x69, 0x64, 0x65, 0x72, 0x52, 0x10, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f,
0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67,
0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f,
0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x1a, 0x9b, 0x01, 0x0a,
0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12,
0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4c, 0x0a, 0x14,
0x75, 0x73, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69,
0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0xed, 0x01, 0x0a, 0x0e, 0x54,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x53, 0x0a,
0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50,
0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72,
0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72,
0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61,
0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x1a, 0x40, 0x0a, 0x12, 0x54, 0x72,
0x61, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04,
0x74, 0x79, 0x70, 0x65, 0x22, 0xa5, 0x03, 0x0a, 0x09, 0x46, 0x61, 0x69, 0x6c, 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, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12,
0x51, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69,
0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 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, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 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, 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, 0x61, 0x74, 0x65, 0x49,
0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x52, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
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,
0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 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,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20,
0x01, 0x28, 0x0b, 0x32, 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, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74,
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x1d, 0x0a,
0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28,
0x09, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0x26, 0x0a, 0x0e,
0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14,
0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73,
0x74, 0x61, 0x74, 0x65, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61,
0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
0x22, 0xd8, 0x05, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 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, 0x54, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x29, 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, 0x2e, 0x57, 0x6f,
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e,
0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x54,
0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f,
0x72, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d,
0x70, 0x6f, 0x72, 0x74, 0x12, 0x55, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29,
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, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x5b, 0x0a, 0x0e, 0x57,
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a,
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74,
0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x81, 0x02, 0x0a, 0x0e, 0x54, 0x65, 0x6d,
0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x0f, 0x73,
0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0e, 0x73, 0x74, 0x61,
0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x73,
0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x69, 0x63,
0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0e,
0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2c,
0x0a, 0x12, 0x67, 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x41,
0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x45, 0x0a, 0x0e,
0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x33,
0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03,
0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65,
0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xcf,
0x02, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f,
0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67,
0x73, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73,
0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61,
0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x4c, 0x0a, 0x12,
0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,
0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56,
0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x14, 0x75, 0x73,
0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,
0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64,
0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65,
0x22, 0xbc, 0x01, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c,
0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c,
0x65, 0x64, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70,
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d,
0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61,
0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
0x0e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22,
0x4a, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 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, 0x0a,
0x64, 0x61, 0x69, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x52, 0x09, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x73, 0x74, 0x22, 0x68, 0x0a, 0x13, 0x43,
0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02,
0x6f, 0x6b, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x5f, 0x63, 0x6f,
0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x63, 0x72,
0x65, 0x64, 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x16, 0x0a,
0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x62,
0x75, 0x64, 0x67, 0x65, 0x74, 0x2a, 0x34, 0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45,
0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52,
0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x32, 0xec, 0x02, 0x0a, 0x11,
0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f,
0x6e, 0x12, 0x3c, 0x0a, 0x0a, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x12,
0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12,
0x52, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x20,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f,
0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62,
0x12, 0x1e, 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, 0x71, 0x75, 0x65, 0x73, 0x74,
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,
0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c,
0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65,
0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x1a, 0x26, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f,
0x72, 0x74, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72,
0x79, 0x52, 0x75, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xd8, 0x05, 0x0a,
0x0c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 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, 0x54, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b,
0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x74, 0x65,
0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x2e,
0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00,
0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74,
0x12, 0x55, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x79,
0x5f, 0x72, 0x75, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44,
0x72, 0x79, 0x52, 0x75, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x5b, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73,
0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12,
0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x73, 0x1a, 0x81, 0x02, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74,
0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x70, 0x5f,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61,
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63,
0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x72, 0x69, 0x63, 0x68,
0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x67, 0x69,
0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73,
0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x50,
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x45, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70,
0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e,
0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x42,
0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12,
0x2f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c,
0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x12, 0x2b, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f,
0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a,
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05,
0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61,
0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x8a, 0x02, 0x0a, 0x10, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x4c, 0x0a,
0x12, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62,
0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x14, 0x75,
0x73, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76,
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x75, 0x73, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61,
0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61,
0x64, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d,
0x65, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x7a, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08,
0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69,
0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e,
0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76,
0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4a, 0x04, 0x08,
0x02, 0x10, 0x03, 0x22, 0x4a, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f,
0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 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, 0x0a, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x02,
0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x6f, 0x73, 0x74, 0x22,
0x68, 0x0a, 0x13, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x6b, 0x18, 0x01, 0x20, 0x01,
0x28, 0x08, 0x52, 0x02, 0x6f, 0x6b, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74,
0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
0x52, 0x0f, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65,
0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x05, 0x52, 0x06, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74, 0x2a, 0x34, 0x0a, 0x09, 0x4c, 0x6f, 0x67,
0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53,
0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0f,
0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x32,
0xec, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x44,
0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x0a, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65,
0x4a, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64,
0x4a, 0x6f, 0x62, 0x12, 0x52, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f,
0x74, 0x61, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61, 0x74,
0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1e, 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, 0x71,
0x75, 0x65, 0x73, 0x74, 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 (
@ -1664,15 +1614,13 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{
(*CompletedJob_TemplateImport)(nil), // 18: provisionerd.CompletedJob.TemplateImport
(*CompletedJob_TemplateDryRun)(nil), // 19: provisionerd.CompletedJob.TemplateDryRun
(proto.LogLevel)(0), // 20: provisioner.LogLevel
(*proto.ParameterSchema)(nil), // 21: provisioner.ParameterSchema
(*proto.TemplateVariable)(nil), // 22: provisioner.TemplateVariable
(*proto.VariableValue)(nil), // 23: provisioner.VariableValue
(*proto.ParameterValue)(nil), // 24: provisioner.ParameterValue
(*proto.RichParameterValue)(nil), // 25: provisioner.RichParameterValue
(*proto.GitAuthProvider)(nil), // 26: provisioner.GitAuthProvider
(*proto.Provision_Metadata)(nil), // 27: provisioner.Provision.Metadata
(*proto.Resource)(nil), // 28: provisioner.Resource
(*proto.RichParameter)(nil), // 29: provisioner.RichParameter
(*proto.TemplateVariable)(nil), // 21: provisioner.TemplateVariable
(*proto.VariableValue)(nil), // 22: provisioner.VariableValue
(*proto.RichParameterValue)(nil), // 23: provisioner.RichParameterValue
(*proto.GitAuthProvider)(nil), // 24: provisioner.GitAuthProvider
(*proto.Provision_Metadata)(nil), // 25: provisioner.Provision.Metadata
(*proto.Resource)(nil), // 26: provisioner.Resource
(*proto.RichParameter)(nil), // 27: provisioner.RichParameter
}
var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{
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
20, // 11: provisionerd.Log.level:type_name -> provisioner.LogLevel
5, // 12: provisionerd.UpdateJobRequest.logs:type_name -> provisionerd.Log
21, // 13: provisionerd.UpdateJobRequest.parameter_schemas:type_name -> provisioner.ParameterSchema
22, // 14: provisionerd.UpdateJobRequest.template_variables:type_name -> provisioner.TemplateVariable
23, // 15: provisionerd.UpdateJobRequest.user_variable_values:type_name -> provisioner.VariableValue
24, // 16: provisionerd.UpdateJobResponse.parameter_values:type_name -> provisioner.ParameterValue
23, // 17: provisionerd.UpdateJobResponse.variable_values:type_name -> provisioner.VariableValue
24, // 18: provisionerd.AcquiredJob.WorkspaceBuild.parameter_values:type_name -> provisioner.ParameterValue
25, // 19: provisionerd.AcquiredJob.WorkspaceBuild.rich_parameter_values:type_name -> provisioner.RichParameterValue
23, // 20: provisionerd.AcquiredJob.WorkspaceBuild.variable_values:type_name -> provisioner.VariableValue
26, // 21: provisionerd.AcquiredJob.WorkspaceBuild.git_auth_providers:type_name -> provisioner.GitAuthProvider
27, // 22: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata
27, // 23: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata
23, // 24: provisionerd.AcquiredJob.TemplateImport.user_variable_values:type_name -> provisioner.VariableValue
24, // 25: provisionerd.AcquiredJob.TemplateDryRun.parameter_values:type_name -> provisioner.ParameterValue
25, // 26: provisionerd.AcquiredJob.TemplateDryRun.rich_parameter_values:type_name -> provisioner.RichParameterValue
23, // 27: provisionerd.AcquiredJob.TemplateDryRun.variable_values:type_name -> provisioner.VariableValue
27, // 28: provisionerd.AcquiredJob.TemplateDryRun.metadata:type_name -> provisioner.Provision.Metadata
28, // 29: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource
28, // 30: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource
28, // 31: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource
29, // 32: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter
28, // 33: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource
1, // 34: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty
8, // 35: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest
6, // 36: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest
3, // 37: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob
4, // 38: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob
2, // 39: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob
9, // 40: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse
7, // 41: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse
1, // 42: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty
1, // 43: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty
39, // [39:44] is the sub-list for method output_type
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
21, // 13: provisionerd.UpdateJobRequest.template_variables:type_name -> provisioner.TemplateVariable
22, // 14: provisionerd.UpdateJobRequest.user_variable_values:type_name -> provisioner.VariableValue
22, // 15: provisionerd.UpdateJobResponse.variable_values:type_name -> provisioner.VariableValue
23, // 16: provisionerd.AcquiredJob.WorkspaceBuild.rich_parameter_values:type_name -> provisioner.RichParameterValue
22, // 17: provisionerd.AcquiredJob.WorkspaceBuild.variable_values:type_name -> provisioner.VariableValue
24, // 18: provisionerd.AcquiredJob.WorkspaceBuild.git_auth_providers:type_name -> provisioner.GitAuthProvider
25, // 19: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata
25, // 20: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata
22, // 21: provisionerd.AcquiredJob.TemplateImport.user_variable_values:type_name -> provisioner.VariableValue
23, // 22: provisionerd.AcquiredJob.TemplateDryRun.rich_parameter_values:type_name -> provisioner.RichParameterValue
22, // 23: provisionerd.AcquiredJob.TemplateDryRun.variable_values:type_name -> provisioner.VariableValue
25, // 24: provisionerd.AcquiredJob.TemplateDryRun.metadata:type_name -> provisioner.Provision.Metadata
26, // 25: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource
26, // 26: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource
26, // 27: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource
27, // 28: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter
26, // 29: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource
1, // 30: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty
8, // 31: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest
6, // 32: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest
3, // 33: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob
4, // 34: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob
2, // 35: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob
9, // 36: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse
7, // 37: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse
1, // 38: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty
1, // 39: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty
35, // [35:40] is the sub-list for method output_type
30, // [30:35] is the sub-list for method input_type
30, // [30:30] is the sub-list for extension type_name
30, // [30:30] is the sub-list for extension extendee
0, // [0:30] is the sub-list for field type_name
}
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.
message AcquiredJob {
message WorkspaceBuild {
reserved 3;
string workspace_build_id = 1;
string workspace_name = 2;
repeated provisioner.ParameterValue parameter_values = 3;
repeated provisioner.RichParameterValue rich_parameter_values = 4;
repeated provisioner.VariableValue variable_values = 5;
repeated provisioner.GitAuthProvider git_auth_providers = 6;
@ -27,7 +28,8 @@ message AcquiredJob {
repeated provisioner.VariableValue user_variable_values = 2;
}
message TemplateDryRun {
repeated provisioner.ParameterValue parameter_values = 1;
reserved 1;
repeated provisioner.RichParameterValue rich_parameter_values = 2;
repeated provisioner.VariableValue variable_values = 3;
provisioner.Provision.Metadata metadata = 4;
@ -106,19 +108,19 @@ message Log {
// This message should be sent periodically as a heartbeat.
message UpdateJobRequest {
reserved 3;
string job_id = 1;
repeated Log logs = 2;
repeated provisioner.ParameterSchema parameter_schemas = 3;
repeated provisioner.TemplateVariable template_variables = 4;
repeated provisioner.VariableValue user_variable_values = 5;
bytes readme = 6;
}
message UpdateJobResponse {
reserved 2;
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;
}

View File

@ -371,18 +371,6 @@ func TestProvisionerd(t *testing.T) {
completeChan = make(chan struct{})
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{}
)
@ -402,8 +390,7 @@ func TestProvisionerd(t *testing.T) {
}),
Type: &proto.AcquiredJob_TemplateDryRun_{
TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{
ParameterValues: parameterValues,
Metadata: metadata,
Metadata: metadata,
},
},
}, nil

View File

@ -344,7 +344,6 @@ func (r *Runner) update(ctx context.Context, u *proto.UpdateJobRequest) (*proto.
span.SetAttributes(
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("user_variable_values_len", int64(len(u.UserVariableValues))),
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_:
r.logger.Debug(context.Background(), "acquired job is template dry-run",
slog.F("workspace_name", jobType.TemplateDryRun.Metadata.WorkspaceName),
slog.F("parameters", jobType.TemplateDryRun.ParameterValues),
slog.F("rich_parameter_values", jobType.TemplateDryRun.RichParameterValues),
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",
slog.F("workspace_name", jobType.WorkspaceBuild.WorkspaceName),
slog.F("state_length", len(jobType.WorkspaceBuild.State)),
slog.F("parameters", jobType.WorkspaceBuild.ParameterValues),
slog.F("rich_parameter_values", jobType.WorkspaceBuild.RichParameterValues),
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",
CreatedAt: time.Now().UnixMilli(),
})
parameterSchemas, templateVariables, err := r.runTemplateImportParse(ctx)
templateVariables, err := r.runTemplateImportParse(ctx)
if err != nil {
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.
updateResponse, err := r.update(ctx, &proto.UpdateJobRequest{
JobId: r.job.JobId,
ParameterSchemas: parameterSchemas,
TemplateVariables: templateVariables,
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)
}
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
r.queueLog(ctx, &proto.Log{
Source: proto.LogSource_PROVISIONER_DAEMON,
@ -652,7 +637,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
Stage: "Detecting persistent resources",
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,
WorkspaceTransition: sdkproto.WorkspaceTransition_START,
})
@ -667,7 +652,7 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p
Stage: "Detecting ephemeral resources",
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,
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.
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())
defer span.End()
@ -697,13 +682,13 @@ func (r *Runner) runTemplateImportParse(ctx context.Context) ([]*sdkproto.Parame
Directory: r.workDirectory,
})
if err != nil {
return nil, nil, xerrors.Errorf("parse source: %w", err)
return nil, xerrors.Errorf("parse source: %w", err)
}
defer stream.Close()
for {
msg, err := stream.Recv()
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) {
case *sdkproto.Parse_Response_Log:
@ -721,13 +706,12 @@ func (r *Runner) runTemplateImportParse(ctx context.Context) ([]*sdkproto.Parame
})
case *sdkproto.Parse_Response_Complete:
r.logger.Info(context.Background(), "parse complete",
slog.F("parameter_schemas", msgType.Complete.ParameterSchemas),
slog.F("template_variables", msgType.Complete.TemplateVariables),
)
return msgType.Complete.ParameterSchemas, msgType.Complete.TemplateVariables, nil
return msgType.Complete.TemplateVariables, nil
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())
}
}
@ -742,13 +726,13 @@ type templateImportProvision struct {
// 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.
// 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) {
return r.runTemplateImportProvisionWithRichParameters(ctx, values, variableValues, nil, metadata)
func (r *Runner) runTemplateImportProvision(ctx context.Context, variableValues []*sdkproto.VariableValue, metadata *sdkproto.Provision_Metadata) (*templateImportProvision, error) {
return r.runTemplateImportProvisionWithRichParameters(ctx, variableValues, nil, metadata)
}
// 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.
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())
defer span.End()
@ -785,7 +769,6 @@ func (r *Runner) runTemplateImportProvisionWithRichParameters(ctx context.Contex
Directory: r.workDirectory,
Metadata: metadata,
},
ParameterValues: values,
RichParameterValues: richParameterValues,
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.
provision, err := r.runTemplateImportProvisionWithRichParameters(ctx,
r.job.GetTemplateDryRun().GetParameterValues(),
r.job.GetTemplateDryRun().GetVariableValues(),
r.job.GetTemplateDryRun().GetRichParameterValues(),
metadata,
@ -1052,7 +1034,6 @@ func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *p
Type: &sdkproto.Provision_Request_Plan{
Plan: &sdkproto.Provision_Plan{
Config: config,
ParameterValues: r.job.GetWorkspaceBuild().ParameterValues,
RichParameterValues: r.job.GetWorkspaceBuild().RichParameterValues,
VariableValues: r.job.GetWorkspaceBuild().VariableValues,
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.
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.
message TemplateVariable {
string name = 1;
@ -99,7 +54,7 @@ message RichParameterValue {
message VariableValue {
string name = 1;
string value = 2;
bool sensitive = 3;
bool sensitive = 3;
}
// LogLevel represents severity of the log.
@ -210,8 +165,9 @@ message Parse {
string directory = 1;
}
message Complete {
reserved 2;
repeated TemplateVariable template_variables = 1;
repeated ParameterSchema parameter_schemas = 2;
}
message Response {
oneof type {
@ -255,8 +211,9 @@ message Provision {
}
message Plan {
reserved 2;
Config config = 1;
repeated ParameterValue parameter_values = 2;
repeated RichParameterValue rich_parameter_values = 3;
repeated VariableValue variable_values = 4;
repeated GitAuthProvider git_auth_providers = 5;
@ -279,9 +236,9 @@ message Provision {
bytes state = 1;
string error = 2;
repeated Resource resources = 3;
repeated RichParameter parameters = 4;
repeated string git_auth_providers = 5;
bytes plan = 6;
repeated RichParameter parameters = 4;
repeated string git_auth_providers = 5;
bytes plan = 6;
}
message Response {
oneof type {

View File

@ -239,15 +239,6 @@ export const getTemplateVersion = async (
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 (
versionId: string,
): Promise<TypesGen.WorkspaceResource[]> => {
@ -335,15 +326,6 @@ export const getTemplateVersionGitAuth = async (
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 (
versionId: string,
): Promise<TypesGen.TemplateVersionParameter[]> => {

View File

@ -139,12 +139,6 @@ export interface BuildInfoResponse {
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
export interface CreateFirstUserRequest {
readonly email: string
@ -171,15 +165,6 @@ export interface CreateOrganizationRequest {
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
export interface CreateTemplateRequest {
readonly name: string
@ -187,7 +172,6 @@ export interface CreateTemplateRequest {
readonly description?: string
readonly icon?: string
readonly template_version_id: string
readonly parameter_values?: CreateParameterRequest[]
readonly default_ttl_ms?: number
readonly max_ttl_ms?: number
readonly allow_user_cancel_workspace_jobs?: boolean
@ -200,7 +184,6 @@ export interface CreateTemplateRequest {
// From codersdk/templateversions.go
export interface CreateTemplateVersionDryRunRequest {
readonly workspace_name: string
readonly parameter_values: CreateParameterRequest[]
readonly rich_parameter_values: WorkspaceBuildParameter[]
readonly user_variable_values?: VariableValue[]
}
@ -214,7 +197,6 @@ export interface CreateTemplateVersionRequest {
readonly example_id?: string
readonly provisioner: ProvisionerType
readonly tags: Record<string, string>
readonly parameter_values?: CreateParameterRequest[]
readonly user_variable_values?: VariableValue[]
}
@ -251,7 +233,6 @@ export interface CreateWorkspaceBuildRequest {
readonly dry_run?: boolean
readonly state?: string
readonly orphan?: boolean
readonly parameter_values?: CreateParameterRequest[]
readonly rich_parameter_values?: WorkspaceBuildParameter[]
readonly log_level?: ProvisionerLogLevel
}
@ -269,7 +250,6 @@ export interface CreateWorkspaceRequest {
readonly name: string
readonly autostart_schedule?: string
readonly ttl_ms?: number
readonly parameter_values?: CreateParameterRequest[]
readonly rich_parameter_values?: WorkspaceBuildParameter[]
}
@ -585,40 +565,6 @@ export interface Pagination {
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
export interface PatchGroupRequest {
readonly add_users: string[]
@ -1450,33 +1396,6 @@ export const LogSources: LogSource[] = ["provisioner", "provisioner_daemon"]
export type 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
export type ProvisionerJobStatus =
| "canceled"
@ -1604,9 +1523,9 @@ export type TemplateRole = "" | "admin" | "use"
export const TemplateRoles: TemplateRole[] = ["", "admin", "use"]
// From codersdk/templateversions.go
export type TemplateVersionWarning = "DEPRECATED_PARAMETERS"
export type TemplateVersionWarning = "UNSUPPORTED_WORKSPACES"
export const TemplateVersionWarnings: TemplateVersionWarning[] = [
"DEPRECATED_PARAMETERS",
"UNSUPPORTED_WORKSPACES",
]
// 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} />
)
export const DeprecatedParameters = Template.bind({})
DeprecatedParameters.args = {
warnings: ["DEPRECATED_PARAMETERS"],
export const UnsupportedWorkspaces = Template.bind({})
UnsupportedWorkspaces.args = {
warnings: ["UNSUPPORTED_WORKSPACES"],
}

View File

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

View File

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

View File

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

View File

@ -2,13 +2,11 @@ import Checkbox from "@mui/material/Checkbox"
import { makeStyles } from "@mui/styles"
import TextField from "@mui/material/TextField"
import {
ParameterSchema,
ProvisionerJobLog,
Template,
TemplateExample,
TemplateVersionVariable,
} from "api/typesGenerated"
import { ParameterInput } from "components/ParameterInput/ParameterInput"
import { Stack } from "components/Stack/Stack"
import {
TemplateUpload,
@ -112,7 +110,6 @@ const defaultInitialValues: CreateTemplateData = {
type GetInitialValuesParams = {
fromExample?: TemplateExample
fromCopy?: Template
parameters?: ParameterSchema[]
variables?: TemplateVersionVariable[]
allowAdvancedScheduling: boolean
}
@ -122,7 +119,6 @@ const getInitialValues = ({
fromCopy,
allowAdvancedScheduling,
variables,
parameters,
}: GetInitialValuesParams) => {
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
}
@ -185,7 +171,6 @@ export interface CreateTemplateFormProps {
isSubmitting: boolean
upload: TemplateUploadProps
starterTemplate?: TemplateExample
parameters?: ParameterSchema[]
variables?: TemplateVersionVariable[]
error?: unknown
jobError?: string
@ -199,7 +184,6 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = ({
onSubmit,
starterTemplate,
copiedTemplate,
parameters,
variables,
isSubmitting,
upload,
@ -215,7 +199,6 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = ({
fromExample: starterTemplate,
fromCopy: copiedTemplate,
variables,
parameters,
}),
validationSchema,
onSubmit,
@ -439,30 +422,6 @@ export const CreateTemplateForm: FC<CreateTemplateFormProps> = ({
</FormFields>
</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.length > 0 && (
<FormSection

View File

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

View File

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

View File

@ -3,7 +3,6 @@ import userEvent from "@testing-library/user-event"
import * as API from "api/api"
import i18next from "i18next"
import {
mockParameterSchema,
MockTemplate,
MockUser,
MockWorkspace,
@ -79,7 +78,6 @@ describe("CreateWorkspacePage", () => {
})
it("succeeds with default owner", async () => {
jest.spyOn(API, "getTemplateVersionSchema").mockResolvedValueOnce([])
jest
.spyOn(API, "getUsers")
.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 () => {
const param = "first_parameter"
const paramValue = "It works!"
jest.spyOn(API, "getTemplateVersionSchema").mockResolvedValueOnce([
mockParameterSchema({
name: param,
default_source_value: "",
}),
])
jest
.spyOn(API, "getTemplateVersionRichParameters")
.mockResolvedValueOnce([MockTemplateVersionParameter1])

View File

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

View File

@ -1,8 +1,6 @@
import { ComponentMeta, Story } from "@storybook/react"
import {
mockApiError,
mockParameterSchema,
MockParameterSchemas,
MockTemplate,
MockTemplateVersionParameter1,
MockTemplateVersionParameter2,
@ -27,7 +25,6 @@ export const NoParameters = Template.bind({})
NoParameters.args = {
templates: [MockTemplate],
selectedTemplate: MockTemplate,
templateSchema: [],
createWorkspaceErrors: {},
}
@ -35,7 +32,6 @@ export const Parameters = Template.bind({})
Parameters.args = {
templates: [MockTemplate],
selectedTemplate: MockTemplate,
templateSchema: MockParameterSchemas,
createWorkspaceErrors: {},
}
@ -43,41 +39,6 @@ export const RedisplayParameters = Template.bind({})
RedisplayParameters.args = {
templates: [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: {},
}
@ -93,18 +54,6 @@ GetTemplatesError.args = {
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({})
CreateWorkspaceError.args = {
...Parameters.args,

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