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

Twingate / terraform-provider-twingate / 12792631619

15 Jan 2025 04:23PM UTC coverage: 58.088% (-0.02%) from 58.111%
12792631619

Pull #628

github

web-flow
Bump golang.org/x/net from 0.28.0 to 0.33.0

Bumps [golang.org/x/net](https://github.com/golang/net) from 0.28.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.28.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #628: Bump golang.org/x/net from 0.28.0 to 0.33.0

5160 of 8883 relevant lines covered (58.09%)

1.0 hits per line

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

18.45
/twingate/internal/test/acctests/helper.go
1
package acctests
2

3
import (
4
        "context"
5
        "errors"
6
        "fmt"
7
        "log"
8
        "os"
9
        "strconv"
10
        "strings"
11
        "testing"
12
        "time"
13

14
        "github.com/Twingate/terraform-provider-twingate/v3/twingate"
15
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/attr"
16
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/client"
17
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/model"
18
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/provider/datasource"
19
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/provider/resource"
20
        "github.com/Twingate/terraform-provider-twingate/v3/twingate/internal/test"
21
        "github.com/hashicorp/terraform-plugin-framework/providerserver"
22
        "github.com/hashicorp/terraform-plugin-go/tfprotov6"
23
        sdk "github.com/hashicorp/terraform-plugin-testing/helper/resource"
24
        "github.com/hashicorp/terraform-plugin-testing/plancheck"
25
        "github.com/hashicorp/terraform-plugin-testing/terraform"
26
        "github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
27
)
28

29
var (
30
        ErrResourceIDNotSet         = errors.New("id not set")
31
        ErrResourceNotFound         = errors.New("resource not found")
32
        ErrResourceStillPresent     = errors.New("resource still present")
33
        ErrResourceFoundInState     = errors.New("this resource should not be here")
34
        ErrUnknownResourceType      = errors.New("unknown resource type")
35
        ErrClientNotInitialized     = errors.New("meta client not initialized")
36
        ErrSecurityPoliciesNotFound = errors.New("security policies not found")
37
        ErrInvalidPath              = errors.New("invalid path: the path value cannot be asserted as string")
38
        ErrNotNullSecurityPolicy    = errors.New("expected null security policy in GroupAccess, got non null")
39
        ErrNotNullUsageBased        = errors.New("expected null usage based duration in GroupAccess, got non null")
40
        ErrNullSecurityPolicy       = errors.New("expected non null security policy in GroupAccess, got null")
41
        ErrNullUsageBased           = errors.New("expected non null usage based duration in GroupAccess, got null")
42
        ErrEmptyGroupAccess         = errors.New("expected at least one group in GroupAccess")
43
)
44

45
func ErrServiceAccountsLenMismatch(expected, actual int) error {
×
46
        return fmt.Errorf("expected %d service accounts, actual - %d", expected, actual) //nolint
×
47
}
×
48

49
func ErrDNSProfileAllowedDomainsLenMismatch(expected, actual int) error {
×
50
        return fmt.Errorf("expected %d allowed domains, actual - %d", expected, actual) //nolint
×
51
}
×
52

53
func ErrGroupsLenMismatch(expected, actual int) error {
×
54
        return fmt.Errorf("expected %d groups, actual - %d", expected, actual) //nolint
×
55
}
×
56

57
func ErrUsersLenMismatch(expected, actual int) error {
×
58
        return fmt.Errorf("expected %d users, actual - %d", expected, actual) //nolint
×
59
}
×
60

61
var providerClient = func() *client.Client { //nolint
3✔
62
        client, err := test.TwingateClient()
3✔
63
        if err != nil {
3✔
64
                log.Fatal("failed to init client:", err)
×
65
        }
×
66

67
        return client
3✔
68
}()
69

70
var ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){ //nolint
71
        "twingate": providerserver.NewProtocol6WithError(twingate.New(client.DefaultAgent, "test")()),
72
}
73

74
func SetPageLimit(limit int) {
×
75
        if err := os.Setenv(client.EnvPageLimit, strconv.Itoa(limit)); err != nil {
×
76
                log.Fatal("failed to set page limit", err)
×
77
        }
×
78
}
79

80
const WaitDuration = 500 * time.Millisecond
81

82
func WaitTestFunc() sdk.TestCheckFunc {
3✔
83
        return func(state *terraform.State) error {
6✔
84
                // Sleep 500 ms
3✔
85
                time.Sleep(WaitDuration)
3✔
86

3✔
87
                return nil
3✔
88
        }
3✔
89
}
90

91
func ComposeTestCheckFunc(checkFuncs ...sdk.TestCheckFunc) sdk.TestCheckFunc {
3✔
92
        return func(state *terraform.State) error {
6✔
93
                if err := WaitTestFunc()(state); err != nil {
3✔
94
                        return fmt.Errorf("WaitTestFunc error: %w", err)
×
95
                }
×
96

97
                for i, f := range checkFuncs {
6✔
98
                        if err := f(state); err != nil {
4✔
99
                                return fmt.Errorf("check %d/%d error: %w", i+1, len(checkFuncs), err)
1✔
100
                        }
1✔
101
                }
102

103
                return nil
3✔
104
        }
105
}
106

