-
Notifications
You must be signed in to change notification settings - Fork 26
/
resource_version.go
139 lines (118 loc) · 3.8 KB
/
resource_version.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package spacelift
import (
"context"
"time"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/shurcooL/graphql"
"github.com/spacelift-io/terraform-provider-spacelift/spacelift/internal"
"github.com/spacelift-io/terraform-provider-spacelift/spacelift/internal/validations"
)
func resourceVersion() *schema.Resource {
return &schema.Resource{
Description: "" +
"`spacelift_version` allows to programmatically trigger a module version creation " +
"in response to arbitrary changes in the keepers section.",
CreateContext: resourceVersionCreate,
ReadContext: schema.NoopContext,
Delete: schema.RemoveFromState,
Schema: map[string]*schema.Schema{
"module_id": {
Type: schema.TypeString,
Description: "ID of the module on which the version creation is to be triggered.",
Required: true,
ForceNew: true,
ValidateDiagFunc: validations.DisallowEmptyString,
},
"commit_sha": {
Description: "The commit SHA for which to trigger a version.",
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"version_number": {
Description: "A semantic version number to set for the triggered version, example: 0.11.2",
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"keepers": {
Description: "" +
"Arbitrary map of values that, when changed, will trigger " +
"recreation of the resource.",
Type: schema.TypeMap,
Optional: true,
ForceNew: true,
},
"id": {
Description: "The ID of the triggered version.",
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceVersionCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
var mutation struct {
Version struct {
ID string
} `graphql:"versionCreate(module: $module, commitSha: $sha, version: $version)"`
}
moduleID := d.Get("module_id")
variables := map[string]interface{}{
"module": toID(moduleID),
"sha": (*graphql.String)(nil),
"version": (*graphql.String)(nil),
}
if sha, ok := d.GetOk("commit_sha"); ok {
variables["sha"] = toString(sha)
}
if version, ok := d.GetOk("version_number"); ok {
variables["version"] = toString(version)
}
if err := meta.(*internal.Client).Mutate(ctx, "ResourceVersionCreate", &mutation, variables); err != nil {
return diag.Errorf("could not trigger version for module %s: %v", moduleID, internal.FromSpaceliftError(err))
}
if mutation.Version.ID != "" {
diag := waitForVersionCreate(ctx, meta.(*internal.Client), mutation.Version.ID, moduleID.(string))
if diag.HasError() {
return diag
}
}
d.SetId(mutation.Version.ID)
return nil
}
func waitForVersionCreate(ctx context.Context, client *internal.Client, versionID, moduleID string) diag.Diagnostics {
ticker := time.NewTicker(time.Second * 5)
defer ticker.Stop()
variables := map[string]interface{}{
"moduleId": graphql.ID(moduleID),
"versionId": graphql.ID(versionID),
}
for {
select {
case <-ctx.Done():
return diag.FromErr(ctx.Err())
case <-ticker.C:
}
var query struct {
Module struct {
Version struct {
State string `graphql:"state"`
} `graphql:"version(id: $versionId)"`
} `graphql:"module(id: $moduleId)"`
}
if err := client.Query(ctx, "GetVersion", &query, variables); err != nil {
return diag.Errorf("could not query for module %q with version %q: %v", moduleID, versionID, err)
}
switch query.Module.Version.State {
case "ACTIVE":
return nil
case "FAILED":
return diag.Errorf("module %q version %q creation failed, please check the run logs for more information", moduleID, versionID)
default:
// We wait if module version is in any other state.
continue
}
}
}