diff --git a/.github/workflows/coder.yaml b/.github/workflows/coder.yaml index 8467dbe81ba4d..a3ee273af8671 100644 --- a/.github/workflows/coder.yaml +++ b/.github/workflows/coder.yaml @@ -160,7 +160,7 @@ jobs: run: DB=true gotestsum --jsonfile="gotests.json" --packages="./..." -- -covermode=atomic -coverprofile="gotests.coverage" -timeout=3m - -count=1 -race -parallel=2 + -count=1 -race -parallel=1 - uses: codecov/codecov-action@v2 with: 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..abf887cd17693 100644 --- a/database/query.sql +++ b/database/query.sql @@ -4,6 +4,38 @@ -- Run "make gen" to generate models and query functions. ; +-- Acquires the lock for a single job that isn't started, completed, +-- cancelled, and that matches an array of provisioner types. +-- +-- SKIP LOCKED is used to jump over locked rows. This prevents +-- multiple provisioners from acquiring the same jobs. See: +-- https://www.postgresql.org/docs/9.5/sql-select.html#SQL-FOR-UPDATE-SHARE +-- 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 +73,14 @@ SELECT FROM users; +-- name: GetOrganizationByID :one +SELECT + * +FROM + organizations +WHERE + id = $1; + -- name: GetOrganizationByName :one SELECT * @@ -77,6 +117,15 @@ WHERE LIMIT 1; +-- name: GetParameterValuesByScope :many +SELECT + * +FROM + parameter_value +WHERE + scope = $1 + AND scope_id = $2; + -- name: GetProjectByID :one SELECT * @@ -106,6 +155,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 +179,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 +231,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 +332,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 +386,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 +415,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 +524,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..83c2a8af006f0 100644 --- a/database/query.sql.go +++ b/database/query.sql.go @@ -13,6 +13,66 @@ 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"` +} + +// Acquires the lock for a single job that isn't started, completed, +// cancelled, and that matches an array of provisioner types. +// +// SKIP LOCKED is used to jump over locked rows. This prevents +// multiple provisioners from acquiring the same jobs. See: +// https://www.postgresql.org/docs/9.5/sql-select.html#SQL-FOR-UPDATE-SHARE +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 +107,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 +243,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 +418,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 +508,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 +695,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 +749,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 +1156,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 +1325,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 +1354,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 +1387,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 +1407,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 +1423,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 +1802,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