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

Skip to content

Commit 5a44d84

Browse files
committed
Allow one-off project import jobs
1 parent 2d82f89 commit 5a44d84

25 files changed

+550
-332
lines changed

coderd/coderd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,11 @@ func New(options *Options) http.Handler {
117117
httpmw.ExtractAPIKey(options.Database, nil),
118118
httpmw.ExtractOrganizationParam(options.Database),
119119
)
120+
r.Post("/", api.postProvisionerJobsByOrganization)
120121
r.Route("/{provisionerjob}", func(r chi.Router) {
121122
r.Use(httpmw.ExtractProvisionerJobParam(options.Database))
122123
r.Get("/logs", api.provisionerJobLogsByID)
124+
r.Get("/resources", api.provisionerJobResourcesByOrganization)
123125
})
124126
})
125127
})

coderd/coderdtest/coderdtest.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ func CreateProjectVersion(t *testing.T, client *codersdk.Client, organization, p
139139
data, err := echo.Tar(responses)
140140
require.NoError(t, err)
141141
version, err := client.CreateProjectVersion(context.Background(), organization, project, coderd.CreateProjectVersionRequest{
142-
StorageMethod: database.ProjectStorageMethodInlineArchive,
143142
StorageSource: data,
144143
})
145144
require.NoError(t, err)

coderd/files.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (api *api) postFiles(rw http.ResponseWriter, r *http.Request) {
5353
})
5454
return
5555
}
56-
render.Status(r, http.StatusOK)
56+
render.Status(r, http.StatusCreated)
5757
render.JSON(rw, r, UploadFileResponse{
5858
Hash: file.Hash,
5959
})

coderd/files_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@ func TestPostFiles(t *testing.T) {
1515
t.Parallel()
1616
client := coderdtest.New(t)
1717
_ = coderdtest.CreateInitialUser(t, client)
18-
_, err := client.Upload(context.Background(), "bad", []byte{'a'})
18+
_, err := client.UploadFile(context.Background(), "bad", []byte{'a'})
1919
require.NoError(t, err)
2020
})
2121

2222
t.Run("MassiveBody", func(t *testing.T) {
2323
t.Parallel()
2424
client := coderdtest.New(t)
2525
_ = coderdtest.CreateInitialUser(t, client)
26-
_, err := client.Upload(context.Background(), codersdk.ContentTypeTar, make([]byte, 11*(10<<20)))
26+
_, err := client.UploadFile(context.Background(), codersdk.ContentTypeTar, make([]byte, 11*(10<<20)))
2727
require.Error(t, err)
2828
})
2929

3030
t.Run("Insert", func(t *testing.T) {
3131
t.Parallel()
3232
client := coderdtest.New(t)
3333
_ = coderdtest.CreateInitialUser(t, client)
34-
_, err := client.Upload(context.Background(), codersdk.ContentTypeTar, make([]byte, 10<<20))
34+
_, err := client.UploadFile(context.Background(), codersdk.ContentTypeTar, make([]byte, 10<<20))
3535
require.NoError(t, err)
3636
})
3737
}

coderd/projectparameter/projectparameter.go