107
func PreCheck(t *testing.T) {
2✔
108
        t.Helper()
2✔
109

2✔
110
        var requiredEnvironmentVariables = []string{
2✔
111
                twingate.EnvAPIToken,
2✔
112
                twingate.EnvNetwork,
2✔
113
                twingate.EnvURL,
2✔
114
        }
2✔
115

2✔
116
        t.Run("Test Twingate Resource : AccPreCheck", func(t *testing.T) {
4✔
117
                for _, requiredEnvironmentVariable := range requiredEnvironmentVariables {
4✔
118
                        if value := os.Getenv(requiredEnvironmentVariable); value == "" {
2✔
119
                                t.Fatalf("%s must be set before running acceptance tests.", requiredEnvironmentVariable)
×
120
                        }
×
121
                }
122
        })
123
}
124

125
func CheckTwingateResourceDoesNotExists(resourceName string) sdk.TestCheckFunc {
×
126
        return func(s *terraform.State) error {
×
127
                _, ok := s.RootModule().Resources[resourceName]
×
128
                if !ok {
×
129
                        return nil
×
130
                }
×
131

132
                return fmt.Errorf("%w: %s", ErrResourceFoundInState, resourceName)
×
133
        }
134
}
135

136
func CheckTwingateServiceAccountDestroy(s *terraform.State) error {
×
137
        for _, rs := range s.RootModule().Resources {
×
138
                if rs.Type != resource.TwingateServiceAccount {
×
139
                        continue
×
140
                }
141

142
                serviceAccountID := rs.Primary.ID
×
143

×
144
                serviceAccount, _ := providerClient.ReadShallowServiceAccount(context.Background(), serviceAccountID)
×
145
                if serviceAccount != nil {
×
146
                        return fmt.Errorf("%w with ID %s", ErrResourceStillPresent, serviceAccountID)
×
147
                }
×
148
        }
149

150
        return nil
×
151
}
152

153
func CheckTwingateResourceExists(resourceName string) sdk.TestCheckFunc {
1✔
154
        return func(s *terraform.State) error {
1✔
155
                resource, ok := s.RootModule().Resources[resourceName]
×
156

×
157
                if !ok {
×
158
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
159
                }
×
160

161
                if resource.Primary.ID == "" {
×
162
                        return ErrResourceIDNotSet
×
163
                }
×
164

165
                return nil
×
166
        }
167
}
168

169
func GetTwingateResourceID(resourceName string, resourceID **string) sdk.TestCheckFunc {
1✔
170
        return func(s *terraform.State) error {
1✔
171
                resource, ok := s.RootModule().Resources[resourceName]
×
172

×
173
                if !ok {
×
174
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
175
                }
×
176

177
                if resource.Primary.ID == "" {
×
178
                        return ErrResourceIDNotSet
×
179
                }
×
180

181
                id := resource.Primary.ID
×
182
                *resourceID = &id
×
183

×
184
                return nil
×
185
        }
186
}
187

188
func DatasourceName(resource, name string) string {
3✔
189
        return fmt.Sprintf("data.%s.%s", resource, name)
3✔
190
}
3✔
191

192
func ResourceName(resource, name string) string {
3✔
193
        return fmt.Sprintf("%s.%s", resource, name)
3✔
194
}
3✔
195

196
func TerraformResource(name string) string {
1✔
197
        return ResourceName(resource.TwingateResource, name)
1✔
198
}
1✔
199

200
func TerraformRemoteNetwork(name string) string {
1✔
201
        return ResourceName(resource.TwingateRemoteNetwork, name)
1✔
202
}
1✔
203

204
func TerraformGroup(name string) string {
1✔
205
        return ResourceName(resource.TwingateGroup, name)
1✔
206
}
1✔
207

208
func TerraformConnector(name string) string {
1✔
209
        return ResourceName(resource.TwingateConnector, name)
1✔
210
}
1✔
211

212
func TerraformConnectorTokens(name string) string {
1✔
213
        return ResourceName(resource.TwingateConnectorTokens, name)
1✔
214
}
1✔
215

216
func TerraformServiceAccount(name string) string {
1✔
217
        return ResourceName(resource.TwingateServiceAccount, name)
1✔
218
}
1✔
219

220
func TerraformServiceKey(name string) string {
1✔
221
        return ResourceName(resource.TwingateServiceAccountKey, name)
1✔
222
}
1✔
223

224
func TerraformUser(name string) string {
3✔
225
        return ResourceName(resource.TwingateUser, name)
3✔
226
}
3✔
227

228
func TerraformDNSFilteringProfile(name string) string {
1✔
229
        return ResourceName(resource.TwingateDNSFilteringProfile, name)
1✔
230
}
1✔
231

232
func TerraformDatasourceUsers(name string) string {
3✔
233
        return DatasourceName(datasource.TwingateUsers, name)
3✔
234
}
3✔
235

