|
7 | 7 | "database/sql"
|
8 | 8 | "encoding/json"
|
9 | 9 | "fmt"
|
| 10 | + "log" |
10 | 11 | "net/http"
|
11 | 12 | "time"
|
12 | 13 |
|
@@ -55,14 +56,17 @@ type Builder struct {
|
55 | 56 | store database.Store
|
56 | 57 |
|
57 | 58 | // cache of objects, so we only fetch once
|
58 |
| - template *database.Template |
59 |
| - templateVersion *database.TemplateVersion |
60 |
| - templateVersionJob *database.ProvisionerJob |
61 |
| - templateVersionParameters *[]database.TemplateVersionParameter |
62 |
| - lastBuild *database.WorkspaceBuild |
63 |
| - lastBuildErr *error |
64 |
| - lastBuildParameters *[]database.WorkspaceBuildParameter |
65 |
| - lastBuildJob *database.ProvisionerJob |
| 59 | + template *database.Template |
| 60 | + templateVersion *database.TemplateVersion |
| 61 | + templateVersionJob *database.ProvisionerJob |
| 62 | + templateVersionParameters *[]database.TemplateVersionParameter |
| 63 | + templateVersionWorkspaceTags *[]database.TemplateVersionWorkspaceTag |
| 64 | + lastBuild *database.WorkspaceBuild |
| 65 | + lastBuildErr *error |
| 66 | + lastBuildParameters *[]database.WorkspaceBuildParameter |
| 67 | + lastBuildJob *database.ProvisionerJob |
| 68 | + parameterNames *[]string |
| 69 | + parameterValues *[]string |
66 | 70 |
|
67 | 71 | verifyNoLegacyParametersOnce bool
|
68 | 72 | }
|
@@ -297,7 +301,11 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object
|
297 | 301 | if err != nil {
|
298 | 302 | return nil, nil, BuildError{http.StatusInternalServerError, "marshal metadata", err}
|
299 | 303 | }
|
300 |
| - tags := provisionersdk.MutateTags(b.workspace.OwnerID, templateVersionJob.Tags) |
| 304 | + |
| 305 | + tags, err := b.getProvisionerTags() |
| 306 | + if err != nil { |
| 307 | + return nil, nil, err // already wrapped BuildError |
| 308 | + } |
301 | 309 |
|
302 | 310 | now := dbtime.Now()
|
303 | 311 | provisionerJob, err := b.store.InsertProvisionerJob(b.ctx, database.InsertProvisionerJobParams{
|
@@ -364,6 +372,7 @@ func (b *Builder) buildTx(authFunc func(action policy.Action, object rbac.Object
|
364 | 372 | // getParameters already wraps errors in BuildError
|
365 | 373 | return err
|
366 | 374 | }
|
| 375 | + |
367 | 376 | err = store.InsertWorkspaceBuildParameters(b.ctx, database.InsertWorkspaceBuildParametersParams{
|
368 | 377 | WorkspaceBuildID: workspaceBuildID,
|
369 | 378 | Name: names,
|
@@ -502,6 +511,10 @@ func (b *Builder) getState() ([]byte, error) {
|
502 | 511 | }
|
503 | 512 |
|
504 | 513 | func (b *Builder) getParameters() (names, values []string, err error) {
|
| 514 | + if b.parameterNames != nil { |
| 515 | + return *b.parameterNames, *b.parameterValues, nil |
| 516 | + } |
| 517 | + |
505 | 518 | templateVersionParameters, err := b.getTemplateVersionParameters()
|
506 | 519 | if err != nil {
|
507 | 520 | return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch template version parameters", err}
|
@@ -535,6 +548,9 @@ func (b *Builder) getParameters() (names, values []string, err error) {
|
535 | 548 | names = append(names, templateVersionParameter.Name)
|
536 | 549 | values = append(values, value)
|
537 | 550 | }
|
| 551 | + |
| 552 | + b.parameterNames = &names |
| 553 | + b.parameterValues = &values |
538 | 554 | return names, values, nil
|
539 | 555 | }
|
540 | 556 |
|
@@ -632,6 +648,53 @@ func (b *Builder) getLastBuildJob() (*database.ProvisionerJob, error) {
|
632 | 648 | return b.lastBuildJob, nil
|
633 | 649 | }
|
634 | 650 |
|
| 651 | +func (b *Builder) getProvisionerTags() (map[string]string, error) { |
| 652 | + // Step 1: Fetch required data |
| 653 | + workspaceTags, err := b.getTemplateVersionWorkspaceTags() |
| 654 | + if err != nil { |
| 655 | + return nil, BuildError{http.StatusInternalServerError, "failed to fetch template version workspace tags", err} |
| 656 | + } |
| 657 | + parameterNames, parameterValues, err := b.getParameters() |
| 658 | + if err != nil { |
| 659 | + return nil, err // already wrapped BuildError |
| 660 | + } |
| 661 | + templateVersionJob, err := b.getTemplateVersionJob() |
| 662 | + if err != nil { |
| 663 | + return nil, BuildError{http.StatusInternalServerError, "failed to fetch template version job", err} |
| 664 | + } |
| 665 | + annotationTags := provisionersdk.MutateTags(b.workspace.OwnerID, templateVersionJob.Tags) |
| 666 | + |
| 667 | + // Step 2: Evaluate provisioner tags |
| 668 | + tags := map[string]string{} |
| 669 | + for name, value := range annotationTags { |
| 670 | + tags[name] = value |
| 671 | + } |
| 672 | + |
| 673 | + // FIXME evaluate and merge workspace tags |
| 674 | + log.Println(workspaceTags, parameterNames, parameterValues) |
| 675 | + |
| 676 | + return tags, nil |
| 677 | +} |
| 678 | + |
| 679 | +func (b *Builder) getTemplateVersionWorkspaceTags() ([]database.TemplateVersionWorkspaceTag, error) { |
| 680 | + if b.templateVersionWorkspaceTags != nil { |
| 681 | + return *b.templateVersionWorkspaceTags, nil |
| 682 | + } |
| 683 | + |
| 684 | + templateVersion, err := b.getTemplateVersion() |
| 685 | + if err != nil { |
| 686 | + return nil, xerrors.Errorf("get template version: %w", err) |
| 687 | + } |
| 688 | + |
| 689 | + workspaceTags, err := b.store.GetTemplateVersionWorkspaceTags(b.ctx, templateVersion.ID) |
| 690 | + if err != nil { |
| 691 | + return nil, xerrors.Errorf("get template version workspace tags: %w", err) |
| 692 | + } |
| 693 | + |
| 694 | + b.templateVersionWorkspaceTags = &workspaceTags |
| 695 | + return *b.templateVersionWorkspaceTags, nil |
| 696 | +} |
| 697 | + |
635 | 698 | // authorize performs build authorization pre-checks using the provided authFunc
|
636 | 699 | func (b *Builder) authorize(authFunc func(action policy.Action, object rbac.Objecter) bool) error {
|
637 | 700 | // Doing this up front saves a lot of work if the user doesn't have permission.
|
|
0 commit comments