From 48527f7de48140ec08fe528d4e8c047019f87618 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Sat, 29 Jan 2022 15:24:27 +0000 Subject: [PATCH 1/5] feat: Add parameter and jobs database schema This modifies a prior migration which is typically forbidden, but because we're pre-production deployment I felt grouping would be helpful to future contributors. This adds database functions that are required for the provisioner daemon and job queue logic. --- database/databasefake/databasefake.go | 215 +++++++- database/dump.sql | 82 +++- database/migrations/000002_projects.up.sql | 12 +- database/migrations/000004_jobs.down.sql | 0 database/migrations/000004_jobs.up.sql | 53 ++ database/migrations/create_migration.sh | 2 +- database/models.go | 146 +++++- database/querier.go | 13 + database/query.sql | 155 +++++- database/query.sql.go | 545 ++++++++++++++++++++- 10 files changed, 1161 insertions(+), 62 deletions(-) create mode 100644 database/migrations/000004_jobs.down.sql create mode 100644 database/migrations/000004_jobs.up.sql diff --git a/database/databasefake/databasefake.go b/database/databasefake/databasefake.go index b7cd6de3c57e8..f0e97101321f5 100644 --- a/database/databasefake/databasefake.go +++ b/database/databasefake/databasefake.go @@ -18,13 +18,16 @@ func New() database.Store { organizationMembers: make([]database.OrganizationMember, 0), users: make([]database.User, 0), - project: make([]database.Project, 0), - projectHistory: make([]database.ProjectHistory, 0), - projectParameter: make([]database.ProjectParameter, 0), - workspace: make([]database.Workspace, 0), - workspaceResource: make([]database.WorkspaceResource, 0), - workspaceHistory: make([]database.WorkspaceHistory, 0), - workspaceAgent: make([]database.WorkspaceAgent, 0), + parameterValue: make([]database.ParameterValue, 0), + project: make([]database.Project, 0), + projectHistory: make([]database.ProjectHistory, 0), + projectParameter: make([]database.ProjectParameter, 0), + provisionerDaemons: make([]database.ProvisionerDaemon, 0), + provisionerJobs: make([]database.ProvisionerJob, 0), + workspace: make([]database.Workspace, 0), + workspaceResource: make([]database.WorkspaceResource, 0), + workspaceHistory: make([]database.WorkspaceHistory, 0), + workspaceAgent: make([]database.WorkspaceAgent, 0), } } @@ -37,13 +40,16 @@ type fakeQuerier struct { users []database.User // New tables - project []database.Project - projectHistory []database.ProjectHistory - projectParameter []database.ProjectParameter - workspace []database.Workspace - workspaceResource []database.WorkspaceResource - workspaceHistory []database.WorkspaceHistory - workspaceAgent []database.WorkspaceAgent + parameterValue []database.ParameterValue + project []database.Project + projectHistory []database.ProjectHistory + projectParameter []database.ProjectParameter + provisionerDaemons []database.ProvisionerDaemon + provisionerJobs []database.ProvisionerJob + workspace []database.Workspace + workspaceResource []database.WorkspaceResource + workspaceHistory []database.WorkspaceHistory + workspaceAgent []database.WorkspaceAgent } // InTx doesn't rollback data properly for in-memory yet. @@ -51,6 +57,31 @@ func (q *fakeQuerier) InTx(fn func(database.Store) error) error { return fn(q) } +func (q *fakeQuerier) AcquireProvisionerJob(_ context.Context, arg database.AcquireProvisionerJobParams) (database.ProvisionerJob, error) { + for index, provisionerJob := range q.provisionerJobs { + if provisionerJob.StartedAt.Valid { + continue + } + found := false + for _, provisionerType := range arg.Types { + if provisionerJob.Provisioner != provisionerType { + continue + } + found = true + break + } + if !found { + continue + } + provisionerJob.StartedAt = arg.StartedAt + provisionerJob.UpdatedAt = arg.StartedAt.Time + provisionerJob.WorkerID = arg.WorkerID + q.provisionerJobs[index] = provisionerJob + return provisionerJob, nil + } + return database.ProvisionerJob{}, sql.ErrNoRows +} + func (q *fakeQuerier) GetAPIKeyByID(_ context.Context, id string) (database.APIKey, error) { for _, apiKey := range q.apiKeys { if apiKey.ID == id { @@ -97,6 +128,15 @@ func (q *fakeQuerier) GetWorkspaceAgentsByResourceIDs(_ context.Context, ids []u return agents, nil } +func (q *fakeQuerier) GetWorkspaceByID(_ context.Context, id uuid.UUID) (database.Workspace, error) { + for _, workspace := range q.workspace { + if workspace.ID.String() == id.String() { + return workspace, nil + } + } + return database.Workspace{}, sql.ErrNoRows +} + func (q *fakeQuerier) GetWorkspaceByUserIDAndName(_ context.Context, arg database.GetWorkspaceByUserIDAndNameParams) (database.Workspace, error) { for _, workspace := range q.workspace { if workspace.OwnerID != arg.OwnerID { @@ -123,6 +163,15 @@ func (q *fakeQuerier) GetWorkspaceResourcesByHistoryID(_ context.Context, worksp return resources, nil } +func (q *fakeQuerier) GetWorkspaceHistoryByID(_ context.Context, id uuid.UUID) (database.WorkspaceHistory, error) { + for _, history := range q.workspaceHistory { + if history.ID.String() == id.String() { + return history, nil + } + } + return database.WorkspaceHistory{}, sql.ErrNoRows +} + func (q *fakeQuerier) GetWorkspaceHistoryByWorkspaceIDWithoutAfter(_ context.Context, workspaceID uuid.UUID) (database.WorkspaceHistory, error) { for _, workspaceHistory := range q.workspaceHistory { if workspaceHistory.WorkspaceID.String() != workspaceID.String() { @@ -179,6 +228,15 @@ func (q *fakeQuerier) GetWorkspacesByUserID(_ context.Context, ownerID string) ( return workspaces, nil } +func (q *fakeQuerier) GetOrganizationByID(_ context.Context, id string) (database.Organization, error) { + for _, organization := range q.organizations { + if organization.ID == id { + return organization, nil + } + } + return database.Organization{}, sql.ErrNoRows +} + func (q *fakeQuerier) GetOrganizationByName(_ context.Context, name string) (database.Organization, error) { for _, organization := range q.organizations { if organization.Name == name { @@ -207,6 +265,23 @@ func (q *fakeQuerier) GetOrganizationsByUserID(_ context.Context, userID string) return organizations, nil } +func (q *fakeQuerier) GetParameterValuesByScope(_ context.Context, arg database.GetParameterValuesByScopeParams) ([]database.ParameterValue, error) { + parameterValues := make([]database.ParameterValue, 0) + for _, parameterValue := range q.parameterValue { + if parameterValue.Scope != arg.Scope { + continue + } + if parameterValue.ScopeID != arg.ScopeID { + continue + } + parameterValues = append(parameterValues, parameterValue) + } + if len(parameterValues) == 0 { + return nil, sql.ErrNoRows + } + return parameterValues, nil +} + func (q *fakeQuerier) GetProjectByID(_ context.Context, id uuid.UUID) (database.Project, error) { for _, project := range q.project { if project.ID.String() == id.String() { @@ -253,6 +328,20 @@ func (q *fakeQuerier) GetProjectHistoryByID(_ context.Context, projectHistoryID return database.ProjectHistory{}, sql.ErrNoRows } +func (q *fakeQuerier) GetProjectParametersByHistoryID(_ context.Context, projectHistoryID uuid.UUID) ([]database.ProjectParameter, error) { + parameters := make([]database.ProjectParameter, 0) + for _, projectParameter := range q.projectParameter { + if projectParameter.ProjectHistoryID.String() != projectHistoryID.String() { + continue + } + parameters = append(parameters, projectParameter) + } + if len(parameters) == 0 { + return nil, sql.ErrNoRows + } + return parameters, nil +} + func (q *fakeQuerier) GetProjectsByOrganizationIDs(_ context.Context, ids []string) ([]database.Project, error) { projects := make([]database.Project, 0) for _, project := range q.project { @@ -282,6 +371,26 @@ func (q *fakeQuerier) GetOrganizationMemberByUserID(_ context.Context, arg datab return database.OrganizationMember{}, sql.ErrNoRows } +func (q *fakeQuerier) GetProvisionerDaemonByID(_ context.Context, id uuid.UUID) (database.ProvisionerDaemon, error) { + for _, provisionerDaemon := range q.provisionerDaemons { + if provisionerDaemon.ID.String() != id.String() { + continue + } + return provisionerDaemon, nil + } + return database.ProvisionerDaemon{}, sql.ErrNoRows +} + +func (q *fakeQuerier) GetProvisionerJobByID(_ context.Context, id uuid.UUID) (database.ProvisionerJob, error) { + for _, provisionerJob := range q.provisionerJobs { + if provisionerJob.ID.String() != id.String() { + continue + } + return provisionerJob, nil + } + return database.ProvisionerJob{}, sql.ErrNoRows +} + func (q *fakeQuerier) InsertAPIKey(_ context.Context, arg database.InsertAPIKeyParams) (database.APIKey, error) { //nolint:gosimple key := database.APIKey{ @@ -329,6 +438,24 @@ func (q *fakeQuerier) InsertOrganizationMember(_ context.Context, arg database.I return organizationMember, nil } +func (q *fakeQuerier) InsertParameterValue(_ context.Context, arg database.InsertParameterValueParams) (database.ParameterValue, error) { + //nolint:gosimple + parameterValue := database.ParameterValue{ + ID: arg.ID, + Name: arg.Name, + CreatedAt: arg.CreatedAt, + UpdatedAt: arg.UpdatedAt, + Scope: arg.Scope, + ScopeID: arg.ScopeID, + SourceScheme: arg.SourceScheme, + SourceValue: arg.SourceValue, + DestinationScheme: arg.DestinationScheme, + DestinationValue: arg.DestinationValue, + } + q.parameterValue = append(q.parameterValue, parameterValue) + return parameterValue, nil +} + func (q *fakeQuerier) InsertProject(_ context.Context, arg database.InsertProjectParams) (database.Project, error) { project := database.Project{ ID: arg.ID, @@ -367,9 +494,11 @@ func (q *fakeQuerier) InsertProjectParameter(_ context.Context, arg database.Ins ProjectHistoryID: arg.ProjectHistoryID, Name: arg.Name, Description: arg.Description, - DefaultSource: arg.DefaultSource, + DefaultSourceScheme: arg.DefaultSourceScheme, + DefaultSourceValue: arg.DefaultSourceValue, AllowOverrideSource: arg.AllowOverrideSource, - DefaultDestination: arg.DefaultDestination, + DefaultDestinationScheme: arg.DefaultDestinationScheme, + DefaultDestinationValue: arg.DefaultDestinationValue, AllowOverrideDestination: arg.AllowOverrideDestination, DefaultRefresh: arg.DefaultRefresh, RedisplayValue: arg.RedisplayValue, @@ -382,6 +511,32 @@ func (q *fakeQuerier) InsertProjectParameter(_ context.Context, arg database.Ins return param, nil } +func (q *fakeQuerier) InsertProvisionerDaemon(_ context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) { + daemon := database.ProvisionerDaemon{ + ID: arg.ID, + CreatedAt: arg.CreatedAt, + Name: arg.Name, + Provisioners: arg.Provisioners, + } + q.provisionerDaemons = append(q.provisionerDaemons, daemon) + return daemon, nil +} + +func (q *fakeQuerier) InsertProvisionerJob(_ context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) { + job := database.ProvisionerJob{ + ID: arg.ID, + CreatedAt: arg.CreatedAt, + UpdatedAt: arg.UpdatedAt, + InitiatorID: arg.InitiatorID, + Provisioner: arg.Provisioner, + ProjectID: arg.ProjectID, + Type: arg.Type, + Input: arg.Input, + } + q.provisionerJobs = append(q.provisionerJobs, job) + return job, nil +} + func (q *fakeQuerier) InsertUser(_ context.Context, arg database.InsertUserParams) (database.User, error) { user := database.User{ ID: arg.ID, @@ -470,6 +625,34 @@ func (q *fakeQuerier) UpdateAPIKeyByID(_ context.Context, arg database.UpdateAPI return sql.ErrNoRows } +func (q *fakeQuerier) UpdateProvisionerDaemonByID(_ context.Context, arg database.UpdateProvisionerDaemonByIDParams) error { + for index, daemon := range q.provisionerDaemons { + if arg.ID.String() != daemon.ID.String() { + continue + } + daemon.UpdatedAt = arg.UpdatedAt + daemon.Provisioners = arg.Provisioners + q.provisionerDaemons[index] = daemon + return nil + } + return sql.ErrNoRows +} + +func (q *fakeQuerier) UpdateProvisionerJobByID(_ context.Context, arg database.UpdateProvisionerJobByIDParams) error { + for index, job := range q.provisionerJobs { + if arg.ID.String() != job.ID.String() { + continue + } + job.CompletedAt = arg.CompletedAt + job.CancelledAt = arg.CancelledAt + job.UpdatedAt = arg.UpdatedAt + job.Error = arg.Error + q.provisionerJobs[index] = job + return nil + } + return sql.ErrNoRows +} + func (q *fakeQuerier) UpdateWorkspaceHistoryByID(_ context.Context, arg database.UpdateWorkspaceHistoryByIDParams) error { for index, workspaceHistory := range q.workspaceHistory { if workspaceHistory.ID.String() != arg.ID.String() { diff --git a/database/dump.sql b/database/dump.sql index 9ba40007c5285..af4874e96db94 100644 --- a/database/dump.sql +++ b/database/dump.sql @@ -15,6 +15,22 @@ CREATE TYPE login_type AS ENUM ( 'oidc' ); +CREATE TYPE parameter_destination_scheme AS ENUM ( + 'environment_variable', + 'provisioner_variable' +); + +CREATE TYPE parameter_scope AS ENUM ( + 'organization', + 'project', + 'user', + 'workspace' +); + +CREATE TYPE parameter_source_scheme AS ENUM ( + 'data' +); + CREATE TYPE parameter_type_system AS ENUM ( 'hcl' ); @@ -23,6 +39,11 @@ CREATE TYPE project_storage_method AS ENUM ( 'inline-archive' ); +CREATE TYPE provisioner_job_type AS ENUM ( + 'project_import', + 'workspace_provision' +); + CREATE TYPE provisioner_type AS ENUM ( 'terraform', 'cdr-basic' @@ -86,6 +107,19 @@ CREATE TABLE organizations ( workspace_auto_off boolean DEFAULT false NOT NULL ); +CREATE TABLE parameter_value ( + id uuid NOT NULL, + name character varying(64) NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + scope parameter_scope NOT NULL, + scope_id text NOT NULL, + source_scheme parameter_source_scheme NOT NULL, + source_value text NOT NULL, + destination_scheme parameter_destination_scheme NOT NULL, + destination_value text NOT NULL +); + CREATE TABLE project ( id uuid NOT NULL, created_at timestamp with time zone NOT NULL, @@ -114,9 +148,11 @@ CREATE TABLE project_parameter ( project_history_id uuid NOT NULL, name character varying(64) NOT NULL, description character varying(8192) DEFAULT ''::character varying NOT NULL, - default_source text, + default_source_scheme parameter_source_scheme, + default_source_value text, allow_override_source boolean NOT NULL, - default_destination text, + default_destination_scheme parameter_destination_scheme, + default_destination_value text, allow_override_destination boolean NOT NULL, default_refresh text NOT NULL, redisplay_value boolean NOT NULL, @@ -126,6 +162,30 @@ CREATE TABLE project_parameter ( validation_value_type character varying(64) NOT NULL ); +CREATE TABLE provisioner_daemon ( + id uuid NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone, + name character varying(64) NOT NULL, + provisioners provisioner_type[] NOT NULL +); + +CREATE TABLE provisioner_job ( + id uuid NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + started_at timestamp with time zone, + cancelled_at timestamp with time zone, + completed_at timestamp with time zone, + error text, + initiator_id text NOT NULL, + provisioner provisioner_type NOT NULL, + type provisioner_job_type NOT NULL, + project_id uuid NOT NULL, + input jsonb NOT NULL, + worker_id uuid +); + CREATE TABLE users ( id text NOT NULL, email text NOT NULL, @@ -200,6 +260,12 @@ CREATE TABLE workspace_resource ( workspace_agent_id uuid ); +ALTER TABLE ONLY parameter_value + ADD CONSTRAINT parameter_value_id_key UNIQUE (id); + +ALTER TABLE ONLY parameter_value + ADD CONSTRAINT parameter_value_name_scope_scope_id_key UNIQUE (name, scope, scope_id); + ALTER TABLE ONLY project_history ADD CONSTRAINT project_history_id_key UNIQUE (id); @@ -218,6 +284,15 @@ ALTER TABLE ONLY project_parameter ALTER TABLE ONLY project_parameter ADD CONSTRAINT project_parameter_project_history_id_name_key UNIQUE (project_history_id, name); +ALTER TABLE ONLY provisioner_daemon + ADD CONSTRAINT provisioner_daemon_id_key UNIQUE (id); + +ALTER TABLE ONLY provisioner_daemon + ADD CONSTRAINT provisioner_daemon_name_key UNIQUE (name); + +ALTER TABLE ONLY provisioner_job + ADD CONSTRAINT provisioner_job_id_key UNIQUE (id); + ALTER TABLE ONLY workspace_agent ADD CONSTRAINT workspace_agent_id_key UNIQUE (id); @@ -244,6 +319,9 @@ ALTER TABLE ONLY project_history ALTER TABLE ONLY project_parameter ADD CONSTRAINT project_parameter_project_history_id_fkey FOREIGN KEY (project_history_id) REFERENCES project_history(id) ON DELETE CASCADE; +ALTER TABLE ONLY provisioner_job + ADD CONSTRAINT provisioner_job_project_id_fkey FOREIGN KEY (project_id) REFERENCES project(id) ON DELETE CASCADE; + ALTER TABLE ONLY workspace_agent ADD CONSTRAINT workspace_agent_workspace_resource_id_fkey FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resource(id) ON DELETE CASCADE; diff --git a/database/migrations/000002_projects.up.sql b/database/migrations/000002_projects.up.sql index 3483dcd9ff858..251b368ef3701 100644 --- a/database/migrations/000002_projects.up.sql +++ b/database/migrations/000002_projects.up.sql @@ -48,6 +48,12 @@ CREATE TABLE project_history ( -- Types of parameters the automator supports. CREATE TYPE parameter_type_system AS ENUM ('hcl'); +-- Supported schemes for a parameter source. +CREATE TYPE parameter_source_scheme AS ENUM('data'); + +-- Supported schemes for a parameter destination. +CREATE TYPE parameter_destination_scheme AS ENUM('environment_variable', 'provisioner_variable'); + -- Stores project version parameters parsed on import. -- No secrets are stored here. -- @@ -65,11 +71,13 @@ CREATE TABLE project_parameter ( -- 8KB limit description varchar(8192) NOT NULL DEFAULT '', -- eg. data://inlinevalue - default_source text, + default_source_scheme parameter_source_scheme, + default_source_value text, -- Allows the user to override the source. allow_override_source boolean NOT null, -- eg. env://SOME_VARIABLE, tfvars://example - default_destination text, + default_destination_scheme parameter_destination_scheme, + default_destination_value text, -- Allows the user to override the destination. allow_override_destination boolean NOT null, default_refresh text NOT NULL, diff --git a/database/migrations/000004_jobs.down.sql b/database/migrations/000004_jobs.down.sql new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/database/migrations/000004_jobs.up.sql b/database/migrations/000004_jobs.up.sql new file mode 100644 index 0000000000000..7f767e7dfd983 --- /dev/null +++ b/database/migrations/000004_jobs.up.sql @@ -0,0 +1,53 @@ +CREATE TABLE IF NOT EXISTS provisioner_daemon ( + id uuid NOT NULL UNIQUE, + created_at timestamptz NOT NULL, + updated_at timestamptz, + -- Name is generated for ease of differentiation. + -- eg. WowBananas16 + name varchar(64) NOT NULL UNIQUE, + provisioners provisioner_type [ ] NOT NULL +); + +CREATE TYPE provisioner_job_type AS ENUM ( + 'project_import', + 'workspace_provision' +); + +CREATE TABLE IF NOT EXISTS provisioner_job ( + id uuid NOT NULL UNIQUE, + created_at timestamptz NOT NULL, + updated_at timestamptz NOT NULL, + started_at timestamptz, + cancelled_at timestamptz, + completed_at timestamptz, + error text, + initiator_id text NOT NULL, + provisioner provisioner_type NOT NULL, + type provisioner_job_type NOT NULL, + project_id uuid NOT NULL REFERENCES project(id) ON DELETE CASCADE, + input jsonb NOT NULL, + worker_id uuid +); + +CREATE TYPE parameter_scope AS ENUM ( + 'organization', + 'project', + 'user', + 'workspace' +); + +-- Parameters are provided to jobs for provisioning and to workspaces. +CREATE TABLE parameter_value ( + id uuid NOT NULL UNIQUE, + name varchar(64) NOT NULL, + created_at timestamptz NOT NULL, + updated_at timestamptz NOT NULL, + scope parameter_scope NOT NULL, + scope_id text NOT NULL, + source_scheme parameter_source_scheme NOT NULL, + source_value text NOT NULL, + destination_scheme parameter_destination_scheme NOT NULL, + destination_value text NOT NULL, + -- Prevents duplicates for parameters in the same scope. + UNIQUE(name, scope, scope_id) +); \ No newline at end of file diff --git a/database/migrations/create_migration.sh b/database/migrations/create_migration.sh index 68c17eb3a62a1..d063ea1eec562 100755 --- a/database/migrations/create_migration.sh +++ b/database/migrations/create_migration.sh @@ -8,4 +8,4 @@ fi migrate create -ext sql -dir . -seq $1 -echo "After making adjustments, run \"make database/generate\" to generate models." +echo "Run \"make gen\" to generate models." diff --git a/database/models.go b/database/models.go index 58f0e05f28b9f..3b9fdfcd83668 100644 --- a/database/models.go +++ b/database/models.go @@ -54,6 +54,64 @@ func (e *LoginType) Scan(src interface{}) error { return nil } +type ParameterDestinationScheme string + +const ( + ParameterDestinationSchemeEnvironmentVariable ParameterDestinationScheme = "environment_variable" + ParameterDestinationSchemeProvisionerVariable ParameterDestinationScheme = "provisioner_variable" +) + +func (e *ParameterDestinationScheme) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = ParameterDestinationScheme(s) + case string: + *e = ParameterDestinationScheme(s) + default: + return fmt.Errorf("unsupported scan type for ParameterDestinationScheme: %T", src) + } + return nil +} + +type ParameterScope string + +const ( + ParameterScopeOrganization ParameterScope = "organization" + ParameterScopeProject ParameterScope = "project" + ParameterScopeUser ParameterScope = "user" + ParameterScopeWorkspace ParameterScope = "workspace" +) + +func (e *ParameterScope) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = ParameterScope(s) + case string: + *e = ParameterScope(s) + default: + return fmt.Errorf("unsupported scan type for ParameterScope: %T", src) + } + return nil +} + +type ParameterSourceScheme string + +const ( + ParameterSourceSchemeData ParameterSourceScheme = "data" +) + +func (e *ParameterSourceScheme) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = ParameterSourceScheme(s) + case string: + *e = ParameterSourceScheme(s) + default: + return fmt.Errorf("unsupported scan type for ParameterSourceScheme: %T", src) + } + return nil +} + type ParameterTypeSystem string const ( @@ -90,6 +148,25 @@ func (e *ProjectStorageMethod) Scan(src interface{}) error { return nil } +type ProvisionerJobType string + +const ( + ProvisionerJobTypeProjectImport ProvisionerJobType = "project_import" + ProvisionerJobTypeWorkspaceProvision ProvisionerJobType = "workspace_provision" +) + +func (e *ProvisionerJobType) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = ProvisionerJobType(s) + case string: + *e = ProvisionerJobType(s) + default: + return fmt.Errorf("unsupported scan type for ProvisionerJobType: %T", src) + } + return nil +} + type ProvisionerType string const ( @@ -195,6 +272,19 @@ type OrganizationMember struct { Roles []string `db:"roles" json:"roles"` } +type ParameterValue struct { + ID uuid.UUID `db:"id" json:"id"` + Name string `db:"name" json:"name"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + Scope ParameterScope `db:"scope" json:"scope"` + ScopeID string `db:"scope_id" json:"scope_id"` + SourceScheme ParameterSourceScheme `db:"source_scheme" json:"source_scheme"` + SourceValue string `db:"source_value" json:"source_value"` + DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"` + DestinationValue string `db:"destination_value" json:"destination_value"` +} + type Project struct { ID uuid.UUID `db:"id" json:"id"` CreatedAt time.Time `db:"created_at" json:"created_at"` @@ -218,21 +308,47 @@ type ProjectHistory struct { } type ProjectParameter struct { - ID uuid.UUID `db:"id" json:"id"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - ProjectHistoryID uuid.UUID `db:"project_history_id" json:"project_history_id"` - Name string `db:"name" json:"name"` - Description string `db:"description" json:"description"` - DefaultSource sql.NullString `db:"default_source" json:"default_source"` - AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"` - DefaultDestination sql.NullString `db:"default_destination" json:"default_destination"` - AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"` - DefaultRefresh string `db:"default_refresh" json:"default_refresh"` - RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"` - ValidationError string `db:"validation_error" json:"validation_error"` - ValidationCondition string `db:"validation_condition" json:"validation_condition"` - ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"` - ValidationValueType string `db:"validation_value_type" json:"validation_value_type"` + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + ProjectHistoryID uuid.UUID `db:"project_history_id" json:"project_history_id"` + Name string `db:"name" json:"name"` + Description string `db:"description" json:"description"` + DefaultSourceScheme ParameterSourceScheme `db:"default_source_scheme" json:"default_source_scheme"` + DefaultSourceValue sql.NullString `db:"default_source_value" json:"default_source_value"` + AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"` + DefaultDestinationScheme ParameterDestinationScheme `db:"default_destination_scheme" json:"default_destination_scheme"` + DefaultDestinationValue sql.NullString `db:"default_destination_value" json:"default_destination_value"` + AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"` + DefaultRefresh string `db:"default_refresh" json:"default_refresh"` + RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"` + ValidationError string `db:"validation_error" json:"validation_error"` + ValidationCondition string `db:"validation_condition" json:"validation_condition"` + ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"` + ValidationValueType string `db:"validation_value_type" json:"validation_value_type"` +} + +type ProvisionerDaemon struct { + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"` + Name string `db:"name" json:"name"` + Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"` +} + +type ProvisionerJob struct { + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + StartedAt sql.NullTime `db:"started_at" json:"started_at"` + CancelledAt sql.NullTime `db:"cancelled_at" json:"cancelled_at"` + CompletedAt sql.NullTime `db:"completed_at" json:"completed_at"` + Error sql.NullString `db:"error" json:"error"` + InitiatorID string `db:"initiator_id" json:"initiator_id"` + Provisioner ProvisionerType `db:"provisioner" json:"provisioner"` + Type ProvisionerJobType `db:"type" json:"type"` + ProjectID uuid.UUID `db:"project_id" json:"project_id"` + Input json.RawMessage `db:"input" json:"input"` + WorkerID uuid.NullUUID `db:"worker_id" json:"worker_id"` } type User struct { diff --git a/database/querier.go b/database/querier.go index 64b26cbdaf4da..1c908c186c544 100644 --- a/database/querier.go +++ b/database/querier.go @@ -9,20 +9,28 @@ import ( ) type querier interface { + AcquireProvisionerJob(ctx context.Context, arg AcquireProvisionerJobParams) (ProvisionerJob, error) GetAPIKeyByID(ctx context.Context, id string) (APIKey, error) + GetOrganizationByID(ctx context.Context, id string) (Organization, error) GetOrganizationByName(ctx context.Context, name string) (Organization, error) GetOrganizationMemberByUserID(ctx context.Context, arg GetOrganizationMemberByUserIDParams) (OrganizationMember, error) GetOrganizationsByUserID(ctx context.Context, userID string) ([]Organization, error) + GetParameterValuesByScope(ctx context.Context, arg GetParameterValuesByScopeParams) ([]ParameterValue, error) GetProjectByID(ctx context.Context, id uuid.UUID) (Project, error) GetProjectByOrganizationAndName(ctx context.Context, arg GetProjectByOrganizationAndNameParams) (Project, error) GetProjectHistoryByID(ctx context.Context, id uuid.UUID) (ProjectHistory, error) GetProjectHistoryByProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectHistory, error) + GetProjectParametersByHistoryID(ctx context.Context, projectHistoryID uuid.UUID) ([]ProjectParameter, error) GetProjectsByOrganizationIDs(ctx context.Context, ids []string) ([]Project, error) + GetProvisionerDaemonByID(ctx context.Context, id uuid.UUID) (ProvisionerDaemon, error) + GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error) GetUserByEmailOrUsername(ctx context.Context, arg GetUserByEmailOrUsernameParams) (User, error) GetUserByID(ctx context.Context, id string) (User, error) GetUserCount(ctx context.Context) (int64, error) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgent, error) + GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Workspace, error) GetWorkspaceByUserIDAndName(ctx context.Context, arg GetWorkspaceByUserIDAndNameParams) (Workspace, error) + GetWorkspaceHistoryByID(ctx context.Context, id uuid.UUID) (WorkspaceHistory, error) GetWorkspaceHistoryByWorkspaceID(ctx context.Context, workspaceID uuid.UUID) ([]WorkspaceHistory, error) GetWorkspaceHistoryByWorkspaceIDWithoutAfter(ctx context.Context, workspaceID uuid.UUID) (WorkspaceHistory, error) GetWorkspaceResourcesByHistoryID(ctx context.Context, workspaceHistoryID uuid.UUID) ([]WorkspaceResource, error) @@ -31,15 +39,20 @@ type querier interface { InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (APIKey, error) InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error) InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error) + InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error) InsertProject(ctx context.Context, arg InsertProjectParams) (Project, error) InsertProjectHistory(ctx context.Context, arg InsertProjectHistoryParams) (ProjectHistory, error) InsertProjectParameter(ctx context.Context, arg InsertProjectParameterParams) (ProjectParameter, error) + InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error) + InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error) InsertUser(ctx context.Context, arg InsertUserParams) (User, error) InsertWorkspace(ctx context.Context, arg InsertWorkspaceParams) (Workspace, error) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error) InsertWorkspaceHistory(ctx context.Context, arg InsertWorkspaceHistoryParams) (WorkspaceHistory, error) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error + UpdateProvisionerDaemonByID(ctx context.Context, arg UpdateProvisionerDaemonByIDParams) error + UpdateProvisionerJobByID(ctx context.Context, arg UpdateProvisionerJobByIDParams) error UpdateWorkspaceHistoryByID(ctx context.Context, arg UpdateWorkspaceHistoryByIDParams) error } diff --git a/database/query.sql b/database/query.sql index 6ed73a070edcd..b361bbe3094d0 100644 --- a/database/query.sql +++ b/database/query.sql @@ -4,6 +4,32 @@ -- Run "make gen" to generate models and query functions. ; +-- name: AcquireProvisionerJob :one +UPDATE + provisioner_job +SET + started_at = @started_at, + updated_at = @started_at, + worker_id = @worker_id +WHERE + id = ( + SELECT + id + FROM + provisioner_job AS nested + WHERE + nested.started_at IS NULL + AND nested.cancelled_at IS NULL + AND nested.completed_at IS NULL + AND nested.provisioner = ANY(@types :: provisioner_type [ ]) + ORDER BY + nested.created FOR + UPDATE + SKIP LOCKED + LIMIT + 1 + ) RETURNING *; + -- name: GetAPIKeyByID :one SELECT * @@ -41,6 +67,14 @@ SELECT FROM users; +-- name: GetOrganizationByID :one +SELECT + * +FROM + organizations +WHERE + id = $1; + -- name: GetOrganizationByName :one SELECT * @@ -77,6 +111,15 @@ WHERE LIMIT 1; +-- name: GetParameterValuesByScope :many +SELECT + * +FROM + parameter_value +WHERE + scope = $1 + AND scope_id = $2; + -- name: GetProjectByID :one SELECT * @@ -106,6 +149,14 @@ FROM WHERE organization_id = ANY(@ids :: text [ ]); +-- name: GetProjectParametersByHistoryID :many +SELECT + * +FROM + project_parameter +WHERE + project_history_id = $1; + -- name: GetProjectHistoryByProjectID :many SELECT * @@ -122,6 +173,32 @@ FROM WHERE id = $1; +-- name: GetProvisionerDaemonByID :one +SELECT + * +FROM + provisioner_daemon +WHERE + id = $1; + +-- name: GetProvisionerJobByID :one +SELECT + * +FROM + provisioner_job +WHERE + id = $1; + +-- name: GetWorkspaceByID :one +SELECT + * +FROM + workspace +WHERE + id = $1 +LIMIT + 1; + -- name: GetWorkspacesByUserID :many SELECT * @@ -148,6 +225,16 @@ WHERE owner_id = $1 AND project_id = $2; +-- name: GetWorkspaceHistoryByID :one +SELECT + * +FROM + workspace_history +WHERE + id = $1 +LIMIT + 1; + -- name: GetWorkspaceHistoryByWorkspaceID :many SELECT * @@ -239,6 +326,23 @@ INSERT INTO VALUES ($1, $2, $3, $4, $5) RETURNING *; +-- name: InsertParameterValue :one +INSERT INTO + parameter_value ( + id, + name, + created_at, + updated_at, + scope, + scope_id, + source_scheme, + source_value, + destination_scheme, + destination_value + ) +VALUES + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *; + -- name: InsertProject :one INSERT INTO project ( @@ -276,9 +380,11 @@ INSERT INTO project_history_id, name, description, - default_source, + default_source_scheme, + default_source_value, allow_override_source, - default_destination, + default_destination_scheme, + default_destination_value, allow_override_destination, default_refresh, redisplay_value, @@ -303,9 +409,32 @@ VALUES $12, $13, $14, - $15 + $15, + $16, + $17 ) RETURNING *; +-- name: InsertProvisionerDaemon :one +INSERT INTO + provisioner_daemon (id, created_at, name, provisioners) +VALUES + ($1, $2, $3, $4) RETURNING *; + +-- name: InsertProvisionerJob :one +INSERT INTO + provisioner_job ( + id, + created_at, + updated_at, + initiator_id, + provisioner, + type, + project_id, + input + ) +VALUES + ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *; + -- name: InsertUser :one INSERT INTO users ( @@ -389,6 +518,26 @@ SET WHERE id = $1; +-- name: UpdateProvisionerDaemonByID :exec +UPDATE + provisioner_daemon +SET + updated_at = $2, + provisioners = $3 +WHERE + id = $1; + +-- name: UpdateProvisionerJobByID :exec +UPDATE + provisioner_job +SET + updated_at = $2, + cancelled_at = $3, + completed_at = $4, + error = $5 +WHERE + id = $1; + -- name: UpdateWorkspaceHistoryByID :exec UPDATE workspace_history diff --git a/database/query.sql.go b/database/query.sql.go index abb5aea348521..cb49f86eb67f0 100644 --- a/database/query.sql.go +++ b/database/query.sql.go @@ -13,6 +13,60 @@ import ( "github.com/lib/pq" ) +const acquireProvisionerJob = `-- name: AcquireProvisionerJob :one +UPDATE + provisioner_job +SET + started_at = $1, + updated_at = $1, + worker_id = $2 +WHERE + id = ( + SELECT + id + FROM + provisioner_job AS nested + WHERE + nested.started_at IS NULL + AND nested.cancelled_at IS NULL + AND nested.completed_at IS NULL + AND nested.provisioner = ANY($3 :: provisioner_type [ ]) + ORDER BY + nested.created FOR + UPDATE + SKIP LOCKED + LIMIT + 1 + ) RETURNING id, created_at, updated_at, started_at, cancelled_at, completed_at, error, initiator_id, provisioner, type, project_id, input, worker_id +` + +type AcquireProvisionerJobParams struct { + StartedAt sql.NullTime `db:"started_at" json:"started_at"` + WorkerID uuid.NullUUID `db:"worker_id" json:"worker_id"` + Types []ProvisionerType `db:"types" json:"types"` +} + +func (q *sqlQuerier) AcquireProvisionerJob(ctx context.Context, arg AcquireProvisionerJobParams) (ProvisionerJob, error) { + row := q.db.QueryRowContext(ctx, acquireProvisionerJob, arg.StartedAt, arg.WorkerID, pq.Array(arg.Types)) + var i ProvisionerJob + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.StartedAt, + &i.CancelledAt, + &i.CompletedAt, + &i.Error, + &i.InitiatorID, + &i.Provisioner, + &i.Type, + &i.ProjectID, + &i.Input, + &i.WorkerID, + ) + return i, err +} + const getAPIKeyByID = `-- name: GetAPIKeyByID :one SELECT id, hashed_secret, user_id, application, name, last_used, expires_at, created_at, updated_at, login_type, oidc_access_token, oidc_refresh_token, oidc_id_token, oidc_expiry, devurl_token @@ -47,6 +101,33 @@ func (q *sqlQuerier) GetAPIKeyByID(ctx context.Context, id string) (APIKey, erro return i, err } +const getOrganizationByID = `-- name: GetOrganizationByID :one +SELECT + id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off +FROM + organizations +WHERE + id = $1 +` + +func (q *sqlQuerier) GetOrganizationByID(ctx context.Context, id string) (Organization, error) { + row := q.db.QueryRowContext(ctx, getOrganizationByID, id) + var i Organization + err := row.Scan( + &i.ID, + &i.Name, + &i.Description, + &i.CreatedAt, + &i.UpdatedAt, + &i.Default, + &i.AutoOffThreshold, + &i.CpuProvisioningRate, + &i.MemoryProvisioningRate, + &i.WorkspaceAutoOff, + ) + return i, err +} + const getOrganizationByName = `-- name: GetOrganizationByName :one SELECT id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off @@ -156,6 +237,55 @@ func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID string return items, nil } +const getParameterValuesByScope = `-- name: GetParameterValuesByScope :many +SELECT + id, name, created_at, updated_at, scope, scope_id, source_scheme, source_value, destination_scheme, destination_value +FROM + parameter_value +WHERE + scope = $1 + AND scope_id = $2 +` + +type GetParameterValuesByScopeParams struct { + Scope ParameterScope `db:"scope" json:"scope"` + ScopeID string `db:"scope_id" json:"scope_id"` +} + +func (q *sqlQuerier) GetParameterValuesByScope(ctx context.Context, arg GetParameterValuesByScopeParams) ([]ParameterValue, error) { + rows, err := q.db.QueryContext(ctx, getParameterValuesByScope, arg.Scope, arg.ScopeID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ParameterValue + for rows.Next() { + var i ParameterValue + if err := rows.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UpdatedAt, + &i.Scope, + &i.ScopeID, + &i.SourceScheme, + &i.SourceValue, + &i.DestinationScheme, + &i.DestinationValue, + ); 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 getProjectByID = `-- name: GetProjectByID :one SELECT id, created_at, updated_at, organization_id, name, provisioner, active_version_id @@ -282,6 +412,56 @@ func (q *sqlQuerier) GetProjectHistoryByProjectID(ctx context.Context, projectID return items, nil } +const getProjectParametersByHistoryID = `-- name: GetProjectParametersByHistoryID :many +SELECT + id, created_at, project_history_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, default_destination_value, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type +FROM + project_parameter +WHERE + project_history_id = $1 +` + +func (q *sqlQuerier) GetProjectParametersByHistoryID(ctx context.Context, projectHistoryID uuid.UUID) ([]ProjectParameter, error) { + rows, err := q.db.QueryContext(ctx, getProjectParametersByHistoryID, projectHistoryID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []ProjectParameter + for rows.Next() { + var i ProjectParameter + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.ProjectHistoryID, + &i.Name, + &i.Description, + &i.DefaultSourceScheme, + &i.DefaultSourceValue, + &i.AllowOverrideSource, + &i.DefaultDestinationScheme, + &i.DefaultDestinationValue, + &i.AllowOverrideDestination, + &i.DefaultRefresh, + &i.RedisplayValue, + &i.ValidationError, + &i.ValidationCondition, + &i.ValidationTypeSystem, + &i.ValidationValueType, + ); 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 getProjectsByOrganizationIDs = `-- name: GetProjectsByOrganizationIDs :many SELECT id, created_at, updated_at, organization_id, name, provisioner, active_version_id @@ -322,6 +502,58 @@ func (q *sqlQuerier) GetProjectsByOrganizationIDs(ctx context.Context, ids []str return items, nil } +const getProvisionerDaemonByID = `-- name: GetProvisionerDaemonByID :one +SELECT + id, created_at, updated_at, name, provisioners +FROM + provisioner_daemon +WHERE + id = $1 +` + +func (q *sqlQuerier) GetProvisionerDaemonByID(ctx context.Context, id uuid.UUID) (ProvisionerDaemon, error) { + row := q.db.QueryRowContext(ctx, getProvisionerDaemonByID, id) + var i ProvisionerDaemon + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.Name, + pq.Array(&i.Provisioners), + ) + return i, err +} + +const getProvisionerJobByID = `-- name: GetProvisionerJobByID :one +SELECT + id, created_at, updated_at, started_at, cancelled_at, completed_at, error, initiator_id, provisioner, type, project_id, input, worker_id +FROM + provisioner_job +WHERE + id = $1 +` + +func (q *sqlQuerier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error) { + row := q.db.QueryRowContext(ctx, getProvisionerJobByID, id) + var i ProvisionerJob + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.StartedAt, + &i.CancelledAt, + &i.CompletedAt, + &i.Error, + &i.InitiatorID, + &i.Provisioner, + &i.Type, + &i.ProjectID, + &i.Input, + &i.WorkerID, + ) + return i, err +} + const getUserByEmailOrUsername = `-- name: GetUserByEmailOrUsername :one SELECT id, email, name, revoked, login_type, hashed_password, created_at, updated_at, temporary_password, avatar_hash, ssh_key_regenerated_at, username, dotfiles_git_uri, roles, status, relatime, gpg_key_regenerated_at, _decomissioned, shell @@ -457,6 +689,31 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids [] return items, nil } +const getWorkspaceByID = `-- name: GetWorkspaceByID :one +SELECT + id, created_at, updated_at, owner_id, project_id, name +FROM + workspace +WHERE + id = $1 +LIMIT + 1 +` + +func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Workspace, error) { + row := q.db.QueryRowContext(ctx, getWorkspaceByID, id) + var i Workspace + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.OwnerID, + &i.ProjectID, + &i.Name, + ) + return i, err +} + const getWorkspaceByUserIDAndName = `-- name: GetWorkspaceByUserIDAndName :one SELECT id, created_at, updated_at, owner_id, project_id, name @@ -486,6 +743,37 @@ func (q *sqlQuerier) GetWorkspaceByUserIDAndName(ctx context.Context, arg GetWor return i, err } +const getWorkspaceHistoryByID = `-- name: GetWorkspaceHistoryByID :one +SELECT + id, created_at, updated_at, completed_at, workspace_id, project_history_id, before_id, after_id, transition, initiator, provisioner_state, provision_job_id +FROM + workspace_history +WHERE + id = $1 +LIMIT + 1 +` + +func (q *sqlQuerier) GetWorkspaceHistoryByID(ctx context.Context, id uuid.UUID) (WorkspaceHistory, error) { + row := q.db.QueryRowContext(ctx, getWorkspaceHistoryByID, id) + var i WorkspaceHistory + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.CompletedAt, + &i.WorkspaceID, + &i.ProjectHistoryID, + &i.BeforeID, + &i.AfterID, + &i.Transition, + &i.Initiator, + &i.ProvisionerState, + &i.ProvisionJobID, + ) + return i, err +} + const getWorkspaceHistoryByWorkspaceID = `-- name: GetWorkspaceHistoryByWorkspaceID :many SELECT id, created_at, updated_at, completed_at, workspace_id, project_history_id, before_id, after_id, transition, initiator, provisioner_state, provision_job_id @@ -862,6 +1150,66 @@ func (q *sqlQuerier) InsertOrganizationMember(ctx context.Context, arg InsertOrg return i, err } +const insertParameterValue = `-- name: InsertParameterValue :one +INSERT INTO + parameter_value ( + id, + name, + created_at, + updated_at, + scope, + scope_id, + source_scheme, + source_value, + destination_scheme, + destination_value + ) +VALUES + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, name, created_at, updated_at, scope, scope_id, source_scheme, source_value, destination_scheme, destination_value +` + +type InsertParameterValueParams struct { + ID uuid.UUID `db:"id" json:"id"` + Name string `db:"name" json:"name"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + Scope ParameterScope `db:"scope" json:"scope"` + ScopeID string `db:"scope_id" json:"scope_id"` + SourceScheme ParameterSourceScheme `db:"source_scheme" json:"source_scheme"` + SourceValue string `db:"source_value" json:"source_value"` + DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"` + DestinationValue string `db:"destination_value" json:"destination_value"` +} + +func (q *sqlQuerier) InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error) { + row := q.db.QueryRowContext(ctx, insertParameterValue, + arg.ID, + arg.Name, + arg.CreatedAt, + arg.UpdatedAt, + arg.Scope, + arg.ScopeID, + arg.SourceScheme, + arg.SourceValue, + arg.DestinationScheme, + arg.DestinationValue, + ) + var i ParameterValue + err := row.Scan( + &i.ID, + &i.Name, + &i.CreatedAt, + &i.UpdatedAt, + &i.Scope, + &i.ScopeID, + &i.SourceScheme, + &i.SourceValue, + &i.DestinationScheme, + &i.DestinationValue, + ) + return i, err +} + const insertProject = `-- name: InsertProject :one INSERT INTO project ( @@ -971,9 +1319,11 @@ INSERT INTO project_history_id, name, description, - default_source, + default_source_scheme, + default_source_value, allow_override_source, - default_destination, + default_destination_scheme, + default_destination_value, allow_override_destination, default_refresh, redisplay_value, @@ -998,26 +1348,30 @@ VALUES $12, $13, $14, - $15 - ) RETURNING id, created_at, project_history_id, name, description, default_source, allow_override_source, default_destination, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type + $15, + $16, + $17 + ) RETURNING id, created_at, project_history_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, default_destination_value, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type ` type InsertProjectParameterParams struct { - ID uuid.UUID `db:"id" json:"id"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - ProjectHistoryID uuid.UUID `db:"project_history_id" json:"project_history_id"` - Name string `db:"name" json:"name"` - Description string `db:"description" json:"description"` - DefaultSource sql.NullString `db:"default_source" json:"default_source"` - AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"` - DefaultDestination sql.NullString `db:"default_destination" json:"default_destination"` - AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"` - DefaultRefresh string `db:"default_refresh" json:"default_refresh"` - RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"` - ValidationError string `db:"validation_error" json:"validation_error"` - ValidationCondition string `db:"validation_condition" json:"validation_condition"` - ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"` - ValidationValueType string `db:"validation_value_type" json:"validation_value_type"` + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + ProjectHistoryID uuid.UUID `db:"project_history_id" json:"project_history_id"` + Name string `db:"name" json:"name"` + Description string `db:"description" json:"description"` + DefaultSourceScheme ParameterSourceScheme `db:"default_source_scheme" json:"default_source_scheme"` + DefaultSourceValue sql.NullString `db:"default_source_value" json:"default_source_value"` + AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"` + DefaultDestinationScheme ParameterDestinationScheme `db:"default_destination_scheme" json:"default_destination_scheme"` + DefaultDestinationValue sql.NullString `db:"default_destination_value" json:"default_destination_value"` + AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"` + DefaultRefresh string `db:"default_refresh" json:"default_refresh"` + RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"` + ValidationError string `db:"validation_error" json:"validation_error"` + ValidationCondition string `db:"validation_condition" json:"validation_condition"` + ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"` + ValidationValueType string `db:"validation_value_type" json:"validation_value_type"` } func (q *sqlQuerier) InsertProjectParameter(ctx context.Context, arg InsertProjectParameterParams) (ProjectParameter, error) { @@ -1027,9 +1381,11 @@ func (q *sqlQuerier) InsertProjectParameter(ctx context.Context, arg InsertProje arg.ProjectHistoryID, arg.Name, arg.Description, - arg.DefaultSource, + arg.DefaultSourceScheme, + arg.DefaultSourceValue, arg.AllowOverrideSource, - arg.DefaultDestination, + arg.DefaultDestinationScheme, + arg.DefaultDestinationValue, arg.AllowOverrideDestination, arg.DefaultRefresh, arg.RedisplayValue, @@ -1045,9 +1401,11 @@ func (q *sqlQuerier) InsertProjectParameter(ctx context.Context, arg InsertProje &i.ProjectHistoryID, &i.Name, &i.Description, - &i.DefaultSource, + &i.DefaultSourceScheme, + &i.DefaultSourceValue, &i.AllowOverrideSource, - &i.DefaultDestination, + &i.DefaultDestinationScheme, + &i.DefaultDestinationValue, &i.AllowOverrideDestination, &i.DefaultRefresh, &i.RedisplayValue, @@ -1059,6 +1417,95 @@ func (q *sqlQuerier) InsertProjectParameter(ctx context.Context, arg InsertProje return i, err } +const insertProvisionerDaemon = `-- name: InsertProvisionerDaemon :one +INSERT INTO + provisioner_daemon (id, created_at, name, provisioners) +VALUES + ($1, $2, $3, $4) RETURNING id, created_at, updated_at, name, provisioners +` + +type InsertProvisionerDaemonParams struct { + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + Name string `db:"name" json:"name"` + Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"` +} + +func (q *sqlQuerier) InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error) { + row := q.db.QueryRowContext(ctx, insertProvisionerDaemon, + arg.ID, + arg.CreatedAt, + arg.Name, + pq.Array(arg.Provisioners), + ) + var i ProvisionerDaemon + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.Name, + pq.Array(&i.Provisioners), + ) + return i, err +} + +const insertProvisionerJob = `-- name: InsertProvisionerJob :one +INSERT INTO + provisioner_job ( + id, + created_at, + updated_at, + initiator_id, + provisioner, + type, + project_id, + input + ) +VALUES + ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, created_at, updated_at, started_at, cancelled_at, completed_at, error, initiator_id, provisioner, type, project_id, input, worker_id +` + +type InsertProvisionerJobParams struct { + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + InitiatorID string `db:"initiator_id" json:"initiator_id"` + Provisioner ProvisionerType `db:"provisioner" json:"provisioner"` + Type ProvisionerJobType `db:"type" json:"type"` + ProjectID uuid.UUID `db:"project_id" json:"project_id"` + Input json.RawMessage `db:"input" json:"input"` +} + +func (q *sqlQuerier) InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error) { + row := q.db.QueryRowContext(ctx, insertProvisionerJob, + arg.ID, + arg.CreatedAt, + arg.UpdatedAt, + arg.InitiatorID, + arg.Provisioner, + arg.Type, + arg.ProjectID, + arg.Input, + ) + var i ProvisionerJob + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.UpdatedAt, + &i.StartedAt, + &i.CancelledAt, + &i.CompletedAt, + &i.Error, + &i.InitiatorID, + &i.Provisioner, + &i.Type, + &i.ProjectID, + &i.Input, + &i.WorkerID, + ) + return i, err +} + const insertUser = `-- name: InsertUser :one INSERT INTO users ( @@ -1349,6 +1796,58 @@ func (q *sqlQuerier) UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDP return err } +const updateProvisionerDaemonByID = `-- name: UpdateProvisionerDaemonByID :exec +UPDATE + provisioner_daemon +SET + updated_at = $2, + provisioners = $3 +WHERE + id = $1 +` + +type UpdateProvisionerDaemonByIDParams struct { + ID uuid.UUID `db:"id" json:"id"` + UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"` + Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"` +} + +func (q *sqlQuerier) UpdateProvisionerDaemonByID(ctx context.Context, arg UpdateProvisionerDaemonByIDParams) error { + _, err := q.db.ExecContext(ctx, updateProvisionerDaemonByID, arg.ID, arg.UpdatedAt, pq.Array(arg.Provisioners)) + return err +} + +const updateProvisionerJobByID = `-- name: UpdateProvisionerJobByID :exec +UPDATE + provisioner_job +SET + updated_at = $2, + cancelled_at = $3, + completed_at = $4, + error = $5 +WHERE + id = $1 +` + +type UpdateProvisionerJobByIDParams struct { + ID uuid.UUID `db:"id" json:"id"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + CancelledAt sql.NullTime `db:"cancelled_at" json:"cancelled_at"` + CompletedAt sql.NullTime `db:"completed_at" json:"completed_at"` + Error sql.NullString `db:"error" json:"error"` +} + +func (q *sqlQuerier) UpdateProvisionerJobByID(ctx context.Context, arg UpdateProvisionerJobByIDParams) error { + _, err := q.db.ExecContext(ctx, updateProvisionerJobByID, + arg.ID, + arg.UpdatedAt, + arg.CancelledAt, + arg.CompletedAt, + arg.Error, + ) + return err +} + const updateWorkspaceHistoryByID = `-- name: UpdateWorkspaceHistoryByID :exec UPDATE workspace_history From c7c7388a064a5295aed73bcfd074cfb5cd4feef0 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Sat, 29 Jan 2022 15:41:46 +0000 Subject: [PATCH 2/5] feat: Compute project build parameters Adds a projectparameter package to compute build-time project values for a provided scope. This package will be used to return which variables are being used for a build, and can visually indicate the hierarchy to a user. --- coderd/projectparameter/projectparameter.go | 234 +++++++ .../projectparameter/projectparameter_test.go | 205 ++++++ provisionersdk/proto/provisioner.pb.go | 640 +++++++++++++----- provisionersdk/proto/provisioner.proto | 51 +- 4 files changed, 949 insertions(+), 181 deletions(-) create mode 100644 coderd/projectparameter/projectparameter.go create mode 100644 coderd/projectparameter/projectparameter_test.go diff --git a/coderd/projectparameter/projectparameter.go b/coderd/projectparameter/projectparameter.go new file mode 100644 index 0000000000000..f1814657f22bb --- /dev/null +++ b/coderd/projectparameter/projectparameter.go @@ -0,0 +1,234 @@ +package projectparameter + +import ( + "context" + "database/sql" + "errors" + "fmt" + + "github.com/google/uuid" + "golang.org/x/xerrors" + + "github.com/coder/coder/database" + "github.com/coder/coder/provisionersdk/proto" +) + +// Scope targets identifiers to pull parameters from. +type Scope struct { + OrganizationID string + ProjectID uuid.UUID + ProjectHistoryID uuid.UUID + UserID string + WorkspaceID uuid.UUID + WorkspaceHistoryID uuid.UUID +} + +// Value represents a computed parameter. +type Value struct { + Proto *proto.ParameterValue + // DefaultValue is whether a default value for the scope + // was consumed. This can only be true for projects. + DefaultValue bool + Scope database.ParameterScope + ScopeID string +} + +// Compute accepts a scope in which parameter values are sourced. +// These sources are iterated in a hierarchial fashion to determine +// the runtime parameter vaues for a project. +func Compute(ctx context.Context, db database.Store, scope Scope) ([]Value, error) { + compute := &compute{ + parameterByName: map[string]Value{}, + projectParameterByName: map[string]database.ProjectParameter{}, + } + + // All parameters for the project version! + projectHistoryParameters, err := db.GetProjectParametersByHistoryID(ctx, scope.ProjectHistoryID) + if errors.Is(err, sql.ErrNoRows) { + // It's valid to have no parameters! + return []Value{}, nil + } + if err != nil { + return nil, xerrors.Errorf("get project parameters: %w", err) + } + for _, projectParameter := range projectHistoryParameters { + compute.projectParameterByName[projectParameter.Name] = projectParameter + } + + // Organization parameters come first! + organizationParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + Scope: database.ParameterScopeOrganization, + ScopeID: scope.OrganizationID, + }) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + return nil, xerrors.Errorf("get organization parameters: %w", err) + } + err = compute.inject(organizationParameters) + if err != nil { + return nil, xerrors.Errorf("inject organization parameters: %w", err) + } + + // Default project parameter values come second! + for _, projectParameter := range projectHistoryParameters { + if !projectParameter.DefaultSourceValue.Valid { + continue + } + if !projectParameter.DefaultDestinationValue.Valid { + continue + } + + destinationScheme, err := convertDestinationScheme(projectParameter.DefaultDestinationScheme) + if err != nil { + return nil, xerrors.Errorf("convert default destination scheme for project parameter %q: %w", projectParameter.Name, err) + } + + switch projectParameter.DefaultSourceScheme { + case database.ParameterSourceSchemeData: + compute.parameterByName[projectParameter.Name] = Value{ + Proto: &proto.ParameterValue{ + DestinationScheme: destinationScheme, + Name: projectParameter.DefaultDestinationValue.String, + Value: projectParameter.DefaultSourceValue.String, + }, + DefaultValue: true, + Scope: database.ParameterScopeProject, + ScopeID: scope.ProjectID.String(), + } + default: + return nil, xerrors.Errorf("unsupported source scheme for project parameter %q: %q", projectParameter.Name, string(projectParameter.DefaultSourceScheme)) + } + } + + // Project parameters come third! + projectParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + Scope: database.ParameterScopeProject, + ScopeID: scope.ProjectID.String(), + }) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + return nil, xerrors.Errorf("get project parameters: %w", err) + } + err = compute.inject(projectParameters) + if err != nil { + return nil, xerrors.Errorf("inject project parameters: %w", err) + } + + // User parameters come fourth! + userParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + Scope: database.ParameterScopeUser, + ScopeID: scope.UserID, + }) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + return nil, xerrors.Errorf("get user parameters: %w", err) + } + err = compute.inject(userParameters) + if err != nil { + return nil, xerrors.Errorf("inject user parameters: %w", err) + } + + // Workspace parameters come last! + workspaceParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + Scope: database.ParameterScopeWorkspace, + ScopeID: scope.WorkspaceID.String(), + }) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + return nil, xerrors.Errorf("get workspace parameters: %w", err) + } + err = compute.inject(workspaceParameters) + if err != nil { + return nil, xerrors.Errorf("inject workspace parameters: %w", err) + } + + for _, projectParameter := range compute.projectParameterByName { + if _, ok := compute.parameterByName[projectParameter.Name]; ok { + continue + } + return nil, NoValueError{ + ParameterID: projectParameter.ID, + ParameterName: projectParameter.Name, + } + } + + values := make([]Value, 0, len(compute.parameterByName)) + for _, value := range compute.parameterByName { + values = append(values, value) + } + return values, nil +} + +type compute struct { + parameterByName map[string]Value + projectParameterByName map[string]database.ProjectParameter +} + +// Validates and computes the value for parameters; setting the value on "parameterByName". +func (c *compute) inject(scopedParameters []database.ParameterValue) error { + for _, scopedParameter := range scopedParameters { + projectParameter, hasProjectParameter := c.projectParameterByName[scopedParameter.Name] + if !hasProjectParameter { + // Don't inject parameters that aren't defined by the project. + continue + } + + _, hasExistingParameter := c.parameterByName[scopedParameter.Name] + if hasExistingParameter { + // If a parameter already exists, check if this variable can override it. + // Injection hierarchy is the responsibility of the caller. This check ensures + // project parameters cannot be overridden if already set. + if !projectParameter.AllowOverrideSource && scopedParameter.Scope != database.ParameterScopeProject { + continue + } + } + + destinationScheme, err := convertDestinationScheme(scopedParameter.DestinationScheme) + if err != nil { + return xerrors.Errorf("convert destination scheme: %w", err) + } + + switch scopedParameter.SourceScheme { + case database.ParameterSourceSchemeData: + c.parameterByName[projectParameter.Name] = Value{ + Proto: &proto.ParameterValue{ + DestinationScheme: destinationScheme, + Name: scopedParameter.SourceValue, + Value: scopedParameter.DestinationValue, + }, + } + default: + return xerrors.Errorf("unsupported source scheme: %q", string(projectParameter.DefaultSourceScheme)) + } + } + return nil +} + +// Converts the database destination scheme to the protobuf version. +func convertDestinationScheme(scheme database.ParameterDestinationScheme) (proto.ParameterDestination_Scheme, error) { + switch scheme { + case database.ParameterDestinationSchemeEnvironmentVariable: + return proto.ParameterDestination_ENVIRONMENT_VARIABLE, nil + case database.ParameterDestinationSchemeProvisionerVariable: + return proto.ParameterDestination_PROVISIONER_VARIABLE, nil + default: + return 0, xerrors.Errorf("unsupported destination scheme: %q", scheme) + } +} + +type NoValueError struct { + ParameterID uuid.UUID + ParameterName string +} + +func (e NoValueError) Error() string { + return fmt.Sprintf("no value for parameter %q found", e.ParameterName) +} diff --git a/coderd/projectparameter/projectparameter_test.go b/coderd/projectparameter/projectparameter_test.go new file mode 100644 index 0000000000000..5b562175497e6 --- /dev/null +++ b/coderd/projectparameter/projectparameter_test.go @@ -0,0 +1,205 @@ +package projectparameter_test + +import ( + "context" + "database/sql" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" + + "github.com/coder/coder/coderd/projectparameter" + "github.com/coder/coder/cryptorand" + "github.com/coder/coder/database" + "github.com/coder/coder/database/databasefake" + "github.com/coder/coder/provisionersdk/proto" +) + +func TestCompute(t *testing.T) { + t.Parallel() + generateScope := func() projectparameter.Scope { + return projectparameter.Scope{ + OrganizationID: uuid.New().String(), + ProjectID: uuid.New(), + ProjectHistoryID: uuid.New(), + UserID: uuid.NewString(), + } + } + type projectParameterOptions struct { + AllowOverrideSource bool + AllowOverrideDestination bool + DefaultDestinationScheme database.ParameterDestinationScheme + ProjectHistoryID uuid.UUID + } + generateProjectParameter := func(t *testing.T, db database.Store, opts projectParameterOptions) database.ProjectParameter { + if opts.DefaultDestinationScheme == "" { + opts.DefaultDestinationScheme = database.ParameterDestinationSchemeEnvironmentVariable + } + name, err := cryptorand.String(8) + require.NoError(t, err) + sourceValue, err := cryptorand.String(8) + require.NoError(t, err) + destinationValue, err := cryptorand.String(8) + require.NoError(t, err) + param, err := db.InsertProjectParameter(context.Background(), database.InsertProjectParameterParams{ + ID: uuid.New(), + Name: name, + ProjectHistoryID: opts.ProjectHistoryID, + DefaultSourceScheme: database.ParameterSourceSchemeData, + DefaultSourceValue: sql.NullString{ + String: sourceValue, + Valid: true, + }, + DefaultDestinationValue: sql.NullString{ + String: destinationValue, + Valid: true, + }, + AllowOverrideSource: opts.AllowOverrideSource, + AllowOverrideDestination: opts.AllowOverrideDestination, + DefaultDestinationScheme: opts.DefaultDestinationScheme, + }) + require.NoError(t, err) + return param + } + + t.Run("NoValue", func(t *testing.T) { + t.Parallel() + db := databasefake.New() + scope := generateScope() + parameter, err := db.InsertProjectParameter(context.Background(), database.InsertProjectParameterParams{ + ID: uuid.New(), + ProjectHistoryID: scope.ProjectHistoryID, + Name: "hey", + }) + require.NoError(t, err) + + _, err = projectparameter.Compute(context.Background(), db, scope) + var noValueErr projectparameter.NoValueError + require.ErrorAs(t, err, &noValueErr) + require.Equal(t, parameter.ID.String(), noValueErr.ParameterID.String()) + require.Equal(t, parameter.Name, noValueErr.ParameterName) + }) + + t.Run("UseDefaultProjectValue", func(t *testing.T) { + t.Parallel() + db := databasefake.New() + scope := generateScope() + parameter := generateProjectParameter(t, db, projectParameterOptions{ + ProjectHistoryID: scope.ProjectHistoryID, + DefaultDestinationScheme: database.ParameterDestinationSchemeProvisionerVariable, + }) + values, err := projectparameter.Compute(context.Background(), db, scope) + require.NoError(t, err) + require.Len(t, values, 1) + value := values[0] + require.True(t, value.DefaultValue) + require.Equal(t, database.ParameterScopeProject, value.Scope) + require.Equal(t, scope.ProjectID.String(), value.ScopeID) + require.Equal(t, value.Proto.Name, parameter.DefaultDestinationValue.String) + require.Equal(t, value.Proto.DestinationScheme, proto.ParameterDestination_PROVISIONER_VARIABLE) + require.Equal(t, value.Proto.Value, parameter.DefaultSourceValue.String) + }) + + t.Run("OverrideOrganizationWithProjectDefault", func(t *testing.T) { + t.Parallel() + db := databasefake.New() + scope := generateScope() + parameter := generateProjectParameter(t, db, projectParameterOptions{ + ProjectHistoryID: scope.ProjectHistoryID, + }) + _, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{ + ID: uuid.New(), + Name: parameter.Name, + Scope: database.ParameterScopeOrganization, + ScopeID: scope.OrganizationID, + SourceScheme: database.ParameterSourceSchemeData, + SourceValue: "nop", + DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable, + DestinationValue: "organizationvalue", + }) + require.NoError(t, err) + + values, err := projectparameter.Compute(context.Background(), db, scope) + require.NoError(t, err) + require.Len(t, values, 1) + require.Equal(t, true, values[0].DefaultValue) + require.Equal(t, parameter.DefaultSourceValue.String, values[0].Proto.Value) + }) + + t.Run("ProjectOverridesProjectDefault", func(t *testing.T) { + t.Parallel() + db := databasefake.New() + scope := generateScope() + parameter := generateProjectParameter(t, db, projectParameterOptions{ + ProjectHistoryID: scope.ProjectHistoryID, + }) + value, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{ + ID: uuid.New(), + Name: parameter.Name, + Scope: database.ParameterScopeProject, + ScopeID: scope.ProjectID.String(), + SourceScheme: database.ParameterSourceSchemeData, + SourceValue: "nop", + DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable, + DestinationValue: "projectvalue", + }) + require.NoError(t, err) + + values, err := projectparameter.Compute(context.Background(), db, scope) + require.NoError(t, err) + require.Len(t, values, 1) + require.Equal(t, false, values[0].DefaultValue) + require.Equal(t, value.DestinationValue, values[0].Proto.Value) + }) + + t.Run("WorkspaceCannotOverwriteProjectDefault", func(t *testing.T) { + t.Parallel() + db := databasefake.New() + scope := generateScope() + parameter := generateProjectParameter(t, db, projectParameterOptions{ + ProjectHistoryID: scope.ProjectHistoryID, + }) + _, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{ + ID: uuid.New(), + Name: parameter.Name, + Scope: database.ParameterScopeWorkspace, + ScopeID: scope.WorkspaceID.String(), + SourceScheme: database.ParameterSourceSchemeData, + SourceValue: "nop", + DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable, + DestinationValue: "projectvalue", + }) + require.NoError(t, err) + + values, err := projectparameter.Compute(context.Background(), db, scope) + require.NoError(t, err) + require.Len(t, values, 1) + require.Equal(t, true, values[0].DefaultValue) + }) + + t.Run("WorkspaceOverwriteProjectDefault", func(t *testing.T) { + t.Parallel() + db := databasefake.New() + scope := generateScope() + parameter := generateProjectParameter(t, db, projectParameterOptions{ + AllowOverrideSource: true, + ProjectHistoryID: scope.ProjectHistoryID, + }) + _, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{ + ID: uuid.New(), + Name: parameter.Name, + Scope: database.ParameterScopeWorkspace, + ScopeID: scope.WorkspaceID.String(), + SourceScheme: database.ParameterSourceSchemeData, + SourceValue: "nop", + DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable, + DestinationValue: "projectvalue", + }) + require.NoError(t, err) + + values, err := projectparameter.Compute(context.Background(), db, scope) + require.NoError(t, err) + require.Len(t, values, 1) + require.Equal(t, false, values[0].DefaultValue) + }) +} diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 37bf884066dd4..7537f69f27c51 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -20,6 +20,95 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type ParameterSource_Scheme int32 + +const ( + ParameterSource_DATA ParameterSource_Scheme = 0 +) + +// Enum value maps for ParameterSource_Scheme. +var ( + ParameterSource_Scheme_name = map[int32]string{ + 0: "DATA", + } + ParameterSource_Scheme_value = map[string]int32{ + "DATA": 0, + } +) + +func (x ParameterSource_Scheme) Enum() *ParameterSource_Scheme { + p := new(ParameterSource_Scheme) + *p = x + return p +} + +func (x ParameterSource_Scheme) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ParameterSource_Scheme) Descriptor() protoreflect.EnumDescriptor { + return file_provisioner_proto_enumTypes[0].Descriptor() +} + +func (ParameterSource_Scheme) Type() protoreflect.EnumType { + return &file_provisioner_proto_enumTypes[0] +} + +func (x ParameterSource_Scheme) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ParameterSource_Scheme.Descriptor instead. +func (ParameterSource_Scheme) EnumDescriptor() ([]byte, []int) { + return file_provisioner_proto_rawDescGZIP(), []int{0, 0} +} + +type ParameterDestination_Scheme int32 + +const ( + ParameterDestination_ENVIRONMENT_VARIABLE ParameterDestination_Scheme = 0 + ParameterDestination_PROVISIONER_VARIABLE ParameterDestination_Scheme = 1 +) + +// Enum value maps for ParameterDestination_Scheme. +var ( + ParameterDestination_Scheme_name = map[int32]string{ + 0: "ENVIRONMENT_VARIABLE", + 1: "PROVISIONER_VARIABLE", + } + ParameterDestination_Scheme_value = map[string]int32{ + "ENVIRONMENT_VARIABLE": 0, + "PROVISIONER_VARIABLE": 1, + } +) + +func (x ParameterDestination_Scheme) Enum() *ParameterDestination_Scheme { + p := new(ParameterDestination_Scheme) + *p = x + return p +} + +func (x ParameterDestination_Scheme) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ParameterDestination_Scheme) Descriptor() protoreflect.EnumDescriptor { + return file_provisioner_proto_enumTypes[1].Descriptor() +} + +func (ParameterDestination_Scheme) Type() protoreflect.EnumType { + return &file_provisioner_proto_enumTypes[1] +} + +func (x ParameterDestination_Scheme) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ParameterDestination_Scheme.Descriptor instead. +func (ParameterDestination_Scheme) EnumDescriptor() ([]byte, []int) { + return file_provisioner_proto_rawDescGZIP(), []int{1, 0} +} + type ParameterSchema_TypeSystem int32 const ( @@ -47,11 +136,11 @@ func (x ParameterSchema_TypeSystem) String() string { } func (ParameterSchema_TypeSystem) Descriptor() protoreflect.EnumDescriptor { - return file_provisioner_proto_enumTypes[0].Descriptor() + return file_provisioner_proto_enumTypes[2].Descriptor() } func (ParameterSchema_TypeSystem) Type() protoreflect.EnumType { - return &file_provisioner_proto_enumTypes[0] + return &file_provisioner_proto_enumTypes[2] } func (x ParameterSchema_TypeSystem) Number() protoreflect.EnumNumber { @@ -60,27 +149,21 @@ func (x ParameterSchema_TypeSystem) Number() protoreflect.EnumNumber { // Deprecated: Use ParameterSchema_TypeSystem.Descriptor instead. func (ParameterSchema_TypeSystem) EnumDescriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{0, 0} + return file_provisioner_proto_rawDescGZIP(), []int{3, 0} } -// ParameterSchema represents validation and type information for a parsed parameter. -type ParameterSchema struct { +// ParameterSource represents the source location for a parameter to get it's value from. +type ParameterSource struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - DefaultValue string `protobuf:"bytes,3,opt,name=default_value,json=defaultValue,proto3" json:"default_value,omitempty"` - Sensitive bool `protobuf:"varint,4,opt,name=sensitive,proto3" json:"sensitive,omitempty"` - ValidationTypeSystem ParameterSchema_TypeSystem `protobuf:"varint,5,opt,name=validation_type_system,json=validationTypeSystem,proto3,enum=provisioner.ParameterSchema_TypeSystem" json:"validation_type_system,omitempty"` - ValidationValueType string `protobuf:"bytes,6,opt,name=validation_value_type,json=validationValueType,proto3" json:"validation_value_type,omitempty"` - ValidationError string `protobuf:"bytes,7,opt,name=validation_error,json=validationError,proto3" json:"validation_error,omitempty"` - ValidationCondition string `protobuf:"bytes,8,opt,name=validation_condition,json=validationCondition,proto3" json:"validation_condition,omitempty"` + Scheme ParameterSource_Scheme `protobuf:"varint,1,opt,name=scheme,proto3,enum=provisioner.ParameterSource_Scheme" json:"scheme,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` } -func (x *ParameterSchema) Reset() { - *x = ParameterSchema{} +func (x *ParameterSource) Reset() { + *x = ParameterSource{} if protoimpl.UnsafeEnabled { mi := &file_provisioner_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -88,13 +171,13 @@ func (x *ParameterSchema) Reset() { } } -func (x *ParameterSchema) String() string { +func (x *ParameterSource) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ParameterSchema) ProtoMessage() {} +func (*ParameterSource) ProtoMessage() {} -func (x *ParameterSchema) ProtoReflect() protoreflect.Message { +func (x *ParameterSource) ProtoReflect() protoreflect.Message { mi := &file_provisioner_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -106,81 +189,96 @@ func (x *ParameterSchema) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ParameterSchema.ProtoReflect.Descriptor instead. -func (*ParameterSchema) Descriptor() ([]byte, []int) { +// Deprecated: Use ParameterSource.ProtoReflect.Descriptor instead. +func (*ParameterSource) Descriptor() ([]byte, []int) { return file_provisioner_proto_rawDescGZIP(), []int{0} } -func (x *ParameterSchema) GetName() string { +func (x *ParameterSource) GetScheme() ParameterSource_Scheme { if x != nil { - return x.Name + return x.Scheme } - return "" + return ParameterSource_DATA } -func (x *ParameterSchema) GetDescription() string { +func (x *ParameterSource) GetValue() string { if x != nil { - return x.Description + return x.Value } return "" } -func (x *ParameterSchema) GetDefaultValue() string { - if x != nil { - return x.DefaultValue - } - return "" +// ParameterDestination represents the target location for a provisioner to set the value. +type ParameterDestination struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Scheme ParameterDestination_Scheme `protobuf:"varint,1,opt,name=scheme,proto3,enum=provisioner.ParameterDestination_Scheme" json:"scheme,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` } -func (x *ParameterSchema) GetSensitive() bool { - if x != nil { - return x.Sensitive +func (x *ParameterDestination) Reset() { + *x = ParameterDestination{} + if protoimpl.UnsafeEnabled { + mi := &file_provisioner_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return false } -func (x *ParameterSchema) GetValidationTypeSystem() ParameterSchema_TypeSystem { - if x != nil { - return x.ValidationTypeSystem - } - return ParameterSchema_HCL +func (x *ParameterDestination) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *ParameterSchema) GetValidationValueType() string { - if x != nil { - return x.ValidationValueType +func (*ParameterDestination) ProtoMessage() {} + +func (x *ParameterDestination) ProtoReflect() protoreflect.Message { + mi := &file_provisioner_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return "" + return mi.MessageOf(x) } -func (x *ParameterSchema) GetValidationError() string { +// Deprecated: Use ParameterDestination.ProtoReflect.Descriptor instead. +func (*ParameterDestination) Descriptor() ([]byte, []int) { + return file_provisioner_proto_rawDescGZIP(), []int{1} +} + +func (x *ParameterDestination) GetScheme() ParameterDestination_Scheme { if x != nil { - return x.ValidationError + return x.Scheme } - return "" + return ParameterDestination_ENVIRONMENT_VARIABLE } -func (x *ParameterSchema) GetValidationCondition() string { +func (x *ParameterDestination) GetValue() string { if x != nil { - return x.ValidationCondition + return x.Value } return "" } -// ParameterValue holds the value of a parameter. +// ParameterValue represents the resolved source and destination of a parameter. type ParameterValue struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + DestinationScheme ParameterDestination_Scheme `protobuf:"varint,1,opt,name=destination_scheme,json=destinationScheme,proto3,enum=provisioner.ParameterDestination_Scheme" json:"destination_scheme,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` } func (x *ParameterValue) Reset() { *x = ParameterValue{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[1] + mi := &file_provisioner_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -193,7 +291,7 @@ func (x *ParameterValue) String() string { func (*ParameterValue) ProtoMessage() {} func (x *ParameterValue) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[1] + mi := &file_provisioner_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -206,7 +304,14 @@ func (x *ParameterValue) ProtoReflect() protoreflect.Message { // Deprecated: Use ParameterValue.ProtoReflect.Descriptor instead. func (*ParameterValue) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{1} + return file_provisioner_proto_rawDescGZIP(), []int{2} +} + +func (x *ParameterValue) GetDestinationScheme() ParameterDestination_Scheme { + if x != nil { + return x.DestinationScheme + } + return ParameterDestination_ENVIRONMENT_VARIABLE } func (x *ParameterValue) GetName() string { @@ -223,6 +328,134 @@ func (x *ParameterValue) GetValue() string { return "" } +// ParameterSchema represents validation and type information for a parsed parameter. +type ParameterSchema struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` + DefaultSource *ParameterSource `protobuf:"bytes,3,opt,name=default_source,json=defaultSource,proto3" json:"default_source,omitempty"` + AllowOverrideSource bool `protobuf:"varint,4,opt,name=allow_override_source,json=allowOverrideSource,proto3" json:"allow_override_source,omitempty"` + DefaultDestination *ParameterDestination `protobuf:"bytes,5,opt,name=default_destination,json=defaultDestination,proto3" json:"default_destination,omitempty"` + AllowOverrideDestination bool `protobuf:"varint,6,opt,name=allow_override_destination,json=allowOverrideDestination,proto3" json:"allow_override_destination,omitempty"` + RedisplayValue bool `protobuf:"varint,7,opt,name=redisplay_value,json=redisplayValue,proto3" json:"redisplay_value,omitempty"` + ValidationTypeSystem ParameterSchema_TypeSystem `protobuf:"varint,8,opt,name=validation_type_system,json=validationTypeSystem,proto3,enum=provisioner.ParameterSchema_TypeSystem" json:"validation_type_system,omitempty"` + ValidationValueType string `protobuf:"bytes,9,opt,name=validation_value_type,json=validationValueType,proto3" json:"validation_value_type,omitempty"` + ValidationError string `protobuf:"bytes,10,opt,name=validation_error,json=validationError,proto3" json:"validation_error,omitempty"` + ValidationCondition string `protobuf:"bytes,11,opt,name=validation_condition,json=validationCondition,proto3" json:"validation_condition,omitempty"` +} + +func (x *ParameterSchema) Reset() { + *x = ParameterSchema{} + if protoimpl.UnsafeEnabled { + mi := &file_provisioner_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ParameterSchema) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ParameterSchema) ProtoMessage() {} + +func (x *ParameterSchema) ProtoReflect() protoreflect.Message { + mi := &file_provisioner_proto_msgTypes[3] + 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 ParameterSchema.ProtoReflect.Descriptor instead. +func (*ParameterSchema) Descriptor() ([]byte, []int) { + return file_provisioner_proto_rawDescGZIP(), []int{3} +} + +func (x *ParameterSchema) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ParameterSchema) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *ParameterSchema) GetDefaultSource() *ParameterSource { + if x != nil { + return x.DefaultSource + } + return nil +} + +func (x *ParameterSchema) GetAllowOverrideSource() bool { + if x != nil { + return x.AllowOverrideSource + } + return false +} + +func (x *ParameterSchema) GetDefaultDestination() *ParameterDestination { + if x != nil { + return x.DefaultDestination + } + return nil +} + +func (x *ParameterSchema) GetAllowOverrideDestination() bool { + if x != nil { + return x.AllowOverrideDestination + } + return false +} + +func (x *ParameterSchema) GetRedisplayValue() bool { + if x != nil { + return x.RedisplayValue + } + return false +} + +func (x *ParameterSchema) GetValidationTypeSystem() ParameterSchema_TypeSystem { + if x != nil { + return x.ValidationTypeSystem + } + return ParameterSchema_HCL +} + +func (x *ParameterSchema) GetValidationValueType() string { + if x != nil { + return x.ValidationValueType + } + return "" +} + +func (x *ParameterSchema) GetValidationError() string { + if x != nil { + return x.ValidationError + } + return "" +} + +func (x *ParameterSchema) GetValidationCondition() string { + if x != nil { + return x.ValidationCondition + } + return "" +} + // Parse consumes source-code from a directory to produce inputs. type Parse struct { state protoimpl.MessageState @@ -233,7 +466,7 @@ type Parse struct { func (x *Parse) Reset() { *x = Parse{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[2] + mi := &file_provisioner_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -246,7 +479,7 @@ func (x *Parse) String() string { func (*Parse) ProtoMessage() {} func (x *Parse) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[2] + mi := &file_provisioner_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -259,7 +492,7 @@ func (x *Parse) ProtoReflect() protoreflect.Message { // Deprecated: Use Parse.ProtoReflect.Descriptor instead. func (*Parse) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{2} + return file_provisioner_proto_rawDescGZIP(), []int{4} } // Resource is a provisioned unit. @@ -275,7 +508,7 @@ type Resource struct { func (x *Resource) Reset() { *x = Resource{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[3] + mi := &file_provisioner_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -288,7 +521,7 @@ func (x *Resource) String() string { func (*Resource) ProtoMessage() {} func (x *Resource) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[3] + mi := &file_provisioner_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -301,7 +534,7 @@ func (x *Resource) ProtoReflect() protoreflect.Message { // Deprecated: Use Resource.ProtoReflect.Descriptor instead. func (*Resource) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{3} + return file_provisioner_proto_rawDescGZIP(), []int{5} } func (x *Resource) GetName() string { @@ -328,7 +561,7 @@ type Provision struct { func (x *Provision) Reset() { *x = Provision{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[4] + mi := &file_provisioner_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -341,7 +574,7 @@ func (x *Provision) String() string { func (*Provision) ProtoMessage() {} func (x *Provision) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[4] + mi := &file_provisioner_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -354,7 +587,7 @@ func (x *Provision) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision.ProtoReflect.Descriptor instead. func (*Provision) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{4} + return file_provisioner_proto_rawDescGZIP(), []int{6} } type Parse_Request struct { @@ -368,7 +601,7 @@ type Parse_Request struct { func (x *Parse_Request) Reset() { *x = Parse_Request{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[5] + mi := &file_provisioner_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -381,7 +614,7 @@ func (x *Parse_Request) String() string { func (*Parse_Request) ProtoMessage() {} func (x *Parse_Request) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[5] + mi := &file_provisioner_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -394,7 +627,7 @@ func (x *Parse_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Parse_Request.ProtoReflect.Descriptor instead. func (*Parse_Request) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{2, 0} + return file_provisioner_proto_rawDescGZIP(), []int{4, 0} } func (x *Parse_Request) GetDirectory() string { @@ -415,7 +648,7 @@ type Parse_Response struct { func (x *Parse_Response) Reset() { *x = Parse_Response{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[6] + mi := &file_provisioner_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -428,7 +661,7 @@ func (x *Parse_Response) String() string { func (*Parse_Response) ProtoMessage() {} func (x *Parse_Response) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[6] + mi := &file_provisioner_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -441,7 +674,7 @@ func (x *Parse_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Parse_Response.ProtoReflect.Descriptor instead. func (*Parse_Response) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{2, 1} + return file_provisioner_proto_rawDescGZIP(), []int{4, 1} } func (x *Parse_Response) GetParameterSchemas() []*ParameterSchema { @@ -464,7 +697,7 @@ type Provision_Request struct { func (x *Provision_Request) Reset() { *x = Provision_Request{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[7] + mi := &file_provisioner_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -477,7 +710,7 @@ func (x *Provision_Request) String() string { func (*Provision_Request) ProtoMessage() {} func (x *Provision_Request) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[7] + mi := &file_provisioner_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -490,7 +723,7 @@ func (x *Provision_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Request.ProtoReflect.Descriptor instead. func (*Provision_Request) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{4, 0} + return file_provisioner_proto_rawDescGZIP(), []int{6, 0} } func (x *Provision_Request) GetDirectory() string { @@ -526,7 +759,7 @@ type Provision_Response struct { func (x *Provision_Response) Reset() { *x = Provision_Response{} if protoimpl.UnsafeEnabled { - mi := &file_provisioner_proto_msgTypes[8] + mi := &file_provisioner_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -539,7 +772,7 @@ func (x *Provision_Response) String() string { func (*Provision_Response) ProtoMessage() {} func (x *Provision_Response) ProtoReflect() protoreflect.Message { - mi := &file_provisioner_proto_msgTypes[8] + mi := &file_provisioner_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -552,7 +785,7 @@ func (x *Provision_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Response.ProtoReflect.Descriptor instead. func (*Provision_Response) Descriptor() ([]byte, []int) { - return file_provisioner_proto_rawDescGZIP(), []int{4, 1} + return file_provisioner_proto_rawDescGZIP(), []int{6, 1} } func (x *Provision_Response) GetState() []byte { @@ -574,75 +807,115 @@ var File_provisioner_proto protoreflect.FileDescriptor var file_provisioner_proto_rawDesc = []byte{ 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, - 0x22, 0x92, 0x03, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x5d, 0x0a, + 0x22, 0x78, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x12, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, + 0x12, 0x08, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x41, 0x10, 0x00, 0x22, 0xac, 0x01, 0x0a, 0x14, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x52, 0x06, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3c, 0x0a, 0x06, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x4e, 0x56, 0x49, 0x52, 0x4f, 0x4e, + 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, + 0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x56, + 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x01, 0x22, 0x93, 0x01, 0x0a, 0x0e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x57, 0x0a, 0x12, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x65, 0x52, 0x11, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x83, 0x05, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x43, 0x0a, 0x0e, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x32, + 0x0a, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, + 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x12, 0x52, 0x0a, 0x13, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x64, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x12, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x44, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x1a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, + 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x18, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, + 0x65, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x5d, 0x0a, 0x16, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, + 0x5f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x32, 0x0a, 0x15, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x76, 0x61, 0x6c, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x31, 0x0a, 0x14, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x15, 0x0a, 0x0a, 0x54, 0x79, 0x70, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x07, 0x0a, 0x03, - 0x48, 0x43, 0x4c, 0x10, 0x00, 0x22, 0x3a, 0x0a, 0x0e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x22, 0x87, 0x01, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x1a, 0x27, 0x0a, 0x07, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x55, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x22, 0x32, 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, 0x22, - 0xea, 0x01, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x85, 0x01, - 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, - 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x55, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x32, 0x9d, 0x01, 0x0a, - 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x40, 0x0a, 0x05, - 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, - 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2a, 0x5a, 0x28, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x48, 0x43, 0x4c, 0x10, 0x00, 0x22, 0x87, 0x01, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x1a, + 0x27, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x55, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x22, + 0x32, 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, 0x22, 0xea, 0x01, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x1a, 0x85, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, + 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x55, 0x0a, 0x08, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x32, 0x9d, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x12, 0x40, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -657,34 +930,43 @@ func file_provisioner_proto_rawDescGZIP() []byte { return file_provisioner_proto_rawDescData } -var file_provisioner_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_provisioner_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_provisioner_proto_goTypes = []interface{}{ - (ParameterSchema_TypeSystem)(0), // 0: provisioner.ParameterSchema.TypeSystem - (*ParameterSchema)(nil), // 1: provisioner.ParameterSchema - (*ParameterValue)(nil), // 2: provisioner.ParameterValue - (*Parse)(nil), // 3: provisioner.Parse - (*Resource)(nil), // 4: provisioner.Resource - (*Provision)(nil), // 5: provisioner.Provision - (*Parse_Request)(nil), // 6: provisioner.Parse.Request - (*Parse_Response)(nil), // 7: provisioner.Parse.Response - (*Provision_Request)(nil), // 8: provisioner.Provision.Request - (*Provision_Response)(nil), // 9: provisioner.Provision.Response + (ParameterSource_Scheme)(0), // 0: provisioner.ParameterSource.Scheme + (ParameterDestination_Scheme)(0), // 1: provisioner.ParameterDestination.Scheme + (ParameterSchema_TypeSystem)(0), // 2: provisioner.ParameterSchema.TypeSystem + (*ParameterSource)(nil), // 3: provisioner.ParameterSource + (*ParameterDestination)(nil), // 4: provisioner.ParameterDestination + (*ParameterValue)(nil), // 5: provisioner.ParameterValue + (*ParameterSchema)(nil), // 6: provisioner.ParameterSchema + (*Parse)(nil), // 7: provisioner.Parse + (*Resource)(nil), // 8: provisioner.Resource + (*Provision)(nil), // 9: provisioner.Provision + (*Parse_Request)(nil), // 10: provisioner.Parse.Request + (*Parse_Response)(nil), // 11: provisioner.Parse.Response + (*Provision_Request)(nil), // 12: provisioner.Provision.Request + (*Provision_Response)(nil), // 13: provisioner.Provision.Response } var file_provisioner_proto_depIdxs = []int32{ - 0, // 0: provisioner.ParameterSchema.validation_type_system:type_name -> provisioner.ParameterSchema.TypeSystem - 1, // 1: provisioner.Parse.Response.parameter_schemas:type_name -> provisioner.ParameterSchema - 2, // 2: provisioner.Provision.Request.parameter_values:type_name -> provisioner.ParameterValue - 4, // 3: provisioner.Provision.Response.resources:type_name -> provisioner.Resource - 6, // 4: provisioner.Provisioner.Parse:input_type -> provisioner.Parse.Request - 8, // 5: provisioner.Provisioner.Provision:input_type -> provisioner.Provision.Request - 7, // 6: provisioner.Provisioner.Parse:output_type -> provisioner.Parse.Response - 9, // 7: provisioner.Provisioner.Provision:output_type -> provisioner.Provision.Response - 6, // [6:8] is the sub-list for method output_type - 4, // [4:6] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 0, // 0: provisioner.ParameterSource.scheme:type_name -> provisioner.ParameterSource.Scheme + 1, // 1: provisioner.ParameterDestination.scheme:type_name -> provisioner.ParameterDestination.Scheme + 1, // 2: provisioner.ParameterValue.destination_scheme:type_name -> provisioner.ParameterDestination.Scheme + 3, // 3: provisioner.ParameterSchema.default_source:type_name -> provisioner.ParameterSource + 4, // 4: provisioner.ParameterSchema.default_destination:type_name -> provisioner.ParameterDestination + 2, // 5: provisioner.ParameterSchema.validation_type_system:type_name -> provisioner.ParameterSchema.TypeSystem + 6, // 6: provisioner.Parse.Response.parameter_schemas:type_name -> provisioner.ParameterSchema + 5, // 7: provisioner.Provision.Request.parameter_values:type_name -> provisioner.ParameterValue + 8, // 8: provisioner.Provision.Response.resources:type_name -> provisioner.Resource + 10, // 9: provisioner.Provisioner.Parse:input_type -> provisioner.Parse.Request + 12, // 10: provisioner.Provisioner.Provision:input_type -> provisioner.Provision.Request + 11, // 11: provisioner.Provisioner.Parse:output_type -> provisioner.Parse.Response + 13, // 12: provisioner.Provisioner.Provision:output_type -> provisioner.Provision.Response + 11, // [11:13] is the sub-list for method output_type + 9, // [9:11] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name } func init() { file_provisioner_proto_init() } @@ -694,7 +976,7 @@ func file_provisioner_proto_init() { } if !protoimpl.UnsafeEnabled { file_provisioner_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParameterSchema); i { + switch v := v.(*ParameterSource); i { case 0: return &v.state case 1: @@ -706,7 +988,7 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ParameterValue); i { + switch v := v.(*ParameterDestination); i { case 0: return &v.state case 1: @@ -718,7 +1000,7 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Parse); i { + switch v := v.(*ParameterValue); i { case 0: return &v.state case 1: @@ -730,7 +1012,7 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Resource); i { + switch v := v.(*ParameterSchema); i { case 0: return &v.state case 1: @@ -742,7 +1024,7 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Provision); i { + switch v := v.(*Parse); i { case 0: return &v.state case 1: @@ -754,7 +1036,7 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Parse_Request); i { + switch v := v.(*Resource); i { case 0: return &v.state case 1: @@ -766,7 +1048,7 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Parse_Response); i { + switch v := v.(*Provision); i { case 0: return &v.state case 1: @@ -778,7 +1060,7 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Provision_Request); i { + switch v := v.(*Parse_Request); i { case 0: return &v.state case 1: @@ -790,6 +1072,30 @@ func file_provisioner_proto_init() { } } file_provisioner_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Parse_Response); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_provisioner_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Provision_Request); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_provisioner_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision_Response); i { case 0: return &v.state @@ -807,8 +1113,8 @@ func file_provisioner_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_provisioner_proto_rawDesc, - NumEnums: 1, - NumMessages: 9, + NumEnums: 3, + NumMessages: 11, NumExtensions: 0, NumServices: 1, }, diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index 362604c27ec89..c865dced18fe9 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -1,29 +1,52 @@ syntax = "proto3"; -option go_package = "github.com/coder/coder/provisioner/proto"; +option go_package = "github.com/coder/coder/provisionersdk/proto"; package provisioner; +// ParameterSource represents the source location for a parameter to get it's value from. +message ParameterSource { + enum Scheme { + DATA = 0; + } + Scheme scheme = 1; + string value = 2; +} + +// ParameterDestination represents the target location for a provisioner to set the value. +message ParameterDestination { + enum Scheme { + ENVIRONMENT_VARIABLE = 0; + PROVISIONER_VARIABLE = 1; + } + Scheme scheme = 1; + string value = 2; +} + +// ParameterValue represents the resolved source and destination of a parameter. +message ParameterValue { + ParameterDestination.Scheme destination_scheme = 1; + string name = 2; + string value = 3; +} + // ParameterSchema represents validation and type information for a parsed parameter. message ParameterSchema { string name = 1; string description = 2; - string default_value = 3; - bool sensitive = 4; + ParameterSource default_source = 3; + bool allow_override_source = 4; + ParameterDestination default_destination = 5; + bool allow_override_destination = 6; + bool redisplay_value = 7; enum TypeSystem { HCL = 0; } - TypeSystem validation_type_system = 5; - string validation_value_type = 6; - string validation_error = 7; - string validation_condition = 8; -} - -// ParameterValue holds the value of a parameter. -message ParameterValue { - string name = 1; - string value = 2; + TypeSystem validation_type_system = 8; + string validation_value_type = 9; + string validation_error = 10; + string validation_condition = 11; } // Parse consumes source-code from a directory to produce inputs. @@ -58,4 +81,4 @@ message Provision { service Provisioner { rpc Parse(Parse.Request) returns (Parse.Response); rpc Provision(Provision.Request) returns (Provision.Response); -} +} \ No newline at end of file From ace6248a07da898c2e5aa5481a2d75ab97fb64ab Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Sat, 29 Jan 2022 15:44:57 +0000 Subject: [PATCH 3/5] Fix terraform provisioner --- provisioner/terraform/parse.go | 11 +++++++++-- provisioner/terraform/parse_test.go | 11 +++++++++-- provisioner/terraform/provision.go | 17 +++++++++++++++-- provisioner/terraform/provision_test.go | 5 +++-- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/provisioner/terraform/parse.go b/provisioner/terraform/parse.go index 639d1039f451c..cc92bc8f8008c 100644 --- a/provisioner/terraform/parse.go +++ b/provisioner/terraform/parse.go @@ -37,7 +37,7 @@ func convertVariableToParameter(variable *tfconfig.Variable) (*proto.ParameterSc schema := &proto.ParameterSchema{ Name: variable.Name, Description: variable.Description, - Sensitive: variable.Sensitive, + RedisplayValue: variable.Sensitive, ValidationValueType: variable.Type, } @@ -46,7 +46,14 @@ func convertVariableToParameter(variable *tfconfig.Variable) (*proto.ParameterSc if err != nil { return nil, xerrors.Errorf("parse variable %q default: %w", variable.Name, err) } - schema.DefaultValue = string(defaultData) + schema.DefaultSource = &proto.ParameterSource{ + Scheme: proto.ParameterSource_DATA, + Value: string(defaultData), + } + schema.DefaultDestination = &proto.ParameterDestination{ + Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE, + Value: variable.Name, + } } if len(variable.Validations) > 0 && variable.Validations[0].Condition != nil { diff --git a/provisioner/terraform/parse_test.go b/provisioner/terraform/parse_test.go index 94af39103a308..bbfe166827851 100644 --- a/provisioner/terraform/parse_test.go +++ b/provisioner/terraform/parse_test.go @@ -63,8 +63,15 @@ func TestParse(t *testing.T) { }, Response: &proto.Parse_Response{ ParameterSchemas: []*proto.ParameterSchema{{ - Name: "A", - DefaultValue: "\"wow\"", + Name: "A", + DefaultSource: &proto.ParameterSource{ + Scheme: proto.ParameterSource_DATA, + Value: "\"wow\"", + }, + DefaultDestination: &proto.ParameterDestination{ + Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE, + Value: "A", + }, }}, }, }, { diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go index 34f57ff649192..4cf94ec0d9378 100644 --- a/provisioner/terraform/provision.go +++ b/provisioner/terraform/provision.go @@ -37,10 +37,23 @@ func (t *terraform) Provision(ctx context.Context, request *proto.Provision_Requ return nil, xerrors.Errorf("initialize terraform: %w", err) } + env := map[string]string{} options := make([]tfexec.ApplyOption, 0) - for _, params := range request.ParameterValues { - options = append(options, tfexec.Var(fmt.Sprintf("%s=%s", params.Name, params.Value))) + for _, param := range request.ParameterValues { + switch param.DestinationScheme { + case proto.ParameterDestination_ENVIRONMENT_VARIABLE: + env[param.Name] = param.Value + case proto.ParameterDestination_PROVISIONER_VARIABLE: + options = append(options, tfexec.Var(fmt.Sprintf("%s=%s", param.Name, param.Value))) + default: + return nil, xerrors.Errorf("unsupported parameter type %q for %q", param.DestinationScheme, param.Name) + } + } + err = terraform.SetEnv(env) + if err != nil { + return nil, xerrors.Errorf("apply environment variables: %w", err) } + err = terraform.Apply(ctx, options...) if err != nil { return nil, xerrors.Errorf("apply terraform: %w", err) diff --git a/provisioner/terraform/provision_test.go b/provisioner/terraform/provision_test.go index 7d193033f1e65..b596c85d0bf15 100644 --- a/provisioner/terraform/provision_test.go +++ b/provisioner/terraform/provision_test.go @@ -63,8 +63,9 @@ func TestProvision(t *testing.T) { }, Request: &proto.Provision_Request{ ParameterValues: []*proto.ParameterValue{{ - Name: "A", - Value: "example", + DestinationScheme: proto.ParameterDestination_PROVISIONER_VARIABLE, + Name: "A", + Value: "example", }}, }, Response: &proto.Provision_Response{}, From c4644e119f18a0de300658a4de8679ce822438f4 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Sat, 29 Jan 2022 23:31:42 +0000 Subject: [PATCH 4/5] Improve naming, abstract inject to consume scope --- coderd/projectparameter/projectparameter.go | 119 +++++++++----------- 1 file changed, 51 insertions(+), 68 deletions(-) diff --git a/coderd/projectparameter/projectparameter.go b/coderd/projectparameter/projectparameter.go index f1814657f22bb..95975849e0ddf 100644 --- a/coderd/projectparameter/projectparameter.go +++ b/coderd/projectparameter/projectparameter.go @@ -34,159 +34,142 @@ type Value struct { } // Compute accepts a scope in which parameter values are sourced. -// These sources are iterated in a hierarchial fashion to determine -// the runtime parameter vaues for a project. +// These sources are iterated in a hierarchical fashion to determine +// the runtime parameter values for a project. func Compute(ctx context.Context, db database.Store, scope Scope) ([]Value, error) { compute := &compute{ - parameterByName: map[string]Value{}, - projectParameterByName: map[string]database.ProjectParameter{}, + db: db, + computedParameterByName: map[string]Value{}, + projectHistoryParametersByName: map[string]database.ProjectParameter{}, } // All parameters for the project version! projectHistoryParameters, err := db.GetProjectParametersByHistoryID(ctx, scope.ProjectHistoryID) if errors.Is(err, sql.ErrNoRows) { - // It's valid to have no parameters! + // This occurs when the project history has defined + // no parameters, so we have nothing to compute! return []Value{}, nil } if err != nil { return nil, xerrors.Errorf("get project parameters: %w", err) } - for _, projectParameter := range projectHistoryParameters { - compute.projectParameterByName[projectParameter.Name] = projectParameter + for _, projectHistoryParameter := range projectHistoryParameters { + compute.projectHistoryParametersByName[projectHistoryParameter.Name] = projectHistoryParameter } // Organization parameters come first! - organizationParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + err = compute.inject(ctx, database.GetParameterValuesByScopeParams{ Scope: database.ParameterScopeOrganization, ScopeID: scope.OrganizationID, }) - if errors.Is(err, sql.ErrNoRows) { - err = nil - } if err != nil { - return nil, xerrors.Errorf("get organization parameters: %w", err) - } - err = compute.inject(organizationParameters) - if err != nil { - return nil, xerrors.Errorf("inject organization parameters: %w", err) + return nil, err } // Default project parameter values come second! - for _, projectParameter := range projectHistoryParameters { - if !projectParameter.DefaultSourceValue.Valid { + for _, projectHistoryParameter := range projectHistoryParameters { + if !projectHistoryParameter.DefaultSourceValue.Valid { continue } - if !projectParameter.DefaultDestinationValue.Valid { + if !projectHistoryParameter.DefaultDestinationValue.Valid { continue } - destinationScheme, err := convertDestinationScheme(projectParameter.DefaultDestinationScheme) + destinationScheme, err := convertDestinationScheme(projectHistoryParameter.DefaultDestinationScheme) if err != nil { - return nil, xerrors.Errorf("convert default destination scheme for project parameter %q: %w", projectParameter.Name, err) + return nil, xerrors.Errorf("convert default destination scheme for project history parameter %q: %w", projectHistoryParameter.Name, err) } - switch projectParameter.DefaultSourceScheme { + switch projectHistoryParameter.DefaultSourceScheme { case database.ParameterSourceSchemeData: - compute.parameterByName[projectParameter.Name] = Value{ + compute.computedParameterByName[projectHistoryParameter.Name] = Value{ Proto: &proto.ParameterValue{ DestinationScheme: destinationScheme, - Name: projectParameter.DefaultDestinationValue.String, - Value: projectParameter.DefaultSourceValue.String, + Name: projectHistoryParameter.DefaultDestinationValue.String, + Value: projectHistoryParameter.DefaultSourceValue.String, }, DefaultValue: true, Scope: database.ParameterScopeProject, ScopeID: scope.ProjectID.String(), } default: - return nil, xerrors.Errorf("unsupported source scheme for project parameter %q: %q", projectParameter.Name, string(projectParameter.DefaultSourceScheme)) + return nil, xerrors.Errorf("unsupported source scheme for project history parameter %q: %q", projectHistoryParameter.Name, string(projectHistoryParameter.DefaultSourceScheme)) } } // Project parameters come third! - projectParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + err = compute.inject(ctx, database.GetParameterValuesByScopeParams{ Scope: database.ParameterScopeProject, ScopeID: scope.ProjectID.String(), }) - if errors.Is(err, sql.ErrNoRows) { - err = nil - } - if err != nil { - return nil, xerrors.Errorf("get project parameters: %w", err) - } - err = compute.inject(projectParameters) if err != nil { - return nil, xerrors.Errorf("inject project parameters: %w", err) + return nil, err } // User parameters come fourth! - userParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + err = compute.inject(ctx, database.GetParameterValuesByScopeParams{ Scope: database.ParameterScopeUser, ScopeID: scope.UserID, }) - if errors.Is(err, sql.ErrNoRows) { - err = nil - } if err != nil { - return nil, xerrors.Errorf("get user parameters: %w", err) - } - err = compute.inject(userParameters) - if err != nil { - return nil, xerrors.Errorf("inject user parameters: %w", err) + return nil, err } // Workspace parameters come last! - workspaceParameters, err := db.GetParameterValuesByScope(ctx, database.GetParameterValuesByScopeParams{ + err = compute.inject(ctx, database.GetParameterValuesByScopeParams{ Scope: database.ParameterScopeWorkspace, ScopeID: scope.WorkspaceID.String(), }) - if errors.Is(err, sql.ErrNoRows) { - err = nil - } - if err != nil { - return nil, xerrors.Errorf("get workspace parameters: %w", err) - } - err = compute.inject(workspaceParameters) if err != nil { - return nil, xerrors.Errorf("inject workspace parameters: %w", err) + return nil, err } - for _, projectParameter := range compute.projectParameterByName { - if _, ok := compute.parameterByName[projectParameter.Name]; ok { + for _, projectHistoryParameter := range compute.projectHistoryParametersByName { + if _, ok := compute.computedParameterByName[projectHistoryParameter.Name]; ok { continue } return nil, NoValueError{ - ParameterID: projectParameter.ID, - ParameterName: projectParameter.Name, + ParameterID: projectHistoryParameter.ID, + ParameterName: projectHistoryParameter.Name, } } - values := make([]Value, 0, len(compute.parameterByName)) - for _, value := range compute.parameterByName { + values := make([]Value, 0, len(compute.computedParameterByName)) + for _, value := range compute.computedParameterByName { values = append(values, value) } return values, nil } type compute struct { - parameterByName map[string]Value - projectParameterByName map[string]database.ProjectParameter + db database.Store + computedParameterByName map[string]Value + projectHistoryParametersByName map[string]database.ProjectParameter } // Validates and computes the value for parameters; setting the value on "parameterByName". -func (c *compute) inject(scopedParameters []database.ParameterValue) error { +func (c *compute) inject(ctx context.Context, scopeParams database.GetParameterValuesByScopeParams) error { + scopedParameters, err := c.db.GetParameterValuesByScope(ctx, scopeParams) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + return xerrors.Errorf("get %s parameters: %w", scopeParams.Scope, err) + } + for _, scopedParameter := range scopedParameters { - projectParameter, hasProjectParameter := c.projectParameterByName[scopedParameter.Name] - if !hasProjectParameter { + projectHistoryParameter, hasProjectHistoryParameter := c.projectHistoryParametersByName[scopedParameter.Name] + if !hasProjectHistoryParameter { // Don't inject parameters that aren't defined by the project. continue } - _, hasExistingParameter := c.parameterByName[scopedParameter.Name] + _, hasExistingParameter := c.computedParameterByName[scopedParameter.Name] if hasExistingParameter { // If a parameter already exists, check if this variable can override it. // Injection hierarchy is the responsibility of the caller. This check ensures // project parameters cannot be overridden if already set. - if !projectParameter.AllowOverrideSource && scopedParameter.Scope != database.ParameterScopeProject { + if !projectHistoryParameter.AllowOverrideSource && scopedParameter.Scope != database.ParameterScopeProject { continue } } @@ -198,7 +181,7 @@ func (c *compute) inject(scopedParameters []database.ParameterValue) error { switch scopedParameter.SourceScheme { case database.ParameterSourceSchemeData: - c.parameterByName[projectParameter.Name] = Value{ + c.computedParameterByName[projectHistoryParameter.Name] = Value{ Proto: &proto.ParameterValue{ DestinationScheme: destinationScheme, Name: scopedParameter.SourceValue, @@ -206,7 +189,7 @@ func (c *compute) inject(scopedParameters []database.ParameterValue) error { }, } default: - return xerrors.Errorf("unsupported source scheme: %q", string(projectParameter.DefaultSourceScheme)) + return xerrors.Errorf("unsupported source scheme: %q", string(projectHistoryParameter.DefaultSourceScheme)) } } return nil From 4117ee2b708ff8192c5d08f90ce9adee2c31bda4 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Sat, 29 Jan 2022 23:41:01 +0000 Subject: [PATCH 5/5] Run CI on all branches --- .github/workflows/coder.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/coder.yaml b/.github/workflows/coder.yaml index a3ee273af8671..7e0b890edad9b 100644 --- a/.github/workflows/coder.yaml +++ b/.github/workflows/coder.yaml @@ -10,8 +10,7 @@ on: pull_request: branches: - - main - - "release/*" + - "*" workflow_dispatch: