From 3e9ecc33c579a74502c49bfae2cd197036e4d6c2 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Wed, 25 May 2022 08:38:58 +0000 Subject: [PATCH 01/10] feat: add new provisioner job type template_version_plan --- cli/create.go | 26 + coderd/coderd.go | 1 + coderd/database/dump.sql | 3 +- .../000014_provisioner_job_type_plan.down.sql | 9 + .../000014_provisioner_job_type_plan.up.sql | 2 + coderd/database/models.go | 1 + coderd/database/queries.sql.go | 2 +- coderd/parameter/compute.go | 19 +- coderd/provisionerdaemons.go | 73 ++- coderd/templateversions.go | 75 +++ codersdk/templateversions.go | 22 + provisionerd/proto/provisionerd.pb.go | 606 +++++++++++++----- provisionerd/proto/provisionerd.proto | 17 +- provisionerd/provisionerd.go | 61 ++ provisionerd/provisionerd_test.go | 98 +++ 15 files changed, 823 insertions(+), 192 deletions(-) create mode 100644 coderd/database/migrations/000014_provisioner_job_type_plan.down.sql create mode 100644 coderd/database/migrations/000014_provisioner_job_type_plan.up.sql diff --git a/cli/create.go b/cli/create.go index 7bd7a7532a282..8b22cdaa45ca6 100644 --- a/cli/create.go +++ b/cli/create.go @@ -184,6 +184,32 @@ func create() *cobra.Command { return err } + // Run a plan with the given parameters to check correctness + planJob, err := client.TemplateVersionPlan(cmd.Context(), templateVersion.ID, codersdk.TemplateVersionPlanRequest{ + ParameterValues: parameters, + }) + if err != nil { + return xerrors.Errorf("plan workspace: %w", err) + } + err = cliui.ProvisionerJob(cmd.Context(), cmd.OutOrStdout(), cliui.ProvisionerJobOptions{ + Fetch: func() (codersdk.ProvisionerJob, error) { + return planJob, nil + }, + Cancel: func() error { + // TODO: workspace plan cancellation endpoint + return nil + }, + Logs: func() (<-chan codersdk.ProvisionerJobLog, error) { + // TODO: workspace plan log endpoint + return make(chan codersdk.ProvisionerJobLog), nil + }, + }) + if err != nil { + // TODO: reprompt for parameter values if we deem it to be a + // validation error + return xerrors.Errorf("error occurred during workspace plan: %w", err) + } + _, err = cliui.Prompt(cmd, cliui.PromptOptions{ Text: "Confirm create?", IsConfirm: true, diff --git a/coderd/coderd.go b/coderd/coderd.go index 343da27bf55cf..1c0fbeadb5ae5 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -208,6 +208,7 @@ func newRouter(options *Options, a *api) chi.Router { r.Get("/parameters", a.templateVersionParameters) r.Get("/resources", a.templateVersionResources) r.Get("/logs", a.templateVersionLogs) + r.Post("/plan", a.templateVersionPlan) }) r.Route("/users", func(r chi.Router) { r.Get("/first", a.firstUser) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 4cd90454283d7..d4d2d71001ee5 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -50,7 +50,8 @@ CREATE TYPE parameter_type_system AS ENUM ( CREATE TYPE provisioner_job_type AS ENUM ( 'template_version_import', - 'workspace_build' + 'workspace_build', + 'template_version_plan' ); CREATE TYPE provisioner_storage_method AS ENUM ( diff --git a/coderd/database/migrations/000014_provisioner_job_type_plan.down.sql b/coderd/database/migrations/000014_provisioner_job_type_plan.down.sql new file mode 100644 index 0000000000000..d27e93f6160e6 --- /dev/null +++ b/coderd/database/migrations/000014_provisioner_job_type_plan.down.sql @@ -0,0 +1,9 @@ +-- It's not possible to drop enum values from enum types, so the UP has "IF NOT +-- EXISTS". + +-- Delete all jobs that use the new enum value. +DELETE FROM + provisioner_jobs +WHERE + provisioner_job_type = 'template_version_plan' +; diff --git a/coderd/database/migrations/000014_provisioner_job_type_plan.up.sql b/coderd/database/migrations/000014_provisioner_job_type_plan.up.sql new file mode 100644 index 0000000000000..3c19977c59354 --- /dev/null +++ b/coderd/database/migrations/000014_provisioner_job_type_plan.up.sql @@ -0,0 +1,2 @@ +ALTER TYPE provisioner_job_type +ADD VALUE IF NOT EXISTS 'template_version_plan'; diff --git a/coderd/database/models.go b/coderd/database/models.go index 3fcf947bf4cae..5eb95dea15b54 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -179,6 +179,7 @@ type ProvisionerJobType string const ( ProvisionerJobTypeTemplateVersionImport ProvisionerJobType = "template_version_import" ProvisionerJobTypeWorkspaceBuild ProvisionerJobType = "workspace_build" + ProvisionerJobTypeTemplateVersionPlan ProvisionerJobType = "template_version_plan" ) func (e *ProvisionerJobType) Scan(src interface{}) error { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 57eeb67ac5814..38f0cac06091e 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -2211,7 +2211,7 @@ WHERE WHEN $2 :: text != '' THEN ( email LIKE concat('%', $2, '%') OR username LIKE concat('%', $2, '%') - ) + ) ELSE true END -- Filter by status diff --git a/coderd/parameter/compute.go b/coderd/parameter/compute.go index 4551d3fd56772..407bd21717a36 100644 --- a/coderd/parameter/compute.go +++ b/coderd/parameter/compute.go @@ -13,11 +13,12 @@ import ( // ComputeScope targets identifiers to pull parameters from. type ComputeScope struct { - TemplateImportJobID uuid.UUID - OrganizationID uuid.UUID - UserID uuid.UUID - TemplateID uuid.NullUUID - WorkspaceID uuid.NullUUID + TemplateImportJobID uuid.UUID + OrganizationID uuid.UUID + UserID uuid.UUID + TemplateID uuid.NullUUID + WorkspaceID uuid.NullUUID + AdditionalParameterValues []database.ParameterValue } type ComputeOptions struct { @@ -142,6 +143,14 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options } } + // 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) diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index bb3fa21361bdd..bdafaba4605d7 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -107,6 +107,12 @@ type workspaceProvisionJob struct { DryRun bool `json:"dry_run"` } +// The input for a "template_version_plan" job. +type templateVersionPlanJob struct { + TemplateVersionID uuid.UUID `json:"template_version_id"` + ParameterValues []database.ParameterValue `json:"parameter_values"` +} + // Implementation of the provisioner daemon protobuf server. type provisionerdServer struct { AccessURL *url.URL @@ -216,18 +222,15 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty if err != nil { return nil, failJob(fmt.Sprintf("compute parameters: %s", 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, failJob(fmt.Sprintf("convert parameter: %s", err)) - } - protoParameters = append(protoParameters, converted) + + // 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.Sprint("convert workspace transition: %w", err)) + return nil, failJob(fmt.Sprintf("convert workspace transition: %s", err)) } protoJob.Type = &proto.AcquiredJob_WorkspaceBuild_{ @@ -246,6 +249,45 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty }, }, } + case database.ProvisionerJobTypeTemplateVersionPlan: + var input templateVersionPlanJob + err = json.Unmarshal(job.Input, &input) + if err != nil { + return nil, failJob(fmt.Sprintf("unmarshal job input %q: %s", job.Input, err)) + } + + templateVersion, err := server.Database.GetTemplateVersionByID(ctx, input.TemplateVersionID) + if err != nil { + return nil, failJob(fmt.Sprintf("get template version: %s", err)) + } + + // Compute parameters for the plan to consume. + parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{ + TemplateImportJobID: templateVersion.JobID, + OrganizationID: job.OrganizationID, + TemplateID: templateVersion.TemplateID, + UserID: user.ID, + 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_TemplatePlan_{ + TemplatePlan: &proto.AcquiredJob_TemplatePlan{ + ParameterValues: protoParameters, + Metadata: &sdkproto.Provision_Metadata{ + CoderUrl: server.AccessURL.String(), + }, + }, + } case database.ProvisionerJobTypeTemplateVersionImport: protoJob.Type = &proto.AcquiredJob_TemplateImport_{ TemplateImport: &proto.AcquiredJob_TemplateImport{ @@ -716,6 +758,19 @@ func convertLogSource(logSource proto.LogSource) (database.LogSource, error) { } } +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 { diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 560281908d728..1ff971b5b48ea 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -2,6 +2,7 @@ package coderd import ( "database/sql" + "encoding/json" "errors" "fmt" "net/http" @@ -146,6 +147,80 @@ func (api *api) templateVersionParameters(rw http.ResponseWriter, r *http.Reques httpapi.Write(rw, http.StatusOK, values) } +func (api *api) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { + apiKey := httpmw.APIKey(r) + organization := httpmw.OrganizationParam(r) + templateVersion := httpmw.TemplateVersionParam(r) + + var req codersdk.TemplateVersionPlanRequest + if !httpapi.Read(rw, r, &req) { + return + } + + job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("get provisioner job: %s", err), + }) + return + } + if !job.CompletedAt.Valid { + httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{ + Message: "Template version import job hasn't completed!", + }) + 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, + } + } + + // Marshal template version plan job with the parameters from the request. + input, err := json.Marshal(templateVersionPlanJob{ + TemplateVersionID: templateVersion.ID, + ParameterValues: parameterValues, + }) + if err != nil { + httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{ + Message: fmt.Sprintf("marshal new provisioner job: %s", err), + }) + return + } + + // Create a plan job + jobID := uuid.New() + provisionerJob, err := api.Database.InsertProvisionerJob(r.Context(), database.InsertProvisionerJobParams{ + ID: jobID, + CreatedAt: database.Now(), + UpdatedAt: database.Now(), + OrganizationID: organization.ID, + InitiatorID: apiKey.UserID, + Provisioner: job.Provisioner, + StorageMethod: job.StorageMethod, + StorageSource: job.StorageSource, + Type: database.ProvisionerJobTypeTemplateVersionPlan, + Input: input, + }) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("insert provisioner job: %s", err), + }) + return + } + + httpapi.Write(rw, http.StatusCreated, convertProvisionerJob(provisionerJob)) +} + func (api *api) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Request) { template := httpmw.TemplateParam(r) diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index 0c72b6d26385e..ceb70debc7ddf 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -114,3 +114,25 @@ func (c *Client) TemplateVersionLogsBefore(ctx context.Context, version uuid.UUI func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID, after time.Time) (<-chan ProvisionerJobLog, error) { return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/templateversions/%s/logs", version), after) } + +// TemplateVersionPlanRequest defines the request parameters for +// TemplateVersionPlan. +type TemplateVersionPlanRequest struct { + ParameterValues []CreateParameterRequest +} + +// TemplateVersionPlan begins a dry-run provisioner job against the given +// template version with the given parameter values. +func (c *Client) TemplateVersionPlan(ctx context.Context, version uuid.UUID, req TemplateVersionPlanRequest) (ProvisionerJob, error) { + res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/templateversions/%s/plan", version), req) + if err != nil { + return ProvisionerJob{}, err + } + defer res.Body.Close() + if res.StatusCode != http.StatusCreated { + return ProvisionerJob{}, readBodyAsError(res) + } + + var job ProvisionerJob + return job, json.NewDecoder(res.Body).Decode(&job) +} diff --git a/provisionerd/proto/provisionerd.pb.go b/provisionerd/proto/provisionerd.pb.go index 639e0d4bd1135..cae934f9246bc 100644 --- a/provisionerd/proto/provisionerd.pb.go +++ b/provisionerd/proto/provisionerd.pb.go @@ -121,6 +121,7 @@ type AcquiredJob struct { // Types that are assignable to Type: // *AcquiredJob_WorkspaceBuild_ // *AcquiredJob_TemplateImport_ + // *AcquiredJob_TemplatePlan_ Type isAcquiredJob_Type `protobuf_oneof:"type"` } @@ -212,6 +213,13 @@ func (x *AcquiredJob) GetTemplateImport() *AcquiredJob_TemplateImport { return nil } +func (x *AcquiredJob) GetTemplatePlan() *AcquiredJob_TemplatePlan { + if x, ok := x.GetType().(*AcquiredJob_TemplatePlan_); ok { + return x.TemplatePlan + } + return nil +} + type isAcquiredJob_Type interface { isAcquiredJob_Type() } @@ -224,10 +232,16 @@ type AcquiredJob_TemplateImport_ struct { TemplateImport *AcquiredJob_TemplateImport `protobuf:"bytes,7,opt,name=template_import,json=templateImport,proto3,oneof"` } +type AcquiredJob_TemplatePlan_ struct { + TemplatePlan *AcquiredJob_TemplatePlan `protobuf:"bytes,8,opt,name=template_plan,json=templatePlan,proto3,oneof"` +} + func (*AcquiredJob_WorkspaceBuild_) isAcquiredJob_Type() {} func (*AcquiredJob_TemplateImport_) isAcquiredJob_Type() {} +func (*AcquiredJob_TemplatePlan_) isAcquiredJob_Type() {} + type FailedJob struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -238,6 +252,7 @@ type FailedJob struct { // Types that are assignable to Type: // *FailedJob_WorkspaceBuild_ // *FailedJob_TemplateImport_ + // *FailedJob_TemplatePlan_ Type isFailedJob_Type `protobuf_oneof:"type"` } @@ -308,6 +323,13 @@ func (x *FailedJob) GetTemplateImport() *FailedJob_TemplateImport { return nil } +func (x *FailedJob) GetTemplatePlan() *FailedJob_TemplatePlan { + if x, ok := x.GetType().(*FailedJob_TemplatePlan_); ok { + return x.TemplatePlan + } + return nil +} + type isFailedJob_Type interface { isFailedJob_Type() } @@ -320,10 +342,16 @@ type FailedJob_TemplateImport_ struct { TemplateImport *FailedJob_TemplateImport `protobuf:"bytes,4,opt,name=template_import,json=templateImport,proto3,oneof"` } +type FailedJob_TemplatePlan_ struct { + TemplatePlan *FailedJob_TemplatePlan `protobuf:"bytes,5,opt,name=template_plan,json=templatePlan,proto3,oneof"` +} + func (*FailedJob_WorkspaceBuild_) isFailedJob_Type() {} func (*FailedJob_TemplateImport_) isFailedJob_Type() {} +func (*FailedJob_TemplatePlan_) isFailedJob_Type() {} + // CompletedJob is sent when the provisioner daemon completes a job. type CompletedJob struct { state protoimpl.MessageState @@ -334,6 +362,7 @@ type CompletedJob struct { // Types that are assignable to Type: // *CompletedJob_WorkspaceBuild_ // *CompletedJob_TemplateImport_ + // *CompletedJob_TemplatePlan_ Type isCompletedJob_Type `protobuf_oneof:"type"` } @@ -397,6 +426,13 @@ func (x *CompletedJob) GetTemplateImport() *CompletedJob_TemplateImport { return nil } +func (x *CompletedJob) GetTemplatePlan() *CompletedJob_TemplatePlan { + if x, ok := x.GetType().(*CompletedJob_TemplatePlan_); ok { + return x.TemplatePlan + } + return nil +} + type isCompletedJob_Type interface { isCompletedJob_Type() } @@ -409,10 +445,16 @@ type CompletedJob_TemplateImport_ struct { TemplateImport *CompletedJob_TemplateImport `protobuf:"bytes,3,opt,name=template_import,json=templateImport,proto3,oneof"` } +type CompletedJob_TemplatePlan_ struct { + TemplatePlan *CompletedJob_TemplatePlan `protobuf:"bytes,4,opt,name=template_plan,json=templatePlan,proto3,oneof"` +} + func (*CompletedJob_WorkspaceBuild_) isCompletedJob_Type() {} func (*CompletedJob_TemplateImport_) isCompletedJob_Type() {} +func (*CompletedJob_TemplatePlan_) isCompletedJob_Type() {} + // Log represents output from a job. type Log struct { state protoimpl.MessageState @@ -748,6 +790,61 @@ func (x *AcquiredJob_TemplateImport) GetMetadata() *proto.Provision_Metadata { return nil } +type AcquiredJob_TemplatePlan struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ParameterValues []*proto.ParameterValue `protobuf:"bytes,1,rep,name=parameter_values,json=parameterValues,proto3" json:"parameter_values,omitempty"` + Metadata *proto.Provision_Metadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (x *AcquiredJob_TemplatePlan) Reset() { + *x = AcquiredJob_TemplatePlan{} + if protoimpl.UnsafeEnabled { + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AcquiredJob_TemplatePlan) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AcquiredJob_TemplatePlan) ProtoMessage() {} + +func (x *AcquiredJob_TemplatePlan) ProtoReflect() protoreflect.Message { + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AcquiredJob_TemplatePlan.ProtoReflect.Descriptor instead. +func (*AcquiredJob_TemplatePlan) Descriptor() ([]byte, []int) { + return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{1, 2} +} + +func (x *AcquiredJob_TemplatePlan) GetParameterValues() []*proto.ParameterValue { + if x != nil { + return x.ParameterValues + } + return nil +} + +func (x *AcquiredJob_TemplatePlan) GetMetadata() *proto.Provision_Metadata { + if x != nil { + return x.Metadata + } + return nil +} + type FailedJob_WorkspaceBuild struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -759,7 +856,7 @@ type FailedJob_WorkspaceBuild struct { func (x *FailedJob_WorkspaceBuild) Reset() { *x = FailedJob_WorkspaceBuild{} if protoimpl.UnsafeEnabled { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[9] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -772,7 +869,7 @@ func (x *FailedJob_WorkspaceBuild) String() string { func (*FailedJob_WorkspaceBuild) ProtoMessage() {} func (x *FailedJob_WorkspaceBuild) ProtoReflect() protoreflect.Message { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[9] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -804,7 +901,7 @@ type FailedJob_TemplateImport struct { func (x *FailedJob_TemplateImport) Reset() { *x = FailedJob_TemplateImport{} if protoimpl.UnsafeEnabled { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[10] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -817,7 +914,7 @@ func (x *FailedJob_TemplateImport) String() string { func (*FailedJob_TemplateImport) ProtoMessage() {} func (x *FailedJob_TemplateImport) ProtoReflect() protoreflect.Message { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[10] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -833,6 +930,44 @@ func (*FailedJob_TemplateImport) Descriptor() ([]byte, []int) { return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{2, 1} } +type FailedJob_TemplatePlan struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FailedJob_TemplatePlan) Reset() { + *x = FailedJob_TemplatePlan{} + if protoimpl.UnsafeEnabled { + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FailedJob_TemplatePlan) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FailedJob_TemplatePlan) ProtoMessage() {} + +func (x *FailedJob_TemplatePlan) ProtoReflect() protoreflect.Message { + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FailedJob_TemplatePlan.ProtoReflect.Descriptor instead. +func (*FailedJob_TemplatePlan) Descriptor() ([]byte, []int) { + return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{2, 2} +} + type CompletedJob_WorkspaceBuild struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -845,7 +980,7 @@ type CompletedJob_WorkspaceBuild struct { func (x *CompletedJob_WorkspaceBuild) Reset() { *x = CompletedJob_WorkspaceBuild{} if protoimpl.UnsafeEnabled { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[11] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -858,7 +993,7 @@ func (x *CompletedJob_WorkspaceBuild) String() string { func (*CompletedJob_WorkspaceBuild) ProtoMessage() {} func (x *CompletedJob_WorkspaceBuild) ProtoReflect() protoreflect.Message { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[11] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -900,7 +1035,7 @@ type CompletedJob_TemplateImport struct { func (x *CompletedJob_TemplateImport) Reset() { *x = CompletedJob_TemplateImport{} if protoimpl.UnsafeEnabled { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -913,7 +1048,7 @@ func (x *CompletedJob_TemplateImport) String() string { func (*CompletedJob_TemplateImport) ProtoMessage() {} func (x *CompletedJob_TemplateImport) ProtoReflect() protoreflect.Message { - mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12] + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -943,6 +1078,53 @@ func (x *CompletedJob_TemplateImport) GetStopResources() []*proto.Resource { return nil } +type CompletedJob_TemplatePlan struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Resources []*proto.Resource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"` +} + +func (x *CompletedJob_TemplatePlan) Reset() { + *x = CompletedJob_TemplatePlan{} + if protoimpl.UnsafeEnabled { + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CompletedJob_TemplatePlan) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CompletedJob_TemplatePlan) ProtoMessage() {} + +func (x *CompletedJob_TemplatePlan) ProtoReflect() protoreflect.Message { + mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CompletedJob_TemplatePlan.ProtoReflect.Descriptor instead. +func (*CompletedJob_TemplatePlan) Descriptor() ([]byte, []int) { + return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{3, 2} +} + +func (x *CompletedJob_TemplatePlan) GetResources() []*proto.Resource { + if x != nil { + return x.Resources + } + return nil +} + var File_provisionerd_proto_provisionerd_proto protoreflect.FileDescriptor var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{ @@ -952,7 +1134,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, 0xbe, 0x05, 0x0a, 0x0b, 0x41, 0x63, 0x71, 0x75, 0x69, + 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xa3, 0x07, 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, @@ -974,130 +1156,160 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{ 0x0b, 0x32, 0x28, 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, 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, 0x1a, 0x80, 0x02, - 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, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x4d, 0x0a, + 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 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, 0x2e, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x48, 0x00, 0x52, 0x0c, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x1a, 0x80, 0x02, 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, 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, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, + 0x4d, 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, 0x1a, 0x93, + 0x01, 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 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, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x02, 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, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xfd, 0x02, 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, 0x4b, 0x0a, + 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 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, 0x50, 0x6c, 0x61, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x6e, 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, 0x0e, 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x50, 0x6c, 0x61, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x04, 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, 0x4e, 0x0a, 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6c, 0x61, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 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, 0x50, 0x6c, 0x61, 0x6e, + 0x48, 0x00, 0x52, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 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, 0x8e, 0x01, + 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, 0x1a, 0x43, + 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 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, 0xb3, + 0x01, 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, 0x16, 0x0a, 0x06, + 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, + 0x61, 0x64, 0x6d, 0x65, 0x22, 0x77, 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, 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, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x1a, 0x4d, 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, 0x42, - 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xa0, 0x02, 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, 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, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xc7, 0x03, 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, 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, 0x8e, 0x01, 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, 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, 0xb3, 0x01, 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, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x22, 0x77, 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, 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, 0x98, 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, 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, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 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, 0x98, 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, 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 ( @@ -1113,7 +1325,7 @@ func file_provisionerd_proto_provisionerd_proto_rawDescGZIP() []byte { } var file_provisionerd_proto_provisionerd_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_provisionerd_proto_provisionerd_proto_msgTypes = make([]protoimpl.MessageInfo, 13) +var file_provisionerd_proto_provisionerd_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{ (LogSource)(0), // 0: provisionerd.LogSource (*Empty)(nil), // 1: provisionerd.Empty @@ -1125,47 +1337,56 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{ (*UpdateJobResponse)(nil), // 7: provisionerd.UpdateJobResponse (*AcquiredJob_WorkspaceBuild)(nil), // 8: provisionerd.AcquiredJob.WorkspaceBuild (*AcquiredJob_TemplateImport)(nil), // 9: provisionerd.AcquiredJob.TemplateImport - (*FailedJob_WorkspaceBuild)(nil), // 10: provisionerd.FailedJob.WorkspaceBuild - (*FailedJob_TemplateImport)(nil), // 11: provisionerd.FailedJob.TemplateImport - (*CompletedJob_WorkspaceBuild)(nil), // 12: provisionerd.CompletedJob.WorkspaceBuild - (*CompletedJob_TemplateImport)(nil), // 13: provisionerd.CompletedJob.TemplateImport - (proto.LogLevel)(0), // 14: provisioner.LogLevel - (*proto.ParameterSchema)(nil), // 15: provisioner.ParameterSchema - (*proto.ParameterValue)(nil), // 16: provisioner.ParameterValue - (*proto.Provision_Metadata)(nil), // 17: provisioner.Provision.Metadata - (*proto.Resource)(nil), // 18: provisioner.Resource + (*AcquiredJob_TemplatePlan)(nil), // 10: provisionerd.AcquiredJob.TemplatePlan + (*FailedJob_WorkspaceBuild)(nil), // 11: provisionerd.FailedJob.WorkspaceBuild + (*FailedJob_TemplateImport)(nil), // 12: provisionerd.FailedJob.TemplateImport + (*FailedJob_TemplatePlan)(nil), // 13: provisionerd.FailedJob.TemplatePlan + (*CompletedJob_WorkspaceBuild)(nil), // 14: provisionerd.CompletedJob.WorkspaceBuild + (*CompletedJob_TemplateImport)(nil), // 15: provisionerd.CompletedJob.TemplateImport + (*CompletedJob_TemplatePlan)(nil), // 16: provisionerd.CompletedJob.TemplatePlan + (proto.LogLevel)(0), // 17: provisioner.LogLevel + (*proto.ParameterSchema)(nil), // 18: provisioner.ParameterSchema + (*proto.ParameterValue)(nil), // 19: provisioner.ParameterValue + (*proto.Provision_Metadata)(nil), // 20: provisioner.Provision.Metadata + (*proto.Resource)(nil), // 21: provisioner.Resource } var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{ 8, // 0: provisionerd.AcquiredJob.workspace_build:type_name -> provisionerd.AcquiredJob.WorkspaceBuild 9, // 1: provisionerd.AcquiredJob.template_import:type_name -> provisionerd.AcquiredJob.TemplateImport - 10, // 2: provisionerd.FailedJob.workspace_build:type_name -> provisionerd.FailedJob.WorkspaceBuild - 11, // 3: provisionerd.FailedJob.template_import:type_name -> provisionerd.FailedJob.TemplateImport - 12, // 4: provisionerd.CompletedJob.workspace_build:type_name -> provisionerd.CompletedJob.WorkspaceBuild - 13, // 5: provisionerd.CompletedJob.template_import:type_name -> provisionerd.CompletedJob.TemplateImport - 0, // 6: provisionerd.Log.source:type_name -> provisionerd.LogSource - 14, // 7: provisionerd.Log.level:type_name -> provisioner.LogLevel - 5, // 8: provisionerd.UpdateJobRequest.logs:type_name -> provisionerd.Log - 15, // 9: provisionerd.UpdateJobRequest.parameter_schemas:type_name -> provisioner.ParameterSchema - 16, // 10: provisionerd.UpdateJobResponse.parameter_values:type_name -> provisioner.ParameterValue - 16, // 11: provisionerd.AcquiredJob.WorkspaceBuild.parameter_values:type_name -> provisioner.ParameterValue - 17, // 12: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata - 17, // 13: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata - 18, // 14: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource - 18, // 15: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource - 18, // 16: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource - 1, // 17: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty - 6, // 18: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest - 3, // 19: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob - 4, // 20: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob - 2, // 21: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob - 7, // 22: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse - 1, // 23: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty - 1, // 24: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty - 21, // [21:25] is the sub-list for method output_type - 17, // [17:21] is the sub-list for method input_type - 17, // [17:17] is the sub-list for extension type_name - 17, // [17:17] is the sub-list for extension extendee - 0, // [0:17] is the sub-list for field type_name + 10, // 2: provisionerd.AcquiredJob.template_plan:type_name -> provisionerd.AcquiredJob.TemplatePlan + 11, // 3: provisionerd.FailedJob.workspace_build:type_name -> provisionerd.FailedJob.WorkspaceBuild + 12, // 4: provisionerd.FailedJob.template_import:type_name -> provisionerd.FailedJob.TemplateImport + 13, // 5: provisionerd.FailedJob.template_plan:type_name -> provisionerd.FailedJob.TemplatePlan + 14, // 6: provisionerd.CompletedJob.workspace_build:type_name -> provisionerd.CompletedJob.WorkspaceBuild + 15, // 7: provisionerd.CompletedJob.template_import:type_name -> provisionerd.CompletedJob.TemplateImport + 16, // 8: provisionerd.CompletedJob.template_plan:type_name -> provisionerd.CompletedJob.TemplatePlan + 0, // 9: provisionerd.Log.source:type_name -> provisionerd.LogSource + 17, // 10: provisionerd.Log.level:type_name -> provisioner.LogLevel + 5, // 11: provisionerd.UpdateJobRequest.logs:type_name -> provisionerd.Log + 18, // 12: provisionerd.UpdateJobRequest.parameter_schemas:type_name -> provisioner.ParameterSchema + 19, // 13: provisionerd.UpdateJobResponse.parameter_values:type_name -> provisioner.ParameterValue + 19, // 14: provisionerd.AcquiredJob.WorkspaceBuild.parameter_values:type_name -> provisioner.ParameterValue + 20, // 15: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata + 20, // 16: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata + 19, // 17: provisionerd.AcquiredJob.TemplatePlan.parameter_values:type_name -> provisioner.ParameterValue + 20, // 18: provisionerd.AcquiredJob.TemplatePlan.metadata:type_name -> provisioner.Provision.Metadata + 21, // 19: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource + 21, // 20: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource + 21, // 21: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource + 21, // 22: provisionerd.CompletedJob.TemplatePlan.resources:type_name -> provisioner.Resource + 1, // 23: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty + 6, // 24: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest + 3, // 25: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob + 4, // 26: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob + 2, // 27: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob + 7, // 28: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse + 1, // 29: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty + 1, // 30: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty + 27, // [27:31] is the sub-list for method output_type + 23, // [23:27] is the sub-list for method input_type + 23, // [23:23] is the sub-list for extension type_name + 23, // [23:23] is the sub-list for extension extendee + 0, // [0:23] is the sub-list for field type_name } func init() { file_provisionerd_proto_provisionerd_proto_init() } @@ -1283,7 +1504,7 @@ func file_provisionerd_proto_provisionerd_proto_init() { } } file_provisionerd_proto_provisionerd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailedJob_WorkspaceBuild); i { + switch v := v.(*AcquiredJob_TemplatePlan); i { case 0: return &v.state case 1: @@ -1295,7 +1516,7 @@ func file_provisionerd_proto_provisionerd_proto_init() { } } file_provisionerd_proto_provisionerd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailedJob_TemplateImport); i { + switch v := v.(*FailedJob_WorkspaceBuild); i { case 0: return &v.state case 1: @@ -1307,7 +1528,7 @@ func file_provisionerd_proto_provisionerd_proto_init() { } } file_provisionerd_proto_provisionerd_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CompletedJob_WorkspaceBuild); i { + switch v := v.(*FailedJob_TemplateImport); i { case 0: return &v.state case 1: @@ -1319,6 +1540,30 @@ func file_provisionerd_proto_provisionerd_proto_init() { } } file_provisionerd_proto_provisionerd_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FailedJob_TemplatePlan); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_provisionerd_proto_provisionerd_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CompletedJob_WorkspaceBuild); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_provisionerd_proto_provisionerd_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CompletedJob_TemplateImport); i { case 0: return &v.state @@ -1330,18 +1575,33 @@ func file_provisionerd_proto_provisionerd_proto_init() { return nil } } + file_provisionerd_proto_provisionerd_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CompletedJob_TemplatePlan); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_provisionerd_proto_provisionerd_proto_msgTypes[1].OneofWrappers = []interface{}{ (*AcquiredJob_WorkspaceBuild_)(nil), (*AcquiredJob_TemplateImport_)(nil), + (*AcquiredJob_TemplatePlan_)(nil), } file_provisionerd_proto_provisionerd_proto_msgTypes[2].OneofWrappers = []interface{}{ (*FailedJob_WorkspaceBuild_)(nil), (*FailedJob_TemplateImport_)(nil), + (*FailedJob_TemplatePlan_)(nil), } file_provisionerd_proto_provisionerd_proto_msgTypes[3].OneofWrappers = []interface{}{ (*CompletedJob_WorkspaceBuild_)(nil), (*CompletedJob_TemplateImport_)(nil), + (*CompletedJob_TemplatePlan_)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1349,7 +1609,7 @@ func file_provisionerd_proto_provisionerd_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_provisionerd_proto_provisionerd_proto_rawDesc, NumEnums: 1, - NumMessages: 13, + NumMessages: 16, NumExtensions: 0, NumServices: 1, }, diff --git a/provisionerd/proto/provisionerd.proto b/provisionerd/proto/provisionerd.proto index b1808c5443e55..50d4c53cae0ad 100644 --- a/provisionerd/proto/provisionerd.proto +++ b/provisionerd/proto/provisionerd.proto @@ -21,6 +21,11 @@ message AcquiredJob { message TemplateImport { provisioner.Provision.Metadata metadata = 1; } + message TemplatePlan { + repeated provisioner.ParameterValue parameter_values = 1; + provisioner.Provision.Metadata metadata = 2; + } + string job_id = 1; int64 created_at = 2; string provisioner = 3; @@ -29,6 +34,7 @@ message AcquiredJob { oneof type { WorkspaceBuild workspace_build = 6; TemplateImport template_import = 7; + TemplatePlan template_plan = 8; } } @@ -36,13 +42,14 @@ message FailedJob { message WorkspaceBuild { bytes state = 1; } - message TemplateImport{ - } + message TemplateImport {} + message TemplatePlan {} string job_id = 1; string error = 2; oneof type { WorkspaceBuild workspace_build = 3; TemplateImport template_import = 4; + TemplatePlan template_plan = 5; } } @@ -56,10 +63,14 @@ message CompletedJob { repeated provisioner.Resource start_resources = 1; repeated provisioner.Resource stop_resources = 2; } + message TemplatePlan { + repeated provisioner.Resource resources = 1; + } string job_id = 1; oneof type { WorkspaceBuild workspace_build = 2; TemplateImport template_import = 3; + TemplatePlan template_plan = 4; } } @@ -98,7 +109,7 @@ service ProvisionerDaemon { // hold a lock on the job until CompleteJob() is // called with the matching ID. rpc AcquireJob(Empty) returns (AcquiredJob); - + // UpdateJob streams periodic updates for a job. // Implementations should buffer logs so this stream // is non-blocking. diff --git a/provisionerd/provisionerd.go b/provisionerd/provisionerd.go index 56f2707a1bf18..75d817bbbc7b0 100644 --- a/provisionerd/provisionerd.go +++ b/provisionerd/provisionerd.go @@ -15,6 +15,7 @@ import ( "sync" "time" + "github.com/google/uuid" "github.com/hashicorp/yamux" "go.uber.org/atomic" "golang.org/x/xerrors" @@ -414,6 +415,12 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) { p.runReadmeParse(ctx, job) p.runTemplateImport(ctx, shutdown, provisioner, job) + case *proto.AcquiredJob_TemplatePlan_: + p.opts.Logger.Debug(context.Background(), "acquired job is template plan", + slog.F("workspace_name", jobType.TemplatePlan.Metadata.WorkspaceName), + slog.F("parameters", jobType.TemplatePlan.ParameterValues), + ) + p.runTemplatePlan(ctx, shutdown, provisioner, job) case *proto.AcquiredJob_WorkspaceBuild_: p.opts.Logger.Debug(context.Background(), "acquired job is workspace provision", slog.F("workspace_name", jobType.WorkspaceBuild.WorkspaceName), @@ -733,6 +740,60 @@ func (p *Server) runTemplateImportProvision(ctx, shutdown context.Context, provi } } +func (p *Server) runTemplatePlan(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) { + // Ensure all metadata fields are set as they are all optional for plans. + metadata := job.GetTemplatePlan().GetMetadata() + metadata.WorkspaceTransition = sdkproto.WorkspaceTransition_START + if metadata.CoderUrl == "" { + metadata.CoderUrl = "http://localhost:3000" + } + if metadata.WorkspaceName == "" { + metadata.WorkspaceName = "plan" + } + metadata.WorkspaceOwner = job.UserName + if metadata.WorkspaceOwner == "" { + metadata.WorkspaceOwner = "planner" + } + if metadata.WorkspaceId == "" { + id, err := uuid.NewRandom() + if err != nil { + p.failActiveJobf("generate random ID: %s", err) + return + } + metadata.WorkspaceId = id.String() + } + if metadata.WorkspaceOwnerId == "" { + id, err := uuid.NewRandom() + if err != nil { + p.failActiveJobf("generate random ID: %s", err) + return + } + metadata.WorkspaceOwnerId = id.String() + } + + // Run the template import provision task since it's already a dry run. + resources, err := p.runTemplateImportProvision(ctx, + shutdown, + provisioner, + job, + job.GetTemplatePlan().GetParameterValues(), + metadata, + ) + if err != nil { + p.failActiveJobf("run dry-run provision job: %s", err) + return + } + + p.completeJob(&proto.CompletedJob{ + JobId: job.JobId, + Type: &proto.CompletedJob_TemplatePlan_{ + TemplatePlan: &proto.CompletedJob_TemplatePlan{ + Resources: resources, + }, + }, + }) +} + func (p *Server) runWorkspaceBuild(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) { var stage string switch job.GetWorkspaceBuild().Metadata.WorkspaceTransition { diff --git a/provisionerd/provisionerd_test.go b/provisionerd/provisionerd_test.go index 0b12720ce68d0..63b4569813ba4 100644 --- a/provisionerd/provisionerd_test.go +++ b/provisionerd/provisionerd_test.go @@ -315,6 +315,104 @@ func TestProvisionerd(t *testing.T) { require.NoError(t, closer.Close()) }) + t.Run("TemplatePlan", func(t *testing.T) { + t.Parallel() + var ( + didComplete atomic.Bool + didLog atomic.Bool + didAcquireJob atomic.Bool + 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{} + ) + + closer := createProvisionerd(t, func(ctx context.Context) (proto.DRPCProvisionerDaemonClient, error) { + return createProvisionerDaemonClient(t, provisionerDaemonTestServer{ + acquireJob: func(ctx context.Context, _ *proto.Empty) (*proto.AcquiredJob, error) { + if !didAcquireJob.CAS(false, true) { + completeOnce.Do(func() { close(completeChan) }) + return &proto.AcquiredJob{}, nil + } + + return &proto.AcquiredJob{ + JobId: "test", + Provisioner: "someprovisioner", + TemplateSourceArchive: createTar(t, map[string]string{ + "test.txt": "content", + }), + Type: &proto.AcquiredJob_TemplatePlan_{ + TemplatePlan: &proto.AcquiredJob_TemplatePlan{ + ParameterValues: parameterValues, + Metadata: metadata, + }, + }, + }, nil + }, + updateJob: func(ctx context.Context, update *proto.UpdateJobRequest) (*proto.UpdateJobResponse, error) { + if len(update.Logs) != 0 { + didLog.Store(true) + } + return &proto.UpdateJobResponse{}, nil + }, + completeJob: func(ctx context.Context, job *proto.CompletedJob) (*proto.Empty, error) { + didComplete.Store(true) + return &proto.Empty{}, nil + }, + }), nil + }, provisionerd.Provisioners{ + "someprovisioner": createProvisionerClient(t, provisionerTestServer{ + provision: func(stream sdkproto.DRPCProvisioner_ProvisionStream) error { + err := stream.Send(&sdkproto.Provision_Response{ + Type: &sdkproto.Provision_Response_Complete{ + Complete: &sdkproto.Provision_Complete{ + Resources: []*sdkproto.Resource{ + { + Name: "test-resource", + Type: "test_type", + Agents: []*sdkproto.Agent{ + { + Id: "test-id", + Name: "test", + Env: map[string]string{}, + StartupScript: "echo hi", + OperatingSystem: "linux", + Architecture: "amd64", + Directory: "/home/coder", + Auth: &sdkproto.Agent_Token{ + Token: "test-token", + }, + }, + }, + }, + }, + }, + }, + }) + require.NoError(t, err) + return nil + }, + }), + }) + + <-completeChan + require.True(t, didLog.Load()) + require.True(t, didComplete.Load()) + require.NoError(t, closer.Close()) + }) + t.Run("WorkspaceBuild", func(t *testing.T) { t.Parallel() var ( From cf033aa9dd10733712224dea83840320cc65db3d Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 27 May 2022 09:52:56 +0000 Subject: [PATCH 02/10] feat: finish implementing workspace planning --- cli/cliui/provisionerjob.go | 31 ++++++- cli/create.go | 50 ++++++----- coderd/coderd.go | 8 +- coderd/provisionerdaemons.go | 29 ++++++ coderd/templateversions.go | 125 +++++++++++++++++++++++++- codersdk/client.go | 17 +++- codersdk/templateversions.go | 66 ++++++++++++-- provisionerd/proto/provisionerd.proto | 2 + 8 files changed, 291 insertions(+), 37 deletions(-) diff --git a/cli/cliui/provisionerjob.go b/cli/cliui/provisionerjob.go index 4255fba43c539..88375c9134772 100644 --- a/cli/cliui/provisionerjob.go +++ b/cli/cliui/provisionerjob.go @@ -1,6 +1,7 @@ package cliui import ( + "bytes" "context" "fmt" "io" @@ -35,6 +36,9 @@ type ProvisionerJobOptions struct { FetchInterval time.Duration // Verbose determines whether debug and trace logs will be shown. Verbose bool + // Silent determines whether log output will be shown unless there is an + // error. + Silent bool } // ProvisionerJob renders a provisioner job with interactive cancellation. @@ -133,12 +137,30 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp return xerrors.Errorf("logs: %w", err) } + var ( + // logOutput is where log output is written + logOutput = writer + // logBuffer is where logs are buffered if opts.Silent is true + logBuffer = &bytes.Buffer{} + ) + if opts.Silent { + logOutput = logBuffer + } + flushLogBuffer := func() { + if opts.Silent { + _, _ = io.Copy(writer, logBuffer) + } + } + ticker := time.NewTicker(opts.FetchInterval) + defer ticker.Stop() for { select { case err = <-errChan: + flushLogBuffer() return err case <-ctx.Done(): + flushLogBuffer() return ctx.Err() case <-ticker.C: updateJob() @@ -160,8 +182,10 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp } err = xerrors.New(job.Error) jobMutex.Unlock() + flushLogBuffer() return err } + output := "" switch log.Level { case codersdk.LogLevelTrace, codersdk.LogLevelDebug: @@ -176,14 +200,17 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp case codersdk.LogLevelInfo: output = log.Output } + jobMutex.Lock() if log.Stage != currentStage && log.Stage != "" { updateStage(log.Stage, log.CreatedAt) jobMutex.Unlock() continue } - _, _ = fmt.Fprintf(writer, "%s %s\n", Styles.Placeholder.Render(" "), output) - didLogBetweenStage = true + _, _ = fmt.Fprintf(logOutput, "%s %s\n", Styles.Placeholder.Render(" "), output) + if !opts.Silent { + didLogBetweenStage = true + } jobMutex.Unlock() } } diff --git a/cli/create.go b/cli/create.go index 8b22cdaa45ca6..21a9187ffdb48 100644 --- a/cli/create.go +++ b/cli/create.go @@ -170,44 +170,47 @@ func create() *cobra.Command { } _, _ = fmt.Fprintln(cmd.OutOrStdout()) - resources, err := client.TemplateVersionResources(cmd.Context(), templateVersion.ID) - if err != nil { - return err - } - err = cliui.WorkspaceResources(cmd.OutOrStdout(), resources, cliui.WorkspaceResourcesOptions{ - WorkspaceName: workspaceName, - // Since agent's haven't connected yet, hiding this makes more sense. - HideAgentState: true, - Title: "Workspace Preview", - }) - if err != nil { - return err - } - // Run a plan with the given parameters to check correctness - planJob, err := client.TemplateVersionPlan(cmd.Context(), templateVersion.ID, codersdk.TemplateVersionPlanRequest{ + after := time.Now() + planJob, err := client.CreateTemplateVersionPlan(cmd.Context(), templateVersion.ID, codersdk.CreateTemplateVersionPlanRequest{ ParameterValues: parameters, }) if err != nil { - return xerrors.Errorf("plan workspace: %w", err) + return xerrors.Errorf("begin workspace plan: %w", err) } + _, _ = fmt.Fprintln(cmd.OutOrStdout(), "Planning workspace...") err = cliui.ProvisionerJob(cmd.Context(), cmd.OutOrStdout(), cliui.ProvisionerJobOptions{ Fetch: func() (codersdk.ProvisionerJob, error) { - return planJob, nil + return client.TemplateVersionPlan(cmd.Context(), templateVersion.ID, planJob.ID) }, Cancel: func() error { - // TODO: workspace plan cancellation endpoint - return nil + return client.CancelTemplateVersionPlan(cmd.Context(), templateVersion.ID, planJob.ID) }, Logs: func() (<-chan codersdk.ProvisionerJobLog, error) { - // TODO: workspace plan log endpoint - return make(chan codersdk.ProvisionerJobLog), nil + return client.TemplateVersionPlanLogsAfter(cmd.Context(), templateVersion.ID, planJob.ID, after) }, + // Don't show log output for the plan unless there's an error. + Silent: true, }) if err != nil { // TODO: reprompt for parameter values if we deem it to be a // validation error - return xerrors.Errorf("error occurred during workspace plan: %w", err) + return xerrors.Errorf("plan workspace: %w", err) + } + + resources, err := client.TemplateVersionPlanResources(cmd.Context(), templateVersion.ID, planJob.ID) + if err != nil { + return xerrors.Errorf("get workspace plan resources: %w", err) + } + + err = cliui.WorkspaceResources(cmd.OutOrStdout(), resources, cliui.WorkspaceResourcesOptions{ + WorkspaceName: workspaceName, + // Since agent's haven't connected yet, hiding this makes more sense. + HideAgentState: true, + Title: "Workspace Preview", + }) + if err != nil { + return err } _, err = cliui.Prompt(cmd, cliui.PromptOptions{ @@ -218,7 +221,6 @@ func create() *cobra.Command { return err } - before := time.Now() workspace, err := client.CreateWorkspace(cmd.Context(), organization.ID, codersdk.CreateWorkspaceRequest{ TemplateID: template.ID, Name: workspaceName, @@ -230,7 +232,7 @@ func create() *cobra.Command { return err } - err = cliui.WorkspaceBuild(cmd.Context(), cmd.OutOrStdout(), client, workspace.LatestBuild.ID, before) + err = cliui.WorkspaceBuild(cmd.Context(), cmd.OutOrStdout(), client, workspace.LatestBuild.ID, after) if err != nil { return err } diff --git a/coderd/coderd.go b/coderd/coderd.go index 1c0fbeadb5ae5..41fd6cf4dad06 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -208,7 +208,13 @@ func newRouter(options *Options, a *api) chi.Router { r.Get("/parameters", a.templateVersionParameters) r.Get("/resources", a.templateVersionResources) r.Get("/logs", a.templateVersionLogs) - r.Post("/plan", a.templateVersionPlan) + r.Route("/plan", func(r chi.Router) { + r.Post("/", a.createTemplateVersionPlan) + r.Get("/{jobID}", a.templateVersionPlan) + r.Get("/{jobID}/resources", a.templateVersionPlanResources) + r.Get("/{jobID}/logs", a.templateVersionPlanLogs) + r.Patch("/{jobID}/cancel", a.templateVersionPlanCancel) + }) }) r.Route("/users", func(r chi.Router) { r.Get("/first", a.firstUser) diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index bdafaba4605d7..2eb0cdfe52ac3 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -628,6 +628,35 @@ func (server *provisionerdServer) CompleteJob(ctx context.Context, completed *pr if err != nil { return nil, xerrors.Errorf("complete job: %w", err) } + case *proto.CompletedJob_TemplatePlan_: + for _, resource := range jobType.TemplatePlan.Resources { + server.Logger.Info(ctx, "inserting template plan job resource", + slog.F("job_id", job.ID.String()), + slog.F("resource_name", resource.Name), + slog.F("resource_type", resource.Type)) + + err = insertWorkspaceResource(ctx, server.Database, jobID, database.WorkspaceTransitionStart, resource) + if err != nil { + return nil, xerrors.Errorf("insert resource: %w", err) + } + } + + err = server.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ + ID: jobID, + UpdatedAt: database.Now(), + CompletedAt: sql.NullTime{ + Time: database.Now(), + Valid: true, + }, + }) + if err != nil { + return nil, xerrors.Errorf("update provisioner job: %w", err) + } + server.Logger.Debug(ctx, "marked template plan job as completed", slog.F("job_id", jobID)) + if err != nil { + return nil, xerrors.Errorf("complete job: %w", err) + } + default: return nil, xerrors.Errorf("unknown job type %q; ensure coderd and provisionerd versions match", reflect.TypeOf(completed.Type).String()) diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 1ff971b5b48ea..01981aee04c74 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -147,12 +147,11 @@ func (api *api) templateVersionParameters(rw http.ResponseWriter, r *http.Reques httpapi.Write(rw, http.StatusOK, values) } -func (api *api) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { +func (api *api) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Request) { apiKey := httpmw.APIKey(r) - organization := httpmw.OrganizationParam(r) templateVersion := httpmw.TemplateVersionParam(r) - var req codersdk.TemplateVersionPlanRequest + var req codersdk.CreateTemplateVersionPlanRequest if !httpapi.Read(rw, r, &req) { return } @@ -203,7 +202,7 @@ func (api *api) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { ID: jobID, CreatedAt: database.Now(), UpdatedAt: database.Now(), - OrganizationID: organization.ID, + OrganizationID: templateVersion.OrganizationID, InitiatorID: apiKey.UserID, Provisioner: job.Provisioner, StorageMethod: job.StorageMethod, @@ -221,6 +220,124 @@ func (api *api) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { httpapi.Write(rw, http.StatusCreated, convertProvisionerJob(provisionerJob)) } +func (api *api) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { + job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + if !ok { + return + } + + httpapi.Write(rw, http.StatusOK, convertProvisionerJob(job)) +} + +func (api *api) templateVersionPlanResources(rw http.ResponseWriter, r *http.Request) { + job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + if !ok { + return + } + + api.provisionerJobResources(rw, r, job) +} + +func (api *api) templateVersionPlanLogs(rw http.ResponseWriter, r *http.Request) { + job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + if !ok { + return + } + + api.provisionerJobLogs(rw, r, job) +} + +func (api *api) templateVersionPlanCancel(rw http.ResponseWriter, r *http.Request) { + job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + if !ok { + return + } + + if job.CompletedAt.Valid { + httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{ + Message: "Job has already completed", + }) + return + } + if job.CanceledAt.Valid { + httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{ + Message: "Job has already been marked as canceled", + }) + return + } + + err := api.Database.UpdateProvisionerJobWithCancelByID(r.Context(), database.UpdateProvisionerJobWithCancelByIDParams{ + ID: job.ID, + CanceledAt: sql.NullTime{ + Time: database.Now(), + Valid: true, + }, + }) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("update provisioner job: %s", err), + }) + return + } + + httpapi.Write(rw, http.StatusOK, httpapi.Response{ + Message: "Job has been marked as canceled", + }) +} + +func getTemplateVersionPlanJob(db database.Store, rw http.ResponseWriter, r *http.Request) (database.ProvisionerJob, bool) { + var ( + apiKey = httpmw.APIKey(r) + templateVersion = httpmw.TemplateVersionParam(r) + jobID = chi.URLParam(r, "jobID") + ) + + jobUUID, err := uuid.Parse(jobID) + if err != nil { + httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{ + Message: "Job ID must be a valid UUID", + }) + return database.ProvisionerJob{}, false + } + + job, err := db.GetProvisionerJobByID(r.Context(), jobUUID) + if xerrors.Is(err, sql.ErrNoRows) { + httpapi.Forbidden(rw) + return database.ProvisionerJob{}, false + } + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("get provisioner job by ID %q: %s", jobUUID.String(), err), + }) + return database.ProvisionerJob{}, false + } + if job.Type != database.ProvisionerJobTypeTemplateVersionPlan { + httpapi.Forbidden(rw) + return database.ProvisionerJob{}, false + } + // TODO: real RBAC + if job.InitiatorID != apiKey.UserID { + httpapi.Forbidden(rw) + return database.ProvisionerJob{}, false + } + + // Verify that the template version is the one used in the request. + var input templateVersionPlanJob + err = json.Unmarshal(job.Input, &input) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("unmarshal job metadata: %s", err), + }) + return database.ProvisionerJob{}, false + } + if input.TemplateVersionID != templateVersion.ID { + httpapi.Forbidden(rw) + return database.ProvisionerJob{}, false + } + + return job, true +} + func (api *api) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Request) { template := httpmw.TemplateParam(r) diff --git a/codersdk/client.go b/codersdk/client.go index 2735c1900a2e9..0167bc43db96f 100644 --- a/codersdk/client.go +++ b/codersdk/client.go @@ -126,6 +126,14 @@ func (c *Client) dialWebsocket(ctx context.Context, path string) (*websocket.Con func readBodyAsError(res *http.Response) error { contentType := res.Header.Get("Content-Type") + var method, u string + if res.Request != nil { + method = res.Request.Method + if res.Request.URL != nil { + u = res.Request.URL.String() + } + } + var helper string if res.StatusCode == http.StatusUnauthorized { // 401 means the user is not logged in @@ -163,6 +171,8 @@ func readBodyAsError(res *http.Response) error { return &Error{ Response: m, statusCode: res.StatusCode, + method: method, + url: u, Helper: helper, } } @@ -173,6 +183,8 @@ type Error struct { httpapi.Response statusCode int + method string + url string Helper string } @@ -183,7 +195,10 @@ func (e *Error) StatusCode() int { func (e *Error) Error() string { var builder strings.Builder - _, _ = fmt.Fprintf(&builder, "status code %d: %s", e.statusCode, e.Message) + if e.method != "" && e.url != "" { + _, _ = fmt.Fprintf(&builder, "%v %v: ", e.method, e.url) + } + _, _ = fmt.Fprintf(&builder, "unexpected status code %d: %s", e.statusCode, e.Message) if e.Helper != "" { _, _ = fmt.Fprintf(&builder, ": %s", e.Helper) } diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index ceb70debc7ddf..b81260bb0f309 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -115,15 +115,15 @@ func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/templateversions/%s/logs", version), after) } -// TemplateVersionPlanRequest defines the request parameters for -// TemplateVersionPlan. -type TemplateVersionPlanRequest struct { +// CreateTemplateVersionPlanRequest defines the request parameters for +// CreateTemplateVersionPlan. +type CreateTemplateVersionPlanRequest struct { ParameterValues []CreateParameterRequest } -// TemplateVersionPlan begins a dry-run provisioner job against the given +// CreateTemplateVersionPlan begins a dry-run provisioner job against the given // template version with the given parameter values. -func (c *Client) TemplateVersionPlan(ctx context.Context, version uuid.UUID, req TemplateVersionPlanRequest) (ProvisionerJob, error) { +func (c *Client) CreateTemplateVersionPlan(ctx context.Context, version uuid.UUID, req CreateTemplateVersionPlanRequest) (ProvisionerJob, error) { res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/templateversions/%s/plan", version), req) if err != nil { return ProvisionerJob{}, err @@ -136,3 +136,59 @@ func (c *Client) TemplateVersionPlan(ctx context.Context, version uuid.UUID, req var job ProvisionerJob return job, json.NewDecoder(res.Body).Decode(&job) } + +// TemplateVersionPlan returns the current state of a template version plan job. +func (c *Client) TemplateVersionPlan(ctx context.Context, version, job uuid.UUID) (ProvisionerJob, error) { + res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s", version, job), nil) + if err != nil { + return ProvisionerJob{}, err + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return ProvisionerJob{}, readBodyAsError(res) + } + + var j ProvisionerJob + return j, json.NewDecoder(res.Body).Decode(&j) +} + +// TemplateVersionPlanResources returns the resources of a finished template +// version plan job. +func (c *Client) TemplateVersionPlanResources(ctx context.Context, version, job uuid.UUID) ([]WorkspaceResource, error) { + res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/resources", version, job), nil) + if err != nil { + return nil, err + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return nil, readBodyAsError(res) + } + + var resources []WorkspaceResource + return resources, json.NewDecoder(res.Body).Decode(&resources) +} + +// TemplateVersionPlanLogsBefore returns logs for a template version plan that +// occurred before a specific time. +func (c *Client) TemplateVersionPlanLogsBefore(ctx context.Context, version, job uuid.UUID, before time.Time) ([]ProvisionerJobLog, error) { + return c.provisionerJobLogsBefore(ctx, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/logs", version, job), before) +} + +// TemplateVersionPlanLogsAfter streams logs for a template version plan that +// occurred after a specific time. +func (c *Client) TemplateVersionPlanLogsAfter(ctx context.Context, version, job uuid.UUID, after time.Time) (<-chan ProvisionerJobLog, error) { + return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/logs", version, job), after) +} + +// CancelTemplateVersionPlan marks a template version plan job as canceled. +func (c *Client) CancelTemplateVersionPlan(ctx context.Context, version, job uuid.UUID) error { + res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/cancel", version, job), nil) + if err != nil { + return err + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return readBodyAsError(res) + } + return nil +} diff --git a/provisionerd/proto/provisionerd.proto b/provisionerd/proto/provisionerd.proto index 50d4c53cae0ad..93556ea4acea7 100644 --- a/provisionerd/proto/provisionerd.proto +++ b/provisionerd/proto/provisionerd.proto @@ -44,6 +44,7 @@ message FailedJob { } message TemplateImport {} message TemplatePlan {} + string job_id = 1; string error = 2; oneof type { @@ -66,6 +67,7 @@ message CompletedJob { message TemplatePlan { repeated provisioner.Resource resources = 1; } + string job_id = 1; oneof type { WorkspaceBuild workspace_build = 2; From cfe34afcde3e257f497acf3d2a2aeba0459ae1ae Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 27 May 2022 19:49:56 +0000 Subject: [PATCH 03/10] big tests --- cli/create.go | 4 +- cli/create_test.go | 48 +++++++ coderd/coderd_test.go | 26 ++++ coderd/templateversions.go | 52 +++++--- coderd/templateversions_test.go | 229 ++++++++++++++++++++++++++++++++ codersdk/templateversions.go | 15 ++- provisioner/echo/serve.go | 3 +- provisionerd/provisionerd.go | 10 +- 8 files changed, 358 insertions(+), 29 deletions(-) diff --git a/cli/create.go b/cli/create.go index 21a9187ffdb48..f4ce52dcfedcc 100644 --- a/cli/create.go +++ b/cli/create.go @@ -193,8 +193,8 @@ func create() *cobra.Command { Silent: true, }) if err != nil { - // TODO: reprompt for parameter values if we deem it to be a - // validation error + // TODO (Dean): reprompt for parameter values if we deem it to + // be a validation error return xerrors.Errorf("plan workspace: %w", err) } diff --git a/cli/create_test.go b/cli/create_test.go index 2a6ff752d201f..607835043f583 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -2,6 +2,7 @@ package cli_test import ( "context" + "database/sql" "fmt" "os" "testing" @@ -12,6 +13,8 @@ import ( "github.com/coder/coder/cli/clitest" "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/coderd/database" + "github.com/coder/coder/codersdk" "github.com/coder/coder/provisioner/echo" "github.com/coder/coder/provisionersdk/proto" "github.com/coder/coder/pty/ptytest" @@ -249,6 +252,7 @@ func TestCreate(t *testing.T) { <-doneChan removeTmpDirUntilSuccess(t, tempDir) }) + t.Run("WithParameterFileNotContainingTheValue", func(t *testing.T) { t.Parallel() client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) @@ -279,6 +283,50 @@ func TestCreate(t *testing.T) { <-doneChan removeTmpDirUntilSuccess(t, tempDir) }) + + t.Run("FailedPlan", func(t *testing.T) { + t.Parallel() + client, api := coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionDryRun: []*proto.Provision_Response{ + { + Type: &proto.Provision_Response_Complete{ + Complete: &proto.Provision_Complete{ + Error: "test error", + }, + }, + }, + }, + }) + + // The template import job should end up failed, but we need it to be + // succeeded so the plan can begin. + version = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + require.Equal(t, codersdk.ProvisionerJobFailed, version.Job.Status, "job is not failed") + err := api.Database.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{ + ID: version.Job.ID, + CompletedAt: sql.NullTime{ + Time: time.Now(), + Valid: true, + }, + UpdatedAt: time.Now(), + Error: sql.NullString{}, + }) + require.NoError(t, err, "update provisioner job") + + _ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + cmd, root := clitest.New(t, "create", "test") + clitest.SetupConfig(t, client, root) + pty := ptytest.New(t) + cmd.SetIn(pty.Input()) + cmd.SetOut(pty.Output()) + + err = cmd.Execute() + require.Error(t, err) + require.ErrorContains(t, err, "plan workspace") + }) } func createTestParseResponseWithDefault(defaultValue string) []*proto.Parse_Response { diff --git a/coderd/coderd_test.go b/coderd/coderd_test.go index 9b1e83a252ee6..79423c50d0b4c 100644 --- a/coderd/coderd_test.go +++ b/coderd/coderd_test.go @@ -96,6 +96,10 @@ func TestAuthorizeAllEndpoints(t *testing.T) { require.NoError(t, err, "upload file") workspaceResources, err := client.WorkspaceResourcesByBuild(ctx, workspace.LatestBuild.ID) require.NoError(t, err, "workspace resources") + templateVersionPlanJob, err := client.CreateTemplateVersionPlan(ctx, version.ID, codersdk.CreateTemplateVersionPlanRequest{ + ParameterValues: []codersdk.CreateParameterRequest{}, + }) + require.NoError(t, err, "template version plan") // Always fail auth from this point forward authorizer.AlwaysReturn = rbac.ForbiddenWithInternal(xerrors.New("fake implementation"), nil, nil) @@ -264,6 +268,27 @@ func TestAuthorizeAllEndpoints(t *testing.T) { AssertAction: rbac.ActionRead, AssertObject: rbac.ResourceTemplate.InOrg(template.OrganizationID).WithID(template.ID.String()), }, + "POST:/api/v2/templateversions/{templateversion}/plan": { + // The first check is to read the template + AssertAction: rbac.ActionRead, + AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), + }, + "GET:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}": { + AssertAction: rbac.ActionRead, + AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), + }, + "GET:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}/resources": { + AssertAction: rbac.ActionRead, + AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), + }, + "GET:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}/logs": { + AssertAction: rbac.ActionRead, + AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), + }, + "PATCH:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}/cancel": { + AssertAction: rbac.ActionRead, + AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), + }, "GET:/api/v2/provisionerdaemons": { StatusCode: http.StatusOK, AssertObject: rbac.ResourceProvisionerDaemon.WithID(provisionerds[0].ID.String()), @@ -326,6 +351,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) { route = strings.ReplaceAll(route, "{hash}", file.Hash) route = strings.ReplaceAll(route, "{workspaceresource}", workspaceResources[0].ID.String()) route = strings.ReplaceAll(route, "{templateversion}", version.ID.String()) + route = strings.ReplaceAll(route, "{templateversionplan}", templateVersionPlanJob.ID.String()) route = strings.ReplaceAll(route, "{templatename}", template.Name) // Only checking org scoped params here route = strings.ReplaceAll(route, "{scope}", string(organizationParam.Scope)) diff --git a/coderd/templateversions.go b/coderd/templateversions.go index d484017450db7..d840d392b6459 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -167,6 +167,15 @@ func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Reques func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Request) { apiKey := httpmw.APIKey(r) templateVersion := httpmw.TemplateVersionParam(r) + if !api.Authorize(rw, r, rbac.ActionRead, templateVersion) { + return + } + // We use the workspace RBAC check since we don't want to allow plans if the + // user can't create workspaces. + if !api.Authorize(rw, r, rbac.ActionCreate, + rbac.ResourceWorkspace.InOrg(templateVersion.OrganizationID).WithOwner(apiKey.UserID.String())) { + return + } var req codersdk.CreateTemplateVersionPlanRequest if !httpapi.Read(rw, r, &req) { @@ -238,7 +247,7 @@ func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Reques } func (api *API) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { - job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + job, ok := api.fetchTemplateVersionPlanJob(rw, r) if !ok { return } @@ -247,7 +256,7 @@ func (api *API) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { } func (api *API) templateVersionPlanResources(rw http.ResponseWriter, r *http.Request) { - job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + job, ok := api.fetchTemplateVersionPlanJob(rw, r) if !ok { return } @@ -256,7 +265,7 @@ func (api *API) templateVersionPlanResources(rw http.ResponseWriter, r *http.Req } func (api *API) templateVersionPlanLogs(rw http.ResponseWriter, r *http.Request) { - job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + job, ok := api.fetchTemplateVersionPlanJob(rw, r) if !ok { return } @@ -265,10 +274,16 @@ func (api *API) templateVersionPlanLogs(rw http.ResponseWriter, r *http.Request) } func (api *API) templateVersionPlanCancel(rw http.ResponseWriter, r *http.Request) { - job, ok := getTemplateVersionPlanJob(api.Database, rw, r) + templateVersion := httpmw.TemplateVersionParam(r) + + job, ok := api.fetchTemplateVersionPlanJob(rw, r) if !ok { return } + if !api.Authorize(rw, r, rbac.ActionUpdate, + rbac.ResourceWorkspace.InOrg(templateVersion.OrganizationID).WithOwner(job.InitiatorID.String())) { + return + } if job.CompletedAt.Valid { httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{ @@ -302,12 +317,14 @@ func (api *API) templateVersionPlanCancel(rw http.ResponseWriter, r *http.Reques }) } -func getTemplateVersionPlanJob(db database.Store, rw http.ResponseWriter, r *http.Request) (database.ProvisionerJob, bool) { +func (api *API) fetchTemplateVersionPlanJob(rw http.ResponseWriter, r *http.Request) (database.ProvisionerJob, bool) { var ( - apiKey = httpmw.APIKey(r) templateVersion = httpmw.TemplateVersionParam(r) jobID = chi.URLParam(r, "jobID") ) + if !api.Authorize(rw, r, rbac.ActionRead, templateVersion) { + return database.ProvisionerJob{}, false + } jobUUID, err := uuid.Parse(jobID) if err != nil { @@ -317,7 +334,7 @@ func getTemplateVersionPlanJob(db database.Store, rw http.ResponseWriter, r *htt return database.ProvisionerJob{}, false } - job, err := db.GetProvisionerJobByID(r.Context(), jobUUID) + job, err := api.Database.GetProvisionerJobByID(r.Context(), jobUUID) if xerrors.Is(err, sql.ErrNoRows) { httpapi.Forbidden(rw) return database.ProvisionerJob{}, false @@ -332,9 +349,9 @@ func getTemplateVersionPlanJob(db database.Store, rw http.ResponseWriter, r *htt httpapi.Forbidden(rw) return database.ProvisionerJob{}, false } - // TODO: real RBAC - if job.InitiatorID != apiKey.UserID { - httpapi.Forbidden(rw) + // Do a workspace resource check since it's basically a workspace plan. + if !api.Authorize(rw, r, rbac.ActionRead, + rbac.ResourceWorkspace.InOrg(templateVersion.OrganizationID).WithOwner(job.InitiatorID.String())) { return database.ProvisionerJob{}, false } @@ -645,12 +662,13 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) { func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob) codersdk.TemplateVersion { return codersdk.TemplateVersion{ - ID: version.ID, - TemplateID: &version.TemplateID.UUID, - CreatedAt: version.CreatedAt, - UpdatedAt: version.UpdatedAt, - Name: version.Name, - Job: job, - Readme: version.Readme, + ID: version.ID, + TemplateID: &version.TemplateID.UUID, + OrganizationID: version.OrganizationID, + CreatedAt: version.CreatedAt, + UpdatedAt: version.UpdatedAt, + Name: version.Name, + Job: job, + Readme: version.Readme, } } diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 92c5036090c15..42b65cb796820 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -2,6 +2,7 @@ package coderd_test import ( "context" + "database/sql" "net/http" "testing" "time" @@ -11,6 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/coderd/database" "github.com/coder/coder/codersdk" "github.com/coder/coder/provisioner/echo" "github.com/coder/coder/provisionersdk/proto" @@ -448,6 +450,213 @@ func TestPatchActiveTemplateVersion(t *testing.T) { }) } +func TestTemplateVersionPlan(t *testing.T) { + t.Parallel() + + t.Run("OK", func(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + resource := &proto.Resource{ + Name: "cool-resource", + Type: "cool_resource_type", + } + + client := coderdtest.New(t, &coderdtest.Options{APIRateLimit: -1, IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + Provision: []*proto.Provision_Response{ + { + Type: &proto.Provision_Response_Log{ + Log: &proto.Log{}, + }, + }, + { + Type: &proto.Provision_Response_Complete{ + Complete: &proto.Provision_Complete{ + Resources: []*proto.Resource{resource}, + }, + }, + }, + }, + }) + _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + + // Create template version plan + after := time.Now() + job, err := client.CreateTemplateVersionPlan(ctx, version.ID, codersdk.CreateTemplateVersionPlanRequest{ + ParameterValues: []codersdk.CreateParameterRequest{}, + }) + require.NoError(t, err) + + // Fetch template version plan + newJob, err := client.TemplateVersionPlan(ctx, version.ID, job.ID) + require.NoError(t, err) + require.Equal(t, job, newJob) + + // Stream logs + logs, err := client.TemplateVersionPlanLogsAfter(ctx, version.ID, job.ID, after) + require.NoError(t, err) + + logsDone := make(chan struct{}) + go func() { + defer close(logsDone) + + logCount := 0 + for { + select { + case _, ok := <-logs: + if !ok { + assert.GreaterOrEqual(t, logCount, 1, "unexpected log count") + return + } + logCount++ + } + } + }() + + // Wait for the job to complete + require.Eventually(t, func() bool { + job, err := client.TemplateVersionPlan(ctx, version.ID, job.ID) + assert.NoError(t, err) + + return job.Status == codersdk.ProvisionerJobSucceeded + }, 5*time.Second, 25*time.Millisecond) + + <-logsDone + + resources, err := client.TemplateVersionPlanResources(ctx, version.ID, job.ID) + require.NoError(t, err) + require.Len(t, resources, 1) + require.Equal(t, resource.Name, resources[0].Name) + require.Equal(t, resource.Type, resources[0].Type) + }) + + t.Run("ImportNotFinished", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + // This import job will never finish + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + Provision: []*proto.Provision_Response{{ + Type: &proto.Provision_Response_Log{ + Log: &proto.Log{}, + }, + }}, + }) + + _, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + ParameterValues: []codersdk.CreateParameterRequest{}, + }) + var apiErr *codersdk.Error + require.ErrorAs(t, err, &apiErr) + require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode()) + }) + + t.Run("Cancel", func(t *testing.T) { + t.Parallel() + + t.Run("OK", func(t *testing.T) { + t.Parallel() + client, api := coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + Provision: []*proto.Provision_Response{{ + Type: &proto.Provision_Response_Log{ + Log: &proto.Log{}, + }, + }}, + }) + forceCompleteTemplateVersionJob(t, api.Database, client, version) + + // Create the plan + job, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + ParameterValues: []codersdk.CreateParameterRequest{}, + }) + require.NoError(t, err) + + require.Eventually(t, func() bool { + job, err := client.TemplateVersionPlan(context.Background(), version.ID, job.ID) + assert.NoError(t, err) + + t.Logf("Status: %s", job.Status) + return job.Status == codersdk.ProvisionerJobRunning + }, 5*time.Second, 25*time.Millisecond) + + err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + require.NoError(t, err) + + require.Eventually(t, func() bool { + job, err := client.TemplateVersionPlan(context.Background(), version.ID, job.ID) + assert.NoError(t, err) + + t.Logf("Status: %s", job.Status) + return job.Status == codersdk.ProvisionerJobCanceled + }, 5*time.Second, 25*time.Millisecond) + }) + + t.Run("AlreadyCompleted", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) + coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + + // Create the plan + job, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + ParameterValues: []codersdk.CreateParameterRequest{}, + }) + require.NoError(t, err) + + require.Eventually(t, func() bool { + job, err := client.TemplateVersionPlan(context.Background(), version.ID, job.ID) + assert.NoError(t, err) + + t.Logf("Status: %s", job.Status) + return job.Status == codersdk.ProvisionerJobSucceeded + }, 5*time.Second, 25*time.Millisecond) + + err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + var apiErr *codersdk.Error + require.ErrorAs(t, err, &apiErr) + require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode()) + }) + + t.Run("AlreadyCanceled", func(t *testing.T) { + t.Parallel() + client, api := coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerD: true}) + user := coderdtest.CreateFirstUser(t, client) + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + Provision: []*proto.Provision_Response{{ + Type: &proto.Provision_Response_Log{ + Log: &proto.Log{}, + }, + }}, + }) + forceCompleteTemplateVersionJob(t, api.Database, client, version) + + // Create the plan + job, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + ParameterValues: []codersdk.CreateParameterRequest{}, + }) + require.NoError(t, err) + + err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + require.NoError(t, err) + + err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + var apiErr *codersdk.Error + require.ErrorAs(t, err, &apiErr) + require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode()) + }) + }) +} + // TestPaginatedTemplateVersions creates a list of template versions and paginate. func TestPaginatedTemplateVersions(t *testing.T) { t.Parallel() @@ -539,3 +748,23 @@ func TestPaginatedTemplateVersions(t *testing.T) { }) } } + +func forceCompleteTemplateVersionJob(t *testing.T, db database.Store, client *codersdk.Client, version codersdk.TemplateVersion) { + t.Helper() + + // HACK: we need the template version job to be finished so the plan job can + // be created. We do this by canceling the job and then marking it as + // successful. + err := client.CancelTemplateVersion(context.Background(), version.ID) + require.NoError(t, err) + err = db.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{ + ID: version.Job.ID, + UpdatedAt: time.Now(), + CompletedAt: sql.NullTime{ + Time: time.Now(), + Valid: true, + }, + Error: sql.NullString{}, + }) + require.NoError(t, err) +} diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index b81260bb0f309..c8e6d6874a779 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -12,13 +12,14 @@ import ( // TemplateVersion represents a single version of a template. type TemplateVersion struct { - ID uuid.UUID `json:"id"` - TemplateID *uuid.UUID `json:"template_id,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Name string `json:"name"` - Job ProvisionerJob `json:"job"` - Readme string `json:"readme"` + ID uuid.UUID `json:"id"` + TemplateID *uuid.UUID `json:"template_id,omitempty"` + OrganizationID uuid.UUID `json:"organization_id,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Name string `json:"name"` + Job ProvisionerJob `json:"job"` + Readme string `json:"readme"` } // TemplateVersionParameter represents a computed parameter value. diff --git a/provisioner/echo/serve.go b/provisioner/echo/serve.go index 6a9ecab23dee3..1aa79a93ef23e 100644 --- a/provisioner/echo/serve.go +++ b/provisioner/echo/serve.go @@ -38,8 +38,7 @@ func Serve(ctx context.Context, options *provisionersdk.ServeOptions) error { // The echo provisioner serves as a dummy provisioner primarily // used for testing. It echos responses from JSON files in the // format %d.protobuf. It's used for testing. -type echo struct { -} +type echo struct{} // Parse reads requests from the provided directory to stream responses. func (*echo) Parse(request *proto.Parse_Request, stream proto.DRPCProvisioner_ParseStream) error { diff --git a/provisionerd/provisionerd.go b/provisionerd/provisionerd.go index 75d817bbbc7b0..06aef5301b3d8 100644 --- a/provisionerd/provisionerd.go +++ b/provisionerd/provisionerd.go @@ -590,7 +590,7 @@ func (p *Server) runTemplateImport(ctx, shutdown context.Context, provisioner sd WorkspaceTransition: sdkproto.WorkspaceTransition_STOP, }) if err != nil { - p.failActiveJobf("template import provision for start: %s", err) + p.failActiveJobf("template import provision for stop: %s", err) return } @@ -726,6 +726,14 @@ func (p *Server) runTemplateImportProvision(ctx, shutdown context.Context, provi return nil, xerrors.Errorf("send job update: %w", err) } case *sdkproto.Provision_Response_Complete: + if msgType.Complete.Error != "" { + p.opts.Logger.Info(context.Background(), "dry-run provision failure", + slog.F("error", msgType.Complete.Error), + ) + + return nil, xerrors.New(msgType.Complete.Error) + } + p.opts.Logger.Info(context.Background(), "parse dry-run provision successful", slog.F("resource_count", len(msgType.Complete.Resources)), slog.F("resources", msgType.Complete.Resources), From 0d03a396a5e0a22205ae69277c5a750703728c39 Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Fri, 27 May 2022 21:25:12 +0100 Subject: [PATCH 04/10] fix: workspaces: relax error assertion --- coderd/workspaces_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index aa57b528e77b2..a77b66ea7221d 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -495,7 +495,7 @@ func TestWorkspaceUpdateAutostart(t *testing.T) { }) if testCase.expectedError != "" { - require.EqualError(t, err, testCase.expectedError, "unexpected error when setting workspace autostart schedule") + require.ErrorContains(t, err, testCase.expectedError, "unexpected error when setting workspace autostart schedule") return } From 4078fd112e0286fab9d1ea0e83768c9d3d9a10d7 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 27 May 2022 20:37:55 +0000 Subject: [PATCH 05/10] fix --- cli/create.go | 1 + ...ql => 000099_provisioner_job_type_plan.down.sql} | 0 ....sql => 000099_provisioner_job_type_plan.up.sql} | 0 coderd/provisionerdaemons.go | 4 +++- coderd/templateversions.go | 1 + coderd/templateversions_test.go | 13 ++++--------- codersdk/templateversions.go | 1 + 7 files changed, 10 insertions(+), 10 deletions(-) rename coderd/database/migrations/{000014_provisioner_job_type_plan.down.sql => 000099_provisioner_job_type_plan.down.sql} (100%) rename coderd/database/migrations/{000014_provisioner_job_type_plan.up.sql => 000099_provisioner_job_type_plan.up.sql} (100%) diff --git a/cli/create.go b/cli/create.go index f4ce52dcfedcc..ce51b7db91803 100644 --- a/cli/create.go +++ b/cli/create.go @@ -173,6 +173,7 @@ func create() *cobra.Command { // Run a plan with the given parameters to check correctness after := time.Now() planJob, err := client.CreateTemplateVersionPlan(cmd.Context(), templateVersion.ID, codersdk.CreateTemplateVersionPlanRequest{ + WorkspaceName: workspaceName, ParameterValues: parameters, }) if err != nil { diff --git a/coderd/database/migrations/000014_provisioner_job_type_plan.down.sql b/coderd/database/migrations/000099_provisioner_job_type_plan.down.sql similarity index 100% rename from coderd/database/migrations/000014_provisioner_job_type_plan.down.sql rename to coderd/database/migrations/000099_provisioner_job_type_plan.down.sql diff --git a/coderd/database/migrations/000014_provisioner_job_type_plan.up.sql b/coderd/database/migrations/000099_provisioner_job_type_plan.up.sql similarity index 100% rename from coderd/database/migrations/000014_provisioner_job_type_plan.up.sql rename to coderd/database/migrations/000099_provisioner_job_type_plan.up.sql diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index feb6464298460..7220ebdc26984 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -113,6 +113,7 @@ type workspaceProvisionJob struct { // The input for a "template_version_plan" job. type templateVersionPlanJob struct { TemplateVersionID uuid.UUID `json:"template_version_id"` + WorkspaceName string `json:"workspace_name"` ParameterValues []database.ParameterValue `json:"parameter_values"` } @@ -287,7 +288,8 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty TemplatePlan: &proto.AcquiredJob_TemplatePlan{ ParameterValues: protoParameters, Metadata: &sdkproto.Provision_Metadata{ - CoderUrl: server.AccessURL.String(), + CoderUrl: server.AccessURL.String(), + WorkspaceName: input.WorkspaceName, }, }, } diff --git a/coderd/templateversions.go b/coderd/templateversions.go index d840d392b6459..23c12e60b1538 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -213,6 +213,7 @@ func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Reques // Marshal template version plan job with the parameters from the request. input, err := json.Marshal(templateVersionPlanJob{ TemplateVersionID: templateVersion.ID, + WorkspaceName: req.WorkspaceName, ParameterValues: parameterValues, }) if err != nil { diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 42b65cb796820..62c5bf07c1a8e 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -505,16 +505,11 @@ func TestTemplateVersionPlan(t *testing.T) { defer close(logsDone) logCount := 0 - for { - select { - case _, ok := <-logs: - if !ok { - assert.GreaterOrEqual(t, logCount, 1, "unexpected log count") - return - } - logCount++ - } + for range logs { + logCount++ } + assert.GreaterOrEqual(t, logCount, 1, "unexpected log count") + return }() // Wait for the job to complete diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index c8e6d6874a779..e29f561380de9 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -119,6 +119,7 @@ func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID // CreateTemplateVersionPlanRequest defines the request parameters for // CreateTemplateVersionPlan. type CreateTemplateVersionPlanRequest struct { + WorkspaceName string ParameterValues []CreateParameterRequest } From 8d04749eecdf397ddd0e679d3df23d3ccf38b5dc Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 27 May 2022 20:39:58 +0000 Subject: [PATCH 06/10] fixup! fix --- coderd/templateversions_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 62c5bf07c1a8e..73c82a7cb8217 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -509,7 +509,6 @@ func TestTemplateVersionPlan(t *testing.T) { logCount++ } assert.GreaterOrEqual(t, logCount, 1, "unexpected log count") - return }() // Wait for the job to complete From 4b06c726915fb844b59bbad2a61a44cae538bb64 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 27 May 2022 20:45:32 +0000 Subject: [PATCH 07/10] gen --- coderd/database/queries.sql.go | 2 +- site/src/api/typesGenerated.ts | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index f30726e5efb2c..137fe36b4456b 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -2205,7 +2205,7 @@ WHERE WHEN $2 :: text != '' THEN ( email LIKE concat('%', $2, '%') OR username LIKE concat('%', $2, '%') - ) + ) ELSE true END -- Filter by status diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 57bc83ebc6dc3..7555dbe436556 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -65,6 +65,12 @@ export interface CreateTemplateRequest { readonly parameter_values?: CreateParameterRequest[] } +// From codersdk/templateversions.go:121:6 +export interface CreateTemplateVersionPlanRequest { + readonly WorkspaceName: string + readonly ParameterValues: CreateParameterRequest[] +} + // From codersdk/organizations.go:36:6 export interface CreateTemplateVersionRequest { readonly template_id?: string @@ -244,6 +250,7 @@ export interface Template { export interface TemplateVersion { readonly id: string readonly template_id?: string + readonly organization_id?: string readonly created_at: string readonly updated_at: string readonly name: string @@ -251,7 +258,7 @@ export interface TemplateVersion { readonly readme: string } -// From codersdk/templateversions.go:25:6 +// From codersdk/templateversions.go:26:6 export interface TemplateVersionParameter { readonly id: string readonly created_at: string From 2fee23a4ed8b9cd9db9059b8b4446b2831418a4c Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 27 May 2022 20:57:13 +0000 Subject: [PATCH 08/10] fixup! gen --- .../migrations/000099_provisioner_job_type_plan.down.sql | 2 +- coderd/templateversions_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/database/migrations/000099_provisioner_job_type_plan.down.sql b/coderd/database/migrations/000099_provisioner_job_type_plan.down.sql index d27e93f6160e6..32312535b28c4 100644 --- a/coderd/database/migrations/000099_provisioner_job_type_plan.down.sql +++ b/coderd/database/migrations/000099_provisioner_job_type_plan.down.sql @@ -5,5 +5,5 @@ DELETE FROM provisioner_jobs WHERE - provisioner_job_type = 'template_version_plan' + type = 'template_version_plan' ; diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 73c82a7cb8217..bade2f4fa13c7 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -494,7 +494,7 @@ func TestTemplateVersionPlan(t *testing.T) { // Fetch template version plan newJob, err := client.TemplateVersionPlan(ctx, version.ID, job.ID) require.NoError(t, err) - require.Equal(t, job, newJob) + require.Equal(t, job.ID, newJob.ID) // Stream logs logs, err := client.TemplateVersionPlanLogsAfter(ctx, version.ID, job.ID, after) From 6b95e54bf4cce1c29d3d7620c9afd0977414f533 Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Fri, 27 May 2022 21:08:07 +0000 Subject: [PATCH 09/10] remove heavy object nesting in tests --- provisionerd/provisionerd_test.go | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/provisionerd/provisionerd_test.go b/provisionerd/provisionerd_test.go index 63b4569813ba4..d51d73647586d 100644 --- a/provisionerd/provisionerd_test.go +++ b/provisionerd/provisionerd_test.go @@ -378,26 +378,7 @@ func TestProvisionerd(t *testing.T) { err := stream.Send(&sdkproto.Provision_Response{ Type: &sdkproto.Provision_Response_Complete{ Complete: &sdkproto.Provision_Complete{ - Resources: []*sdkproto.Resource{ - { - Name: "test-resource", - Type: "test_type", - Agents: []*sdkproto.Agent{ - { - Id: "test-id", - Name: "test", - Env: map[string]string{}, - StartupScript: "echo hi", - OperatingSystem: "linux", - Architecture: "amd64", - Directory: "/home/coder", - Auth: &sdkproto.Agent_Token{ - Token: "test-token", - }, - }, - }, - }, - }, + Resources: []*sdkproto.Resource{}, }, }, }) From 0b6d0837d94653a6604aecac5bfe4bed799c4b5c Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Tue, 31 May 2022 16:51:28 +0000 Subject: [PATCH 10/10] Rename template version plan to template version dry run --- cli/create.go | 20 +- cli/create_test.go | 6 +- coderd/coderd.go | 12 +- coderd/coderd_test.go | 16 +- coderd/database/dump.sql | 2 +- ...099_provisioner_job_type_dry_run.down.sql} | 2 +- ...000099_provisioner_job_type_dry_run.up.sql | 2 + .../000099_provisioner_job_type_plan.up.sql | 2 - coderd/database/models.go | 2 +- coderd/provisionerdaemons.go | 22 +- coderd/templateversions.go | 41 +- coderd/templateversions_test.go | 48 +- codersdk/templateversions.go | 51 ++- provisionerd/proto/provisionerd.pb.go | 427 +++++++++--------- provisionerd/proto/provisionerd.proto | 12 +- provisionerd/provisionerd.go | 26 +- provisionerd/provisionerd_test.go | 6 +- site/src/api/typesGenerated.ts | 2 +- 18 files changed, 351 insertions(+), 348 deletions(-) rename coderd/database/migrations/{000099_provisioner_job_type_plan.down.sql => 000099_provisioner_job_type_dry_run.down.sql} (82%) create mode 100644 coderd/database/migrations/000099_provisioner_job_type_dry_run.up.sql delete mode 100644 coderd/database/migrations/000099_provisioner_job_type_plan.up.sql diff --git a/cli/create.go b/cli/create.go index ce51b7db91803..fedfb071b47e6 100644 --- a/cli/create.go +++ b/cli/create.go @@ -170,38 +170,38 @@ func create() *cobra.Command { } _, _ = fmt.Fprintln(cmd.OutOrStdout()) - // Run a plan with the given parameters to check correctness + // Run a dry-run with the given parameters to check correctness after := time.Now() - planJob, err := client.CreateTemplateVersionPlan(cmd.Context(), templateVersion.ID, codersdk.CreateTemplateVersionPlanRequest{ + dryRun, err := client.CreateTemplateVersionDryRun(cmd.Context(), templateVersion.ID, codersdk.CreateTemplateVersionDryRunRequest{ WorkspaceName: workspaceName, ParameterValues: parameters, }) if err != nil { - return xerrors.Errorf("begin workspace plan: %w", err) + return xerrors.Errorf("begin workspace dry-run: %w", err) } _, _ = fmt.Fprintln(cmd.OutOrStdout(), "Planning workspace...") err = cliui.ProvisionerJob(cmd.Context(), cmd.OutOrStdout(), cliui.ProvisionerJobOptions{ Fetch: func() (codersdk.ProvisionerJob, error) { - return client.TemplateVersionPlan(cmd.Context(), templateVersion.ID, planJob.ID) + return client.TemplateVersionDryRun(cmd.Context(), templateVersion.ID, dryRun.ID) }, Cancel: func() error { - return client.CancelTemplateVersionPlan(cmd.Context(), templateVersion.ID, planJob.ID) + return client.CancelTemplateVersionDryRun(cmd.Context(), templateVersion.ID, dryRun.ID) }, Logs: func() (<-chan codersdk.ProvisionerJobLog, error) { - return client.TemplateVersionPlanLogsAfter(cmd.Context(), templateVersion.ID, planJob.ID, after) + return client.TemplateVersionDryRunLogsAfter(cmd.Context(), templateVersion.ID, dryRun.ID, after) }, - // Don't show log output for the plan unless there's an error. + // Don't show log output for the dry-run unless there's an error. Silent: true, }) if err != nil { // TODO (Dean): reprompt for parameter values if we deem it to // be a validation error - return xerrors.Errorf("plan workspace: %w", err) + return xerrors.Errorf("dry-run workspace: %w", err) } - resources, err := client.TemplateVersionPlanResources(cmd.Context(), templateVersion.ID, planJob.ID) + resources, err := client.TemplateVersionDryRunResources(cmd.Context(), templateVersion.ID, dryRun.ID) if err != nil { - return xerrors.Errorf("get workspace plan resources: %w", err) + return xerrors.Errorf("get workspace dry-run resources: %w", err) } err = cliui.WorkspaceResources(cmd.OutOrStdout(), resources, cliui.WorkspaceResourcesOptions{ diff --git a/cli/create_test.go b/cli/create_test.go index 607835043f583..9675a68fc3139 100644 --- a/cli/create_test.go +++ b/cli/create_test.go @@ -284,7 +284,7 @@ func TestCreate(t *testing.T) { removeTmpDirUntilSuccess(t, tempDir) }) - t.Run("FailedPlan", func(t *testing.T) { + t.Run("FailedDryRun", func(t *testing.T) { t.Parallel() client, api := coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerD: true}) user := coderdtest.CreateFirstUser(t, client) @@ -302,7 +302,7 @@ func TestCreate(t *testing.T) { }) // The template import job should end up failed, but we need it to be - // succeeded so the plan can begin. + // succeeded so the dry-run can begin. version = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) require.Equal(t, codersdk.ProvisionerJobFailed, version.Job.Status, "job is not failed") err := api.Database.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{ @@ -325,7 +325,7 @@ func TestCreate(t *testing.T) { err = cmd.Execute() require.Error(t, err) - require.ErrorContains(t, err, "plan workspace") + require.ErrorContains(t, err, "dry-run workspace") }) } diff --git a/coderd/coderd.go b/coderd/coderd.go index ab40b2b6cb061..999ec86a146bf 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -207,12 +207,12 @@ func New(options *Options) *API { r.Get("/parameters", api.templateVersionParameters) r.Get("/resources", api.templateVersionResources) r.Get("/logs", api.templateVersionLogs) - r.Route("/plan", func(r chi.Router) { - r.Post("/", api.createTemplateVersionPlan) - r.Get("/{jobID}", api.templateVersionPlan) - r.Get("/{jobID}/resources", api.templateVersionPlanResources) - r.Get("/{jobID}/logs", api.templateVersionPlanLogs) - r.Patch("/{jobID}/cancel", api.templateVersionPlanCancel) + r.Route("/dry-run", func(r chi.Router) { + r.Post("/", api.postTemplateVersionDryRun) + r.Get("/{jobID}", api.templateVersionDryRun) + r.Get("/{jobID}/resources", api.templateVersionDryRunResources) + r.Get("/{jobID}/logs", api.templateVersionDryRunLogs) + r.Patch("/{jobID}/cancel", api.patchTemplateVersionDryRunCancel) }) }) r.Route("/users", func(r chi.Router) { diff --git a/coderd/coderd_test.go b/coderd/coderd_test.go index 79423c50d0b4c..c9a5924d1a2a2 100644 --- a/coderd/coderd_test.go +++ b/coderd/coderd_test.go @@ -96,10 +96,10 @@ func TestAuthorizeAllEndpoints(t *testing.T) { require.NoError(t, err, "upload file") workspaceResources, err := client.WorkspaceResourcesByBuild(ctx, workspace.LatestBuild.ID) require.NoError(t, err, "workspace resources") - templateVersionPlanJob, err := client.CreateTemplateVersionPlan(ctx, version.ID, codersdk.CreateTemplateVersionPlanRequest{ + templateVersionDryRun, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ ParameterValues: []codersdk.CreateParameterRequest{}, }) - require.NoError(t, err, "template version plan") + require.NoError(t, err, "template version dry-run") // Always fail auth from this point forward authorizer.AlwaysReturn = rbac.ForbiddenWithInternal(xerrors.New("fake implementation"), nil, nil) @@ -268,24 +268,24 @@ func TestAuthorizeAllEndpoints(t *testing.T) { AssertAction: rbac.ActionRead, AssertObject: rbac.ResourceTemplate.InOrg(template.OrganizationID).WithID(template.ID.String()), }, - "POST:/api/v2/templateversions/{templateversion}/plan": { + "POST:/api/v2/templateversions/{templateversion}/dry-run": { // The first check is to read the template AssertAction: rbac.ActionRead, AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), }, - "GET:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}": { + "GET:/api/v2/templateversions/{templateversion}/dry-run/{templateversiondryrun}": { AssertAction: rbac.ActionRead, AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), }, - "GET:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}/resources": { + "GET:/api/v2/templateversions/{templateversion}/dry-run/{templateversiondryrun}/resources": { AssertAction: rbac.ActionRead, AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), }, - "GET:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}/logs": { + "GET:/api/v2/templateversions/{templateversion}/dry-run/{templateversiondryrun}/logs": { AssertAction: rbac.ActionRead, AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), }, - "PATCH:/api/v2/templateversions/{templateversion}/plan/{templateversionplan}/cancel": { + "PATCH:/api/v2/templateversions/{templateversion}/dry-run/{templateversiondryrun}/cancel": { AssertAction: rbac.ActionRead, AssertObject: rbac.ResourceTemplate.InOrg(version.OrganizationID).WithID(template.ID.String()), }, @@ -351,7 +351,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) { route = strings.ReplaceAll(route, "{hash}", file.Hash) route = strings.ReplaceAll(route, "{workspaceresource}", workspaceResources[0].ID.String()) route = strings.ReplaceAll(route, "{templateversion}", version.ID.String()) - route = strings.ReplaceAll(route, "{templateversionplan}", templateVersionPlanJob.ID.String()) + route = strings.ReplaceAll(route, "{templateversiondryrun}", templateVersionDryRun.ID.String()) route = strings.ReplaceAll(route, "{templatename}", template.Name) // Only checking org scoped params here route = strings.ReplaceAll(route, "{scope}", string(organizationParam.Scope)) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index d4beb3b18b4af..4e82e2feed0b5 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -51,7 +51,7 @@ CREATE TYPE parameter_type_system AS ENUM ( CREATE TYPE provisioner_job_type AS ENUM ( 'template_version_import', 'workspace_build', - 'template_version_plan' + 'template_version_dry_run' ); CREATE TYPE provisioner_storage_method AS ENUM ( diff --git a/coderd/database/migrations/000099_provisioner_job_type_plan.down.sql b/coderd/database/migrations/000099_provisioner_job_type_dry_run.down.sql similarity index 82% rename from coderd/database/migrations/000099_provisioner_job_type_plan.down.sql rename to coderd/database/migrations/000099_provisioner_job_type_dry_run.down.sql index 32312535b28c4..75b99db54da22 100644 --- a/coderd/database/migrations/000099_provisioner_job_type_plan.down.sql +++ b/coderd/database/migrations/000099_provisioner_job_type_dry_run.down.sql @@ -5,5 +5,5 @@ DELETE FROM provisioner_jobs WHERE - type = 'template_version_plan' + type = 'template_version_dry_run' ; diff --git a/coderd/database/migrations/000099_provisioner_job_type_dry_run.up.sql b/coderd/database/migrations/000099_provisioner_job_type_dry_run.up.sql new file mode 100644 index 0000000000000..b843aeb3621cb --- /dev/null +++ b/coderd/database/migrations/000099_provisioner_job_type_dry_run.up.sql @@ -0,0 +1,2 @@ +ALTER TYPE provisioner_job_type +ADD VALUE IF NOT EXISTS 'template_version_dry_run'; diff --git a/coderd/database/migrations/000099_provisioner_job_type_plan.up.sql b/coderd/database/migrations/000099_provisioner_job_type_plan.up.sql deleted file mode 100644 index 3c19977c59354..0000000000000 --- a/coderd/database/migrations/000099_provisioner_job_type_plan.up.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TYPE provisioner_job_type -ADD VALUE IF NOT EXISTS 'template_version_plan'; diff --git a/coderd/database/models.go b/coderd/database/models.go index a8da9f78eed21..2e7b027355b73 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -179,7 +179,7 @@ type ProvisionerJobType string const ( ProvisionerJobTypeTemplateVersionImport ProvisionerJobType = "template_version_import" ProvisionerJobTypeWorkspaceBuild ProvisionerJobType = "workspace_build" - ProvisionerJobTypeTemplateVersionPlan ProvisionerJobType = "template_version_plan" + ProvisionerJobTypeTemplateVersionDryRun ProvisionerJobType = "template_version_dry_run" ) func (e *ProvisionerJobType) Scan(src interface{}) error { diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index 7220ebdc26984..a8f5b4c4c704a 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -110,8 +110,8 @@ type workspaceProvisionJob struct { DryRun bool `json:"dry_run"` } -// The input for a "template_version_plan" job. -type templateVersionPlanJob struct { +// The input for a "template_version_dry_run" job. +type templateVersionDryRunJob struct { TemplateVersionID uuid.UUID `json:"template_version_id"` WorkspaceName string `json:"workspace_name"` ParameterValues []database.ParameterValue `json:"parameter_values"` @@ -253,8 +253,8 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty }, }, } - case database.ProvisionerJobTypeTemplateVersionPlan: - var input templateVersionPlanJob + case database.ProvisionerJobTypeTemplateVersionDryRun: + var input templateVersionDryRunJob err = json.Unmarshal(job.Input, &input) if err != nil { return nil, failJob(fmt.Sprintf("unmarshal job input %q: %s", job.Input, err)) @@ -265,7 +265,7 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty return nil, failJob(fmt.Sprintf("get template version: %s", err)) } - // Compute parameters for the plan to consume. + // Compute parameters for the dry-run to consume. parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{ TemplateImportJobID: templateVersion.JobID, OrganizationID: job.OrganizationID, @@ -284,8 +284,8 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty return nil, failJob(fmt.Sprintf("convert computed parameters to protobuf: %s", err)) } - protoJob.Type = &proto.AcquiredJob_TemplatePlan_{ - TemplatePlan: &proto.AcquiredJob_TemplatePlan{ + protoJob.Type = &proto.AcquiredJob_TemplateDryRun_{ + TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{ ParameterValues: protoParameters, Metadata: &sdkproto.Provision_Metadata{ CoderUrl: server.AccessURL.String(), @@ -647,9 +647,9 @@ func (server *provisionerdServer) CompleteJob(ctx context.Context, completed *pr if err != nil { return nil, xerrors.Errorf("complete job: %w", err) } - case *proto.CompletedJob_TemplatePlan_: - for _, resource := range jobType.TemplatePlan.Resources { - server.Logger.Info(ctx, "inserting template plan job resource", + case *proto.CompletedJob_TemplateDryRun_: + for _, resource := range jobType.TemplateDryRun.Resources { + server.Logger.Info(ctx, "inserting template dry-run job resource", slog.F("job_id", job.ID.String()), slog.F("resource_name", resource.Name), slog.F("resource_type", resource.Type)) @@ -671,7 +671,7 @@ func (server *provisionerdServer) CompleteJob(ctx context.Context, completed *pr if err != nil { return nil, xerrors.Errorf("update provisioner job: %w", err) } - server.Logger.Debug(ctx, "marked template plan job as completed", slog.F("job_id", jobID)) + server.Logger.Debug(ctx, "marked template dry-run job as completed", slog.F("job_id", jobID)) if err != nil { return nil, xerrors.Errorf("complete job: %w", err) } diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 23c12e60b1538..43306bc7ffd6d 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -164,20 +164,20 @@ func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Reques httpapi.Write(rw, http.StatusOK, values) } -func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Request) { +func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Request) { apiKey := httpmw.APIKey(r) templateVersion := httpmw.TemplateVersionParam(r) if !api.Authorize(rw, r, rbac.ActionRead, templateVersion) { return } - // We use the workspace RBAC check since we don't want to allow plans if the - // user can't create workspaces. + // We use the workspace RBAC check since we don't want to allow dry runs if + // the user can't create workspaces. if !api.Authorize(rw, r, rbac.ActionCreate, rbac.ResourceWorkspace.InOrg(templateVersion.OrganizationID).WithOwner(apiKey.UserID.String())) { return } - var req codersdk.CreateTemplateVersionPlanRequest + var req codersdk.CreateTemplateVersionDryRunRequest if !httpapi.Read(rw, r, &req) { return } @@ -210,8 +210,9 @@ func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Reques } } - // Marshal template version plan job with the parameters from the request. - input, err := json.Marshal(templateVersionPlanJob{ + // Marshal template version dry-run job with the parameters from the + // request. + input, err := json.Marshal(templateVersionDryRunJob{ TemplateVersionID: templateVersion.ID, WorkspaceName: req.WorkspaceName, ParameterValues: parameterValues, @@ -223,7 +224,7 @@ func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Reques return } - // Create a plan job + // Create a dry-run job jobID := uuid.New() provisionerJob, err := api.Database.InsertProvisionerJob(r.Context(), database.InsertProvisionerJobParams{ ID: jobID, @@ -234,7 +235,7 @@ func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Reques Provisioner: job.Provisioner, StorageMethod: job.StorageMethod, StorageSource: job.StorageSource, - Type: database.ProvisionerJobTypeTemplateVersionPlan, + Type: database.ProvisionerJobTypeTemplateVersionDryRun, Input: input, }) if err != nil { @@ -247,8 +248,8 @@ func (api *API) createTemplateVersionPlan(rw http.ResponseWriter, r *http.Reques httpapi.Write(rw, http.StatusCreated, convertProvisionerJob(provisionerJob)) } -func (api *API) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { - job, ok := api.fetchTemplateVersionPlanJob(rw, r) +func (api *API) templateVersionDryRun(rw http.ResponseWriter, r *http.Request) { + job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { return } @@ -256,8 +257,8 @@ func (api *API) templateVersionPlan(rw http.ResponseWriter, r *http.Request) { httpapi.Write(rw, http.StatusOK, convertProvisionerJob(job)) } -func (api *API) templateVersionPlanResources(rw http.ResponseWriter, r *http.Request) { - job, ok := api.fetchTemplateVersionPlanJob(rw, r) +func (api *API) templateVersionDryRunResources(rw http.ResponseWriter, r *http.Request) { + job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { return } @@ -265,8 +266,8 @@ func (api *API) templateVersionPlanResources(rw http.ResponseWriter, r *http.Req api.provisionerJobResources(rw, r, job) } -func (api *API) templateVersionPlanLogs(rw http.ResponseWriter, r *http.Request) { - job, ok := api.fetchTemplateVersionPlanJob(rw, r) +func (api *API) templateVersionDryRunLogs(rw http.ResponseWriter, r *http.Request) { + job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { return } @@ -274,10 +275,10 @@ func (api *API) templateVersionPlanLogs(rw http.ResponseWriter, r *http.Request) api.provisionerJobLogs(rw, r, job) } -func (api *API) templateVersionPlanCancel(rw http.ResponseWriter, r *http.Request) { +func (api *API) patchTemplateVersionDryRunCancel(rw http.ResponseWriter, r *http.Request) { templateVersion := httpmw.TemplateVersionParam(r) - job, ok := api.fetchTemplateVersionPlanJob(rw, r) + job, ok := api.fetchTemplateVersionDryRunJob(rw, r) if !ok { return } @@ -318,7 +319,7 @@ func (api *API) templateVersionPlanCancel(rw http.ResponseWriter, r *http.Reques }) } -func (api *API) fetchTemplateVersionPlanJob(rw http.ResponseWriter, r *http.Request) (database.ProvisionerJob, bool) { +func (api *API) fetchTemplateVersionDryRunJob(rw http.ResponseWriter, r *http.Request) (database.ProvisionerJob, bool) { var ( templateVersion = httpmw.TemplateVersionParam(r) jobID = chi.URLParam(r, "jobID") @@ -346,18 +347,18 @@ func (api *API) fetchTemplateVersionPlanJob(rw http.ResponseWriter, r *http.Requ }) return database.ProvisionerJob{}, false } - if job.Type != database.ProvisionerJobTypeTemplateVersionPlan { + if job.Type != database.ProvisionerJobTypeTemplateVersionDryRun { httpapi.Forbidden(rw) return database.ProvisionerJob{}, false } - // Do a workspace resource check since it's basically a workspace plan. + // Do a workspace resource check since it's basically a workspace dry-run . if !api.Authorize(rw, r, rbac.ActionRead, rbac.ResourceWorkspace.InOrg(templateVersion.OrganizationID).WithOwner(job.InitiatorID.String())) { return database.ProvisionerJob{}, false } // Verify that the template version is the one used in the request. - var input templateVersionPlanJob + var input templateVersionDryRunJob err = json.Unmarshal(job.Input, &input) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index bade2f4fa13c7..359acf391b223 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -450,7 +450,7 @@ func TestPatchActiveTemplateVersion(t *testing.T) { }) } -func TestTemplateVersionPlan(t *testing.T) { +func TestTemplateVersionDryRun(t *testing.T) { t.Parallel() t.Run("OK", func(t *testing.T) { @@ -484,20 +484,20 @@ func TestTemplateVersionPlan(t *testing.T) { }) _ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID) - // Create template version plan + // Create template version dry-run after := time.Now() - job, err := client.CreateTemplateVersionPlan(ctx, version.ID, codersdk.CreateTemplateVersionPlanRequest{ + job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ ParameterValues: []codersdk.CreateParameterRequest{}, }) require.NoError(t, err) - // Fetch template version plan - newJob, err := client.TemplateVersionPlan(ctx, version.ID, job.ID) + // Fetch template version dry-run + newJob, err := client.TemplateVersionDryRun(ctx, version.ID, job.ID) require.NoError(t, err) require.Equal(t, job.ID, newJob.ID) // Stream logs - logs, err := client.TemplateVersionPlanLogsAfter(ctx, version.ID, job.ID, after) + logs, err := client.TemplateVersionDryRunLogsAfter(ctx, version.ID, job.ID, after) require.NoError(t, err) logsDone := make(chan struct{}) @@ -513,7 +513,7 @@ func TestTemplateVersionPlan(t *testing.T) { // Wait for the job to complete require.Eventually(t, func() bool { - job, err := client.TemplateVersionPlan(ctx, version.ID, job.ID) + job, err := client.TemplateVersionDryRun(ctx, version.ID, job.ID) assert.NoError(t, err) return job.Status == codersdk.ProvisionerJobSucceeded @@ -521,7 +521,7 @@ func TestTemplateVersionPlan(t *testing.T) { <-logsDone - resources, err := client.TemplateVersionPlanResources(ctx, version.ID, job.ID) + resources, err := client.TemplateVersionDryRunResources(ctx, version.ID, job.ID) require.NoError(t, err) require.Len(t, resources, 1) require.Equal(t, resource.Name, resources[0].Name) @@ -542,7 +542,7 @@ func TestTemplateVersionPlan(t *testing.T) { }}, }) - _, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + _, err := client.CreateTemplateVersionDryRun(context.Background(), version.ID, codersdk.CreateTemplateVersionDryRunRequest{ ParameterValues: []codersdk.CreateParameterRequest{}, }) var apiErr *codersdk.Error @@ -567,25 +567,25 @@ func TestTemplateVersionPlan(t *testing.T) { }) forceCompleteTemplateVersionJob(t, api.Database, client, version) - // Create the plan - job, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + // Create the dry-run + job, err := client.CreateTemplateVersionDryRun(context.Background(), version.ID, codersdk.CreateTemplateVersionDryRunRequest{ ParameterValues: []codersdk.CreateParameterRequest{}, }) require.NoError(t, err) require.Eventually(t, func() bool { - job, err := client.TemplateVersionPlan(context.Background(), version.ID, job.ID) + job, err := client.TemplateVersionDryRun(context.Background(), version.ID, job.ID) assert.NoError(t, err) t.Logf("Status: %s", job.Status) return job.Status == codersdk.ProvisionerJobRunning }, 5*time.Second, 25*time.Millisecond) - err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + err = client.CancelTemplateVersionDryRun(context.Background(), version.ID, job.ID) require.NoError(t, err) require.Eventually(t, func() bool { - job, err := client.TemplateVersionPlan(context.Background(), version.ID, job.ID) + job, err := client.TemplateVersionDryRun(context.Background(), version.ID, job.ID) assert.NoError(t, err) t.Logf("Status: %s", job.Status) @@ -600,21 +600,21 @@ func TestTemplateVersionPlan(t *testing.T) { version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) - // Create the plan - job, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + // Create the dry-run + job, err := client.CreateTemplateVersionDryRun(context.Background(), version.ID, codersdk.CreateTemplateVersionDryRunRequest{ ParameterValues: []codersdk.CreateParameterRequest{}, }) require.NoError(t, err) require.Eventually(t, func() bool { - job, err := client.TemplateVersionPlan(context.Background(), version.ID, job.ID) + job, err := client.TemplateVersionDryRun(context.Background(), version.ID, job.ID) assert.NoError(t, err) t.Logf("Status: %s", job.Status) return job.Status == codersdk.ProvisionerJobSucceeded }, 5*time.Second, 25*time.Millisecond) - err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + err = client.CancelTemplateVersionDryRun(context.Background(), version.ID, job.ID) var apiErr *codersdk.Error require.ErrorAs(t, err, &apiErr) require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode()) @@ -634,16 +634,16 @@ func TestTemplateVersionPlan(t *testing.T) { }) forceCompleteTemplateVersionJob(t, api.Database, client, version) - // Create the plan - job, err := client.CreateTemplateVersionPlan(context.Background(), version.ID, codersdk.CreateTemplateVersionPlanRequest{ + // Create the dry-run + job, err := client.CreateTemplateVersionDryRun(context.Background(), version.ID, codersdk.CreateTemplateVersionDryRunRequest{ ParameterValues: []codersdk.CreateParameterRequest{}, }) require.NoError(t, err) - err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + err = client.CancelTemplateVersionDryRun(context.Background(), version.ID, job.ID) require.NoError(t, err) - err = client.CancelTemplateVersionPlan(context.Background(), version.ID, job.ID) + err = client.CancelTemplateVersionDryRun(context.Background(), version.ID, job.ID) var apiErr *codersdk.Error require.ErrorAs(t, err, &apiErr) require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode()) @@ -746,8 +746,8 @@ func TestPaginatedTemplateVersions(t *testing.T) { func forceCompleteTemplateVersionJob(t *testing.T, db database.Store, client *codersdk.Client, version codersdk.TemplateVersion) { t.Helper() - // HACK: we need the template version job to be finished so the plan job can - // be created. We do this by canceling the job and then marking it as + // HACK: we need the template version job to be finished so the dry-run job + // can be created. We do this by canceling the job and then marking it as // successful. err := client.CancelTemplateVersion(context.Background(), version.ID) require.NoError(t, err) diff --git a/codersdk/templateversions.go b/codersdk/templateversions.go index e29f561380de9..afe8c32552eef 100644 --- a/codersdk/templateversions.go +++ b/codersdk/templateversions.go @@ -116,17 +116,17 @@ func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/templateversions/%s/logs", version), after) } -// CreateTemplateVersionPlanRequest defines the request parameters for -// CreateTemplateVersionPlan. -type CreateTemplateVersionPlanRequest struct { +// CreateTemplateVersionDryRunRequest defines the request parameters for +// CreateTemplateVersionDryRun. +type CreateTemplateVersionDryRunRequest struct { WorkspaceName string ParameterValues []CreateParameterRequest } -// CreateTemplateVersionPlan begins a dry-run provisioner job against the given -// template version with the given parameter values. -func (c *Client) CreateTemplateVersionPlan(ctx context.Context, version uuid.UUID, req CreateTemplateVersionPlanRequest) (ProvisionerJob, error) { - res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/templateversions/%s/plan", version), req) +// CreateTemplateVersionDryRun begins a dry-run provisioner job against the +// given template version with the given parameter values. +func (c *Client) CreateTemplateVersionDryRun(ctx context.Context, version uuid.UUID, req CreateTemplateVersionDryRunRequest) (ProvisionerJob, error) { + res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/templateversions/%s/dry-run", version), req) if err != nil { return ProvisionerJob{}, err } @@ -139,9 +139,10 @@ func (c *Client) CreateTemplateVersionPlan(ctx context.Context, version uuid.UUI return job, json.NewDecoder(res.Body).Decode(&job) } -// TemplateVersionPlan returns the current state of a template version plan job. -func (c *Client) TemplateVersionPlan(ctx context.Context, version, job uuid.UUID) (ProvisionerJob, error) { - res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s", version, job), nil) +// TemplateVersionDryRun returns the current state of a template version dry-run +// job. +func (c *Client) TemplateVersionDryRun(ctx context.Context, version, job uuid.UUID) (ProvisionerJob, error) { + res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/dry-run/%s", version, job), nil) if err != nil { return ProvisionerJob{}, err } @@ -154,10 +155,10 @@ func (c *Client) TemplateVersionPlan(ctx context.Context, version, job uuid.UUID return j, json.NewDecoder(res.Body).Decode(&j) } -// TemplateVersionPlanResources returns the resources of a finished template -// version plan job. -func (c *Client) TemplateVersionPlanResources(ctx context.Context, version, job uuid.UUID) ([]WorkspaceResource, error) { - res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/resources", version, job), nil) +// TemplateVersionDryRunResources returns the resources of a finished template +// version dry-run job. +func (c *Client) TemplateVersionDryRunResources(ctx context.Context, version, job uuid.UUID) ([]WorkspaceResource, error) { + res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/dry-run/%s/resources", version, job), nil) if err != nil { return nil, err } @@ -170,21 +171,21 @@ func (c *Client) TemplateVersionPlanResources(ctx context.Context, version, job return resources, json.NewDecoder(res.Body).Decode(&resources) } -// TemplateVersionPlanLogsBefore returns logs for a template version plan that -// occurred before a specific time. -func (c *Client) TemplateVersionPlanLogsBefore(ctx context.Context, version, job uuid.UUID, before time.Time) ([]ProvisionerJobLog, error) { - return c.provisionerJobLogsBefore(ctx, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/logs", version, job), before) +// TemplateVersionDryRunLogsBefore returns logs for a template version dry-run +// that occurred before a specific time. +func (c *Client) TemplateVersionDryRunLogsBefore(ctx context.Context, version, job uuid.UUID, before time.Time) ([]ProvisionerJobLog, error) { + return c.provisionerJobLogsBefore(ctx, fmt.Sprintf("/api/v2/templateversions/%s/dry-run/%s/logs", version, job), before) } -// TemplateVersionPlanLogsAfter streams logs for a template version plan that -// occurred after a specific time. -func (c *Client) TemplateVersionPlanLogsAfter(ctx context.Context, version, job uuid.UUID, after time.Time) (<-chan ProvisionerJobLog, error) { - return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/logs", version, job), after) +// TemplateVersionDryRunLogsAfter streams logs for a template version dry-run +// that occurred after a specific time. +func (c *Client) TemplateVersionDryRunLogsAfter(ctx context.Context, version, job uuid.UUID, after time.Time) (<-chan ProvisionerJobLog, error) { + return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/templateversions/%s/dry-run/%s/logs", version, job), after) } -// CancelTemplateVersionPlan marks a template version plan job as canceled. -func (c *Client) CancelTemplateVersionPlan(ctx context.Context, version, job uuid.UUID) error { - res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templateversions/%s/plan/%s/cancel", version, job), nil) +// CancelTemplateVersionDryRun marks a template version dry-run job as canceled. +func (c *Client) CancelTemplateVersionDryRun(ctx context.Context, version, job uuid.UUID) error { + res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templateversions/%s/dry-run/%s/cancel", version, job), nil) if err != nil { return err } diff --git a/provisionerd/proto/provisionerd.pb.go b/provisionerd/proto/provisionerd.pb.go index cae934f9246bc..ccb028111f9ba 100644 --- a/provisionerd/proto/provisionerd.pb.go +++ b/provisionerd/proto/provisionerd.pb.go @@ -121,7 +121,7 @@ type AcquiredJob struct { // Types that are assignable to Type: // *AcquiredJob_WorkspaceBuild_ // *AcquiredJob_TemplateImport_ - // *AcquiredJob_TemplatePlan_ + // *AcquiredJob_TemplateDryRun_ Type isAcquiredJob_Type `protobuf_oneof:"type"` } @@ -213,9 +213,9 @@ func (x *AcquiredJob) GetTemplateImport() *AcquiredJob_TemplateImport { return nil } -func (x *AcquiredJob) GetTemplatePlan() *AcquiredJob_TemplatePlan { - if x, ok := x.GetType().(*AcquiredJob_TemplatePlan_); ok { - return x.TemplatePlan +func (x *AcquiredJob) GetTemplateDryRun() *AcquiredJob_TemplateDryRun { + if x, ok := x.GetType().(*AcquiredJob_TemplateDryRun_); ok { + return x.TemplateDryRun } return nil } @@ -232,15 +232,15 @@ type AcquiredJob_TemplateImport_ struct { TemplateImport *AcquiredJob_TemplateImport `protobuf:"bytes,7,opt,name=template_import,json=templateImport,proto3,oneof"` } -type AcquiredJob_TemplatePlan_ struct { - TemplatePlan *AcquiredJob_TemplatePlan `protobuf:"bytes,8,opt,name=template_plan,json=templatePlan,proto3,oneof"` +type AcquiredJob_TemplateDryRun_ struct { + TemplateDryRun *AcquiredJob_TemplateDryRun `protobuf:"bytes,8,opt,name=template_dry_run,json=templateDryRun,proto3,oneof"` } func (*AcquiredJob_WorkspaceBuild_) isAcquiredJob_Type() {} func (*AcquiredJob_TemplateImport_) isAcquiredJob_Type() {} -func (*AcquiredJob_TemplatePlan_) isAcquiredJob_Type() {} +func (*AcquiredJob_TemplateDryRun_) isAcquiredJob_Type() {} type FailedJob struct { state protoimpl.MessageState @@ -252,7 +252,7 @@ type FailedJob struct { // Types that are assignable to Type: // *FailedJob_WorkspaceBuild_ // *FailedJob_TemplateImport_ - // *FailedJob_TemplatePlan_ + // *FailedJob_TemplateDryRun_ Type isFailedJob_Type `protobuf_oneof:"type"` } @@ -323,9 +323,9 @@ func (x *FailedJob) GetTemplateImport() *FailedJob_TemplateImport { return nil } -func (x *FailedJob) GetTemplatePlan() *FailedJob_TemplatePlan { - if x, ok := x.GetType().(*FailedJob_TemplatePlan_); ok { - return x.TemplatePlan +func (x *FailedJob) GetTemplateDryRun() *FailedJob_TemplateDryRun { + if x, ok := x.GetType().(*FailedJob_TemplateDryRun_); ok { + return x.TemplateDryRun } return nil } @@ -342,15 +342,15 @@ type FailedJob_TemplateImport_ struct { TemplateImport *FailedJob_TemplateImport `protobuf:"bytes,4,opt,name=template_import,json=templateImport,proto3,oneof"` } -type FailedJob_TemplatePlan_ struct { - TemplatePlan *FailedJob_TemplatePlan `protobuf:"bytes,5,opt,name=template_plan,json=templatePlan,proto3,oneof"` +type FailedJob_TemplateDryRun_ struct { + TemplateDryRun *FailedJob_TemplateDryRun `protobuf:"bytes,5,opt,name=template_dry_run,json=templateDryRun,proto3,oneof"` } func (*FailedJob_WorkspaceBuild_) isFailedJob_Type() {} func (*FailedJob_TemplateImport_) isFailedJob_Type() {} -func (*FailedJob_TemplatePlan_) isFailedJob_Type() {} +func (*FailedJob_TemplateDryRun_) isFailedJob_Type() {} // CompletedJob is sent when the provisioner daemon completes a job. type CompletedJob struct { @@ -362,7 +362,7 @@ type CompletedJob struct { // Types that are assignable to Type: // *CompletedJob_WorkspaceBuild_ // *CompletedJob_TemplateImport_ - // *CompletedJob_TemplatePlan_ + // *CompletedJob_TemplateDryRun_ Type isCompletedJob_Type `protobuf_oneof:"type"` } @@ -426,9 +426,9 @@ func (x *CompletedJob) GetTemplateImport() *CompletedJob_TemplateImport { return nil } -func (x *CompletedJob) GetTemplatePlan() *CompletedJob_TemplatePlan { - if x, ok := x.GetType().(*CompletedJob_TemplatePlan_); ok { - return x.TemplatePlan +func (x *CompletedJob) GetTemplateDryRun() *CompletedJob_TemplateDryRun { + if x, ok := x.GetType().(*CompletedJob_TemplateDryRun_); ok { + return x.TemplateDryRun } return nil } @@ -445,15 +445,15 @@ type CompletedJob_TemplateImport_ struct { TemplateImport *CompletedJob_TemplateImport `protobuf:"bytes,3,opt,name=template_import,json=templateImport,proto3,oneof"` } -type CompletedJob_TemplatePlan_ struct { - TemplatePlan *CompletedJob_TemplatePlan `protobuf:"bytes,4,opt,name=template_plan,json=templatePlan,proto3,oneof"` +type CompletedJob_TemplateDryRun_ struct { + TemplateDryRun *CompletedJob_TemplateDryRun `protobuf:"bytes,4,opt,name=template_dry_run,json=templateDryRun,proto3,oneof"` } func (*CompletedJob_WorkspaceBuild_) isCompletedJob_Type() {} func (*CompletedJob_TemplateImport_) isCompletedJob_Type() {} -func (*CompletedJob_TemplatePlan_) isCompletedJob_Type() {} +func (*CompletedJob_TemplateDryRun_) isCompletedJob_Type() {} // Log represents output from a job. type Log struct { @@ -790,7 +790,7 @@ func (x *AcquiredJob_TemplateImport) GetMetadata() *proto.Provision_Metadata { return nil } -type AcquiredJob_TemplatePlan struct { +type AcquiredJob_TemplateDryRun struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -799,8 +799,8 @@ type AcquiredJob_TemplatePlan struct { Metadata *proto.Provision_Metadata `protobuf:"bytes,2,opt,name=metadata,proto3" json:"metadata,omitempty"` } -func (x *AcquiredJob_TemplatePlan) Reset() { - *x = AcquiredJob_TemplatePlan{} +func (x *AcquiredJob_TemplateDryRun) Reset() { + *x = AcquiredJob_TemplateDryRun{} if protoimpl.UnsafeEnabled { mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -808,13 +808,13 @@ func (x *AcquiredJob_TemplatePlan) Reset() { } } -func (x *AcquiredJob_TemplatePlan) String() string { +func (x *AcquiredJob_TemplateDryRun) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AcquiredJob_TemplatePlan) ProtoMessage() {} +func (*AcquiredJob_TemplateDryRun) ProtoMessage() {} -func (x *AcquiredJob_TemplatePlan) ProtoReflect() protoreflect.Message { +func (x *AcquiredJob_TemplateDryRun) ProtoReflect() protoreflect.Message { mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -826,19 +826,19 @@ func (x *AcquiredJob_TemplatePlan) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AcquiredJob_TemplatePlan.ProtoReflect.Descriptor instead. -func (*AcquiredJob_TemplatePlan) Descriptor() ([]byte, []int) { +// Deprecated: Use AcquiredJob_TemplateDryRun.ProtoReflect.Descriptor instead. +func (*AcquiredJob_TemplateDryRun) Descriptor() ([]byte, []int) { return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{1, 2} } -func (x *AcquiredJob_TemplatePlan) GetParameterValues() []*proto.ParameterValue { +func (x *AcquiredJob_TemplateDryRun) GetParameterValues() []*proto.ParameterValue { if x != nil { return x.ParameterValues } return nil } -func (x *AcquiredJob_TemplatePlan) GetMetadata() *proto.Provision_Metadata { +func (x *AcquiredJob_TemplateDryRun) GetMetadata() *proto.Provision_Metadata { if x != nil { return x.Metadata } @@ -930,14 +930,14 @@ func (*FailedJob_TemplateImport) Descriptor() ([]byte, []int) { return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{2, 1} } -type FailedJob_TemplatePlan struct { +type FailedJob_TemplateDryRun struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields } -func (x *FailedJob_TemplatePlan) Reset() { - *x = FailedJob_TemplatePlan{} +func (x *FailedJob_TemplateDryRun) Reset() { + *x = FailedJob_TemplateDryRun{} if protoimpl.UnsafeEnabled { mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -945,13 +945,13 @@ func (x *FailedJob_TemplatePlan) Reset() { } } -func (x *FailedJob_TemplatePlan) String() string { +func (x *FailedJob_TemplateDryRun) String() string { return protoimpl.X.MessageStringOf(x) } -func (*FailedJob_TemplatePlan) ProtoMessage() {} +func (*FailedJob_TemplateDryRun) ProtoMessage() {} -func (x *FailedJob_TemplatePlan) ProtoReflect() protoreflect.Message { +func (x *FailedJob_TemplateDryRun) ProtoReflect() protoreflect.Message { mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -963,8 +963,8 @@ func (x *FailedJob_TemplatePlan) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use FailedJob_TemplatePlan.ProtoReflect.Descriptor instead. -func (*FailedJob_TemplatePlan) Descriptor() ([]byte, []int) { +// Deprecated: Use FailedJob_TemplateDryRun.ProtoReflect.Descriptor instead. +func (*FailedJob_TemplateDryRun) Descriptor() ([]byte, []int) { return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{2, 2} } @@ -1078,7 +1078,7 @@ func (x *CompletedJob_TemplateImport) GetStopResources() []*proto.Resource { return nil } -type CompletedJob_TemplatePlan struct { +type CompletedJob_TemplateDryRun struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -1086,8 +1086,8 @@ type CompletedJob_TemplatePlan struct { Resources []*proto.Resource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"` } -func (x *CompletedJob_TemplatePlan) Reset() { - *x = CompletedJob_TemplatePlan{} +func (x *CompletedJob_TemplateDryRun) Reset() { + *x = CompletedJob_TemplateDryRun{} if protoimpl.UnsafeEnabled { mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1095,13 +1095,13 @@ func (x *CompletedJob_TemplatePlan) Reset() { } } -func (x *CompletedJob_TemplatePlan) String() string { +func (x *CompletedJob_TemplateDryRun) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CompletedJob_TemplatePlan) ProtoMessage() {} +func (*CompletedJob_TemplateDryRun) ProtoMessage() {} -func (x *CompletedJob_TemplatePlan) ProtoReflect() protoreflect.Message { +func (x *CompletedJob_TemplateDryRun) ProtoReflect() protoreflect.Message { mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -1113,12 +1113,12 @@ func (x *CompletedJob_TemplatePlan) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CompletedJob_TemplatePlan.ProtoReflect.Descriptor instead. -func (*CompletedJob_TemplatePlan) Descriptor() ([]byte, []int) { +// Deprecated: Use CompletedJob_TemplateDryRun.ProtoReflect.Descriptor instead. +func (*CompletedJob_TemplateDryRun) Descriptor() ([]byte, []int) { return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{3, 2} } -func (x *CompletedJob_TemplatePlan) GetResources() []*proto.Resource { +func (x *CompletedJob_TemplateDryRun) GetResources() []*proto.Resource { if x != nil { return x.Resources } @@ -1134,7 +1134,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, 0xa3, 0x07, 0x0a, 0x0b, 0x41, 0x63, 0x71, 0x75, 0x69, + 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xac, 0x07, 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, @@ -1156,160 +1156,161 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{ 0x0b, 0x32, 0x28, 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, 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, 0x4d, 0x0a, - 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 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, 0x2e, - 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x48, 0x00, 0x52, 0x0c, - 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x1a, 0x80, 0x02, 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, 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, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, - 0x4d, 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, 0x1a, 0x93, - 0x01, 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 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, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x02, 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, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xfd, 0x02, 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, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x54, 0x0a, + 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, + 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 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, 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, 0x80, 0x02, 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, 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, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x4d, 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, 0x1a, 0x95, 0x01, 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, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 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, 0x42, 0x06, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x86, 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, 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, 0x4b, 0x0a, - 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 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, 0x50, 0x6c, 0x61, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x74, 0x65, - 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x1a, 0x26, 0x0a, 0x0e, 0x57, 0x6f, + 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, 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, 0x0e, 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, - 0x50, 0x6c, 0x61, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xdc, 0x04, 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, 0x4e, 0x0a, 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x70, 0x6c, 0x61, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 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, 0x50, 0x6c, 0x61, 0x6e, - 0x48, 0x00, 0x52, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 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, 0x8e, 0x01, - 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, 0x1a, 0x43, - 0x0a, 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x33, - 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 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, 0xe5, + 0x04, 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, 0x8e, 0x01, 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, 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, 0xb3, - 0x01, 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, 0x16, 0x0a, 0x06, - 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, - 0x61, 0x64, 0x6d, 0x65, 0x22, 0x77, 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, 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, 0x98, 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, 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, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xb3, 0x01, 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, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x22, + 0x77, 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, 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, 0x98, + 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, 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 ( @@ -1337,13 +1338,13 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{ (*UpdateJobResponse)(nil), // 7: provisionerd.UpdateJobResponse (*AcquiredJob_WorkspaceBuild)(nil), // 8: provisionerd.AcquiredJob.WorkspaceBuild (*AcquiredJob_TemplateImport)(nil), // 9: provisionerd.AcquiredJob.TemplateImport - (*AcquiredJob_TemplatePlan)(nil), // 10: provisionerd.AcquiredJob.TemplatePlan + (*AcquiredJob_TemplateDryRun)(nil), // 10: provisionerd.AcquiredJob.TemplateDryRun (*FailedJob_WorkspaceBuild)(nil), // 11: provisionerd.FailedJob.WorkspaceBuild (*FailedJob_TemplateImport)(nil), // 12: provisionerd.FailedJob.TemplateImport - (*FailedJob_TemplatePlan)(nil), // 13: provisionerd.FailedJob.TemplatePlan + (*FailedJob_TemplateDryRun)(nil), // 13: provisionerd.FailedJob.TemplateDryRun (*CompletedJob_WorkspaceBuild)(nil), // 14: provisionerd.CompletedJob.WorkspaceBuild (*CompletedJob_TemplateImport)(nil), // 15: provisionerd.CompletedJob.TemplateImport - (*CompletedJob_TemplatePlan)(nil), // 16: provisionerd.CompletedJob.TemplatePlan + (*CompletedJob_TemplateDryRun)(nil), // 16: provisionerd.CompletedJob.TemplateDryRun (proto.LogLevel)(0), // 17: provisioner.LogLevel (*proto.ParameterSchema)(nil), // 18: provisioner.ParameterSchema (*proto.ParameterValue)(nil), // 19: provisioner.ParameterValue @@ -1353,13 +1354,13 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{ var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{ 8, // 0: provisionerd.AcquiredJob.workspace_build:type_name -> provisionerd.AcquiredJob.WorkspaceBuild 9, // 1: provisionerd.AcquiredJob.template_import:type_name -> provisionerd.AcquiredJob.TemplateImport - 10, // 2: provisionerd.AcquiredJob.template_plan:type_name -> provisionerd.AcquiredJob.TemplatePlan + 10, // 2: provisionerd.AcquiredJob.template_dry_run:type_name -> provisionerd.AcquiredJob.TemplateDryRun 11, // 3: provisionerd.FailedJob.workspace_build:type_name -> provisionerd.FailedJob.WorkspaceBuild 12, // 4: provisionerd.FailedJob.template_import:type_name -> provisionerd.FailedJob.TemplateImport - 13, // 5: provisionerd.FailedJob.template_plan:type_name -> provisionerd.FailedJob.TemplatePlan + 13, // 5: provisionerd.FailedJob.template_dry_run:type_name -> provisionerd.FailedJob.TemplateDryRun 14, // 6: provisionerd.CompletedJob.workspace_build:type_name -> provisionerd.CompletedJob.WorkspaceBuild 15, // 7: provisionerd.CompletedJob.template_import:type_name -> provisionerd.CompletedJob.TemplateImport - 16, // 8: provisionerd.CompletedJob.template_plan:type_name -> provisionerd.CompletedJob.TemplatePlan + 16, // 8: provisionerd.CompletedJob.template_dry_run:type_name -> provisionerd.CompletedJob.TemplateDryRun 0, // 9: provisionerd.Log.source:type_name -> provisionerd.LogSource 17, // 10: provisionerd.Log.level:type_name -> provisioner.LogLevel 5, // 11: provisionerd.UpdateJobRequest.logs:type_name -> provisionerd.Log @@ -1368,12 +1369,12 @@ var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{ 19, // 14: provisionerd.AcquiredJob.WorkspaceBuild.parameter_values:type_name -> provisioner.ParameterValue 20, // 15: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata 20, // 16: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata - 19, // 17: provisionerd.AcquiredJob.TemplatePlan.parameter_values:type_name -> provisioner.ParameterValue - 20, // 18: provisionerd.AcquiredJob.TemplatePlan.metadata:type_name -> provisioner.Provision.Metadata + 19, // 17: provisionerd.AcquiredJob.TemplateDryRun.parameter_values:type_name -> provisioner.ParameterValue + 20, // 18: provisionerd.AcquiredJob.TemplateDryRun.metadata:type_name -> provisioner.Provision.Metadata 21, // 19: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource 21, // 20: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource 21, // 21: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource - 21, // 22: provisionerd.CompletedJob.TemplatePlan.resources:type_name -> provisioner.Resource + 21, // 22: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource 1, // 23: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty 6, // 24: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest 3, // 25: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob @@ -1504,7 +1505,7 @@ func file_provisionerd_proto_provisionerd_proto_init() { } } file_provisionerd_proto_provisionerd_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AcquiredJob_TemplatePlan); i { + switch v := v.(*AcquiredJob_TemplateDryRun); i { case 0: return &v.state case 1: @@ -1540,7 +1541,7 @@ func file_provisionerd_proto_provisionerd_proto_init() { } } file_provisionerd_proto_provisionerd_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FailedJob_TemplatePlan); i { + switch v := v.(*FailedJob_TemplateDryRun); i { case 0: return &v.state case 1: @@ -1576,7 +1577,7 @@ func file_provisionerd_proto_provisionerd_proto_init() { } } file_provisionerd_proto_provisionerd_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CompletedJob_TemplatePlan); i { + switch v := v.(*CompletedJob_TemplateDryRun); i { case 0: return &v.state case 1: @@ -1591,17 +1592,17 @@ func file_provisionerd_proto_provisionerd_proto_init() { file_provisionerd_proto_provisionerd_proto_msgTypes[1].OneofWrappers = []interface{}{ (*AcquiredJob_WorkspaceBuild_)(nil), (*AcquiredJob_TemplateImport_)(nil), - (*AcquiredJob_TemplatePlan_)(nil), + (*AcquiredJob_TemplateDryRun_)(nil), } file_provisionerd_proto_provisionerd_proto_msgTypes[2].OneofWrappers = []interface{}{ (*FailedJob_WorkspaceBuild_)(nil), (*FailedJob_TemplateImport_)(nil), - (*FailedJob_TemplatePlan_)(nil), + (*FailedJob_TemplateDryRun_)(nil), } file_provisionerd_proto_provisionerd_proto_msgTypes[3].OneofWrappers = []interface{}{ (*CompletedJob_WorkspaceBuild_)(nil), (*CompletedJob_TemplateImport_)(nil), - (*CompletedJob_TemplatePlan_)(nil), + (*CompletedJob_TemplateDryRun_)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/provisionerd/proto/provisionerd.proto b/provisionerd/proto/provisionerd.proto index 93556ea4acea7..57f768ad68ada 100644 --- a/provisionerd/proto/provisionerd.proto +++ b/provisionerd/proto/provisionerd.proto @@ -21,7 +21,7 @@ message AcquiredJob { message TemplateImport { provisioner.Provision.Metadata metadata = 1; } - message TemplatePlan { + message TemplateDryRun { repeated provisioner.ParameterValue parameter_values = 1; provisioner.Provision.Metadata metadata = 2; } @@ -34,7 +34,7 @@ message AcquiredJob { oneof type { WorkspaceBuild workspace_build = 6; TemplateImport template_import = 7; - TemplatePlan template_plan = 8; + TemplateDryRun template_dry_run = 8; } } @@ -43,14 +43,14 @@ message FailedJob { bytes state = 1; } message TemplateImport {} - message TemplatePlan {} + message TemplateDryRun {} string job_id = 1; string error = 2; oneof type { WorkspaceBuild workspace_build = 3; TemplateImport template_import = 4; - TemplatePlan template_plan = 5; + TemplateDryRun template_dry_run = 5; } } @@ -64,7 +64,7 @@ message CompletedJob { repeated provisioner.Resource start_resources = 1; repeated provisioner.Resource stop_resources = 2; } - message TemplatePlan { + message TemplateDryRun { repeated provisioner.Resource resources = 1; } @@ -72,7 +72,7 @@ message CompletedJob { oneof type { WorkspaceBuild workspace_build = 2; TemplateImport template_import = 3; - TemplatePlan template_plan = 4; + TemplateDryRun template_dry_run = 4; } } diff --git a/provisionerd/provisionerd.go b/provisionerd/provisionerd.go index 06aef5301b3d8..4717dd7905c3a 100644 --- a/provisionerd/provisionerd.go +++ b/provisionerd/provisionerd.go @@ -415,12 +415,12 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) { p.runReadmeParse(ctx, job) p.runTemplateImport(ctx, shutdown, provisioner, job) - case *proto.AcquiredJob_TemplatePlan_: - p.opts.Logger.Debug(context.Background(), "acquired job is template plan", - slog.F("workspace_name", jobType.TemplatePlan.Metadata.WorkspaceName), - slog.F("parameters", jobType.TemplatePlan.ParameterValues), + case *proto.AcquiredJob_TemplateDryRun_: + p.opts.Logger.Debug(context.Background(), "acquired job is template dry-run", + slog.F("workspace_name", jobType.TemplateDryRun.Metadata.WorkspaceName), + slog.F("parameters", jobType.TemplateDryRun.ParameterValues), ) - p.runTemplatePlan(ctx, shutdown, provisioner, job) + p.runTemplateDryRun(ctx, shutdown, provisioner, job) case *proto.AcquiredJob_WorkspaceBuild_: p.opts.Logger.Debug(context.Background(), "acquired job is workspace provision", slog.F("workspace_name", jobType.WorkspaceBuild.WorkspaceName), @@ -748,19 +748,19 @@ func (p *Server) runTemplateImportProvision(ctx, shutdown context.Context, provi } } -func (p *Server) runTemplatePlan(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) { - // Ensure all metadata fields are set as they are all optional for plans. - metadata := job.GetTemplatePlan().GetMetadata() +func (p *Server) runTemplateDryRun(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) { + // Ensure all metadata fields are set as they are all optional for dry-run. + metadata := job.GetTemplateDryRun().GetMetadata() metadata.WorkspaceTransition = sdkproto.WorkspaceTransition_START if metadata.CoderUrl == "" { metadata.CoderUrl = "http://localhost:3000" } if metadata.WorkspaceName == "" { - metadata.WorkspaceName = "plan" + metadata.WorkspaceName = "dryrun" } metadata.WorkspaceOwner = job.UserName if metadata.WorkspaceOwner == "" { - metadata.WorkspaceOwner = "planner" + metadata.WorkspaceOwner = "dryrunner" } if metadata.WorkspaceId == "" { id, err := uuid.NewRandom() @@ -784,7 +784,7 @@ func (p *Server) runTemplatePlan(ctx, shutdown context.Context, provisioner sdkp shutdown, provisioner, job, - job.GetTemplatePlan().GetParameterValues(), + job.GetTemplateDryRun().GetParameterValues(), metadata, ) if err != nil { @@ -794,8 +794,8 @@ func (p *Server) runTemplatePlan(ctx, shutdown context.Context, provisioner sdkp p.completeJob(&proto.CompletedJob{ JobId: job.JobId, - Type: &proto.CompletedJob_TemplatePlan_{ - TemplatePlan: &proto.CompletedJob_TemplatePlan{ + Type: &proto.CompletedJob_TemplateDryRun_{ + TemplateDryRun: &proto.CompletedJob_TemplateDryRun{ Resources: resources, }, }, diff --git a/provisionerd/provisionerd_test.go b/provisionerd/provisionerd_test.go index d51d73647586d..0031d662311f4 100644 --- a/provisionerd/provisionerd_test.go +++ b/provisionerd/provisionerd_test.go @@ -315,7 +315,7 @@ func TestProvisionerd(t *testing.T) { require.NoError(t, closer.Close()) }) - t.Run("TemplatePlan", func(t *testing.T) { + t.Run("TemplateDryRun", func(t *testing.T) { t.Parallel() var ( didComplete atomic.Bool @@ -353,8 +353,8 @@ func TestProvisionerd(t *testing.T) { TemplateSourceArchive: createTar(t, map[string]string{ "test.txt": "content", }), - Type: &proto.AcquiredJob_TemplatePlan_{ - TemplatePlan: &proto.AcquiredJob_TemplatePlan{ + Type: &proto.AcquiredJob_TemplateDryRun_{ + TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{ ParameterValues: parameterValues, Metadata: metadata, }, diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 7555dbe436556..8ae256e447b72 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -66,7 +66,7 @@ export interface CreateTemplateRequest { } // From codersdk/templateversions.go:121:6 -export interface CreateTemplateVersionPlanRequest { +export interface CreateTemplateVersionDryRunRequest { readonly WorkspaceName: string readonly ParameterValues: CreateParameterRequest[] }