dependabot-terraform 0.148.10 → 0.149.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ed478756c01d88049afd53fc85a20ad7ed9063791ab30058d0f917e26dc47e5
4
- data.tar.gz: 72510b0297858ce6b4d417542100a6697d546a4e0e4d0d405e55a1e51796fb43
3
+ metadata.gz: e9de51bfa366e94b80943405b7083988d76080444dc177b57d9a8fd425e9292f
4
+ data.tar.gz: 1d4794c8175cac535813c12a8e017e3b8e3c4f96068a91e5db3c75db5945ceba
5
5
  SHA512:
6
- metadata.gz: 8c2c0a8a731d1ff0baf8ce05af819e819702be48302173d12e6973b84af8e304fe75cdb323198f28d4a20358c836a8edb699659bf5db3232944334cd76f7e735
7
- data.tar.gz: 4a651ed95e4d097100595c457146faba5e097ea12b1f7ebecbd38156bd55c7f51ec07fdb84c0a07ff8defdcd4546c92376571ffc5b3e322bfd68402e33ddeec0
6
+ metadata.gz: 74431e13c158375f439e50127078fd7db31b56387cf3a2ff5d013ebff91427642c2b67874dd94a22e83d336f58efddcb6ec9edeb4181d7cadc25fe759fe12fcc
7
+ data.tar.gz: 384487d5ad087fee58324485f1c288ae7803f550e6b763128efadc883999931dd233182f56afc8c26ec2030d20179b234d32b0c96b535722c72fedf4cfa0e49e
@@ -99,19 +99,19 @@ module Dependabot
99
99
 
100
100
  def provider_declaration_regex
101
101
  name = Regexp.escape(dependency.name)