236
func DeleteTwingateResource(resourceName, resourceType string) sdk.TestCheckFunc {
1✔
237
        return func(s *terraform.State) error {
1✔
238
                resourceState, ok := s.RootModule().Resources[resourceName]
×
239
                if !ok {
×
240
                        return fmt.Errorf("%w: %s ", ErrResourceNotFound, resourceName)
×
241
                }
×
242

243
                resourceID := resourceState.Primary.ID
×
244
                if resourceID == "" {
×
245
                        return ErrResourceIDNotSet
×
246
                }
×
247

248
                err := deleteResource(resourceType, resourceID)
×
249
                if err != nil {
×
250
                        return fmt.Errorf("%s with ID %s still active: %w", resourceType, resourceID, err)
×
251
                }
×
252

253
                return nil
×
254
        }
255
}
256

257
func deleteResource(resourceType, resourceID string) error {
×
258
        var err error
×
259

×
260
        switch resourceType {
×
261
        case resource.TwingateResource:
×
262
                err = providerClient.DeleteResource(context.Background(), resourceID)
×
263
        case resource.TwingateRemoteNetwork:
×
264
                err = providerClient.DeleteRemoteNetwork(context.Background(), resourceID)
×
265
        case resource.TwingateGroup:
×
266
                err = providerClient.DeleteGroup(context.Background(), resourceID)
×
267
        case resource.TwingateConnector:
×
268
                err = providerClient.DeleteConnector(context.Background(), resourceID)
×
269
        case resource.TwingateServiceAccount:
×
270
                err = providerClient.DeleteServiceAccount(context.Background(), resourceID)
×
271
        case resource.TwingateServiceAccountKey:
×
272
                err = providerClient.DeleteServiceKey(context.Background(), resourceID)
×
273
        case resource.TwingateUser:
×
274
                err = providerClient.DeleteUser(context.Background(), resourceID)
×
275
        default:
×
276
                err = fmt.Errorf("%s %w", resourceType, ErrUnknownResourceType)
×
277
        }
278

279
        return err
×
280
}
281

282
func CheckTwingateResourceDestroy(s *terraform.State) error {
×
283
        for _, rs := range s.RootModule().Resources {
×
284
                if rs.Type != resource.TwingateResource {
×
285
                        continue
×
286
                }
287

288
                resourceID := rs.Primary.ID
×
289

×
290
                resource, _ := providerClient.ReadResource(context.Background(), resourceID)
×
291
                if resource != nil {
×
292
                        return fmt.Errorf("%w: with ID %s", ErrResourceStillPresent, resourceID)
×
293
                }
×
294
        }
295

296
        return nil
×
297
}
298

299
func DeactivateTwingateResource(resourceName string) sdk.TestCheckFunc {
1✔
300
        return func(s *terraform.State) error {
1✔
301
                resourceState, ok := s.RootModule().Resources[resourceName]
×
302

×
303
                if !ok {
×
304
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
305
                }
×
306

307
                resourceID := resourceState.Primary.ID
×
308

×
309
                if resourceID == "" {
×
310
                        return ErrResourceIDNotSet
×
311
                }
×
312

313
                err := providerClient.UpdateResourceActiveState(context.Background(), &model.Resource{
×
314
                        ID:       resourceID,
×
315
                        IsActive: false,
×
316
                })
×
317

×
318
                if err != nil {
×
319
                        return fmt.Errorf("resource with ID %s still active: %w", resourceID, err)
×
320
                }
×
321

322
                return nil
×
323
        }
324
}
325

326
func CheckTwingateResourceSecurityPolicyOnGroupAccess(resourceName string, expectedSecurityPolicy string) sdk.TestCheckFunc {
×
327
        return func(s *terraform.State) error {
×
328
                resourceState, ok := s.RootModule().Resources[resourceName]
×
329

×
330
                if !ok {
×
331
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
332
                }
×
333

334
                if resourceState.Primary.ID == "" {
×
335
                        return ErrResourceIDNotSet
×
336
                }
×
337

338
                res, err := providerClient.ReadResource(context.Background(), resourceState.Primary.ID)
×
339
                if err != nil {
×
340
                        return fmt.Errorf("failed to read resource: %w", err)
×
341
                }
×
342

343
                if len(res.GroupsAccess) == 0 {
×
344
                        return ErrEmptyGroupAccess
×
345
                }
×
346

347
                if res.GroupsAccess[0].SecurityPolicyID == nil {
×
348
                        return ErrNullSecurityPolicy
×
349
                }
×
350

351
                if *res.GroupsAccess[0].SecurityPolicyID != expectedSecurityPolicy {
×
352
                        return fmt.Errorf("expected security policy %v, got %v", expectedSecurityPolicy, *res.GroupsAccess[0].SecurityPolicyID) //nolint:goerr113
×
353
                }
×
354

355
                return nil
×
356
        }
357
}
358

359
func CheckTwingateResourceUsageBasedOnGroupAccess(resourceName string, expectedUsageBased int64) sdk.TestCheckFunc {
1✔
360
        return func(s *terraform.State) error {
1✔
361
                resourceState, ok := s.RootModule().Resources[resourceName]
×
362

×
363
                if !ok {
×
364
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
365
                }
×
366

367
                if resourceState.Primary.ID == "" {
×
368
                        return ErrResourceIDNotSet
×
369
                }
×
370

371
                res, err := providerClient.ReadResource(context.Background(), resourceState.Primary.ID)
×
372
                if err != nil {
×
373
                        return fmt.Errorf("failed to read resource: %w", err)
×
374
                }
×
375

376
                if len(res.GroupsAccess) == 0 {
×
377
                        return ErrEmptyGroupAccess
×
378
                }
×
379

380
                if res.GroupsAccess[0].UsageBasedDuration == nil {
×
381
                        return ErrNullUsageBased
×
382
                }
×
383

384
                if *res.GroupsAccess[0].UsageBasedDuration != expectedUsageBased {
×
385
                        return fmt.Errorf("expected usage based duration %v, got %v", expectedUsageBased, *res.GroupsAccess[0].UsageBasedDuration) //nolint:goerr113
×
386
                }
×
387

388
                return nil
×
389
        }
390
}
391

