chore: persist template import terraform plan in postgres (#17012)

This commit is contained in:
ケイラ
2025-03-24 10:01:50 -06:00
committed by GitHub
parent 445a059da2
commit 5b3eda6719
26 changed files with 491 additions and 257 deletions

View File

@ -3320,6 +3320,13 @@ func (q *querier) InsertTemplateVersionParameter(ctx context.Context, arg databa
return q.db.InsertTemplateVersionParameter(ctx, arg)
}
func (q *querier) InsertTemplateVersionTerraformValuesByJobID(ctx context.Context, arg database.InsertTemplateVersionTerraformValuesByJobIDParams) error {
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
return err
}
return q.db.InsertTemplateVersionTerraformValuesByJobID(ctx, arg)
}
func (q *querier) InsertTemplateVersionVariable(ctx context.Context, arg database.InsertTemplateVersionVariableParams) (database.TemplateVersionVariable, error) {
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
return database.TemplateVersionVariable{}, err

View File

@ -1261,6 +1261,23 @@ func (s *MethodTestSuite) TestTemplate() {
OrganizationID: t1.OrganizationID,
}).Asserts(t1, policy.ActionRead, t1, policy.ActionCreate)
}))
s.Run("InsertTemplateVersionTerraformValuesByJobID", s.Subtest(func(db database.Store, check *expects) {
o := dbgen.Organization(s.T(), db, database.Organization{})
u := dbgen.User(s.T(), db, database.User{})
_ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{OrganizationID: o.ID, UserID: u.ID})
t := dbgen.Template(s.T(), db, database.Template{OrganizationID: o.ID, CreatedBy: u.ID})
job := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{OrganizationID: o.ID})
_ = dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
OrganizationID: o.ID,
CreatedBy: u.ID,
JobID: job.ID,
TemplateID: uuid.NullUUID{UUID: t.ID, Valid: true},
})
check.Args(database.InsertTemplateVersionTerraformValuesByJobIDParams{
JobID: job.ID,
CachedPlan: []byte("{}"),
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
}))
s.Run("SoftDeleteTemplateByID", s.Subtest(func(db database.Store, check *expects) {
dbtestutil.DisableForeignKeysAndTriggers(s.T(), db)
t1 := dbgen.Template(s.T(), db, database.Template{})

View File

@ -54,47 +54,48 @@ func New() database.Store {
q := &FakeQuerier{
mutex: &sync.RWMutex{},
data: &data{
apiKeys: make([]database.APIKey, 0),
auditLogs: make([]database.AuditLog, 0),
customRoles: make([]database.CustomRole, 0),
dbcryptKeys: make([]database.DBCryptKey, 0),
externalAuthLinks: make([]database.ExternalAuthLink, 0),
files: make([]database.File, 0),
gitSSHKey: make([]database.GitSSHKey, 0),
groups: make([]database.Group, 0),
groupMembers: make([]database.GroupMemberTable, 0),
licenses: make([]database.License, 0),
locks: map[int64]struct{}{},
notificationMessages: make([]database.NotificationMessage, 0),
notificationPreferences: make([]database.NotificationPreference, 0),
organizationMembers: make([]database.OrganizationMember, 0),
organizations: make([]database.Organization, 0),
inboxNotifications: make([]database.InboxNotification, 0),
parameterSchemas: make([]database.ParameterSchema, 0),
presets: make([]database.TemplateVersionPreset, 0),
presetParameters: make([]database.TemplateVersionPresetParameter, 0),
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
provisionerJobs: make([]database.ProvisionerJob, 0),
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
provisionerKeys: make([]database.ProvisionerKey, 0),
runtimeConfig: map[string]string{},
telemetryItems: make([]database.TelemetryItem, 0),
templateVersions: make([]database.TemplateVersionTable, 0),
templates: make([]database.TemplateTable, 0),
users: make([]database.User, 0),
userConfigs: make([]database.UserConfig, 0),
userStatusChanges: make([]database.UserStatusChange, 0),
workspaceAgents: make([]database.WorkspaceAgent, 0),
workspaceResources: make([]database.WorkspaceResource, 0),
workspaceModules: make([]database.WorkspaceModule, 0),
workspaceResourceMetadata: make([]database.WorkspaceResourceMetadatum, 0),
workspaceAgentStats: make([]database.WorkspaceAgentStat, 0),
workspaceAgentLogs: make([]database.WorkspaceAgentLog, 0),
workspaceBuilds: make([]database.WorkspaceBuild, 0),
workspaceApps: make([]database.WorkspaceApp, 0),
workspaceAppAuditSessions: make([]database.WorkspaceAppAuditSession, 0),
workspaces: make([]database.WorkspaceTable, 0),
workspaceProxies: make([]database.WorkspaceProxy, 0),
apiKeys: make([]database.APIKey, 0),
auditLogs: make([]database.AuditLog, 0),
customRoles: make([]database.CustomRole, 0),
dbcryptKeys: make([]database.DBCryptKey, 0),
externalAuthLinks: make([]database.ExternalAuthLink, 0),
files: make([]database.File, 0),
gitSSHKey: make([]database.GitSSHKey, 0),
groups: make([]database.Group, 0),
groupMembers: make([]database.GroupMemberTable, 0),
licenses: make([]database.License, 0),
locks: map[int64]struct{}{},
notificationMessages: make([]database.NotificationMessage, 0),
notificationPreferences: make([]database.NotificationPreference, 0),
organizationMembers: make([]database.OrganizationMember, 0),
organizations: make([]database.Organization, 0),
inboxNotifications: make([]database.InboxNotification, 0),
parameterSchemas: make([]database.ParameterSchema, 0),
presets: make([]database.TemplateVersionPreset, 0),
presetParameters: make([]database.TemplateVersionPresetParameter, 0),
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
provisionerJobs: make([]database.ProvisionerJob, 0),
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
provisionerKeys: make([]database.ProvisionerKey, 0),
runtimeConfig: map[string]string{},
telemetryItems: make([]database.TelemetryItem, 0),
templateVersions: make([]database.TemplateVersionTable, 0),
templateVersionTerraformValues: make([]database.TemplateVersionTerraformValue, 0),
templates: make([]database.TemplateTable, 0),
users: make([]database.User, 0),
userConfigs: make([]database.UserConfig, 0),
userStatusChanges: make([]database.UserStatusChange, 0),
workspaceAgents: make([]database.WorkspaceAgent, 0),
workspaceResources: make([]database.WorkspaceResource, 0),
workspaceModules: make([]database.WorkspaceModule, 0),
workspaceResourceMetadata: make([]database.WorkspaceResourceMetadatum, 0),
workspaceAgentStats: make([]database.WorkspaceAgentStat, 0),
workspaceAgentLogs: make([]database.WorkspaceAgentLog, 0),
workspaceBuilds: make([]database.WorkspaceBuild, 0),
workspaceApps: make([]database.WorkspaceApp, 0),
workspaceAppAuditSessions: make([]database.WorkspaceAppAuditSession, 0),
workspaces: make([]database.WorkspaceTable, 0),
workspaceProxies: make([]database.WorkspaceProxy, 0),
},
}
// Always start with a default org. Matching migration 198.
@ -222,6 +223,7 @@ type data struct {
replicas []database.Replica
templateVersions []database.TemplateVersionTable
templateVersionParameters []database.TemplateVersionParameter
templateVersionTerraformValues []database.TemplateVersionTerraformValue
templateVersionVariables []database.TemplateVersionVariable
templateVersionWorkspaceTags []database.TemplateVersionWorkspaceTag
templates []database.TemplateTable
@ -8828,6 +8830,37 @@ func (q *FakeQuerier) InsertTemplateVersionParameter(_ context.Context, arg data
return param, nil
}
func (q *FakeQuerier) InsertTemplateVersionTerraformValuesByJobID(_ context.Context, arg database.InsertTemplateVersionTerraformValuesByJobIDParams) error {
err := validateDatabaseType(arg)
if err != nil {
return err
}
q.mutex.Lock()
defer q.mutex.Unlock()
// Find the template version by the job_id
templateVersion, ok := slice.Find(q.templateVersions, func(v database.TemplateVersionTable) bool {
return v.JobID == arg.JobID
})
if !ok {
return sql.ErrNoRows
}
if !json.Valid(arg.CachedPlan) {
return xerrors.Errorf("cached plan must be valid json, received %q", string(arg.CachedPlan))
}
// Insert the new row
row := database.TemplateVersionTerraformValue{
TemplateVersionID: templateVersion.ID,
CachedPlan: arg.CachedPlan,
UpdatedAt: arg.UpdatedAt,
}
q.templateVersionTerraformValues = append(q.templateVersionTerraformValues, row)
return nil
}
func (q *FakeQuerier) InsertTemplateVersionVariable(_ context.Context, arg database.InsertTemplateVersionVariableParams) (database.TemplateVersionVariable, error) {
if err := validateDatabaseType(arg); err != nil {
return database.TemplateVersionVariable{}, err

View File

@ -2082,6 +2082,13 @@ func (m queryMetricsStore) InsertTemplateVersionParameter(ctx context.Context, a
return parameter, err
}
func (m queryMetricsStore) InsertTemplateVersionTerraformValuesByJobID(ctx context.Context, arg database.InsertTemplateVersionTerraformValuesByJobIDParams) error {
start := time.Now()
r0 := m.s.InsertTemplateVersionTerraformValuesByJobID(ctx, arg)
m.queryLatencies.WithLabelValues("InsertTemplateVersionTerraformValuesByJobID").Observe(time.Since(start).Seconds())
return r0
}
func (m queryMetricsStore) InsertTemplateVersionVariable(ctx context.Context, arg database.InsertTemplateVersionVariableParams) (database.TemplateVersionVariable, error) {
start := time.Now()
variable, err := m.s.InsertTemplateVersionVariable(ctx, arg)

View File

@ -4394,6 +4394,20 @@ func (mr *MockStoreMockRecorder) InsertTemplateVersionParameter(ctx, arg any) *g
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertTemplateVersionParameter", reflect.TypeOf((*MockStore)(nil).InsertTemplateVersionParameter), ctx, arg)
}
// InsertTemplateVersionTerraformValuesByJobID mocks base method.
func (m *MockStore) InsertTemplateVersionTerraformValuesByJobID(ctx context.Context, arg database.InsertTemplateVersionTerraformValuesByJobIDParams) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InsertTemplateVersionTerraformValuesByJobID", ctx, arg)
ret0, _ := ret[0].(error)
return ret0
}
// InsertTemplateVersionTerraformValuesByJobID indicates an expected call of InsertTemplateVersionTerraformValuesByJobID.
func (mr *MockStoreMockRecorder) InsertTemplateVersionTerraformValuesByJobID(ctx, arg any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertTemplateVersionTerraformValuesByJobID", reflect.TypeOf((*MockStore)(nil).InsertTemplateVersionTerraformValuesByJobID), ctx, arg)
}
// InsertTemplateVersionVariable mocks base method.
func (m *MockStore) InsertTemplateVersionVariable(ctx context.Context, arg database.InsertTemplateVersionVariableParams) (database.TemplateVersionVariable, error) {
m.ctrl.T.Helper()

View File

@ -1375,6 +1375,12 @@ CREATE TABLE template_version_presets (
created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TABLE template_version_terraform_values (
template_version_id uuid NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
cached_plan jsonb NOT NULL
);
CREATE TABLE template_version_variables (
template_version_id uuid NOT NULL,
name text NOT NULL,
@ -2240,6 +2246,9 @@ ALTER TABLE ONLY template_version_preset_parameters
ALTER TABLE ONLY template_version_presets
ADD CONSTRAINT template_version_presets_pkey PRIMARY KEY (id);
ALTER TABLE ONLY template_version_terraform_values
ADD CONSTRAINT template_version_terraform_values_template_version_id_key UNIQUE (template_version_id);
ALTER TABLE ONLY template_version_variables
ADD CONSTRAINT template_version_variables_template_version_id_name_key UNIQUE (template_version_id, name);
@ -2668,6 +2677,9 @@ ALTER TABLE ONLY template_version_preset_parameters
ALTER TABLE ONLY template_version_presets
ADD CONSTRAINT template_version_presets_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ALTER TABLE ONLY template_version_terraform_values
ADD CONSTRAINT template_version_terraform_values_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ALTER TABLE ONLY template_version_variables
ADD CONSTRAINT template_version_variables_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;

View File

@ -44,6 +44,7 @@ const (
ForeignKeyTemplateVersionParametersTemplateVersionID ForeignKeyConstraint = "template_version_parameters_template_version_id_fkey" // ALTER TABLE ONLY template_version_parameters ADD CONSTRAINT template_version_parameters_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ForeignKeyTemplateVersionPresetParametTemplateVersionPresetID ForeignKeyConstraint = "template_version_preset_paramet_template_version_preset_id_fkey" // ALTER TABLE ONLY template_version_preset_parameters ADD CONSTRAINT template_version_preset_paramet_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE CASCADE;
ForeignKeyTemplateVersionPresetsTemplateVersionID ForeignKeyConstraint = "template_version_presets_template_version_id_fkey" // ALTER TABLE ONLY template_version_presets ADD CONSTRAINT template_version_presets_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ForeignKeyTemplateVersionTerraformValuesTemplateVersionID ForeignKeyConstraint = "template_version_terraform_values_template_version_id_fkey" // ALTER TABLE ONLY template_version_terraform_values ADD CONSTRAINT template_version_terraform_values_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ForeignKeyTemplateVersionVariablesTemplateVersionID ForeignKeyConstraint = "template_version_variables_template_version_id_fkey" // ALTER TABLE ONLY template_version_variables ADD CONSTRAINT template_version_variables_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ForeignKeyTemplateVersionWorkspaceTagsTemplateVersionID ForeignKeyConstraint = "template_version_workspace_tags_template_version_id_fkey" // ALTER TABLE ONLY template_version_workspace_tags ADD CONSTRAINT template_version_workspace_tags_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
ForeignKeyTemplateVersionsCreatedBy ForeignKeyConstraint = "template_versions_created_by_fkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;

View File

@ -0,0 +1 @@
drop table template_version_terraform_values;

View File

@ -0,0 +1,5 @@
create table template_version_terraform_values (
template_version_id uuid not null unique references template_versions(id) on delete cascade,
updated_at timestamptz not null default now(),
cached_plan jsonb not null
);

View File

@ -0,0 +1,12 @@
insert into
template_version_terraform_values (
template_version_id,
cached_plan,
updated_at
)
select
id,
'{}',
now()
from
template_versions;

View File

@ -3139,6 +3139,12 @@ type TemplateVersionTable struct {
SourceExampleID sql.NullString `db:"source_example_id" json:"source_example_id"`
}
type TemplateVersionTerraformValue struct {
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
CachedPlan json.RawMessage `db:"cached_plan" json:"cached_plan"`
}
type TemplateVersionVariable struct {
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
// Variable name

View File

@ -441,6 +441,7 @@ type sqlcQuerier interface {
InsertTemplate(ctx context.Context, arg InsertTemplateParams) error
InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) error
InsertTemplateVersionParameter(ctx context.Context, arg InsertTemplateVersionParameterParams) (TemplateVersionParameter, error)
InsertTemplateVersionTerraformValuesByJobID(ctx context.Context, arg InsertTemplateVersionTerraformValuesByJobIDParams) error
InsertTemplateVersionVariable(ctx context.Context, arg InsertTemplateVersionVariableParams) (TemplateVersionVariable, error)
InsertTemplateVersionWorkspaceTag(ctx context.Context, arg InsertTemplateVersionWorkspaceTagParams) (TemplateVersionWorkspaceTag, error)
InsertUser(ctx context.Context, arg InsertUserParams) (User, error)

View File

@ -10819,6 +10819,32 @@ func (q *sqlQuerier) UpdateTemplateVersionExternalAuthProvidersByJobID(ctx conte
return err
}
const insertTemplateVersionTerraformValuesByJobID = `-- name: InsertTemplateVersionTerraformValuesByJobID :exec
INSERT INTO
template_version_terraform_values (
template_version_id,
cached_plan,
updated_at
)
VALUES
(
(select id from template_versions where job_id = $1),
$2,
$3
)
`
type InsertTemplateVersionTerraformValuesByJobIDParams struct {
JobID uuid.UUID `db:"job_id" json:"job_id"`
CachedPlan json.RawMessage `db:"cached_plan" json:"cached_plan"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
func (q *sqlQuerier) InsertTemplateVersionTerraformValuesByJobID(ctx context.Context, arg InsertTemplateVersionTerraformValuesByJobIDParams) error {
_, err := q.db.ExecContext(ctx, insertTemplateVersionTerraformValuesByJobID, arg.JobID, arg.CachedPlan, arg.UpdatedAt)
return err
}
const getTemplateVersionVariables = `-- name: GetTemplateVersionVariables :many
SELECT template_version_id, name, description, type, value, default_value, required, sensitive FROM template_version_variables WHERE template_version_id = $1
`

View File

@ -0,0 +1,13 @@
-- name: InsertTemplateVersionTerraformValuesByJobID :exec
INSERT INTO
template_version_terraform_values (
template_version_id,
cached_plan,
updated_at
)
VALUES
(
(select id from template_versions where job_id = @job_id),
@cached_plan,
@updated_at
);

View File

@ -60,6 +60,7 @@ const (
UniqueTemplateVersionParametersTemplateVersionIDNameKey UniqueConstraint = "template_version_parameters_template_version_id_name_key" // ALTER TABLE ONLY template_version_parameters ADD CONSTRAINT template_version_parameters_template_version_id_name_key UNIQUE (template_version_id, name);
UniqueTemplateVersionPresetParametersPkey UniqueConstraint = "template_version_preset_parameters_pkey" // ALTER TABLE ONLY template_version_preset_parameters ADD CONSTRAINT template_version_preset_parameters_pkey PRIMARY KEY (id);
UniqueTemplateVersionPresetsPkey UniqueConstraint = "template_version_presets_pkey" // ALTER TABLE ONLY template_version_presets ADD CONSTRAINT template_version_presets_pkey PRIMARY KEY (id);
UniqueTemplateVersionTerraformValuesTemplateVersionIDKey UniqueConstraint = "template_version_terraform_values_template_version_id_key" // ALTER TABLE ONLY template_version_terraform_values ADD CONSTRAINT template_version_terraform_values_template_version_id_key UNIQUE (template_version_id);
UniqueTemplateVersionVariablesTemplateVersionIDNameKey UniqueConstraint = "template_version_variables_template_version_id_name_key" // ALTER TABLE ONLY template_version_variables ADD CONSTRAINT template_version_variables_template_version_id_name_key UNIQUE (template_version_id, name);
UniqueTemplateVersionWorkspaceTagsTemplateVersionIDKeyKey UniqueConstraint = "template_version_workspace_tags_template_version_id_key_key" // ALTER TABLE ONLY template_version_workspace_tags ADD CONSTRAINT template_version_workspace_tags_template_version_id_key_key UNIQUE (template_version_id, key);
UniqueTemplateVersionsPkey UniqueConstraint = "template_versions_pkey" // ALTER TABLE ONLY template_versions ADD CONSTRAINT template_versions_pkey PRIMARY KEY (id);