mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
feat: Add backend API support for resource metadata (#3242)
* Initial support for metadata in provisioner API and Terraform provisioner * add support for nullable metadata fields * handle metadata fields in provisionerd and API
This commit is contained in:
@ -26,21 +26,22 @@ func New() database.Store {
|
||||
organizations: make([]database.Organization, 0),
|
||||
users: make([]database.User, 0),
|
||||
|
||||
auditLogs: make([]database.AuditLog, 0),
|
||||
files: make([]database.File, 0),
|
||||
gitSSHKey: make([]database.GitSSHKey, 0),
|
||||
parameterSchemas: make([]database.ParameterSchema, 0),
|
||||
parameterValues: make([]database.ParameterValue, 0),
|
||||
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
|
||||
provisionerJobAgents: make([]database.WorkspaceAgent, 0),
|
||||
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
|
||||
provisionerJobResources: make([]database.WorkspaceResource, 0),
|
||||
provisionerJobs: make([]database.ProvisionerJob, 0),
|
||||
templateVersions: make([]database.TemplateVersion, 0),
|
||||
templates: make([]database.Template, 0),
|
||||
workspaceBuilds: make([]database.WorkspaceBuild, 0),
|
||||
workspaceApps: make([]database.WorkspaceApp, 0),
|
||||
workspaces: make([]database.Workspace, 0),
|
||||
auditLogs: make([]database.AuditLog, 0),
|
||||
files: make([]database.File, 0),
|
||||
gitSSHKey: make([]database.GitSSHKey, 0),
|
||||
parameterSchemas: make([]database.ParameterSchema, 0),
|
||||
parameterValues: make([]database.ParameterValue, 0),
|
||||
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
|
||||
provisionerJobAgents: make([]database.WorkspaceAgent, 0),
|
||||
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
|
||||
provisionerJobResources: make([]database.WorkspaceResource, 0),
|
||||
provisionerJobResourceMetadata: make([]database.WorkspaceResourceMetadatum, 0),
|
||||
provisionerJobs: make([]database.ProvisionerJob, 0),
|
||||
templateVersions: make([]database.TemplateVersion, 0),
|
||||
templates: make([]database.Template, 0),
|
||||
workspaceBuilds: make([]database.WorkspaceBuild, 0),
|
||||
workspaceApps: make([]database.WorkspaceApp, 0),
|
||||
workspaces: make([]database.Workspace, 0),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -74,21 +75,22 @@ type data struct {
|
||||
users []database.User
|
||||
|
||||
// New tables
|
||||
auditLogs []database.AuditLog
|
||||
files []database.File
|
||||
gitSSHKey []database.GitSSHKey
|
||||
parameterSchemas []database.ParameterSchema
|
||||
parameterValues []database.ParameterValue
|
||||
provisionerDaemons []database.ProvisionerDaemon
|
||||
provisionerJobAgents []database.WorkspaceAgent
|
||||
provisionerJobLogs []database.ProvisionerJobLog
|
||||
provisionerJobResources []database.WorkspaceResource
|
||||
provisionerJobs []database.ProvisionerJob
|
||||
templateVersions []database.TemplateVersion
|
||||
templates []database.Template
|
||||
workspaceBuilds []database.WorkspaceBuild
|
||||
workspaceApps []database.WorkspaceApp
|
||||
workspaces []database.Workspace
|
||||
auditLogs []database.AuditLog
|
||||
files []database.File
|
||||
gitSSHKey []database.GitSSHKey
|
||||
parameterSchemas []database.ParameterSchema
|
||||
parameterValues []database.ParameterValue
|
||||
provisionerDaemons []database.ProvisionerDaemon
|
||||
provisionerJobAgents []database.WorkspaceAgent
|
||||
provisionerJobLogs []database.ProvisionerJobLog
|
||||
provisionerJobResources []database.WorkspaceResource
|
||||
provisionerJobResourceMetadata []database.WorkspaceResourceMetadatum
|
||||
provisionerJobs []database.ProvisionerJob
|
||||
templateVersions []database.TemplateVersion
|
||||
templates []database.Template
|
||||
workspaceBuilds []database.WorkspaceBuild
|
||||
workspaceApps []database.WorkspaceApp
|
||||
workspaces []database.Workspace
|
||||
|
||||
deploymentID string
|
||||
}
|
||||
@ -1331,6 +1333,34 @@ func (q *fakeQuerier) GetWorkspaceResourcesCreatedAfter(_ context.Context, after
|
||||
return resources, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetWorkspaceResourceMetadataByResourceID(_ context.Context, id uuid.UUID) ([]database.WorkspaceResourceMetadatum, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
metadata := make([]database.WorkspaceResourceMetadatum, 0)
|
||||
for _, metadatum := range q.provisionerJobResourceMetadata {
|
||||
if metadatum.WorkspaceResourceID.String() == id.String() {
|
||||
metadata = append(metadata, metadatum)
|
||||
}
|
||||
}
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetWorkspaceResourceMetadataByResourceIDs(_ context.Context, ids []uuid.UUID) ([]database.WorkspaceResourceMetadatum, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
metadata := make([]database.WorkspaceResourceMetadatum, 0)
|
||||
for _, metadatum := range q.provisionerJobResourceMetadata {
|
||||
for _, id := range ids {
|
||||
if metadatum.WorkspaceResourceID.String() == id.String() {
|
||||
metadata = append(metadata, metadatum)
|
||||
}
|
||||
}
|
||||
}
|
||||
return metadata, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProvisionerJobsByIDs(_ context.Context, ids []uuid.UUID) ([]database.ProvisionerJob, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
@ -1659,6 +1689,21 @@ func (q *fakeQuerier) InsertWorkspaceResource(_ context.Context, arg database.In
|
||||
return resource, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertWorkspaceResourceMetadata(_ context.Context, arg database.InsertWorkspaceResourceMetadataParams) (database.WorkspaceResourceMetadatum, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
//nolint:gosimple
|
||||
metadatum := database.WorkspaceResourceMetadatum{
|
||||
WorkspaceResourceID: arg.WorkspaceResourceID,
|
||||
Key: arg.Key,
|
||||
Value: arg.Value,
|
||||
Sensitive: arg.Sensitive,
|
||||
}
|
||||
q.provisionerJobResourceMetadata = append(q.provisionerJobResourceMetadata, metadatum)
|
||||
return metadatum, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertUser(_ context.Context, arg database.InsertUserParams) (database.User, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
13
coderd/database/dump.sql
generated
13
coderd/database/dump.sql
generated
@ -328,6 +328,13 @@ CREATE TABLE workspace_builds (
|
||||
reason build_reason DEFAULT 'initiator'::public.build_reason NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_resource_metadata (
|
||||
workspace_resource_id uuid NOT NULL,
|
||||
key character varying(1024) NOT NULL,
|
||||
value character varying(65536),
|
||||
sensitive boolean NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE workspace_resources (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
@ -433,6 +440,9 @@ ALTER TABLE ONLY workspace_builds
|
||||
ALTER TABLE ONLY workspace_builds
|
||||
ADD CONSTRAINT workspace_builds_workspace_id_name_key UNIQUE (workspace_id, name);
|
||||
|
||||
ALTER TABLE ONLY workspace_resource_metadata
|
||||
ADD CONSTRAINT workspace_resource_metadata_pkey PRIMARY KEY (workspace_resource_id, key);
|
||||
|
||||
ALTER TABLE ONLY workspace_resources
|
||||
ADD CONSTRAINT workspace_resources_pkey PRIMARY KEY (id);
|
||||
|
||||
@ -518,6 +528,9 @@ ALTER TABLE ONLY workspace_builds
|
||||
ALTER TABLE ONLY workspace_builds
|
||||
ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_resource_metadata
|
||||
ADD CONSTRAINT workspace_resource_metadata_workspace_resource_id_fkey FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_resources
|
||||
ADD CONSTRAINT workspace_resources_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS workspace_resource_metadata;
|
@ -0,0 +1,8 @@
|
||||
CREATE TABLE IF NOT EXISTS workspace_resource_metadata (
|
||||
workspace_resource_id uuid NOT NULL,
|
||||
key varchar(1024) NOT NULL,
|
||||
value varchar(65536),
|
||||
sensitive boolean NOT NULL,
|
||||
PRIMARY KEY (workspace_resource_id, key),
|
||||
FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resources (id) ON DELETE CASCADE
|
||||
);
|
@ -564,3 +564,10 @@ type WorkspaceResource struct {
|
||||
Type string `db:"type" json:"type"`
|
||||
Name string `db:"name" json:"name"`
|
||||
}
|
||||
|
||||
type WorkspaceResourceMetadatum struct {
|
||||
WorkspaceResourceID uuid.UUID `db:"workspace_resource_id" json:"workspace_resource_id"`
|
||||
Key string `db:"key" json:"key"`
|
||||
Value sql.NullString `db:"value" json:"value"`
|
||||
Sensitive bool `db:"sensitive" json:"sensitive"`
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ type querier interface {
|
||||
GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (Workspace, error)
|
||||
GetWorkspaceOwnerCountsByTemplateIDs(ctx context.Context, ids []uuid.UUID) ([]GetWorkspaceOwnerCountsByTemplateIDsRow, error)
|
||||
GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID) (WorkspaceResource, error)
|
||||
GetWorkspaceResourceMetadataByResourceID(ctx context.Context, workspaceResourceID uuid.UUID) ([]WorkspaceResourceMetadatum, error)
|
||||
GetWorkspaceResourceMetadataByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceResourceMetadatum, error)
|
||||
GetWorkspaceResourcesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceResource, error)
|
||||
GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResource, error)
|
||||
GetWorkspaces(ctx context.Context, arg GetWorkspacesParams) ([]Workspace, error)
|
||||
@ -108,6 +110,7 @@ type querier interface {
|
||||
InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error)
|
||||
InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) (WorkspaceBuild, error)
|
||||
InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error)
|
||||
InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) (WorkspaceResourceMetadatum, error)
|
||||
ParameterValue(ctx context.Context, id uuid.UUID) (ParameterValue, error)
|
||||
ParameterValues(ctx context.Context, arg ParameterValuesParams) ([]ParameterValue, error)
|
||||
UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error
|
||||
|
@ -3895,6 +3895,80 @@ func (q *sqlQuerier) GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceResourceMetadataByResourceID = `-- name: GetWorkspaceResourceMetadataByResourceID :many
|
||||
SELECT
|
||||
workspace_resource_id, key, value, sensitive
|
||||
FROM
|
||||
workspace_resource_metadata
|
||||
WHERE
|
||||
workspace_resource_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetWorkspaceResourceMetadataByResourceID(ctx context.Context, workspaceResourceID uuid.UUID) ([]WorkspaceResourceMetadatum, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataByResourceID, workspaceResourceID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []WorkspaceResourceMetadatum
|
||||
for rows.Next() {
|
||||
var i WorkspaceResourceMetadatum
|
||||
if err := rows.Scan(
|
||||
&i.WorkspaceResourceID,
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.Sensitive,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getWorkspaceResourceMetadataByResourceIDs = `-- name: GetWorkspaceResourceMetadataByResourceIDs :many
|
||||
SELECT
|
||||
workspace_resource_id, key, value, sensitive
|
||||
FROM
|
||||
workspace_resource_metadata
|
||||
WHERE
|
||||
workspace_resource_id = ANY($1 :: uuid [ ])
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetWorkspaceResourceMetadataByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceResourceMetadatum, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getWorkspaceResourceMetadataByResourceIDs, pq.Array(ids))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []WorkspaceResourceMetadatum
|
||||
for rows.Next() {
|
||||
var i WorkspaceResourceMetadatum
|
||||
if err := rows.Scan(
|
||||
&i.WorkspaceResourceID,
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.Sensitive,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getWorkspaceResourcesByJobID = `-- name: GetWorkspaceResourcesByJobID :many
|
||||
SELECT
|
||||
id, created_at, job_id, transition, type, name
|
||||
@ -4005,6 +4079,37 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertWorkspaceResourceMetadata = `-- name: InsertWorkspaceResourceMetadata :one
|
||||
INSERT INTO
|
||||
workspace_resource_metadata (workspace_resource_id, key, value, sensitive)
|
||||
VALUES
|
||||
($1, $2, $3, $4) RETURNING workspace_resource_id, key, value, sensitive
|
||||
`
|
||||
|
||||
type InsertWorkspaceResourceMetadataParams struct {
|
||||
WorkspaceResourceID uuid.UUID `db:"workspace_resource_id" json:"workspace_resource_id"`
|
||||
Key string `db:"key" json:"key"`
|
||||
Value sql.NullString `db:"value" json:"value"`
|
||||
Sensitive bool `db:"sensitive" json:"sensitive"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) (WorkspaceResourceMetadatum, error) {
|
||||
row := q.db.QueryRowContext(ctx, insertWorkspaceResourceMetadata,
|
||||
arg.WorkspaceResourceID,
|
||||
arg.Key,
|
||||
arg.Value,
|
||||
arg.Sensitive,
|
||||
)
|
||||
var i WorkspaceResourceMetadatum
|
||||
err := row.Scan(
|
||||
&i.WorkspaceResourceID,
|
||||
&i.Key,
|
||||
&i.Value,
|
||||
&i.Sensitive,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getWorkspaceByID = `-- name: GetWorkspaceByID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, owner_id, organization_id, template_id, deleted, name, autostart_schedule, ttl
|
||||
|
@ -22,3 +22,25 @@ INSERT INTO
|
||||
workspace_resources (id, created_at, job_id, transition, type, name)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6) RETURNING *;
|
||||
|
||||
-- name: GetWorkspaceResourceMetadataByResourceID :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
workspace_resource_metadata
|
||||
WHERE
|
||||
workspace_resource_id = $1;
|
||||
|
||||
-- name: GetWorkspaceResourceMetadataByResourceIDs :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
workspace_resource_metadata
|
||||
WHERE
|
||||
workspace_resource_id = ANY(@ids :: uuid [ ]);
|
||||
|
||||
-- name: InsertWorkspaceResourceMetadata :one
|
||||
INSERT INTO
|
||||
workspace_resource_metadata (workspace_resource_id, key, value, sensitive)
|
||||
VALUES
|
||||
($1, $2, $3, $4) RETURNING *;
|
||||
|
Reference in New Issue
Block a user