chore: update v1 schema (#643)

This commit is contained in:
Colin Adler
2022-04-01 14:42:36 -05:00
committed by GitHub
parent cbb82ce017
commit 2b1a0ee126
69 changed files with 757 additions and 624 deletions

View File

@ -155,10 +155,10 @@ func NewProvisionerDaemon(t *testing.T, client *codersdk.Client) io.Closer {
// with the passed in codersdk client.
func CreateFirstUser(t *testing.T, client *codersdk.Client) codersdk.CreateFirstUserResponse {
req := codersdk.CreateFirstUserRequest{
Email: "testuser@coder.com",
Username: "testuser",
Password: "testpass",
Organization: "testorg",
Email: "testuser@coder.com",
Username: "testuser",
Password: "testpass",
OrganizationName: "testorg",
}
resp, err := client.CreateFirstUser(context.Background(), req)
require.NoError(t, err)
@ -173,12 +173,12 @@ func CreateFirstUser(t *testing.T, client *codersdk.Client) codersdk.CreateFirst
}
// CreateAnotherUser creates and authenticates a new user.
func CreateAnotherUser(t *testing.T, client *codersdk.Client, organization string) *codersdk.Client {
func CreateAnotherUser(t *testing.T, client *codersdk.Client, organizationID uuid.UUID) *codersdk.Client {
req := codersdk.CreateUserRequest{
Email: namesgenerator.GetRandomName(1) + "@coder.com",
Username: randomUsername(),
Password: "testpass",
OrganizationID: organization,
OrganizationID: organizationID,
}
_, err := client.CreateUser(context.Background(), req)
require.NoError(t, err)
@ -197,12 +197,12 @@ func CreateAnotherUser(t *testing.T, client *codersdk.Client, organization strin
// CreateProjectVersion creates a project import provisioner job
// with the responses provided. It uses the "echo" provisioner for compatibility
// with testing.
func CreateProjectVersion(t *testing.T, client *codersdk.Client, organization string, res *echo.Responses) codersdk.ProjectVersion {
func CreateProjectVersion(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses) codersdk.ProjectVersion {
data, err := echo.Tar(res)
require.NoError(t, err)
file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, data)
require.NoError(t, err)
projectVersion, err := client.CreateProjectVersion(context.Background(), organization, codersdk.CreateProjectVersionRequest{
projectVersion, err := client.CreateProjectVersion(context.Background(), organizationID, codersdk.CreateProjectVersionRequest{
StorageSource: file.Hash,
StorageMethod: database.ProvisionerStorageMethodFile,
Provisioner: database.ProvisionerTypeEcho,
@ -213,7 +213,7 @@ func CreateProjectVersion(t *testing.T, client *codersdk.Client, organization st
// CreateProject creates a project with the "echo" provisioner for
// compatibility with testing. The name assigned is randomly generated.
func CreateProject(t *testing.T, client *codersdk.Client, organization string, version uuid.UUID) codersdk.Project {
func CreateProject(t *testing.T, client *codersdk.Client, organization uuid.UUID, version uuid.UUID) codersdk.Project {
project, err := client.CreateProject(context.Background(), organization, codersdk.CreateProjectRequest{
Name: randomUsername(),
VersionID: version,
@ -268,7 +268,7 @@ func AwaitWorkspaceAgents(t *testing.T, client *codersdk.Client, build uuid.UUID
// CreateWorkspace creates a workspace for the user and project provided.
// A random name is generated for it.
func CreateWorkspace(t *testing.T, client *codersdk.Client, user string, projectID uuid.UUID) codersdk.Workspace {
func CreateWorkspace(t *testing.T, client *codersdk.Client, user uuid.UUID, projectID uuid.UUID) codersdk.Workspace {
workspace, err := client.CreateWorkspace(context.Background(), user, codersdk.CreateWorkspaceRequest{
ProjectID: projectID,
Name: randomUsername(),

View File

@ -6,6 +6,7 @@ import (
"go.uber.org/goleak"
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/codersdk"
)
func TestMain(m *testing.M) {
@ -20,7 +21,7 @@ func TestNew(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
coderdtest.AwaitWorkspaceAgents(t, client, workspace.LatestBuild.ID)
_, _ = coderdtest.NewGoogleInstanceIdentity(t, "example", false)

View File

@ -143,7 +143,7 @@ func (q *fakeQuerier) GetUserByEmailOrUsername(_ context.Context, arg database.G
return database.User{}, sql.ErrNoRows
}
func (q *fakeQuerier) GetUserByID(_ context.Context, id string) (database.User, error) {
func (q *fakeQuerier) GetUserByID(_ context.Context, id uuid.UUID) (database.User, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
@ -217,34 +217,33 @@ func (q *fakeQuerier) GetWorkspaceOwnerCountsByProjectIDs(_ context.Context, pro
q.mutex.RLock()
defer q.mutex.RUnlock()
counts := map[string]map[string]struct{}{}
counts := map[uuid.UUID]map[uuid.UUID]struct{}{}
for _, projectID := range projectIDs {
found := false
for _, workspace := range q.workspace {
if workspace.ProjectID.String() != projectID.String() {
if workspace.ProjectID != projectID {
continue
}
if workspace.Deleted {
continue
}
countByOwnerID, ok := counts[projectID.String()]
countByOwnerID, ok := counts[projectID]
if !ok {
countByOwnerID = map[string]struct{}{}
countByOwnerID = map[uuid.UUID]struct{}{}
}
countByOwnerID[workspace.OwnerID] = struct{}{}
counts[projectID.String()] = countByOwnerID
counts[projectID] = countByOwnerID
found = true
break
}
if !found {
counts[projectID.String()] = map[string]struct{}{}
counts[projectID] = map[uuid.UUID]struct{}{}
}
}
res := make([]database.GetWorkspaceOwnerCountsByProjectIDsRow, 0)
for key, value := range counts {
uid := uuid.MustParse(key)
res = append(res, database.GetWorkspaceOwnerCountsByProjectIDsRow{
ProjectID: uid,
ProjectID: key,
Count: int64(len(value)),
})
}
@ -364,7 +363,7 @@ func (q *fakeQuerier) GetWorkspacesByUserID(_ context.Context, req database.GetW
return workspaces, nil
}
func (q *fakeQuerier) GetOrganizationByID(_ context.Context, id string) (database.Organization, error) {
func (q *fakeQuerier) GetOrganizationByID(_ context.Context, id uuid.UUID) (database.Organization, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
@ -388,7 +387,7 @@ func (q *fakeQuerier) GetOrganizationByName(_ context.Context, name string) (dat
return database.Organization{}, sql.ErrNoRows
}
func (q *fakeQuerier) GetOrganizationsByUserID(_ context.Context, userID string) ([]database.Organization, error) {
func (q *fakeQuerier) GetOrganizationsByUserID(_ context.Context, userID uuid.UUID) ([]database.Organization, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
@ -483,7 +482,7 @@ func (q *fakeQuerier) GetProjectVersionByProjectIDAndName(_ context.Context, arg
defer q.mutex.RUnlock()
for _, projectVersion := range q.projectVersion {
if projectVersion.ProjectID.UUID.String() != arg.ProjectID.UUID.String() {
if projectVersion.ProjectID != arg.ProjectID {
continue
}
if !strings.EqualFold(projectVersion.Name, arg.Name) {
@ -1056,7 +1055,7 @@ func (q *fakeQuerier) InsertWorkspaceBuild(_ context.Context, arg database.Inser
ProjectVersionID: arg.ProjectVersionID,
BeforeID: arg.BeforeID,
Transition: arg.Transition,
Initiator: arg.Initiator,
InitiatorID: arg.InitiatorID,
JobID: arg.JobID,
ProvisionerState: arg.ProvisionerState,
}

159
coderd/database/dump.sql generated
View File

@ -57,12 +57,6 @@ CREATE TYPE provisioner_type AS ENUM (
'terraform'
);
CREATE TYPE userstatus AS ENUM (
'active',
'dormant',
'decommissioned'
);
CREATE TYPE workspace_transition AS ENUM (
'start',
'stop',
@ -72,7 +66,7 @@ CREATE TYPE workspace_transition AS ENUM (
CREATE TABLE api_keys (
id text NOT NULL,
hashed_secret bytea NOT NULL,
user_id text NOT NULL,
user_id uuid NOT NULL,
application boolean NOT NULL,
name text NOT NULL,
last_used timestamp with time zone NOT NULL,
@ -90,7 +84,7 @@ CREATE TABLE api_keys (
CREATE TABLE files (
hash character varying(64) NOT NULL,
created_at timestamp with time zone NOT NULL,
created_by text NOT NULL,
created_by uuid NOT NULL,
mimetype character varying(64) NOT NULL,
data bytea NOT NULL
);
@ -101,25 +95,30 @@ CREATE TABLE licenses (
created_at timestamp with time zone NOT NULL
);
CREATE SEQUENCE licenses_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE licenses_id_seq OWNED BY public.licenses.id;
CREATE TABLE organization_members (
organization_id text NOT NULL,
user_id text NOT NULL,
user_id uuid NOT NULL,
organization_id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
roles text[] DEFAULT '{organization-member}'::text[] NOT NULL
);
CREATE TABLE organizations (
id text NOT NULL,
id uuid NOT NULL,
name text NOT NULL,
description text NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
"default" boolean DEFAULT false NOT NULL,
auto_off_threshold bigint DEFAULT '28800000000000'::bigint NOT NULL,
cpu_provisioning_rate real DEFAULT 4.0 NOT NULL,
memory_provisioning_rate real DEFAULT 1.0 NOT NULL,
workspace_auto_off boolean DEFAULT false NOT NULL
updated_at timestamp with time zone NOT NULL
);
CREATE TABLE parameter_schemas (
@ -146,7 +145,7 @@ CREATE TABLE parameter_values (
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,
scope_id uuid NOT NULL,
name character varying(64) NOT NULL,
source_scheme parameter_source_scheme NOT NULL,
source_value text NOT NULL,
@ -156,7 +155,7 @@ CREATE TABLE parameter_values (
CREATE TABLE project_versions (
id uuid NOT NULL,
project_id uuid,
organization_id text NOT NULL,
organization_id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
name character varying(64) NOT NULL,
@ -168,7 +167,7 @@ CREATE TABLE projects (
id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
organization_id text NOT NULL,
organization_id uuid NOT NULL,
deleted boolean DEFAULT false NOT NULL,
name character varying(64) NOT NULL,
provisioner provisioner_type NOT NULL,
@ -179,7 +178,7 @@ CREATE TABLE provisioner_daemons (
id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone,
organization_id text,
organization_id uuid,
name character varying(64) NOT NULL,
provisioners provisioner_type[] NOT NULL
);
@ -202,8 +201,8 @@ CREATE TABLE provisioner_jobs (
canceled_at timestamp with time zone,
completed_at timestamp with time zone,
error text,
organization_id text NOT NULL,
initiator_id text NOT NULL,
organization_id uuid NOT NULL,
initiator_id uuid NOT NULL,
provisioner provisioner_type NOT NULL,
storage_method provisioner_storage_method NOT NULL,
storage_source text NOT NULL,
@ -213,7 +212,7 @@ CREATE TABLE provisioner_jobs (
);
CREATE TABLE users (
id text NOT NULL,
id uuid NOT NULL,
email text NOT NULL,
name text NOT NULL,
revoked boolean NOT NULL,
@ -221,17 +220,7 @@ CREATE TABLE users (
hashed_password bytea NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
temporary_password boolean DEFAULT false NOT NULL,
avatar_hash text DEFAULT ''::text NOT NULL,
ssh_key_regenerated_at timestamp with time zone DEFAULT now() NOT NULL,
username text DEFAULT ''::text NOT NULL,
dotfiles_git_uri text DEFAULT ''::text NOT NULL,
roles text[] DEFAULT '{site-member}'::text[] NOT NULL,
status userstatus DEFAULT 'active'::public.userstatus NOT NULL,
relatime timestamp with time zone DEFAULT now() NOT NULL,
gpg_key_regenerated_at timestamp with time zone DEFAULT now() NOT NULL,
_decomissioned boolean DEFAULT false NOT NULL,
shell text DEFAULT ''::text NOT NULL
username text DEFAULT ''::text NOT NULL
);
CREATE TABLE workspace_agents (
@ -260,7 +249,7 @@ CREATE TABLE workspace_builds (
before_id uuid,
after_id uuid,
transition workspace_transition NOT NULL,
initiator character varying(255) NOT NULL,
initiator_id uuid NOT NULL,
provisioner_state bytea,
job_id uuid NOT NULL
);
@ -280,85 +269,136 @@ CREATE TABLE workspaces (
id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
owner_id text NOT NULL,
owner_id uuid NOT NULL,
project_id uuid NOT NULL,
deleted boolean DEFAULT false NOT NULL,
name character varying(64) NOT NULL
);
ALTER TABLE ONLY files
ADD CONSTRAINT files_hash_key UNIQUE (hash);
ALTER TABLE ONLY licenses ALTER COLUMN id SET DEFAULT nextval('public.licenses_id_seq'::regclass);
ALTER TABLE ONLY parameter_schemas
ADD CONSTRAINT parameter_schemas_id_key UNIQUE (id);
ALTER TABLE ONLY api_keys
ADD CONSTRAINT api_keys_pkey PRIMARY KEY (id);
ALTER TABLE ONLY files
ADD CONSTRAINT files_pkey PRIMARY KEY (hash);
ALTER TABLE ONLY licenses
ADD CONSTRAINT licenses_pkey PRIMARY KEY (id);
ALTER TABLE ONLY organization_members
ADD CONSTRAINT organization_members_pkey PRIMARY KEY (organization_id, user_id);
ALTER TABLE ONLY organizations
ADD CONSTRAINT organizations_pkey PRIMARY KEY (id);
ALTER TABLE ONLY parameter_schemas
ADD CONSTRAINT parameter_schemas_job_id_name_key UNIQUE (job_id, name);
ALTER TABLE ONLY parameter_schemas
ADD CONSTRAINT parameter_schemas_pkey PRIMARY KEY (id);
ALTER TABLE ONLY parameter_values
ADD CONSTRAINT parameter_values_id_key UNIQUE (id);
ADD CONSTRAINT parameter_values_pkey PRIMARY KEY (id);
ALTER TABLE ONLY parameter_values
ADD CONSTRAINT parameter_values_scope_id_name_key UNIQUE (scope_id, name);
ALTER TABLE ONLY project_versions
ADD CONSTRAINT project_versions_id_key UNIQUE (id);
ADD CONSTRAINT project_versions_pkey PRIMARY KEY (id);
ALTER TABLE ONLY project_versions
ADD CONSTRAINT project_versions_project_id_name_key UNIQUE (project_id, name);
ALTER TABLE ONLY projects
ADD CONSTRAINT projects_id_key UNIQUE (id);
ALTER TABLE ONLY projects
ADD CONSTRAINT projects_organization_id_name_key UNIQUE (organization_id, name);
ALTER TABLE ONLY provisioner_daemons
ADD CONSTRAINT provisioner_daemons_id_key UNIQUE (id);
ALTER TABLE ONLY projects
ADD CONSTRAINT projects_pkey PRIMARY KEY (id);
ALTER TABLE ONLY provisioner_daemons
ADD CONSTRAINT provisioner_daemons_name_key UNIQUE (name);
ALTER TABLE ONLY provisioner_daemons
ADD CONSTRAINT provisioner_daemons_pkey PRIMARY KEY (id);
ALTER TABLE ONLY provisioner_job_logs
ADD CONSTRAINT provisioner_job_logs_id_key UNIQUE (id);
ADD CONSTRAINT provisioner_job_logs_pkey PRIMARY KEY (id);
ALTER TABLE ONLY provisioner_jobs
ADD CONSTRAINT provisioner_jobs_id_key UNIQUE (id);
ADD CONSTRAINT provisioner_jobs_pkey PRIMARY KEY (id);
ALTER TABLE ONLY users
ADD CONSTRAINT users_pkey PRIMARY KEY (id);
ALTER TABLE ONLY workspace_agents
ADD CONSTRAINT workspace_agents_auth_token_key UNIQUE (auth_token);
ALTER TABLE ONLY workspace_agents
ADD CONSTRAINT workspace_agents_id_key UNIQUE (id);
ALTER TABLE ONLY workspace_builds
ADD CONSTRAINT workspace_builds_id_key UNIQUE (id);
ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id);
ALTER TABLE ONLY workspace_builds
ADD CONSTRAINT workspace_builds_job_id_key UNIQUE (job_id);
ALTER TABLE ONLY workspace_builds
ADD CONSTRAINT workspace_builds_pkey PRIMARY KEY (id);
ALTER TABLE ONLY workspace_builds
ADD CONSTRAINT workspace_builds_workspace_id_name_key UNIQUE (workspace_id, name);
ALTER TABLE ONLY workspace_resources
ADD CONSTRAINT workspace_resources_id_key UNIQUE (id);
ADD CONSTRAINT workspace_resources_pkey PRIMARY KEY (id);
ALTER TABLE ONLY workspaces
ADD CONSTRAINT workspaces_id_key UNIQUE (id);
ADD CONSTRAINT workspaces_pkey PRIMARY KEY (id);
CREATE INDEX idx_api_keys_user ON api_keys USING btree (user_id);
CREATE INDEX idx_organization_member_organization_id_uuid ON organization_members USING btree (organization_id);
CREATE INDEX idx_organization_member_user_id_uuid ON organization_members USING btree (user_id);
CREATE UNIQUE INDEX idx_organization_name ON organizations USING btree (name);
CREATE UNIQUE INDEX idx_organization_name_lower ON organizations USING btree (lower(name));
CREATE UNIQUE INDEX idx_users_email ON users USING btree (email);
CREATE UNIQUE INDEX idx_users_username ON users USING btree (username);
CREATE UNIQUE INDEX projects_organization_id_name_idx ON projects USING btree (organization_id, name) WHERE (deleted = false);
CREATE UNIQUE INDEX users_username_lower_idx ON users USING btree (lower(username));
CREATE UNIQUE INDEX workspaces_owner_id_name_idx ON workspaces USING btree (owner_id, name) WHERE (deleted = false);
ALTER TABLE ONLY api_keys
ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE ONLY organization_members
ADD CONSTRAINT organization_members_organization_id_uuid_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE ONLY organization_members
ADD CONSTRAINT organization_members_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
ALTER TABLE ONLY parameter_schemas
ADD CONSTRAINT parameter_schemas_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
ALTER TABLE ONLY project_versions
ADD CONSTRAINT project_versions_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id);
ADD CONSTRAINT project_versions_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE ONLY project_versions
ADD CONSTRAINT project_versions_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY projects
ADD CONSTRAINT projects_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE ONLY provisioner_job_logs
ADD CONSTRAINT provisioner_job_logs_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
ALTER TABLE ONLY provisioner_jobs
ADD CONSTRAINT provisioner_jobs_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE ONLY workspace_agents
ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
@ -375,5 +415,8 @@ ALTER TABLE ONLY workspace_resources
ADD CONSTRAINT workspace_resources_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
ALTER TABLE ONLY workspaces
ADD CONSTRAINT workspaces_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id);
ADD CONSTRAINT workspaces_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT;
ALTER TABLE ONLY workspaces
ADD CONSTRAINT workspaces_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE RESTRICT;

View File

@ -19,14 +19,17 @@ func main() {
panic(err)
}
defer closeFn()
db, err := sql.Open("postgres", connection)
if err != nil {
panic(err)
}
err = database.MigrateUp(db)
if err != nil {
panic(err)
}
cmd := exec.Command(
"pg_dump",
"--schema-only",
@ -39,10 +42,11 @@ func main() {
// queries executing against this table.
"--exclude-table=schema_migrations",
)
cmd.Env = []string{
cmd.Env = append(os.Environ(), []string{
"PGTZ=UTC",
"PGCLIENTENCODING=UTF8",
}
}...)
var output bytes.Buffer
cmd.Stdout = &output
cmd.Stderr = os.Stderr
@ -57,7 +61,7 @@ func main() {
// Public is implicit in the schema.
"s/ public\\./ /",
// Remove database settings.
"s/SET.*;//g",
"s/SET .* = .*;//g",
// Remove select statements. These aren't useful
// to a reader of the dump.
"s/SELECT.*;//g",

View File

@ -0,0 +1,8 @@
DROP TABLE licenses;
DROP TABLE api_keys;
DROP TABLE organization_members;
DROP TABLE organizations;
DROP TABLE users;
DROP TYPE login_type;

View File

@ -4,28 +4,18 @@
-- All tables and types are stolen from:
-- https://github.com/coder/m/blob/47b6fc383347b9f9fab424d829c482defd3e1fe2/product/coder/pkg/database/dump.sql
DO $$ BEGIN
CREATE TYPE login_type AS ENUM (
'built-in',
'saml',
'oidc'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--
-- Name: users; Type: TABLE; Schema: public; Owner: coder
--
DO $$ BEGIN
CREATE TYPE userstatus AS ENUM (
'active',
'dormant',
'decommissioned'
);
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
CREATE TYPE login_type AS ENUM (
'built-in',
'saml',
'oidc'
);
CREATE TABLE IF NOT EXISTS users (
id text NOT NULL,
id uuid NOT NULL,
email text NOT NULL,
name text NOT NULL,
revoked boolean NOT NULL,
@ -33,44 +23,51 @@ CREATE TABLE IF NOT EXISTS users (
hashed_password bytea NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
temporary_password boolean DEFAULT false NOT NULL,
avatar_hash text DEFAULT '' :: text NOT NULL,
ssh_key_regenerated_at timestamp with time zone DEFAULT now() NOT NULL,
username text DEFAULT '' :: text NOT NULL,
dotfiles_git_uri text DEFAULT '' :: text NOT NULL,
roles text [] DEFAULT '{site-member}' :: text [] NOT NULL,
status userstatus DEFAULT 'active' :: public.userstatus NOT NULL,
relatime timestamp with time zone DEFAULT now() NOT NULL,
gpg_key_regenerated_at timestamp with time zone DEFAULT now() NOT NULL,
_decomissioned boolean DEFAULT false NOT NULL,
shell text DEFAULT '' :: text NOT NULL
username text DEFAULT ''::text NOT NULL,
PRIMARY KEY (id)
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_email ON users USING btree (email);
CREATE UNIQUE INDEX IF NOT EXISTS idx_users_username ON users USING btree (username);
CREATE UNIQUE INDEX IF NOT EXISTS users_username_lower_idx ON users USING btree (lower(username));
--
-- Name: organizations; Type: TABLE; Schema: Owner: coder
--
CREATE TABLE IF NOT EXISTS organizations (
id text NOT NULL,
id uuid NOT NULL,
name text NOT NULL,
description text NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
"default" boolean DEFAULT false NOT NULL,
auto_off_threshold bigint DEFAULT '28800000000000' :: bigint NOT NULL,
cpu_provisioning_rate real DEFAULT 4.0 NOT NULL,
memory_provisioning_rate real DEFAULT 1.0 NOT NULL,
workspace_auto_off boolean DEFAULT false NOT NULL
PRIMARY KEY (id)
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_organization_name ON organizations USING btree (name);
CREATE UNIQUE INDEX IF NOT EXISTS idx_organization_name_lower ON organizations USING btree (lower(name));
CREATE TABLE IF NOT EXISTS organization_members (
organization_id text NOT NULL,
user_id text NOT NULL,
user_id uuid NOT NULL,
organization_id uuid NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
roles text [] DEFAULT '{organization-member}' :: text [] NOT NULL
roles text [] DEFAULT '{organization-member}' :: text [] NOT NULL,
PRIMARY KEY (organization_id, user_id)
);
CREATE INDEX idx_organization_member_organization_id_uuid ON organization_members USING btree (organization_id);
CREATE INDEX idx_organization_member_user_id_uuid ON organization_members USING btree (user_id);
ALTER TABLE ONLY organization_members
ADD CONSTRAINT organization_members_organization_id_uuid_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
ALTER TABLE ONLY organization_members
ADD CONSTRAINT organization_members_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
CREATE TABLE IF NOT EXISTS api_keys (
id text NOT NULL,
hashed_secret bytea NOT NULL,
user_id text NOT NULL,
user_id uuid NOT NULL,
application boolean NOT NULL,
name text NOT NULL,
last_used timestamp with time zone NOT NULL,
@ -82,11 +79,18 @@ CREATE TABLE IF NOT EXISTS api_keys (
oidc_refresh_token text DEFAULT ''::text NOT NULL,
oidc_id_token text DEFAULT ''::text NOT NULL,
oidc_expiry timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL,
devurl_token boolean DEFAULT false NOT NULL
devurl_token boolean DEFAULT false NOT NULL,
PRIMARY KEY (id)
);
CREATE INDEX IF NOT EXISTS idx_api_keys_user ON api_keys USING btree (user_id);
ALTER TABLE ONLY api_keys
ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
CREATE TABLE IF NOT EXISTS licenses (
id integer NOT NULL,
id serial,
license jsonb NOT NULL,
created_at timestamp with time zone NOT NULL
created_at timestamptz NOT NULL,
PRIMARY KEY (id)
);

View File

@ -1,10 +1,12 @@
-- Store arbitrary data like project source code or avatars.
CREATE TABLE files (
hash varchar(64) NOT NULL UNIQUE,
hash varchar(64) NOT NULL,
created_at timestamptz NOT NULL,
created_by text NOT NULL,
-- foreign key?
created_by uuid NOT NULL,
mimetype varchar(64) NOT NULL,
data bytea NOT NULL
data bytea NOT NULL,
PRIMARY KEY (hash)
);
CREATE TYPE provisioner_type AS ENUM ('echo', 'terraform');
@ -12,17 +14,18 @@ CREATE TYPE provisioner_type AS ENUM ('echo', 'terraform');
-- Project defines infrastructure that your software project
-- requires for development.
CREATE TABLE projects (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
-- Projects must be scoped to an organization.
organization_id text NOT NULL,
organization_id uuid NOT NULL REFERENCES organizations (id) ON DELETE CASCADE,
deleted boolean NOT NULL DEFAULT FALSE,
name varchar(64) NOT NULL,
provisioner provisioner_type NOT NULL,
-- Target's a Project Version to use for Workspaces.
-- If a Workspace doesn't match this version, it will be prompted to rebuild.
active_version_id uuid NOT NULL,
PRIMARY KEY (id),
-- Disallow projects to have the same name under
-- the same organization.
UNIQUE(organization_id, name)
@ -35,10 +38,10 @@ CREATE UNIQUE INDEX ON projects (organization_id, name) WHERE deleted = FALSE;
-- an "import" job is queued to parse parameters. A Project Version
-- can only be used if the import job succeeds.
CREATE TABLE project_versions (
id uuid NOT NULL UNIQUE,
-- This should be indexed.
project_id uuid REFERENCES projects (id),
organization_id text NOT NULL,
id uuid NOT NULL,
-- This should be indexed. It is intentionally nullable.
project_id uuid REFERENCES projects (id) ON DELETE CASCADE,
organization_id uuid NOT NULL REFERENCES organizations (id) ON DELETE CASCADE,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
-- Name is generated for ease of differentiation.
@ -49,6 +52,7 @@ CREATE TABLE project_versions (
description varchar(1048576) NOT NULL,
-- The job ID for building the project version.
job_id uuid NOT NULL,
PRIMARY KEY (id),
-- Disallow projects to have the same build name
-- multiple times.
UNIQUE(project_id, name)

View File

@ -1,11 +1,14 @@
CREATE TABLE workspaces (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
owner_id text NOT NULL,
project_id uuid NOT NULL REFERENCES projects (id),
-- Use ON DELETE RESTRICT so that we can cleanup external workspace
-- resources first.
owner_id uuid NOT NULL REFERENCES users (id) ON DELETE RESTRICT,
project_id uuid NOT NULL REFERENCES projects (id) ON DELETE RESTRICT,
deleted boolean NOT NULL DEFAULT FALSE,
name varchar(64) NOT NULL
name varchar(64) NOT NULL,
PRIMARY KEY (id)
);
-- Enforces no active workspaces have the same name.

View File

@ -1,12 +1,13 @@
CREATE TABLE IF NOT EXISTS provisioner_daemons (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz,
organization_id text,
organization_id uuid,
-- Name is generated for ease of differentiation.
-- eg. WowBananas16
name varchar(64) NOT NULL UNIQUE,
provisioners provisioner_type [ ] NOT NULL
provisioners provisioner_type [ ] NOT NULL,
PRIMARY KEY (id)
);
CREATE TYPE provisioner_job_type AS ENUM (
@ -17,21 +18,23 @@ CREATE TYPE provisioner_job_type AS ENUM (
CREATE TYPE provisioner_storage_method AS ENUM ('file');
CREATE TABLE IF NOT EXISTS provisioner_jobs (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
started_at timestamptz,
canceled_at timestamptz,
completed_at timestamptz,
error text,
organization_id text NOT NULL,
initiator_id text NOT NULL,
organization_id uuid NOT NULL REFERENCES organizations (id) ON DELETE CASCADE,
-- foreign key?
initiator_id uuid NOT NULL,
provisioner provisioner_type NOT NULL,
storage_method provisioner_storage_method NOT NULL,
storage_source text NOT NULL,
type provisioner_job_type NOT NULL,
input jsonb NOT NULL,
worker_id uuid
worker_id uuid,
PRIMARY KEY (id)
);
CREATE TYPE log_level AS ENUM (
@ -48,28 +51,30 @@ CREATE TYPE log_source AS ENUM (
);
CREATE TABLE IF NOT EXISTS provisioner_job_logs (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
job_id uuid NOT NULL REFERENCES provisioner_jobs (id) ON DELETE CASCADE,
created_at timestamptz NOT NULL,
source log_source NOT NULL,
level log_level NOT NULL,
stage varchar(128) NOT NULL,
output varchar(1024) NOT NULL
output varchar(1024) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE workspace_resources (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
job_id uuid NOT NULL REFERENCES provisioner_jobs (id) ON DELETE CASCADE,
transition workspace_transition NOT NULL,
address varchar(256) NOT NULL,
type varchar(192) NOT NULL,
name varchar(64) NOT NULL,
agent_id uuid
agent_id uuid,
PRIMARY KEY (id)
);
CREATE TABLE workspace_agents (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
first_connected_at timestamptz,
@ -81,7 +86,8 @@ CREATE TABLE workspace_agents (
environment_variables jsonb,
startup_script varchar(65534),
instance_metadata jsonb,
resource_metadata jsonb
resource_metadata jsonb,
PRIMARY KEY (id)
);
CREATE TYPE parameter_scope AS ENUM (
@ -111,7 +117,7 @@ CREATE TYPE parameter_destination_scheme AS ENUM('none', 'environment_variable',
-- a UI for users to enter values.
-- Needs to be made consistent with the examples below.
CREATE TABLE parameter_schemas (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
job_id uuid NOT NULL REFERENCES provisioner_jobs (id) ON DELETE CASCADE,
name varchar(64) NOT NULL,
@ -131,26 +137,28 @@ CREATE TABLE parameter_schemas (
validation_condition varchar(512) NOT NULL,
validation_type_system parameter_type_system NOT NULL,
validation_value_type varchar(64) NOT NULL,
PRIMARY KEY (id),
UNIQUE(job_id, name)
);
-- Parameters are provided to jobs for provisioning and to workspaces.
CREATE TABLE parameter_values (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
scope parameter_scope NOT NULL,
scope_id text NOT NULL,
scope_id uuid NOT NULL,
name varchar(64) NOT NULL,
source_scheme parameter_source_scheme NOT NULL,
source_value text NOT NULL,
destination_scheme parameter_destination_scheme NOT NULL,
PRIMARY KEY (id),
-- Prevents duplicates for parameters in the same scope.
UNIQUE(scope_id, name)
);
CREATE TABLE workspace_builds (
id uuid NOT NULL UNIQUE,
id uuid NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
workspace_id uuid NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE,
@ -159,10 +167,11 @@ CREATE TABLE workspace_builds (
before_id uuid,
after_id uuid,
transition workspace_transition NOT NULL,
initiator varchar(255) NOT NULL,
initiator_id uuid NOT NULL,
-- State stored by the provisioner
provisioner_state bytea,
-- Job ID of the action
job_id uuid NOT NULL UNIQUE REFERENCES provisioner_jobs (id) ON DELETE CASCADE,
PRIMARY KEY (id),
UNIQUE(workspace_id, name)
);

View File

@ -209,26 +209,6 @@ func (e *ProvisionerType) Scan(src interface{}) error {
return nil
}
type UserStatus string
const (
UserstatusActive UserStatus = "active"
UserstatusDormant UserStatus = "dormant"
UserstatusDecommissioned UserStatus = "decommissioned"
)
func (e *UserStatus) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = UserStatus(s)
case string:
*e = UserStatus(s)
default:
return fmt.Errorf("unsupported scan type for UserStatus: %T", src)
}
return nil
}
type WorkspaceTransition string
const (
@ -252,7 +232,7 @@ func (e *WorkspaceTransition) Scan(src interface{}) error {
type APIKey struct {
ID string `db:"id" json:"id"`
HashedSecret []byte `db:"hashed_secret" json:"hashed_secret"`
UserID string `db:"user_id" json:"user_id"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
Application bool `db:"application" json:"application"`
Name string `db:"name" json:"name"`
LastUsed time.Time `db:"last_used" json:"last_used"`
@ -270,7 +250,7 @@ type APIKey struct {
type File struct {
Hash string `db:"hash" json:"hash"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
CreatedBy string `db:"created_by" json:"created_by"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
Mimetype string `db:"mimetype" json:"mimetype"`
Data []byte `db:"data" json:"data"`
}
@ -282,21 +262,16 @@ type License struct {
}
type Organization struct {
ID string `db:"id" json:"id"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Default bool `db:"default" json:"default"`
AutoOffThreshold int64 `db:"auto_off_threshold" json:"auto_off_threshold"`
CpuProvisioningRate float32 `db:"cpu_provisioning_rate" json:"cpu_provisioning_rate"`
MemoryProvisioningRate float32 `db:"memory_provisioning_rate" json:"memory_provisioning_rate"`
WorkspaceAutoOff bool `db:"workspace_auto_off" json:"workspace_auto_off"`
ID uuid.UUID `db:"id" json:"id"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
type OrganizationMember struct {
OrganizationID string `db:"organization_id" json:"organization_id"`
UserID string `db:"user_id" json:"user_id"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Roles []string `db:"roles" json:"roles"`
@ -326,7 +301,7 @@ type ParameterValue struct {
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"`
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
Name string `db:"name" json:"name"`
SourceScheme ParameterSourceScheme `db:"source_scheme" json:"source_scheme"`
SourceValue string `db:"source_value" json:"source_value"`
@ -337,7 +312,7 @@ type Project 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"`
OrganizationID string `db:"organization_id" json:"organization_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
Deleted bool `db:"deleted" json:"deleted"`
Name string `db:"name" json:"name"`
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
@ -347,7 +322,7 @@ type Project struct {
type ProjectVersion struct {
ID uuid.UUID `db:"id" json:"id"`
ProjectID uuid.NullUUID `db:"project_id" json:"project_id"`
OrganizationID string `db:"organization_id" json:"organization_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
@ -359,7 +334,7 @@ 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"`
OrganizationID sql.NullString `db:"organization_id" json:"organization_id"`
OrganizationID uuid.NullUUID `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"`
}
@ -372,8 +347,8 @@ type ProvisionerJob struct {
CanceledAt sql.NullTime `db:"canceled_at" json:"canceled_at"`
CompletedAt sql.NullTime `db:"completed_at" json:"completed_at"`
Error sql.NullString `db:"error" json:"error"`
OrganizationID string `db:"organization_id" json:"organization_id"`
InitiatorID string `db:"initiator_id" json:"initiator_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
StorageMethod ProvisionerStorageMethod `db:"storage_method" json:"storage_method"`
StorageSource string `db:"storage_source" json:"storage_source"`
@ -393,32 +368,22 @@ type ProvisionerJobLog struct {
}
type User struct {
ID string `db:"id" json:"id"`
Email string `db:"email" json:"email"`
Name string `db:"name" json:"name"`
Revoked bool `db:"revoked" json:"revoked"`
LoginType LoginType `db:"login_type" json:"login_type"`
HashedPassword []byte `db:"hashed_password" json:"hashed_password"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
TemporaryPassword bool `db:"temporary_password" json:"temporary_password"`
AvatarHash string `db:"avatar_hash" json:"avatar_hash"`
SshKeyRegeneratedAt time.Time `db:"ssh_key_regenerated_at" json:"ssh_key_regenerated_at"`
Username string `db:"username" json:"username"`
DotfilesGitUri string `db:"dotfiles_git_uri" json:"dotfiles_git_uri"`
Roles []string `db:"roles" json:"roles"`
Status UserStatus `db:"status" json:"status"`
Relatime time.Time `db:"relatime" json:"relatime"`
GpgKeyRegeneratedAt time.Time `db:"gpg_key_regenerated_at" json:"gpg_key_regenerated_at"`
Decomissioned bool `db:"_decomissioned" json:"_decomissioned"`
Shell string `db:"shell" json:"shell"`
ID uuid.UUID `db:"id" json:"id"`
Email string `db:"email" json:"email"`
Name string `db:"name" json:"name"`
Revoked bool `db:"revoked" json:"revoked"`
LoginType LoginType `db:"login_type" json:"login_type"`
HashedPassword []byte `db:"hashed_password" json:"hashed_password"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Username string `db:"username" json:"username"`
}
type Workspace 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"`
OwnerID string `db:"owner_id" json:"owner_id"`
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
ProjectID uuid.UUID `db:"project_id" json:"project_id"`
Deleted bool `db:"deleted" json:"deleted"`
Name string `db:"name" json:"name"`
@ -450,7 +415,7 @@ type WorkspaceBuild struct {
BeforeID uuid.NullUUID `db:"before_id" json:"before_id"`
AfterID uuid.NullUUID `db:"after_id" json:"after_id"`
Transition WorkspaceTransition `db:"transition" json:"transition"`
Initiator string `db:"initiator" json:"initiator"`
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
JobID uuid.UUID `db:"job_id" json:"job_id"`
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"net"
"os"
"strconv"
"sync"
"time"
@ -31,15 +32,18 @@ func Open() (string, func(), error) {
return "", nil, xerrors.Errorf("connect to ci postgres: %w", err)
}
defer db.Close()
dbName, err := cryptorand.StringCharset(cryptorand.Lower, 10)
if err != nil {
return "", nil, xerrors.Errorf("generate db name: %w", err)
}
dbName = "ci" + dbName
_, err = db.Exec("CREATE DATABASE " + dbName)
if err != nil {
return "", nil, xerrors.Errorf("create db: %w", err)
}
return "postgres://postgres:postgres@127.0.0.1:5432/" + dbName + "?sslmode=disable", func() {}, nil
}
@ -59,7 +63,7 @@ func Open() (string, func(), error) {
port, err := getFreePort()
if err != nil {
openPortMutex.Unlock()
return "", nil, xerrors.Errorf("Unable to get free port: %w", err)
return "", nil, xerrors.Errorf("get free port: %w", err)
}
resource, err := pool.RunWithOptions(&dockertest.RunOptions{
@ -80,7 +84,8 @@ func Open() (string, func(), error) {
// https://github.com/moby/moby/issues/42442
// where the ipv4 and ipv6 ports might be _different_ and collide with other running docker containers.
HostIP: "0.0.0.0",
HostPort: fmt.Sprintf("%d", port)}},
HostPort: strconv.FormatInt(int64(port), 10),
}},
},
Mounts: []string{
// The postgres image has a VOLUME parameter in it's image.
@ -107,18 +112,23 @@ func Open() (string, func(), error) {
// Docker should hard-kill the container after 120 seconds.
err = resource.Expire(120)
if err != nil {
return "", nil, xerrors.Errorf("could not expire resource: %w", err)
return "", nil, xerrors.Errorf("expire resource: %w", err)
}
pool.MaxWait = 120 * time.Second
err = pool.Retry(func() error {
db, err := sql.Open("postgres", dbURL)
if err != nil {
return err
return xerrors.Errorf("open postgres: %w", err)
}
defer db.Close()
err = db.Ping()
_ = db.Close()
return err
if err != nil {
return xerrors.Errorf("ping postgres: %w", err)
}
return nil
})
if err != nil {
return "", nil, err

View File

@ -13,10 +13,10 @@ type querier interface {
DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
GetFileByHash(ctx context.Context, hash string) (File, error)
GetOrganizationByID(ctx context.Context, id string) (Organization, error)
GetOrganizationByID(ctx context.Context, id uuid.UUID) (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)
GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error)
GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error)
GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error)
GetParameterValuesByScope(ctx context.Context, arg GetParameterValuesByScopeParams) ([]ParameterValue, error)
@ -34,7 +34,7 @@ type querier interface {
GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID) ([]ProvisionerJob, error)
GetProvisionerLogsByIDBetween(ctx context.Context, arg GetProvisionerLogsByIDBetweenParams) ([]ProvisionerJobLog, error)
GetUserByEmailOrUsername(ctx context.Context, arg GetUserByEmailOrUsernameParams) (User, error)
GetUserByID(ctx context.Context, id string) (User, error)
GetUserByID(ctx context.Context, id uuid.UUID) (User, error)
GetUserCount(ctx context.Context) (int64, error)
GetWorkspaceAgentByAuthToken(ctx context.Context, authToken uuid.UUID) (WorkspaceAgent, error)
GetWorkspaceAgentByInstanceID(ctx context.Context, authInstanceID string) (WorkspaceAgent, error)

View File

@ -683,7 +683,7 @@ INSERT INTO
before_id,
name,
transition,
initiator,
initiator_id,
job_id,
provisioner_state
)

View File

@ -148,14 +148,14 @@ func (q *sqlQuerier) GetFileByHash(ctx context.Context, hash string) (File, erro
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
id, name, description, created_at, updated_at
FROM
organizations
WHERE
id = $1
`
func (q *sqlQuerier) GetOrganizationByID(ctx context.Context, id string) (Organization, error) {
func (q *sqlQuerier) GetOrganizationByID(ctx context.Context, id uuid.UUID) (Organization, error) {
row := q.db.QueryRowContext(ctx, getOrganizationByID, id)
var i Organization
err := row.Scan(
@ -164,18 +164,13 @@ func (q *sqlQuerier) GetOrganizationByID(ctx context.Context, id string) (Organi
&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
id, name, description, created_at, updated_at
FROM
organizations
WHERE
@ -193,18 +188,13 @@ func (q *sqlQuerier) GetOrganizationByName(ctx context.Context, name string) (Or
&i.Description,
&i.CreatedAt,
&i.UpdatedAt,
&i.Default,
&i.AutoOffThreshold,
&i.CpuProvisioningRate,
&i.MemoryProvisioningRate,
&i.WorkspaceAutoOff,
)
return i, err
}
const getOrganizationMemberByUserID = `-- name: GetOrganizationMemberByUserID :one
SELECT
organization_id, user_id, created_at, updated_at, roles
user_id, organization_id, created_at, updated_at, roles
FROM
organization_members
WHERE
@ -215,16 +205,16 @@ LIMIT
`
type GetOrganizationMemberByUserIDParams struct {
OrganizationID string `db:"organization_id" json:"organization_id"`
UserID string `db:"user_id" json:"user_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
}
func (q *sqlQuerier) GetOrganizationMemberByUserID(ctx context.Context, arg GetOrganizationMemberByUserIDParams) (OrganizationMember, error) {
row := q.db.QueryRowContext(ctx, getOrganizationMemberByUserID, arg.OrganizationID, arg.UserID)
var i OrganizationMember
err := row.Scan(
&i.OrganizationID,
&i.UserID,
&i.OrganizationID,
&i.CreatedAt,
&i.UpdatedAt,
pq.Array(&i.Roles),
@ -234,7 +224,7 @@ func (q *sqlQuerier) GetOrganizationMemberByUserID(ctx context.Context, arg GetO
const getOrganizationsByUserID = `-- name: GetOrganizationsByUserID :many
SELECT
id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off
id, name, description, created_at, updated_at
FROM
organizations
WHERE
@ -248,7 +238,7 @@ WHERE
)
`
func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID string) ([]Organization, error) {
func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error) {
rows, err := q.db.QueryContext(ctx, getOrganizationsByUserID, userID)
if err != nil {
return nil, err
@ -263,11 +253,6 @@ func (q *sqlQuerier) GetOrganizationsByUserID(ctx context.Context, userID string
&i.Description,
&i.CreatedAt,
&i.UpdatedAt,
&i.Default,
&i.AutoOffThreshold,
&i.CpuProvisioningRate,
&i.MemoryProvisioningRate,
&i.WorkspaceAutoOff,
); err != nil {
return nil, err
}
@ -346,7 +331,7 @@ LIMIT
type GetParameterValueByScopeAndNameParams struct {
Scope ParameterScope `db:"scope" json:"scope"`
ScopeID string `db:"scope_id" json:"scope_id"`
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
Name string `db:"name" json:"name"`
}
@ -379,7 +364,7 @@ WHERE
type GetParameterValuesByScopeParams struct {
Scope ParameterScope `db:"scope" json:"scope"`
ScopeID string `db:"scope_id" json:"scope_id"`
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
}
func (q *sqlQuerier) GetParameterValuesByScope(ctx context.Context, arg GetParameterValuesByScopeParams) ([]ParameterValue, error) {
@ -456,9 +441,9 @@ LIMIT
`
type GetProjectByOrganizationAndNameParams struct {
OrganizationID string `db:"organization_id" json:"organization_id"`
Deleted bool `db:"deleted" json:"deleted"`
Name string `db:"name" json:"name"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
Deleted bool `db:"deleted" json:"deleted"`
Name string `db:"name" json:"name"`
}
func (q *sqlQuerier) GetProjectByOrganizationAndName(ctx context.Context, arg GetProjectByOrganizationAndNameParams) (Project, error) {
@ -651,8 +636,8 @@ WHERE
`
type GetProjectsByOrganizationParams struct {
OrganizationID string `db:"organization_id" json:"organization_id"`
Deleted bool `db:"deleted" json:"deleted"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
Deleted bool `db:"deleted" json:"deleted"`
}
func (q *sqlQuerier) GetProjectsByOrganization(ctx context.Context, arg GetProjectsByOrganizationParams) ([]Project, error) {
@ -881,7 +866,7 @@ func (q *sqlQuerier) GetProvisionerLogsByIDBetween(ctx context.Context, arg GetP
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
id, email, name, revoked, login_type, hashed_password, created_at, updated_at, username
FROM
users
WHERE
@ -908,24 +893,14 @@ func (q *sqlQuerier) GetUserByEmailOrUsername(ctx context.Context, arg GetUserBy
&i.HashedPassword,
&i.CreatedAt,
&i.UpdatedAt,
&i.TemporaryPassword,
&i.AvatarHash,
&i.SshKeyRegeneratedAt,
&i.Username,
&i.DotfilesGitUri,
pq.Array(&i.Roles),
&i.Status,
&i.Relatime,
&i.GpgKeyRegeneratedAt,
&i.Decomissioned,
&i.Shell,
)
return i, err
}
const getUserByID = `-- name: GetUserByID :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
id, email, name, revoked, login_type, hashed_password, created_at, updated_at, username
FROM
users
WHERE
@ -934,7 +909,7 @@ LIMIT
1
`
func (q *sqlQuerier) GetUserByID(ctx context.Context, id string) (User, error) {
func (q *sqlQuerier) GetUserByID(ctx context.Context, id uuid.UUID) (User, error) {
row := q.db.QueryRowContext(ctx, getUserByID, id)
var i User
err := row.Scan(
@ -946,17 +921,7 @@ func (q *sqlQuerier) GetUserByID(ctx context.Context, id string) (User, error) {
&i.HashedPassword,
&i.CreatedAt,
&i.UpdatedAt,
&i.TemporaryPassword,
&i.AvatarHash,
&i.SshKeyRegeneratedAt,
&i.Username,
&i.DotfilesGitUri,
pq.Array(&i.Roles),
&i.Status,
&i.Relatime,
&i.GpgKeyRegeneratedAt,
&i.Decomissioned,
&i.Shell,
)
return i, err
}
@ -1071,7 +1036,7 @@ func (q *sqlQuerier) GetWorkspaceAgentByResourceID(ctx context.Context, resource
const getWorkspaceBuildByID = `-- name: GetWorkspaceBuildByID :one
SELECT
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator, provisioner_state, job_id
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator_id, provisioner_state, job_id
FROM
workspace_builds
WHERE
@ -1093,7 +1058,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
&i.BeforeID,
&i.AfterID,
&i.Transition,
&i.Initiator,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
)
@ -1102,7 +1067,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
const getWorkspaceBuildByJobID = `-- name: GetWorkspaceBuildByJobID :one
SELECT
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator, provisioner_state, job_id
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator_id, provisioner_state, job_id
FROM
workspace_builds
WHERE
@ -1124,7 +1089,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
&i.BeforeID,
&i.AfterID,
&i.Transition,
&i.Initiator,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
)
@ -1133,7 +1098,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
const getWorkspaceBuildByWorkspaceID = `-- name: GetWorkspaceBuildByWorkspaceID :many
SELECT
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator, provisioner_state, job_id
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator_id, provisioner_state, job_id
FROM
workspace_builds
WHERE
@ -1159,7 +1124,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, workspa
&i.BeforeID,
&i.AfterID,
&i.Transition,
&i.Initiator,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
); err != nil {
@ -1178,7 +1143,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, workspa
const getWorkspaceBuildByWorkspaceIDAndName = `-- name: GetWorkspaceBuildByWorkspaceIDAndName :one
SELECT
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator, provisioner_state, job_id
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator_id, provisioner_state, job_id
FROM
workspace_builds
WHERE
@ -1204,7 +1169,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndName(ctx context.Context,
&i.BeforeID,
&i.AfterID,
&i.Transition,
&i.Initiator,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
)
@ -1213,7 +1178,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndName(ctx context.Context,
const getWorkspaceBuildByWorkspaceIDWithoutAfter = `-- name: GetWorkspaceBuildByWorkspaceIDWithoutAfter :one
SELECT
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator, provisioner_state, job_id
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator_id, provisioner_state, job_id
FROM
workspace_builds
WHERE
@ -1236,7 +1201,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDWithoutAfter(ctx context.Cont
&i.BeforeID,
&i.AfterID,
&i.Transition,
&i.Initiator,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
)
@ -1245,7 +1210,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDWithoutAfter(ctx context.Cont
const getWorkspaceBuildsByWorkspaceIDsWithoutAfter = `-- name: GetWorkspaceBuildsByWorkspaceIDsWithoutAfter :many
SELECT
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator, provisioner_state, job_id
id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator_id, provisioner_state, job_id
FROM
workspace_builds
WHERE
@ -1272,7 +1237,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsByWorkspaceIDsWithoutAfter(ctx context.Co
&i.BeforeID,
&i.AfterID,
&i.Transition,
&i.Initiator,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
); err != nil {
@ -1327,9 +1292,9 @@ WHERE
`
type GetWorkspaceByUserIDAndNameParams struct {
OwnerID string `db:"owner_id" json:"owner_id"`
Deleted bool `db:"deleted" json:"deleted"`
Name string `db:"name" json:"name"`
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
Deleted bool `db:"deleted" json:"deleted"`
Name string `db:"name" json:"name"`
}
func (q *sqlQuerier) GetWorkspaceByUserIDAndName(ctx context.Context, arg GetWorkspaceByUserIDAndNameParams) (Workspace, error) {
@ -1511,8 +1476,8 @@ WHERE
`
type GetWorkspacesByUserIDParams struct {
OwnerID string `db:"owner_id" json:"owner_id"`
Deleted bool `db:"deleted" json:"deleted"`
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
Deleted bool `db:"deleted" json:"deleted"`
}
func (q *sqlQuerier) GetWorkspacesByUserID(ctx context.Context, arg GetWorkspacesByUserIDParams) ([]Workspace, error) {
@ -1588,7 +1553,7 @@ VALUES
type InsertAPIKeyParams struct {
ID string `db:"id" json:"id"`
HashedSecret []byte `db:"hashed_secret" json:"hashed_secret"`
UserID string `db:"user_id" json:"user_id"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
Application bool `db:"application" json:"application"`
Name string `db:"name" json:"name"`
LastUsed time.Time `db:"last_used" json:"last_used"`
@ -1652,7 +1617,7 @@ VALUES
type InsertFileParams struct {
Hash string `db:"hash" json:"hash"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
CreatedBy string `db:"created_by" json:"created_by"`
CreatedBy uuid.UUID `db:"created_by" json:"created_by"`
Mimetype string `db:"mimetype" json:"mimetype"`
Data []byte `db:"data" json:"data"`
}
@ -1680,11 +1645,11 @@ const insertOrganization = `-- name: InsertOrganization :one
INSERT INTO
organizations (id, name, description, created_at, updated_at)
VALUES
($1, $2, $3, $4, $5) RETURNING id, name, description, created_at, updated_at, "default", auto_off_threshold, cpu_provisioning_rate, memory_provisioning_rate, workspace_auto_off
($1, $2, $3, $4, $5) RETURNING id, name, description, created_at, updated_at
`
type InsertOrganizationParams struct {
ID string `db:"id" json:"id"`
ID uuid.UUID `db:"id" json:"id"`
Name string `db:"name" json:"name"`
Description string `db:"description" json:"description"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
@ -1706,11 +1671,6 @@ func (q *sqlQuerier) InsertOrganization(ctx context.Context, arg InsertOrganizat
&i.Description,
&i.CreatedAt,
&i.UpdatedAt,
&i.Default,
&i.AutoOffThreshold,
&i.CpuProvisioningRate,
&i.MemoryProvisioningRate,
&i.WorkspaceAutoOff,
)
return i, err
}
@ -1725,12 +1685,12 @@ INSERT INTO
roles
)
VALUES
($1, $2, $3, $4, $5) RETURNING organization_id, user_id, created_at, updated_at, roles
($1, $2, $3, $4, $5) RETURNING user_id, organization_id, created_at, updated_at, roles
`
type InsertOrganizationMemberParams struct {
OrganizationID string `db:"organization_id" json:"organization_id"`
UserID string `db:"user_id" json:"user_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
UserID uuid.UUID `db:"user_id" json:"user_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Roles []string `db:"roles" json:"roles"`
@ -1746,8 +1706,8 @@ func (q *sqlQuerier) InsertOrganizationMember(ctx context.Context, arg InsertOrg
)
var i OrganizationMember
err := row.Scan(
&i.OrganizationID,
&i.UserID,
&i.OrganizationID,
&i.CreatedAt,
&i.UpdatedAt,
pq.Array(&i.Roles),
@ -1879,7 +1839,7 @@ type InsertParameterValueParams struct {
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"`
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
SourceScheme ParameterSourceScheme `db:"source_scheme" json:"source_scheme"`
SourceValue string `db:"source_value" json:"source_value"`
DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"`
@ -1931,7 +1891,7 @@ type InsertProjectParams 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"`
OrganizationID string `db:"organization_id" json:"organization_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
ActiveVersionID uuid.UUID `db:"active_version_id" json:"active_version_id"`
@ -1980,7 +1940,7 @@ VALUES
type InsertProjectVersionParams struct {
ID uuid.UUID `db:"id" json:"id"`
ProjectID uuid.NullUUID `db:"project_id" json:"project_id"`
OrganizationID string `db:"organization_id" json:"organization_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Name string `db:"name" json:"name"`
@ -2023,7 +1983,7 @@ VALUES
type InsertProvisionerDaemonParams struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
OrganizationID sql.NullString `db:"organization_id" json:"organization_id"`
OrganizationID uuid.NullUUID `db:"organization_id" json:"organization_id"`
Name string `db:"name" json:"name"`
Provisioners []ProvisionerType `db:"provisioners" json:"provisioners"`
}
@ -2070,8 +2030,8 @@ 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"`
OrganizationID string `db:"organization_id" json:"organization_id"`
InitiatorID string `db:"initiator_id" json:"initiator_id"`
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
StorageMethod ProvisionerStorageMethod `db:"storage_method" json:"storage_method"`
StorageSource string `db:"storage_source" json:"storage_source"`
@ -2189,11 +2149,11 @@ INSERT INTO
username
)
VALUES
($1, $2, $3, $4, false, $5, $6, $7, $8) RETURNING 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
($1, $2, $3, $4, false, $5, $6, $7, $8) RETURNING id, email, name, revoked, login_type, hashed_password, created_at, updated_at, username
`
type InsertUserParams struct {
ID string `db:"id" json:"id"`
ID uuid.UUID `db:"id" json:"id"`
Email string `db:"email" json:"email"`
Name string `db:"name" json:"name"`
LoginType LoginType `db:"login_type" json:"login_type"`
@ -2224,17 +2184,7 @@ func (q *sqlQuerier) InsertUser(ctx context.Context, arg InsertUserParams) (User
&i.HashedPassword,
&i.CreatedAt,
&i.UpdatedAt,
&i.TemporaryPassword,
&i.AvatarHash,
&i.SshKeyRegeneratedAt,
&i.Username,
&i.DotfilesGitUri,
pq.Array(&i.Roles),
&i.Status,
&i.Relatime,
&i.GpgKeyRegeneratedAt,
&i.Decomissioned,
&i.Shell,
)
return i, err
}
@ -2257,7 +2207,7 @@ type InsertWorkspaceParams 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"`
OwnerID string `db:"owner_id" json:"owner_id"`
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
ProjectID uuid.UUID `db:"project_id" json:"project_id"`
Name string `db:"name" json:"name"`
}
@ -2358,12 +2308,12 @@ INSERT INTO
before_id,
name,
transition,
initiator,
initiator_id,
job_id,
provisioner_state
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator, provisioner_state, job_id
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, workspace_id, project_version_id, name, before_id, after_id, transition, initiator_id, provisioner_state, job_id
`
type InsertWorkspaceBuildParams struct {
@ -2375,7 +2325,7 @@ type InsertWorkspaceBuildParams struct {
BeforeID uuid.NullUUID `db:"before_id" json:"before_id"`
Name string `db:"name" json:"name"`
Transition WorkspaceTransition `db:"transition" json:"transition"`
Initiator string `db:"initiator" json:"initiator"`
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
JobID uuid.UUID `db:"job_id" json:"job_id"`
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
}
@ -2390,7 +2340,7 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa
arg.BeforeID,
arg.Name,
arg.Transition,
arg.Initiator,
arg.InitiatorID,
arg.JobID,
arg.ProvisionerState,
)
@ -2405,7 +2355,7 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa
&i.BeforeID,
&i.AfterID,
&i.Transition,
&i.Initiator,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
)

View File

@ -19,6 +19,13 @@ func parseUUID(rw http.ResponseWriter, r *http.Request, param string) (uuid.UUID
})
return uuid.UUID{}, false
}
// Automatically set uuid.Nil to the acting users id.
if param == UserKey && rawID == "me" {
key := APIKey(r)
return key.UserID, true
}
parsed, err := uuid.Parse(rawID)
if err != nil {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
@ -26,5 +33,6 @@ func parseUUID(rw http.ResponseWriter, r *http.Request, param string) (uuid.UUID
})
return uuid.UUID{}, false
}
return parsed, true
}

View File

@ -7,8 +7,6 @@ import (
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/httpapi"
)
@ -40,17 +38,15 @@ func OrganizationMemberParam(r *http.Request) database.OrganizationMember {
func ExtractOrganizationParam(db database.Store) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
organizationID := chi.URLParam(r, "organization")
if organizationID == "" {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: "organization must be provided",
})
orgID, ok := parseUUID(rw, r, "organization")
if !ok {
return
}
organization, err := db.GetOrganizationByID(r.Context(), organizationID)
organization, err := db.GetOrganizationByID(r.Context(), orgID)
if errors.Is(err, sql.ErrNoRows) {
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
Message: fmt.Sprintf("organization %q does not exist", organizationID),
Message: fmt.Sprintf("organization %q does not exist", orgID),
})
return
}
@ -60,6 +56,7 @@ func ExtractOrganizationParam(db database.Store) func(http.Handler) http.Handler
})
return
}
apiKey := APIKey(r)
organizationMember, err := db.GetOrganizationMemberByUserID(r.Context(), database.GetOrganizationMemberByUserIDParams{
OrganizationID: organization.ID,

View File

@ -32,10 +32,11 @@ func TestOrganizationParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
ID: userID,
Email: "testaccount@coder.com",
@ -86,7 +87,7 @@ func TestOrganizationParam(t *testing.T) {
r, _ = setupAuthentication(db)
rtr = chi.NewRouter()
)
chi.RouteContext(r.Context()).URLParams.Add("organization", "nothin")
chi.RouteContext(r.Context()).URLParams.Add("organization", uuid.NewString())
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),
@ -98,6 +99,26 @@ func TestOrganizationParam(t *testing.T) {
require.Equal(t, http.StatusNotFound, res.StatusCode)
})
t.Run("InvalidUUID", func(t *testing.T) {
t.Parallel()
var (
db = databasefake.New()
rw = httptest.NewRecorder()
r, _ = setupAuthentication(db)
rtr = chi.NewRouter()
)
chi.RouteContext(r.Context()).URLParams.Add("organization", "not-a-uuid")
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),
)
rtr.Get("/", nil)
rtr.ServeHTTP(rw, r)
res := rw.Result()
defer res.Body.Close()
require.Equal(t, http.StatusBadRequest, res.StatusCode)
})
t.Run("NotInOrganization", func(t *testing.T) {
t.Parallel()
var (
@ -107,13 +128,13 @@ func TestOrganizationParam(t *testing.T) {
rtr = chi.NewRouter()
)
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: uuid.NewString(),
ID: uuid.New(),
Name: "test",
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
})
require.NoError(t, err)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),
@ -134,7 +155,7 @@ func TestOrganizationParam(t *testing.T) {
rtr = chi.NewRouter()
)
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: uuid.NewString(),
ID: uuid.New(),
Name: "test",
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
@ -147,7 +168,7 @@ func TestOrganizationParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID)
chi.RouteContext(r.Context()).URLParams.Add("organization", organization.ID.String())
rtr.Use(
httpmw.ExtractAPIKey(db, nil),
httpmw.ExtractOrganizationParam(db),

View File

@ -46,7 +46,7 @@ func ExtractProjectParam(db database.Store) func(http.Handler) http.Handler {
}
ctx := context.WithValue(r.Context(), projectParamContextKey{}, project)
chi.RouteContext(ctx).URLParams.Add("organization", project.OrganizationID)
chi.RouteContext(ctx).URLParams.Add("organization", project.OrganizationID.String())
next.ServeHTTP(rw, r.WithContext(ctx))
})
}

View File

@ -32,8 +32,8 @@ func TestProjectParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@ -47,6 +47,7 @@ func TestProjectParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@ -55,8 +56,8 @@ func TestProjectParam(t *testing.T) {
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
orgID, err := cryptorand.String(16)
require.NoError(t, err)
orgID := uuid.New()
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: orgID,
Name: "banana",
@ -65,6 +66,7 @@ func TestProjectParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertOrganizationMember(r.Context(), database.InsertOrganizationMemberParams{
OrganizationID: orgID,
UserID: user.ID,

View File

@ -47,7 +47,7 @@ func ExtractProjectVersionParam(db database.Store) func(http.Handler) http.Handl
}
ctx := context.WithValue(r.Context(), projectVersionParamContextKey{}, projectVersion)
chi.RouteContext(ctx).URLParams.Add("organization", projectVersion.OrganizationID)
chi.RouteContext(ctx).URLParams.Add("organization", projectVersion.OrganizationID.String())
next.ServeHTTP(rw, r.WithContext(ctx))
})
}

View File

@ -32,8 +32,8 @@ func TestProjectVersionParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@ -47,6 +47,7 @@ func TestProjectVersionParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@ -55,8 +56,8 @@ func TestProjectVersionParam(t *testing.T) {
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
orgID, err := cryptorand.String(16)
require.NoError(t, err)
orgID := uuid.New()
organization, err := db.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: orgID,
Name: "banana",
@ -65,6 +66,7 @@ func TestProjectVersionParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertOrganizationMember(r.Context(), database.InsertOrganizationMemberParams{
OrganizationID: orgID,
UserID: user.ID,
@ -72,6 +74,7 @@ func TestProjectVersionParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
project, err := db.InsertProject(context.Background(), database.InsertProjectParams{
ID: uuid.New(),
OrganizationID: organization.ID,

View File

@ -5,12 +5,12 @@ import (
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/httpapi"
)
const UserKey = "user"
type userParamContextKey struct{}
// UserParam returns the user from the ExtractUserParam handler.
@ -26,21 +26,20 @@ func UserParam(r *http.Request) database.User {
func ExtractUserParam(db database.Store) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
userID := chi.URLParam(r, "user")
if userID == "" {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: "user id or name must be provided",
})
userID, ok := parseUUID(rw, r, UserKey)
if !ok {
return
}
apiKey := APIKey(r)
if apiKey.UserID != userID && userID != "me" {
if apiKey.UserID != userID {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: "getting non-personal users isn't supported yet",
})
return
}
user, err := db.GetUserByID(r.Context(), apiKey.UserID)
user, err := db.GetUserByID(r.Context(), userID)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("get user: %s", err.Error()),

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
"github.com/coder/coder/coderd/database"
@ -32,18 +33,20 @@ func TestUserParam(t *testing.T) {
Value: fmt.Sprintf("%s-%s", id, secret),
})
_, err := db.InsertUser(r.Context(), database.InsertUserParams{
ID: "bananas",
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
ID: uuid.New(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: "bananas",
UserID: user.ID,
HashedSecret: hashed[:],
LastUsed: database.Now(),
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
return db, rw, r
}
@ -82,7 +85,7 @@ func TestUserParam(t *testing.T) {
require.Equal(t, http.StatusBadRequest, res.StatusCode)
})
t.Run("Me", func(t *testing.T) {
t.Run("me", func(t *testing.T) {
t.Parallel()
db, rw, r := setup(t)

View File

@ -32,8 +32,8 @@ func TestWorkspaceBuildParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@ -47,6 +47,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@ -55,6 +56,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
ExpiresAt: database.Now().Add(time.Minute),
})
require.NoError(t, err)
workspace, err := db.InsertWorkspace(context.Background(), database.InsertWorkspaceParams{
ID: uuid.New(),
ProjectID: uuid.New(),
@ -64,7 +66,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
require.NoError(t, err)
ctx := chi.NewRouteContext()
ctx.URLParams.Add("user", userID)
ctx.URLParams.Add("user", userID.String())
ctx.URLParams.Add("workspace", workspace.Name)
r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx))
return r, workspace

View File

@ -32,8 +32,8 @@ func TestWorkspaceParam(t *testing.T) {
Name: httpmw.AuthCookie,
Value: fmt.Sprintf("%s-%s", id, secret),
})
userID, err := cryptorand.String(16)
require.NoError(t, err)
userID := uuid.New()
username, err := cryptorand.String(8)
require.NoError(t, err)
user, err := db.InsertUser(r.Context(), database.InsertUserParams{
@ -47,6 +47,7 @@ func TestWorkspaceParam(t *testing.T) {
UpdatedAt: database.Now(),
})
require.NoError(t, err)
_, err = db.InsertAPIKey(r.Context(), database.InsertAPIKeyParams{
ID: id,
UserID: user.ID,
@ -105,7 +106,7 @@ func TestWorkspaceParam(t *testing.T) {
r, _ := setup(db)
workspace, err := db.InsertWorkspace(context.Background(), database.InsertWorkspaceParams{
ID: uuid.New(),
OwnerID: "not-me",
OwnerID: uuid.New(),
Name: "hello",
})
require.NoError(t, err)

View File

@ -91,7 +91,7 @@ func (api *api) postProjectVersionsByOrganization(rw http.ResponseWriter, r *htt
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
Scope: database.ParameterScopeImportJob,
ScopeID: jobID.String(),
ScopeID: jobID,
SourceScheme: parameterValue.SourceScheme,
SourceValue: parameterValue.SourceValue,
DestinationScheme: parameterValue.DestinationScheme,
@ -200,10 +200,11 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
var project codersdk.Project
err = api.Database.InTx(func(db database.Store) error {
now := database.Now()
dbProject, err := db.InsertProject(r.Context(), database.InsertProjectParams{
ID: uuid.New(),
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
CreatedAt: now,
UpdatedAt: now,
OrganizationID: organization.ID,
Name: createProject.Name,
Provisioner: importJob.Provisioner,
@ -212,6 +213,7 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
if err != nil {
return xerrors.Errorf("insert project: %s", err)
}
err = db.UpdateProjectVersionByID(r.Context(), database.UpdateProjectVersionByIDParams{
ID: projectVersion.ID,
ProjectID: uuid.NullUUID{
@ -222,6 +224,7 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
if err != nil {
return xerrors.Errorf("insert project version: %s", err)
}
for _, parameterValue := range createProject.ParameterValues {
_, err = db.InsertParameterValue(r.Context(), database.InsertParameterValueParams{
ID: uuid.New(),
@ -229,7 +232,7 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
Scope: database.ParameterScopeProject,
ScopeID: dbProject.ID.String(),
ScopeID: dbProject.ID,
SourceScheme: parameterValue.SourceScheme,
SourceValue: parameterValue.SourceValue,
DestinationScheme: parameterValue.DestinationScheme,
@ -238,6 +241,7 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
return xerrors.Errorf("insert parameter value: %w", err)
}
}
project = convertProject(dbProject, 0)
return nil
})
@ -291,18 +295,20 @@ func (api *api) projectByOrganizationAndName(rw http.ResponseWriter, r *http.Req
OrganizationID: organization.ID,
Name: projectName,
})
if errors.Is(err, sql.ErrNoRows) {
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
Message: fmt.Sprintf("no project found by name %q in the %q organization", projectName, organization.Name),
})
return
}
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
Message: fmt.Sprintf("no project found by name %q in the %q organization", projectName, organization.Name),
})
return
}
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("get project by organization and name: %s", err),
})
return
}
workspaceCounts, err := api.Database.GetWorkspaceOwnerCountsByProjectIDs(r.Context(), []uuid.UUID{project.ID})
if errors.Is(err, sql.ErrNoRows) {
err = nil
@ -313,10 +319,12 @@ func (api *api) projectByOrganizationAndName(rw http.ResponseWriter, r *http.Req
})
return
}
count := uint32(0)
if len(workspaceCounts) > 0 {
count = uint32(workspaceCounts[0].Count)
}
render.Status(r, http.StatusOK)
render.JSON(rw, r, convertProject(project, count))
}

View File

@ -19,7 +19,7 @@ func TestProvisionerDaemonsByOrganization(t *testing.T) {
t.Run("NoAuth", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
_, err := client.ProvisionerDaemonsByOrganization(context.Background(), "someorg")
_, err := client.ProvisionerDaemonsByOrganization(context.Background(), uuid.New())
require.Error(t, err)
})

View File

@ -14,8 +14,8 @@ import (
// ComputeScope targets identifiers to pull parameters from.
type ComputeScope struct {
ProjectImportJobID uuid.UUID
OrganizationID string
UserID string
OrganizationID uuid.UUID
UserID uuid.UUID
ProjectID uuid.NullUUID
WorkspaceID uuid.NullUUID
}
@ -71,7 +71,7 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options
// Job parameters come second!
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
Scope: database.ParameterScopeImportJob,
ScopeID: scope.ProjectImportJobID.String(),
ScopeID: scope.ProjectImportJobID,
})
if err != nil {
return nil, err
@ -101,7 +101,7 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options
DestinationScheme: parameterSchema.DefaultDestinationScheme,
SourceValue: parameterSchema.DefaultSourceValue,
Scope: database.ParameterScopeImportJob,
ScopeID: scope.ProjectImportJobID.String(),
ScopeID: scope.ProjectImportJobID,
}, true)
if err != nil {
return nil, xerrors.Errorf("insert default value: %w", err)
@ -115,7 +115,7 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options
// Project parameters come third!
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
Scope: database.ParameterScopeProject,
ScopeID: scope.ProjectID.UUID.String(),
ScopeID: scope.ProjectID.UUID,
})
if err != nil {
return nil, err
@ -135,7 +135,7 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options
// Workspace parameters come last!
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
Scope: database.ParameterScopeWorkspace,
ScopeID: scope.WorkspaceID.UUID.String(),
ScopeID: scope.WorkspaceID.UUID,
})
if err != nil {
return nil, err

View File

@ -18,7 +18,7 @@ func TestCompute(t *testing.T) {
generateScope := func() parameter.ComputeScope {
return parameter.ComputeScope{
ProjectImportJobID: uuid.New(),
OrganizationID: uuid.NewString(),
OrganizationID: uuid.New(),
ProjectID: uuid.NullUUID{
UUID: uuid.New(),
Valid: true,
@ -27,7 +27,7 @@ func TestCompute(t *testing.T) {
UUID: uuid.New(),
Valid: true,
},
UserID: uuid.NewString(),
UserID: uuid.New(),
}
}
type parameterOptions struct {
@ -88,7 +88,7 @@ func TestCompute(t *testing.T) {
computedValue := computed[0]
require.True(t, computedValue.DefaultSourceValue)
require.Equal(t, database.ParameterScopeImportJob, computedValue.Scope)
require.Equal(t, scope.ProjectImportJobID.String(), computedValue.ScopeID)
require.Equal(t, scope.ProjectImportJobID, computedValue.ScopeID)
require.Equal(t, computedValue.SourceValue, parameterSchema.DefaultSourceValue)
})
@ -114,7 +114,7 @@ func TestCompute(t *testing.T) {
ID: uuid.New(),
Name: parameterSchema.Name,
Scope: database.ParameterScopeImportJob,
ScopeID: scope.ProjectImportJobID.String(),
ScopeID: scope.ProjectImportJobID,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: "secondnop",
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
@ -139,7 +139,7 @@ func TestCompute(t *testing.T) {
ID: uuid.New(),
Name: parameterSchema.Name,
Scope: database.ParameterScopeProject,
ScopeID: scope.ProjectID.UUID.String(),
ScopeID: scope.ProjectID.UUID,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: "nop",
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
@ -160,11 +160,12 @@ func TestCompute(t *testing.T) {
parameterSchema := generateParameter(t, db, parameterOptions{
ProjectImportJobID: scope.ProjectImportJobID,
})
_, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
ID: uuid.New(),
Name: parameterSchema.Name,
Scope: database.ParameterScopeWorkspace,
ScopeID: scope.WorkspaceID.UUID.String(),
ScopeID: scope.WorkspaceID.UUID,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: "nop",
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
@ -189,7 +190,7 @@ func TestCompute(t *testing.T) {
ID: uuid.New(),
Name: parameterSchema.Name,
Scope: database.ParameterScopeWorkspace,
ScopeID: scope.WorkspaceID.UUID.String(),
ScopeID: scope.WorkspaceID.UUID,
SourceScheme: database.ParameterSourceSchemeData,
SourceValue: "nop",
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,

View File

@ -138,7 +138,7 @@ func convertParameterValue(parameterValue database.ParameterValue) codersdk.Para
}
}
func readScopeAndID(rw http.ResponseWriter, r *http.Request) (database.ParameterScope, string, bool) {
func readScopeAndID(rw http.ResponseWriter, r *http.Request) (database.ParameterScope, uuid.UUID, bool) {
var scope database.ParameterScope
switch chi.URLParam(r, "scope") {
case string(codersdk.ParameterOrganization):
@ -153,8 +153,17 @@ func readScopeAndID(rw http.ResponseWriter, r *http.Request) (database.Parameter
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: fmt.Sprintf("invalid scope %q", scope),
})
return scope, "", false
return scope, uuid.Nil, false
}
return scope, chi.URLParam(r, "id"), true
id := chi.URLParam(r, "id")
uid, err := uuid.Parse(id)
if err != nil {
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
Message: fmt.Sprintf("invalid uuid %q: %s", id, err),
})
return scope, uuid.Nil, false
}
return scope, uid, true
}

View File

@ -47,7 +47,7 @@ func TestDeleteProject(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
coderdtest.CreateWorkspace(t, client, "me", project.ID)
coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
err := client.DeleteProject(context.Background(), project.ID)
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)

View File

@ -9,6 +9,7 @@ import (
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/provisioner/echo"
"github.com/coder/coder/provisionersdk/proto"
)
@ -37,7 +38,7 @@ func TestProvisionerJobLogs(t *testing.T) {
})
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
before := time.Now().UTC()
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
@ -75,7 +76,7 @@ func TestProvisionerJobLogs(t *testing.T) {
})
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
before := database.Now()
ctx, cancelFunc := context.WithCancel(context.Background())
t.Cleanup(cancelFunc)
@ -111,7 +112,7 @@ func TestProvisionerJobLogs(t *testing.T) {
})
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
logs, err := client.WorkspaceBuildLogsBefore(context.Background(), workspace.LatestBuild.ID, time.Now())
require.NoError(t, err)

View File

@ -32,12 +32,14 @@ func (api *api) firstUser(rw http.ResponseWriter, r *http.Request) {
})
return
}
if userCount == 0 {
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
Message: "The initial user has not been created!",
})
return
}
httpapi.Write(rw, http.StatusOK, httpapi.Response{
Message: "The initial user has already been created!",
})
@ -49,6 +51,7 @@ func (api *api) postFirstUser(rw http.ResponseWriter, r *http.Request) {
if !httpapi.Read(rw, r, &createUser) {
return
}
// This should only function for the first user.
userCount, err := api.Database.GetUserCount(r.Context())
if err != nil {
@ -57,6 +60,7 @@ func (api *api) postFirstUser(rw http.ResponseWriter, r *http.Request) {
})
return
}
// If a user already exists, the initial admin user no longer can be created.
if userCount != 0 {
httpapi.Write(rw, http.StatusConflict, httpapi.Response{
@ -64,6 +68,7 @@ func (api *api) postFirstUser(rw http.ResponseWriter, r *http.Request) {
})
return
}
hashedPassword, err := userpassword.Hash(createUser.Password)
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
@ -77,7 +82,7 @@ func (api *api) postFirstUser(rw http.ResponseWriter, r *http.Request) {
var organization database.Organization
err = api.Database.InTx(func(s database.Store) error {
user, err = api.Database.InsertUser(r.Context(), database.InsertUserParams{
ID: uuid.NewString(),
ID: uuid.New(),
Email: createUser.Email,
HashedPassword: []byte(hashedPassword),
Username: createUser.Username,
@ -89,8 +94,8 @@ func (api *api) postFirstUser(rw http.ResponseWriter, r *http.Request) {
return xerrors.Errorf("create user: %w", err)
}
organization, err = api.Database.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: uuid.NewString(),
Name: createUser.Organization,
ID: uuid.New(),
Name: createUser.OrganizationName,
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
})
@ -190,7 +195,7 @@ func (api *api) postUsers(rw http.ResponseWriter, r *http.Request) {
var user database.User
err = api.Database.InTx(func(db database.Store) error {
user, err = db.InsertUser(r.Context(), database.InsertUserParams{
ID: uuid.NewString(),
ID: uuid.New(),
Email: createUser.Email,
HashedPassword: []byte(hashedPassword),
Username: createUser.Username,
@ -317,7 +322,7 @@ func (api *api) postOrganizationsByUser(rw http.ResponseWriter, r *http.Request)
var organization database.Organization
err = api.Database.InTx(func(db database.Store) error {
organization, err = api.Database.InsertOrganization(r.Context(), database.InsertOrganizationParams{
ID: uuid.NewString(),
ID: uuid.New(),
Name: req.Name,
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
@ -611,7 +616,7 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
CreatedAt: database.Now(),
UpdatedAt: database.Now(),
Scope: database.ParameterScopeWorkspace,
ScopeID: workspace.ID.String(),
ScopeID: workspace.ID,
SourceScheme: parameterValue.SourceScheme,
SourceValue: parameterValue.SourceValue,
DestinationScheme: parameterValue.DestinationScheme,
@ -649,7 +654,7 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
WorkspaceID: workspace.ID,
ProjectVersionID: projectVersion.ID,
Name: namesgenerator.GetRandomName(1),
Initiator: apiKey.UserID,
InitiatorID: apiKey.UserID,
Transition: database.WorkspaceTransitionStart,
JobID: provisionerJob.ID,
})
@ -725,35 +730,35 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
return
}
buildByWorkspaceID := map[string]database.WorkspaceBuild{}
buildByWorkspaceID := map[uuid.UUID]database.WorkspaceBuild{}
for _, workspaceBuild := range workspaceBuilds {
buildByWorkspaceID[workspaceBuild.WorkspaceID.String()] = workspaceBuild
buildByWorkspaceID[workspaceBuild.WorkspaceID] = workspaceBuild
}
projectByID := map[string]database.Project{}
projectByID := map[uuid.UUID]database.Project{}
for _, project := range projects {
projectByID[project.ID.String()] = project
projectByID[project.ID] = project
}
jobByID := map[string]database.ProvisionerJob{}
jobByID := map[uuid.UUID]database.ProvisionerJob{}
for _, job := range jobs {
jobByID[job.ID.String()] = job
jobByID[job.ID] = job
}
apiWorkspaces := make([]codersdk.Workspace, 0, len(workspaces))
for _, workspace := range workspaces {
build, exists := buildByWorkspaceID[workspace.ID.String()]
build, exists := buildByWorkspaceID[workspace.ID]
if !exists {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("build not found for workspace %q", workspace.Name),
})
return
}
project, exists := projectByID[workspace.ProjectID.String()]
project, exists := projectByID[workspace.ProjectID]
if !exists {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("project not found for workspace %q", workspace.Name),
})
return
}
job, exists := jobByID[build.JobID.String()]
job, exists := jobByID[build.JobID]
if !exists {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
Message: fmt.Sprintf("build job not found for workspace %q", workspace.Name),

View File

@ -27,10 +27,10 @@ func TestFirstUser(t *testing.T) {
client := coderdtest.New(t, nil)
_ = coderdtest.CreateFirstUser(t, client)
_, err := client.CreateFirstUser(context.Background(), codersdk.CreateFirstUserRequest{
Email: "some@email.com",
Username: "exampleuser",
Password: "password",
Organization: "someorg",
Email: "some@email.com",
Username: "exampleuser",
Password: "password",
OrganizationName: "someorg",
})
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
@ -62,10 +62,10 @@ func TestPostLogin(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
req := codersdk.CreateFirstUserRequest{
Email: "testuser@coder.com",
Username: "testuser",
Password: "testpass",
Organization: "testorg",
Email: "testuser@coder.com",
Username: "testuser",
Password: "testpass",
OrganizationName: "testorg",
}
_, err := client.CreateFirstUser(context.Background(), req)
require.NoError(t, err)
@ -82,10 +82,10 @@ func TestPostLogin(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
req := codersdk.CreateFirstUserRequest{
Email: "testuser@coder.com",
Username: "testuser",
Password: "testpass",
Organization: "testorg",
Email: "testuser@coder.com",
Username: "testuser",
Password: "testpass",
OrganizationName: "testorg",
}
_, err := client.CreateFirstUser(context.Background(), req)
require.NoError(t, err)
@ -137,13 +137,13 @@ func TestPostUsers(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
me, err := client.User(context.Background(), "")
me, err := client.User(context.Background(), codersdk.Me)
require.NoError(t, err)
_, err = client.CreateUser(context.Background(), codersdk.CreateUserRequest{
Email: me.Email,
Username: me.Username,
Password: "password",
OrganizationID: "someorg",
OrganizationID: uuid.New(),
})
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
@ -155,7 +155,7 @@ func TestPostUsers(t *testing.T) {
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
_, err := client.CreateUser(context.Background(), codersdk.CreateUserRequest{
OrganizationID: "not-exists",
OrganizationID: uuid.New(),
Email: "another@user.org",
Username: "someone-else",
Password: "testing",
@ -170,7 +170,7 @@ func TestPostUsers(t *testing.T) {
client := coderdtest.New(t, nil)
first := coderdtest.CreateFirstUser(t, client)
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
org, err := other.CreateOrganization(context.Background(), "", codersdk.CreateOrganizationRequest{
org, err := other.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
Name: "another",
})
require.NoError(t, err)
@ -204,7 +204,7 @@ func TestUserByName(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
_ = coderdtest.CreateFirstUser(t, client)
_, err := client.User(context.Background(), "")
_, err := client.User(context.Background(), codersdk.Me)
require.NoError(t, err)
}
@ -212,7 +212,7 @@ func TestOrganizationsByUser(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
_ = coderdtest.CreateFirstUser(t, client)
orgs, err := client.OrganizationsByUser(context.Background(), "")
orgs, err := client.OrganizationsByUser(context.Background(), codersdk.Me)
require.NoError(t, err)
require.NotNil(t, orgs)
require.Len(t, orgs, 1)
@ -224,7 +224,7 @@ func TestOrganizationByUserAndName(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
_, err := client.OrganizationByName(context.Background(), "", "nothing")
_, err := client.OrganizationByName(context.Background(), codersdk.Me, "nothing")
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
@ -235,11 +235,11 @@ func TestOrganizationByUserAndName(t *testing.T) {
client := coderdtest.New(t, nil)
first := coderdtest.CreateFirstUser(t, client)
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
org, err := other.CreateOrganization(context.Background(), "", codersdk.CreateOrganizationRequest{
org, err := other.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
Name: "another",
})
require.NoError(t, err)
_, err = client.OrganizationByName(context.Background(), "", org.Name)
_, err = client.OrganizationByName(context.Background(), codersdk.Me, org.Name)
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
@ -251,7 +251,7 @@ func TestOrganizationByUserAndName(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
org, err := client.Organization(context.Background(), user.OrganizationID)
require.NoError(t, err)
_, err = client.OrganizationByName(context.Background(), "", org.Name)
_, err = client.OrganizationByName(context.Background(), codersdk.Me, org.Name)
require.NoError(t, err)
})
}
@ -264,7 +264,7 @@ func TestPostOrganizationsByUser(t *testing.T) {
user := coderdtest.CreateFirstUser(t, client)
org, err := client.Organization(context.Background(), user.OrganizationID)
require.NoError(t, err)
_, err = client.CreateOrganization(context.Background(), "", codersdk.CreateOrganizationRequest{
_, err = client.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
Name: org.Name,
})
var apiErr *codersdk.Error
@ -276,7 +276,7 @@ func TestPostOrganizationsByUser(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
_ = coderdtest.CreateFirstUser(t, client)
_, err := client.CreateOrganization(context.Background(), "", codersdk.CreateOrganizationRequest{
_, err := client.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
Name: "new",
})
require.NoError(t, err)
@ -291,7 +291,7 @@ func TestPostAPIKey(t *testing.T) {
_ = coderdtest.CreateFirstUser(t, client)
client.SessionToken = ""
_, err := client.CreateAPIKey(context.Background(), "")
_, err := client.CreateAPIKey(context.Background(), codersdk.Me)
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
@ -301,7 +301,7 @@ func TestPostAPIKey(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
_ = coderdtest.CreateFirstUser(t, client)
apiKey, err := client.CreateAPIKey(context.Background(), "")
apiKey, err := client.CreateAPIKey(context.Background(), codersdk.Me)
require.NotNil(t, apiKey)
require.GreaterOrEqual(t, len(apiKey.Key), 2)
require.NoError(t, err)
@ -314,7 +314,7 @@ func TestPostWorkspacesByUser(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
_ = coderdtest.CreateFirstUser(t, client)
_, err := client.CreateWorkspace(context.Background(), "", codersdk.CreateWorkspaceRequest{
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
ProjectID: uuid.New(),
Name: "workspace",
})
@ -330,14 +330,14 @@ func TestPostWorkspacesByUser(t *testing.T) {
first := coderdtest.CreateFirstUser(t, client)
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
org, err := other.CreateOrganization(context.Background(), "", codersdk.CreateOrganizationRequest{
org, err := other.CreateOrganization(context.Background(), codersdk.Me, codersdk.CreateOrganizationRequest{
Name: "another",
})
require.NoError(t, err)
version := coderdtest.CreateProjectVersion(t, other, org.ID, nil)
project := coderdtest.CreateProject(t, other, org.ID, version.ID)
_, err = client.CreateWorkspace(context.Background(), "", codersdk.CreateWorkspaceRequest{
_, err = client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
ProjectID: project.ID,
Name: "workspace",
})
@ -355,8 +355,8 @@ func TestPostWorkspacesByUser(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
_, err := client.CreateWorkspace(context.Background(), "", codersdk.CreateWorkspaceRequest{
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
ProjectID: project.ID,
Name: workspace.Name,
})
@ -374,7 +374,7 @@ func TestPostWorkspacesByUser(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
_ = coderdtest.CreateWorkspace(t, client, "", project.ID)
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
})
}
@ -384,7 +384,7 @@ func TestWorkspacesByUser(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
_, err := client.WorkspacesByUser(context.Background(), "")
_, err := client.WorkspacesByUser(context.Background(), codersdk.Me)
require.NoError(t, err)
})
t.Run("List", func(t *testing.T) {
@ -395,8 +395,8 @@ func TestWorkspacesByUser(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
_ = coderdtest.CreateWorkspace(t, client, "", project.ID)
workspaces, err := client.WorkspacesByUser(context.Background(), "")
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
workspaces, err := client.WorkspacesByUser(context.Background(), codersdk.Me)
require.NoError(t, err)
require.Len(t, workspaces, 1)
})
@ -408,7 +408,7 @@ func TestWorkspaceByUserAndName(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
_, err := client.WorkspaceByName(context.Background(), "", "something")
_, err := client.WorkspaceByName(context.Background(), codersdk.Me, "something")
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
@ -421,8 +421,8 @@ func TestWorkspaceByUserAndName(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
_, err := client.WorkspaceByName(context.Background(), "", workspace.Name)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.WorkspaceByName(context.Background(), codersdk.Me, workspace.Name)
require.NoError(t, err)
})
}

View File

@ -101,7 +101,7 @@ func convertWorkspaceBuild(workspaceBuild database.WorkspaceBuild, job codersdk.
AfterID: workspaceBuild.AfterID.UUID,
Name: workspaceBuild.Name,
Transition: workspaceBuild.Transition,
Initiator: workspaceBuild.Initiator,
InitiatorID: workspaceBuild.InitiatorID,
Job: job,
}
}

View File

@ -22,7 +22,7 @@ func TestWorkspaceBuild(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.WorkspaceBuild(context.Background(), workspace.LatestBuild.ID)
require.NoError(t, err)
}
@ -43,7 +43,7 @@ func TestPatchCancelWorkspaceBuild(t *testing.T) {
})
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
var build codersdk.WorkspaceBuild
require.Eventually(t, func() bool {
var err error
@ -72,7 +72,7 @@ func TestWorkspaceBuildResources(t *testing.T) {
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
closeDaemon.Close()
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.WorkspaceResourcesByBuild(context.Background(), workspace.LatestBuild.ID)
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
@ -105,7 +105,7 @@ func TestWorkspaceBuildResources(t *testing.T) {
})
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
resources, err := client.WorkspaceResourcesByBuild(context.Background(), workspace.LatestBuild.ID)
require.NoError(t, err)
@ -152,7 +152,7 @@ func TestWorkspaceBuildLogs(t *testing.T) {
})
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
ctx, cancelFunc := context.WithCancel(context.Background())
t.Cleanup(cancelFunc)
logs, err := client.WorkspaceBuildLogsAfter(ctx, workspace.LatestBuild.ID, before)

View File

@ -44,7 +44,7 @@ func TestPostWorkspaceAuthAWSInstanceIdentity(t *testing.T) {
})
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
client.HTTPClient = metadataClient
@ -110,7 +110,7 @@ func TestPostWorkspaceAuthGoogleInstanceIdentity(t *testing.T) {
})
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
_, err := client.AuthWorkspaceGoogleInstanceIdentity(context.Background(), "", metadata)

View File

@ -44,7 +44,7 @@ func TestWorkspaceResource(t *testing.T) {
})
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
resources, err := client.WorkspaceResourcesByBuild(context.Background(), workspace.LatestBuild.ID)
require.NoError(t, err)
@ -81,7 +81,7 @@ func TestWorkspaceAgentListen(t *testing.T) {
})
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
daemonCloser.Close()

View File

@ -222,7 +222,7 @@ func (api *api) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
BeforeID: priorHistoryID,
Name: namesgenerator.GetRandomName(1),
ProvisionerState: priorHistory.ProvisionerState,
Initiator: apiKey.UserID,
InitiatorID: apiKey.UserID,
Transition: createBuild.Transition,
JobID: provisionerJob.ID,
})

View File

@ -23,7 +23,7 @@ func TestWorkspace(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.Workspace(context.Background(), workspace.ID)
require.NoError(t, err)
}
@ -38,7 +38,7 @@ func TestWorkspaceBuilds(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.WorkspaceBuilds(context.Background(), workspace.ID)
require.NoError(t, err)
})
@ -54,7 +54,7 @@ func TestPostWorkspaceBuild(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
ProjectVersionID: uuid.New(),
Transition: database.WorkspaceTransitionStart,
@ -75,7 +75,7 @@ func TestPostWorkspaceBuild(t *testing.T) {
})
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
_, err := client.CreateWorkspace(context.Background(), "", codersdk.CreateWorkspaceRequest{
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
ProjectID: project.ID,
Name: "workspace",
})
@ -94,7 +94,7 @@ func TestPostWorkspaceBuild(t *testing.T) {
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
// Close here so workspace build doesn't process!
closeDaemon.Close()
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
ProjectVersionID: project.ActiveVersionID,
Transition: database.WorkspaceTransitionStart,
@ -113,7 +113,7 @@ func TestPostWorkspaceBuild(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
build, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
ProjectVersionID: project.ActiveVersionID,
@ -135,7 +135,7 @@ func TestPostWorkspaceBuild(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
build, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
Transition: database.WorkspaceTransitionDelete,
@ -160,7 +160,7 @@ func TestWorkspaceBuildByName(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
_, err := client.WorkspaceBuildByName(context.Background(), workspace.ID, "something")
var apiErr *codersdk.Error
require.ErrorAs(t, err, &apiErr)
@ -175,7 +175,7 @@ func TestWorkspaceBuildByName(t *testing.T) {
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID)
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
build, err := client.WorkspaceBuild(context.Background(), workspace.LatestBuild.ID)
require.NoError(t, err)
_, err = client.WorkspaceBuildByName(context.Background(), workspace.ID, build.Name)