mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: remove coder_secret Terraform integration (#25512)
Removes the coder_secret Terraform integration: the data.coder_secret consumption path through provisionerdserver → provisioner.proto → provisioner/terraform, the dynamic-parameter secret-requirement validation, and the workspace-update / resolve-autostart surfaces that depended on it. This is being done due to a product/feature direction change (see PLAT-243). User-secret CRUD (DB, REST, CLI, UI, telemetry, audit) and the agent-manifest secret-injection path are untouched. The provisionerd API is bumped from v1.17 to v1.18 rather than rolled back: v1.17 shipped in v2.33.x, so user_secrets field numbers are reserved and the changelog documents both versions. Generated with assistance from Coder Agents.
This commit is contained in:
+8
-465
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtestutil"
|
||||
"github.com/coder/coder/v2/coderd/database/pubsub"
|
||||
"github.com/coder/coder/v2/coderd/dynamicparameters"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/codersdk/wsjson"
|
||||
@@ -387,433 +386,11 @@ func TestDynamicParametersWithTerraformValues(t *testing.T) {
|
||||
coderdtest.AssertParameter(t, "variable_values", preview.Parameters).
|
||||
Exists().Value("austin")
|
||||
})
|
||||
|
||||
t.Run("MissingSecret", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dynamicParametersTerraformSource, err := os.ReadFile("testdata/parameters/secret_required/main.tf")
|
||||
require.NoError(t, err)
|
||||
|
||||
setup := setupDynamicParamsTest(t, setupDynamicParamsTestParams{
|
||||
provisionerDaemonVersion: provProto.CurrentVersion.String(),
|
||||
mainTF: dynamicParametersTerraformSource,
|
||||
})
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
previews := setup.stream.Chan()
|
||||
|
||||
preview := testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, -1, preview.ID)
|
||||
for _, diag := range preview.Diagnostics {
|
||||
require.NotEqual(t, dynamicparameters.DiagCodeMissingSecret, diag.Extra.Code)
|
||||
}
|
||||
require.Equal(t, []codersdk.SecretRequirementStatus{{
|
||||
Env: "GITHUB_TOKEN",
|
||||
HelpMessage: "Add a GitHub PAT with env=GITHUB_TOKEN",
|
||||
Satisfied: false,
|
||||
}}, preview.SecretRequirements)
|
||||
})
|
||||
|
||||
t.Run("SecretRequirementPushesOnSecretChange", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dynamicParametersTerraformSource, err := os.ReadFile("testdata/parameters/secret_required/main.tf")
|
||||
require.NoError(t, err)
|
||||
|
||||
setup := setupDynamicParamsTest(t, setupDynamicParamsTestParams{
|
||||
provisionerDaemonVersion: provProto.CurrentVersion.String(),
|
||||
mainTF: dynamicParametersTerraformSource,
|
||||
})
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||
previews := setup.stream.Chan()
|
||||
|
||||
preview := testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, -1, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.False(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
_, err = setup.dynamicParamsClient.CreateUserSecret(ctx, codersdk.Me, codersdk.CreateUserSecretRequest{
|
||||
Name: "github-token",
|
||||
Value: "ghp_test",
|
||||
EnvName: "GITHUB_TOKEN",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
preview = testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, 0, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.True(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
err = setup.dynamicParamsClient.DeleteUserSecret(ctx, codersdk.Me, "github-token")
|
||||
require.NoError(t, err)
|
||||
|
||||
preview = testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, 1, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.False(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
_, err = setup.dynamicParamsClient.CreateUserSecret(ctx, codersdk.Me, codersdk.CreateUserSecretRequest{
|
||||
Name: "github-token",
|
||||
Value: "ghp_test",
|
||||
EnvName: "GITHUB_TOKEN",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
preview = testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, 2, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.True(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
otherEnvName := "OTHER_GITHUB_TOKEN"
|
||||
_, err = setup.dynamicParamsClient.UpdateUserSecret(ctx, codersdk.Me, "github-token", codersdk.UpdateUserSecretRequest{
|
||||
EnvName: &otherEnvName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
preview = testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, 3, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.False(t, preview.SecretRequirements[0].Satisfied)
|
||||
})
|
||||
|
||||
t.Run("SecretRequirementPushesAfterOwnerSwitch", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dynamicParametersTerraformSource, err := os.ReadFile("testdata/parameters/secret_required/main.tf")
|
||||
require.NoError(t, err)
|
||||
|
||||
setup := setupDynamicParamsTest(t, setupDynamicParamsTestParams{
|
||||
// No production role grants cross-user user_secret:read today,
|
||||
// so use an allow-all authorizer for lifecycle coverage.
|
||||
authorizer: &coderdtest.FakeAuthorizer{},
|
||||
provisionerDaemonVersion: provProto.CurrentVersion.String(),
|
||||
mainTF: dynamicParametersTerraformSource,
|
||||
})
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||
previews := setup.stream.Chan()
|
||||
targetClient, target := coderdtest.CreateAnotherUser(t, setup.client, setup.template.OrganizationID)
|
||||
|
||||
preview := testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, -1, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.False(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
err = setup.stream.Send(codersdk.DynamicParametersRequest{
|
||||
ID: 0,
|
||||
Inputs: map[string]string{},
|
||||
OwnerID: target.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
preview = testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, 0, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.False(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
_, err = targetClient.CreateUserSecret(ctx, codersdk.Me, codersdk.CreateUserSecretRequest{
|
||||
Name: "github-token",
|
||||
Value: "ghp_target",
|
||||
EnvName: "GITHUB_TOKEN",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
preview = testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, 1, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.True(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
_, err = setup.dynamicParamsClient.CreateUserSecret(ctx, codersdk.Me, codersdk.CreateUserSecretRequest{
|
||||
Name: "github-token",
|
||||
Value: "ghp_initial",
|
||||
EnvName: "GITHUB_TOKEN",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Never(t, func() bool {
|
||||
select {
|
||||
case <-previews:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}, testutil.WaitShort/5, testutil.IntervalFast)
|
||||
})
|
||||
|
||||
t.Run("SecretRequirementDoesNotSubscribeWhenOwnerUnauthorized", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dynamicParametersTerraformSource, err := os.ReadFile("testdata/parameters/secret_required/main.tf")
|
||||
require.NoError(t, err)
|
||||
|
||||
setup := setupDynamicParamsTest(t, setupDynamicParamsTestParams{
|
||||
provisionerDaemonVersion: provProto.CurrentVersion.String(),
|
||||
mainTF: dynamicParametersTerraformSource,
|
||||
})
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||
previews := setup.stream.Chan()
|
||||
targetClient, target := coderdtest.CreateAnotherUser(t, setup.client, setup.template.OrganizationID)
|
||||
|
||||
preview := testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, -1, preview.ID)
|
||||
require.Len(t, preview.SecretRequirements, 1)
|
||||
require.False(t, preview.SecretRequirements[0].Satisfied)
|
||||
|
||||
err = setup.stream.Send(codersdk.DynamicParametersRequest{
|
||||
ID: 0,
|
||||
Inputs: map[string]string{},
|
||||
OwnerID: target.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
preview = testutil.RequireReceive(ctx, t, previews)
|
||||
require.Equal(t, 0, preview.ID)
|
||||
require.Empty(t, preview.SecretRequirements)
|
||||
require.Len(t, preview.Diagnostics, 1)
|
||||
require.Equal(t, dynamicparameters.DiagCodeSecretValidationForbidden, preview.Diagnostics[0].Extra.Code)
|
||||
|
||||
_, err = targetClient.CreateUserSecret(ctx, codersdk.Me, codersdk.CreateUserSecretRequest{
|
||||
Name: "github-token",
|
||||
Value: "ghp_target",
|
||||
EnvName: "GITHUB_TOKEN",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Never(t, func() bool {
|
||||
select {
|
||||
case <-previews:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}, testutil.WaitShort/5, testutil.IntervalFast)
|
||||
})
|
||||
|
||||
// Regression test for PLAT-100: a workspace whose template has an
|
||||
// unsatisfied coder_secret requirement must still be stoppable and
|
||||
// deletable. Start remains blocked.
|
||||
t.Run("SecretRequirementDoesNotBlockStopOrDelete", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dynamicParametersTerraformSource, err := os.ReadFile("testdata/parameters/secret_required/main.tf")
|
||||
require.NoError(t, err)
|
||||
|
||||
setup := setupDynamicParamsTest(t, setupDynamicParamsTestParams{
|
||||
provisionerDaemonVersion: provProto.CurrentVersion.String(),
|
||||
mainTF: dynamicParametersTerraformSource,
|
||||
})
|
||||
_ = setup.stream.Close(websocket.StatusGoingAway)
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
// Owner must satisfy the coder_secret requirement to create
|
||||
// the workspace; delete it later to provoke the bug scenario.
|
||||
_, err = setup.client.CreateUserSecret(ctx, codersdk.Me, codersdk.CreateUserSecretRequest{
|
||||
Name: "github-token",
|
||||
Value: "ghp_test",
|
||||
EnvName: "GITHUB_TOKEN",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
wrk := coderdtest.CreateWorkspace(t, setup.client, setup.template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, setup.client, wrk.LatestBuild.ID)
|
||||
|
||||
require.NoError(t, setup.client.DeleteUserSecret(ctx, codersdk.Me, "github-token"))
|
||||
|
||||
// Start on the now-unsatisfied requirement must still fail;
|
||||
// otherwise we've over-filtered the diagnostic.
|
||||
_, err = setup.client.CreateWorkspaceBuild(ctx, wrk.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
Transition: codersdk.WorkspaceTransitionStart,
|
||||
})
|
||||
require.Error(t, err, "start must still reject unsatisfied secret requirement")
|
||||
var sdkErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &sdkErr)
|
||||
require.Contains(t, sdkErr.Detail, "Missing required secrets")
|
||||
require.Contains(t, sdkErr.Detail, "env GITHUB_TOKEN")
|
||||
|
||||
// Stop must succeed despite the unsatisfied requirement.
|
||||
stop, err := setup.client.CreateWorkspaceBuild(ctx, wrk.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
Transition: codersdk.WorkspaceTransitionStop,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, setup.client, stop.ID)
|
||||
|
||||
// Delete must succeed despite the unsatisfied requirement.
|
||||
del, err := setup.client.CreateWorkspaceBuild(ctx, wrk.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
Transition: codersdk.WorkspaceTransitionDelete,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, setup.client, del.ID)
|
||||
})
|
||||
}
|
||||
|
||||
// TestResolveAutostartPreservesParameterMismatchOnSecretEvalError exercises
|
||||
// the handler's default switch arm: when EvaluateSecretMismatch returns a
|
||||
// non-ErrTemplateVersionNotReady error, the handler must log and treat
|
||||
// SecretMismatch as "unknown" without dropping the already-computed
|
||||
// ParameterMismatch signal.
|
||||
func TestResolveAutostartPreservesParameterMismatchOnSecretEvalError(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db, ps := dbtestutil.NewDB(t)
|
||||
|
||||
// Wrap the DB so we can fail the renderer's GetTemplateVersionTerraformValues
|
||||
// call. Toggle is flipped on after setup so initial template version
|
||||
// processing succeeds.
|
||||
reject := &dbRejectTemplateVersionTerraformValues{Store: db}
|
||||
|
||||
noRequirementsTF := []byte(`terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
setup := setupDynamicParamsTest(t, setupDynamicParamsTestParams{
|
||||
db: reject,
|
||||
ps: ps,
|
||||
provisionerDaemonVersion: provProto.CurrentVersion.String(),
|
||||
mainTF: noRequirementsTF,
|
||||
})
|
||||
_ = setup.stream.Close(websocket.StatusGoingAway)
|
||||
|
||||
wrk := coderdtest.CreateWorkspace(t, setup.client, setup.template.ID,
|
||||
func(req *codersdk.CreateWorkspaceRequest) {
|
||||
req.AutomaticUpdates = codersdk.AutomaticUpdatesAlways
|
||||
})
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, setup.client, wrk.LatestBuild.ID)
|
||||
|
||||
// Push a v2 that adds a required-no-default parameter so resolve-autostart
|
||||
// computes ParameterMismatch=true. The new version becomes active via
|
||||
// DynamicParameterTemplate's UpdateActiveTemplateVersion call.
|
||||
paramRequiredTF := []byte(`terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data "coder_parameter" "required_param" {
|
||||
name = "required_param"
|
||||
type = "string"
|
||||
}
|
||||
`)
|
||||
// StaticParams populates the legacy template_version_parameters table via
|
||||
// the GraphComplete response. resolve-autostart reads from this table to
|
||||
// determine ParameterMismatch.
|
||||
_, _ = coderdtest.DynamicParameterTemplate(t, setup.dynamicParamsClient,
|
||||
wrk.OrganizationID,
|
||||
coderdtest.DynamicParameterTemplateParams{
|
||||
MainTF: string(paramRequiredTF),
|
||||
TemplateID: setup.template.ID,
|
||||
StaticParams: []*proto.RichParameter{{
|
||||
Name: "required_param",
|
||||
Type: "string",
|
||||
Required: true,
|
||||
}},
|
||||
})
|
||||
|
||||
// Arm the rejection only for the resolve-autostart call. Setup has
|
||||
// already completed, so all earlier calls passed through.
|
||||
reject.SetReject(true)
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
resp, err := setup.client.ResolveAutostart(ctx, wrk.ID.String())
|
||||
require.NoError(t, err, "resolve-autostart must not 500 when secret evaluation fails")
|
||||
require.True(t, resp.ParameterMismatch, "ParameterMismatch should be preserved across secret evaluation failure")
|
||||
require.False(t, resp.SecretMismatch, "SecretMismatch should be unknown (false) when evaluation fails")
|
||||
}
|
||||
|
||||
// TestResolveAutostartSecretRequirements is the PLAT-81 backend coverage:
|
||||
// resolve-autostart must surface coder_secret requirements declared by the
|
||||
// active template version that the workspace owner's secrets do not
|
||||
// satisfy. The dashboard banner uses this to tell the user autostart
|
||||
// cannot run the auto-update build until they create the missing secrets.
|
||||
func TestResolveAutostartSecretRequirements(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
noRequirementsTF := []byte(`terraform {
|
||||
required_providers {
|
||||
coder = {
|
||||
source = "coder/coder"
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
secretRequiredTF, err := os.ReadFile("testdata/parameters/secret_required/main.tf")
|
||||
require.NoError(t, err)
|
||||
|
||||
// v1 has no secret requirements; we need a workspace to exist so
|
||||
// resolve-autostart enters its version-mismatch branch.
|
||||
setup := setupDynamicParamsTest(t, setupDynamicParamsTestParams{
|
||||
provisionerDaemonVersion: provProto.CurrentVersion.String(),
|
||||
mainTF: noRequirementsTF,
|
||||
})
|
||||
_ = setup.stream.Close(websocket.StatusGoingAway)
|
||||
|
||||
wrk := coderdtest.CreateWorkspace(t, setup.client, setup.template.ID,
|
||||
func(req *codersdk.CreateWorkspaceRequest) {
|
||||
req.AutomaticUpdates = codersdk.AutomaticUpdatesAlways
|
||||
})
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, setup.client, wrk.LatestBuild.ID)
|
||||
|
||||
// Push v2 with a coder_secret requirement and make it active.
|
||||
_, _ = coderdtest.DynamicParameterTemplate(t, setup.dynamicParamsClient,
|
||||
wrk.OrganizationID,
|
||||
coderdtest.DynamicParameterTemplateParams{
|
||||
MainTF: string(secretRequiredTF),
|
||||
TemplateID: setup.template.ID,
|
||||
})
|
||||
|
||||
t.Run("OwnerSeesMismatchThenSatisfies", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
// Owner has no GITHUB_TOKEN secret; resolve-autostart must surface
|
||||
// the unsatisfied requirement.
|
||||
resp, err := setup.client.ResolveAutostart(ctx, wrk.ID.String())
|
||||
require.NoError(t, err)
|
||||
require.False(t, resp.ParameterMismatch)
|
||||
require.True(t, resp.SecretMismatch)
|
||||
|
||||
// Creating the matching secret must clear the entry without further
|
||||
// template changes.
|
||||
_, err = setup.client.CreateUserSecret(ctx, codersdk.Me, codersdk.CreateUserSecretRequest{
|
||||
Name: "github-token",
|
||||
Value: "ghp_test",
|
||||
EnvName: "GITHUB_TOKEN",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err = setup.client.ResolveAutostart(ctx, wrk.ID.String())
|
||||
require.NoError(t, err)
|
||||
require.False(t, resp.ParameterMismatch)
|
||||
require.False(t, resp.SecretMismatch)
|
||||
})
|
||||
|
||||
t.Run("ForbiddenCallerSeesNoMismatch", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
// The template-admin client can read the workspace but lacks
|
||||
// user_secret:read on the workspace owner. The renderer's secret
|
||||
// fetch produces a forbidden diagnostic, and the handler must
|
||||
// treat that as "unknown" and report SecretMismatch=false rather
|
||||
// than leaking a 500 or a stale true value.
|
||||
resp, err := setup.dynamicParamsClient.ResolveAutostart(ctx, wrk.ID.String())
|
||||
require.NoError(t, err)
|
||||
require.False(t, resp.SecretMismatch)
|
||||
})
|
||||
}
|
||||
|
||||
type setupDynamicParamsTestParams struct {
|
||||
db database.Store
|
||||
ps pubsub.Pubsub
|
||||
authorizer rbac.Authorizer
|
||||
provisionerDaemonVersion string
|
||||
mainTF []byte
|
||||
modulesArchive []byte
|
||||
@@ -825,18 +402,16 @@ type setupDynamicParamsTestParams struct {
|
||||
}
|
||||
|
||||
type dynamicParamsTest struct {
|
||||
client *codersdk.Client
|
||||
dynamicParamsClient *codersdk.Client
|
||||
api *coderd.API
|
||||
stream *wsjson.Stream[codersdk.DynamicParametersResponse, codersdk.DynamicParametersRequest]
|
||||
template codersdk.Template
|
||||
client *codersdk.Client
|
||||
api *coderd.API
|
||||
stream *wsjson.Stream[codersdk.DynamicParametersResponse, codersdk.DynamicParametersRequest]
|
||||
template codersdk.Template
|
||||
}
|
||||
|
||||
func setupDynamicParamsTest(t *testing.T, args setupDynamicParamsTestParams) dynamicParamsTest {
|
||||
ownerClient, _, api := coderdtest.NewWithAPI(t, &coderdtest.Options{
|
||||
Database: args.db,
|
||||
Pubsub: args.ps,
|
||||
Authorizer: args.authorizer,
|
||||
IncludeProvisionerDaemon: true,
|
||||
ProvisionerDaemonVersion: args.provisionerDaemonVersion,
|
||||
})
|
||||
@@ -871,11 +446,10 @@ func setupDynamicParamsTest(t *testing.T, args setupDynamicParamsTestParams) dyn
|
||||
})
|
||||
|
||||
return dynamicParamsTest{
|
||||
client: ownerClient,
|
||||
dynamicParamsClient: templateAdmin,
|
||||
api: api,
|
||||
stream: stream,
|
||||
template: tpl,
|
||||
client: ownerClient,
|
||||
api: api,
|
||||
stream: stream,
|
||||
template: tpl,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -910,34 +484,3 @@ func (d *dbRejectGitSSHKey) GetGitSSHKey(ctx context.Context, userID uuid.UUID)
|
||||
|
||||
return d.Store.GetGitSSHKey(ctx, userID)
|
||||
}
|
||||
|
||||
// dbRejectTemplateVersionTerraformValues wraps a Store so the dynamic
|
||||
// parameter renderer's GetTemplateVersionTerraformValues call can be made
|
||||
// to fail on demand. This forces the resolve-autostart handler into the
|
||||
// default switch arm where EvaluateSecretMismatch returns a non-
|
||||
// ErrTemplateVersionNotReady error.
|
||||
type dbRejectTemplateVersionTerraformValues struct {
|
||||
database.Store
|
||||
rejectMu sync.RWMutex
|
||||
reject bool
|
||||
}
|
||||
|
||||
// SetReject toggles whether GetTemplateVersionTerraformValues should
|
||||
// return an error or passthrough to the underlying store.
|
||||
func (d *dbRejectTemplateVersionTerraformValues) SetReject(reject bool) {
|
||||
d.rejectMu.Lock()
|
||||
defer d.rejectMu.Unlock()
|
||||
d.reject = reject
|
||||
}
|
||||
|
||||
func (d *dbRejectTemplateVersionTerraformValues) GetTemplateVersionTerraformValues(ctx context.Context, templateVersionID uuid.UUID) (database.TemplateVersionTerraformValue, error) {
|
||||
d.rejectMu.RLock()
|
||||
reject := d.reject
|
||||
d.rejectMu.RUnlock()
|
||||
|
||||
if reject {
|
||||
return database.TemplateVersionTerraformValue{}, xerrors.New("forcing a fake error")
|
||||
}
|
||||
|
||||
return d.Store.GetTemplateVersionTerraformValues(ctx, templateVersionID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user