- Notifications
You must be signed in to change notification settings - Fork1.1k
feat: add migrations and queries to support prebuilds#16891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
300e80fb7882378122595bfb7c286639167769ae1de7e9c2739360478bdcafb412d19851773ec23773c2bc3ff44baa3076ed14fb33cc74fbfc32154d7b4ec4e8b53f79df6554ccc309eee1f16ad040ddd83a6722cd7071097cc4ff4d59039205d6afe489e1b1b2968620470e47b9c8cee189a0b692c0e5f747db03166a42aa6b490bc4e7d2f167b928fd34ab7a8ec49a64d661c787cd2bd38603097f9c34cfdd6f4a34d528d9cd45f870d7e18ad9314667171a26c0946ed41212312f415150a5cbff34eaef462b6dc451659c8a352eb809190b2bbee3a97bf62eeb88473f99e8113e12b217cae0b0bf220ff72a00a007d4aea9c53b66d44ed29e121ff64754f7e0239755d9827866454b4fa959aFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -18,6 +18,7 @@ import ( | ||
| "cdr.dev/slog" | ||
| "github.com/coder/coder/v2/coderd/prebuilds" | ||
| "github.com/coder/coder/v2/coderd/rbac/policy" | ||
| "github.com/coder/coder/v2/coderd/rbac/rolestore" | ||
| @@ -361,6 +362,27 @@ var ( | ||
| }), | ||
| Scope: rbac.ScopeAll, | ||
| }.WithCachedASTValue() | ||
| subjectPrebuildsOrchestrator = rbac.Subject{ | ||
| FriendlyName: "Prebuilds Orchestrator", | ||
| ID: prebuilds.SystemUserID.String(), | ||
| Roles: rbac.Roles([]rbac.Role{ | ||
| { | ||
| Identifier: rbac.RoleIdentifier{Name: "prebuilds-orchestrator"}, | ||
| DisplayName: "Coder", | ||
| Site: rbac.Permissions(map[string][]policy.Action{ | ||
| // May use template, read template-related info, & insert template-related resources (preset prebuilds). | ||
| rbac.ResourceTemplate.Type: {policy.ActionRead, policy.ActionUpdate, policy.ActionUse, policy.ActionViewInsights}, | ||
| // May CRUD workspaces, and start/stop them. | ||
| rbac.ResourceWorkspace.Type: { | ||
| policy.ActionCreate, policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, | ||
| policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, | ||
| }, | ||
| }), | ||
| }, | ||
| }), | ||
| Scope: rbac.ScopeAll, | ||
| }.WithCachedASTValue() | ||
| ) | ||
| // AsProvisionerd returns a context with an actor that has permissions required | ||
| @@ -415,6 +437,12 @@ func AsSystemReadProvisionerDaemons(ctx context.Context) context.Context { | ||
| return context.WithValue(ctx, authContextKey{}, subjectSystemReadProvisionerDaemons) | ||
| } | ||
| // AsPrebuildsOrchestrator returns a context with an actor that has permissions | ||
| // to read orchestrator workspace prebuilds. | ||
| func AsPrebuildsOrchestrator(ctx context.Context) context.Context { | ||
| return context.WithValue(ctx, authContextKey{}, subjectPrebuildsOrchestrator) | ||
| } | ||
| var AsRemoveActor = rbac.Subject{ | ||
| ID: "remove-actor", | ||
| } | ||
| @@ -1109,6 +1137,31 @@ func (q *querier) BulkMarkNotificationMessagesSent(ctx context.Context, arg data | ||
| return q.db.BulkMarkNotificationMessagesSent(ctx, arg) | ||
| } | ||
| func (q *querier) ClaimPrebuiltWorkspace(ctx context.Context, arg database.ClaimPrebuiltWorkspaceParams) (database.ClaimPrebuiltWorkspaceRow, error) { | ||
| empty := database.ClaimPrebuiltWorkspaceRow{} | ||
| preset, err := q.db.GetPresetByID(ctx, arg.PresetID) | ||
| if err != nil { | ||
| return empty, err | ||
| } | ||
| workspaceObject := rbac.ResourceWorkspace.WithOwner(arg.NewUserID.String()).InOrg(preset.OrganizationID) | ||
| err = q.authorizeContext(ctx, policy.ActionCreate, workspaceObject.RBACObject()) | ||
| if err != nil { | ||
| return empty, err | ||
| } | ||
| tpl, err := q.GetTemplateByID(ctx, preset.TemplateID.UUID) | ||
| if err != nil { | ||
| return empty, xerrors.Errorf("verify template by id: %w", err) | ||
| } | ||
| if err := q.authorizeContext(ctx, policy.ActionUse, tpl); err != nil { | ||
| return empty, xerrors.Errorf("use template for workspace: %w", err) | ||
| } | ||
Comment on lines +1148 to +1160 Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Just leave a comment this should match | ||
| return q.db.ClaimPrebuiltWorkspace(ctx, arg) | ||
| } | ||
| func (q *querier) CleanTailnetCoordinators(ctx context.Context) error { | ||
| if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceTailnetCoordinator); err != nil { | ||
| return err | ||
| @@ -1130,6 +1183,13 @@ func (q *querier) CleanTailnetTunnels(ctx context.Context) error { | ||
| return q.db.CleanTailnetTunnels(ctx) | ||
| } | ||
| func (q *querier) CountInProgressPrebuilds(ctx context.Context) ([]database.CountInProgressPrebuildsRow, error) { | ||
| if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspace.All()); err != nil { | ||
| return nil, err | ||
| } | ||
| return q.db.CountInProgressPrebuilds(ctx) | ||
| } | ||
Comment on lines +1186 to +1191 Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. This query spans all organizations, and prebuilds are just workspaces 👍 | ||
| func (q *querier) CountUnreadInboxNotificationsByUserID(ctx context.Context, userID uuid.UUID) (int64, error) { | ||
| if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceInboxNotification.WithOwner(userID.String())); err != nil { | ||
| return 0, err | ||
| @@ -2096,6 +2156,30 @@ func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUI | ||
| return q.db.GetParameterSchemasByJobID(ctx, jobID) | ||
| } | ||
| func (q *querier) GetPrebuildMetrics(ctx context.Context) ([]database.GetPrebuildMetricsRow, error) { | ||
| // GetPrebuildMetrics returns metrics related to prebuilt workspaces, | ||
| // such as the number of created and failed prebuilt workspaces. | ||
| if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspace.All()); err != nil { | ||
| return nil, err | ||
| } | ||
| return q.db.GetPrebuildMetrics(ctx) | ||
| } | ||
dannykopping marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| func (q *querier) GetPresetByID(ctx context.Context, presetID uuid.UUID) (database.GetPresetByIDRow, error) { | ||
| empty := database.GetPresetByIDRow{} | ||
| preset, err := q.db.GetPresetByID(ctx, presetID) | ||
| if err != nil { | ||
| return empty, err | ||
| } | ||
| _, err = q.GetTemplateByID(ctx, preset.TemplateID.UUID) | ||
| if err != nil { | ||
| return empty, err | ||
| } | ||
dannykopping marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| return preset, nil | ||
| } | ||
| func (q *querier) GetPresetByWorkspaceBuildID(ctx context.Context, workspaceID uuid.UUID) (database.TemplateVersionPreset, error) { | ||
| if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplate); err != nil { | ||
| return database.TemplateVersionPreset{}, err | ||
| @@ -2113,6 +2197,14 @@ func (q *querier) GetPresetParametersByTemplateVersionID(ctx context.Context, te | ||
| return q.db.GetPresetParametersByTemplateVersionID(ctx, templateVersionID) | ||
| } | ||
| func (q *querier) GetPresetsBackoff(ctx context.Context, lookback time.Time) ([]database.GetPresetsBackoffRow, error) { | ||
| // GetPresetsBackoff returns a list of template version presets along with metadata such as the number of failed prebuilds. | ||
| if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate.All()); err != nil { | ||
| return nil, err | ||
| } | ||
| return q.db.GetPresetsBackoff(ctx, lookback) | ||
| } | ||
Comment on lines +2200 to +2206 Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. @spikecurtis we decided to just lump in the preset metrics with template insights. Since template insights are metrics related to a template, prebuild metrics metadata is essentially the same imo. | ||
| func (q *querier) GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]database.TemplateVersionPreset, error) { | ||
| // An actor can read template version presets if they can read the related template version. | ||
| _, err := q.GetTemplateVersionByID(ctx, templateVersionID) | ||
| @@ -2164,13 +2256,13 @@ func (q *querier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (data | ||
| // can read the job. | ||
| _, err := q.GetWorkspaceBuildByJobID(ctx, id) | ||
| if err != nil { | ||
| return database.ProvisionerJob{},xerrors.Errorf("fetch related workspace build: %w",err) | ||
SasSwart marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| } | ||
| case database.ProvisionerJobTypeTemplateVersionDryRun, database.ProvisionerJobTypeTemplateVersionImport: | ||
| // Authorized call to get template version. | ||
| _, err := authorizedTemplateVersionFromJob(ctx, q, job) | ||
| if err != nil { | ||
| return database.ProvisionerJob{},xerrors.Errorf("fetch related template version: %w",err) | ||
| } | ||
| default: | ||
| return database.ProvisionerJob{}, xerrors.Errorf("unknown job type: %q", job.Type) | ||
| @@ -2263,6 +2355,14 @@ func (q *querier) GetReplicasUpdatedAfter(ctx context.Context, updatedAt time.Ti | ||
| return q.db.GetReplicasUpdatedAfter(ctx, updatedAt) | ||
| } | ||
| func (q *querier) GetRunningPrebuiltWorkspaces(ctx context.Context) ([]database.GetRunningPrebuiltWorkspacesRow, error) { | ||
| // This query returns only prebuilt workspaces, but we decided to require permissions for all workspaces. | ||
| if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceWorkspace.All()); err != nil { | ||
| return nil, err | ||
| } | ||
dannykopping marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| return q.db.GetRunningPrebuiltWorkspaces(ctx) | ||
| } | ||
| func (q *querier) GetRuntimeConfig(ctx context.Context, key string) (string, error) { | ||
| if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil { | ||
| return "", err | ||
| @@ -2387,6 +2487,15 @@ func (q *querier) GetTemplateParameterInsights(ctx context.Context, arg database | ||
| return q.db.GetTemplateParameterInsights(ctx, arg) | ||
| } | ||
| func (q *querier) GetTemplatePresetsWithPrebuilds(ctx context.Context, templateID uuid.NullUUID) ([]database.GetTemplatePresetsWithPrebuildsRow, error) { | ||
| // GetTemplatePresetsWithPrebuilds retrieves template versions with configured presets and prebuilds. | ||
| // Presets and prebuilds are part of the template, so if you can access templates - you can access them as well. | ||
| if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplate.All()); err != nil { | ||
| return nil, err | ||
| } | ||
| return q.db.GetTemplatePresetsWithPrebuilds(ctx, templateID) | ||
| } | ||
dannykopping marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| func (q *querier) GetTemplateUsageStats(ctx context.Context, arg database.GetTemplateUsageStatsParams) ([]database.TemplateUsageStat, error) { | ||
| if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil { | ||
| return nil, err | ||
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.