/
data_source_deployment.go
164 lines (146 loc) · 5.3 KB
/
data_source_deployment.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package vercel
import (
"context"
"fmt"
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/vercel/terraform-provider-vercel/client"
)
// Ensure the implementation satisfies the expected interfaces.
var (
_ datasource.DataSource = &deploymentDataSource{}
_ datasource.DataSourceWithConfigure = &deploymentDataSource{}
)
func newDeploymentDataSource() datasource.DataSource {
return &deploymentDataSource{}
}
type deploymentDataSource struct {
client *client.Client
}
func (d *deploymentDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
resp.TypeName = req.ProviderTypeName + "_deployment"
}
func (d *deploymentDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
// Prevent panic if the provider has not been configured.
if req.ProviderData == nil {
return
}
client, ok := req.ProviderData.(*client.Client)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}
d.client = client
}
// Schema returns the schema information for an deployment data source
func (r *deploymentDataSource) Schema(_ context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Description: `
Provides information about an existing Deployment.
A Deployment is the result of building your Project and making it available through a live URL.
`,
Attributes: map[string]schema.Attribute{
"team_id": schema.StringAttribute{
Description: "The Team ID to the Deployment belong to. Required when reading a team resource if a default team has not been set in the provider.",
Optional: true,
Computed: true,
},
"id": schema.StringAttribute{
Required: true,
Description: "The ID or URL of the Deployment to read.",
},
"domains": schema.ListAttribute{
Description: "A list of all the domains (default domains, staging domains and production domains) that were assigned upon deployment creation.",
Computed: true,
ElementType: types.StringType,
},
"project_id": schema.StringAttribute{
Description: "The project ID to add the deployment to.",
Computed: true,
},
"url": schema.StringAttribute{
Description: "A unique URL that is automatically generated for a deployment.",
Computed: true,
},
"production": schema.BoolAttribute{
Description: "true if the deployment is a production deployment, meaning production aliases will be assigned.",
Computed: true,
},
"ref": schema.StringAttribute{
Description: "The branch or commit hash that has been deployed. Note this will only work if the project is configured to use a Git repository.",
Computed: true,
},
},
}
}
type DeploymentDataSource struct {
Domains types.List `tfsdk:"domains"`
ID types.String `tfsdk:"id"`
Production types.Bool `tfsdk:"production"`
ProjectID types.String `tfsdk:"project_id"`
TeamID types.String `tfsdk:"team_id"`
URL types.String `tfsdk:"url"`
Ref types.String `tfsdk:"ref"`
}
func convertResponseToDeploymentDataSource(in client.DeploymentResponse) DeploymentDataSource {
ref := types.StringNull()
if in.GitSource.Ref != "" {
ref = types.StringValue(in.GitSource.Ref)
}
var domains []attr.Value
for _, a := range in.Aliases {
domains = append(domains, types.StringValue(a))
}
return DeploymentDataSource{
Domains: types.ListValueMust(types.StringType, domains),
Production: types.BoolValue(in.Target != nil && *in.Target == "production"),
TeamID: toTeamID(in.TeamID),
ProjectID: types.StringValue(in.ProjectID),
ID: types.StringValue(in.ID),
URL: types.StringValue(in.URL),
Ref: ref,
}
}
// Read will read the deployment information by requesting it from the Vercel API, and will update terraform
// with this information.
// It is called by the provider whenever data source values should be read to update state.
func (d *deploymentDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
var config DeploymentDataSource
diags := req.Config.Get(ctx, &config)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
out, err := d.client.GetDeployment(ctx, config.ID.ValueString(), config.TeamID.ValueString())
if client.NotFound(err) {
resp.State.RemoveResource(ctx)
return
}
if err != nil {
resp.Diagnostics.AddError(
"Error reading deployment",
fmt.Sprintf("Could not get deployment %s %s, unexpected error: %s",
config.TeamID.ValueString(),
config.ID.ValueString(),
err,
),
)
return
}
result := convertResponseToDeploymentDataSource(out)
tflog.Info(ctx, "read deployment", map[string]interface{}{
"team_id": result.TeamID.ValueString(),
"project_id": result.ID.ValueString(),
})
diags = resp.State.Set(ctx, result)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}