-
Notifications
You must be signed in to change notification settings - Fork 232
/
teststep_providers.go
97 lines (76 loc) · 2.9 KB
/
teststep_providers.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
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package resource
import (
"context"
"fmt"
"regexp"
"strings"
)
var configProviderBlockRegex = regexp.MustCompile(`provider "?[a-zA-Z0-9_-]+"? {`)
// configHasProviderBlock returns true if the Config has declared a provider
// configuration block, e.g. provider "examplecloud" {...}
func (s TestStep) configHasProviderBlock(_ context.Context) bool {
return configProviderBlockRegex.MatchString(s.Config)
}
// configHasTerraformBlock returns true if the Config has declared a terraform
// configuration block, e.g. terraform {...}
func (s TestStep) configHasTerraformBlock(_ context.Context) bool {
return strings.Contains(s.Config, "terraform {")
}
// mergedConfig prepends any necessary terraform configuration blocks to the
// TestStep Config.
//
// If there are ExternalProviders configurations in either the TestCase or
// TestStep, the terraform configuration block should be included with the
// step configuration to prevent errors with providers outside the
// registry.terraform.io hostname or outside the hashicorp namespace.
func (s TestStep) mergedConfig(ctx context.Context, testCase TestCase) string {
var config strings.Builder
// Prevent issues with existing configurations containing the terraform
// configuration block.
if s.configHasTerraformBlock(ctx) {
config.WriteString(s.Config)
return config.String()
}
if testCase.hasProviders(ctx) {
config.WriteString(testCase.providerConfig(ctx, s.configHasProviderBlock(ctx)))
} else {
config.WriteString(s.providerConfig(ctx, s.configHasProviderBlock(ctx)))
}
config.WriteString(s.Config)
return config.String()
}
// providerConfig takes the list of providers in a TestStep and returns a
// config with only empty provider blocks. This is useful for Import, where no
// config is provided, but the providers must be defined.
func (s TestStep) providerConfig(_ context.Context, skipProviderBlock bool) string {
var providerBlocks, requiredProviderBlocks strings.Builder
for name, externalProvider := range s.ExternalProviders {
if !skipProviderBlock {
providerBlocks.WriteString(fmt.Sprintf("provider %q {}\n", name))
}
if externalProvider.Source == "" && externalProvider.VersionConstraint == "" {
continue
}
requiredProviderBlocks.WriteString(fmt.Sprintf(" %s = {\n", name))
if externalProvider.Source != "" {
requiredProviderBlocks.WriteString(fmt.Sprintf(" source = %q\n", externalProvider.Source))
}
if externalProvider.VersionConstraint != "" {
requiredProviderBlocks.WriteString(fmt.Sprintf(" version = %q\n", externalProvider.VersionConstraint))
}
requiredProviderBlocks.WriteString(" }\n")
}
if requiredProviderBlocks.Len() > 0 {
return fmt.Sprintf(`
terraform {
required_providers {
%[1]s
}
}
%[2]s
`, strings.TrimSuffix(requiredProviderBlocks.String(), "\n"), providerBlocks.String())
}
return providerBlocks.String()
}