392
func CheckTwingateResourceSecurityPolicyIsNullOnGroupAccess(resourceName string) sdk.TestCheckFunc {
×
393
        return func(s *terraform.State) error {
×
394
                resourceState, ok := s.RootModule().Resources[resourceName]
×
395

×
396
                if !ok {
×
397
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
398
                }
×
399

400
                if resourceState.Primary.ID == "" {
×
401
                        return ErrResourceIDNotSet
×
402
                }
×
403

404
                res, err := providerClient.ReadResource(context.Background(), resourceState.Primary.ID)
×
405
                if err != nil {
×
406
                        return fmt.Errorf("failed to read resource: %w", err)
×
407
                }
×
408

409
                if len(res.GroupsAccess) == 0 {
×
410
                        return ErrEmptyGroupAccess
×
411
                }
×
412

413
                if res.GroupsAccess[0].SecurityPolicyID != nil {
×
414
                        return ErrNotNullSecurityPolicy
×
415
                }
×
416

417
                return nil
×
418
        }
419
}
420

421
func CheckTwingateResourceUsageBasedIsNullOnGroupAccess(resourceName string) sdk.TestCheckFunc {
1✔
422
        return func(s *terraform.State) error {
1✔
423
                resourceState, ok := s.RootModule().Resources[resourceName]
×
424

×
425
                if !ok {
×
426
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
427
                }
×
428

429
                if resourceState.Primary.ID == "" {
×
430
                        return ErrResourceIDNotSet
×
431
                }
×
432

433
                res, err := providerClient.ReadResource(context.Background(), resourceState.Primary.ID)
×
434
                if err != nil {
×
435
                        return fmt.Errorf("failed to read resource: %w", err)
×
436
                }
×
437

438
                if len(res.GroupsAccess) == 0 {
×
439
                        return ErrEmptyGroupAccess
×
440
                }
×
441

442
                if res.GroupsAccess[0].UsageBasedDuration != nil {
×
443
                        return ErrNotNullUsageBased
×
444
                }
×
445

446
                return nil
×
447
        }
448
}
449

450
func CheckTwingateResourceActiveState(resourceName string, expectedActiveState bool) sdk.TestCheckFunc {
1✔
451
        return func(s *terraform.State) error {
1✔
452
                resourceState, ok := s.RootModule().Resources[resourceName]
×
453

×
454
                if !ok {
×
455
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
456
                }
×
457

458
                if resourceState.Primary.ID == "" {
×
459
                        return ErrResourceIDNotSet
×
460
                }
×
461

462
                res, err := providerClient.ReadResource(context.Background(), resourceState.Primary.ID)
×
463
                if err != nil {
×
464
                        return fmt.Errorf("failed to read resource: %w", err)
×
465
                }
×
466

467
                if res.IsActive != expectedActiveState {
×
468
                        return fmt.Errorf("expected active state %v, got %v", expectedActiveState, res.IsActive) //nolint:goerr113
×
469
                }
×
470

471
                return nil
×
472
        }
473
}
474

475
type checkResourceActiveState struct {
476
        resourceAddress     string
477
        expectedActiveState bool
478
}
479

480
// CheckPlan implements the plan check logic.
481
func (e checkResourceActiveState) CheckPlan(ctx context.Context, req plancheck.CheckPlanRequest, resp *plancheck.CheckPlanResponse) {
×
482
        var resourceID string
×
483

×
484
        for _, rc := range req.Plan.ResourceChanges {
×
485
                if e.resourceAddress != rc.Address {
×
486
                        continue
×
487
                }
488

489
                result, err := tfjsonpath.Traverse(rc.Change.Before, tfjsonpath.New(attr.ID))
×
490
                if err != nil {
×
491
                        resp.Error = err
×
492

×
493
                        return
×
494
                }
×
495

496
                resultID, ok := result.(string)
×
497
                if !ok {
×
498
                        resp.Error = ErrInvalidPath
×
499

×
500
                        return
×
501
                }
×
502

503
                resourceID = resultID
×
504

×
505
                break
×
506
        }
507

508
        if resourceID == "" {
×
509
                resp.Error = fmt.Errorf("%s - Resource not found in plan ResourceChanges", e.resourceAddress) //nolint:goerr113
×
510

×
511
                return
×
512
        }
×
513

514
        res, err := providerClient.ReadResource(ctx, resourceID)
×
515
        if err != nil {
×
516
                resp.Error = fmt.Errorf("failed to read resource: %w", err)
×
517

×
518
                return
×
519
        }
×
520

521
        if res.IsActive != e.expectedActiveState {
×
522
                resp.Error = fmt.Errorf("expected active state %v, got %v", e.expectedActiveState, res.IsActive) //nolint:goerr113
×
523

×
524
                return
×
525
        }
×
526
}
527

528
func CheckResourceActiveState(resourceAddress string, activeState bool) plancheck.PlanCheck {
1✔
529
        return checkResourceActiveState{
1✔
530
                resourceAddress:     resourceAddress,
1✔
531
                expectedActiveState: activeState,
1✔
532
        }
1✔
533
}
1✔
534

535
func CheckImportState(attributes map[string]string) func(data []*terraform.InstanceState) error {
1✔
536
        return func(data []*terraform.InstanceState) error {
1✔
537
                if len(data) != 1 {
×
538
                        return fmt.Errorf("expected 1 resource, got %d", len(data)) //nolint:goerr113
×
539
                }
×
540

541
                res := data[0]
×
542
                for name, expected := range attributes {
×
543
                        if res.Attributes[name] != expected {
×
544
                                return fmt.Errorf("attribute %s doesn't match, expected: %s, got: %s", name, expected, res.Attributes[name]) //nolint:goerr113
×
545
                        }
×
546
                }
547

548
                return nil
×
549
        }
550
}
551

552
func CheckTwingateRemoteNetworkDestroy(s *terraform.State) error {
×
553
        for _, rs := range s.RootModule().Resources {
×
554
                if rs.Type != resource.TwingateRemoteNetwork {
×
555
                        continue
×
556
                }
557

558
                remoteNetworkID := rs.Primary.ID
×
559

×
560
                remoteNetwork, _ := providerClient.ReadRemoteNetworkByID(context.Background(), remoteNetworkID)
×
561
                if remoteNetwork != nil {
×
562
                        return fmt.Errorf("%w with ID %s", ErrResourceStillPresent, remoteNetworkID)
×
563
                }
×
564
        }
565

566
        return nil
×
567
}
568

569
func CheckTwingateGroupDestroy(s *terraform.State) error {
×
570
        for _, rs := range s.RootModule().Resources {
×
571
                if rs.Type != resource.TwingateGroup {
×
572
                        continue
×
573
                }
574

575
                groupID := rs.Primary.ID
×
576

×
577
                group, _ := providerClient.ReadGroup(context.Background(), groupID)
×
578
                if group != nil {
×
579
                        return fmt.Errorf("%w with ID %s", ErrResourceStillPresent, groupID)
×
580
                }
×
581
        }
582

583
        return nil
×
584
}
585

586
func CheckTwingateConnectorDestroy(s *terraform.State) error {
×
587
        for _, rs := range s.RootModule().Resources {
×
588
                if rs.Type != resource.TwingateConnector {
×
589
                        continue
×
590
                }
591

592
                connectorID := rs.Primary.ID
×
593

×
594
                connector, _ := providerClient.ReadConnector(context.Background(), connectorID)
×
595
                if connector != nil {
×
596
                        return fmt.Errorf("%w with ID %s", ErrResourceStillPresent, connectorID)
×
597
                }
×
598
        }
599

600
        return nil
×
601
}
602

603
func CheckTwingateDNSProfileDestroy(s *terraform.State) error {
×
604
        for _, rs := range s.RootModule().Resources {
×
605
                if rs.Type != resource.TwingateDNSFilteringProfile {
×
606
                        continue
×
607
                }
608

609
                profileID := rs.Primary.ID
×
610

×
611
                profile, _ := providerClient.ReadDNSFilteringProfile(context.Background(), profileID)
×
612
                if profile != nil {
×
613
                        return fmt.Errorf("%w with ID %s", ErrResourceStillPresent, profileID)
×
614
                }
×
615
        }
616

617
        return nil
×
618
}
619

620
func RevokeTwingateServiceKey(resourceName string) sdk.TestCheckFunc {
1✔
621
        return func(s *terraform.State) error {
1✔
622
                resourceState, ok := s.RootModule().Resources[resourceName]
×
623
                if !ok {
×
624
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
625
                }
×
626

627
                resourceID := resourceState.Primary.ID
×
628
                if resourceID == "" {
×
629
                        return ErrResourceIDNotSet
×
630
                }
×
631

632
                err := providerClient.RevokeServiceKey(context.Background(), resourceID)
×
633
                if err != nil {
×
634
                        return fmt.Errorf("failed to revoke service account key with ID %s: %w", resourceID, err)
×
635
                }
×
636

637
                return nil
×
638
        }
639
}
640

641
func CheckTwingateServiceKeyStatus(resourceName string, expectedStatus string) sdk.TestCheckFunc {
1✔
642
        return func(s *terraform.State) error {
1✔
643
                resourceState, ok := s.RootModule().Resources[resourceName]
×
644
                if !ok {
×
645
                        return fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
646
                }
×
647

648
                if resourceState.Primary.ID == "" {
×
649
                        return ErrResourceIDNotSet
×
650
                }
×
651

652
                serviceAccountKey, err := providerClient.ReadServiceKey(context.Background(), resourceState.Primary.ID)
×
653
                if err != nil {
×
654
                        return fmt.Errorf("failed to read service account key with ID %s: %w", resourceState.Primary.ID, err)
×
655
                }
×
656

657
                if serviceAccountKey.Status != expectedStatus {
×
658
                        return fmt.Errorf("expected status %v, got %v", expectedStatus, serviceAccountKey.Status) //nolint:goerr113
×
659
                }
×
660

661
                return nil
×
662
        }
663
}
664

665
func ListSecurityPolicies() ([]*model.SecurityPolicy, error) {
1✔
666
        if providerClient == nil {
1✔
667
                return nil, ErrClientNotInitialized
×
668
        }
×
669

670
        securityPolicies, err := providerClient.ReadSecurityPolicies(context.Background(), "", "")
1✔
671
        if err != nil {
2✔
672
                return nil, fmt.Errorf("failed to fetch all security policies: %w", err)
1✔
673
        }
1✔
674

675
        if len(securityPolicies) == 0 {
×
676
                return nil, ErrSecurityPoliciesNotFound
×
677
        }
×
678

679
        return securityPolicies, nil
×
680
}
681

682
func AddResourceGroup(resourceName, groupName string) sdk.TestCheckFunc {
1✔
683
        return func(state *terraform.State) error {
1✔
684
                resourceID, err := getResourceID(state, resourceName)
×
685
                if err != nil {
×
686
                        return err
×
687
                }
×
688

689
                groupID, err := getResourceID(state, groupName)
×
690
                if err != nil {
×
691
                        return err
×
692
                }
×
693

694
                err = providerClient.AddResourceAccess(context.Background(), resourceID, []client.AccessInput{
×
695
                        {PrincipalID: groupID},
×
696
                })
×
697
                if err != nil {
×
698
                        return fmt.Errorf("resource with ID %s failed to add group with ID %s: %w", resourceID, groupID, err)
×
699
                }
×
700

701
                return nil
×
702
        }
703
}
704

705
func DeleteResourceGroup(resourceName, groupName string) sdk.TestCheckFunc {
1✔
706
        return func(state *terraform.State) error {
1✔
707
                resourceID, err := getResourceID(state, resourceName)
×
708
                if err != nil {
×
709
                        return err
×
710
                }
×
711

712
                groupID, err := getResourceID(state, groupName)
×
713
                if err != nil {
×
714
                        return err
×
715
                }
×
716

717
                err = providerClient.RemoveResourceAccess(context.Background(), resourceID, []string{groupID})
×
718
                if err != nil {
×
719
                        return fmt.Errorf("resource with ID %s failed to delete group with ID %s: %w", resourceID, groupID, err)
×
720
                }
×
721

722
                return nil
×
723
        }
724
}
725

726
func CheckResourceGroupsLen(resourceName string, expectedGroupsLen int) sdk.TestCheckFunc {
1✔
727
        return func(state *terraform.State) error {
1✔
728
                resourceID, err := getResourceID(state, resourceName)
×
729
                if err != nil {
×
730
                        return err
×
731
                }
×
732

733
                resource, err := providerClient.ReadResource(context.Background(), resourceID)
×
734
                if err != nil {
×
735
                        return fmt.Errorf("resource with ID %s failed to read: %w", resourceID, err)
×
736
                }
×
737

738
                if len(resource.GroupsAccess) != expectedGroupsLen {
×
739
                        return ErrGroupsLenMismatch(expectedGroupsLen, len(resource.GroupsAccess))
×
740
                }
×
741

742
                return nil
×
743
        }
744
}
745

746
func getResourceID(s *terraform.State, resourceName string) (string, error) {
×
747
        resourceState, ok := s.RootModule().Resources[resourceName]
×
748

×
749
        if !ok {
×
750
                return "", fmt.Errorf("%w: %s", ErrResourceNotFound, resourceName)
×
751
        }
×
752

753
        resourceID := resourceState.Primary.ID
×
754

×
755
        if resourceID == "" {
×
756
                return "", ErrResourceIDNotSet
×
757
        }
×
758

759
        return resourceID, nil
×
760
}
761

762
func AddResourceServiceAccount(resourceName, serviceAccountName string) sdk.TestCheckFunc {
1✔
763
        return func(state *terraform.State) error {
1✔
764
                resourceID, err := getResourceID(state, resourceName)
×
765
                if err != nil {
×
766
                        return err
×
767
                }
×
768

769
                serviceAccountID, err := getResourceID(state, serviceAccountName)
×
770
                if err != nil {
×
771
                        return err
×
772
                }
×
773

774
                err = providerClient.AddResourceAccess(context.Background(), resourceID, []client.AccessInput{
×
775
                        {PrincipalID: serviceAccountID},
×
776
                })
×
777
                if err != nil {
×
778
                        return fmt.Errorf("resource with ID %s failed to add service account with ID %s: %w", resourceID, serviceAccountID, err)
×
779
                }
×
780

781
                return nil
×
782
        }
783
}
784

