Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 789c4be

Browse files
authored
chore: add dynamic parameter error if missing metadata from provisioner (#17809)
1 parent f3bcac2 commit 789c4be

14 files changed

+163
-25
lines changed

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,6 +1774,7 @@ func (api *API) CreateInMemoryTaggedProvisionerDaemon(dialCtx context.Context, n
17741774
logger := api.Logger.Named(fmt.Sprintf("inmem-provisionerd-%s", name))
17751775
srv, err := provisionerdserver.NewServer(
17761776
api.ctx, // use the same ctx as the API
1777+
daemon.APIVersion,
17771778
api.AccessURL,
17781779
daemon.ID,
17791780
defaultOrg.ID,

coderd/database/dbgen/dbgen.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/coder/coder/v2/coderd/rbac"
3030
"github.com/coder/coder/v2/codersdk"
3131
"github.com/coder/coder/v2/cryptorand"
32+
"github.com/coder/coder/v2/provisionerd/proto"
3233
"github.com/coder/coder/v2/testutil"
3334
)
3435

@@ -1000,10 +1001,11 @@ func TemplateVersionTerraformValues(t testing.TB, db database.Store, orig databa
10001001
t.Helper()
10011002

10021003
params := database.InsertTemplateVersionTerraformValuesByJobIDParams{
1003-
JobID: takeFirst(orig.JobID, uuid.New()),
1004-
CachedPlan: takeFirstSlice(orig.CachedPlan, []byte("{}")),
1005-
CachedModuleFiles: orig.CachedModuleFiles,
1006-
UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
1004+
JobID: takeFirst(orig.JobID, uuid.New()),
1005+
CachedPlan: takeFirstSlice(orig.CachedPlan, []byte("{}")),
1006+
CachedModuleFiles: orig.CachedModuleFiles,
1007+
UpdatedAt: takeFirst(orig.UpdatedAt, dbtime.Now()),
1008+
ProvisionerdVersion: takeFirst(orig.ProvisionerdVersion, proto.CurrentVersion.String()),
10071009
}
10081010

10091011
err := db.InsertTemplateVersionTerraformValuesByJobID(genCtx, params)

coderd/database/dbmem/dbmem.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9343,10 +9343,11 @@ func (q *FakeQuerier) InsertTemplateVersionTerraformValuesByJobID(_ context.Cont
93439343

93449344
// Insert the new row
93459345
row := database.TemplateVersionTerraformValue{
9346-
TemplateVersionID: templateVersion.ID,
9347-
CachedPlan: arg.CachedPlan,
9348-
CachedModuleFiles: arg.CachedModuleFiles,
9349-
UpdatedAt: arg.UpdatedAt,
9346+
TemplateVersionID: templateVersion.ID,
9347+
UpdatedAt: arg.UpdatedAt,
9348+
CachedPlan: arg.CachedPlan,
9349+
CachedModuleFiles: arg.CachedModuleFiles,
9350+
ProvisionerdVersion: arg.ProvisionerdVersion,
93509351
}
93519352
q.templateVersionTerraformValues = append(q.templateVersionTerraformValues, row)
93529353
return nil

coderd/database/dump.sql

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE template_version_terraform_values DROP COLUMN provisionerd_version;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ALTER TABLE template_version_terraform_values ADD COLUMN IF NOT EXISTS provisionerd_version TEXT NOT NULL DEFAULT '';
2+
3+
COMMENT ON COLUMN template_version_terraform_values.provisionerd_version IS
4+
'What version of the provisioning engine was used to generate the cached plan and module files.';

coderd/database/models.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 12 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/templateversionterraformvalues.sql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ INSERT INTO
1212
template_version_id,
1313
cached_plan,
1414
cached_module_files,
15-
updated_at
15+
updated_at,
16+
provisionerd_version
1617
)
1718
VALUES
1819
(
1920
(select id from template_versions where job_id = @job_id),
2021
@cached_plan,
2122
@cached_module_files,
22-
@updated_at
23+
@updated_at,
24+
@provisionerd_version
2325
);

coderd/parameters.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ import (
88
"time"
99

1010
"github.com/google/uuid"
11+
"github.com/hashicorp/hcl/v2"
1112
"golang.org/x/sync/errgroup"
1213
"golang.org/x/xerrors"
1314

15+
"github.com/coder/coder/v2/apiversion"
1416
"github.com/coder/coder/v2/coderd/database"
1517
"github.com/coder/coder/v2/coderd/database/dbauthz"
1618
"github.com/coder/coder/v2/coderd/files"
@@ -107,6 +109,9 @@ func (api *API) templateVersionDynamicParameters(rw http.ResponseWriter, r *http
107109
return
108110
}
109111

112+
// If the err is sql.ErrNoRows, an empty terraform values struct is correct.
113+
staticDiagnostics := parameterProvisionerVersionDiagnostic(tf)
114+
110115
owner, err := api.getWorkspaceOwnerData(ctx, user, templateVersion.OrganizationID)
111116
if err != nil {
112117
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
@@ -141,7 +146,7 @@ func (api *API) templateVersionDynamicParameters(rw http.ResponseWriter, r *http
141146
result, diagnostics := preview.Preview(ctx, input, templateFS)
142147
response := codersdk.DynamicParametersResponse{
143148
ID: -1,
144-
Diagnostics: previewtypes.Diagnostics(diagnostics),
149+
Diagnostics: previewtypes.Diagnostics(diagnostics.Extend(staticDiagnostics)),
145150
}
146151
if result != nil {
147152
response.Parameters = result.Parameters
@@ -169,7 +174,7 @@ func (api *API) templateVersionDynamicParameters(rw http.ResponseWriter, r *http
169174
result, diagnostics := preview.Preview(ctx, input, templateFS)
170175
response := codersdk.DynamicParametersResponse{
171176
ID: update.ID,
172-
Diagnostics: previewtypes.Diagnostics(diagnostics),
177+
Diagnostics: previewtypes.Diagnostics(diagnostics.Extend(staticDiagnostics)),
173178
}
174179
if result != nil {
175180
response.Parameters = result.Parameters
@@ -262,3 +267,31 @@ func (api *API) getWorkspaceOwnerData(
262267
Groups: groupNames,
263268
}, nil
264269
}
270+
271+
// parameterProvisionerVersionDiagnostic checks the version of the provisioner
272+
// used to create the template version. If the version is less than 1.5, it
273+
// returns a warning diagnostic. Only versions 1.5+ return the module & plan data
274+
// required.
275+
func parameterProvisionerVersionDiagnostic(tf database.TemplateVersionTerraformValue) hcl.Diagnostics {
276+
missingMetadata := hcl.Diagnostic{
277+
Severity: hcl.DiagError,
278+
Summary: "This template version is missing required metadata to support dynamic parameters. Go back to the classic creation flow.",
279+
Detail: "To restore full functionality, please re-import the terraform as a new template version.",
280+
}
281+
282+
if tf.ProvisionerdVersion == "" {
283+
return hcl.Diagnostics{&missingMetadata}
284+
}
285+
286+
major, minor, err := apiversion.Parse(tf.ProvisionerdVersion)
287+
if err != nil || tf.ProvisionerdVersion == "" {
288+
return hcl.Diagnostics{&missingMetadata}
289+
} else if major < 1 || (major == 1 && minor < 5) {
290+
missingMetadata.Detail = "This template version does not support dynamic parameters. " +
291+
"Some options may be missing or incorrect. " +
292+
"Please contact an administrator to update the provisioner and re-import the template version."
293+
return hcl.Diagnostics{&missingMetadata}
294+
}
295+
296+
return nil
297+
}

coderd/parameters_internal_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package coderd
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/coder/coder/v2/coderd/database"
9+
)
10+
11+
func Test_parameterProvisionerVersionDiagnostic(t *testing.T) {
12+
t.Parallel()
13+
14+
testCases := []struct {
15+
version string
16+
warning bool
17+
}{
18+
{
19+
version: "",
20+
warning: true,
21+
},
22+
{
23+
version: "invalid",
24+
warning: true,
25+
},
26+
{
27+
version: "0.4",
28+
warning: true,
29+
},
30+
{
31+
version: "0.5",
32+
warning: true,
33+
},
34+
{
35+
version: "0.6",
36+
warning: true,
37+
},
38+
{
39+
version: "1.4",
40+
warning: true,
41+
},
42+
{
43+
version: "1.5",
44+
warning: false,
45+
},
46+
{
47+
version: "1.6",
48+
warning: false,
49+
},
50+
{
51+
version: "2.0",
52+
warning: false,
53+
},
54+
{
55+
version: "2.5",
56+
warning: false,
57+
},
58+
{
59+
version: "2.6",
60+
warning: false,
61+
},
62+
}
63+
64+
for _, tc := range testCases {
65+
t.Run("Version_"+tc.version, func(t *testing.T) {
66+
t.Parallel()
67+
diags := parameterProvisionerVersionDiagnostic(database.TemplateVersionTerraformValue{
68+
ProvisionerdVersion: tc.version,
69+
})
70+
if tc.warning {
71+
require.Len(t, diags, 1, "expected warning")
72+
} else {
73+
require.Len(t, diags, 0, "expected no warning")
74+
}
75+
})
76+
}
77+
}

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ type Options struct {
9595
}
9696

9797
type server struct {
98+
apiVersion string
9899
// lifecycleCtx must be tied to the API server's lifecycle
99100
// as when the API server shuts down, we want to cancel any
100101
// long-running operations.
@@ -153,7 +154,9 @@ func (t Tags) Valid() error {
153154
return nil
154155
}
155156

156-
func NewServer(lifecycleCtx context.Context,
157+
func NewServer(
158+
lifecycleCtx context.Context,
159+
apiVersion string,
157160
accessURL *url.URL,
158161
id uuid.UUID,
159162
organizationID uuid.UUID,
@@ -214,6 +217,7 @@ func NewServer(lifecycleCtx context.Context,
214217

215218
s := &server{
216219
lifecycleCtx: lifecycleCtx,
220+
apiVersion: apiVersion,
217221
AccessURL: accessURL,
218222
ID: id,
219223
OrganizationID: organizationID,
@@ -1536,10 +1540,11 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
15361540
}
15371541

15381542
err = s.Database.InsertTemplateVersionTerraformValuesByJobID(ctx, database.InsertTemplateVersionTerraformValuesByJobIDParams{
1539-
JobID: jobID,
1540-
UpdatedAt: now,
1541-
CachedPlan: plan,
1542-
CachedModuleFiles: fileID,
1543+
JobID: jobID,
1544+
UpdatedAt: now,
1545+
CachedPlan: plan,
1546+
CachedModuleFiles: fileID,
1547+
ProvisionerdVersion: s.apiVersion,
15431548
})
15441549
if err != nil {
15451550
return nil, xerrors.Errorf("insert template version terraform data: %w", err)

coderd/provisionerdserver/provisionerdserver_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,6 +2993,7 @@ func setup(t *testing.T, ignoreLogErrors bool, ov *overrides) (proto.DRPCProvisi
29932993

29942994
srv, err := provisionerdserver.NewServer(
29952995
ov.ctx,
2996+
proto.CurrentVersion.String(),
29962997
&url.URL{},
29972998
daemon.ID,
29982999
defOrg.ID,

enterprise/coderd/provisionerdaemons.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request)
336336
logger.Info(ctx, "starting external provisioner daemon")
337337
srv, err := provisionerdserver.NewServer(
338338
srvCtx,
339+
daemon.APIVersion,
339340
api.AccessURL,
340341
daemon.ID,
341342
authRes.orgID,

0 commit comments

Comments
 (0)