102
- /
103
- ((source\s*=\s*["']#{name}["']|\s*#{name}\s*=\s*\{.*)
102
+ %r{
103
+ ((source\s*=\s*["'](#{Regexp.escape(registry_host_for(dependency))}/)?#{name}["']|\s*#{name}\s*=\s*\{.*)
104
104
  (?:(?!^\}).)+)
105
- /mx
105
+ }mx
106
106
  end
107
107
 
108
108
  def registry_declaration_regex
109
- /
109
+ %r{
110
110
  (?<=\{)
111
111
  (?:(?!^\}).)*
112
- source\s*=\s*["']#{Regexp.escape(dependency.name)}["']
112
+ source\s*=\s*["'](#{Regexp.escape(registry_host_for(dependency))}/)?#{Regexp.escape(dependency.name)}["']
113
113
  (?:(?!^\}).)*
114
- /mx
114
+ }mx
115
115
  end
116
116
 
117
117
  def git_declaration_regex(filename)
@@ -126,6 +126,11 @@ module Dependabot
126
126
  (?:(?!^\}).)*
127
127
  /mx
128
128
  end
129
+
130
+ def registry_host_for(dependency)
131
+ source = dependency.requirements.map { |r| r[:source] }.compact.first
132
+ source[:registry_hostname] || source["registry_hostname"] || "registry.terraform.io"
133
+ end
129
134
  end
130
135
  end
131
136
  end
@@ -4,6 +4,7 @@ require "excon"
4
4
  require "json"
5
5
  require "dependabot/metadata_finders"
6
6
  require "dependabot/metadata_finders/base"
7
+ require "dependabot/terraform/registry_client"
7
8
  require "dependabot/shared_helpers"
8
9
 
9
10
  module Dependabot
@@ -40,7 +41,9 @@ module Dependabot
40
41
  info = dependency.requirements.map { |r| r[:source] }.compact.first
41
42
  hostname = info[:registry_hostname] || info["registry_hostname"]
42
43
 
43
- RegistryClient.new(hostname: hostname).source(dependency: dependency)
44
+ RegistryClient.
45
+ new(hostname: hostname, credentials: credentials).
46
+ source(dependency: dependency)
44
47
  end
45
48
  end
46
49
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dependabot/dependency"
4
+ require "dependabot/errors"
4
5
  require "dependabot/source"
5
6
  require "dependabot/terraform/version"
6
7
 
@@ -11,8 +12,11 @@ module Dependabot
11
12
  class RegistryClient
12
13
  PUBLIC_HOSTNAME = "registry.terraform.io"
13
14
 
14
- def initialize(hostname:)
15
+ def initialize(hostname: PUBLIC_HOSTNAME, credentials: [])
15
16
  @hostname = hostname
17
+ @tokens = credentials.each_with_object({}) do |item, memo|
18
+ memo[item["host"]] = item["token"] if item["type"] == "terraform_registry"
19
+ end
16
20
  end
17
21
 
18
22
  # Fetch all the versions of a provider, and return a Version
@@ -21,14 +25,12 @@ module Dependabot
21
25
  # @param identifier [String] the identifier for the dependency, i.e:
22
26
  # "hashicorp/aws"
23
27
  # @return [Array<Dependabot::Terraform::Version>]
24
- # @raise [RuntimeError] when the versions cannot be retrieved
28
+ # @raise [Dependabot::DependabotError] when the versions cannot be retrieved
25
29
  def all_provider_versions(identifier:)
26
- # TODO: Implement service discovery for custom registries
27
- return [] unless hostname == PUBLIC_HOSTNAME
30
+ base_url = service_url_for("providers.v1")
31
+ response = http_get!(URI.join(base_url, "#{identifier}/versions"))
28
32
 
29
- response = get(endpoint: "providers/#{identifier}/versions")
30
-
31
- JSON.parse(response).
33
+ JSON.parse(response.body).
32
34
  fetch("versions").
33
35
  map { |release| version_class.new(release.fetch("version")) }
34
36
  end
@@ -39,14 +41,12 @@ module Dependabot
39
41
  # @param identifier [String] the identifier for the dependency, i.e:
40
42
  # "hashicorp/consul/aws"
41
43
  # @return [Array<Dependabot::Terraform::Version>]
42
- # @raise [RuntimeError] when the versions cannot be retrieved
44
+ # @raise [Dependabot::DependabotError] when the versions cannot be retrieved
43
45
  def all_module_versions(identifier:)
44
- # TODO: Implement service discovery for custom registries
45
- return [] unless hostname == PUBLIC_HOSTNAME
46
-
47
- response = get(endpoint: "modules/#{identifier}/versions")
46
+ base_url = service_url_for("modules.v1")
47
+ response = http_get!(URI.join(base_url, "#{identifier}/versions"))
48
48
 
49
- JSON.parse(response).
49
+ JSON.parse(response.body).
50
50
  fetch("modules").first.fetch("versions").
51
51
  map { |release| version_class.new(release.fetch("version")) }
52
52
  end
@@ -59,45 +59,85 @@ module Dependabot
59
59
  # @param dependency [Dependabot::Dependency] the dependency who's source
60
60
  # we're attempting to find
61
61
  # @return Dependabot::Source
62
- # @raise [RuntimeError] when the source cannot be retrieved
62
+ # @raise [Dependabot::DependabotError] when the source cannot be retrieved
63
63
  def source(dependency:)
64
- # TODO: Implement service discovery for custom registries
65
- return unless hostname == PUBLIC_HOSTNAME
66
-
67
64
  type = dependency.requirements.first[:source][:type]
68
- endpoint = if type == "registry"
69
- "modules/#{dependency.name}/#{dependency.version}"
70
- elsif type == "provider"
71
- "providers/#{dependency.name}/#{dependency.version}"
72
- else
73
- raise "Invalid source type"
74
- end
75
- response = get(endpoint: endpoint)
76
-
77
- source_url = JSON.parse(response).fetch("source")
65
+ base_url = service_url_for(service_key_for(type))
66
+ response = http_get!(URI.join(base_url, "#{dependency.name}/#{dependency.version}"))
67
+
68
+ source_url = JSON.parse(response.body).fetch("source")
78
69
  Source.from_url(source_url) if source_url
79
70
  end
80
71
 
72
+ # Perform service discovery and return the absolute URL for
73
+ # the requested service.
74
+ # https://www.terraform.io/docs/internals/remote-service-discovery.html
75
+ #
76
+ # @param service_key [String] the service type described in https://www.terraform.io/docs/internals/remote-service-discovery.html#supported-services
77
+ # @param return String
78
+ # @raise [Dependabot::DependabotError] when the service is not available
79
+ def service_url_for(service_key)
80
+ url_for(services.fetch(service_key))
81
+ rescue KeyError
82
+ raise error("Host does not support required Terraform-native service")
83
+ end
84
+
81
85
  private
82
86
 
83
- attr_reader :hostname
87
+ attr_reader :hostname, :tokens
84
88
 
85
- def get(endpoint:)
86
- url = "https://#{hostname}/v1/#{endpoint}"
89
+ def version_class
90
+ Version
91
+ end
87
92
 
88
- response = Excon.get(
89
- url,
90
- idempotent: true,
91
- **SharedHelpers.excon_defaults
92
- )
93
+ def headers_for(hostname)
94
+ token = tokens[hostname]
95
+ token ? { "Authorization" => "Bearer #{token}" } : {}
96
+ end
93
97
 
94
- raise "Response from registry was #{response.status}" unless response.status == 200
98
+ def services
99
+ @services ||=
100
+ begin
101
+ response = http_get(url_for("/.well-known/terraform.json"))
102
+ response.status == 200 ? JSON.parse(response.body) : {}
103
+ end
104
+ end
95
105
 
96
- response.body
106
+ def service_key_for(type)
107
+ case type
108
+ when "module", "modules", "registry"
109
+ "modules.v1"
110
+ when "provider", "providers"
111
+ "providers.v1"
112
+ else
113
+ raise error("Invalid source type")
114
+ end
97
115
  end
98
116
 
99
- def version_class
100
- Version
117
+ def http_get(url)
118
+ Excon.get(url.to_s, idempotent: true, **SharedHelpers.excon_defaults(headers: headers_for(hostname)))
119
+ end
120
+
121
+ def http_get!(url)
122
+ response = http_get(url)
123
+
124
+ raise error("Response from registry was #{response.status}") unless response.status == 200
125
+
126
+ response
127
+ end
128
+
129
+ def url_for(path)
130
+ uri = URI.parse(path)
131
+ return uri.to_s if uri.scheme == "https"
132
+ raise error("Unsupported scheme provided") if uri.host && uri.scheme
133
+
134
+ uri.host = hostname
135
+ uri.scheme = "https"
136
+ uri.to_s
137
+ end
138
+
139
+ def error(message)
140
+ Dependabot::DependabotError.new(message)
101
141
  end
102
142
  end
103
143
  end
@@ -87,7 +87,7 @@ module Dependabot
87
87
  def registry_client
88
88
  @registry_client ||= begin
89
89
  hostname = dependency_source_details.fetch(:registry_hostname)
90
- RegistryClient.new(hostname: hostname)
90
+ RegistryClient.new(hostname: hostname, credentials: credentials)
91
91
  end
92
92
  end
93
93
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dependabot-terraform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.148.10
4
+ version: 0.149.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-26 00:00:00.000000000 Z
11
+ date: 2021-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dependabot-common
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.148.10
19
+ version: 0.149.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.148.10
26
+ version: 0.149.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: byebug
29
29
  requirement: !ruby/object:Gem::Requirement