• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Scalr / terraform-provider-scalr / 14440924069

14 Apr 2025 08:23AM UTC coverage: 65.436% (-2.1%) from 67.516%
14440924069

push

github

web-flow
SCALRCORE-33934 [TF-PROVIDER] Scalr Provider > Add new resources and data source for Hooks (#403)

* SCALRCORE-33934 add scalr_hook resource

* SCALRCORE-33934 add scalr_hook resource

* SCALRCORE-33934 delete unused code

* SCALRCORE-33934 delete test

* SCALRCORE-33934 add scalr_hook datasource

* SCALRCORE-33934 add scalr_hook_environment_link resource

* SCALRCORE-33934 fix doc

* SCALRCORE-33934 fix test

* SCALRCORE-33934 CR fixes

* SCALRCORE-33934 small fixes

* Update examples/resources/scalr_environment_hook/import.sh

Co-authored-by: Petro Protsakh <p.protsakh@scalr.com>

* Update internal/provider/hook_resource.go

Co-authored-by: Petro Protsakh <p.protsakh@scalr.com>

* Update internal/provider/hook_resource.go

Co-authored-by: Petro Protsakh <p.protsakh@scalr.com>

* Update internal/provider/environment_hook_resource.go

Co-authored-by: Petro Protsakh <p.protsakh@scalr.com>

* SCALRCORE-33934 CR fixes

* SCALRCORE-33934 CR fixes

* SCALRCORE-33934 CR fixes

* SCALRCORE-33934 CR fixes

* SCALRCORE-33934 CR fixes

* SCALRCORE-33934 CR fixes

* SCALRCORE-33934 Update env hook asterisk logic

* SCALRCORE-33934 Generate docs

* SCALRCORE-33934 Roll back messed go.mod

* SCALRCORE-33934 update go.mod/sum files

* SCALRCORE-33934 fix typo docs

---------

Co-authored-by: Petro Protsakh <p.protsakh@scalr.com>

184 of 646 new or added lines in 5 files covered. (28.48%)

2 existing lines in 1 file now uncovered.

7995 of 12218 relevant lines covered (65.44%)

237.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

38.62
/internal/provider/hook_data_source.go
1
package provider
2

3
import (
4
        "context"
5
        "fmt"
6

7
        "github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator"
8
        "github.com/hashicorp/terraform-plugin-framework/attr"
9
        "github.com/hashicorp/terraform-plugin-framework/datasource"
10
        "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
11
        "github.com/hashicorp/terraform-plugin-framework/path"
12
        "github.com/hashicorp/terraform-plugin-framework/schema/validator"
13
        "github.com/hashicorp/terraform-plugin-framework/types"
14
        "github.com/scalr/go-scalr"
15

16
        "github.com/scalr/terraform-provider-scalr/internal/framework"
17
        "github.com/scalr/terraform-provider-scalr/internal/framework/validation"
18
)
19

20
// Compile-time interface checks
21
var (
22
        _ datasource.DataSource                     = &hookDataSource{}
23
        _ datasource.DataSourceWithConfigure        = &hookDataSource{}
24
        _ datasource.DataSourceWithConfigValidators = &hookDataSource{}
25
)
26

27
func newHookDataSource() datasource.DataSource {
1,622✔
28
        return &hookDataSource{}
1,622✔
29
}
1,622✔
30

31
// hookDataSource defines the data source implementation.
32
type hookDataSource struct {
33
        framework.DataSourceWithScalrClient
34
}
35

36
// hookDataSourceModel describes the data source data model.
37
type hookDataSourceModel struct {
38
        Id             types.String `tfsdk:"id"`
39
        Name           types.String `tfsdk:"name"`
40
        Description    types.String `tfsdk:"description"`
41
        Interpreter    types.String `tfsdk:"interpreter"`
42
        ScriptfilePath types.String `tfsdk:"scriptfile_path"`
43
        VcsProviderId  types.String `tfsdk:"vcs_provider_id"`
44
        VcsRepo        types.List   `tfsdk:"vcs_repo"`
45
}
46

47
// hookDataSourceVcsRepoModel maps the vcs_repo nested schema data.
48
type hookDataSourceVcsRepoModel struct {
49
        Identifier types.String `tfsdk:"identifier"`
50
        Branch     types.String `tfsdk:"branch"`
51
}
52

53
func (d *hookDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
100✔
54
        resp.TypeName = req.ProviderTypeName + "_hook"
100✔
55
}
100✔
56

57
func (d *hookDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
1,522✔
58
        resp.Schema = schema.Schema{
1,522✔
59
                MarkdownDescription: "Retrieves information about a hook.",
1,522✔
60

1,522✔
61
                Attributes: map[string]schema.Attribute{
1,522✔
62
                        "id": schema.StringAttribute{
1,522✔
63
                                MarkdownDescription: "The identifier of the hook in the format `hook-<RANDOM STRING>`.",
1,522✔
64
                                Optional:            true,
1,522✔
65
                                Computed:            true,
1,522✔
66
                                Validators: []validator.String{
1,522✔
67
                                        validation.StringIsNotWhiteSpace(),
1,522✔
68
                                },
1,522✔
69
                        },
1,522✔
70
                        "name": schema.StringAttribute{
1,522✔
71
                                MarkdownDescription: "The name of the hook.",
1,522✔
72
                                Optional:            true,
1,522✔
73
                                Computed:            true,
1,522✔
74
                                Validators: []validator.String{
1,522✔
75
                                        validation.StringIsNotWhiteSpace(),
1,522✔
76
                                },
1,522✔
77
                        },
1,522✔
78
                        "description": schema.StringAttribute{
1,522✔
79
                                MarkdownDescription: "Description of the hook.",
1,522✔
80
                                Computed:            true,
1,522✔
81
                        },
1,522✔
82
                        "interpreter": schema.StringAttribute{
1,522✔
83
                                MarkdownDescription: "The interpreter to execute the hook script, such as 'bash', 'python3', etc.",
1,522✔
84
                                Computed:            true,
1,522✔
85
                        },
1,522✔
86
                        "scriptfile_path": schema.StringAttribute{
1,522✔
87
                                MarkdownDescription: "Path to the script file in the repository.",
1,522✔
88
                                Computed:            true,
1,522✔
89
                        },
1,522✔
90
                        "vcs_provider_id": schema.StringAttribute{
1,522✔
91
                                MarkdownDescription: "ID of the VCS provider in the format `vcs-<RANDOM STRING>`.",
1,522✔
92
                                Computed:            true,
1,522✔
93
                        },
1,522✔
94
                        "vcs_repo": schema.ListAttribute{
1,522✔
95
                                MarkdownDescription: "Settings for the repository where the hook script is stored.",
1,522✔
96
                                Computed:            true,
1,522✔
97
                                ElementType: types.ObjectType{
1,522✔
98
                                        AttrTypes: map[string]attr.Type{
1,522✔
99
                                                "identifier": types.StringType,
1,522✔
100
                                                "branch":     types.StringType,
1,522✔
101
                                        },
1,522✔
102
                                },
1,522✔
103
                        },
1,522✔
104
                },
1,522✔
105
        }
1,522✔
106
}
1,522✔
107

NEW
108
func (d *hookDataSource) ConfigValidators(_ context.Context) []datasource.ConfigValidator {
×
NEW
109
        return []datasource.ConfigValidator{
×
NEW
110
                datasourcevalidator.AtLeastOneOf(
×
NEW
111
                        path.MatchRoot("id"),
×
NEW
112
                        path.MatchRoot("name"),
×
NEW
113
                ),
×
NEW
114
        }
×
NEW
115
}
×
116

NEW
117
func (d *hookDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
×
NEW
118
        var cfg hookDataSourceModel
×
NEW
119

×
NEW
120
        resp.Diagnostics.Append(req.Config.Get(ctx, &cfg)...)
×
NEW
121
        if resp.Diagnostics.HasError() {
×
NEW
122
                return
×
NEW
123
        }
×
124

NEW
125
        opts := scalr.HookListOptions{}
×
NEW
126

×
NEW
127
        if !cfg.Id.IsNull() {
×
NEW
128
                opts.Hook = cfg.Id.ValueStringPointer()
×
NEW
129
        }
×
130

NEW
131
        if !cfg.Name.IsNull() {
×
NEW
132
                opts.Name = cfg.Name.ValueString()
×
NEW
133
        }
×
134

NEW
135
        hooks, err := d.Client.Hooks.List(ctx, opts)
×
NEW
136
        if err != nil {
×
NEW
137
                resp.Diagnostics.AddError("Error retrieving hook", err.Error())
×
NEW
138
                return
×
NEW
139
        }
×
140

NEW
141
        if !cfg.Id.IsNull() {
×
NEW
142
                idToFind := cfg.Id.ValueString()
×
NEW
143
                filteredHooks := make([]*scalr.Hook, 0)
×
NEW
144

×
NEW
145
                for _, hook := range hooks.Items {
×
NEW
146
                        if hook.ID == idToFind {
×
NEW
147
                                filteredHooks = append(filteredHooks, hook)
×
NEW
148
                        }
×
149
                }
150

NEW
151
                hooks.Items = filteredHooks
×
NEW
152
                hooks.TotalCount = len(filteredHooks)
×
153
        }
154

NEW
155
        if hooks.TotalCount > 1 {
×
NEW
156
                resp.Diagnostics.AddError(
×
NEW
157
                        "Error retrieving hook",
×
NEW
158
                        "Your query returned more than one result. Please try a more specific search criteria.",
×
NEW
159
                )
×
NEW
160
                return
×
NEW
161
        }
×
162

NEW
163
        if hooks.TotalCount == 0 {
×
NEW
164
                resp.Diagnostics.AddError(
×
NEW
165
                        "Error retrieving hook",
×
NEW
166
                        fmt.Sprintf("Could not find hook with ID '%s', name '%s'.", cfg.Id.ValueString(), cfg.Name.ValueString()),
×
NEW
167
                )
×
NEW
168
                return
×
NEW
169
        }
×
170

NEW
171
        hook := hooks.Items[0]
×
NEW
172

×
NEW
173
        cfg.Id = types.StringValue(hook.ID)
×
NEW
174
        cfg.Name = types.StringValue(hook.Name)
×
NEW
175

×
NEW
176
        if hook.Description != "" {
×
NEW
177
                cfg.Description = types.StringValue(hook.Description)
×
NEW
178
        } else {
×
NEW
179
                cfg.Description = types.StringNull()
×
NEW
180
        }
×
181

NEW
182
        cfg.Interpreter = types.StringValue(hook.Interpreter)
×
NEW
183
        cfg.ScriptfilePath = types.StringValue(hook.ScriptfilePath)
×
NEW
184

×
NEW
185
        if hook.VcsProvider != nil {
×
NEW
186
                cfg.VcsProviderId = types.StringValue(hook.VcsProvider.ID)
×
NEW
187
        }
×
188

NEW
189
        if hook.VcsRepo != nil {
×
NEW
190
                vcsRepoModel := hookDataSourceVcsRepoModel{
×
NEW
191
                        Identifier: types.StringValue(hook.VcsRepo.Identifier),
×
NEW
192
                        Branch:     types.StringValue(hook.VcsRepo.Branch),
×
NEW
193
                }
×
NEW
194

×
NEW
195
                vcsRepos := []hookDataSourceVcsRepoModel{vcsRepoModel}
×
NEW
196

×
NEW
197
                vcsRepoList, diags := types.ListValueFrom(ctx, types.ObjectType{
×
NEW
198
                        AttrTypes: map[string]attr.Type{
×
NEW
199
                                "identifier": types.StringType,
×
NEW
200
                                "branch":     types.StringType,
×
NEW
201
                        },
×
NEW
202
                }, vcsRepos)
×
NEW
203

×
NEW
204
                if diags.HasError() {
×
NEW
205
                        resp.Diagnostics.AddError("Error creating VCS repo list", diags.Errors()[0].Summary())
×
NEW
206
                        return
×
NEW
207
                }
×
208

NEW
209
                cfg.VcsRepo = vcsRepoList
×
210
        }
211

NEW
212
        resp.Diagnostics.Append(resp.State.Set(ctx, &cfg)...)
×
213
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc