/
provider.go
128 lines (115 loc) · 4.32 KB
/
provider.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
package provider
import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)
func New() (*schema.Provider, error) {
return &schema.Provider{
ResourcesMap: map[string]*schema.Resource{
"tls_private_key": resourcePrivateKey(),
"tls_locally_signed_cert": resourceLocallySignedCert(),
"tls_self_signed_cert": resourceSelfSignedCert(),
"tls_cert_request": resourceCertRequest(),
},
DataSourcesMap: map[string]*schema.Resource{
"tls_public_key": dataSourcePublicKey(),
"tls_certificate": dataSourceCertificate(),
},
Schema: map[string]*schema.Schema{
"proxy": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"url": {
Type: schema.TypeString,
Optional: true,
ValidateDiagFunc: validation.ToDiagFunc(validation.IsURLWithScheme(SupportedProxySchemesStr())),
ConflictsWith: []string{"proxy.0.from_env"},
Description: "URL used to connect to the Proxy. " +
fmt.Sprintf("Accepted schemes are: `%s`. ", strings.Join(SupportedProxySchemesStr(), "`, `")),
},
"username": {
Type: schema.TypeString,
Optional: true,
RequiredWith: []string{"proxy.0.url"},
Description: "Username (or Token) used for Basic authentication against the Proxy.",
},
"password": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
RequiredWith: []string{"proxy.0.username"},
Description: "Password used for Basic authentication against the Proxy.",
},
"from_env": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ConflictsWith: []string{"proxy.0.url", "proxy.0.username", "proxy.0.password"},
Description: "When `true` the provider will discover the proxy configuration from environment variables. " +
"This is based upon [`http.ProxyFromEnvironment`](https://pkg.go.dev/net/http#ProxyFromEnvironment) " +
"and it supports the same environment variables (default: `false`). " +
"**NOTE**: the default value for this argument will be change to `true` in the next major release.",
},
},
},
Description: "Proxy used by resources and data sources that connect to external endpoints.",
},
},
ConfigureContextFunc: configureProvider,
}, nil
}
// providerConfig is produced by configureProvider as part of the provider initialization.
type providerConfig struct {
proxyURL *url.URL
proxyFromEnv bool
}
func configureProvider(_ context.Context, data *schema.ResourceData) (interface{}, diag.Diagnostics) {
var diags diag.Diagnostics
var config = &providerConfig{}
var err error
if proxyUrl, ok := data.GetOk("proxy.0.url"); ok {
config.proxyURL, err = url.Parse(proxyUrl.(string))
if err != nil {
diags = append(diags, diag.Diagnostic{
Severity: diag.Error,
Summary: fmt.Sprintf("Unable to parse proxy URL '%s': %v", proxyUrl, err),
})
}
}
if proxyUsername, ok := data.GetOk("proxy.0.username"); ok {
// NOTE: we know that `.proxyURL` is set, as this is imposed by the provider schema
config.proxyURL.User = url.User(proxyUsername.(string))
}
if proxyPassword, ok := data.GetOk("proxy.0.password"); ok {
// NOTE: we know that `.proxyURL.User.Username()` is set, as this is imposed by the provider schema
config.proxyURL.User = url.UserPassword(config.proxyURL.User.Username(), proxyPassword.(string))
}
if proxyFromEnv, ok := data.GetOk("proxy.0.from_env"); ok {
config.proxyFromEnv = proxyFromEnv.(bool)
}
return config, diags
}
// proxyForRequestFunc is an adapter that returns the configured proxy.
//
// It works by returning a function that, given an *http.Request,
// provides the http.Client with the *url.URL to the proxy.
func (pc *providerConfig) proxyForRequestFunc() func(_ *http.Request) (*url.URL, error) {
if pc.proxyFromEnv {
return http.ProxyFromEnvironment
}
return func(_ *http.Request) (*url.URL, error) {
return pc.proxyURL, nil
}
}
func (pc *providerConfig) isProxyConfigured() bool {
return pc.proxyURL != nil || pc.proxyFromEnv
}