aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/terraform/registry
diff options
context:
space:
mode:
authorAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
committerAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
commit15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/hashicorp/terraform/registry
parent07971ca38143c5faf951d152fba370ddcbe26ad5 (diff)
downloadterraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/registry')
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/client.go227
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/errors.go23
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/regsrc/friendly_host.go140
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/regsrc/module.go205
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/regsrc/regsrc.go8
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/response/module.go93
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/response/module_list.go7
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/response/module_provider.go14
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/response/module_versions.go32
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/response/pagination.go65
-rw-r--r--vendor/github.com/hashicorp/terraform/registry/response/redirect.go6
11 files changed, 820 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/registry/client.go b/vendor/github.com/hashicorp/terraform/registry/client.go
new file mode 100644
index 0000000..a18e6b8
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/client.go
@@ -0,0 +1,227 @@
1package registry
2
3import (
4 "encoding/json"
5 "fmt"
6 "io/ioutil"
7 "log"
8 "net/http"
9 "net/url"
10 "path"
11 "strings"
12 "time"
13
14 "github.com/hashicorp/terraform/httpclient"
15 "github.com/hashicorp/terraform/registry/regsrc"
16 "github.com/hashicorp/terraform/registry/response"
17 "github.com/hashicorp/terraform/svchost"
18 "github.com/hashicorp/terraform/svchost/disco"
19 "github.com/hashicorp/terraform/version"
20)
21
22const (
23 xTerraformGet = "X-Terraform-Get"
24 xTerraformVersion = "X-Terraform-Version"
25 requestTimeout = 10 * time.Second
26 serviceID = "modules.v1"
27)
28
29var tfVersion = version.String()
30
31// Client provides methods to query Terraform Registries.
32type Client struct {
33 // this is the client to be used for all requests.
34 client *http.Client
35
36 // services is a required *disco.Disco, which may have services and
37 // credentials pre-loaded.
38 services *disco.Disco
39}
40
41// NewClient returns a new initialized registry client.
42func NewClient(services *disco.Disco, client *http.Client) *Client {
43 if services == nil {
44 services = disco.New()
45 }
46
47 if client == nil {
48 client = httpclient.New()
49 client.Timeout = requestTimeout
50 }
51
52 services.Transport = client.Transport
53
54 return &Client{
55 client: client,
56 services: services,
57 }
58}
59
60// Discover queries the host, and returns the url for the registry.
61func (c *Client) Discover(host svchost.Hostname) (*url.URL, error) {
62 service, err := c.services.DiscoverServiceURL(host, serviceID)
63 if err != nil {
64 return nil, err
65 }
66 if !strings.HasSuffix(service.Path, "/") {
67 service.Path += "/"
68 }
69 return service, nil
70}
71
72// Versions queries the registry for a module, and returns the available versions.
73func (c *Client) Versions(module *regsrc.Module) (*response.ModuleVersions, error) {
74 host, err := module.SvcHost()
75 if err != nil {
76 return nil, err
77 }
78
79 service, err := c.Discover(host)
80 if err != nil {
81 return nil, err
82 }
83
84 p, err := url.Parse(path.Join(module.Module(), "versions"))
85 if err != nil {
86 return nil, err
87 }
88
89 service = service.ResolveReference(p)
90
91 log.Printf("[DEBUG] fetching module versions from %q", service)
92
93 req, err := http.NewRequest("GET", service.String(), nil)
94 if err != nil {
95 return nil, err
96 }
97
98 c.addRequestCreds(host, req)
99 req.Header.Set(xTerraformVersion, tfVersion)
100
101 resp, err := c.client.Do(req)
102 if err != nil {
103 return nil, err
104 }
105 defer resp.Body.Close()
106
107 switch resp.StatusCode {
108 case http.StatusOK:
109 // OK
110 case http.StatusNotFound:
111 return nil, &errModuleNotFound{addr: module}
112 default:
113 return nil, fmt.Errorf("error looking up module versions: %s", resp.Status)
114 }
115
116 var versions response.ModuleVersions
117
118 dec := json.NewDecoder(resp.Body)
119 if err := dec.Decode(&versions); err != nil {
120 return nil, err
121 }
122
123 for _, mod := range versions.Modules {
124 for _, v := range mod.Versions {
125 log.Printf("[DEBUG] found available version %q for %s", v.Version, mod.Source)
126 }
127 }
128
129 return &versions, nil
130}
131
132func (c *Client) addRequestCreds(host svchost.Hostname, req *http.Request) {
133 creds, err := c.services.CredentialsForHost(host)
134 if err != nil {
135 log.Printf("[WARN] Failed to get credentials for %s: %s (ignoring)", host, err)
136 return
137 }
138
139 if creds != nil {
140 creds.PrepareRequest(req)
141 }
142}
143
144// Location find the download location for a specific version module.
145// This returns a string, because the final location may contain special go-getter syntax.
146func (c *Client) Location(module *regsrc.Module, version string) (string, error) {
147 host, err := module.SvcHost()
148 if err != nil {
149 return "", err
150 }
151
152 service, err := c.Discover(host)
153 if err != nil {
154 return "", err
155 }
156
157 var p *url.URL
158 if version == "" {
159 p, err = url.Parse(path.Join(module.Module(), "download"))
160 } else {
161 p, err = url.Parse(path.Join(module.Module(), version, "download"))
162 }
163 if err != nil {
164 return "", err
165 }
166 download := service.ResolveReference(p)
167
168 log.Printf("[DEBUG] looking up module location from %q", download)
169
170 req, err := http.NewRequest("GET", download.String(), nil)
171 if err != nil {
172 return "", err
173 }
174
175 c.addRequestCreds(host, req)
176 req.Header.Set(xTerraformVersion, tfVersion)
177
178 resp, err := c.client.Do(req)
179 if err != nil {
180 return "", err
181 }
182 defer resp.Body.Close()
183
184 // there should be no body, but save it for logging
185 body, err := ioutil.ReadAll(resp.Body)
186 if err != nil {
187 return "", fmt.Errorf("error reading response body from registry: %s", err)
188 }
189
190 switch resp.StatusCode {
191 case http.StatusOK, http.StatusNoContent:
192 // OK
193 case http.StatusNotFound:
194 return "", fmt.Errorf("module %q version %q not found", module, version)
195 default:
196 // anything else is an error:
197 return "", fmt.Errorf("error getting download location for %q: %s resp:%s", module, resp.Status, body)
198 }
199
200 // the download location is in the X-Terraform-Get header
201 location := resp.Header.Get(xTerraformGet)
202 if location == "" {
203 return "", fmt.Errorf("failed to get download URL for %q: %s resp:%s", module, resp.Status, body)
204 }
205
206 // If location looks like it's trying to be a relative URL, treat it as
207 // one.
208 //
209 // We don't do this for just _any_ location, since the X-Terraform-Get
210 // header is a go-getter location rather than a URL, and so not all
211 // possible values will parse reasonably as URLs.)
212 //
213 // When used in conjunction with go-getter we normally require this header
214 // to be an absolute URL, but we are more liberal here because third-party
215 // registry implementations may not "know" their own absolute URLs if
216 // e.g. they are running behind a reverse proxy frontend, or such.
217 if strings.HasPrefix(location, "/") || strings.HasPrefix(location, "./") || strings.HasPrefix(location, "../") {
218 locationURL, err := url.Parse(location)
219 if err != nil {
220 return "", fmt.Errorf("invalid relative URL for %q: %s", module, err)
221 }
222 locationURL = download.ResolveReference(locationURL)
223 location = locationURL.String()
224 }
225
226 return location, nil
227}
diff --git a/vendor/github.com/hashicorp/terraform/registry/errors.go b/vendor/github.com/hashicorp/terraform/registry/errors.go
new file mode 100644
index 0000000..b8dcd31
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/errors.go
@@ -0,0 +1,23 @@
1package registry
2
3import (
4 "fmt"
5
6 "github.com/hashicorp/terraform/registry/regsrc"
7)
8
9type errModuleNotFound struct {
10 addr *regsrc.Module
11}
12
13func (e *errModuleNotFound) Error() string {
14 return fmt.Sprintf("module %s not found", e.addr)
15}
16
17// IsModuleNotFound returns true only if the given error is a "module not found"
18// error. This allows callers to recognize this particular error condition
19// as distinct from operational errors such as poor network connectivity.
20func IsModuleNotFound(err error) bool {
21 _, ok := err.(*errModuleNotFound)
22 return ok
23}
diff --git a/vendor/github.com/hashicorp/terraform/registry/regsrc/friendly_host.go b/vendor/github.com/hashicorp/terraform/registry/regsrc/friendly_host.go
new file mode 100644
index 0000000..14b4dce
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/regsrc/friendly_host.go
@@ -0,0 +1,140 @@
1package regsrc
2
3import (
4 "regexp"
5 "strings"
6
7 "github.com/hashicorp/terraform/svchost"
8)
9
10var (
11 // InvalidHostString is a placeholder returned when a raw host can't be
12 // converted by IDNA spec. It will never be returned for any host for which
13 // Valid() is true.
14 InvalidHostString = "<invalid host>"
15
16 // urlLabelEndSubRe is a sub-expression that matches any character that's
17 // allowed at the start or end of a URL label according to RFC1123.
18 urlLabelEndSubRe = "[0-9A-Za-z]"
19
20 // urlLabelEndSubRe is a sub-expression that matches any character that's
21 // allowed at in a non-start or end of a URL label according to RFC1123.
22 urlLabelMidSubRe = "[0-9A-Za-z-]"
23
24 // urlLabelUnicodeSubRe is a sub-expression that matches any non-ascii char
25 // in an IDN (Unicode) display URL. It's not strict - there are only ~15k
26 // valid Unicode points in IDN RFC (some with conditions). We are just going
27 // with being liberal with matching and then erroring if we fail to convert
28 // to punycode later (which validates chars fully). This at least ensures
29 // ascii chars dissalowed by the RC1123 parts above don't become legal
30 // again.
31 urlLabelUnicodeSubRe = "[^[:ascii:]]"
32
33 // hostLabelSubRe is the sub-expression that matches a valid hostname label.
34 // It does not anchor the start or end so it can be composed into more
35 // complex RegExps below. Note that for sanity we don't handle disallowing
36 // raw punycode in this regexp (esp. since re2 doesn't support negative
37 // lookbehind, but we can capture it's presence here to check later).
38 hostLabelSubRe = "" +
39 // Match valid initial char, or unicode char
40 "(?:" + urlLabelEndSubRe + "|" + urlLabelUnicodeSubRe + ")" +
41 // Optionally, match 0 to 61 valid URL or Unicode chars,
42 // followed by one valid end char or unicode char
43 "(?:" +
44 "(?:" + urlLabelMidSubRe + "|" + urlLabelUnicodeSubRe + "){0,61}" +
45 "(?:" + urlLabelEndSubRe + "|" + urlLabelUnicodeSubRe + ")" +
46 ")?"
47
48 // hostSubRe is the sub-expression that matches a valid host prefix.
49 // Allows custom port.
50 hostSubRe = hostLabelSubRe + "(?:\\." + hostLabelSubRe + ")+(?::\\d+)?"
51
52 // hostRe is a regexp that matches a valid host prefix. Additional
53 // validation of unicode strings is needed for matches.
54 hostRe = regexp.MustCompile("^" + hostSubRe + "$")
55)
56
57// FriendlyHost describes a registry instance identified in source strings by a
58// simple bare hostname like registry.terraform.io.
59type FriendlyHost struct {
60 Raw string
61}
62
63func NewFriendlyHost(host string) *FriendlyHost {
64 return &FriendlyHost{Raw: host}
65}
66
67// ParseFriendlyHost attempts to parse a valid "friendly host" prefix from the
68// given string. If no valid prefix is found, host will be nil and rest will
69// contain the full source string. The host prefix must terminate at the end of
70// the input or at the first / character. If one or more characters exist after
71// the first /, they will be returned as rest (without the / delimiter).
72// Hostnames containing punycode WILL be parsed successfully since they may have
73// come from an internal normalized source string, however should be considered
74// invalid if the string came from a user directly. This must be checked
75// explicitly for user-input strings by calling Valid() on the
76// returned host.
77func ParseFriendlyHost(source string) (host *FriendlyHost, rest string) {
78 parts := strings.SplitN(source, "/", 2)
79
80 if hostRe.MatchString(parts[0]) {
81 host = &FriendlyHost{Raw: parts[0]}
82 if len(parts) == 2 {
83 rest = parts[1]
84 }
85 return
86 }
87
88 // No match, return whole string as rest along with nil host
89 rest = source
90 return
91}
92
93// Valid returns whether the host prefix is considered valid in any case.
94// Example of invalid prefixes might include ones that don't conform to the host
95// name specifications. Not that IDN prefixes containing punycode are not valid
96// input which we expect to always be in user-input or normalised display form.
97func (h *FriendlyHost) Valid() bool {
98 return svchost.IsValid(h.Raw)
99}
100
101// Display returns the host formatted for display to the user in CLI or web
102// output.
103func (h *FriendlyHost) Display() string {
104 return svchost.ForDisplay(h.Raw)
105}
106
107// Normalized returns the host formatted for internal reference or comparison.
108func (h *FriendlyHost) Normalized() string {
109 host, err := svchost.ForComparison(h.Raw)
110 if err != nil {
111 return InvalidHostString
112 }
113 return string(host)
114}
115
116// String returns the host formatted as the user originally typed it assuming it
117// was parsed from user input.
118func (h *FriendlyHost) String() string {
119 return h.Raw
120}
121
122// Equal compares the FriendlyHost against another instance taking normalization
123// into account. Invalid hosts cannot be compared and will always return false.
124func (h *FriendlyHost) Equal(other *FriendlyHost) bool {
125 if other == nil {
126 return false
127 }
128
129 otherHost, err := svchost.ForComparison(other.Raw)
130 if err != nil {
131 return false
132 }
133
134 host, err := svchost.ForComparison(h.Raw)
135 if err != nil {
136 return false
137 }
138
139 return otherHost == host
140}
diff --git a/vendor/github.com/hashicorp/terraform/registry/regsrc/module.go b/vendor/github.com/hashicorp/terraform/registry/regsrc/module.go
new file mode 100644
index 0000000..325706e
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/regsrc/module.go
@@ -0,0 +1,205 @@
1package regsrc
2
3import (
4 "errors"
5 "fmt"
6 "regexp"
7 "strings"
8
9 "github.com/hashicorp/terraform/svchost"
10)
11
12var (
13 ErrInvalidModuleSource = errors.New("not a valid registry module source")
14
15 // nameSubRe is the sub-expression that matches a valid module namespace or
16 // name. It's strictly a super-set of what GitHub allows for user/org and
17 // repo names respectively, but more restrictive than our original repo-name
18 // regex which allowed periods but could cause ambiguity with hostname
19 // prefixes. It does not anchor the start or end so it can be composed into
20 // more complex RegExps below. Alphanumeric with - and _ allowed in non
21 // leading or trailing positions. Max length 64 chars. (GitHub username is
22 // 38 max.)
23 nameSubRe = "[0-9A-Za-z](?:[0-9A-Za-z-_]{0,62}[0-9A-Za-z])?"
24
25 // providerSubRe is the sub-expression that matches a valid provider. It
26 // does not anchor the start or end so it can be composed into more complex
27 // RegExps below. Only lowercase chars and digits are supported in practice.
28 // Max length 64 chars.
29 providerSubRe = "[0-9a-z]{1,64}"
30
31 // moduleSourceRe is a regular expression that matches the basic
32 // namespace/name/provider[//...] format for registry sources. It assumes
33 // any FriendlyHost prefix has already been removed if present.
34 moduleSourceRe = regexp.MustCompile(
35 fmt.Sprintf("^(%s)\\/(%s)\\/(%s)(?:\\/\\/(.*))?$",
36 nameSubRe, nameSubRe, providerSubRe))
37
38 // NameRe is a regular expression defining the format allowed for namespace
39 // or name fields in module registry implementations.
40 NameRe = regexp.MustCompile("^" + nameSubRe + "$")
41
42 // ProviderRe is a regular expression defining the format allowed for
43 // provider fields in module registry implementations.
44 ProviderRe = regexp.MustCompile("^" + providerSubRe + "$")
45
46 // these hostnames are not allowed as registry sources, because they are
47 // already special case module sources in terraform.
48 disallowed = map[string]bool{
49 "github.com": true,
50 "bitbucket.org": true,
51 }
52)
53
54// Module describes a Terraform Registry Module source.
55type Module struct {
56 // RawHost is the friendly host prefix if one was present. It might be nil
57 // if the original source had no host prefix which implies
58 // PublicRegistryHost but is distinct from having an actual pointer to
59 // PublicRegistryHost since it encodes the fact the original string didn't
60 // include a host prefix at all which is significant for recovering actual
61 // input not just normalized form. Most callers should access it with Host()
62 // which will return public registry host instance if it's nil.
63 RawHost *FriendlyHost
64 RawNamespace string
65 RawName string
66 RawProvider string
67 RawSubmodule string
68}
69
70// NewModule construct a new module source from separate parts. Pass empty
71// string if host or submodule are not needed.
72func NewModule(host, namespace, name, provider, submodule string) (*Module, error) {
73 m := &Module{
74 RawNamespace: namespace,
75 RawName: name,
76 RawProvider: provider,
77 RawSubmodule: submodule,
78 }
79 if host != "" {
80 h := NewFriendlyHost(host)
81 if h != nil {
82 fmt.Println("HOST:", h)
83 if !h.Valid() || disallowed[h.Display()] {
84 return nil, ErrInvalidModuleSource
85 }
86 }
87 m.RawHost = h
88 }
89 return m, nil
90}
91
92// ParseModuleSource attempts to parse source as a Terraform registry module
93// source. If the string is not found to be in a valid format,
94// ErrInvalidModuleSource is returned. Note that this can only be used on
95// "input" strings, e.g. either ones supplied by the user or potentially
96// normalised but in Display form (unicode). It will fail to parse a source with
97// a punycoded domain since this is not permitted input from a user. If you have
98// an already normalized string internally, you can compare it without parsing
99// by comparing with the normalized version of the subject with the normal
100// string equality operator.
101func ParseModuleSource(source string) (*Module, error) {
102 // See if there is a friendly host prefix.
103 host, rest := ParseFriendlyHost(source)
104 if host != nil {
105 if !host.Valid() || disallowed[host.Display()] {
106 return nil, ErrInvalidModuleSource
107 }
108 }
109
110 matches := moduleSourceRe.FindStringSubmatch(rest)
111 if len(matches) < 4 {
112 return nil, ErrInvalidModuleSource
113 }
114
115 m := &Module{
116 RawHost: host,
117 RawNamespace: matches[1],
118 RawName: matches[2],
119 RawProvider: matches[3],
120 }
121
122 if len(matches) == 5 {
123 m.RawSubmodule = matches[4]
124 }
125
126 return m, nil
127}
128
129// Display returns the source formatted for display to the user in CLI or web
130// output.
131func (m *Module) Display() string {
132 return m.formatWithPrefix(m.normalizedHostPrefix(m.Host().Display()), false)
133}
134
135// Normalized returns the source formatted for internal reference or comparison.
136func (m *Module) Normalized() string {
137 return m.formatWithPrefix(m.normalizedHostPrefix(m.Host().Normalized()), false)
138}
139
140// String returns the source formatted as the user originally typed it assuming
141// it was parsed from user input.
142func (m *Module) String() string {
143 // Don't normalize public registry hostname - leave it exactly like the user
144 // input it.
145 hostPrefix := ""
146 if m.RawHost != nil {
147 hostPrefix = m.RawHost.String() + "/"
148 }
149 return m.formatWithPrefix(hostPrefix, true)
150}
151
152// Equal compares the module source against another instance taking
153// normalization into account.
154func (m *Module) Equal(other *Module) bool {
155 return m.Normalized() == other.Normalized()
156}
157
158// Host returns the FriendlyHost object describing which registry this module is
159// in. If the original source string had not host component this will return the
160// PublicRegistryHost.
161func (m *Module) Host() *FriendlyHost {
162 if m.RawHost == nil {
163 return PublicRegistryHost
164 }
165 return m.RawHost
166}
167
168func (m *Module) normalizedHostPrefix(host string) string {
169 if m.Host().Equal(PublicRegistryHost) {
170 return ""
171 }
172 return host + "/"
173}
174
175func (m *Module) formatWithPrefix(hostPrefix string, preserveCase bool) string {
176 suffix := ""
177 if m.RawSubmodule != "" {
178 suffix = "//" + m.RawSubmodule
179 }
180 str := fmt.Sprintf("%s%s/%s/%s%s", hostPrefix, m.RawNamespace, m.RawName,
181 m.RawProvider, suffix)
182
183 // lower case by default
184 if !preserveCase {
185 return strings.ToLower(str)
186 }
187 return str
188}
189
190// Module returns just the registry ID of the module, without a hostname or
191// suffix.
192func (m *Module) Module() string {
193 return fmt.Sprintf("%s/%s/%s", m.RawNamespace, m.RawName, m.RawProvider)
194}
195
196// SvcHost returns the svchost.Hostname for this module. Since FriendlyHost may
197// contain an invalid hostname, this also returns an error indicating if it
198// could be converted to a svchost.Hostname. If no host is specified, the
199// default PublicRegistryHost is returned.
200func (m *Module) SvcHost() (svchost.Hostname, error) {
201 if m.RawHost == nil {
202 return svchost.ForComparison(PublicRegistryHost.Raw)
203 }
204 return svchost.ForComparison(m.RawHost.Raw)
205}
diff --git a/vendor/github.com/hashicorp/terraform/registry/regsrc/regsrc.go b/vendor/github.com/hashicorp/terraform/registry/regsrc/regsrc.go
new file mode 100644
index 0000000..c430bf1
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/regsrc/regsrc.go
@@ -0,0 +1,8 @@
1// Package regsrc provides helpers for working with source strings that identify
2// resources within a Terraform registry.
3package regsrc
4
5var (
6 // PublicRegistryHost is a FriendlyHost that represents the public registry.
7 PublicRegistryHost = NewFriendlyHost("registry.terraform.io")
8)
diff --git a/vendor/github.com/hashicorp/terraform/registry/response/module.go b/vendor/github.com/hashicorp/terraform/registry/response/module.go
new file mode 100644
index 0000000..3bd2b3d
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/response/module.go
@@ -0,0 +1,93 @@
1package response
2
3import (
4 "time"
5)
6
7// Module is the response structure with the data for a single module version.
8type Module struct {
9 ID string `json:"id"`
10
11 //---------------------------------------------------------------
12 // Metadata about the overall module.
13
14 Owner string `json:"owner"`
15 Namespace string `json:"namespace"`
16 Name string `json:"name"`
17 Version string `json:"version"`
18 Provider string `json:"provider"`
19 Description string `json:"description"`
20 Source string `json:"source"`
21 PublishedAt time.Time `json:"published_at"`
22 Downloads int `json:"downloads"`
23 Verified bool `json:"verified"`
24}
25
26// ModuleDetail represents a module in full detail.
27type ModuleDetail struct {
28 Module
29
30 //---------------------------------------------------------------
31 // Metadata about the overall module. This is only available when
32 // requesting the specific module (not in list responses).
33
34 // Root is the root module.
35 Root *ModuleSubmodule `json:"root"`
36
37 // Submodules are the other submodules that are available within
38 // this module.
39 Submodules []*ModuleSubmodule `json:"submodules"`
40
41 //---------------------------------------------------------------
42 // The fields below are only set when requesting this specific
43 // module. They are available to easily know all available versions
44 // and providers without multiple API calls.
45
46 Providers []string `json:"providers"` // All available providers
47 Versions []string `json:"versions"` // All versions
48}
49
50// ModuleSubmodule is the metadata about a specific submodule within
51// a module. This includes the root module as a special case.
52type ModuleSubmodule struct {
53 Path string `json:"path"`
54 Readme string `json:"readme"`
55 Empty bool `json:"empty"`
56
57 Inputs []*ModuleInput `json:"inputs"`
58 Outputs []*ModuleOutput `json:"outputs"`
59 Dependencies []*ModuleDep `json:"dependencies"`
60 Resources []*ModuleResource `json:"resources"`
61}
62
63// ModuleInput is an input for a module.
64type ModuleInput struct {
65 Name string `json:"name"`
66 Description string `json:"description"`
67 Default string `json:"default"`
68}
69
70// ModuleOutput is an output for a module.
71type ModuleOutput struct {
72 Name string `json:"name"`
73 Description string `json:"description"`
74}
75
76// ModuleDep is an output for a module.
77type ModuleDep struct {
78 Name string `json:"name"`
79 Source string `json:"source"`
80 Version string `json:"version"`
81}
82
83// ModuleProviderDep is the output for a provider dependency
84type ModuleProviderDep struct {
85 Name string `json:"name"`
86 Version string `json:"version"`
87}
88
89// ModuleResource is an output for a module.
90type ModuleResource struct {
91 Name string `json:"name"`
92 Type string `json:"type"`
93}
diff --git a/vendor/github.com/hashicorp/terraform/registry/response/module_list.go b/vendor/github.com/hashicorp/terraform/registry/response/module_list.go
new file mode 100644
index 0000000..9783748
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/response/module_list.go
@@ -0,0 +1,7 @@
1package response
2
3// ModuleList is the response structure for a pageable list of modules.
4type ModuleList struct {
5 Meta PaginationMeta `json:"meta"`
6 Modules []*Module `json:"modules"`
7}
diff --git a/vendor/github.com/hashicorp/terraform/registry/response/module_provider.go b/vendor/github.com/hashicorp/terraform/registry/response/module_provider.go
new file mode 100644
index 0000000..e48499d
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/response/module_provider.go
@@ -0,0 +1,14 @@
1package response
2
3// ModuleProvider represents a single provider for modules.
4type ModuleProvider struct {
5 Name string `json:"name"`
6 Downloads int `json:"downloads"`
7 ModuleCount int `json:"module_count"`
8}
9
10// ModuleProviderList is the response structure for a pageable list of ModuleProviders.
11type ModuleProviderList struct {
12 Meta PaginationMeta `json:"meta"`
13 Providers []*ModuleProvider `json:"providers"`
14}
diff --git a/vendor/github.com/hashicorp/terraform/registry/response/module_versions.go b/vendor/github.com/hashicorp/terraform/registry/response/module_versions.go
new file mode 100644
index 0000000..f69e975
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/response/module_versions.go
@@ -0,0 +1,32 @@
1package response
2
3// ModuleVersions is the response format that contains all metadata about module
4// versions needed for terraform CLI to resolve version constraints. See RFC
5// TF-042 for details on this format.
6type ModuleVersions struct {
7 Modules []*ModuleProviderVersions `json:"modules"`
8}
9
10// ModuleProviderVersions is the response format for a single module instance,
11// containing metadata about all versions and their dependencies.
12type ModuleProviderVersions struct {
13 Source string `json:"source"`
14 Versions []*ModuleVersion `json:"versions"`
15}
16
17// ModuleVersion is the output metadata for a given version needed by CLI to
18// resolve candidate versions to satisfy requirements.
19type ModuleVersion struct {
20 Version string `json:"version"`
21 Root VersionSubmodule `json:"root"`
22 Submodules []*VersionSubmodule `json:"submodules"`
23}
24
25// VersionSubmodule is the output metadata for a submodule within a given
26// version needed by CLI to resolve candidate versions to satisfy requirements.
27// When representing the Root in JSON the path is omitted.
28type VersionSubmodule struct {
29 Path string `json:"path,omitempty"`
30 Providers []*ModuleProviderDep `json:"providers"`
31 Dependencies []*ModuleDep `json:"dependencies"`
32}
diff --git a/vendor/github.com/hashicorp/terraform/registry/response/pagination.go b/vendor/github.com/hashicorp/terraform/registry/response/pagination.go
new file mode 100644
index 0000000..75a9254
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/response/pagination.go
@@ -0,0 +1,65 @@
1package response
2
3import (
4 "net/url"
5 "strconv"
6)
7
8// PaginationMeta is a structure included in responses for pagination.
9type PaginationMeta struct {
10 Limit int `json:"limit"`
11 CurrentOffset int `json:"current_offset"`
12 NextOffset *int `json:"next_offset,omitempty"`
13 PrevOffset *int `json:"prev_offset,omitempty"`
14 NextURL string `json:"next_url,omitempty"`
15 PrevURL string `json:"prev_url,omitempty"`
16}
17
18// NewPaginationMeta populates pagination meta data from result parameters
19func NewPaginationMeta(offset, limit int, hasMore bool, currentURL string) PaginationMeta {
20 pm := PaginationMeta{
21 Limit: limit,
22 CurrentOffset: offset,
23 }
24
25 // Calculate next/prev offsets, leave nil if not valid pages
26 nextOffset := offset + limit
27 if hasMore {
28 pm.NextOffset = &nextOffset
29 }
30
31 prevOffset := offset - limit
32 if prevOffset < 0 {
33 prevOffset = 0
34 }
35 if prevOffset < offset {
36 pm.PrevOffset = &prevOffset
37 }
38
39 // If URL format provided, populate URLs. Intentionally swallow URL errors for now, API should
40 // catch missing URLs if we call with bad URL arg (and we care about them being present).
41 if currentURL != "" && pm.NextOffset != nil {
42 pm.NextURL, _ = setQueryParam(currentURL, "offset", *pm.NextOffset, 0)
43 }
44 if currentURL != "" && pm.PrevOffset != nil {
45 pm.PrevURL, _ = setQueryParam(currentURL, "offset", *pm.PrevOffset, 0)
46 }
47
48 return pm
49}
50
51func setQueryParam(baseURL, key string, val, defaultVal int) (string, error) {
52 u, err := url.Parse(baseURL)
53 if err != nil {
54 return "", err
55 }
56 q := u.Query()
57 if val == defaultVal {
58 // elide param if it's the default value
59 q.Del(key)
60 } else {
61 q.Set(key, strconv.Itoa(val))
62 }
63 u.RawQuery = q.Encode()
64 return u.String(), nil
65}
diff --git a/vendor/github.com/hashicorp/terraform/registry/response/redirect.go b/vendor/github.com/hashicorp/terraform/registry/response/redirect.go
new file mode 100644
index 0000000..d5eb49b
--- /dev/null
+++ b/vendor/github.com/hashicorp/terraform/registry/response/redirect.go
@@ -0,0 +1,6 @@
1package response
2
3// Redirect causes the frontend to perform a window redirect.
4type Redirect struct {
5 URL string `json:"url"`
6}