785
func AddDNSProfileAllowedDomains(resourceName string, domains []string) sdk.TestCheckFunc {
1✔
786
        return func(state *terraform.State) error {
1✔
787
                profileID, err := getResourceID(state, resourceName)
×
788
                if err != nil {
×
789
                        return err
×
790
                }
×
791

792
                profile, err := providerClient.ReadDNSFilteringProfile(context.Background(), profileID)
×
793
                if err != nil {
×
794
                        return fmt.Errorf("failed to fetch DNS profile with ID %s: %w", profileID, err)
×
795
                }
×
796

797
                profile.AllowedDomains = domains
×
798

×
799
                _, err = providerClient.UpdateDNSFilteringProfile(context.Background(), profile)
×
800
                if err != nil {
×
801
                        return fmt.Errorf("DNS profile with ID %s failed to set new domains: %w", profileID, err)
×
802
                }
×
803

804
                return nil
×
805
        }
806
}
807

808
func DeleteResourceServiceAccount(resourceName, serviceAccountName string) sdk.TestCheckFunc {
1✔
809
        return func(state *terraform.State) error {
1✔
810
                resourceID, err := getResourceID(state, resourceName)
×
811
                if err != nil {
×
812
                        return err
×
813
                }
×
814

815
                serviceAccountID, err := getResourceID(state, serviceAccountName)
×
816
                if err != nil {
×
817
                        return err
×
818
                }
×
819

820
                err = providerClient.RemoveResourceAccess(context.Background(), resourceID, []string{serviceAccountID})
×
821
                if err != nil {
×
822
                        return fmt.Errorf("resource with ID %s failed to delete service account with ID %s: %w", resourceID, serviceAccountID, err)
×
823
                }
×
824

825
                return nil
×
826
        }
827
}
828

829
func CheckResourceServiceAccountsLen(resourceName string, expectedServiceAccountsLen int) sdk.TestCheckFunc {
1✔
830
        return func(state *terraform.State) error {
1✔
831
                resourceID, err := getResourceID(state, resourceName)
×
832
                if err != nil {
×
833
                        return err
×
834
                }
×
835

836
                resource, err := providerClient.ReadResource(context.Background(), resourceID)
×
837
                if err != nil {
×
838
                        return fmt.Errorf("resource with ID %s failed to read: %w", resourceID, err)
×
839
                }
×
840

841
                if len(resource.ServiceAccounts) != expectedServiceAccountsLen {
×
842
                        return ErrServiceAccountsLenMismatch(expectedServiceAccountsLen, len(resource.ServiceAccounts))
×
843
                }
×
844

845
                return nil
×
846
        }
847
}
848

849
func CheckDNSProfileAllowedDomainsLen(resourceName string, expectedLen int) sdk.TestCheckFunc {
1✔
850
        return func(state *terraform.State) error {
1✔
851
                resourceID, err := getResourceID(state, resourceName)
×
852
                if err != nil {
×
853
                        return err
×
854
                }
×
855

856
                profile, err := providerClient.ReadDNSFilteringProfile(context.Background(), resourceID)
×
857
                if err != nil {
×
858
                        return fmt.Errorf("profile with ID %s failed to read: %w", resourceID, err)
×
859
                }
×
860

861
                if len(profile.AllowedDomains) != expectedLen {
×
862
                        return ErrDNSProfileAllowedDomainsLenMismatch(expectedLen, len(profile.AllowedDomains))
×
863
                }
×
864

865
                return nil
×
866
        }
867
}
868

869
func CheckResourceSecurityPolicy(resourceName string, expectedSecurityPolicyID string) sdk.TestCheckFunc {
×
870
        return func(state *terraform.State) error {
×
871
                resourceID, err := getResourceID(state, resourceName)
×
872
                if err != nil {
×
873
                        return err
×
874
                }
×
875

876
                resource, err := providerClient.ReadResource(context.Background(), resourceID)
×
877
                if err != nil {
×
878
                        return fmt.Errorf("resource with ID %s failed to read: %w", resourceID, err)
×
879
                }
×
880

881
                if resource.SecurityPolicyID != nil && *resource.SecurityPolicyID != expectedSecurityPolicyID {
×
882
                        return fmt.Errorf("expected security_policy_id %s, got %s", expectedSecurityPolicyID, *resource.SecurityPolicyID) //nolint
×
883
                }
×
884

885
                return nil
×
886
        }
887
}
888

889
func UpdateResourceSecurityPolicy(resourceName, securityPolicyID string) sdk.TestCheckFunc {
×
890
        return func(state *terraform.State) error {
×
891
                resourceID, err := getResourceID(state, resourceName)
×
892
                if err != nil {
×
893
                        return err
×
894
                }
×
895

896
                resource, err := providerClient.ReadResource(context.Background(), resourceID)
×
897
                if err != nil {
×
898
                        return fmt.Errorf("resource with ID %s failed to read: %w", resourceID, err)
×
899
                }
×
900

901
                resource.SecurityPolicyID = &securityPolicyID
×
902

×
903
                _, err = providerClient.UpdateResource(context.Background(), resource)
×
904
                if err != nil {
×
905
                        return fmt.Errorf("resource with ID %s failed to update security_policy: %w", resourceID, err)
×
906
                }
×
907

908
                return nil
×
909
        }
910
}
911

912
func AddGroupUser(groupResource, groupName, terraformUserID string) sdk.TestCheckFunc {
1✔
913
        return func(state *terraform.State) error {
1✔
914
                userID, err := getResourceID(state, getResourceNameFromID(terraformUserID))
×
915
                if err != nil {
×
916
                        return err
×
917
                }
×
918

919
                resourceID, err := getResourceID(state, groupResource)
×
920
                if err != nil {
×
921
                        return err
×
922
                }
×
923

924
                _, err = providerClient.UpdateGroup(context.Background(), &model.Group{
×
925
                        ID:    resourceID,
×
926
                        Name:  groupName,
×
927
                        Users: []string{userID},
×
928
                })
×
929
                if err != nil {
×
930
                        return fmt.Errorf("group with ID %s failed to add user with ID %s: %w", resourceID, userID, err)
×
931
                }
×
932

933
                return nil
×
934
        }
935
}
936

937
func getResourceNameFromID(terraformID string) string {
×
938
        return strings.TrimSuffix(terraformID, ".id")
×
939
}
×
940

941
func DeleteGroupUser(groupResource, terraformUserID string) sdk.TestCheckFunc {
1✔
942
        return func(state *terraform.State) error {
1✔
943
                userID, err := getResourceID(state, getResourceNameFromID(terraformUserID))
×
944
                if err != nil {
×
945
                        return err
×
946
                }
×
947

948
                groupID, err := getResourceID(state, groupResource)
×
949
                if err != nil {
×
950
                        return err
×
951
                }
×
952

953
                err = providerClient.DeleteGroupUsers(context.Background(), groupID, []string{userID})
×
954
                if err != nil {
×
955
                        return fmt.Errorf("group with ID %s failed to delete user with ID %s: %w", groupID, userID, err)
×
956
                }
×
957

958
                return nil
×
959
        }
960
}
961

962
func CheckGroupUsersLen(resourceName string, expectedUsersLen int) sdk.TestCheckFunc {
1✔
963
        return func(state *terraform.State) error {
1✔
964
                groupID, err := getResourceID(state, resourceName)
×
965
                if err != nil {
×
966
                        return err
×
967
                }
×
968

969
                group, err := providerClient.ReadGroup(context.Background(), groupID)
×
970
                if err != nil {
×
971
                        return fmt.Errorf("group with ID %s failed to read: %w", groupID, err)
×
972
                }
×
973

974
                if len(group.Users) != expectedUsersLen {
×
975
                        return ErrUsersLenMismatch(expectedUsersLen, len(group.Users))
×
976
                }
×
977

978
                return nil
×
979
        }
980
}
981

982
func GetTestUsers() ([]*model.User, error) {
1✔
983
        if providerClient == nil {
1✔
984
                return nil, ErrClientNotInitialized
×
985
        }
×
986

987
        users, err := providerClient.ReadUsers(context.Background(), nil)
1✔
988
        if err != nil {
2✔
989
                return nil, err //nolint
1✔
990
        }
1✔
991

992
        if len(users) == 0 {
×
993
                return nil, ErrResourceNotFound
×
994
        }
×
995

996
        return users, nil
×
997
}
998

999
func CheckTwingateUserDestroy(s *terraform.State) error {
×
1000
        for _, rs := range s.RootModule().Resources {
×
1001
                if rs.Type != resource.TwingateUser {
×
1002
                        continue
×
1003
                }
1004

1005
                userID := rs.Primary.ID
×
1006

×
1007
                user, _ := providerClient.ReadUser(context.Background(), userID)
×
1008
                if user != nil {
×
1009
                        return fmt.Errorf("%w with ID %s", ErrResourceStillPresent, userID)
×
1010
                }
×
1011
        }
1012

1013
        return nil
×
1014
}
1015

1016
func CheckTwingateConnectorTokensInvalidated(s *terraform.State) error {
×
1017
        for _, res := range s.RootModule().Resources {
×
1018
                if res.Type != resource.TwingateConnectorTokens {
×
1019
                        continue
×
1020
                }
1021

1022
                connectorID := res.Primary.ID
×
1023
                accessToken := res.Primary.Attributes[attr.AccessToken]
×
1024
                refreshToken := res.Primary.Attributes[attr.RefreshToken]
×
1025

×
1026
                err := providerClient.VerifyConnectorTokens(context.Background(), refreshToken, accessToken)
×
1027
                // expecting error here, since tokens invalidated
×
1028
                if err == nil {
×
1029
                        return fmt.Errorf("%w with ID %s", ErrResourceStillPresent, connectorID)
×
1030
                }
×
1031
        }
1032

1033
        return nil
×
1034
}
1035

1036
func GetTestUser() (*model.User, error) {
1✔
1037
        if providerClient == nil {
1✔
1038
                return nil, ErrClientNotInitialized
×
1039
        }
×
1040

1041
        users, err := providerClient.ReadUsers(context.Background(), nil)
1✔
1042
        if err != nil {
2✔
1043
                return nil, fmt.Errorf("failed to get test users: %w", err)
1✔
1044
        }
1✔
1045

1046
        if len(users) == 0 {
×
1047
                return nil, ErrResourceNotFound
×
1048
        }
×
1049

1050
        return users[0], nil
×
1051
}
1052

1053
func CheckTwingateConnectorAndRemoteNetworkDestroy(s *terraform.State) error {
×
1054
        if err := CheckTwingateConnectorDestroy(s); err != nil {
×
1055
                return err
×
1056
        }
×
1057

1058
        return CheckTwingateRemoteNetworkDestroy(s)
×
1059
}
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