Skip to content

Commit 79a56b6

Browse files
committed
Basic creation flow works!
1 parent 8fe05d6 commit 79a56b6

File tree

13 files changed

+377
-260
lines changed

13 files changed

+377
-260
lines changed

cli/projectcreate.go

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ import (
1111

1212
"github.com/briandowns/spinner"
1313
"github.com/fatih/color"
14+
"github.com/google/uuid"
1415
"github.com/manifoldco/promptui"
1516
"github.com/spf13/cobra"
1617
"golang.org/x/xerrors"
1718

1819
"github.com/coder/coder/coderd"
1920
"github.com/coder/coder/codersdk"
2021
"github.com/coder/coder/database"
22+
"github.com/coder/coder/provisionerd"
2123
)
2224

2325
func projectCreate() *cobra.Command {
@@ -49,8 +51,8 @@ func projectCreate() *cobra.Command {
4951
Default: filepath.Base(directory),
5052
Label: "What's your project's name?",
5153
Validate: func(s string) error {
52-
_, err = client.Project(cmd.Context(), organization.Name, s)
53-
if err == nil {
54+
project, _ := client.Project(cmd.Context(), organization.Name, s)
55+
if project.ID.String() != uuid.Nil.String() {
5456
return xerrors.New("A project already exists with that name!")
5557
}
5658
return nil
@@ -63,6 +65,7 @@ func projectCreate() *cobra.Command {
6365
spin := spinner.New(spinner.CharSets[0], 25*time.Millisecond)
6466
spin.Suffix = " Uploading current directory..."
6567
spin.Start()
68+
6669
defer spin.Stop()
6770

6871
bytes, err := tarDirectory(directory)
@@ -79,14 +82,6 @@ func projectCreate() *cobra.Command {
7982
StorageMethod: database.ProvisionerStorageMethodFile,
8083
StorageSource: resp.Hash,
8184
Provisioner: database.ProvisionerTypeTerraform,
82-
// SkipResources on first import to detect variables defined by the project.
83-
SkipResources: true,
84-
// ParameterValues: []coderd.CreateParameterValueRequest{{
85-
// Name: "aws_access_key",
86-
// SourceValue: "tomato",
87-
// SourceScheme: database.ParameterSourceSchemeData,
88-
// DestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
89-
// }},
9085
})
9186
if err != nil {
9287
return err
@@ -102,33 +97,60 @@ func projectCreate() *cobra.Command {
10297
if !ok {
10398
break
10499
}
105-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s %s\n", color.HiGreenString("[parse]"), log.Output)
100+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s %s\n", color.HiGreenString("[tf]"), log.Output)
106101
}
107102

108-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Parsed project source... displaying parameters:")
109-
110-
schemas, err := client.ProvisionerJobParameterSchemas(cmd.Context(), organization.Name, job.ID)
103+
job, err = client.ProvisionerJob(cmd.Context(), organization.Name, job.ID)
111104
if err != nil {
112105
return err
113106
}
114107

115-
values, err := client.ProvisionerJobParameterValues(cmd.Context(), organization.Name, job.ID)
108+
if provisionerd.IsMissingParameterError(job.Error) {
109+
fmt.Printf("Missing something!\n")
110+
return nil
111+
}
112+
113+
resources, err := client.ProvisionerJobResources(cmd.Context(), organization.Name, job.ID)
116114
if err != nil {
117115
return err
118116
}
119-
valueBySchemaID := map[string]coderd.ComputedParameterValue{}
120-
for _, value := range values {
121-
valueBySchemaID[value.SchemaID.String()] = value
122-
}
123117

124-
for _, schema := range schemas {
125-
if value, ok := valueBySchemaID[schema.ID.String()]; ok {
126-
fmt.Printf("Value for: %s %s\n", value.Name, value.SourceValue)
127-
continue
128-
}
129-
fmt.Printf("No value for: %s\n", schema.Name)
118+
fmt.Printf("Resources: %+v\n", resources)
119+
120+
project, err := client.CreateProject(cmd.Context(), organization.Name, coderd.CreateProjectRequest{
121+
Name: name,
122+
VersionImportJobID: job.ID,
123+
})
124+
if err != nil {
125+
return err
130126
}
131127

128+
fmt.Printf("Project: %+v\n", project)
129+
130+
// _, _ = fmt.Fprintf(cmd.OutOrStdout(), "Parsed project source... displaying parameters:")
131+
132+
// schemas, err := client.ProvisionerJobParameterSchemas(cmd.Context(), organization.Name, job.ID)
133+
// if err != nil {
134+
// return err
135+
// }
136+
137+
// values, err := client.ProvisionerJobParameterValues(cmd.Context(), organization.Name, job.ID)
138+
// if err != nil {
139+
// return err
140+
// }
141+
// valueBySchemaID := map[string]coderd.ComputedParameterValue{}
142+
// for _, value := range values {
143+
// valueBySchemaID[value.SchemaID.String()] = value
144+
// }
145+
146+
// for _, schema := range schemas {
147+
// if value, ok := valueBySchemaID[schema.ID.String()]; ok {
148+
// fmt.Printf("Value for: %s %s\n", value.Name, value.SourceValue)
149+
// continue
150+
// }
151+
// fmt.Printf("No value for: %s\n", schema.Name)
152+
// }
153+
132154
// schemas, err := client.ProvisionerJobParameterSchemas(cmd.Context(), organization.Name, job.ID)
133155
// if err != nil {
134156
// return err

cli/root.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,16 @@ func runPrompt(cmd *cobra.Command, prompt *promptui.Prompt) (string, error) {
161161
Invalid: invalid,
162162
Valid: valid,
163163
}
164+
oldValidate := prompt.Validate
165+
if oldValidate != nil {
166+
// Override the validate function to pass our default!
167+
prompt.Validate = func(s string) error {
168+
if s == "" {
169+
s = defaultValue
170+
}
171+
return oldValidate(s)
172+
}
173+
}
164174
value, err := prompt.Run()
165175
if value == "" && !prompt.IsConfirm {
166176
value = defaultValue

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ func New(options *Options) http.Handler {
123123
r.Get("/", api.provisionerJobByOrganization)
124124
r.Get("/schemas", api.provisionerJobParameterSchemasByID)
125125
r.Get("/computed", api.provisionerJobComputedParametersByID)
126+
r.Get("/resources", api.provisionerJobResourcesByID)
126127
r.Get("/logs", api.provisionerJobLogsByID)
127128
})
128129
})

coderd/provisionerdaemons.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,30 @@ func (server *provisionerdServer) CompleteJob(ctx context.Context, completed *pr
437437

438438
switch jobType := completed.Type.(type) {
439439
case *proto.CompletedJob_ProjectImport_:
440+
for transition, resources := range map[database.WorkspaceTransition][]*sdkproto.Resource{
441+
database.WorkspaceTransitionStart: jobType.ProjectImport.StartResources,
442+
database.WorkspaceTransitionStop: jobType.ProjectImport.StopResources,
443+
} {
444+
for _, resource := range resources {
445+
server.Logger.Info(ctx, "inserting project import job resource",
446+
slog.F("job_id", job.ID.String()),
447+
slog.F("resource_name", resource.Name),
448+
slog.F("resource_type", resource.Type),
449+
slog.F("transition", transition))
450+
_, err = server.Database.InsertProjectImportJobResource(ctx, database.InsertProjectImportJobResourceParams{
451+
ID: uuid.New(),
452+
CreatedAt: database.Now(),
453+
JobID: jobID,
454+
Transition: transition,
455+
Type: resource.Type,
456+
Name: resource.Name,
457+
})
458+
if err != nil {
459+
return nil, xerrors.Errorf("insert resource: %w", err)
460+
}
461+
}
462+
}
463+
440464
err = server.Database.UpdateProvisionerJobWithCompleteByID(ctx, database.UpdateProvisionerJobWithCompleteByIDParams{
441465
ID: jobID,
442466
UpdatedAt: database.Now(),

coderd/provisionerjobs.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
"github.com/coder/coder/httpmw"
1717
)
1818

19+
type ProjectImportJobResource database.ProjectImportJobResource
20+
1921
type ProvisionerJobStatus string
2022

2123
// Completed returns whether the job is still processing.
@@ -125,9 +127,9 @@ func (api *api) postProvisionerImportJobByOrganization(rw http.ResponseWriter, r
125127
// Return parsed parameter schemas for a job.
126128
func (api *api) provisionerJobParameterSchemasByID(rw http.ResponseWriter, r *http.Request) {
127129
job := httpmw.ProvisionerJobParam(r)
128-
if convertProvisionerJob(job).Status != ProvisionerJobStatusSucceeded {
130+
if !convertProvisionerJob(job).Status.Completed() {
129131
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
130-
Message: fmt.Sprintf("Job is in state %q! Must be %q.", convertProvisionerJob(job).Status, ProvisionerJobStatusSucceeded),
132+
Message: "Job hasn't completed!",
131133
})
132134
return
133135
}
@@ -150,9 +152,9 @@ func (api *api) provisionerJobParameterSchemasByID(rw http.ResponseWriter, r *ht
150152
func (api *api) provisionerJobComputedParametersByID(rw http.ResponseWriter, r *http.Request) {
151153
apiKey := httpmw.APIKey(r)
152154
job := httpmw.ProvisionerJobParam(r)
153-
if convertProvisionerJob(job).Status != ProvisionerJobStatusSucceeded {
155+
if !convertProvisionerJob(job).Status.Completed() {
154156
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
155-
Message: fmt.Sprintf("Job is in state %q! Must be %q.", convertProvisionerJob(job).Status, ProvisionerJobStatusSucceeded),
157+
Message: "Job hasn't completed!",
156158
})
157159
return
158160
}
@@ -163,6 +165,29 @@ func (api *api) provisionerJobComputedParametersByID(rw http.ResponseWriter, r *
163165
})
164166
}
165167

168+
func (api *api) provisionerJobResourcesByID(rw http.ResponseWriter, r *http.Request) {
169+
job := httpmw.ProvisionerJobParam(r)
170+
if !convertProvisionerJob(job).Status.Completed() {
171+
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
172+
Message: "Job hasn't completed!",
173+
})
174+
return
175+
}
176+
resources, err := api.Database.GetProjectImportJobResourcesByJobID(r.Context(), job.ID)
177+
if errors.Is(err, sql.ErrNoRows) {
178+
err = nil
179+
}
180+
if err != nil {
181+
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
182+
Message: fmt.Sprintf("get project import job resources: %s", err),
183+
})
184+
return
185+
}
186+
187+
render.Status(r, http.StatusOK)
188+
render.JSON(rw, r, resources)
189+
}
190+
166191
func convertProvisionerJob(provisionerJob database.ProvisionerJob) ProvisionerJob {
167192
job := ProvisionerJob{
168193
ID: provisionerJob.ID,

coderd/provisionerjobs_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/coder/coder/coderd"
1212
"github.com/coder/coder/coderd/coderdtest"
13+
"github.com/coder/coder/coderd/parameter"
1314
"github.com/coder/coder/codersdk"
1415
"github.com/coder/coder/database"
1516
"github.com/coder/coder/provisioner/echo"
@@ -170,3 +171,39 @@ func TestProvisionerJobParametersByID(t *testing.T) {
170171
require.Equal(t, params[0].SourceValue, "")
171172
})
172173
}
174+
175+
func TestProvisionerJobResourcesByID(t *testing.T) {
176+
t.Parallel()
177+
t.Run("Something", func(t *testing.T) {
178+
t.Parallel()
179+
client := coderdtest.New(t)
180+
user := coderdtest.CreateInitialUser(t, client)
181+
_ = coderdtest.NewProvisionerDaemon(t, client)
182+
job := coderdtest.CreateProjectImportProvisionerJob(t, client, user.Organization, &echo.Responses{
183+
Parse: []*proto.Parse_Response{{
184+
Type: &proto.Parse_Response_Complete{
185+
Complete: &proto.Parse_Complete{
186+
ParameterSchemas: []*proto.ParameterSchema{{
187+
Name: parameter.CoderWorkspaceTransition,
188+
}},
189+
},
190+
},
191+
}},
192+
Provision: []*proto.Provision_Response{{
193+
Type: &proto.Provision_Response_Complete{
194+
Complete: &proto.Provision_Complete{
195+
Resources: []*proto.Resource{{
196+
Name: "hello",
197+
Type: "ec2_instance",
198+
}},
199+
},
200+
},
201+
}},
202+
})
203+
coderdtest.AwaitProvisionerJob(t, client, user.Organization, job.ID)
204+
resources, err := client.ProvisionerJobResources(context.Background(), user.Organization, job.ID)
205+
require.NoError(t, err)
206+
// One for start, and one for stop!
207+
require.Len(t, resources, 2)
208+
})
209+
}

codersdk/provisioners.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,16 @@ func (c *Client) ProvisionerJobParameterValues(ctx context.Context, organization
179179
var params []coderd.ComputedParameterValue
180180
return params, json.NewDecoder(res.Body).Decode(&params)
181181
}
182+
183+
func (c *Client) ProvisionerJobResources(ctx context.Context, organization string, job uuid.UUID) ([]coderd.ProjectImportJobResource, error) {
184+
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/provisioners/jobs/%s/%s/resources", organization, job), nil)
185+
if err != nil {
186+
return nil, err
187+
}
188+
defer res.Body.Close()
189+
if res.StatusCode != http.StatusOK {
190+
return nil, readBodyAsError(res)
191+
}
192+
var resources []coderd.ProjectImportJobResource
193+
return resources, json.NewDecoder(res.Body).Decode(&resources)
194+
}

database/databasefake/databasefake.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,23 @@ func (q *fakeQuerier) GetProjectByOrganizationAndName(_ context.Context, arg dat
401401
return database.Project{}, sql.ErrNoRows
402402
}
403403

404+
func (q *fakeQuerier) GetProjectImportJobResourcesByJobID(ctx context.Context, jobID uuid.UUID) ([]database.ProjectImportJobResource, error) {
405+
q.mutex.Lock()
406+
defer q.mutex.Unlock()
407+
408+
resources := make([]database.ProjectImportJobResource, 0)
409+
for _, resource := range q.projectImportJobResource {
410+
if resource.JobID.String() != jobID.String() {
411+
continue
412+
}
413+
resources = append(resources, resource)
414+
}
415+
if len(resources) == 0 {
416+
return nil, sql.ErrNoRows
417+
}
418+
return resources, nil
419+
}
420+
404421
func (q *fakeQuerier) GetProjectVersionsByProjectID(_ context.Context, projectID uuid.UUID) ([]database.ProjectVersion, error) {
405422
q.mutex.Lock()
406423
defer q.mutex.Unlock()

database/querier.go

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

database/query.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,14 @@ FROM
173173
WHERE
174174
job_id = $1;
175175

176+
-- name: GetProjectImportJobResourcesByJobID :many
177+
SELECT
178+
*
179+
FROM
180+
project_import_job_resource
181+
WHERE
182+
job_id = $1;
183+
176184
-- name: GetProjectVersionsByProjectID :many
177185
SELECT
178186
*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy