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

Twingate / terraform-provider-twingate / 13158192914

05 Feb 2025 01:14PM UTC coverage: 85.195% (-0.05%) from 85.24%
13158192914

Pull #636

github

web-flow
Bump golang.org/x/sync from 0.10.0 to 0.11.0

Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.10.0 to 0.11.0.
- [Commits](https://github.com/golang/sync/compare/v0.10.0...v0.11.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sync
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #636: Bump golang.org/x/sync from 0.10.0 to 0.11.0

7573 of 8889 relevant lines covered (85.2%)

2.25 hits per line

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

86.9
/twingate/internal/provider/datasource/groups.go
1
package datasource
2

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

8
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/attr"
9
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/client"
10
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/model"
11
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/utils"
12
        "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
13
        "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
14
        tfattr "github.com/hashicorp/terraform-plugin-framework/attr"
15
        "github.com/hashicorp/terraform-plugin-framework/datasource"
16
        "github.com/hashicorp/terraform-plugin-framework/datasource/schema"
17
        "github.com/hashicorp/terraform-plugin-framework/schema/validator"
18
        "github.com/hashicorp/terraform-plugin-framework/types"
19
)
20

21
var ErrGroupsDatasourceShouldSetOneOptionalNameAttribute = errors.New("Only one of name, name_regex, name_contains, name_exclude, name_prefix or name_suffix must be set.")
22

23
// Ensure the implementation satisfies the desired interfaces.
24
var _ datasource.DataSource = &groups{}
25

26
func NewGroupsDatasource() datasource.DataSource {
2✔
27
        return &groups{}
2✔
28
}
2✔
29

30
type groups struct {
31
        client *client.Client
32
}
33

34
type groupsModel struct {
35
        ID           types.String `tfsdk:"id"`
36
        Name         types.String `tfsdk:"name"`
37
        NameRegexp   types.String `tfsdk:"name_regexp"`
38
        NameContains types.String `tfsdk:"name_contains"`
39
        NameExclude  types.String `tfsdk:"name_exclude"`
40
        NamePrefix   types.String `tfsdk:"name_prefix"`
41
        NameSuffix   types.String `tfsdk:"name_suffix"`
42
        Types        types.Set    `tfsdk:"types"`
43
        IsActive     types.Bool   `tfsdk:"is_active"`
44
        Groups       []groupModel `tfsdk:"groups"`
45
}
46

47
func (d *groups) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
2✔
48
        resp.TypeName = TwingateGroups
2✔
49
}
2✔
50

51
func (d *groups) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
2✔
52
        if req.ProviderData == nil {
4✔
53
                return
2✔
54
        }
2✔
55

56
        client, ok := req.ProviderData.(*client.Client)
2✔
57
        if !ok {
2✔
58
                resp.Diagnostics.AddError(
×
59
                        "Unexpected Data Source Configure Type",
×
60
                        fmt.Sprintf("Expected *client.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
×
61
                )
×
62

×
63
                return
×
64
        }
×
65

66
        d.client = client
2✔
67
}
68

69
//nolint:funlen
70
func (d *groups) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
2✔
71
        resp.Schema = schema.Schema{
2✔
72
                Description: "Groups are how users are authorized to access Resources. For more information, see Twingate's [documentation](https://docs.twingate.com/docs/groups).",
2✔
73
                Attributes: map[string]schema.Attribute{
2✔
74
                        attr.ID: schema.StringAttribute{
2✔
75
                                Computed:    true,
2✔
76
                                Description: computedDatasourceIDDescription,
2✔
77
                        },
2✔
78
                        attr.Name: schema.StringAttribute{
2✔
79
                                Optional:    true,
2✔
80
                                Description: "Returns only groups that exactly match this name. If no options are passed it will return all resources. Only one option can be used at a time.",
2✔
81
                        },
2✔
82
                        attr.Name + attr.FilterByRegexp: schema.StringAttribute{
2✔
83
                                Optional:    true,
2✔
84
                                Description: "The regular expression match of the name of the group.",
2✔
85
                        },
2✔
86
                        attr.Name + attr.FilterByContains: schema.StringAttribute{
2✔
87
                                Optional:    true,
2✔
88
                                Description: "Match when the value exist in the name of the group.",
2✔
89
                        },
2✔
90
                        attr.Name + attr.FilterByExclude: schema.StringAttribute{
2✔
91
                                Optional:    true,
2✔
92
                                Description: "Match when the exact value does not exist in the name of the group.",
2✔
93
                        },
2✔
94
                        attr.Name + attr.FilterByPrefix: schema.StringAttribute{
2✔
95
                                Optional:    true,
2✔
96
                                Description: "The name of the group must start with the value.",
2✔
97
                        },
2✔
98
                        attr.Name + attr.FilterBySuffix: schema.StringAttribute{
2✔
99
                                Optional:    true,
2✔
100
                                Description: "The name of the group must end with the value.",
2✔
101
                        },
2✔
102
                        attr.IsActive: schema.BoolAttribute{
2✔
103
                                Optional:    true,
2✔
104
                                Description: "Returns only Groups matching the specified state.",
2✔
105
                        },
2✔
106
                        attr.Types: schema.SetAttribute{
2✔
107
                                Optional:    true,
2✔
108
                                ElementType: types.StringType,
2✔
109
                                Description: fmt.Sprintf("Returns groups that match a list of types. valid types: `%s`, `%s`, `%s`.", model.GroupTypeManual, model.GroupTypeSynced, model.GroupTypeSystem),
2✔
110
                                Validators: []validator.Set{
2✔
111
                                        setvalidator.ValueStringsAre(stringvalidator.OneOf(model.GroupTypeManual, model.GroupTypeSynced, model.GroupTypeSystem)),
2✔
112
                                },
2✔
113
                        },
2✔
114

2✔
115
                        attr.Groups: schema.ListNestedAttribute{
2✔
116
                                Computed:    true,
2✔
117
                                Description: "List of Groups",
2✔
118
                                NestedObject: schema.NestedAttributeObject{
2✔
119
                                        Attributes: map[string]schema.Attribute{
2✔
120
                                                attr.ID: schema.StringAttribute{
2✔
121
                                                        Computed:    true,
2✔
122
                                                        Description: "The ID of the Group",
2✔
123
                                                },
2✔
124
                                                attr.Name: schema.StringAttribute{
2✔
125
                                                        Computed:    true,
2✔
126
                                                        Description: "The name of the Group",
2✔
127
                                                },
2✔
128
                                                attr.IsActive: schema.BoolAttribute{
2✔
129
                                                        Computed:    true,
2✔
130
                                                        Description: "Indicates if the Group is active",
2✔
131
                                                },
2✔
132
                                                attr.Type: schema.StringAttribute{
2✔
133
                                                        Computed:    true,
2✔
134
                                                        Description: "The type of the Group",
2✔
135
                                                },
2✔
136
                                                attr.SecurityPolicyID: schema.StringAttribute{
2✔
137
                                                        Computed:    true,
2✔
138
                                                        Description: "The Security Policy assigned to the Group.",
2✔
139
                                                },
2✔
140
                                        },
2✔
141
                                },
2✔
142
                        },
2✔
143
                },
2✔
144
        }
2✔
145
}
2✔
146

147
func (d *groups) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
2✔
148
        var data groupsModel
2✔
149

2✔
150
        // Read Terraform configuration data into the model
2✔
151
        resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
2✔
152

2✔
153
        if resp.Diagnostics.HasError() {
2✔
154
                return
×
155
        }
×
156

157
        if countOptionalAttributes(data.Name, data.NameRegexp, data.NameContains, data.NameExclude, data.NamePrefix, data.NameSuffix) > 1 {
2✔
158
                addErr(&resp.Diagnostics, ErrGroupsDatasourceShouldSetOneOptionalNameAttribute, TwingateGroups)
×
159

×
160
                return
×
161
        }
×
162

163
        filter := buildFilter(&data)
2✔
164

2✔
165
        groups, err := d.client.ReadGroups(client.WithCallerCtx(ctx, datasourceKey), filter)
2✔
166
        if err != nil && !errors.Is(err, client.ErrGraphqlResultIsEmpty) {
2✔
167
                addErr(&resp.Diagnostics, err, TwingateGroups)
×
168

×
169
                return
×
170
        }
×
171

172
        data.Groups = convertGroupsToTerraform(groups)
2✔
173

2✔
174
        id := "all-groups"
2✔
175
        if filter.HasName() {
4✔
176
                id = "groups-by-name-" + *filter.Name
2✔
177
        }
2✔
178

179
        data.ID = types.StringValue(id)
2✔
180

2✔
181
        // Save data into Terraform state
2✔
182
        resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
2✔
183
}
184

185
//nolint:cyclop
186
func buildFilter(data *groupsModel) *model.GroupsFilter {
2✔
187
        var name, filter string
2✔
188

2✔
189
        if data.Name.ValueString() != "" {
4✔
190
                name = data.Name.ValueString()
2✔
191
        }
2✔
192

193
        if data.NameRegexp.ValueString() != "" {
4✔
194
                name = data.NameRegexp.ValueString()
2✔
195
                filter = attr.FilterByRegexp
2✔
196
        }
2✔
197

198
        if data.NameContains.ValueString() != "" {
4✔
199
                name = data.NameContains.ValueString()
2✔
200
                filter = attr.FilterByContains
2✔
201
        }
2✔
202

203
        if data.NameExclude.ValueString() != "" {
2✔
204
                name = data.NameExclude.ValueString()
×
205
                filter = attr.FilterByExclude
×
206
        }
×
207

208
        if data.NamePrefix.ValueString() != "" {
4✔
209
                name = data.NamePrefix.ValueString()
2✔
210
                filter = attr.FilterByPrefix
2✔
211
        }
2✔
212

213
        if data.NameSuffix.ValueString() != "" {
4✔
214
                name = data.NameSuffix.ValueString()
2✔
215
                filter = attr.FilterBySuffix
2✔
216
        }
2✔
217

218
        groupFilter := &model.GroupsFilter{
2✔
219
                Name:       &name,
2✔
220
                NameFilter: filter,
2✔
221
                IsActive:   data.IsActive.ValueBoolPointer(),
2✔
222
        }
2✔
223

2✔
224
        if len(data.Types.Elements()) > 0 {
4✔
225
                groupFilter.Types = utils.Map(data.Types.Elements(), func(item tfattr.Value) string {
4✔
226
                        return item.(types.String).ValueString()
2✔
227
                })
2✔
228
        }
229

230
        if groupFilter.Name == nil && len(groupFilter.Types) == 0 && groupFilter.IsActive == nil {
2✔
231
                return nil
×
232
        }
×
233

234
        return groupFilter
2✔
235
}
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

© 2025 Coveralls, Inc