Lines changed: 72 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import (
1515

1616
// Scope targets identifiers to pull parameters from.
1717
type Scope struct {
18-
OrganizationID string
19-
ProjectID uuid.UUID
2018
ImportJobID uuid.UUID
19+
OrganizationID sql.NullString
20+
ProjectID uuid.NullUUID
2121
UserID sql.NullString
2222
WorkspaceID uuid.NullUUID
2323
}
@@ -35,38 +35,40 @@ type Value struct {
3535
// Compute accepts a scope in which parameter values are sourced.
3636
// These sources are iterated in a hierarchical fashion to determine
3737
// the runtime parameter values for a project.
38-
func Compute(ctx context.Context, db database.Store, scope Scope) ([]Value, error) {
38+
func Compute(ctx context.Context, db database.Store, scope Scope, additional ...database.ParameterValue) ([]Value, error) {
3939
compute := &compute{
4040
db: db,
4141
computedParameterByName: map[string]Value{},
4242
parameterSchemasByName: map[string]database.ParameterSchema{},
4343
}
4444

4545
// All parameters for the project version!
46-
projectVersionParameters, err := db.GetParameterSchemasByJobID(ctx, scope.ImportJobID)
46+
parameterSchemas, err := db.GetParameterSchemasByJobID(ctx, scope.ImportJobID)
4747
if errors.Is(err, sql.ErrNoRows) {
48-
// This occurs when the project version has defined
49-
// no parameters, so we have nothing to compute!
48+
// This occurs when the provided import job has
49+
// defined no parameters, so we have nothing to compute!
5050
return []Value{}, nil
5151
}
5252
if err != nil {
5353
return nil, xerrors.Errorf("get project parameters: %w", err)
5454
}
55-
for _, projectVersionParameter := range projectVersionParameters {
55+
for _, projectVersionParameter := range parameterSchemas {
5656
compute.parameterSchemasByName[projectVersionParameter.Name] = projectVersionParameter
5757
}
5858

59-
// Organization parameters come first!
60-
err = compute.inject(ctx, database.GetParameterValuesByScopeParams{
61-
Scope: database.ParameterScopeOrganization,
62-
ScopeID: scope.OrganizationID,
63-
})
64-
if err != nil {
65-
return nil, err
59+
if scope.OrganizationID.Valid {
60+
// Organization parameters come first!
61+
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
62+
Scope: database.ParameterScopeOrganization,
63+
ScopeID: scope.OrganizationID.String,
64+
})
65+
if err != nil {
66+
return nil, err
67+
}
6668
}
6769

6870
// Default project parameter values come second!
69-
for _, projectVersionParameter := range projectVersionParameters {
71+
for _, projectVersionParameter := range parameterSchemas {
7072
if !projectVersionParameter.DefaultSourceValue.Valid {
7173
continue
7274
}
@@ -89,25 +91,27 @@ func Compute(ctx context.Context, db database.Store, scope Scope) ([]Value, erro
8991
},
9092
DefaultValue: true,
9193
Scope: database.ParameterScopeProject,
92-
ScopeID: scope.ProjectID.String(),
94+
ScopeID: scope.ProjectID.UUID.String(),
9395
}
9496
default:
9597
return nil, xerrors.Errorf("unsupported source scheme for project version parameter %q: %q", projectVersionParameter.Name, string(projectVersionParameter.DefaultSourceScheme))
9698
}
9799
}
98100

99-
// Project parameters come third!
100-
err = compute.inject(ctx, database.GetParameterValuesByScopeParams{
101-
Scope: database.ParameterScopeProject,
102-
ScopeID: scope.ProjectID.String(),
103-
})
104-
if err != nil {
105-
return nil, err
101+
if scope.ProjectID.Valid {
102+
// Project parameters come third!
103+
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
104+
Scope: database.ParameterScopeProject,
105+
ScopeID: scope.ProjectID.UUID.String(),
106+
})
107+
if err != nil {
108+
return nil, err
109+
}
106110
}
107111

108112
if scope.UserID.Valid {
109113
// User parameters come fourth!
110-
err = compute.inject(ctx, database.GetParameterValuesByScopeParams{
114+
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
111115
Scope: database.ParameterScopeUser,
112116
ScopeID: scope.UserID.String,
113117
})
@@ -118,7 +122,7 @@ func Compute(ctx context.Context, db database.Store, scope Scope) ([]Value, erro
118122

119123
if scope.WorkspaceID.Valid {
120124
// Workspace parameters come last!
121-
err = compute.inject(ctx, database.GetParameterValuesByScopeParams{
125+
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
122126
Scope: database.ParameterScopeWorkspace,
123127
ScopeID: scope.WorkspaceID.UUID.String(),
124128
})
@@ -127,6 +131,13 @@ func Compute(ctx context.Context, db database.Store, scope Scope) ([]Value, erro
127131
}
128132
}
129133

134+
for _, parameterValue := range additional {
135+
err = compute.injectSingle(parameterValue)
136+
if err != nil {
137+
return nil, xerrors.Errorf("inject %q: %w", parameterValue.Name, err)
138+
}
139+
}
140+
130141
for _, projectVersionParameter := range compute.parameterSchemasByName {
131142
if _, ok := compute.computedParameterByName[projectVersionParameter.Name]; ok {
132143
continue
@@ -151,7 +162,7 @@ type compute struct {
151162
}
152163

153164
// Validates and computes the value for parameters; setting the value on "parameterByName".
154-
func (c *compute) inject(ctx context.Context, scopeParams database.GetParameterValuesByScopeParams) error {
165+
func (c *compute) injectScope(ctx context.Context, scopeParams database.GetParameterValuesByScopeParams) error {
155166
scopedParameters, err := c.db.GetParameterValuesByScope(ctx, scopeParams)
156167
if errors.Is(err, sql.ErrNoRows) {
157168
err = nil
@@ -161,39 +172,47 @@ func (c *compute) inject(ctx context.Context, scopeParams database.GetParameterV
161172
}
162173

163174
for _, scopedParameter := range scopedParameters {
164-
projectVersionParameter, hasProjectVersionParameter := c.parameterSchemasByName[scopedParameter.Name]
165-
if !hasProjectVersionParameter {
166-
// Don't inject parameters that aren't defined by the project.
167-
continue
175+
err = c.injectSingle(scopedParameter)
176+
if err != nil {
177+
return xerrors.Errorf("inject single %q: %w", scopedParameter.Name, err)
168178
}
179+
}
180+
return nil
181+
}
169182

170-
_, hasExistingParameter := c.computedParameterByName[scopedParameter.Name]
171-
if hasExistingParameter {
172-
// If a parameter already exists, check if this variable can override it.
173-
// Injection hierarchy is the responsibility of the caller. This check ensures
174-
// project parameters cannot be overridden if already set.
175-
if !projectVersionParameter.AllowOverrideSource && scopedParameter.Scope != database.ParameterScopeProject {
176-
continue
177-
}
178-
}
183+
func (c *compute) injectSingle(scopedParameter database.ParameterValue) error {
184+
parameterSchema, hasParameterSchema := c.parameterSchemasByName[scopedParameter.Name]
185+
if !hasParameterSchema {
186+
// Don't inject parameters that aren't defined by the project.
187+
return nil
188+
}
179189

180-
destinationScheme, err := convertDestinationScheme(scopedParameter.DestinationScheme)
181-
if err != nil {
182-
return xerrors.Errorf("convert destination scheme: %w", err)
190+
_, hasExistingParameter := c.computedParameterByName[scopedParameter.Name]
191+
if hasExistingParameter {
192+
// If a parameter already exists, check if this variable can override it.
193+
// Injection hierarchy is the responsibility of the caller. This check ensures
194+
// project parameters cannot be overridden if already set.
195+
if !parameterSchema.AllowOverrideSource && scopedParameter.Scope != database.ParameterScopeProject {
196+
return nil
183197
}
198+
}
184199

185-
switch scopedParameter.SourceScheme {
186-
case database.ParameterSourceSchemeData:
187-
c.computedParameterByName[projectVersionParameter.Name] = Value{
188-
Proto: &proto.ParameterValue{
189-
DestinationScheme: destinationScheme,
190-
Name: scopedParameter.SourceValue,
191-
Value: scopedParameter.DestinationValue,
192-
},
193-
}
194-
default:
195-
return xerrors.Errorf("unsupported source scheme: %q", string(projectVersionParameter.DefaultSourceScheme))
200+
destinationScheme, err := convertDestinationScheme(scopedParameter.DestinationScheme)
201+
if err != nil {
202+
return xerrors.Errorf("convert destination scheme: %w", err)
203+
}
204+
205+
switch scopedParameter.SourceScheme {
206+
case database.ParameterSourceSchemeData:
207+
c.computedParameterByName[parameterSchema.Name] = Value{
208+
Proto: &proto.ParameterValue{
209+
DestinationScheme: destinationScheme,
210+
Name: scopedParameter.SourceValue,
211+
Value: scopedParameter.DestinationValue,
212+
},
196213
}
214+
default:
215+
return xerrors.Errorf("unsupported source scheme: %q", string(parameterSchema.DefaultSourceScheme))
197216
}
198217
return nil
199218
}

coderd/projectparameter/projectparameter_test.go

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ func TestCompute(t *testing.T) {
1919
t.Parallel()
2020
generateScope := func() projectparameter.Scope {
2121
return projectparameter.Scope{
22-
OrganizationID: uuid.New().String(),
23-
ProjectID: uuid.New(),
24-
ImportJobID: uuid.New(),
22+
ImportJobID: uuid.New(),
23+
OrganizationID: sql.NullString{
24+
String: uuid.New().String(),
25+
Valid: true,
26+
},
27+
ProjectID: uuid.NullUUID{
28+
UUID: uuid.New(),
29+
Valid: true,
30+
},
2531
WorkspaceID: uuid.NullUUID{
2632
UUID: uuid.New(),
2733
Valid: true,
@@ -101,7 +107,7 @@ func TestCompute(t *testing.T) {
101107
value := values[0]
102108
require.True(t, value.DefaultValue)
103109
require.Equal(t, database.ParameterScopeProject, value.Scope)
104-
require.Equal(t, scope.ProjectID.String(), value.ScopeID)
110+
require.Equal(t, scope.ProjectID.UUID.String(), value.ScopeID)
105111
require.Equal(t, value.Proto.Name, parameter.DefaultDestinationValue.String)
106112
require.Equal(t, value.Proto.DestinationScheme, proto.ParameterDestination_PROVISIONER_VARIABLE)
107113
require.Equal(t, value.Proto.Value, parameter.DefaultSourceValue.String)
@@ -118,7 +124,7 @@ func TestCompute(t *testing.T) {
118124
ID: uuid.New(),
119125
Name: parameter.Name,
120126
Scope: database.ParameterScopeOrganization,
121-
ScopeID: scope.OrganizationID,
127+
ScopeID: scope.OrganizationID.String,
122128
SourceScheme: database.ParameterSourceSchemeData,
123129
SourceValue: "nop",
124130
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
@@ -144,7 +150,7 @@ func TestCompute(t *testing.T) {
144150
ID: uuid.New(),
145151
Name: parameter.Name,
146152
Scope: database.ParameterScopeProject,
147-
ScopeID: scope.ProjectID.String(),
153+
ScopeID: scope.ProjectID.UUID.String(),
148154
SourceScheme: database.ParameterSourceSchemeData,
149155
SourceValue: "nop",
150156
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
@@ -209,4 +215,37 @@ func TestCompute(t *testing.T) {
209215
require.Len(t, values, 1)
210216
require.Equal(t, false, values[0].DefaultValue)
211217
})
218+
219+
t.Run("AdditionalOverwriteWorkspace", func(t *testing.T) {
220+
t.Parallel()
221+
db := databasefake.New()
222+
scope := generateScope()
223+
parameter := generateProjectParameter(t, db, projectParameterOptions{
224+
AllowOverrideSource: true,
225+
ImportJobID: scope.ImportJobID,
226+
})
227+
_, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
228+
ID: uuid.New(),
229+
Name: parameter.Name,
230+
Scope: database.ParameterScopeWorkspace,
231+
ScopeID: scope.WorkspaceID.UUID.String(),
232+
SourceScheme: database.ParameterSourceSchemeData,
233+
SourceValue: "nop",
234+
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
235+
DestinationValue: "projectvalue",
236+
})
237+
require.NoError(t, err)
238+
239+
values, err := projectparameter.Compute(context.Background(), db, scope, database.ParameterValue{
240+
Name: parameter.Name,
241+
Scope: database.ParameterScopeUser,
242+
SourceScheme: database.ParameterSourceSchemeData,
243+
SourceValue: "nop",
244+
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
245+
DestinationValue: "testing",
246+
})
247+
require.NoError(t, err)
248+
require.Len(t, values, 1)
249+
require.Equal(t, "testing", values[0].Proto.Value)
250+
})
212251
}

0 commit comments

Comments
 (0)