From 0f713ed8fee680846877c21db3d6258cc9af7c94 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Wed, 6 Nov 2024 13:33:29 +0000 Subject: [PATCH 01/34] add the workspace_modules table, add the module column to workspace_resources --- coderd/database/dump.sql | 13 ++++++++++++- .../migrations/000274_workspace_modules.down.sql | 5 +++++ .../migrations/000274_workspace_modules.up.sql | 14 ++++++++++++++ coderd/database/models.go | 11 +++++++++++ coderd/database/queries.sql.go | 15 ++++++++++----- 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 coderd/database/migrations/000274_workspace_modules.down.sql create mode 100644 coderd/database/migrations/000274_workspace_modules.up.sql diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index e5ce4745dc7cc..4c2264e754860 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1634,6 +1634,16 @@ CREATE VIEW workspace_build_with_user AS COMMENT ON VIEW workspace_build_with_user IS 'Joins in the username + avatar url of the initiated by user.'; +CREATE TABLE workspace_modules ( + id uuid NOT NULL, + job_id uuid NOT NULL, + transition workspace_transition NOT NULL, + source text NOT NULL, + version text NOT NULL, + key text NOT NULL, + created_at timestamp with time zone NOT NULL +); + CREATE TABLE workspace_proxies ( id uuid NOT NULL, name text NOT NULL, @@ -1700,7 +1710,8 @@ CREATE TABLE workspace_resources ( hide boolean DEFAULT false NOT NULL, icon character varying(256) DEFAULT ''::character varying NOT NULL, instance_type character varying(256), - daily_cost integer DEFAULT 0 NOT NULL + daily_cost integer DEFAULT 0 NOT NULL, + module text ); CREATE TABLE workspaces ( diff --git a/coderd/database/migrations/000274_workspace_modules.down.sql b/coderd/database/migrations/000274_workspace_modules.down.sql new file mode 100644 index 0000000000000..afa5c84ceef66 --- /dev/null +++ b/coderd/database/migrations/000274_workspace_modules.down.sql @@ -0,0 +1,5 @@ +DROP TABLE workspace_modules; + +ALTER TABLE + workspace_resources +DROP COLUMN module; diff --git a/coderd/database/migrations/000274_workspace_modules.up.sql b/coderd/database/migrations/000274_workspace_modules.up.sql new file mode 100644 index 0000000000000..753fcff8997c3 --- /dev/null +++ b/coderd/database/migrations/000274_workspace_modules.up.sql @@ -0,0 +1,14 @@ +ALTER TABLE + workspace_resources +ADD + COLUMN module TEXT; + +CREATE TABLE workspace_modules ( + id uuid NOT NULL, + job_id uuid NOT NULL, + transition workspace_transition NOT NULL, + source TEXT NOT NULL, + version TEXT NOT NULL, + key TEXT NOT NULL, + created_at timestamp with time zone NOT NULL +); diff --git a/coderd/database/models.go b/coderd/database/models.go index d84030107de7f..345d9296d60fe 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -3152,6 +3152,16 @@ type WorkspaceBuildTable struct { MaxDeadline time.Time `db:"max_deadline" json:"max_deadline"` } +type WorkspaceModule struct { + ID uuid.UUID `db:"id" json:"id"` + JobID uuid.UUID `db:"job_id" json:"job_id"` + Transition WorkspaceTransition `db:"transition" json:"transition"` + Source string `db:"source" json:"source"` + Version string `db:"version" json:"version"` + Key string `db:"key" json:"key"` + CreatedAt time.Time `db:"created_at" json:"created_at"` +} + type WorkspaceProxy struct { ID uuid.UUID `db:"id" json:"id"` Name string `db:"name" json:"name"` @@ -3186,6 +3196,7 @@ type WorkspaceResource struct { Icon string `db:"icon" json:"icon"` InstanceType sql.NullString `db:"instance_type" json:"instance_type"` DailyCost int32 `db:"daily_cost" json:"daily_cost"` + Module sql.NullString `db:"module" json:"module"` } type WorkspaceResourceMetadatum struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index be7034f7798ff..dede53db9c0d1 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -14117,7 +14117,7 @@ func (q *sqlQuerier) UpdateWorkspaceBuildProvisionerStateByID(ctx context.Contex const getWorkspaceResourceByID = `-- name: GetWorkspaceResourceByID :one SELECT - id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost + id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module FROM workspace_resources WHERE @@ -14138,6 +14138,7 @@ func (q *sqlQuerier) GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID) &i.Icon, &i.InstanceType, &i.DailyCost, + &i.Module, ) return i, err } @@ -14217,7 +14218,7 @@ func (q *sqlQuerier) GetWorkspaceResourceMetadataCreatedAfter(ctx context.Contex const getWorkspaceResourcesByJobID = `-- name: GetWorkspaceResourcesByJobID :many SELECT - id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost + id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module FROM workspace_resources WHERE @@ -14244,6 +14245,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uui &i.Icon, &i.InstanceType, &i.DailyCost, + &i.Module, ); err != nil { return nil, err } @@ -14260,7 +14262,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uui const getWorkspaceResourcesByJobIDs = `-- name: GetWorkspaceResourcesByJobIDs :many SELECT - id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost + id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module FROM workspace_resources WHERE @@ -14287,6 +14289,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobIDs(ctx context.Context, ids []uu &i.Icon, &i.InstanceType, &i.DailyCost, + &i.Module, ); err != nil { return nil, err } @@ -14302,7 +14305,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobIDs(ctx context.Context, ids []uu } const getWorkspaceResourcesCreatedAfter = `-- name: GetWorkspaceResourcesCreatedAfter :many -SELECT id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost FROM workspace_resources WHERE created_at > $1 +SELECT id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module FROM workspace_resources WHERE created_at > $1 ` func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResource, error) { @@ -14325,6 +14328,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, crea &i.Icon, &i.InstanceType, &i.DailyCost, + &i.Module, ); err != nil { return nil, err } @@ -14343,7 +14347,7 @@ const insertWorkspaceResource = `-- name: InsertWorkspaceResource :one INSERT INTO workspace_resources (id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module ` type InsertWorkspaceResourceParams struct { @@ -14384,6 +14388,7 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork &i.Icon, &i.InstanceType, &i.DailyCost, + &i.Module, ) return i, err } From 82c8a3c9b3e99bb376a1d132cc29a92c1ddce4fc Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Wed, 6 Nov 2024 16:28:06 +0000 Subject: [PATCH 02/34] insert workspace modules on provisioner job completion --- coderd/database/dbauthz/dbauthz.go | 7 + coderd/database/dbmem/dbmem.go | 9 + coderd/database/dbmetrics/querymetrics.go | 7 + coderd/database/dbmock/dbmock.go | 15 + coderd/database/querier.go | 1 + coderd/database/queries.sql.go | 40 +++ coderd/database/queries/workspacemodules.sql | 5 + .../provisionerdserver/provisionerdserver.go | 51 +++ provisioner/terraform/modules.go | 52 ++++ provisioner/terraform/provision.go | 6 + provisionerd/proto/provisionerd.pb.go | 158 ++++++---- provisionerd/proto/provisionerd.proto | 4 + provisionerd/runner/runner.go | 6 + provisionersdk/proto/provisioner.pb.go | 293 +++++++++++------- provisionersdk/proto/provisioner.proto | 7 + site/e2e/provisionerGenerated.ts | 28 ++ 16 files changed, 531 insertions(+), 158 deletions(-) create mode 100644 coderd/database/queries/workspacemodules.sql create mode 100644 provisioner/terraform/modules.go diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index ce52c35faae66..949cdbc2a5d6b 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -3222,6 +3222,13 @@ func (q *querier) InsertWorkspaceBuildParameters(ctx context.Context, arg databa return q.db.InsertWorkspaceBuildParameters(ctx, arg) } +func (q *querier) InsertWorkspaceModule(ctx context.Context, arg database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) { + if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil { + return database.WorkspaceModule{}, err + } + return q.db.InsertWorkspaceModule(ctx, arg) +} + func (q *querier) InsertWorkspaceProxy(ctx context.Context, arg database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) { return insert(q.log, q.auth, rbac.ResourceWorkspaceProxy, q.db.InsertWorkspaceProxy)(ctx, arg) } diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index b6e8e59db16a3..ba542ebbc60d5 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -8233,6 +8233,15 @@ func (q *FakeQuerier) InsertWorkspaceBuildParameters(_ context.Context, arg data return nil } +func (q *FakeQuerier) InsertWorkspaceModule(ctx context.Context, arg database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) { + err := validateDatabaseType(arg) + if err != nil { + return database.WorkspaceModule{}, err + } + + panic("not implemented") +} + func (q *FakeQuerier) InsertWorkspaceProxy(_ context.Context, arg database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) { q.mutex.Lock() defer q.mutex.Unlock() diff --git a/coderd/database/dbmetrics/querymetrics.go b/coderd/database/dbmetrics/querymetrics.go index eaf19bdc145f4..bfa19c45ce573 100644 --- a/coderd/database/dbmetrics/querymetrics.go +++ b/coderd/database/dbmetrics/querymetrics.go @@ -1995,6 +1995,13 @@ func (m queryMetricsStore) InsertWorkspaceBuildParameters(ctx context.Context, a return err } +func (m queryMetricsStore) InsertWorkspaceModule(ctx context.Context, arg database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) { + start := time.Now() + r0, r1 := m.s.InsertWorkspaceModule(ctx, arg) + m.queryLatencies.WithLabelValues("InsertWorkspaceModule").Observe(time.Since(start).Seconds()) + return r0, r1 +} + func (m queryMetricsStore) InsertWorkspaceProxy(ctx context.Context, arg database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) { start := time.Now() proxy, err := m.s.InsertWorkspaceProxy(ctx, arg) diff --git a/coderd/database/dbmock/dbmock.go b/coderd/database/dbmock/dbmock.go index a539871ba786b..14108ce50c988 100644 --- a/coderd/database/dbmock/dbmock.go +++ b/coderd/database/dbmock/dbmock.go @@ -4224,6 +4224,21 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceBuildParameters(arg0, arg1 any) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceBuildParameters", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceBuildParameters), arg0, arg1) } +// InsertWorkspaceModule mocks base method. +func (m *MockStore) InsertWorkspaceModule(arg0 context.Context, arg1 database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InsertWorkspaceModule", arg0, arg1) + ret0, _ := ret[0].(database.WorkspaceModule) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// InsertWorkspaceModule indicates an expected call of InsertWorkspaceModule. +func (mr *MockStoreMockRecorder) InsertWorkspaceModule(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceModule", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceModule), arg0, arg1) +} + // InsertWorkspaceProxy mocks base method. func (m *MockStore) InsertWorkspaceProxy(arg0 context.Context, arg1 database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) { m.ctrl.T.Helper() diff --git a/coderd/database/querier.go b/coderd/database/querier.go index 0d03340da6893..38b928dbc6b1a 100644 --- a/coderd/database/querier.go +++ b/coderd/database/querier.go @@ -404,6 +404,7 @@ type sqlcQuerier interface { InsertWorkspaceAppStats(ctx context.Context, arg InsertWorkspaceAppStatsParams) error InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) error InsertWorkspaceBuildParameters(ctx context.Context, arg InsertWorkspaceBuildParametersParams) error + InsertWorkspaceModule(ctx context.Context, arg InsertWorkspaceModuleParams) (WorkspaceModule, error) InsertWorkspaceProxy(ctx context.Context, arg InsertWorkspaceProxyParams) (WorkspaceProxy, error) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) ([]WorkspaceResourceMetadatum, error) diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index dede53db9c0d1..7e8c892c6b806 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -14115,6 +14115,46 @@ func (q *sqlQuerier) UpdateWorkspaceBuildProvisionerStateByID(ctx context.Contex return err } +const insertWorkspaceModule = `-- name: InsertWorkspaceModule :one +INSERT INTO + workspace_modules (id, job_id, transition, source, version, key, created_at) +VALUES + ($1, $2, $3, $4, $5, $6, $7) RETURNING id, job_id, transition, source, version, key, created_at +` + +type InsertWorkspaceModuleParams struct { + ID uuid.UUID `db:"id" json:"id"` + JobID uuid.UUID `db:"job_id" json:"job_id"` + Transition WorkspaceTransition `db:"transition" json:"transition"` + Source string `db:"source" json:"source"` + Version string `db:"version" json:"version"` + Key string `db:"key" json:"key"` + CreatedAt time.Time `db:"created_at" json:"created_at"` +} + +func (q *sqlQuerier) InsertWorkspaceModule(ctx context.Context, arg InsertWorkspaceModuleParams) (WorkspaceModule, error) { + row := q.db.QueryRowContext(ctx, insertWorkspaceModule, + arg.ID, + arg.JobID, + arg.Transition, + arg.Source, + arg.Version, + arg.Key, + arg.CreatedAt, + ) + var i WorkspaceModule + err := row.Scan( + &i.ID, + &i.JobID, + &i.Transition, + &i.Source, + &i.Version, + &i.Key, + &i.CreatedAt, + ) + return i, err +} + const getWorkspaceResourceByID = `-- name: GetWorkspaceResourceByID :one SELECT id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module diff --git a/coderd/database/queries/workspacemodules.sql b/coderd/database/queries/workspacemodules.sql new file mode 100644 index 0000000000000..07fb57245963c --- /dev/null +++ b/coderd/database/queries/workspacemodules.sql @@ -0,0 +1,5 @@ +-- name: InsertWorkspaceModule :one +INSERT INTO + workspace_modules (id, job_id, transition, source, version, key, created_at) +VALUES + ($1, $2, $3, $4, $5, $6, $7) RETURNING *; diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index 5fc0f198102c9..ccaf29b0af55f 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1267,6 +1267,24 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) } } } + for transition, modules := range map[database.WorkspaceTransition][]*sdkproto.Module{ + database.WorkspaceTransitionStart: jobType.TemplateImport.StartModules, + database.WorkspaceTransitionStop: jobType.TemplateImport.StopModules, + } { + for _, module := range modules { + s.Logger.Info(ctx, "inserting template import job module", + slog.F("job_id", job.ID.String()), + slog.F("module_source", module.Source), + slog.F("module_version", module.Version), + slog.F("module_key", module.Key), + slog.F("transition", transition)) + + err = InsertWorkspaceModule(ctx, s.Database, jobID, transition, module) + if err != nil { + return nil, xerrors.Errorf("insert module: %w", err) + } + } + } for _, richParameter := range jobType.TemplateImport.RichParameters { s.Logger.Info(ctx, "inserting template import job parameter", @@ -1472,6 +1490,12 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) return xerrors.Errorf("insert provisioner job: %w", err) } } + for _, module := range jobType.WorkspaceBuild.Modules { + err = InsertWorkspaceModule(ctx, db, job.ID, workspaceBuild.Transition, module) + if err != nil { + return xerrors.Errorf("insert provisioner job module: %w", err) + } + } // On start, we want to ensure that workspace agents timeout statuses // are propagated. This method is simple and does not protect against @@ -1653,6 +1677,17 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) return nil, xerrors.Errorf("insert resource: %w", err) } } + for _, module := range jobType.TemplateDryRun.Modules { + s.Logger.Info(ctx, "inserting template dry-run job module", + slog.F("job_id", job.ID.String()), + slog.F("module_source", module.Source), + ) + + err = InsertWorkspaceModule(ctx, s.Database, jobID, database.WorkspaceTransitionStart, module) + if err != nil { + return nil, xerrors.Errorf("insert module: %w", err) + } + } err = s.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{ ID: jobID, @@ -1734,6 +1769,22 @@ func (s *server) startTrace(ctx context.Context, name string, opts ...trace.Span ))...) } +func InsertWorkspaceModule(ctx context.Context, db database.Store, jobID uuid.UUID, transition database.WorkspaceTransition, protoModule *sdkproto.Module) error { + _, err := db.InsertWorkspaceModule(ctx, database.InsertWorkspaceModuleParams{ + ID: uuid.New(), + CreatedAt: dbtime.Now(), + JobID: jobID, + Transition: transition, + Source: protoModule.Source, + Version: protoModule.Version, + Key: protoModule.Key, + }) + if err != nil { + return xerrors.Errorf("insert provisioner job module %q: %w", protoModule.Source, err) + } + return nil +} + func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.UUID, transition database.WorkspaceTransition, protoResource *sdkproto.Resource, snapshot *telemetry.Snapshot) error { resource, err := db.InsertWorkspaceResource(ctx, database.InsertWorkspaceResourceParams{ ID: uuid.New(), diff --git a/provisioner/terraform/modules.go b/provisioner/terraform/modules.go new file mode 100644 index 0000000000000..e375cfca97feb --- /dev/null +++ b/provisioner/terraform/modules.go @@ -0,0 +1,52 @@ +package terraform + +import ( + "encoding/json" + "os" + "path/filepath" + + "golang.org/x/xerrors" + + "github.com/coder/coder/v2/provisionersdk/proto" +) + +type module struct { + Source string `json:"Source"` + Version string `json:"Version"` + Key string `json:"Key"` +} + +type modulesFile struct { + Modules []*module `json:"Modules"` +} + +func getModulesFilePath(workdir string) string { + return filepath.Join(workdir, ".terraform", "modules", "modules.json") +} + +func parseModulesFile(filePath string) ([]*proto.Module, error) { + modules := &modulesFile{} + data, err := os.ReadFile(filePath) + if err != nil { + return nil, xerrors.Errorf("read modules file: %w", err) + } + if err := json.Unmarshal(data, modules); err != nil { + return nil, xerrors.Errorf("unmarshal modules file: %w", err) + } + protoModules := make([]*proto.Module, len(modules.Modules)) + for i, m := range modules.Modules { + protoModules[i] = &proto.Module{Source: m.Source, Version: m.Version, Key: m.Key} + } + return protoModules, nil +} + +// getModules returns the modules from the modules file if it exists. +// It returns nil if the file does not exist. +// Modules become available after terraform init. +func getModules(workdir string) ([]*proto.Module, error) { + filePath := getModulesFilePath(workdir) + if _, err := os.Stat(filePath); os.IsNotExist(err) { + return nil, nil + } + return parseModulesFile(filePath) +} diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go index 4695133d7d02a..f7680f6a6b417 100644 --- a/provisioner/terraform/provision.go +++ b/provisioner/terraform/provision.go @@ -142,6 +142,11 @@ func (s *server) Plan( return provisionersdk.PlanErrorf("initialize terraform: %s", err) } + modules, err := getModules(sess.WorkDirectory) + if err != nil { + return provisionersdk.PlanErrorf("get modules: %s", err) + } + initTimings.ingest(createInitTimingsEvent(timingInitComplete)) s.logger.Debug(ctx, "ran initialization") @@ -167,6 +172,7 @@ func (s *server) Plan( // Prepend init timings since they occur prior to plan timings. // Order is irrelevant; this is merely indicative. resp.Timings = append(initTimings.aggregate(), resp.Timings...) + resp.Modules = modules return resp } diff --git a/provisionerd/proto/provisionerd.pb.go b/provisionerd/proto/provisionerd.pb.go index d026167eed757..7f5e39a85a8fa 100644 --- a/provisionerd/proto/provisionerd.pb.go +++ b/provisionerd/proto/provisionerd.pb.go @@ -1215,6 +1215,7 @@ type CompletedJob_WorkspaceBuild struct { State []byte `protobuf:"bytes,1,opt,name=state,proto3" json:"state,omitempty"` Resources []*proto.Resource `protobuf:"bytes,2,rep,name=resources,proto3" json:"resources,omitempty"` Timings []*proto.Timing `protobuf:"bytes,3,rep,name=timings,proto3" json:"timings,omitempty"` + Modules []*proto.Module `protobuf:"bytes,4,rep,name=modules,proto3" json:"modules,omitempty"` } func (x *CompletedJob_WorkspaceBuild) Reset() { @@ -1270,6 +1271,13 @@ func (x *CompletedJob_WorkspaceBuild) GetTimings() []*proto.Timing { return nil } +func (x *CompletedJob_WorkspaceBuild) GetModules() []*proto.Module { + if x != nil { + return x.Modules + } + return nil +} + type CompletedJob_TemplateImport struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1280,6 +1288,8 @@ type CompletedJob_TemplateImport struct { RichParameters []*proto.RichParameter `protobuf:"bytes,3,rep,name=rich_parameters,json=richParameters,proto3" json:"rich_parameters,omitempty"` ExternalAuthProvidersNames []string `protobuf:"bytes,4,rep,name=external_auth_providers_names,json=externalAuthProvidersNames,proto3" json:"external_auth_providers_names,omitempty"` ExternalAuthProviders []*proto.ExternalAuthProviderResource `protobuf:"bytes,5,rep,name=external_auth_providers,json=externalAuthProviders,proto3" json:"external_auth_providers,omitempty"` + StartModules []*proto.Module `protobuf:"bytes,6,rep,name=start_modules,json=startModules,proto3" json:"start_modules,omitempty"` + StopModules []*proto.Module `protobuf:"bytes,7,rep,name=stop_modules,json=stopModules,proto3" json:"stop_modules,omitempty"` } func (x *CompletedJob_TemplateImport) Reset() { @@ -1349,12 +1359,27 @@ func (x *CompletedJob_TemplateImport) GetExternalAuthProviders() []*proto.Extern return nil } +func (x *CompletedJob_TemplateImport) GetStartModules() []*proto.Module { + if x != nil { + return x.StartModules + } + return nil +} + +func (x *CompletedJob_TemplateImport) GetStopModules() []*proto.Module { + if x != nil { + return x.StopModules + } + return nil +} + type CompletedJob_TemplateDryRun struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Resources []*proto.Resource `protobuf:"bytes,1,rep,name=resources,proto3" json:"resources,omitempty"` + Modules []*proto.Module `protobuf:"bytes,2,rep,name=modules,proto3" json:"modules,omitempty"` } func (x *CompletedJob_TemplateDryRun) Reset() { @@ -1396,6 +1421,13 @@ func (x *CompletedJob_TemplateDryRun) GetResources() []*proto.Resource { return nil } +func (x *CompletedJob_TemplateDryRun) GetModules() []*proto.Module { + if x != nil { + return x.Modules + } + return nil +} + var File_provisionerd_proto_provisionerd_proto protoreflect.FileDescriptor var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{ @@ -1524,7 +1556,7 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{ 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, - 0x79, 0x52, 0x75, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x80, 0x07, 0x0a, + 0x79, 0x52, 0x75, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xd0, 0x08, 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, @@ -1543,7 +1575,7 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{ 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, 0x8a, 0x01, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, + 0x65, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0xb9, 0x01, 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, @@ -1552,35 +1584,48 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{ 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, - 0x69, 0x6e, 0x67, 0x73, 0x1a, 0xf9, 0x02, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, - 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3e, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x70, 0x5f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x73, 0x1a, 0xeb, 0x03, 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, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, - 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x72, 0x69, 0x63, 0x68, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x1a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x61, 0x0a, - 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, - 0x1a, 0x45, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x44, 0x72, 0x79, 0x52, - 0x75, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0e, 0x72, 0x69, 0x63, 0x68, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x65, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x1a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x17, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, + 0x38, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x0c, 0x73, 0x74, 0x6f, + 0x70, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x70, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x73, 0x1a, 0x74, 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, 0x12, 0x2d, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 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, @@ -1722,8 +1767,9 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{ (*proto.Metadata)(nil), // 27: provisioner.Metadata (*proto.Timing)(nil), // 28: provisioner.Timing (*proto.Resource)(nil), // 29: provisioner.Resource - (*proto.RichParameter)(nil), // 30: provisioner.RichParameter - (*proto.ExternalAuthProviderResource)(nil), // 31: provisioner.ExternalAuthProviderResource + (*proto.Module)(nil), // 30: provisioner.Module + (*proto.RichParameter)(nil), // 31: provisioner.RichParameter + (*proto.ExternalAuthProviderResource)(nil), // 32: provisioner.ExternalAuthProviderResource } var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{ 11, // 0: provisionerd.AcquiredJob.workspace_build:type_name -> provisionerd.AcquiredJob.WorkspaceBuild @@ -1755,28 +1801,32 @@ var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{ 28, // 26: provisionerd.FailedJob.WorkspaceBuild.timings:type_name -> provisioner.Timing 29, // 27: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource 28, // 28: provisionerd.CompletedJob.WorkspaceBuild.timings:type_name -> provisioner.Timing - 29, // 29: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource - 29, // 30: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource - 30, // 31: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter - 31, // 32: provisionerd.CompletedJob.TemplateImport.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource - 29, // 33: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource - 1, // 34: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty - 10, // 35: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:input_type -> provisionerd.CancelAcquire - 8, // 36: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest - 6, // 37: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest - 3, // 38: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob - 4, // 39: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob - 2, // 40: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob - 2, // 41: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:output_type -> provisionerd.AcquiredJob - 9, // 42: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse - 7, // 43: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse - 1, // 44: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty - 1, // 45: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty - 40, // [40:46] is the sub-list for method output_type - 34, // [34:40] is the sub-list for method input_type - 34, // [34:34] is the sub-list for extension type_name - 34, // [34:34] is the sub-list for extension extendee - 0, // [0:34] is the sub-list for field type_name + 30, // 29: provisionerd.CompletedJob.WorkspaceBuild.modules:type_name -> provisioner.Module + 29, // 30: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource + 29, // 31: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource + 31, // 32: provisionerd.CompletedJob.TemplateImport.rich_parameters:type_name -> provisioner.RichParameter + 32, // 33: provisionerd.CompletedJob.TemplateImport.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource + 30, // 34: provisionerd.CompletedJob.TemplateImport.start_modules:type_name -> provisioner.Module + 30, // 35: provisionerd.CompletedJob.TemplateImport.stop_modules:type_name -> provisioner.Module + 29, // 36: provisionerd.CompletedJob.TemplateDryRun.resources:type_name -> provisioner.Resource + 30, // 37: provisionerd.CompletedJob.TemplateDryRun.modules:type_name -> provisioner.Module + 1, // 38: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty + 10, // 39: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:input_type -> provisionerd.CancelAcquire + 8, // 40: provisionerd.ProvisionerDaemon.CommitQuota:input_type -> provisionerd.CommitQuotaRequest + 6, // 41: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest + 3, // 42: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob + 4, // 43: provisionerd.ProvisionerDaemon.CompleteJob:input_type -> provisionerd.CompletedJob + 2, // 44: provisionerd.ProvisionerDaemon.AcquireJob:output_type -> provisionerd.AcquiredJob + 2, // 45: provisionerd.ProvisionerDaemon.AcquireJobWithCancel:output_type -> provisionerd.AcquiredJob + 9, // 46: provisionerd.ProvisionerDaemon.CommitQuota:output_type -> provisionerd.CommitQuotaResponse + 7, // 47: provisionerd.ProvisionerDaemon.UpdateJob:output_type -> provisionerd.UpdateJobResponse + 1, // 48: provisionerd.ProvisionerDaemon.FailJob:output_type -> provisionerd.Empty + 1, // 49: provisionerd.ProvisionerDaemon.CompleteJob:output_type -> provisionerd.Empty + 44, // [44:50] is the sub-list for method output_type + 38, // [38:44] is the sub-list for method input_type + 38, // [38:38] is the sub-list for extension type_name + 38, // [38:38] is the sub-list for extension extendee + 0, // [0:38] is the sub-list for field type_name } func init() { file_provisionerd_proto_provisionerd_proto_init() } diff --git a/provisionerd/proto/provisionerd.proto b/provisionerd/proto/provisionerd.proto index f061ae801efd7..ad1a43e49a33d 100644 --- a/provisionerd/proto/provisionerd.proto +++ b/provisionerd/proto/provisionerd.proto @@ -74,6 +74,7 @@ message CompletedJob { bytes state = 1; repeated provisioner.Resource resources = 2; repeated provisioner.Timing timings = 3; + repeated provisioner.Module modules = 4; } message TemplateImport { repeated provisioner.Resource start_resources = 1; @@ -81,9 +82,12 @@ message CompletedJob { repeated provisioner.RichParameter rich_parameters = 3; repeated string external_auth_providers_names = 4; repeated provisioner.ExternalAuthProviderResource external_auth_providers = 5; + repeated provisioner.Module start_modules = 6; + repeated provisioner.Module stop_modules = 7; } message TemplateDryRun { repeated provisioner.Resource resources = 1; + repeated provisioner.Module modules = 2; } string job_id = 1; diff --git a/provisionerd/runner/runner.go b/provisionerd/runner/runner.go index de157959d5f9a..c64ec93bebbc8 100644 --- a/provisionerd/runner/runner.go +++ b/provisionerd/runner/runner.go @@ -581,6 +581,8 @@ func (r *Runner) runTemplateImport(ctx context.Context) (*proto.CompletedJob, *p RichParameters: startProvision.Parameters, ExternalAuthProvidersNames: externalAuthProviderNames, ExternalAuthProviders: startProvision.ExternalAuthProviders, + StartModules: startProvision.Modules, + StopModules: stopProvision.Modules, }, }, }, nil @@ -640,6 +642,7 @@ type templateImportProvision struct { Resources []*sdkproto.Resource Parameters []*sdkproto.RichParameter ExternalAuthProviders []*sdkproto.ExternalAuthProviderResource + Modules []*sdkproto.Module } // Performs a dry-run provision when importing a template. @@ -731,6 +734,7 @@ func (r *Runner) runTemplateImportProvisionWithRichParameters( Resources: c.Resources, Parameters: c.Parameters, ExternalAuthProviders: c.ExternalAuthProviders, + Modules: c.Modules, }, nil default: return nil, xerrors.Errorf("invalid message type %q received from provisioner", @@ -793,6 +797,7 @@ func (r *Runner) runTemplateDryRun(ctx context.Context) (*proto.CompletedJob, *p Type: &proto.CompletedJob_TemplateDryRun_{ TemplateDryRun: &proto.CompletedJob_TemplateDryRun{ Resources: provision.Resources, + Modules: provision.Modules, }, }, }, nil @@ -1033,6 +1038,7 @@ func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *p State: applyComplete.State, Resources: applyComplete.Resources, Timings: applyComplete.Timings, + Modules: planComplete.Modules, }, }, }, nil diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 9d5406d403375..1beb9dab66e6b 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -1676,6 +1676,69 @@ func (x *Resource) GetDailyCost() int32 { return 0 } +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +func (x *Module) ProtoReflect() protoreflect.Message { + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + 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 Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{17} +} + +func (x *Module) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *Module) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Module) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + // Metadata is information about a workspace used in the execution of a build type Metadata struct { state protoimpl.MessageState @@ -1705,7 +1768,7 @@ type Metadata struct { func (x *Metadata) Reset() { *x = Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1718,7 +1781,7 @@ func (x *Metadata) String() string { func (*Metadata) ProtoMessage() {} func (x *Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1731,7 +1794,7 @@ func (x *Metadata) ProtoReflect() protoreflect.Message { // Deprecated: Use Metadata.ProtoReflect.Descriptor instead. func (*Metadata) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{17} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{18} } func (x *Metadata) GetCoderUrl() string { @@ -1876,7 +1939,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1889,7 +1952,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1902,7 +1965,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{18} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{19} } func (x *Config) GetTemplateSourceArchive() []byte { @@ -1936,7 +1999,7 @@ type ParseRequest struct { func (x *ParseRequest) Reset() { *x = ParseRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1949,7 +2012,7 @@ func (x *ParseRequest) String() string { func (*ParseRequest) ProtoMessage() {} func (x *ParseRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1962,7 +2025,7 @@ func (x *ParseRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseRequest.ProtoReflect.Descriptor instead. func (*ParseRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{19} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{20} } // ParseComplete indicates a request to parse completed. @@ -1980,7 +2043,7 @@ type ParseComplete struct { func (x *ParseComplete) Reset() { *x = ParseComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1993,7 +2056,7 @@ func (x *ParseComplete) String() string { func (*ParseComplete) ProtoMessage() {} func (x *ParseComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2006,7 +2069,7 @@ func (x *ParseComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseComplete.ProtoReflect.Descriptor instead. func (*ParseComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{20} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{21} } func (x *ParseComplete) GetError() string { @@ -2052,7 +2115,7 @@ type PlanRequest struct { func (x *PlanRequest) Reset() { *x = PlanRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2065,7 +2128,7 @@ func (x *PlanRequest) String() string { func (*PlanRequest) ProtoMessage() {} func (x *PlanRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2078,7 +2141,7 @@ func (x *PlanRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanRequest.ProtoReflect.Descriptor instead. func (*PlanRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{21} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{22} } func (x *PlanRequest) GetMetadata() *Metadata { @@ -2120,12 +2183,13 @@ type PlanComplete struct { Parameters []*RichParameter `protobuf:"bytes,3,rep,name=parameters,proto3" json:"parameters,omitempty"` ExternalAuthProviders []*ExternalAuthProviderResource `protobuf:"bytes,4,rep,name=external_auth_providers,json=externalAuthProviders,proto3" json:"external_auth_providers,omitempty"` Timings []*Timing `protobuf:"bytes,6,rep,name=timings,proto3" json:"timings,omitempty"` + Modules []*Module `protobuf:"bytes,7,rep,name=modules,proto3" json:"modules,omitempty"` } func (x *PlanComplete) Reset() { *x = PlanComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2138,7 +2202,7 @@ func (x *PlanComplete) String() string { func (*PlanComplete) ProtoMessage() {} func (x *PlanComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2151,7 +2215,7 @@ func (x *PlanComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanComplete.ProtoReflect.Descriptor instead. func (*PlanComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{22} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{23} } func (x *PlanComplete) GetError() string { @@ -2189,6 +2253,13 @@ func (x *PlanComplete) GetTimings() []*Timing { return nil } +func (x *PlanComplete) GetModules() []*Module { + if x != nil { + return x.Modules + } + return nil +} + // ApplyRequest asks the provisioner to apply the changes. Apply MUST be preceded by a successful plan request/response // in the same Session. The plan data is not transmitted over the wire and is cached by the provisioner in the Session. type ApplyRequest struct { @@ -2202,7 +2273,7 @@ type ApplyRequest struct { func (x *ApplyRequest) Reset() { *x = ApplyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2215,7 +2286,7 @@ func (x *ApplyRequest) String() string { func (*ApplyRequest) ProtoMessage() {} func (x *ApplyRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2228,7 +2299,7 @@ func (x *ApplyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyRequest.ProtoReflect.Descriptor instead. func (*ApplyRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{23} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{24} } func (x *ApplyRequest) GetMetadata() *Metadata { @@ -2255,7 +2326,7 @@ type ApplyComplete struct { func (x *ApplyComplete) Reset() { *x = ApplyComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2268,7 +2339,7 @@ func (x *ApplyComplete) String() string { func (*ApplyComplete) ProtoMessage() {} func (x *ApplyComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2281,7 +2352,7 @@ func (x *ApplyComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyComplete.ProtoReflect.Descriptor instead. func (*ApplyComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{24} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{25} } func (x *ApplyComplete) GetState() []byte { @@ -2343,7 +2414,7 @@ type Timing struct { func (x *Timing) Reset() { *x = Timing{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2356,7 +2427,7 @@ func (x *Timing) String() string { func (*Timing) ProtoMessage() {} func (x *Timing) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2369,7 +2440,7 @@ func (x *Timing) ProtoReflect() protoreflect.Message { // Deprecated: Use Timing.ProtoReflect.Descriptor instead. func (*Timing) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{25} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{26} } func (x *Timing) GetStart() *timestamppb.Timestamp { @@ -2431,7 +2502,7 @@ type CancelRequest struct { func (x *CancelRequest) Reset() { *x = CancelRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2444,7 +2515,7 @@ func (x *CancelRequest) String() string { func (*CancelRequest) ProtoMessage() {} func (x *CancelRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2457,7 +2528,7 @@ func (x *CancelRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelRequest.ProtoReflect.Descriptor instead. func (*CancelRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{26} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{27} } type Request struct { @@ -2478,7 +2549,7 @@ type Request struct { func (x *Request) Reset() { *x = Request{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2491,7 +2562,7 @@ func (x *Request) String() string { func (*Request) ProtoMessage() {} func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2504,7 +2575,7 @@ func (x *Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Request.ProtoReflect.Descriptor instead. func (*Request) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{27} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{28} } func (m *Request) GetType() isRequest_Type { @@ -2600,7 +2671,7 @@ type Response struct { func (x *Response) Reset() { *x = Response{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2613,7 +2684,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2626,7 +2697,7 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{28} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{29} } func (m *Response) GetType() isResponse_Type { @@ -2708,7 +2779,7 @@ type Agent_Metadata struct { func (x *Agent_Metadata) Reset() { *x = Agent_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2721,7 +2792,7 @@ func (x *Agent_Metadata) String() string { func (*Agent_Metadata) ProtoMessage() {} func (x *Agent_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2793,7 +2864,7 @@ type Resource_Metadata struct { func (x *Resource_Metadata) Reset() { *x = Resource_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2806,7 +2877,7 @@ func (x *Resource_Metadata) String() string { func (*Resource_Metadata) ProtoMessage() {} func (x *Resource_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3324,7 +3395,7 @@ func file_provisionersdk_proto_provisioner_proto_rawDescGZIP() []byte { } var file_provisionersdk_proto_provisioner_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 33) +var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 34) var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (LogLevel)(0), // 0: provisioner.LogLevel (AppSharingLevel)(0), // 1: provisioner.AppSharingLevel @@ -3347,72 +3418,74 @@ var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (*App)(nil), // 18: provisioner.App (*Healthcheck)(nil), // 19: provisioner.Healthcheck (*Resource)(nil), // 20: provisioner.Resource - (*Metadata)(nil), // 21: provisioner.Metadata - (*Config)(nil), // 22: provisioner.Config - (*ParseRequest)(nil), // 23: provisioner.ParseRequest - (*ParseComplete)(nil), // 24: provisioner.ParseComplete - (*PlanRequest)(nil), // 25: provisioner.PlanRequest - (*PlanComplete)(nil), // 26: provisioner.PlanComplete - (*ApplyRequest)(nil), // 27: provisioner.ApplyRequest - (*ApplyComplete)(nil), // 28: provisioner.ApplyComplete - (*Timing)(nil), // 29: provisioner.Timing - (*CancelRequest)(nil), // 30: provisioner.CancelRequest - (*Request)(nil), // 31: provisioner.Request - (*Response)(nil), // 32: provisioner.Response - (*Agent_Metadata)(nil), // 33: provisioner.Agent.Metadata - nil, // 34: provisioner.Agent.EnvEntry - (*Resource_Metadata)(nil), // 35: provisioner.Resource.Metadata - nil, // 36: provisioner.ParseComplete.WorkspaceTagsEntry - (*timestamppb.Timestamp)(nil), // 37: google.protobuf.Timestamp + (*Module)(nil), // 21: provisioner.Module + (*Metadata)(nil), // 22: provisioner.Metadata + (*Config)(nil), // 23: provisioner.Config + (*ParseRequest)(nil), // 24: provisioner.ParseRequest + (*ParseComplete)(nil), // 25: provisioner.ParseComplete + (*PlanRequest)(nil), // 26: provisioner.PlanRequest + (*PlanComplete)(nil), // 27: provisioner.PlanComplete + (*ApplyRequest)(nil), // 28: provisioner.ApplyRequest + (*ApplyComplete)(nil), // 29: provisioner.ApplyComplete + (*Timing)(nil), // 30: provisioner.Timing + (*CancelRequest)(nil), // 31: provisioner.CancelRequest + (*Request)(nil), // 32: provisioner.Request + (*Response)(nil), // 33: provisioner.Response + (*Agent_Metadata)(nil), // 34: provisioner.Agent.Metadata + nil, // 35: provisioner.Agent.EnvEntry + (*Resource_Metadata)(nil), // 36: provisioner.Resource.Metadata + nil, // 37: provisioner.ParseComplete.WorkspaceTagsEntry + (*timestamppb.Timestamp)(nil), // 38: google.protobuf.Timestamp } var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{ 6, // 0: provisioner.RichParameter.options:type_name -> provisioner.RichParameterOption 0, // 1: provisioner.Log.level:type_name -> provisioner.LogLevel - 34, // 2: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry + 35, // 2: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry 18, // 3: provisioner.Agent.apps:type_name -> provisioner.App - 33, // 4: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata + 34, // 4: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata 15, // 5: provisioner.Agent.display_apps:type_name -> provisioner.DisplayApps 17, // 6: provisioner.Agent.scripts:type_name -> provisioner.Script 16, // 7: provisioner.Agent.extra_envs:type_name -> provisioner.Env 19, // 8: provisioner.App.healthcheck:type_name -> provisioner.Healthcheck 1, // 9: provisioner.App.sharing_level:type_name -> provisioner.AppSharingLevel 14, // 10: provisioner.Resource.agents:type_name -> provisioner.Agent - 35, // 11: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata + 36, // 11: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata 2, // 12: provisioner.Metadata.workspace_transition:type_name -> provisioner.WorkspaceTransition 5, // 13: provisioner.ParseComplete.template_variables:type_name -> provisioner.TemplateVariable - 36, // 14: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry - 21, // 15: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata + 37, // 14: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry + 22, // 15: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata 8, // 16: provisioner.PlanRequest.rich_parameter_values:type_name -> provisioner.RichParameterValue 9, // 17: provisioner.PlanRequest.variable_values:type_name -> provisioner.VariableValue 13, // 18: provisioner.PlanRequest.external_auth_providers:type_name -> provisioner.ExternalAuthProvider 20, // 19: provisioner.PlanComplete.resources:type_name -> provisioner.Resource 7, // 20: provisioner.PlanComplete.parameters:type_name -> provisioner.RichParameter 12, // 21: provisioner.PlanComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource - 29, // 22: provisioner.PlanComplete.timings:type_name -> provisioner.Timing - 21, // 23: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata - 20, // 24: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource - 7, // 25: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter - 12, // 26: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource - 29, // 27: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing - 37, // 28: provisioner.Timing.start:type_name -> google.protobuf.Timestamp - 37, // 29: provisioner.Timing.end:type_name -> google.protobuf.Timestamp - 3, // 30: provisioner.Timing.state:type_name -> provisioner.TimingState - 22, // 31: provisioner.Request.config:type_name -> provisioner.Config - 23, // 32: provisioner.Request.parse:type_name -> provisioner.ParseRequest - 25, // 33: provisioner.Request.plan:type_name -> provisioner.PlanRequest - 27, // 34: provisioner.Request.apply:type_name -> provisioner.ApplyRequest - 30, // 35: provisioner.Request.cancel:type_name -> provisioner.CancelRequest - 10, // 36: provisioner.Response.log:type_name -> provisioner.Log - 24, // 37: provisioner.Response.parse:type_name -> provisioner.ParseComplete - 26, // 38: provisioner.Response.plan:type_name -> provisioner.PlanComplete - 28, // 39: provisioner.Response.apply:type_name -> provisioner.ApplyComplete - 31, // 40: provisioner.Provisioner.Session:input_type -> provisioner.Request - 32, // 41: provisioner.Provisioner.Session:output_type -> provisioner.Response - 41, // [41:42] is the sub-list for method output_type - 40, // [40:41] is the sub-list for method input_type - 40, // [40:40] is the sub-list for extension type_name - 40, // [40:40] is the sub-list for extension extendee - 0, // [0:40] is the sub-list for field type_name + 30, // 22: provisioner.PlanComplete.timings:type_name -> provisioner.Timing + 21, // 23: provisioner.PlanComplete.modules:type_name -> provisioner.Module + 22, // 24: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata + 20, // 25: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource + 7, // 26: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter + 12, // 27: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource + 30, // 28: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing + 38, // 29: provisioner.Timing.start:type_name -> google.protobuf.Timestamp + 38, // 30: provisioner.Timing.end:type_name -> google.protobuf.Timestamp + 3, // 31: provisioner.Timing.state:type_name -> provisioner.TimingState + 23, // 32: provisioner.Request.config:type_name -> provisioner.Config + 24, // 33: provisioner.Request.parse:type_name -> provisioner.ParseRequest + 26, // 34: provisioner.Request.plan:type_name -> provisioner.PlanRequest + 28, // 35: provisioner.Request.apply:type_name -> provisioner.ApplyRequest + 31, // 36: provisioner.Request.cancel:type_name -> provisioner.CancelRequest + 10, // 37: provisioner.Response.log:type_name -> provisioner.Log + 25, // 38: provisioner.Response.parse:type_name -> provisioner.ParseComplete + 27, // 39: provisioner.Response.plan:type_name -> provisioner.PlanComplete + 29, // 40: provisioner.Response.apply:type_name -> provisioner.ApplyComplete + 32, // 41: provisioner.Provisioner.Session:input_type -> provisioner.Request + 33, // 42: provisioner.Provisioner.Session:output_type -> provisioner.Response + 42, // [42:43] is the sub-list for method output_type + 41, // [41:42] is the sub-list for method input_type + 41, // [41:41] is the sub-list for extension type_name + 41, // [41:41] is the sub-list for extension extendee + 0, // [0:41] is the sub-list for field type_name } func init() { file_provisionersdk_proto_provisioner_proto_init() } @@ -3626,7 +3699,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metadata); i { + switch v := v.(*Module); i { case 0: return &v.state case 1: @@ -3638,7 +3711,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Config); i { + switch v := v.(*Metadata); i { case 0: return &v.state case 1: @@ -3650,7 +3723,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParseRequest); i { + switch v := v.(*Config); i { case 0: return &v.state case 1: @@ -3662,7 +3735,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParseComplete); i { + switch v := v.(*ParseRequest); i { case 0: return &v.state case 1: @@ -3674,7 +3747,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlanRequest); i { + switch v := v.(*ParseComplete); i { case 0: return &v.state case 1: @@ -3686,7 +3759,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlanComplete); i { + switch v := v.(*PlanRequest); i { case 0: return &v.state case 1: @@ -3698,7 +3771,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyRequest); i { + switch v := v.(*PlanComplete); i { case 0: return &v.state case 1: @@ -3710,7 +3783,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyComplete); i { + switch v := v.(*ApplyRequest); i { case 0: return &v.state case 1: @@ -3722,7 +3795,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Timing); i { + switch v := v.(*ApplyComplete); i { case 0: return &v.state case 1: @@ -3734,7 +3807,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CancelRequest); i { + switch v := v.(*Timing); i { case 0: return &v.state case 1: @@ -3746,7 +3819,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Request); i { + switch v := v.(*CancelRequest); i { case 0: return &v.state case 1: @@ -3758,7 +3831,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { + switch v := v.(*Request); i { case 0: return &v.state case 1: @@ -3770,6 +3843,18 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_provisionersdk_proto_provisioner_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Agent_Metadata); i { case 0: return &v.state @@ -3781,7 +3866,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Resource_Metadata); i { case 0: return &v.state @@ -3799,14 +3884,14 @@ func file_provisionersdk_proto_provisioner_proto_init() { (*Agent_Token)(nil), (*Agent_InstanceId)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[27].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[28].OneofWrappers = []interface{}{ (*Request_Config)(nil), (*Request_Parse)(nil), (*Request_Plan)(nil), (*Request_Apply)(nil), (*Request_Cancel)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[28].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[29].OneofWrappers = []interface{}{ (*Response_Log)(nil), (*Response_Parse)(nil), (*Response_Plan)(nil), @@ -3818,7 +3903,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_provisionersdk_proto_provisioner_proto_rawDesc, NumEnums: 4, - NumMessages: 33, + NumMessages: 34, NumExtensions: 0, NumServices: 1, }, diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index 36acd14bef30a..2587216603f58 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -206,6 +206,12 @@ message Resource { int32 daily_cost = 8; } +message Module { + string source = 1; + string version = 2; + string key = 3; +} + // WorkspaceTransition is the desired outcome of a build enum WorkspaceTransition { START = 0; @@ -271,6 +277,7 @@ message PlanComplete { repeated RichParameter parameters = 3; repeated ExternalAuthProviderResource external_auth_providers = 4; repeated Timing timings = 6; + repeated Module modules = 7; } // ApplyRequest asks the provisioner to apply the changes. Apply MUST be preceded by a successful plan request/response diff --git a/site/e2e/provisionerGenerated.ts b/site/e2e/provisionerGenerated.ts index b042e4cec41b1..3cbc0ab667adf 100644 --- a/site/e2e/provisionerGenerated.ts +++ b/site/e2e/provisionerGenerated.ts @@ -224,6 +224,12 @@ export interface Resource_Metadata { isNull: boolean; } +export interface Module { + source: string; + version: string; + key: string; +} + /** Metadata is information about a workspace used in the execution of a build */ export interface Metadata { coderUrl: string; @@ -286,6 +292,7 @@ export interface PlanComplete { parameters: RichParameter[]; externalAuthProviders: ExternalAuthProviderResource[]; timings: Timing[]; + modules: Module[]; } /** @@ -823,6 +830,24 @@ export const Resource_Metadata = { }, }; +export const Module = { + encode( + message: Module, + writer: _m0.Writer = _m0.Writer.create(), + ): _m0.Writer { + if (message.source !== "") { + writer.uint32(10).string(message.source); + } + if (message.version !== "") { + writer.uint32(18).string(message.version); + } + if (message.key !== "") { + writer.uint32(26).string(message.key); + } + return writer; + }, +}; + export const Metadata = { encode( message: Metadata, @@ -996,6 +1021,9 @@ export const PlanComplete = { for (const v of message.timings) { Timing.encode(v!, writer.uint32(50).fork()).ldelim(); } + for (const v of message.modules) { + Module.encode(v!, writer.uint32(58).fork()).ldelim(); + } return writer; }, }; From 307a57e0ea74b4629127cd55025c6cbec65edaf8 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Wed, 6 Nov 2024 16:45:11 +0000 Subject: [PATCH 03/34] add foreign key to job on workspace_modules --- coderd/database/dump.sql | 3 +++ coderd/database/foreign_key_constraint.go | 1 + coderd/database/migrations/000274_workspace_modules.up.sql | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 4c2264e754860..8907b85f5ab9f 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -2371,6 +2371,9 @@ ALTER TABLE ONLY workspace_builds ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY workspace_modules + ADD CONSTRAINT workspace_modules_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; + ALTER TABLE ONLY workspace_resource_metadata ADD CONSTRAINT workspace_resource_metadata_workspace_resource_id_fkey FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go index f142e729b2f38..669ab85f945bd 100644 --- a/coderd/database/foreign_key_constraint.go +++ b/coderd/database/foreign_key_constraint.go @@ -65,6 +65,7 @@ const ( ForeignKeyWorkspaceBuildsJobID ForeignKeyConstraint = "workspace_builds_job_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; ForeignKeyWorkspaceBuildsTemplateVersionID ForeignKeyConstraint = "workspace_builds_template_version_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE; ForeignKeyWorkspaceBuildsWorkspaceID ForeignKeyConstraint = "workspace_builds_workspace_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; + ForeignKeyWorkspaceModulesJobID ForeignKeyConstraint = "workspace_modules_job_id_fkey" // ALTER TABLE ONLY workspace_modules ADD CONSTRAINT workspace_modules_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; ForeignKeyWorkspaceResourceMetadataWorkspaceResourceID ForeignKeyConstraint = "workspace_resource_metadata_workspace_resource_id_fkey" // ALTER TABLE ONLY workspace_resource_metadata ADD CONSTRAINT workspace_resource_metadata_workspace_resource_id_fkey FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; ForeignKeyWorkspaceResourcesJobID ForeignKeyConstraint = "workspace_resources_job_id_fkey" // ALTER TABLE ONLY workspace_resources ADD CONSTRAINT workspace_resources_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; ForeignKeyWorkspacesOrganizationID ForeignKeyConstraint = "workspaces_organization_id_fkey" // ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE RESTRICT; diff --git a/coderd/database/migrations/000274_workspace_modules.up.sql b/coderd/database/migrations/000274_workspace_modules.up.sql index 753fcff8997c3..9aebf378405da 100644 --- a/coderd/database/migrations/000274_workspace_modules.up.sql +++ b/coderd/database/migrations/000274_workspace_modules.up.sql @@ -5,7 +5,7 @@ ADD CREATE TABLE workspace_modules ( id uuid NOT NULL, - job_id uuid NOT NULL, + job_id uuid NOT NULL REFERENCES provisioner_jobs (id) ON DELETE CASCADE, transition workspace_transition NOT NULL, source TEXT NOT NULL, version TEXT NOT NULL, From 2ae16fc9f6303b5709f455da8f7301c51ad11d64 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Thu, 7 Nov 2024 10:26:11 +0000 Subject: [PATCH 04/34] don't return the root module --- provisioner/terraform/modules.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/provisioner/terraform/modules.go b/provisioner/terraform/modules.go index e375cfca97feb..b062633117d47 100644 --- a/provisioner/terraform/modules.go +++ b/provisioner/terraform/modules.go @@ -48,5 +48,17 @@ func getModules(workdir string) ([]*proto.Module, error) { if _, err := os.Stat(filePath); os.IsNotExist(err) { return nil, nil } - return parseModulesFile(filePath) + modules, err := parseModulesFile(filePath) + if err != nil { + return nil, xerrors.Errorf("parse modules file: %w", err) + } + filteredModules := []*proto.Module{} + for _, m := range modules { + // Empty string means root module. It's always present, so we skip it. + if m.Source == "" { + continue + } + filteredModules = append(filteredModules, m) + } + return filteredModules, nil } From 7f2f15551ddcf33686e443e75a1912424efa71b1 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Thu, 7 Nov 2024 15:15:13 +0000 Subject: [PATCH 05/34] add and populate the module_path column to workspace_resources --- coderd/database/dbgen/dbgen.go | 4 + coderd/database/dump.sql | 2 +- .../000274_workspace_modules.down.sql | 2 +- .../000274_workspace_modules.up.sql | 2 +- coderd/database/models.go | 2 +- coderd/database/queries.sql.go | 24 +- .../database/queries/workspaceresources.sql | 4 +- .../provisionerdserver/provisionerdserver.go | 5 + go.mod | 1 + go.sum | 2 + provisioner/terraform/resources.go | 24 ++ provisionersdk/proto/provisioner.pb.go | 293 +++++++----------- provisionersdk/proto/provisioner.proto | 1 + site/e2e/provisionerGenerated.ts | 4 + 14 files changed, 164 insertions(+), 206 deletions(-) diff --git a/coderd/database/dbgen/dbgen.go b/coderd/database/dbgen/dbgen.go index 1ad3d1fe083b7..686025e6ca41f 100644 --- a/coderd/database/dbgen/dbgen.go +++ b/coderd/database/dbgen/dbgen.go @@ -657,6 +657,10 @@ func WorkspaceResource(t testing.TB, db database.Store, orig database.WorkspaceR Valid: takeFirst(orig.InstanceType.Valid, false), }, DailyCost: takeFirst(orig.DailyCost, 0), + ModulePath: sql.NullString{ + String: takeFirst(orig.ModulePath.String, ""), + Valid: takeFirst(orig.ModulePath.Valid, true), + }, }) require.NoError(t, err, "insert resource") return resource diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 8907b85f5ab9f..01fce9b24ee54 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1711,7 +1711,7 @@ CREATE TABLE workspace_resources ( icon character varying(256) DEFAULT ''::character varying NOT NULL, instance_type character varying(256), daily_cost integer DEFAULT 0 NOT NULL, - module text + module_path text ); CREATE TABLE workspaces ( diff --git a/coderd/database/migrations/000274_workspace_modules.down.sql b/coderd/database/migrations/000274_workspace_modules.down.sql index afa5c84ceef66..907f0bad7f8e9 100644 --- a/coderd/database/migrations/000274_workspace_modules.down.sql +++ b/coderd/database/migrations/000274_workspace_modules.down.sql @@ -2,4 +2,4 @@ DROP TABLE workspace_modules; ALTER TABLE workspace_resources -DROP COLUMN module; +DROP COLUMN module_path; diff --git a/coderd/database/migrations/000274_workspace_modules.up.sql b/coderd/database/migrations/000274_workspace_modules.up.sql index 9aebf378405da..8d4c475cf8a9a 100644 --- a/coderd/database/migrations/000274_workspace_modules.up.sql +++ b/coderd/database/migrations/000274_workspace_modules.up.sql @@ -1,7 +1,7 @@ ALTER TABLE workspace_resources ADD - COLUMN module TEXT; + COLUMN module_path TEXT; CREATE TABLE workspace_modules ( id uuid NOT NULL, diff --git a/coderd/database/models.go b/coderd/database/models.go index 345d9296d60fe..af0a3122f7964 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -3196,7 +3196,7 @@ type WorkspaceResource struct { Icon string `db:"icon" json:"icon"` InstanceType sql.NullString `db:"instance_type" json:"instance_type"` DailyCost int32 `db:"daily_cost" json:"daily_cost"` - Module sql.NullString `db:"module" json:"module"` + ModulePath sql.NullString `db:"module_path" json:"module_path"` } type WorkspaceResourceMetadatum struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 7e8c892c6b806..6b5996e7edacc 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -14157,7 +14157,7 @@ func (q *sqlQuerier) InsertWorkspaceModule(ctx context.Context, arg InsertWorksp const getWorkspaceResourceByID = `-- name: GetWorkspaceResourceByID :one SELECT - id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module + id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module_path FROM workspace_resources WHERE @@ -14178,7 +14178,7 @@ func (q *sqlQuerier) GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID) &i.Icon, &i.InstanceType, &i.DailyCost, - &i.Module, + &i.ModulePath, ) return i, err } @@ -14258,7 +14258,7 @@ func (q *sqlQuerier) GetWorkspaceResourceMetadataCreatedAfter(ctx context.Contex const getWorkspaceResourcesByJobID = `-- name: GetWorkspaceResourcesByJobID :many SELECT - id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module + id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module_path FROM workspace_resources WHERE @@ -14285,7 +14285,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uui &i.Icon, &i.InstanceType, &i.DailyCost, - &i.Module, + &i.ModulePath, ); err != nil { return nil, err } @@ -14302,7 +14302,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uui const getWorkspaceResourcesByJobIDs = `-- name: GetWorkspaceResourcesByJobIDs :many SELECT - id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module + id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module_path FROM workspace_resources WHERE @@ -14329,7 +14329,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobIDs(ctx context.Context, ids []uu &i.Icon, &i.InstanceType, &i.DailyCost, - &i.Module, + &i.ModulePath, ); err != nil { return nil, err } @@ -14345,7 +14345,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobIDs(ctx context.Context, ids []uu } const getWorkspaceResourcesCreatedAfter = `-- name: GetWorkspaceResourcesCreatedAfter :many -SELECT id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module FROM workspace_resources WHERE created_at > $1 +SELECT id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module_path FROM workspace_resources WHERE created_at > $1 ` func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResource, error) { @@ -14368,7 +14368,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, crea &i.Icon, &i.InstanceType, &i.DailyCost, - &i.Module, + &i.ModulePath, ); err != nil { return nil, err } @@ -14385,9 +14385,9 @@ func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, crea const insertWorkspaceResource = `-- name: InsertWorkspaceResource :one INSERT INTO - workspace_resources (id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost) + workspace_resources (id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module_path) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module_path ` type InsertWorkspaceResourceParams struct { @@ -14401,6 +14401,7 @@ type InsertWorkspaceResourceParams struct { Icon string `db:"icon" json:"icon"` InstanceType sql.NullString `db:"instance_type" json:"instance_type"` DailyCost int32 `db:"daily_cost" json:"daily_cost"` + ModulePath sql.NullString `db:"module_path" json:"module_path"` } func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) { @@ -14415,6 +14416,7 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork arg.Icon, arg.InstanceType, arg.DailyCost, + arg.ModulePath, ) var i WorkspaceResource err := row.Scan( @@ -14428,7 +14430,7 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork &i.Icon, &i.InstanceType, &i.DailyCost, - &i.Module, + &i.ModulePath, ) return i, err } diff --git a/coderd/database/queries/workspaceresources.sql b/coderd/database/queries/workspaceresources.sql index 0c240c909ec4d..63fb9a26374a8 100644 --- a/coderd/database/queries/workspaceresources.sql +++ b/coderd/database/queries/workspaceresources.sql @@ -27,9 +27,9 @@ SELECT * FROM workspace_resources WHERE created_at > $1; -- name: InsertWorkspaceResource :one INSERT INTO - workspace_resources (id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost) + workspace_resources (id, created_at, job_id, transition, type, name, hide, icon, instance_type, daily_cost, module_path) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *; + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING *; -- name: GetWorkspaceResourceMetadataByResourceIDs :many SELECT diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index ccaf29b0af55f..a9dc997672a70 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1800,6 +1800,11 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. String: protoResource.InstanceType, Valid: protoResource.InstanceType != "", }, + ModulePath: sql.NullString{ + String: protoResource.ModulePath, + // empty string is root module + Valid: true, + }, }) if err != nil { return xerrors.Errorf("insert provisioner job resource %q: %w", protoResource.Name, err) diff --git a/go.mod b/go.mod index 69c6752d806e8..53fe95ffb4cd1 100644 --- a/go.mod +++ b/go.mod @@ -344,6 +344,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-terraform-address v0.0.0-20240523040243-ccea9d309e0c github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/hashicorp/hcl/v2 v2.22.0 diff --git a/go.sum b/go.sum index bc0b036b823d7..3a1a55ca1124e 100644 --- a/go.sum +++ b/go.sum @@ -562,6 +562,8 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9 github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-terraform-address v0.0.0-20240523040243-ccea9d309e0c h1:5v6L/m/HcAZYbrLGYBpPkcCVtDWwIgFxq2+FUmfPxPk= +github.com/hashicorp/go-terraform-address v0.0.0-20240523040243-ccea9d309e0c/go.mod h1:xoy1vl2+4YvqSQEkKcFjNYxTk7cll+o1f1t2wxnHIX8= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index ca32aa25a6ac8..90b853c88896d 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -11,6 +11,8 @@ import ( "github.com/coder/terraform-provider-coder/provider" + tfaddr "github.com/hashicorp/go-terraform-address" + "github.com/coder/coder/v2/coderd/util/slice" stringutil "github.com/coder/coder/v2/coderd/util/strings" "github.com/coder/coder/v2/codersdk" @@ -593,6 +595,13 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error continue } label := convertAddressToLabel(resource.Address) + modulePath, err := convertAddressToModulePath(resource.Address) + if err != nil { + // Module path recording was added primarily to keep track of + // modules in telemetry. We're adding this fallback so we can + // detect if there are any issues with the address parsing. + modulePath = fmt.Sprintf("error parsing address: %s", resource.Address) + } agents, exists := resourceAgents[label] if exists { @@ -608,6 +617,7 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error Icon: resourceIcon[label], DailyCost: resourceCost[label], InstanceType: applyInstanceType(resource), + ModulePath: modulePath, }) } } @@ -752,6 +762,20 @@ func convertAddressToLabel(address string) string { return cut } +// convertAddressToModulePath returns the module path from a Terraform address. +// eg. "module.ec2_dev.ec2_instance.dev[0]" becomes "module.ec2_dev". +// Empty string is returned for the root module. +// +// Module paths are defined in the Terraform spec: +// https://github.com/hashicorp/terraform/blob/ef071f3d0e49ba421ae931c65b263827a8af1adb/website/docs/internals/resource-addressing.html.markdown#module-path +func convertAddressToModulePath(address string) (string, error) { + addr, err := tfaddr.NewAddress(address) + if err != nil { + return "", xerrors.Errorf("parse address: %w", err) + } + return addr.ModulePath.String(), nil +} + func dependsOnAgent(graph *gographviz.Graph, agent *proto.Agent, resourceAgentID string, resource *tfjson.StateResource) bool { // Plan: we need to find if there is edge between the agent and the resource. if agent.Id == "" && resourceAgentID == "" { diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 1beb9dab66e6b..9d5406d403375 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -1676,69 +1676,6 @@ func (x *Resource) GetDailyCost() int32 { return 0 } -type Module struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` - Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` -} - -func (x *Module) Reset() { - *x = Module{} - if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Module) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Module) ProtoMessage() {} - -func (x *Module) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] - 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 Module.ProtoReflect.Descriptor instead. -func (*Module) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{17} -} - -func (x *Module) GetSource() string { - if x != nil { - return x.Source - } - return "" -} - -func (x *Module) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *Module) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - // Metadata is information about a workspace used in the execution of a build type Metadata struct { state protoimpl.MessageState @@ -1768,7 +1705,7 @@ type Metadata struct { func (x *Metadata) Reset() { *x = Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1781,7 +1718,7 @@ func (x *Metadata) String() string { func (*Metadata) ProtoMessage() {} func (x *Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1794,7 +1731,7 @@ func (x *Metadata) ProtoReflect() protoreflect.Message { // Deprecated: Use Metadata.ProtoReflect.Descriptor instead. func (*Metadata) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{18} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{17} } func (x *Metadata) GetCoderUrl() string { @@ -1939,7 +1876,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1952,7 +1889,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1965,7 +1902,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{19} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{18} } func (x *Config) GetTemplateSourceArchive() []byte { @@ -1999,7 +1936,7 @@ type ParseRequest struct { func (x *ParseRequest) Reset() { *x = ParseRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2012,7 +1949,7 @@ func (x *ParseRequest) String() string { func (*ParseRequest) ProtoMessage() {} func (x *ParseRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2025,7 +1962,7 @@ func (x *ParseRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseRequest.ProtoReflect.Descriptor instead. func (*ParseRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{20} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{19} } // ParseComplete indicates a request to parse completed. @@ -2043,7 +1980,7 @@ type ParseComplete struct { func (x *ParseComplete) Reset() { *x = ParseComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2056,7 +1993,7 @@ func (x *ParseComplete) String() string { func (*ParseComplete) ProtoMessage() {} func (x *ParseComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2069,7 +2006,7 @@ func (x *ParseComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseComplete.ProtoReflect.Descriptor instead. func (*ParseComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{21} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{20} } func (x *ParseComplete) GetError() string { @@ -2115,7 +2052,7 @@ type PlanRequest struct { func (x *PlanRequest) Reset() { *x = PlanRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2128,7 +2065,7 @@ func (x *PlanRequest) String() string { func (*PlanRequest) ProtoMessage() {} func (x *PlanRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2141,7 +2078,7 @@ func (x *PlanRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanRequest.ProtoReflect.Descriptor instead. func (*PlanRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{22} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{21} } func (x *PlanRequest) GetMetadata() *Metadata { @@ -2183,13 +2120,12 @@ type PlanComplete struct { Parameters []*RichParameter `protobuf:"bytes,3,rep,name=parameters,proto3" json:"parameters,omitempty"` ExternalAuthProviders []*ExternalAuthProviderResource `protobuf:"bytes,4,rep,name=external_auth_providers,json=externalAuthProviders,proto3" json:"external_auth_providers,omitempty"` Timings []*Timing `protobuf:"bytes,6,rep,name=timings,proto3" json:"timings,omitempty"` - Modules []*Module `protobuf:"bytes,7,rep,name=modules,proto3" json:"modules,omitempty"` } func (x *PlanComplete) Reset() { *x = PlanComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2202,7 +2138,7 @@ func (x *PlanComplete) String() string { func (*PlanComplete) ProtoMessage() {} func (x *PlanComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2215,7 +2151,7 @@ func (x *PlanComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanComplete.ProtoReflect.Descriptor instead. func (*PlanComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{23} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{22} } func (x *PlanComplete) GetError() string { @@ -2253,13 +2189,6 @@ func (x *PlanComplete) GetTimings() []*Timing { return nil } -func (x *PlanComplete) GetModules() []*Module { - if x != nil { - return x.Modules - } - return nil -} - // ApplyRequest asks the provisioner to apply the changes. Apply MUST be preceded by a successful plan request/response // in the same Session. The plan data is not transmitted over the wire and is cached by the provisioner in the Session. type ApplyRequest struct { @@ -2273,7 +2202,7 @@ type ApplyRequest struct { func (x *ApplyRequest) Reset() { *x = ApplyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2286,7 +2215,7 @@ func (x *ApplyRequest) String() string { func (*ApplyRequest) ProtoMessage() {} func (x *ApplyRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2299,7 +2228,7 @@ func (x *ApplyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyRequest.ProtoReflect.Descriptor instead. func (*ApplyRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{24} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{23} } func (x *ApplyRequest) GetMetadata() *Metadata { @@ -2326,7 +2255,7 @@ type ApplyComplete struct { func (x *ApplyComplete) Reset() { *x = ApplyComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2339,7 +2268,7 @@ func (x *ApplyComplete) String() string { func (*ApplyComplete) ProtoMessage() {} func (x *ApplyComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2352,7 +2281,7 @@ func (x *ApplyComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyComplete.ProtoReflect.Descriptor instead. func (*ApplyComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{25} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{24} } func (x *ApplyComplete) GetState() []byte { @@ -2414,7 +2343,7 @@ type Timing struct { func (x *Timing) Reset() { *x = Timing{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2427,7 +2356,7 @@ func (x *Timing) String() string { func (*Timing) ProtoMessage() {} func (x *Timing) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2440,7 +2369,7 @@ func (x *Timing) ProtoReflect() protoreflect.Message { // Deprecated: Use Timing.ProtoReflect.Descriptor instead. func (*Timing) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{26} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{25} } func (x *Timing) GetStart() *timestamppb.Timestamp { @@ -2502,7 +2431,7 @@ type CancelRequest struct { func (x *CancelRequest) Reset() { *x = CancelRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2515,7 +2444,7 @@ func (x *CancelRequest) String() string { func (*CancelRequest) ProtoMessage() {} func (x *CancelRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2528,7 +2457,7 @@ func (x *CancelRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelRequest.ProtoReflect.Descriptor instead. func (*CancelRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{27} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{26} } type Request struct { @@ -2549,7 +2478,7 @@ type Request struct { func (x *Request) Reset() { *x = Request{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2562,7 +2491,7 @@ func (x *Request) String() string { func (*Request) ProtoMessage() {} func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2575,7 +2504,7 @@ func (x *Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Request.ProtoReflect.Descriptor instead. func (*Request) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{28} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{27} } func (m *Request) GetType() isRequest_Type { @@ -2671,7 +2600,7 @@ type Response struct { func (x *Response) Reset() { *x = Response{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2684,7 +2613,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2697,7 +2626,7 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{29} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{28} } func (m *Response) GetType() isResponse_Type { @@ -2779,7 +2708,7 @@ type Agent_Metadata struct { func (x *Agent_Metadata) Reset() { *x = Agent_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[30] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2792,7 +2721,7 @@ func (x *Agent_Metadata) String() string { func (*Agent_Metadata) ProtoMessage() {} func (x *Agent_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[30] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2864,7 +2793,7 @@ type Resource_Metadata struct { func (x *Resource_Metadata) Reset() { *x = Resource_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2877,7 +2806,7 @@ func (x *Resource_Metadata) String() string { func (*Resource_Metadata) ProtoMessage() {} func (x *Resource_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3395,7 +3324,7 @@ func file_provisionersdk_proto_provisioner_proto_rawDescGZIP() []byte { } var file_provisionersdk_proto_provisioner_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 34) +var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 33) var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (LogLevel)(0), // 0: provisioner.LogLevel (AppSharingLevel)(0), // 1: provisioner.AppSharingLevel @@ -3418,74 +3347,72 @@ var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (*App)(nil), // 18: provisioner.App (*Healthcheck)(nil), // 19: provisioner.Healthcheck (*Resource)(nil), // 20: provisioner.Resource - (*Module)(nil), // 21: provisioner.Module - (*Metadata)(nil), // 22: provisioner.Metadata - (*Config)(nil), // 23: provisioner.Config - (*ParseRequest)(nil), // 24: provisioner.ParseRequest - (*ParseComplete)(nil), // 25: provisioner.ParseComplete - (*PlanRequest)(nil), // 26: provisioner.PlanRequest - (*PlanComplete)(nil), // 27: provisioner.PlanComplete - (*ApplyRequest)(nil), // 28: provisioner.ApplyRequest - (*ApplyComplete)(nil), // 29: provisioner.ApplyComplete - (*Timing)(nil), // 30: provisioner.Timing - (*CancelRequest)(nil), // 31: provisioner.CancelRequest - (*Request)(nil), // 32: provisioner.Request - (*Response)(nil), // 33: provisioner.Response - (*Agent_Metadata)(nil), // 34: provisioner.Agent.Metadata - nil, // 35: provisioner.Agent.EnvEntry - (*Resource_Metadata)(nil), // 36: provisioner.Resource.Metadata - nil, // 37: provisioner.ParseComplete.WorkspaceTagsEntry - (*timestamppb.Timestamp)(nil), // 38: google.protobuf.Timestamp + (*Metadata)(nil), // 21: provisioner.Metadata + (*Config)(nil), // 22: provisioner.Config + (*ParseRequest)(nil), // 23: provisioner.ParseRequest + (*ParseComplete)(nil), // 24: provisioner.ParseComplete + (*PlanRequest)(nil), // 25: provisioner.PlanRequest + (*PlanComplete)(nil), // 26: provisioner.PlanComplete + (*ApplyRequest)(nil), // 27: provisioner.ApplyRequest + (*ApplyComplete)(nil), // 28: provisioner.ApplyComplete + (*Timing)(nil), // 29: provisioner.Timing + (*CancelRequest)(nil), // 30: provisioner.CancelRequest + (*Request)(nil), // 31: provisioner.Request + (*Response)(nil), // 32: provisioner.Response + (*Agent_Metadata)(nil), // 33: provisioner.Agent.Metadata + nil, // 34: provisioner.Agent.EnvEntry + (*Resource_Metadata)(nil), // 35: provisioner.Resource.Metadata + nil, // 36: provisioner.ParseComplete.WorkspaceTagsEntry + (*timestamppb.Timestamp)(nil), // 37: google.protobuf.Timestamp } var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{ 6, // 0: provisioner.RichParameter.options:type_name -> provisioner.RichParameterOption 0, // 1: provisioner.Log.level:type_name -> provisioner.LogLevel - 35, // 2: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry + 34, // 2: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry 18, // 3: provisioner.Agent.apps:type_name -> provisioner.App - 34, // 4: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata + 33, // 4: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata 15, // 5: provisioner.Agent.display_apps:type_name -> provisioner.DisplayApps 17, // 6: provisioner.Agent.scripts:type_name -> provisioner.Script 16, // 7: provisioner.Agent.extra_envs:type_name -> provisioner.Env 19, // 8: provisioner.App.healthcheck:type_name -> provisioner.Healthcheck 1, // 9: provisioner.App.sharing_level:type_name -> provisioner.AppSharingLevel 14, // 10: provisioner.Resource.agents:type_name -> provisioner.Agent - 36, // 11: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata + 35, // 11: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata 2, // 12: provisioner.Metadata.workspace_transition:type_name -> provisioner.WorkspaceTransition 5, // 13: provisioner.ParseComplete.template_variables:type_name -> provisioner.TemplateVariable - 37, // 14: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry - 22, // 15: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata + 36, // 14: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry + 21, // 15: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata 8, // 16: provisioner.PlanRequest.rich_parameter_values:type_name -> provisioner.RichParameterValue 9, // 17: provisioner.PlanRequest.variable_values:type_name -> provisioner.VariableValue 13, // 18: provisioner.PlanRequest.external_auth_providers:type_name -> provisioner.ExternalAuthProvider 20, // 19: provisioner.PlanComplete.resources:type_name -> provisioner.Resource 7, // 20: provisioner.PlanComplete.parameters:type_name -> provisioner.RichParameter 12, // 21: provisioner.PlanComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource - 30, // 22: provisioner.PlanComplete.timings:type_name -> provisioner.Timing - 21, // 23: provisioner.PlanComplete.modules:type_name -> provisioner.Module - 22, // 24: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata - 20, // 25: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource - 7, // 26: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter - 12, // 27: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource - 30, // 28: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing - 38, // 29: provisioner.Timing.start:type_name -> google.protobuf.Timestamp - 38, // 30: provisioner.Timing.end:type_name -> google.protobuf.Timestamp - 3, // 31: provisioner.Timing.state:type_name -> provisioner.TimingState - 23, // 32: provisioner.Request.config:type_name -> provisioner.Config - 24, // 33: provisioner.Request.parse:type_name -> provisioner.ParseRequest - 26, // 34: provisioner.Request.plan:type_name -> provisioner.PlanRequest - 28, // 35: provisioner.Request.apply:type_name -> provisioner.ApplyRequest - 31, // 36: provisioner.Request.cancel:type_name -> provisioner.CancelRequest - 10, // 37: provisioner.Response.log:type_name -> provisioner.Log - 25, // 38: provisioner.Response.parse:type_name -> provisioner.ParseComplete - 27, // 39: provisioner.Response.plan:type_name -> provisioner.PlanComplete - 29, // 40: provisioner.Response.apply:type_name -> provisioner.ApplyComplete - 32, // 41: provisioner.Provisioner.Session:input_type -> provisioner.Request - 33, // 42: provisioner.Provisioner.Session:output_type -> provisioner.Response - 42, // [42:43] is the sub-list for method output_type - 41, // [41:42] is the sub-list for method input_type - 41, // [41:41] is the sub-list for extension type_name - 41, // [41:41] is the sub-list for extension extendee - 0, // [0:41] is the sub-list for field type_name + 29, // 22: provisioner.PlanComplete.timings:type_name -> provisioner.Timing + 21, // 23: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata + 20, // 24: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource + 7, // 25: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter + 12, // 26: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource + 29, // 27: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing + 37, // 28: provisioner.Timing.start:type_name -> google.protobuf.Timestamp + 37, // 29: provisioner.Timing.end:type_name -> google.protobuf.Timestamp + 3, // 30: provisioner.Timing.state:type_name -> provisioner.TimingState + 22, // 31: provisioner.Request.config:type_name -> provisioner.Config + 23, // 32: provisioner.Request.parse:type_name -> provisioner.ParseRequest + 25, // 33: provisioner.Request.plan:type_name -> provisioner.PlanRequest + 27, // 34: provisioner.Request.apply:type_name -> provisioner.ApplyRequest + 30, // 35: provisioner.Request.cancel:type_name -> provisioner.CancelRequest + 10, // 36: provisioner.Response.log:type_name -> provisioner.Log + 24, // 37: provisioner.Response.parse:type_name -> provisioner.ParseComplete + 26, // 38: provisioner.Response.plan:type_name -> provisioner.PlanComplete + 28, // 39: provisioner.Response.apply:type_name -> provisioner.ApplyComplete + 31, // 40: provisioner.Provisioner.Session:input_type -> provisioner.Request + 32, // 41: provisioner.Provisioner.Session:output_type -> provisioner.Response + 41, // [41:42] is the sub-list for method output_type + 40, // [40:41] is the sub-list for method input_type + 40, // [40:40] is the sub-list for extension type_name + 40, // [40:40] is the sub-list for extension extendee + 0, // [0:40] is the sub-list for field type_name } func init() { file_provisionersdk_proto_provisioner_proto_init() } @@ -3699,18 +3626,6 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Module); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_provisionersdk_proto_provisioner_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Metadata); i { case 0: return &v.state @@ -3722,7 +3637,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config); i { case 0: return &v.state @@ -3734,7 +3649,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ParseRequest); i { case 0: return &v.state @@ -3746,7 +3661,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ParseComplete); i { case 0: return &v.state @@ -3758,7 +3673,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanRequest); i { case 0: return &v.state @@ -3770,7 +3685,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlanComplete); i { case 0: return &v.state @@ -3782,7 +3697,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyRequest); i { case 0: return &v.state @@ -3794,7 +3709,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyComplete); i { case 0: return &v.state @@ -3806,7 +3721,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Timing); i { case 0: return &v.state @@ -3818,7 +3733,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CancelRequest); i { case 0: return &v.state @@ -3830,7 +3745,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Request); i { case 0: return &v.state @@ -3842,7 +3757,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Response); i { case 0: return &v.state @@ -3854,7 +3769,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Agent_Metadata); i { case 0: return &v.state @@ -3866,7 +3781,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Resource_Metadata); i { case 0: return &v.state @@ -3884,14 +3799,14 @@ func file_provisionersdk_proto_provisioner_proto_init() { (*Agent_Token)(nil), (*Agent_InstanceId)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[28].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[27].OneofWrappers = []interface{}{ (*Request_Config)(nil), (*Request_Parse)(nil), (*Request_Plan)(nil), (*Request_Apply)(nil), (*Request_Cancel)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[29].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[28].OneofWrappers = []interface{}{ (*Response_Log)(nil), (*Response_Parse)(nil), (*Response_Plan)(nil), @@ -3903,7 +3818,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_provisionersdk_proto_provisioner_proto_rawDesc, NumEnums: 4, - NumMessages: 34, + NumMessages: 33, NumExtensions: 0, NumServices: 1, }, diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index 2587216603f58..1e1de886c7d0a 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -204,6 +204,7 @@ message Resource { string icon = 6; string instance_type = 7; int32 daily_cost = 8; + string module_path = 9; } message Module { diff --git a/site/e2e/provisionerGenerated.ts b/site/e2e/provisionerGenerated.ts index 3cbc0ab667adf..9f238b0e47212 100644 --- a/site/e2e/provisionerGenerated.ts +++ b/site/e2e/provisionerGenerated.ts @@ -215,6 +215,7 @@ export interface Resource { icon: string; instanceType: string; dailyCost: number; + modulePath: string; } export interface Resource_Metadata { @@ -805,6 +806,9 @@ export const Resource = { if (message.dailyCost !== 0) { writer.uint32(64).int32(message.dailyCost); } + if (message.modulePath !== "") { + writer.uint32(74).string(message.modulePath); + } return writer; }, }; From 863235dbd455d8ee18e7404d460d723128c0bd57 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Thu, 7 Nov 2024 18:21:38 +0000 Subject: [PATCH 06/34] TestCompleteJob - Modules WIP --- coderd/database/dbauthz/dbauthz.go | 7 ++ coderd/database/dbmem/dbmem.go | 31 ++++- coderd/database/dbmetrics/querymetrics.go | 7 ++ coderd/database/querier.go | 1 + coderd/database/queries.sql.go | 40 ++++++ coderd/database/queries/workspacemodules.sql | 8 ++ .../provisionerdserver_test.go | 118 ++++++++++++++++++ 7 files changed, 211 insertions(+), 1 deletion(-) diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 949cdbc2a5d6b..f565876c3e238 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -2666,6 +2666,13 @@ func (q *querier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspaceApp return fetch(q.log, q.auth, q.db.GetWorkspaceByWorkspaceAppID)(ctx, workspaceAppID) } +func (q *querier) GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid.UUID) ([]database.WorkspaceModule, error) { + if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil { + return nil, err + } + return q.db.GetWorkspaceModulesByJobID(ctx, jobID) +} + func (q *querier) GetWorkspaceProxies(ctx context.Context) ([]database.WorkspaceProxy, error) { return fetchWithPostFilter(q.auth, policy.ActionRead, func(ctx context.Context, _ interface{}) ([]database.WorkspaceProxy, error) { return q.db.GetWorkspaceProxies(ctx) diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index ba542ebbc60d5..b23c870153a53 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -73,6 +73,7 @@ func New() database.Store { workspaceAgents: make([]database.WorkspaceAgent, 0), provisionerJobLogs: make([]database.ProvisionerJobLog, 0), workspaceResources: make([]database.WorkspaceResource, 0), + workspaceModules: make([]database.WorkspaceModule, 0), workspaceResourceMetadata: make([]database.WorkspaceResourceMetadatum, 0), provisionerJobs: make([]database.ProvisionerJob, 0), templateVersions: make([]database.TemplateVersionTable, 0), @@ -232,6 +233,7 @@ type data struct { workspaceBuildParameters []database.WorkspaceBuildParameter workspaceResourceMetadata []database.WorkspaceResourceMetadatum workspaceResources []database.WorkspaceResource + workspaceModules []database.WorkspaceModule workspaces []database.WorkspaceTable workspaceProxies []database.WorkspaceProxy customRoles []database.CustomRole @@ -6671,6 +6673,19 @@ func (q *FakeQuerier) GetWorkspaceByWorkspaceAppID(_ context.Context, workspaceA return database.Workspace{}, sql.ErrNoRows } +func (q *FakeQuerier) GetWorkspaceModulesByJobID(_ context.Context, jobID uuid.UUID) ([]database.WorkspaceModule, error) { + q.mutex.RLock() + defer q.mutex.RUnlock() + + modules := make([]database.WorkspaceModule, 0) + for _, module := range q.workspaceModules { + if module.JobID == jobID { + modules = append(modules, module) + } + } + return modules, nil +} + func (q *FakeQuerier) GetWorkspaceProxies(_ context.Context) ([]database.WorkspaceProxy, error) { q.mutex.RLock() defer q.mutex.RUnlock() @@ -8239,7 +8254,20 @@ func (q *FakeQuerier) InsertWorkspaceModule(ctx context.Context, arg database.In return database.WorkspaceModule{}, err } - panic("not implemented") + q.mutex.Lock() + defer q.mutex.Unlock() + + workspaceModule := database.WorkspaceModule{ + ID: arg.ID, + JobID: arg.JobID, + Transition: arg.Transition, + Source: arg.Source, + Version: arg.Version, + Key: arg.Key, + CreatedAt: arg.CreatedAt, + } + q.workspaceModules = append(q.workspaceModules, workspaceModule) + return workspaceModule, nil } func (q *FakeQuerier) InsertWorkspaceProxy(_ context.Context, arg database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) { @@ -8292,6 +8320,7 @@ func (q *FakeQuerier) InsertWorkspaceResource(_ context.Context, arg database.In Hide: arg.Hide, Icon: arg.Icon, DailyCost: arg.DailyCost, + ModulePath: arg.ModulePath, } q.workspaceResources = append(q.workspaceResources, resource) return resource, nil diff --git a/coderd/database/dbmetrics/querymetrics.go b/coderd/database/dbmetrics/querymetrics.go index bfa19c45ce573..2033f4977b030 100644 --- a/coderd/database/dbmetrics/querymetrics.go +++ b/coderd/database/dbmetrics/querymetrics.go @@ -1568,6 +1568,13 @@ func (m queryMetricsStore) GetWorkspaceByWorkspaceAppID(ctx context.Context, wor return workspace, err } +func (m queryMetricsStore) GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid.UUID) ([]database.WorkspaceModule, error) { + start := time.Now() + r0, r1 := m.s.GetWorkspaceModulesByJobID(ctx, jobID) + m.queryLatencies.WithLabelValues("GetWorkspaceModulesByJobID").Observe(time.Since(start).Seconds()) + return r0, r1 +} + func (m queryMetricsStore) GetWorkspaceProxies(ctx context.Context) ([]database.WorkspaceProxy, error) { start := time.Now() proxies, err := m.s.GetWorkspaceProxies(ctx) diff --git a/coderd/database/querier.go b/coderd/database/querier.go index 38b928dbc6b1a..c8acde1565f11 100644 --- a/coderd/database/querier.go +++ b/coderd/database/querier.go @@ -323,6 +323,7 @@ type sqlcQuerier interface { GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Workspace, error) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (Workspace, error) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspaceAppID uuid.UUID) (Workspace, error) + GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceModule, error) GetWorkspaceProxies(ctx context.Context) ([]WorkspaceProxy, error) // Finds a workspace proxy that has an access URL or app hostname that matches // the provided hostname. This is to check if a hostname matches any workspace diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 6b5996e7edacc..664b4f5dd87dd 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -14115,6 +14115,46 @@ func (q *sqlQuerier) UpdateWorkspaceBuildProvisionerStateByID(ctx context.Contex return err } +const getWorkspaceModulesByJobID = `-- name: GetWorkspaceModulesByJobID :many +SELECT + id, job_id, transition, source, version, key, created_at +FROM + workspace_modules +WHERE + job_id = $1 +` + +func (q *sqlQuerier) GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceModule, error) { + rows, err := q.db.QueryContext(ctx, getWorkspaceModulesByJobID, jobID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []WorkspaceModule + for rows.Next() { + var i WorkspaceModule + if err := rows.Scan( + &i.ID, + &i.JobID, + &i.Transition, + &i.Source, + &i.Version, + &i.Key, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const insertWorkspaceModule = `-- name: InsertWorkspaceModule :one INSERT INTO workspace_modules (id, job_id, transition, source, version, key, created_at) diff --git a/coderd/database/queries/workspacemodules.sql b/coderd/database/queries/workspacemodules.sql index 07fb57245963c..f9f54d3c90114 100644 --- a/coderd/database/queries/workspacemodules.sql +++ b/coderd/database/queries/workspacemodules.sql @@ -3,3 +3,11 @@ INSERT INTO workspace_modules (id, job_id, transition, source, version, key, created_at) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *; + +-- name: GetWorkspaceModulesByJobID :many +SELECT + * +FROM + workspace_modules +WHERE + job_id = $1; diff --git a/coderd/provisionerdserver/provisionerdserver_test.go b/coderd/provisionerdserver/provisionerdserver_test.go index b2d853a292b5d..9468072510930 100644 --- a/coderd/provisionerdserver/provisionerdserver_test.go +++ b/coderd/provisionerdserver/provisionerdserver_test.go @@ -1430,6 +1430,124 @@ func TestCompleteJob(t *testing.T) { }) require.NoError(t, err) }) + + t.Run("Modules", func(t *testing.T) { + t.Parallel() + srv, db, _, pd := setup(t, false, &overrides{}) + job, err := db.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ + ID: uuid.New(), + Provisioner: database.ProvisionerTypeEcho, + Type: database.ProvisionerJobTypeTemplateVersionDryRun, + StorageMethod: database.ProvisionerStorageMethodFile, + }) + require.NoError(t, err) + _, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{ + WorkerID: uuid.NullUUID{ + UUID: pd.ID, + Valid: true, + }, + Types: []database.ProvisionerType{database.ProvisionerTypeEcho}, + }) + require.NoError(t, err) + + cases := []struct { + name string + job *proto.CompletedJob + expectedResources []database.WorkspaceResource + expectedModules []database.WorkspaceModule + }{ + { + name: "TemplateDryRun", + job: &proto.CompletedJob{ + Type: &proto.CompletedJob_TemplateDryRun_{ + TemplateDryRun: &proto.CompletedJob_TemplateDryRun{ + Resources: []*sdkproto.Resource{{ + Name: "something", + Type: "aws_instance", + ModulePath: "module.test1", + }, { + Name: "something2", + Type: "aws_instance", + ModulePath: "", + }}, + Modules: []*sdkproto.Module{ + { + Key: "test1", + Version: "1.0.0", + Source: "github.com/example/example", + }, + }, + }, + }, + }, + expectedResources: []database.WorkspaceResource{{ + Name: "something", + Type: "aws_instance", + ModulePath: sql.NullString{ + String: "module.test1", + Valid: true, + }, + }, { + Name: "something2", + Type: "aws_instance", + ModulePath: sql.NullString{ + String: "", + Valid: true, + }, + }}, + expectedModules: []database.WorkspaceModule{{ + Key: "test1", + Version: "1.0.0", + Source: "github.com/example/example", + }}, + }, + } + + for _, c := range cases { + c := c + + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + completedJob := c.job + completedJob.JobId = job.ID.String() + + _, err = srv.CompleteJob(ctx, completedJob) + require.NoError(t, err) + + resources, err := db.GetWorkspaceResourcesByJobID(ctx, job.ID) + require.NoError(t, err) + require.Len(t, resources, len(c.expectedResources)) + + for _, expectedResource := range c.expectedResources { + for i, resource := range resources { + if resource.Name == expectedResource.Name && resource.Type == expectedResource.Type && resource.ModulePath == expectedResource.ModulePath { + resources[i] = database.WorkspaceResource{Name: "matched"} + } + } + } + // all resources should be matched + for _, resource := range resources { + require.Equal(t, "matched", resource.Name) + } + + modules, err := db.GetWorkspaceModulesByJobID(ctx, job.ID) + require.NoError(t, err) + require.Len(t, modules, len(c.expectedModules)) + + for _, expectedModule := range c.expectedModules { + for i, module := range modules { + if module.Key == expectedModule.Key && module.Version == expectedModule.Version && module.Source == expectedModule.Source { + modules[i] = database.WorkspaceModule{Key: "matched"} + } + } + } + for _, module := range modules { + require.Equal(t, "matched", module.Key) + } + }) + } + }) } func TestInsertWorkspaceResource(t *testing.T) { From 993f0ab3fea8bc2935b5ddf88289769d04e1538d Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 10:37:13 +0000 Subject: [PATCH 07/34] TemplateImport CompleteJob Modules test --- .../provisionerdserver_test.go | 144 +++++++++++++++--- 1 file changed, 119 insertions(+), 25 deletions(-) diff --git a/coderd/provisionerdserver/provisionerdserver_test.go b/coderd/provisionerdserver/provisionerdserver_test.go index 9468072510930..1d32be66ac875 100644 --- a/coderd/provisionerdserver/provisionerdserver_test.go +++ b/coderd/provisionerdserver/provisionerdserver_test.go @@ -1433,28 +1433,13 @@ func TestCompleteJob(t *testing.T) { t.Run("Modules", func(t *testing.T) { t.Parallel() - srv, db, _, pd := setup(t, false, &overrides{}) - job, err := db.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ - ID: uuid.New(), - Provisioner: database.ProvisionerTypeEcho, - Type: database.ProvisionerJobTypeTemplateVersionDryRun, - StorageMethod: database.ProvisionerStorageMethodFile, - }) - require.NoError(t, err) - _, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{ - WorkerID: uuid.NullUUID{ - UUID: pd.ID, - Valid: true, - }, - Types: []database.ProvisionerType{database.ProvisionerTypeEcho}, - }) - require.NoError(t, err) cases := []struct { - name string - job *proto.CompletedJob - expectedResources []database.WorkspaceResource - expectedModules []database.WorkspaceModule + name string + job *proto.CompletedJob + expectedResources []database.WorkspaceResource + expectedModules []database.WorkspaceModule + provisionerJobParams database.InsertProvisionerJobParams }{ { name: "TemplateDryRun", @@ -1487,6 +1472,7 @@ func TestCompleteJob(t *testing.T) { String: "module.test1", Valid: true, }, + Transition: database.WorkspaceTransitionStart, }, { Name: "something2", Type: "aws_instance", @@ -1494,11 +1480,83 @@ func TestCompleteJob(t *testing.T) { String: "", Valid: true, }, + Transition: database.WorkspaceTransitionStart, + }}, + expectedModules: []database.WorkspaceModule{{ + Key: "test1", + Version: "1.0.0", + Source: "github.com/example/example", + Transition: database.WorkspaceTransitionStart, + }}, + provisionerJobParams: database.InsertProvisionerJobParams{ + Type: database.ProvisionerJobTypeTemplateVersionDryRun, + }, + }, + { + name: "TemplateImport", + job: &proto.CompletedJob{ + Type: &proto.CompletedJob_TemplateImport_{ + TemplateImport: &proto.CompletedJob_TemplateImport{ + StartResources: []*sdkproto.Resource{{ + Name: "something", + Type: "aws_instance", + ModulePath: "module.test1", + }}, + StartModules: []*sdkproto.Module{ + { + Key: "test1", + Version: "1.0.0", + Source: "github.com/example/example", + }, + }, + StopResources: []*sdkproto.Resource{{ + Name: "something2", + Type: "aws_instance", + ModulePath: "module.test2", + }}, + StopModules: []*sdkproto.Module{ + { + Key: "test2", + Version: "2.0.0", + Source: "github.com/example2/example", + }, + }, + }, + }, + }, + provisionerJobParams: database.InsertProvisionerJobParams{ + Type: database.ProvisionerJobTypeTemplateVersionImport, + Input: must(json.Marshal(provisionerdserver.TemplateVersionImportJob{ + TemplateVersionID: uuid.New(), + })), + }, + expectedResources: []database.WorkspaceResource{{ + Name: "something", + Type: "aws_instance", + ModulePath: sql.NullString{ + String: "module.test1", + Valid: true, + }, + Transition: database.WorkspaceTransitionStart, + }, { + Name: "something2", + Type: "aws_instance", + ModulePath: sql.NullString{ + String: "module.test2", + Valid: true, + }, + Transition: database.WorkspaceTransitionStop, }}, expectedModules: []database.WorkspaceModule{{ - Key: "test1", - Version: "1.0.0", - Source: "github.com/example/example", + Key: "test1", + Version: "1.0.0", + Source: "github.com/example/example", + Transition: database.WorkspaceTransitionStart, + }, { + Key: "test2", + Version: "2.0.0", + Source: "github.com/example2/example", + Transition: database.WorkspaceTransitionStop, }}, }, } @@ -1509,6 +1567,36 @@ func TestCompleteJob(t *testing.T) { t.Run(c.name, func(t *testing.T) { t.Parallel() + srv, db, _, pd := setup(t, false, &overrides{}) + jobParams := c.provisionerJobParams + if jobParams.ID == uuid.Nil { + jobParams.ID = uuid.New() + } + if jobParams.Provisioner == "" { + jobParams.Provisioner = database.ProvisionerTypeEcho + } + if jobParams.StorageMethod == "" { + jobParams.StorageMethod = database.ProvisionerStorageMethodFile + } + job, err := db.InsertProvisionerJob(ctx, jobParams) + tpl := dbgen.Template(t, db, database.Template{ + OrganizationID: pd.OrganizationID, + }) + _ = dbgen.TemplateVersion(t, db, database.TemplateVersion{ + TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true}, + JobID: job.ID, + }) + + require.NoError(t, err) + _, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{ + WorkerID: uuid.NullUUID{ + UUID: pd.ID, + Valid: true, + }, + Types: []database.ProvisionerType{jobParams.Provisioner}, + }) + require.NoError(t, err) + completedJob := c.job completedJob.JobId = job.ID.String() @@ -1521,7 +1609,10 @@ func TestCompleteJob(t *testing.T) { for _, expectedResource := range c.expectedResources { for i, resource := range resources { - if resource.Name == expectedResource.Name && resource.Type == expectedResource.Type && resource.ModulePath == expectedResource.ModulePath { + if resource.Name == expectedResource.Name && + resource.Type == expectedResource.Type && + resource.ModulePath == expectedResource.ModulePath && + resource.Transition == expectedResource.Transition { resources[i] = database.WorkspaceResource{Name: "matched"} } } @@ -1537,7 +1628,10 @@ func TestCompleteJob(t *testing.T) { for _, expectedModule := range c.expectedModules { for i, module := range modules { - if module.Key == expectedModule.Key && module.Version == expectedModule.Version && module.Source == expectedModule.Source { + if module.Key == expectedModule.Key && + module.Version == expectedModule.Version && + module.Source == expectedModule.Source && + module.Transition == expectedModule.Transition { modules[i] = database.WorkspaceModule{Key: "matched"} } } From e8fbd4015de03e771d29c2272e0d54f1177fc92d Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 10:52:41 +0000 Subject: [PATCH 08/34] TestCompleteJob Modules WorkspaceBuild --- .../provisionerdserver_test.go | 71 ++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/coderd/provisionerdserver/provisionerdserver_test.go b/coderd/provisionerdserver/provisionerdserver_test.go index 1d32be66ac875..f12e3f1607b29 100644 --- a/coderd/provisionerdserver/provisionerdserver_test.go +++ b/coderd/provisionerdserver/provisionerdserver_test.go @@ -1434,6 +1434,9 @@ func TestCompleteJob(t *testing.T) { t.Run("Modules", func(t *testing.T) { t.Parallel() + templateVersionID := uuid.New() + workspaceBuildID := uuid.New() + cases := []struct { name string job *proto.CompletedJob @@ -1527,7 +1530,7 @@ func TestCompleteJob(t *testing.T) { provisionerJobParams: database.InsertProvisionerJobParams{ Type: database.ProvisionerJobTypeTemplateVersionImport, Input: must(json.Marshal(provisionerdserver.TemplateVersionImportJob{ - TemplateVersionID: uuid.New(), + TemplateVersionID: templateVersionID, })), }, expectedResources: []database.WorkspaceResource{{ @@ -1559,6 +1562,60 @@ func TestCompleteJob(t *testing.T) { Transition: database.WorkspaceTransitionStop, }}, }, + { + name: "WorkspaceBuild", + job: &proto.CompletedJob{ + Type: &proto.CompletedJob_WorkspaceBuild_{ + WorkspaceBuild: &proto.CompletedJob_WorkspaceBuild{ + Resources: []*sdkproto.Resource{{ + Name: "something", + Type: "aws_instance", + ModulePath: "module.test1", + }, { + Name: "something2", + Type: "aws_instance", + ModulePath: "", + }}, + Modules: []*sdkproto.Module{ + { + Key: "test1", + Version: "1.0.0", + Source: "github.com/example/example", + }, + }, + }, + }, + }, + expectedResources: []database.WorkspaceResource{{ + Name: "something", + Type: "aws_instance", + ModulePath: sql.NullString{ + String: "module.test1", + Valid: true, + }, + Transition: database.WorkspaceTransitionStart, + }, { + Name: "something2", + Type: "aws_instance", + ModulePath: sql.NullString{ + String: "", + Valid: true, + }, + Transition: database.WorkspaceTransitionStart, + }}, + expectedModules: []database.WorkspaceModule{{ + Key: "test1", + Version: "1.0.0", + Source: "github.com/example/example", + Transition: database.WorkspaceTransitionStart, + }}, + provisionerJobParams: database.InsertProvisionerJobParams{ + Type: database.ProvisionerJobTypeWorkspaceBuild, + Input: must(json.Marshal(provisionerdserver.WorkspaceProvisionJob{ + WorkspaceBuildID: workspaceBuildID, + })), + }, + }, } for _, c := range cases { @@ -1579,13 +1636,23 @@ func TestCompleteJob(t *testing.T) { jobParams.StorageMethod = database.ProvisionerStorageMethodFile } job, err := db.InsertProvisionerJob(ctx, jobParams) + tpl := dbgen.Template(t, db, database.Template{ OrganizationID: pd.OrganizationID, }) - _ = dbgen.TemplateVersion(t, db, database.TemplateVersion{ + tv := dbgen.TemplateVersion(t, db, database.TemplateVersion{ TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true}, JobID: job.ID, }) + workspace := dbgen.Workspace(t, db, database.WorkspaceTable{ + TemplateID: tpl.ID, + }) + _ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{ + ID: workspaceBuildID, + JobID: job.ID, + WorkspaceID: workspace.ID, + TemplateVersionID: tv.ID, + }) require.NoError(t, err) _, err = db.AcquireProvisionerJob(ctx, database.AcquireProvisionerJobParams{ From 5c542e5a94b26438719c4ebb91ee0eec9a461fe6 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 11:32:17 +0000 Subject: [PATCH 09/34] add a test for returning modules in provision_test.go, fix test in resources_test.go --- provisioner/terraform/provision_test.go | 64 ++++++++++++++++++++++++- provisioner/terraform/resources_test.go | 1 + 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/provisioner/terraform/provision_test.go b/provisioner/terraform/provision_test.go index 0ffbe7903ec08..f84e9503dc9a2 100644 --- a/provisioner/terraform/provision_test.go +++ b/provisioner/terraform/provision_test.go @@ -82,7 +82,21 @@ func makeTar(t *testing.T, files map[string]string) []byte { t.Helper() var buffer bytes.Buffer writer := tar.NewWriter(&buffer) + + addedDirs := make(map[string]bool) for name, content := range files { + // Add parent directories if they don't exist + dir := filepath.Dir(name) + if dir != "." && !addedDirs[dir] { + err := writer.WriteHeader(&tar.Header{ + Name: dir + "/", // Directory names must end with / + Mode: 0o755, + Typeflag: tar.TypeDir, + }) + require.NoError(t, err) + addedDirs[dir] = true + } + err := writer.WriteHeader(&tar.Header{ Name: name, Size: int64(len(content)), @@ -745,6 +759,45 @@ func TestProvision(t *testing.T) { }}, }, }, + { + Name: "returns-modules", + Files: map[string]string{ + "main.tf": `module "hello" { + source = "./module" + }`, + "module/module.tf": ` + resource "null_resource" "example" {} + + module "there" { + source = "./inner_module" + } + `, + "module/inner_module/inner_module.tf": ` + resource "null_resource" "inner_example" {} + `, + }, + Request: &proto.PlanRequest{}, + Response: &proto.PlanComplete{ + Resources: []*proto.Resource{{ + Name: "example", + Type: "null_resource", + ModulePath: "module.hello", + }, { + Name: "inner_example", + Type: "null_resource", + ModulePath: "module.hello.module.there", + }}, + Modules: []*proto.Module{{ + Key: "hello", + Version: "", + Source: "./module", + }, { + Key: "hello.there", + Version: "", + Source: "./inner_module", + }}, + }, + }, } for _, testCase := range testCases { @@ -799,7 +852,7 @@ func TestProvision(t *testing.T) { if testCase.Response != nil { require.Equal(t, testCase.Response.Error, planComplete.Error) - // Remove randomly generated data. + // Remove randomly generated data and sort by name. normalizeResources(planComplete.Resources) resourcesGot, err := json.Marshal(planComplete.Resources) require.NoError(t, err) @@ -812,6 +865,12 @@ func TestProvision(t *testing.T) { parametersWant, err := json.Marshal(testCase.Response.Parameters) require.NoError(t, err) require.Equal(t, string(parametersWant), string(parametersGot)) + + modulesGot, err := json.Marshal(planComplete.Modules) + require.NoError(t, err) + modulesWant, err := json.Marshal(testCase.Response.Modules) + require.NoError(t, err) + require.Equal(t, string(modulesWant), string(modulesGot)) } if testCase.Apply { @@ -852,6 +911,9 @@ func normalizeResources(resources []*proto.Resource) { agent.Auth = &proto.Agent_Token{} } } + sort.Slice(resources, func(i, j int) bool { + return resources[i].Name < resources[j].Name + }) } // nolint:paralleltest diff --git a/provisioner/terraform/resources_test.go b/provisioner/terraform/resources_test.go index 5842cbca46833..02106e4c06e94 100644 --- a/provisioner/terraform/resources_test.go +++ b/provisioner/terraform/resources_test.go @@ -109,6 +109,7 @@ func TestConvertResources(t *testing.T) { ConnectionTimeoutSeconds: 120, DisplayApps: &displayApps, }}, + ModulePath: "module.module", }}, }, // Ensures the attachment of multiple agents to a single From 9ec5ee1e80e28674dced192364808fd16995af7a Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 11:47:22 +0000 Subject: [PATCH 10/34] make gen --- coderd/database/dbmock/dbmock.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/coderd/database/dbmock/dbmock.go b/coderd/database/dbmock/dbmock.go index 14108ce50c988..691d92d5e29f4 100644 --- a/coderd/database/dbmock/dbmock.go +++ b/coderd/database/dbmock/dbmock.go @@ -3307,6 +3307,21 @@ func (mr *MockStoreMockRecorder) GetWorkspaceByWorkspaceAppID(arg0, arg1 any) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceByWorkspaceAppID", reflect.TypeOf((*MockStore)(nil).GetWorkspaceByWorkspaceAppID), arg0, arg1) } +// GetWorkspaceModulesByJobID mocks base method. +func (m *MockStore) GetWorkspaceModulesByJobID(arg0 context.Context, arg1 uuid.UUID) ([]database.WorkspaceModule, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetWorkspaceModulesByJobID", arg0, arg1) + ret0, _ := ret[0].([]database.WorkspaceModule) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWorkspaceModulesByJobID indicates an expected call of GetWorkspaceModulesByJobID. +func (mr *MockStoreMockRecorder) GetWorkspaceModulesByJobID(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceModulesByJobID", reflect.TypeOf((*MockStore)(nil).GetWorkspaceModulesByJobID), arg0, arg1) +} + // GetWorkspaceProxies mocks base method. func (m *MockStore) GetWorkspaceProxies(arg0 context.Context) ([]database.WorkspaceProxy, error) { m.ctrl.T.Helper() From 119a6864ce90dd7b1a5daee6aa149b1a98437073 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 11:53:52 +0000 Subject: [PATCH 11/34] fix dbauthz tests --- coderd/database/dbauthz/dbauthz_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 3ecb1c97b3585..1530aec7b345b 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2907,6 +2907,18 @@ func (s *MethodTestSuite) TestSystemFunctions() { } check.Args(build.ID).Asserts(rbac.ResourceSystem, policy.ActionRead).Returns(rows) })) + s.Run("InsertWorkspaceModule", s.Subtest(func(db database.Store, check *expects) { + j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{ + Type: database.ProvisionerJobTypeWorkspaceBuild, + }) + check.Args(database.InsertWorkspaceModuleParams{ + JobID: j.ID, + Transition: database.WorkspaceTransitionStart, + }).Asserts(rbac.ResourceSystem, policy.ActionCreate) + })) + s.Run("GetWorkspaceModulesByJobID", s.Subtest(func(db database.Store, check *expects) { + check.Args(uuid.New()).Asserts(rbac.ResourceSystem, policy.ActionRead) + })) } func (s *MethodTestSuite) TestNotifications() { From 3a5a025b9d348e9ad11fb2f138fe7ff9e9bb8b92 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 13:05:20 +0000 Subject: [PATCH 12/34] add workspace modules and workspace resources's ModulePath to telemetry --- coderd/database/dbauthz/dbauthz.go | 7 +++ coderd/database/dbauthz/dbauthz_test.go | 3 ++ coderd/database/dbgen/dbgen.go | 14 ++++++ coderd/database/dbmem/dbmem.go | 13 ++++++ coderd/database/dbmetrics/querymetrics.go | 7 +++ coderd/database/dbmock/dbmock.go | 15 +++++++ coderd/database/querier.go | 1 + coderd/database/queries.sql.go | 35 +++++++++++++++ coderd/database/queries/workspacemodules.sql | 3 ++ .../provisionerdserver/provisionerdserver.go | 11 ++--- coderd/telemetry/telemetry.go | 45 ++++++++++++++++++- coderd/telemetry/telemetry_test.go | 3 ++ 12 files changed, 151 insertions(+), 6 deletions(-) diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index f565876c3e238..2a9c29b175dae 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -2673,6 +2673,13 @@ func (q *querier) GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid.UUI return q.db.GetWorkspaceModulesByJobID(ctx, jobID) } +func (q *querier) GetWorkspaceModulesCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceModule, error) { + if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil { + return nil, err + } + return q.db.GetWorkspaceModulesCreatedAfter(ctx, createdAt) +} + func (q *querier) GetWorkspaceProxies(ctx context.Context) ([]database.WorkspaceProxy, error) { return fetchWithPostFilter(q.auth, policy.ActionRead, func(ctx context.Context, _ interface{}) ([]database.WorkspaceProxy, error) { return q.db.GetWorkspaceProxies(ctx) diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 1530aec7b345b..978478e4709c5 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -2919,6 +2919,9 @@ func (s *MethodTestSuite) TestSystemFunctions() { s.Run("GetWorkspaceModulesByJobID", s.Subtest(func(db database.Store, check *expects) { check.Args(uuid.New()).Asserts(rbac.ResourceSystem, policy.ActionRead) })) + s.Run("GetWorkspaceModulesCreatedAfter", s.Subtest(func(db database.Store, check *expects) { + check.Args(dbtime.Now()).Asserts(rbac.ResourceSystem, policy.ActionRead) + })) } func (s *MethodTestSuite) TestNotifications() { diff --git a/coderd/database/dbgen/dbgen.go b/coderd/database/dbgen/dbgen.go index 686025e6ca41f..34ebc617496e5 100644 --- a/coderd/database/dbgen/dbgen.go +++ b/coderd/database/dbgen/dbgen.go @@ -666,6 +666,20 @@ func WorkspaceResource(t testing.TB, db database.Store, orig database.WorkspaceR return resource } +func WorkspaceModule(t testing.TB, db database.Store, orig database.WorkspaceModule) database.WorkspaceModule { + module, err := db.InsertWorkspaceModule(genCtx, database.InsertWorkspaceModuleParams{ + ID: takeFirst(orig.ID, uuid.New()), + JobID: takeFirst(orig.JobID, uuid.New()), + Transition: takeFirst(orig.Transition, database.WorkspaceTransitionStart), + Source: takeFirst(orig.Source, "test-source"), + Version: takeFirst(orig.Version, "v1.0.0"), + Key: takeFirst(orig.Key, "test-key"), + CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()), + }) + require.NoError(t, err, "insert workspace module") + return module +} + func WorkspaceResourceMetadatums(t testing.TB, db database.Store, seed database.WorkspaceResourceMetadatum) []database.WorkspaceResourceMetadatum { meta, err := db.InsertWorkspaceResourceMetadata(genCtx, database.InsertWorkspaceResourceMetadataParams{ WorkspaceResourceID: takeFirst(seed.WorkspaceResourceID, uuid.New()), diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index b23c870153a53..2af216f250bb5 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -6686,6 +6686,19 @@ func (q *FakeQuerier) GetWorkspaceModulesByJobID(_ context.Context, jobID uuid.U return modules, nil } +func (q *FakeQuerier) GetWorkspaceModulesCreatedAfter(_ context.Context, createdAt time.Time) ([]database.WorkspaceModule, error) { + q.mutex.RLock() + defer q.mutex.RUnlock() + + modules := make([]database.WorkspaceModule, 0) + for _, module := range q.workspaceModules { + if module.CreatedAt.After(createdAt) { + modules = append(modules, module) + } + } + return modules, nil +} + func (q *FakeQuerier) GetWorkspaceProxies(_ context.Context) ([]database.WorkspaceProxy, error) { q.mutex.RLock() defer q.mutex.RUnlock() diff --git a/coderd/database/dbmetrics/querymetrics.go b/coderd/database/dbmetrics/querymetrics.go index 2033f4977b030..d03e481628991 100644 --- a/coderd/database/dbmetrics/querymetrics.go +++ b/coderd/database/dbmetrics/querymetrics.go @@ -1575,6 +1575,13 @@ func (m queryMetricsStore) GetWorkspaceModulesByJobID(ctx context.Context, jobID return r0, r1 } +func (m queryMetricsStore) GetWorkspaceModulesCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceModule, error) { + start := time.Now() + r0, r1 := m.s.GetWorkspaceModulesCreatedAfter(ctx, createdAt) + m.queryLatencies.WithLabelValues("GetWorkspaceModulesCreatedAfter").Observe(time.Since(start).Seconds()) + return r0, r1 +} + func (m queryMetricsStore) GetWorkspaceProxies(ctx context.Context) ([]database.WorkspaceProxy, error) { start := time.Now() proxies, err := m.s.GetWorkspaceProxies(ctx) diff --git a/coderd/database/dbmock/dbmock.go b/coderd/database/dbmock/dbmock.go index 691d92d5e29f4..04bf967caf26b 100644 --- a/coderd/database/dbmock/dbmock.go +++ b/coderd/database/dbmock/dbmock.go @@ -3322,6 +3322,21 @@ func (mr *MockStoreMockRecorder) GetWorkspaceModulesByJobID(arg0, arg1 any) *gom return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceModulesByJobID", reflect.TypeOf((*MockStore)(nil).GetWorkspaceModulesByJobID), arg0, arg1) } +// GetWorkspaceModulesCreatedAfter mocks base method. +func (m *MockStore) GetWorkspaceModulesCreatedAfter(arg0 context.Context, arg1 time.Time) ([]database.WorkspaceModule, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetWorkspaceModulesCreatedAfter", arg0, arg1) + ret0, _ := ret[0].([]database.WorkspaceModule) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetWorkspaceModulesCreatedAfter indicates an expected call of GetWorkspaceModulesCreatedAfter. +func (mr *MockStoreMockRecorder) GetWorkspaceModulesCreatedAfter(arg0, arg1 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetWorkspaceModulesCreatedAfter", reflect.TypeOf((*MockStore)(nil).GetWorkspaceModulesCreatedAfter), arg0, arg1) +} + // GetWorkspaceProxies mocks base method. func (m *MockStore) GetWorkspaceProxies(arg0 context.Context) ([]database.WorkspaceProxy, error) { m.ctrl.T.Helper() diff --git a/coderd/database/querier.go b/coderd/database/querier.go index c8acde1565f11..b7652865447ad 100644 --- a/coderd/database/querier.go +++ b/coderd/database/querier.go @@ -324,6 +324,7 @@ type sqlcQuerier interface { GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (Workspace, error) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspaceAppID uuid.UUID) (Workspace, error) GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceModule, error) + GetWorkspaceModulesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceModule, error) GetWorkspaceProxies(ctx context.Context) ([]WorkspaceProxy, error) // Finds a workspace proxy that has an access URL or app hostname that matches // the provided hostname. This is to check if a hostname matches any workspace diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 664b4f5dd87dd..94f108886ea60 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -14155,6 +14155,41 @@ func (q *sqlQuerier) GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid. return items, nil } +const getWorkspaceModulesCreatedAfter = `-- name: GetWorkspaceModulesCreatedAfter :many +SELECT id, job_id, transition, source, version, key, created_at FROM workspace_modules WHERE created_at > $1 +` + +func (q *sqlQuerier) GetWorkspaceModulesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceModule, error) { + rows, err := q.db.QueryContext(ctx, getWorkspaceModulesCreatedAfter, createdAt) + if err != nil { + return nil, err + } + defer rows.Close() + var items []WorkspaceModule + for rows.Next() { + var i WorkspaceModule + if err := rows.Scan( + &i.ID, + &i.JobID, + &i.Transition, + &i.Source, + &i.Version, + &i.Key, + &i.CreatedAt, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const insertWorkspaceModule = `-- name: InsertWorkspaceModule :one INSERT INTO workspace_modules (id, job_id, transition, source, version, key, created_at) diff --git a/coderd/database/queries/workspacemodules.sql b/coderd/database/queries/workspacemodules.sql index f9f54d3c90114..9cc8dbc08e39f 100644 --- a/coderd/database/queries/workspacemodules.sql +++ b/coderd/database/queries/workspacemodules.sql @@ -11,3 +11,6 @@ FROM workspace_modules WHERE job_id = $1; + +-- name: GetWorkspaceModulesCreatedAfter :many +SELECT * FROM workspace_modules WHERE created_at > $1; diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index a9dc997672a70..ece5f0bcafc50 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1279,7 +1279,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) slog.F("module_key", module.Key), slog.F("transition", transition)) - err = InsertWorkspaceModule(ctx, s.Database, jobID, transition, module) + err = InsertWorkspaceModule(ctx, s.Database, jobID, transition, module, telemetrySnapshot) if err != nil { return nil, xerrors.Errorf("insert module: %w", err) } @@ -1491,7 +1491,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) } } for _, module := range jobType.WorkspaceBuild.Modules { - err = InsertWorkspaceModule(ctx, db, job.ID, workspaceBuild.Transition, module) + err = InsertWorkspaceModule(ctx, db, job.ID, workspaceBuild.Transition, module, telemetrySnapshot) if err != nil { return xerrors.Errorf("insert provisioner job module: %w", err) } @@ -1683,7 +1683,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) slog.F("module_source", module.Source), ) - err = InsertWorkspaceModule(ctx, s.Database, jobID, database.WorkspaceTransitionStart, module) + err = InsertWorkspaceModule(ctx, s.Database, jobID, database.WorkspaceTransitionStart, module, telemetrySnapshot) if err != nil { return nil, xerrors.Errorf("insert module: %w", err) } @@ -1769,8 +1769,8 @@ func (s *server) startTrace(ctx context.Context, name string, opts ...trace.Span ))...) } -func InsertWorkspaceModule(ctx context.Context, db database.Store, jobID uuid.UUID, transition database.WorkspaceTransition, protoModule *sdkproto.Module) error { - _, err := db.InsertWorkspaceModule(ctx, database.InsertWorkspaceModuleParams{ +func InsertWorkspaceModule(ctx context.Context, db database.Store, jobID uuid.UUID, transition database.WorkspaceTransition, protoModule *sdkproto.Module, snapshot *telemetry.Snapshot) error { + module, err := db.InsertWorkspaceModule(ctx, database.InsertWorkspaceModuleParams{ ID: uuid.New(), CreatedAt: dbtime.Now(), JobID: jobID, @@ -1782,6 +1782,7 @@ func InsertWorkspaceModule(ctx context.Context, db database.Store, jobID uuid.UU if err != nil { return xerrors.Errorf("insert provisioner job module %q: %w", protoModule.Source, err) } + snapshot.WorkspaceModules = append(snapshot.WorkspaceModules, telemetry.ConvertWorkspaceModule(module)) return nil } diff --git a/coderd/telemetry/telemetry.go b/coderd/telemetry/telemetry.go index 2a505b4c48d4e..754db74129374 100644 --- a/coderd/telemetry/telemetry.go +++ b/coderd/telemetry/telemetry.go @@ -456,6 +456,17 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) { } return nil }) + eg.Go(func() error { + workspaceModules, err := r.options.Database.GetWorkspaceModulesCreatedAfter(ctx, createdAfter) + if err != nil { + return xerrors.Errorf("get workspace modules: %w", err) + } + snapshot.WorkspaceModules = make([]WorkspaceModule, 0, len(workspaceModules)) + for _, module := range workspaceModules { + snapshot.WorkspaceModules = append(snapshot.WorkspaceModules, ConvertWorkspaceModule(module)) + } + return nil + }) eg.Go(func() error { licenses, err := r.options.Database.GetUnexpiredLicenses(ctx) if err != nil { @@ -642,7 +653,7 @@ func ConvertWorkspaceApp(app database.WorkspaceApp) WorkspaceApp { // ConvertWorkspaceResource anonymizes a workspace resource. func ConvertWorkspaceResource(resource database.WorkspaceResource) WorkspaceResource { - return WorkspaceResource{ + r := WorkspaceResource{ ID: resource.ID, JobID: resource.JobID, CreatedAt: resource.CreatedAt, @@ -650,6 +661,10 @@ func ConvertWorkspaceResource(resource database.WorkspaceResource) WorkspaceReso Type: resource.Type, InstanceType: resource.InstanceType.String, } + if resource.ModulePath.Valid { + r.ModulePath = &resource.ModulePath.String + } + return r } // ConvertWorkspaceResourceMetadata anonymizes workspace metadata. @@ -661,6 +676,18 @@ func ConvertWorkspaceResourceMetadata(metadata database.WorkspaceResourceMetadat } } +func ConvertWorkspaceModule(module database.WorkspaceModule) WorkspaceModule { + return WorkspaceModule{ + ID: module.ID, + JobID: module.JobID, + Transition: module.Transition, + Source: module.Source, + Version: module.Version, + Key: module.Key, + CreatedAt: module.CreatedAt, + } +} + // ConvertUser anonymizes a user. func ConvertUser(dbUser database.User) User { emailHashed := "" @@ -810,6 +837,7 @@ type Snapshot struct { WorkspaceProxies []WorkspaceProxy `json:"workspace_proxies"` WorkspaceResourceMetadata []WorkspaceResourceMetadata `json:"workspace_resource_metadata"` WorkspaceResources []WorkspaceResource `json:"workspace_resources"` + WorkspaceModules []WorkspaceModule `json:"workspace_modules"` Workspaces []Workspace `json:"workspaces"` NetworkEvents []NetworkEvent `json:"network_events"` } @@ -878,6 +906,11 @@ type WorkspaceResource struct { Transition database.WorkspaceTransition `json:"transition"` Type string `json:"type"` InstanceType string `json:"instance_type"` + // ModulePath is nullable because it was added a long time after the + // original workspace resource telemetry was added. All new resources + // will have a module path, but deployments with older resources still + // in the database will not. + ModulePath *string `json:"module_path"` } type WorkspaceResourceMetadata struct { @@ -886,6 +919,16 @@ type WorkspaceResourceMetadata struct { Sensitive bool `json:"sensitive"` } +type WorkspaceModule struct { + ID uuid.UUID `json:"id"` + CreatedAt time.Time `json:"created_at"` + JobID uuid.UUID `json:"job_id"` + Transition database.WorkspaceTransition `json:"transition"` + Key string `json:"key"` + Version string `json:"version"` + Source string `json:"source"` +} + type WorkspaceAgent struct { ID uuid.UUID `json:"id"` CreatedAt time.Time `json:"created_at"` diff --git a/coderd/telemetry/telemetry_test.go b/coderd/telemetry/telemetry_test.go index 908bcd657ee4f..5210a9962499c 100644 --- a/coderd/telemetry/telemetry_test.go +++ b/coderd/telemetry/telemetry_test.go @@ -87,6 +87,8 @@ func TestTelemetry(t *testing.T) { assert.NoError(t, err) _, _ = dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{}) + _ = dbgen.WorkspaceModule(t, db, database.WorkspaceModule{}) + _, snapshot := collectSnapshot(t, db, nil) require.Len(t, snapshot.ProvisionerJobs, 1) require.Len(t, snapshot.Licenses, 1) @@ -103,6 +105,7 @@ func TestTelemetry(t *testing.T) { require.Len(t, snapshot.WorkspaceResources, 1) require.Len(t, snapshot.WorkspaceAgentStats, 1) require.Len(t, snapshot.WorkspaceProxies, 1) + require.Len(t, snapshot.WorkspaceModules, 1) wsa := snapshot.WorkspaceAgents[0] require.Len(t, wsa.Subsystems, 2) From 3377d22e7d19b0e075989034f6415f0be10d6203 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 13:16:28 +0000 Subject: [PATCH 13/34] add a workspace_modules fixture --- .../fixtures/000274_workspace_modules.up.sql | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 coderd/database/migrations/testdata/fixtures/000274_workspace_modules.up.sql diff --git a/coderd/database/migrations/testdata/fixtures/000274_workspace_modules.up.sql b/coderd/database/migrations/testdata/fixtures/000274_workspace_modules.up.sql new file mode 100644 index 0000000000000..b2ff302722b08 --- /dev/null +++ b/coderd/database/migrations/testdata/fixtures/000274_workspace_modules.up.sql @@ -0,0 +1,20 @@ +INSERT INTO + public.workspace_modules ( + id, + job_id, + transition, + source, + version, + key, + created_at + ) +VALUES + ( + '5b1a722c-b8a0-40b0-a3a0-d8078fff9f6c', + '424a58cb-61d6-4627-9907-613c396c4a38', + 'start', + 'test-source', + 'v1.0.0', + 'test-key', + '2024-11-08 10:00:00+00' + ); From 422b1121ebe2ed2942ccd3756f7fe4882053a777 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 13:35:39 +0000 Subject: [PATCH 14/34] add a workspace resource's modulePath default to the e2e helper --- site/e2e/helpers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts index c5ac7f1abde65..735321c374735 100644 --- a/site/e2e/helpers.ts +++ b/site/e2e/helpers.ts @@ -608,6 +608,7 @@ const createTemplateVersionTar = async ( metadata: [], name: "dev", type: "echo", + modulePath: "", ...resource, } as Resource; }; From 46b9b36021fbc09b75353b0da5048bdc65966ac1 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 13:41:28 +0000 Subject: [PATCH 15/34] add modules default on PlanComplete for e2e tests --- site/e2e/helpers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/site/e2e/helpers.ts b/site/e2e/helpers.ts index 735321c374735..6a7a4d937d031 100644 --- a/site/e2e/helpers.ts +++ b/site/e2e/helpers.ts @@ -637,6 +637,7 @@ const createTemplateVersionTar = async ( parameters: [], externalAuthProviders: [], timings: [], + modules: [], ...response.plan, } as PlanComplete; response.plan.resources = response.plan.resources?.map(fillResource); From f3f4d5cf32ea980b2c88e5dbc6526cb010848d51 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 8 Nov 2024 13:52:20 +0000 Subject: [PATCH 16/34] lint --- coderd/database/dbmem/dbmem.go | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 2af216f250bb5..64310cf36445a 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -8261,7 +8261,7 @@ func (q *FakeQuerier) InsertWorkspaceBuildParameters(_ context.Context, arg data return nil } -func (q *FakeQuerier) InsertWorkspaceModule(ctx context.Context, arg database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) { +func (q *FakeQuerier) InsertWorkspaceModule(_ context.Context, arg database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) { err := validateDatabaseType(arg) if err != nil { return database.WorkspaceModule{}, err @@ -8270,15 +8270,7 @@ func (q *FakeQuerier) InsertWorkspaceModule(ctx context.Context, arg database.In q.mutex.Lock() defer q.mutex.Unlock() - workspaceModule := database.WorkspaceModule{ - ID: arg.ID, - JobID: arg.JobID, - Transition: arg.Transition, - Source: arg.Source, - Version: arg.Version, - Key: arg.Key, - CreatedAt: arg.CreatedAt, - } + workspaceModule := database.WorkspaceModule(arg) q.workspaceModules = append(q.workspaceModules, workspaceModule) return workspaceModule, nil } From 93ed1360c19fb4dcc4453edfc1c2fbea84d48272 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Wed, 13 Nov 2024 13:16:10 +0100 Subject: [PATCH 17/34] set module path to sentinel value when parsing failed and log an error --- provisioner/terraform/executor.go | 6 ++-- provisioner/terraform/resources.go | 18 +++++++++--- provisioner/terraform/resources_test.go | 39 +++++++++++++++++-------- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/provisioner/terraform/executor.go b/provisioner/terraform/executor.go index 916847e28cc58..43754446cbd78 100644 --- a/provisioner/terraform/executor.go +++ b/provisioner/terraform/executor.go @@ -356,7 +356,7 @@ func (e *executor) planResources(ctx, killCtx context.Context, planfilePath stri } modules = append(modules, plan.PlannedValues.RootModule) - state, err := ConvertState(modules, rawGraph) + state, err := ConvertState(ctx, modules, rawGraph, e.server.logger) if err != nil { return nil, err } @@ -484,9 +484,9 @@ func (e *executor) stateResources(ctx, killCtx context.Context) (*State, error) return converted, nil } - converted, err = ConvertState([]*tfjson.StateModule{ + converted, err = ConvertState(ctx, []*tfjson.StateModule{ state.Values.RootModule, - }, rawGraph) + }, rawGraph, e.server.logger) if err != nil { return nil, err } diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index 90b853c88896d..de790a55f5cfa 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -1,6 +1,7 @@ package terraform import ( + "context" "fmt" "strings" @@ -9,6 +10,8 @@ import ( "github.com/mitchellh/mapstructure" "golang.org/x/xerrors" + "cdr.dev/slog" + "github.com/coder/terraform-provider-coder/provider" tfaddr "github.com/hashicorp/go-terraform-address" @@ -134,7 +137,7 @@ type State struct { // ConvertState consumes Terraform state and a GraphViz representation // produced by `terraform graph` to produce resources consumable by Coder. // nolint:gocognit // This function makes more sense being large for now, until refactored. -func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error) { +func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph string, logger slog.Logger) (*State, error) { parsedGraph, err := gographviz.ParseString(rawGraph) if err != nil { return nil, xerrors.Errorf("parse graph: %w", err) @@ -598,9 +601,16 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error modulePath, err := convertAddressToModulePath(resource.Address) if err != nil { // Module path recording was added primarily to keep track of - // modules in telemetry. We're adding this fallback so we can - // detect if there are any issues with the address parsing. - modulePath = fmt.Sprintf("error parsing address: %s", resource.Address) + // modules in telemetry. We're adding this sentinel value so + // we can detect if there are any issues with the address + // parsing. + // + // We don't want to set modulePath to null here because, in + // the database, a null value in WorkspaceResource's ModulePath + // indicates "this resource was created before module paths + // were tracked." + modulePath = "FAILED_TO_PARSE_TERRAFORM_ADDRESS" + logger.Error(ctx, "failed to parse Terraform address", slog.F("address", resource.Address)) } agents, exists := resourceAgents[label] diff --git a/provisioner/terraform/resources_test.go b/provisioner/terraform/resources_test.go index 02106e4c06e94..ddb16fc04f201 100644 --- a/provisioner/terraform/resources_test.go +++ b/provisioner/terraform/resources_test.go @@ -1,6 +1,7 @@ package terraform_test import ( + "context" "encoding/json" "fmt" "os" @@ -14,11 +15,18 @@ import ( "github.com/stretchr/testify/require" protobuf "google.golang.org/protobuf/proto" + "cdr.dev/slog" + "cdr.dev/slog/sloggers/slogtest" + "github.com/coder/coder/v2/cryptorand" "github.com/coder/coder/v2/provisioner/terraform" "github.com/coder/coder/v2/provisionersdk/proto" ) +func ctxAndLogger(t *testing.T) (context.Context, slog.Logger) { + return context.Background(), slogtest.Make(t, nil).Leveled(slog.LevelDebug) +} + func TestConvertResources(t *testing.T) { t.Parallel() // nolint:dogsled @@ -688,6 +696,7 @@ func TestConvertResources(t *testing.T) { dir := filepath.Join(filepath.Dir(filename), "testdata", folderName) t.Run("Plan", func(t *testing.T) { t.Parallel() + ctx, logger := ctxAndLogger(t) tfPlanRaw, err := os.ReadFile(filepath.Join(dir, folderName+".tfplan.json")) require.NoError(t, err) @@ -705,7 +714,7 @@ func TestConvertResources(t *testing.T) { // and that no errors occur! modules = append(modules, tfPlan.PlannedValues.RootModule) } - state, err := terraform.ConvertState(modules, string(tfPlanGraph)) + state, err := terraform.ConvertState(ctx, modules, string(tfPlanGraph), logger) require.NoError(t, err) sortResources(state.Resources) sortExternalAuthProviders(state.ExternalAuthProviders) @@ -763,6 +772,7 @@ func TestConvertResources(t *testing.T) { t.Run("Provision", func(t *testing.T) { t.Parallel() + ctx, logger := ctxAndLogger(t) tfStateRaw, err := os.ReadFile(filepath.Join(dir, folderName+".tfstate.json")) require.NoError(t, err) var tfState tfjson.State @@ -771,7 +781,7 @@ func TestConvertResources(t *testing.T) { tfStateGraph, err := os.ReadFile(filepath.Join(dir, folderName+".tfstate.dot")) require.NoError(t, err) - state, err := terraform.ConvertState([]*tfjson.StateModule{tfState.Values.RootModule}, string(tfStateGraph)) + state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{tfState.Values.RootModule}, string(tfStateGraph), logger) require.NoError(t, err) sortResources(state.Resources) sortExternalAuthProviders(state.ExternalAuthProviders) @@ -808,6 +818,7 @@ func TestConvertResources(t *testing.T) { func TestAppSlugValidation(t *testing.T) { t.Parallel() + ctx, logger := ctxAndLogger(t) // nolint:dogsled _, filename, _, _ := runtime.Caller(0) @@ -829,7 +840,7 @@ func TestAppSlugValidation(t *testing.T) { } } - state, err := terraform.ConvertState([]*tfjson.StateModule{tfPlan.PlannedValues.RootModule}, string(tfPlanGraph)) + state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PlannedValues.RootModule}, string(tfPlanGraph), logger) require.Nil(t, state) require.Error(t, err) require.ErrorContains(t, err, "invalid app slug") @@ -841,7 +852,7 @@ func TestAppSlugValidation(t *testing.T) { } } - state, err = terraform.ConvertState([]*tfjson.StateModule{tfPlan.PlannedValues.RootModule}, string(tfPlanGraph)) + state, err = terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PlannedValues.RootModule}, string(tfPlanGraph), logger) require.Nil(t, state) require.Error(t, err) require.ErrorContains(t, err, "duplicate app slug") @@ -849,6 +860,7 @@ func TestAppSlugValidation(t *testing.T) { func TestMetadataResourceDuplicate(t *testing.T) { t.Parallel() + ctx, logger := ctxAndLogger(t) // Load the multiple-apps state file and edit it. dir := filepath.Join("testdata", "resource-metadata-duplicate") @@ -860,7 +872,7 @@ func TestMetadataResourceDuplicate(t *testing.T) { tfPlanGraph, err := os.ReadFile(filepath.Join(dir, "resource-metadata-duplicate.tfplan.dot")) require.NoError(t, err) - state, err := terraform.ConvertState([]*tfjson.StateModule{tfPlan.PlannedValues.RootModule}, string(tfPlanGraph)) + state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PlannedValues.RootModule}, string(tfPlanGraph), logger) require.Nil(t, state) require.Error(t, err) require.ErrorContains(t, err, "duplicate metadata resource: null_resource.about") @@ -868,6 +880,7 @@ func TestMetadataResourceDuplicate(t *testing.T) { func TestParameterValidation(t *testing.T) { t.Parallel() + ctx, logger := ctxAndLogger(t) // nolint:dogsled _, filename, _, _ := runtime.Caller(0) @@ -891,7 +904,7 @@ func TestParameterValidation(t *testing.T) { } } - state, err := terraform.ConvertState([]*tfjson.StateModule{tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph)) + state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph), logger) require.Nil(t, state) require.Error(t, err) require.ErrorContains(t, err, "coder_parameter names must be unique but \"identical\" appears multiple times") @@ -907,7 +920,7 @@ func TestParameterValidation(t *testing.T) { } } - state, err = terraform.ConvertState([]*tfjson.StateModule{tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph)) + state, err = terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph), logger) require.Nil(t, state) require.Error(t, err) require.ErrorContains(t, err, "coder_parameter names must be unique but \"identical-0\" and \"identical-1\" appear multiple times") @@ -923,7 +936,7 @@ func TestParameterValidation(t *testing.T) { } } - state, err = terraform.ConvertState([]*tfjson.StateModule{tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph)) + state, err = terraform.ConvertState(ctx, []*tfjson.StateModule{tfPlan.PriorState.Values.RootModule}, string(tfPlanGraph), logger) require.Nil(t, state) require.Error(t, err) require.ErrorContains(t, err, "coder_parameter names must be unique but \"identical-0\", \"identical-1\" and \"identical-2\" appear multiple times") @@ -954,9 +967,10 @@ func TestInstanceTypeAssociation(t *testing.T) { tc := tc t.Run(tc.ResourceType, func(t *testing.T) { t.Parallel() + ctx, logger := ctxAndLogger(t) instanceType, err := cryptorand.String(12) require.NoError(t, err) - state, err := terraform.ConvertState([]*tfjson.StateModule{{ + state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{{ Resources: []*tfjson.StateResource{{ Address: tc.ResourceType + ".dev", Type: tc.ResourceType, @@ -973,7 +987,7 @@ func TestInstanceTypeAssociation(t *testing.T) { subgraph "root" { "[root] `+tc.ResourceType+`.dev" [label = "`+tc.ResourceType+`.dev", shape = "box"] } -}`) +}`, logger) require.NoError(t, err) require.Len(t, state.Resources, 1) require.Equal(t, state.Resources[0].GetInstanceType(), instanceType) @@ -1012,9 +1026,10 @@ func TestInstanceIDAssociation(t *testing.T) { tc := tc t.Run(tc.ResourceType, func(t *testing.T) { t.Parallel() + ctx, logger := ctxAndLogger(t) instanceID, err := cryptorand.String(12) require.NoError(t, err) - state, err := terraform.ConvertState([]*tfjson.StateModule{{ + state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{{ Resources: []*tfjson.StateResource{{ Address: "coder_agent.dev", Type: "coder_agent", @@ -1044,7 +1059,7 @@ func TestInstanceIDAssociation(t *testing.T) { "[root] `+tc.ResourceType+`.dev" -> "[root] coder_agent.dev" } } -`) +`, logger) require.NoError(t, err) require.Len(t, state.Resources, 1) require.Len(t, state.Resources[0].Agents, 1) From 301a15332a02d7da65a3ef5e5bc11f3a176d6978 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Wed, 13 Nov 2024 13:17:20 +0100 Subject: [PATCH 18/34] change error string --- provisioner/terraform/resources.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index de790a55f5cfa..01d4f047a7eba 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -781,7 +781,7 @@ func convertAddressToLabel(address string) string { func convertAddressToModulePath(address string) (string, error) { addr, err := tfaddr.NewAddress(address) if err != nil { - return "", xerrors.Errorf("parse address: %w", err) + return "", xerrors.Errorf("parse terraform address: %w", err) } return addr.ModulePath.String(), nil } From 212e7d5ca20ad62420369164291240d505b195fe Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Wed, 13 Nov 2024 13:50:38 +0100 Subject: [PATCH 19/34] obfuscate workspace module source and version --- coderd/telemetry/telemetry.go | 12 ++++++++++-- coderd/telemetry/telemetry_test.go | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/coderd/telemetry/telemetry.go b/coderd/telemetry/telemetry.go index 754db74129374..0b89529cc049e 100644 --- a/coderd/telemetry/telemetry.go +++ b/coderd/telemetry/telemetry.go @@ -677,12 +677,20 @@ func ConvertWorkspaceResourceMetadata(metadata database.WorkspaceResourceMetadat } func ConvertWorkspaceModule(module database.WorkspaceModule) WorkspaceModule { + isCoderModule := strings.Contains(module.Source, "registry.coder.com") + source := module.Source + version := module.Version + if !isCoderModule { + source = fmt.Sprintf("%x", sha256.Sum256([]byte(source))) + version = fmt.Sprintf("%x", sha256.Sum256([]byte(version))) + } + return WorkspaceModule{ ID: module.ID, JobID: module.JobID, Transition: module.Transition, - Source: module.Source, - Version: module.Version, + Source: source, + Version: version, Key: module.Key, CreatedAt: module.CreatedAt, } diff --git a/coderd/telemetry/telemetry_test.go b/coderd/telemetry/telemetry_test.go index 5210a9962499c..29035b6026af6 100644 --- a/coderd/telemetry/telemetry_test.go +++ b/coderd/telemetry/telemetry_test.go @@ -5,6 +5,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "sort" "testing" "time" @@ -122,6 +123,28 @@ func TestTelemetry(t *testing.T) { require.Len(t, snapshot.Users, 1) require.Equal(t, snapshot.Users[0].EmailHashed, "bb44bf07cf9a2db0554bba63a03d822c927deae77df101874496df5a6a3e896d@coder.com") }) + t.Run("HashedModule", func(t *testing.T) { + t.Parallel() + db := dbmem.New() + _ = dbgen.WorkspaceModule(t, db, database.WorkspaceModule{ + Source: "registry.coder.com/terraform/aws", + Version: "1.0.0", + }) + _ = dbgen.WorkspaceModule(t, db, database.WorkspaceModule{ + Source: "internal-url.com/some-module", + Version: "1.0.0", + }) + _, snapshot := collectSnapshot(t, db, nil) + require.Len(t, snapshot.WorkspaceModules, 2) + modules := snapshot.WorkspaceModules + sort.Slice(modules, func(i, j int) bool { + return modules[i].Source < modules[j].Source + }) + require.Equal(t, modules[0].Source, "921c61d6f3eef5118f3cae658d1518b378c5b02a4955a766c791440894d989c5") + require.Equal(t, modules[0].Version, "92521fc3cbd964bdc9f584a991b89fddaa5754ed1cc96d6d42445338669c1305") + require.Equal(t, modules[1].Source, "registry.coder.com/terraform/aws") + require.Equal(t, modules[1].Version, "1.0.0") + }) } // nolint:paralleltest From e9b7c46cbeb658aea2ebf20b16f3cef1a164deac Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Thu, 14 Nov 2024 10:00:20 +0000 Subject: [PATCH 20/34] fixes after rebase --- provisionersdk/proto/provisioner.pb.go | 761 ++++++++++++++----------- 1 file changed, 432 insertions(+), 329 deletions(-) diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 9d5406d403375..026939d17120e 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -1586,6 +1586,7 @@ type Resource struct { Icon string `protobuf:"bytes,6,opt,name=icon,proto3" json:"icon,omitempty"` InstanceType string `protobuf:"bytes,7,opt,name=instance_type,json=instanceType,proto3" json:"instance_type,omitempty"` DailyCost int32 `protobuf:"varint,8,opt,name=daily_cost,json=dailyCost,proto3" json:"daily_cost,omitempty"` + ModulePath string `protobuf:"bytes,9,opt,name=module_path,json=modulePath,proto3" json:"module_path,omitempty"` } func (x *Resource) Reset() { @@ -1676,6 +1677,76 @@ func (x *Resource) GetDailyCost() int32 { return 0 } +func (x *Resource) GetModulePath() string { + if x != nil { + return x.ModulePath + } + return "" +} + +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +func (x *Module) ProtoReflect() protoreflect.Message { + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + 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 Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{17} +} + +func (x *Module) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *Module) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Module) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + // Metadata is information about a workspace used in the execution of a build type Metadata struct { state protoimpl.MessageState @@ -1705,7 +1776,7 @@ type Metadata struct { func (x *Metadata) Reset() { *x = Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1718,7 +1789,7 @@ func (x *Metadata) String() string { func (*Metadata) ProtoMessage() {} func (x *Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1731,7 +1802,7 @@ func (x *Metadata) ProtoReflect() protoreflect.Message { // Deprecated: Use Metadata.ProtoReflect.Descriptor instead. func (*Metadata) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{17} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{18} } func (x *Metadata) GetCoderUrl() string { @@ -1876,7 +1947,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1889,7 +1960,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1902,7 +1973,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{18} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{19} } func (x *Config) GetTemplateSourceArchive() []byte { @@ -1936,7 +2007,7 @@ type ParseRequest struct { func (x *ParseRequest) Reset() { *x = ParseRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1949,7 +2020,7 @@ func (x *ParseRequest) String() string { func (*ParseRequest) ProtoMessage() {} func (x *ParseRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1962,7 +2033,7 @@ func (x *ParseRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseRequest.ProtoReflect.Descriptor instead. func (*ParseRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{19} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{20} } // ParseComplete indicates a request to parse completed. @@ -1980,7 +2051,7 @@ type ParseComplete struct { func (x *ParseComplete) Reset() { *x = ParseComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1993,7 +2064,7 @@ func (x *ParseComplete) String() string { func (*ParseComplete) ProtoMessage() {} func (x *ParseComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2006,7 +2077,7 @@ func (x *ParseComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use ParseComplete.ProtoReflect.Descriptor instead. func (*ParseComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{20} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{21} } func (x *ParseComplete) GetError() string { @@ -2052,7 +2123,7 @@ type PlanRequest struct { func (x *PlanRequest) Reset() { *x = PlanRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2065,7 +2136,7 @@ func (x *PlanRequest) String() string { func (*PlanRequest) ProtoMessage() {} func (x *PlanRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2078,7 +2149,7 @@ func (x *PlanRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanRequest.ProtoReflect.Descriptor instead. func (*PlanRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{21} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{22} } func (x *PlanRequest) GetMetadata() *Metadata { @@ -2120,12 +2191,13 @@ type PlanComplete struct { Parameters []*RichParameter `protobuf:"bytes,3,rep,name=parameters,proto3" json:"parameters,omitempty"` ExternalAuthProviders []*ExternalAuthProviderResource `protobuf:"bytes,4,rep,name=external_auth_providers,json=externalAuthProviders,proto3" json:"external_auth_providers,omitempty"` Timings []*Timing `protobuf:"bytes,6,rep,name=timings,proto3" json:"timings,omitempty"` + Modules []*Module `protobuf:"bytes,7,rep,name=modules,proto3" json:"modules,omitempty"` } func (x *PlanComplete) Reset() { *x = PlanComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2138,7 +2210,7 @@ func (x *PlanComplete) String() string { func (*PlanComplete) ProtoMessage() {} func (x *PlanComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[22] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2151,7 +2223,7 @@ func (x *PlanComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use PlanComplete.ProtoReflect.Descriptor instead. func (*PlanComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{22} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{23} } func (x *PlanComplete) GetError() string { @@ -2189,6 +2261,13 @@ func (x *PlanComplete) GetTimings() []*Timing { return nil } +func (x *PlanComplete) GetModules() []*Module { + if x != nil { + return x.Modules + } + return nil +} + // ApplyRequest asks the provisioner to apply the changes. Apply MUST be preceded by a successful plan request/response // in the same Session. The plan data is not transmitted over the wire and is cached by the provisioner in the Session. type ApplyRequest struct { @@ -2202,7 +2281,7 @@ type ApplyRequest struct { func (x *ApplyRequest) Reset() { *x = ApplyRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2215,7 +2294,7 @@ func (x *ApplyRequest) String() string { func (*ApplyRequest) ProtoMessage() {} func (x *ApplyRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[23] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2228,7 +2307,7 @@ func (x *ApplyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyRequest.ProtoReflect.Descriptor instead. func (*ApplyRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{23} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{24} } func (x *ApplyRequest) GetMetadata() *Metadata { @@ -2255,7 +2334,7 @@ type ApplyComplete struct { func (x *ApplyComplete) Reset() { *x = ApplyComplete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2268,7 +2347,7 @@ func (x *ApplyComplete) String() string { func (*ApplyComplete) ProtoMessage() {} func (x *ApplyComplete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[24] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2281,7 +2360,7 @@ func (x *ApplyComplete) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyComplete.ProtoReflect.Descriptor instead. func (*ApplyComplete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{24} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{25} } func (x *ApplyComplete) GetState() []byte { @@ -2343,7 +2422,7 @@ type Timing struct { func (x *Timing) Reset() { *x = Timing{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2356,7 +2435,7 @@ func (x *Timing) String() string { func (*Timing) ProtoMessage() {} func (x *Timing) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[25] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2369,7 +2448,7 @@ func (x *Timing) ProtoReflect() protoreflect.Message { // Deprecated: Use Timing.ProtoReflect.Descriptor instead. func (*Timing) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{25} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{26} } func (x *Timing) GetStart() *timestamppb.Timestamp { @@ -2431,7 +2510,7 @@ type CancelRequest struct { func (x *CancelRequest) Reset() { *x = CancelRequest{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2444,7 +2523,7 @@ func (x *CancelRequest) String() string { func (*CancelRequest) ProtoMessage() {} func (x *CancelRequest) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[26] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2457,7 +2536,7 @@ func (x *CancelRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CancelRequest.ProtoReflect.Descriptor instead. func (*CancelRequest) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{26} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{27} } type Request struct { @@ -2478,7 +2557,7 @@ type Request struct { func (x *Request) Reset() { *x = Request{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2491,7 +2570,7 @@ func (x *Request) String() string { func (*Request) ProtoMessage() {} func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[27] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2504,7 +2583,7 @@ func (x *Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Request.ProtoReflect.Descriptor instead. func (*Request) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{27} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{28} } func (m *Request) GetType() isRequest_Type { @@ -2600,7 +2679,7 @@ type Response struct { func (x *Response) Reset() { *x = Response{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2613,7 +2692,7 @@ func (x *Response) String() string { func (*Response) ProtoMessage() {} func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[28] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2626,7 +2705,7 @@ func (x *Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Response.ProtoReflect.Descriptor instead. func (*Response) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{28} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{29} } func (m *Response) GetType() isResponse_Type { @@ -2708,7 +2787,7 @@ type Agent_Metadata struct { func (x *Agent_Metadata) Reset() { *x = Agent_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2721,7 +2800,7 @@ func (x *Agent_Metadata) String() string { func (*Agent_Metadata) ProtoMessage() {} func (x *Agent_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[29] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[30] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2793,7 +2872,7 @@ type Resource_Metadata struct { func (x *Resource_Metadata) Reset() { *x = Resource_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2806,7 +2885,7 @@ func (x *Resource_Metadata) String() string { func (*Resource_Metadata) ProtoMessage() {} func (x *Resource_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[31] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[32] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3065,7 +3144,7 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0xf1, 0x02, 0x0a, 0x08, 0x52, + 0x09, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0x92, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, @@ -3082,233 +3161,243 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x43, - 0x6f, 0x73, 0x74, 0x1a, 0x69, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, - 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, - 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x22, 0xac, - 0x07, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x53, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, - 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, - 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, - 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x32, - 0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, - 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x45, 0x6d, 0x61, - 0x69, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x21, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, - 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1d, 0x77, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x4f, 0x69, 0x64, - 0x63, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x41, 0x0a, 0x1d, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, - 0x6e, 0x65, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, - 0x12, 0x30, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, - 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x0e, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, - 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x42, 0x0a, 0x1e, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x73, 0x68, 0x5f, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, - 0x53, 0x73, 0x68, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x1f, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, - 0x73, 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x53, 0x73, 0x68, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, - 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, - 0x12, 0x3b, 0x0a, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x12, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, - 0x77, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8a, 0x01, - 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x65, 0x6d, 0x70, - 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x74, 0x65, 0x6d, 0x70, 0x6c, - 0x61, 0x74, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa3, 0x02, 0x0a, 0x0d, 0x50, - 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, - 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, - 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2e, 0x57, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x40, - 0x0a, 0x12, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0xb5, 0x02, 0x0a, 0x0b, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x6f, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x50, 0x61, 0x74, 0x68, 0x1a, 0x69, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6e, 0x75, 0x6c, + 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x22, + 0x4c, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0xac, 0x07, + 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, + 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x53, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, + 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, + 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, + 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x48, 0x0a, 0x21, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x6f, 0x69, 0x64, 0x63, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1d, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x4f, 0x69, 0x64, 0x63, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x41, 0x0a, 0x1d, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, + 0x65, 0x72, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1f, + 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, + 0x30, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x34, 0x0a, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, + 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x42, 0x0a, 0x1e, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x73, 0x73, 0x68, 0x5f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x53, + 0x73, 0x68, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x44, 0x0a, 0x1f, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x73, + 0x73, 0x68, 0x5f, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, + 0x77, 0x6e, 0x65, 0x72, 0x53, 0x73, 0x68, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, + 0x3b, 0x0a, 0x1a, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, + 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x8a, 0x01, 0x0a, + 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, + 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x0e, 0x0a, 0x0c, 0x50, 0x61, 0x72, + 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa3, 0x02, 0x0a, 0x0d, 0x50, 0x61, + 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x4c, 0x0a, 0x12, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x11, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x72, 0x65, 0x61, 0x64, 0x6d, 0x65, 0x12, 0x54, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, + 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2e, 0x57, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x40, 0x0a, + 0x12, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xb5, 0x02, 0x0a, 0x0b, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, + 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, + 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x59, 0x0a, 0x17, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xd6, 0x02, 0x0a, 0x0c, 0x50, 0x6c, 0x61, 0x6e, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 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, 0x12, 0x3a, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, + 0x61, 0x0a, 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, + 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x15, 0x65, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, + 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, + 0x22, 0x41, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x53, 0x0a, 0x15, 0x72, 0x69, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, - 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x13, 0x72, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x61, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x76, - 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x59, 0x0a, - 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x22, 0xa7, 0x02, 0x0a, 0x0c, 0x50, 0x6c, 0x61, - 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 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, 0x12, 0x3a, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x12, 0x61, 0x0a, 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, - 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x15, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x65, 0x72, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, - 0x67, 0x73, 0x22, 0x41, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xbe, 0x02, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, - 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x18, 0x03, 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, 0x12, 0x3a, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x12, 0x61, 0x0a, 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x15, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, - 0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, - 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, - 0x67, 0x12, 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, - 0x64, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, - 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x8c, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x2d, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x31, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, - 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, 0x70, 0x61, 0x72, - 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, - 0x6c, 0x61, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6c, - 0x61, 0x6e, 0x12, 0x31, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, - 0x61, 0x70, 0x70, 0x6c, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x48, 0x00, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x22, 0xd1, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, - 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x32, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x73, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x48, 0x00, 0x52, 0x05, 0x70, 0x61, 0x72, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x70, 0x6c, - 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x61, - 0x70, 0x70, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x42, - 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x00, 0x12, 0x09, - 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, - 0x4f, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x03, 0x12, 0x09, 0x0a, - 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x2a, 0x3b, 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x53, - 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x4f, - 0x57, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, - 0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, - 0x4c, 0x49, 0x43, 0x10, 0x02, 0x2a, 0x37, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, - 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, - 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x02, 0x2a, 0x35, - 0x0a, 0x0b, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, - 0x07, 0x53, 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, - 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, - 0x4c, 0x45, 0x44, 0x10, 0x02, 0x32, 0x49, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x14, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, - 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, - 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x74, 0x61, 0x22, 0xbe, 0x02, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, + 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, 0x12, 0x3a, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x69, 0x63, 0x68, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x12, 0x61, 0x0a, 0x17, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x61, + 0x75, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x15, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x74, 0x69, 0x6d, + 0x69, 0x6e, 0x67, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x06, 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x12, + 0x30, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x65, 0x6e, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, + 0x65, 0x12, 0x2e, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x54, + 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x8c, 0x02, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, + 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x31, 0x0a, + 0x05, 0x70, 0x61, 0x72, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x12, 0x2e, 0x0a, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x6c, 0x61, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6c, 0x61, 0x6e, + 0x12, 0x31, 0x0a, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x70, + 0x70, 0x6c, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x05, 0x61, 0x70, + 0x70, 0x6c, 0x79, 0x12, 0x34, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, + 0x00, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x22, 0xd1, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, + 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, + 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x32, 0x0a, 0x05, 0x70, 0x61, 0x72, 0x73, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, + 0x00, 0x52, 0x05, 0x70, 0x61, 0x72, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x70, 0x6c, 0x61, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x12, 0x32, 0x0a, 0x05, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x42, 0x06, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, + 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, + 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, + 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x2a, 0x3b, 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x53, 0x68, 0x61, + 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x57, 0x4e, + 0x45, 0x52, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, + 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, + 0x43, 0x10, 0x02, 0x2a, 0x37, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, + 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, + 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x02, 0x2a, 0x35, 0x0a, 0x0b, + 0x54, 0x69, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x53, + 0x54, 0x41, 0x52, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, + 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, + 0x44, 0x10, 0x02, 0x32, 0x49, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x65, 0x72, 0x12, 0x3a, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x30, + 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3324,7 +3413,7 @@ func file_provisionersdk_proto_provisioner_proto_rawDescGZIP() []byte { } var file_provisionersdk_proto_provisioner_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 33) +var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 34) var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (LogLevel)(0), // 0: provisioner.LogLevel (AppSharingLevel)(0), // 1: provisioner.AppSharingLevel @@ -3347,72 +3436,74 @@ var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (*App)(nil), // 18: provisioner.App (*Healthcheck)(nil), // 19: provisioner.Healthcheck (*Resource)(nil), // 20: provisioner.Resource - (*Metadata)(nil), // 21: provisioner.Metadata - (*Config)(nil), // 22: provisioner.Config - (*ParseRequest)(nil), // 23: provisioner.ParseRequest - (*ParseComplete)(nil), // 24: provisioner.ParseComplete - (*PlanRequest)(nil), // 25: provisioner.PlanRequest - (*PlanComplete)(nil), // 26: provisioner.PlanComplete - (*ApplyRequest)(nil), // 27: provisioner.ApplyRequest - (*ApplyComplete)(nil), // 28: provisioner.ApplyComplete - (*Timing)(nil), // 29: provisioner.Timing - (*CancelRequest)(nil), // 30: provisioner.CancelRequest - (*Request)(nil), // 31: provisioner.Request - (*Response)(nil), // 32: provisioner.Response - (*Agent_Metadata)(nil), // 33: provisioner.Agent.Metadata - nil, // 34: provisioner.Agent.EnvEntry - (*Resource_Metadata)(nil), // 35: provisioner.Resource.Metadata - nil, // 36: provisioner.ParseComplete.WorkspaceTagsEntry - (*timestamppb.Timestamp)(nil), // 37: google.protobuf.Timestamp + (*Module)(nil), // 21: provisioner.Module + (*Metadata)(nil), // 22: provisioner.Metadata + (*Config)(nil), // 23: provisioner.Config + (*ParseRequest)(nil), // 24: provisioner.ParseRequest + (*ParseComplete)(nil), // 25: provisioner.ParseComplete + (*PlanRequest)(nil), // 26: provisioner.PlanRequest + (*PlanComplete)(nil), // 27: provisioner.PlanComplete + (*ApplyRequest)(nil), // 28: provisioner.ApplyRequest + (*ApplyComplete)(nil), // 29: provisioner.ApplyComplete + (*Timing)(nil), // 30: provisioner.Timing + (*CancelRequest)(nil), // 31: provisioner.CancelRequest + (*Request)(nil), // 32: provisioner.Request + (*Response)(nil), // 33: provisioner.Response + (*Agent_Metadata)(nil), // 34: provisioner.Agent.Metadata + nil, // 35: provisioner.Agent.EnvEntry + (*Resource_Metadata)(nil), // 36: provisioner.Resource.Metadata + nil, // 37: provisioner.ParseComplete.WorkspaceTagsEntry + (*timestamppb.Timestamp)(nil), // 38: google.protobuf.Timestamp } var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{ 6, // 0: provisioner.RichParameter.options:type_name -> provisioner.RichParameterOption 0, // 1: provisioner.Log.level:type_name -> provisioner.LogLevel - 34, // 2: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry + 35, // 2: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry 18, // 3: provisioner.Agent.apps:type_name -> provisioner.App - 33, // 4: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata + 34, // 4: provisioner.Agent.metadata:type_name -> provisioner.Agent.Metadata 15, // 5: provisioner.Agent.display_apps:type_name -> provisioner.DisplayApps 17, // 6: provisioner.Agent.scripts:type_name -> provisioner.Script 16, // 7: provisioner.Agent.extra_envs:type_name -> provisioner.Env 19, // 8: provisioner.App.healthcheck:type_name -> provisioner.Healthcheck 1, // 9: provisioner.App.sharing_level:type_name -> provisioner.AppSharingLevel 14, // 10: provisioner.Resource.agents:type_name -> provisioner.Agent - 35, // 11: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata + 36, // 11: provisioner.Resource.metadata:type_name -> provisioner.Resource.Metadata 2, // 12: provisioner.Metadata.workspace_transition:type_name -> provisioner.WorkspaceTransition 5, // 13: provisioner.ParseComplete.template_variables:type_name -> provisioner.TemplateVariable - 36, // 14: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry - 21, // 15: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata + 37, // 14: provisioner.ParseComplete.workspace_tags:type_name -> provisioner.ParseComplete.WorkspaceTagsEntry + 22, // 15: provisioner.PlanRequest.metadata:type_name -> provisioner.Metadata 8, // 16: provisioner.PlanRequest.rich_parameter_values:type_name -> provisioner.RichParameterValue 9, // 17: provisioner.PlanRequest.variable_values:type_name -> provisioner.VariableValue 13, // 18: provisioner.PlanRequest.external_auth_providers:type_name -> provisioner.ExternalAuthProvider 20, // 19: provisioner.PlanComplete.resources:type_name -> provisioner.Resource 7, // 20: provisioner.PlanComplete.parameters:type_name -> provisioner.RichParameter 12, // 21: provisioner.PlanComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource - 29, // 22: provisioner.PlanComplete.timings:type_name -> provisioner.Timing - 21, // 23: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata - 20, // 24: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource - 7, // 25: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter - 12, // 26: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource - 29, // 27: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing - 37, // 28: provisioner.Timing.start:type_name -> google.protobuf.Timestamp - 37, // 29: provisioner.Timing.end:type_name -> google.protobuf.Timestamp - 3, // 30: provisioner.Timing.state:type_name -> provisioner.TimingState - 22, // 31: provisioner.Request.config:type_name -> provisioner.Config - 23, // 32: provisioner.Request.parse:type_name -> provisioner.ParseRequest - 25, // 33: provisioner.Request.plan:type_name -> provisioner.PlanRequest - 27, // 34: provisioner.Request.apply:type_name -> provisioner.ApplyRequest - 30, // 35: provisioner.Request.cancel:type_name -> provisioner.CancelRequest - 10, // 36: provisioner.Response.log:type_name -> provisioner.Log - 24, // 37: provisioner.Response.parse:type_name -> provisioner.ParseComplete - 26, // 38: provisioner.Response.plan:type_name -> provisioner.PlanComplete - 28, // 39: provisioner.Response.apply:type_name -> provisioner.ApplyComplete - 31, // 40: provisioner.Provisioner.Session:input_type -> provisioner.Request - 32, // 41: provisioner.Provisioner.Session:output_type -> provisioner.Response - 41, // [41:42] is the sub-list for method output_type - 40, // [40:41] is the sub-list for method input_type - 40, // [40:40] is the sub-list for extension type_name - 40, // [40:40] is the sub-list for extension extendee - 0, // [0:40] is the sub-list for field type_name + 30, // 22: provisioner.PlanComplete.timings:type_name -> provisioner.Timing + 21, // 23: provisioner.PlanComplete.modules:type_name -> provisioner.Module + 22, // 24: provisioner.ApplyRequest.metadata:type_name -> provisioner.Metadata + 20, // 25: provisioner.ApplyComplete.resources:type_name -> provisioner.Resource + 7, // 26: provisioner.ApplyComplete.parameters:type_name -> provisioner.RichParameter + 12, // 27: provisioner.ApplyComplete.external_auth_providers:type_name -> provisioner.ExternalAuthProviderResource + 30, // 28: provisioner.ApplyComplete.timings:type_name -> provisioner.Timing + 38, // 29: provisioner.Timing.start:type_name -> google.protobuf.Timestamp + 38, // 30: provisioner.Timing.end:type_name -> google.protobuf.Timestamp + 3, // 31: provisioner.Timing.state:type_name -> provisioner.TimingState + 23, // 32: provisioner.Request.config:type_name -> provisioner.Config + 24, // 33: provisioner.Request.parse:type_name -> provisioner.ParseRequest + 26, // 34: provisioner.Request.plan:type_name -> provisioner.PlanRequest + 28, // 35: provisioner.Request.apply:type_name -> provisioner.ApplyRequest + 31, // 36: provisioner.Request.cancel:type_name -> provisioner.CancelRequest + 10, // 37: provisioner.Response.log:type_name -> provisioner.Log + 25, // 38: provisioner.Response.parse:type_name -> provisioner.ParseComplete + 27, // 39: provisioner.Response.plan:type_name -> provisioner.PlanComplete + 29, // 40: provisioner.Response.apply:type_name -> provisioner.ApplyComplete + 32, // 41: provisioner.Provisioner.Session:input_type -> provisioner.Request + 33, // 42: provisioner.Provisioner.Session:output_type -> provisioner.Response + 42, // [42:43] is the sub-list for method output_type + 41, // [41:42] is the sub-list for method input_type + 41, // [41:41] is the sub-list for extension type_name + 41, // [41:41] is the sub-list for extension extendee + 0, // [0:41] is the sub-list for field type_name } func init() { file_provisionersdk_proto_provisioner_proto_init() } @@ -3626,7 +3717,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metadata); i { + switch v := v.(*Module); i { case 0: return &v.state case 1: @@ -3638,7 +3729,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Config); i { + switch v := v.(*Metadata); i { case 0: return &v.state case 1: @@ -3650,7 +3741,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParseRequest); i { + switch v := v.(*Config); i { case 0: return &v.state case 1: @@ -3662,7 +3753,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParseComplete); i { + switch v := v.(*ParseRequest); i { case 0: return &v.state case 1: @@ -3674,7 +3765,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlanRequest); i { + switch v := v.(*ParseComplete); i { case 0: return &v.state case 1: @@ -3686,7 +3777,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlanComplete); i { + switch v := v.(*PlanRequest); i { case 0: return &v.state case 1: @@ -3698,7 +3789,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyRequest); i { + switch v := v.(*PlanComplete); i { case 0: return &v.state case 1: @@ -3710,7 +3801,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyComplete); i { + switch v := v.(*ApplyRequest); i { case 0: return &v.state case 1: @@ -3722,7 +3813,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Timing); i { + switch v := v.(*ApplyComplete); i { case 0: return &v.state case 1: @@ -3734,7 +3825,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CancelRequest); i { + switch v := v.(*Timing); i { case 0: return &v.state case 1: @@ -3746,7 +3837,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Request); i { + switch v := v.(*CancelRequest); i { case 0: return &v.state case 1: @@ -3758,7 +3849,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { + switch v := v.(*Request); i { case 0: return &v.state case 1: @@ -3770,6 +3861,18 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_provisionersdk_proto_provisioner_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Agent_Metadata); i { case 0: return &v.state @@ -3781,7 +3884,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Resource_Metadata); i { case 0: return &v.state @@ -3799,14 +3902,14 @@ func file_provisionersdk_proto_provisioner_proto_init() { (*Agent_Token)(nil), (*Agent_InstanceId)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[27].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[28].OneofWrappers = []interface{}{ (*Request_Config)(nil), (*Request_Parse)(nil), (*Request_Plan)(nil), (*Request_Apply)(nil), (*Request_Cancel)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[28].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[29].OneofWrappers = []interface{}{ (*Response_Log)(nil), (*Response_Parse)(nil), (*Response_Plan)(nil), @@ -3818,7 +3921,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_provisionersdk_proto_provisioner_proto_rawDesc, NumEnums: 4, - NumMessages: 33, + NumMessages: 34, NumExtensions: 0, NumServices: 1, }, From 25cba6d4b80212af22b816055f65a5bc06ba335c Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 15 Nov 2024 16:58:49 +0000 Subject: [PATCH 21/34] change migration number --- ...rkspace_modules.down.sql => 000276_workspace_modules.down.sql} | 0 ...4_workspace_modules.up.sql => 000276_workspace_modules.up.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename coderd/database/migrations/{000274_workspace_modules.down.sql => 000276_workspace_modules.down.sql} (100%) rename coderd/database/migrations/{000274_workspace_modules.up.sql => 000276_workspace_modules.up.sql} (100%) diff --git a/coderd/database/migrations/000274_workspace_modules.down.sql b/coderd/database/migrations/000276_workspace_modules.down.sql similarity index 100% rename from coderd/database/migrations/000274_workspace_modules.down.sql rename to coderd/database/migrations/000276_workspace_modules.down.sql diff --git a/coderd/database/migrations/000274_workspace_modules.up.sql b/coderd/database/migrations/000276_workspace_modules.up.sql similarity index 100% rename from coderd/database/migrations/000274_workspace_modules.up.sql rename to coderd/database/migrations/000276_workspace_modules.up.sql From 780730fdb71af216513bb89f2256bb9a6a1fd05a Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 15 Nov 2024 16:59:38 +0000 Subject: [PATCH 22/34] change fixture number --- ...4_workspace_modules.up.sql => 000276_workspace_modules.up.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename coderd/database/migrations/testdata/fixtures/{000274_workspace_modules.up.sql => 000276_workspace_modules.up.sql} (100%) diff --git a/coderd/database/migrations/testdata/fixtures/000274_workspace_modules.up.sql b/coderd/database/migrations/testdata/fixtures/000276_workspace_modules.up.sql similarity index 100% rename from coderd/database/migrations/testdata/fixtures/000274_workspace_modules.up.sql rename to coderd/database/migrations/testdata/fixtures/000276_workspace_modules.up.sql From b47a018beda467f3f08f82bc8bd9467472b033ed Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 15 Nov 2024 17:00:24 +0000 Subject: [PATCH 23/34] add index on created_at --- coderd/database/migrations/000276_workspace_modules.up.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coderd/database/migrations/000276_workspace_modules.up.sql b/coderd/database/migrations/000276_workspace_modules.up.sql index 8d4c475cf8a9a..d471f5fd31dd6 100644 --- a/coderd/database/migrations/000276_workspace_modules.up.sql +++ b/coderd/database/migrations/000276_workspace_modules.up.sql @@ -12,3 +12,5 @@ CREATE TABLE workspace_modules ( key TEXT NOT NULL, created_at timestamp with time zone NOT NULL ); + +CREATE INDEX workspace_modules_created_at_idx ON workspace_modules (created_at); From 03be52e039eff1ad3612ed77747d375485e99787 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 15 Nov 2024 17:21:55 +0000 Subject: [PATCH 24/34] add a comment about using modules from plan instead of apply --- provisionerd/runner/runner.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/provisionerd/runner/runner.go b/provisionerd/runner/runner.go index c64ec93bebbc8..d8b4149ec075f 100644 --- a/provisionerd/runner/runner.go +++ b/provisionerd/runner/runner.go @@ -1038,7 +1038,10 @@ func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *p State: applyComplete.State, Resources: applyComplete.Resources, Timings: applyComplete.Timings, - Modules: planComplete.Modules, + // Modules are created on disk by `terraform init`, and that is only + // called by `plan`. `apply` does not modify them, so we can use the + // modules from the plan response. + Modules: planComplete.Modules, }, }, }, nil From 00b8131967786723f98e54891baf30a5ba0642d4 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 15 Nov 2024 17:40:01 +0000 Subject: [PATCH 25/34] convert sentinel string to an error --- provisioner/terraform/resources.go | 4 +++- provisioner/terraform/resources_test.go | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index 01d4f047a7eba..0ff1660eaf807 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -134,6 +134,8 @@ type State struct { ExternalAuthProviders []*proto.ExternalAuthProviderResource } +var ErrInvalidTerraformAddr = xerrors.New("invalid terraform address") + // ConvertState consumes Terraform state and a GraphViz representation // produced by `terraform graph` to produce resources consumable by Coder. // nolint:gocognit // This function makes more sense being large for now, until refactored. @@ -609,7 +611,7 @@ func ConvertState(ctx context.Context, modules []*tfjson.StateModule, rawGraph s // the database, a null value in WorkspaceResource's ModulePath // indicates "this resource was created before module paths // were tracked." - modulePath = "FAILED_TO_PARSE_TERRAFORM_ADDRESS" + modulePath = fmt.Sprintf("%s", ErrInvalidTerraformAddr) logger.Error(ctx, "failed to parse Terraform address", slog.F("address", resource.Address)) } diff --git a/provisioner/terraform/resources_test.go b/provisioner/terraform/resources_test.go index ddb16fc04f201..576ad9ea8e3b3 100644 --- a/provisioner/terraform/resources_test.go +++ b/provisioner/terraform/resources_test.go @@ -816,6 +816,25 @@ func TestConvertResources(t *testing.T) { } } +func TestInvalidTerraformAddress(t *testing.T) { + t.Parallel() + ctx, logger := context.Background(), slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug) + state, err := terraform.ConvertState(ctx, []*tfjson.StateModule{{ + Resources: []*tfjson.StateResource{{ + Address: "invalid", + Type: "invalid", + Name: "invalid", + Mode: tfjson.ManagedResourceMode, + AttributeValues: map[string]interface{}{}, + }}, + // This is manually created to join the edges. + }}, `digraph {}`, logger) + require.Nil(t, err) + require.Len(t, state.Resources, 1) + require.Equal(t, state.Resources[0].Name, "invalid") + require.Equal(t, state.Resources[0].ModulePath, "invalid terraform address") +} + func TestAppSlugValidation(t *testing.T) { t.Parallel() ctx, logger := ctxAndLogger(t) From 4187fbfcf498904c007e5cfa05f1ff698786e9fb Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 15 Nov 2024 17:40:41 +0000 Subject: [PATCH 26/34] remove unnecessary comment --- provisioner/terraform/resources_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/provisioner/terraform/resources_test.go b/provisioner/terraform/resources_test.go index 576ad9ea8e3b3..29d3552e2d059 100644 --- a/provisioner/terraform/resources_test.go +++ b/provisioner/terraform/resources_test.go @@ -827,7 +827,6 @@ func TestInvalidTerraformAddress(t *testing.T) { Mode: tfjson.ManagedResourceMode, AttributeValues: map[string]interface{}{}, }}, - // This is manually created to join the edges. }}, `digraph {}`, logger) require.Nil(t, err) require.Len(t, state.Resources, 1) From 7e82c3d05d67b31b0888220701ce6169af368e79 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Fri, 15 Nov 2024 17:43:15 +0000 Subject: [PATCH 27/34] don't fail if we can't get modules from disk --- provisioner/terraform/provision.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go index f7680f6a6b417..c2ca6f56ef9a5 100644 --- a/provisioner/terraform/provision.go +++ b/provisioner/terraform/provision.go @@ -144,7 +144,7 @@ func (s *server) Plan( modules, err := getModules(sess.WorkDirectory) if err != nil { - return provisionersdk.PlanErrorf("get modules: %s", err) + s.logger.Error(ctx, "failed to get modules from disk", slog.Error(err)) } initTimings.ingest(createInitTimingsEvent(timingInitComplete)) From 42e57ca90e852a5b2fd72ec42703d41f9a7077eb Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Sat, 16 Nov 2024 12:11:45 +0000 Subject: [PATCH 28/34] add a test for a malformed module --- provisioner/terraform/provision_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/provisioner/terraform/provision_test.go b/provisioner/terraform/provision_test.go index f84e9503dc9a2..f39c1bb4ec605 100644 --- a/provisioner/terraform/provision_test.go +++ b/provisioner/terraform/provision_test.go @@ -991,3 +991,20 @@ func TestProvision_SafeEnv(t *testing.T) { require.NotContains(t, log, secretValue) require.Contains(t, log, "CODER_") } + +func TestProvision_MalformedModules(t *testing.T) { + t.Parallel() + + ctx, api := setupProvisioner(t, nil) + sess := configure(ctx, t, api, &proto.Config{ + TemplateSourceArchive: makeTar(t, map[string]string{ + "main.tf": `module "hello" { source = "./module" }`, + "module/module.tf": `resource "null_`, + }), + }) + + err := sendPlan(sess, proto.WorkspaceTransition_START) + require.NoError(t, err) + log := readProvisionLog(t, sess) + require.Contains(t, log, "Invalid block definition") +} From 368fc258905a71f075ddad67ebd6495cb6aee88a Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Sat, 16 Nov 2024 12:13:43 +0000 Subject: [PATCH 29/34] add a comment --- provisioner/terraform/provision.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go index c2ca6f56ef9a5..70a83bb2334b2 100644 --- a/provisioner/terraform/provision.go +++ b/provisioner/terraform/provision.go @@ -144,6 +144,8 @@ func (s *server) Plan( modules, err := getModules(sess.WorkDirectory) if err != nil { + // We allow getModules to fail, as the result is used only + // for telemetry purposes now. s.logger.Error(ctx, "failed to get modules from disk", slog.Error(err)) } From 73b22cf87518b4f7b1dd7012bb316571e884136a Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Sat, 16 Nov 2024 12:15:18 +0000 Subject: [PATCH 30/34] combine assignment and conditional --- coderd/provisionerdserver/provisionerdserver.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index ece5f0bcafc50..4503eb58ab914 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1261,8 +1261,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) slog.F("resource_type", resource.Type), slog.F("transition", transition)) - err = InsertWorkspaceResource(ctx, s.Database, jobID, transition, resource, telemetrySnapshot) - if err != nil { + if err := InsertWorkspaceResource(ctx, s.Database, jobID, transition, resource, telemetrySnapshot); err != nil { return nil, xerrors.Errorf("insert resource: %w", err) } } @@ -1279,8 +1278,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) slog.F("module_key", module.Key), slog.F("transition", transition)) - err = InsertWorkspaceModule(ctx, s.Database, jobID, transition, module, telemetrySnapshot) - if err != nil { + if err := InsertWorkspaceModule(ctx, s.Database, jobID, transition, module, telemetrySnapshot); err != nil { return nil, xerrors.Errorf("insert module: %w", err) } } From 7b9d70aa3e37754a75d585da99508827a84dc21c Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Sat, 16 Nov 2024 12:19:04 +0000 Subject: [PATCH 31/34] make isCoderModule into a top level function --- coderd/telemetry/telemetry.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coderd/telemetry/telemetry.go b/coderd/telemetry/telemetry.go index 0b89529cc049e..e5216cfd1b743 100644 --- a/coderd/telemetry/telemetry.go +++ b/coderd/telemetry/telemetry.go @@ -676,11 +676,14 @@ func ConvertWorkspaceResourceMetadata(metadata database.WorkspaceResourceMetadat } } +func shouldSendRawModuleSource(source string) bool { + return strings.Contains(source, "registry.coder.com") +} + func ConvertWorkspaceModule(module database.WorkspaceModule) WorkspaceModule { - isCoderModule := strings.Contains(module.Source, "registry.coder.com") source := module.Source version := module.Version - if !isCoderModule { + if !shouldSendRawModuleSource(source) { source = fmt.Sprintf("%x", sha256.Sum256([]byte(source))) version = fmt.Sprintf("%x", sha256.Sum256([]byte(version))) } From ea82313b8da100ee00f566e0c8bfecdb2d60ccbf Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Sat, 16 Nov 2024 12:21:54 +0000 Subject: [PATCH 32/34] use dbtestutil.NewDB instead of dbmem --- coderd/telemetry/telemetry_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/coderd/telemetry/telemetry_test.go b/coderd/telemetry/telemetry_test.go index 29035b6026af6..4d5396b48a25f 100644 --- a/coderd/telemetry/telemetry_test.go +++ b/coderd/telemetry/telemetry_test.go @@ -21,6 +21,7 @@ import ( "github.com/coder/coder/v2/coderd/database" "github.com/coder/coder/v2/coderd/database/dbgen" "github.com/coder/coder/v2/coderd/database/dbmem" + "github.com/coder/coder/v2/coderd/database/dbtestutil" "github.com/coder/coder/v2/coderd/database/dbtime" "github.com/coder/coder/v2/coderd/telemetry" "github.com/coder/coder/v2/testutil" @@ -125,12 +126,15 @@ func TestTelemetry(t *testing.T) { }) t.Run("HashedModule", func(t *testing.T) { t.Parallel() - db := dbmem.New() + db, _ := dbtestutil.NewDB(t) + pj := dbgen.ProvisionerJob(t, db, nil, database.ProvisionerJob{}) _ = dbgen.WorkspaceModule(t, db, database.WorkspaceModule{ + JobID: pj.ID, Source: "registry.coder.com/terraform/aws", Version: "1.0.0", }) _ = dbgen.WorkspaceModule(t, db, database.WorkspaceModule{ + JobID: pj.ID, Source: "internal-url.com/some-module", Version: "1.0.0", }) From 8564e9a97f406060bf77531c3f1a94507f7eeab2 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Sat, 16 Nov 2024 12:35:23 +0000 Subject: [PATCH 33/34] make gen --- coderd/database/dump.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 01fce9b24ee54..9919011579bde 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -2106,6 +2106,8 @@ CREATE INDEX workspace_agents_resource_id_idx ON workspace_agents USING btree (r CREATE INDEX workspace_app_stats_workspace_id_idx ON workspace_app_stats USING btree (workspace_id); +CREATE INDEX workspace_modules_created_at_idx ON workspace_modules USING btree (created_at); + CREATE UNIQUE INDEX workspace_proxies_lower_name_idx ON workspace_proxies USING btree (lower(name)) WHERE (deleted = false); CREATE INDEX workspace_resources_job_id_idx ON workspace_resources USING btree (job_id); From d11fc82b9d111528c226a79765f94cc3b24bb511 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Sat, 16 Nov 2024 12:52:13 +0000 Subject: [PATCH 34/34] combine 2 more assignments and conditionals --- coderd/provisionerdserver/provisionerdserver.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go index 4503eb58ab914..8387f97ea21cb 100644 --- a/coderd/provisionerdserver/provisionerdserver.go +++ b/coderd/provisionerdserver/provisionerdserver.go @@ -1489,8 +1489,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) } } for _, module := range jobType.WorkspaceBuild.Modules { - err = InsertWorkspaceModule(ctx, db, job.ID, workspaceBuild.Transition, module, telemetrySnapshot) - if err != nil { + if err := InsertWorkspaceModule(ctx, db, job.ID, workspaceBuild.Transition, module, telemetrySnapshot); err != nil { return xerrors.Errorf("insert provisioner job module: %w", err) } } @@ -1681,8 +1680,7 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) slog.F("module_source", module.Source), ) - err = InsertWorkspaceModule(ctx, s.Database, jobID, database.WorkspaceTransitionStart, module, telemetrySnapshot) - if err != nil { + if err := InsertWorkspaceModule(ctx, s.Database, jobID, database.WorkspaceTransitionStart, module, telemetrySnapshot); err != nil { return nil, xerrors.Errorf("insert module: %w", err) } }