dependabot-terraform 0.201.1 → 0.204.0

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: 45897d4d4a465d56ad301bd4d7088bd499d64031d3cffd1647637ff013574395
4
- data.tar.gz: 74a5185b2e1e8ca45f832ecdfd7cde24ec0219b5ae82bfc6277b496c8f48c692
3
+ metadata.gz: 857c0219cc9c70bdef3a2c55738a7bf271bd1f64788ad38fd892576c7a73d36a
4
+ data.tar.gz: 8f7e1b97fe1530b307b8445a1f62c27f178399e3c03f8467d3117a6394b95c1b
5
5
  SHA512:
6
- metadata.gz: 96e5fdeb726b95f0d70b1bac87f7743fd5562cdeb68257bf50a95ea5068b4a45b0ecb477157f686b2db8752eb26d19c61e9c1f7caada700c5c36aab395e9f2f7
7
- data.tar.gz: 76e74e3b50f13783ea2102f6a36d217f9bb51386cdcff6fd3d115a1d63521b0353651b5416a4b5de78df4aa08c7b2c06ad47e59c67c8b047ace123487e0da8a7
6
+ metadata.gz: ed0ae12a8ab372985d6ed29d28dd25b9a9e4ef798b38d51291160f8af148f9e188cb11b28a6c7624610f17519df902d1d28579fb48fc0ee4916f862b113095fd
7
+ data.tar.gz: 3c8ecd036fde028e6fef102b8a70549011c4caa81a0a278879227c2165796b0dc8d312eed1e368927bc1f1b4c152edd051fcf37d6df6ee81766c3de78989adaa
@@ -12,6 +12,7 @@ require "dependabot/git_commit_checker"
12
12
  require "dependabot/shared_helpers"
13
13
  require "dependabot/errors"
14
14
  require "dependabot/terraform/file_selector"
15
+ require "dependabot/terraform/registry_client"
15
16
 
16
17
  module Dependabot
17
18
  module Terraform
@@ -20,7 +21,6 @@ module Dependabot
20
21
 
21
22
  include FileSelector
22
23
 
23
- ARCHIVE_EXTENSIONS = %w(.zip .tbz2 .tgz .txz).freeze
24
24
  DEFAULT_REGISTRY = "registry.terraform.io"
25
25
  DEFAULT_NAMESPACE = "hashicorp"
26
26
  # https://www.terraform.io/docs/language/providers/requirements.html#source-addresses
@@ -168,7 +168,7 @@ module Dependabot
168
168
  # Full docs at https://www.terraform.io/docs/modules/sources.html
169
169
  def source_from(details_hash)
170
170
  raw_source = details_hash.fetch("source")
171
- bare_source = get_proxied_source(raw_source)
171
+ bare_source = RegistryClient.get_proxied_source(raw_source)
172
172
 
173
173
  source_details =
174
174
  case source_type(bare_source)
@@ -257,39 +257,6 @@ module Dependabot
257
257
  ref.match(version_regex).named_captures.fetch("version")
258
258
  end
259
259
 
260
- # rubocop:disable Metrics/PerceivedComplexity
261
- # See https://www.terraform.io/docs/modules/sources.html#http-urls for
262
- # details of how Terraform handle HTTP(S) sources for modules
263
- def get_proxied_source(raw_source) # rubocop:disable Metrics/AbcSize
264
- return raw_source unless raw_source.start_with?("http")
265
-
266
- uri = URI.parse(raw_source.split(%r{(?<!:)//}).first)
267
- return raw_source if uri.path.end_with?(*ARCHIVE_EXTENSIONS)
268
- return raw_source if URI.parse(raw_source).query&.include?("archive=")
269
-
270
- url = raw_source.split(%r{(?<!:)//}).first + "?terraform-get=1"
271
- host = URI.parse(raw_source).host
272
-
273
- response = Excon.get(
274
- url,
275
- idempotent: true,
276
- **SharedHelpers.excon_defaults
277
- )
278
- raise PrivateSourceAuthenticationFailure, host if response.status == 401
279
-
280
- return response.headers["X-Terraform-Get"] if response.headers["X-Terraform-Get"]
281
-
282
- doc = Nokogiri::XML(response.body)
283
- doc.css("meta").find do |tag|
284
- tag.attributes&.fetch("name", nil)&.value == "terraform-get"
285
- end&.attributes&.fetch("content", nil)&.value
286
- rescue Excon::Error::Socket, Excon::Error::Timeout => e
287
- raise PrivateSourceAuthenticationFailure, host if e.message.include?("no address for")
288
-
289
- raw_source
290
- end
291
- # rubocop:enable Metrics/PerceivedComplexity
292
-
293
260
  # rubocop:disable Metrics/PerceivedComplexity
294
261
  def source_type(source_string)
295
262
  return :path if source_string.start_with?(".")
@@ -305,7 +272,7 @@ module Dependabot
305
272
 
306
273
  path_uri = URI.parse(source_string.split(%r{(?<!:)//}).first)
307
274
  query_uri = URI.parse(source_string)
308
- return :http_archive if path_uri.path.end_with?(*ARCHIVE_EXTENSIONS)
275
+ return :http_archive if path_uri.path.end_with?(*RegistryClient::ARCHIVE_EXTENSIONS)
309
276
  return :http_archive if query_uri.query&.include?("archive=")
310
277
 
311
278
  raise "HTTP source, but not an archive!"
@@ -103,6 +103,11 @@ module Dependabot
103
103
  select { |h| h&.match?(/^h1:/) }
104
104
  end
105
105
 
106
+ def remove_provider_h1_hashes(content, declaration_regex)
107
+ content.match(declaration_regex).to_s.
108
+ sub(hashes_object_regex, "")
109
+ end
110
+
106
111
  def lockfile_details(new_req)
107
112
  content = lock_file.content.dup
108
113
  provider_source = new_req[:source][:registry_hostname] + "/" + new_req[:source][:module_identifier]
@@ -131,7 +136,7 @@ module Dependabot
131
136
  )
132
137
 
133
138
  base_dir = dependency_files.first.directory
134
- lockfile_hash_removed = content.sub(hashes_object_regex, "")
139
+ lockfile_hash_removed = remove_provider_h1_hashes(content, declaration_regex)
135
140
 
136
141
  # This runs in the same directory as the actual lockfile update so
137
142
  # the platform must be determined before the updated manifest files
@@ -265,7 +270,7 @@ module Dependabot
265
270
  end
266
271
 
267
272
  def hashes_object_regex
268
- /hashes\s*=\s*.*\]/m
273
+ /hashes\s*=\s*[^\]]*\]/m
269
274
  end
270
275
 
271
276
  def hashes_string_regex
@@ -10,6 +10,7 @@ module Dependabot
10
10
  # Terraform::RegistryClient is a basic API client to interact with a
11
11
  # terraform registry: https://www.terraform.io/docs/registry/api.html
12
12
  class RegistryClient
13
+ ARCHIVE_EXTENSIONS = %w(.zip .tbz2 .tgz .txz).freeze
13
14
  PUBLIC_HOSTNAME = "registry.terraform.io"
14
15
 
15
16
  def initialize(hostname: PUBLIC_HOSTNAME, credentials: [])
@@ -19,6 +20,39 @@ module Dependabot
19
20
  end
20
21
  end
21
22
 
23
+ # rubocop:disable Metrics/PerceivedComplexity
24
+ # See https://www.terraform.io/docs/modules/sources.html#http-urls for
25
+ # details of how Terraform handle HTTP(S) sources for modules
26
+ def self.get_proxied_source(raw_source) # rubocop:disable Metrics/AbcSize
27
+ return raw_source unless raw_source.start_with?("http")
28
+
29
+ uri = URI.parse(raw_source.split(%r{(?<!:)//}).first)
30
+ return raw_source if uri.path.end_with?(*ARCHIVE_EXTENSIONS)
31
+ return raw_source if URI.parse(raw_source).query&.include?("archive=")
32
+
33
+ url = raw_source.split(%r{(?<!:)//}).first + "?terraform-get=1"
34
+ host = URI.parse(raw_source).host
35
+
36
+ response = Excon.get(
37
+ url,
38
+ idempotent: true,
39
+ **SharedHelpers.excon_defaults
40
+ )
41
+ raise PrivateSourceAuthenticationFailure, host if response.status == 401
42
+
43
+ return response.headers["X-Terraform-Get"] if response.headers["X-Terraform-Get"]
44
+
45
+ doc = Nokogiri::XML(response.body)
46
+ doc.css("meta").find do |tag|
47
+ tag.attributes&.fetch("name", nil)&.value == "terraform-get"
48
+ end&.attributes&.fetch("content", nil)&.value
49
+ rescue Excon::Error::Socket, Excon::Error::Timeout => e
50
+ raise PrivateSourceAuthenticationFailure, host if e.message.include?("no address for")
51
+
52
+ raw_source
53
+ end
54
+ # rubocop:enable Metrics/PerceivedComplexity
55
+
22
56
  # Fetch all the versions of a provider, and return a Version
23
57
  # representation of them.
24
58
  #
@@ -64,10 +98,26 @@ module Dependabot
64
98
  def source(dependency:)
65
99
  type = dependency.requirements.first[:source][:type]
66
100
  base_url = service_url_for(service_key_for(type))
67
- response = http_get(URI.join(base_url, "#{dependency.name}/#{dependency.version}"))
68
- return nil unless response.status == 200
101
+ case type
102
+ # https://www.terraform.io/internals/module-registry-protocol#download-source-code-for-a-specific-module-version
103
+ when "module", "modules", "registry"
104
+ download_url = URI.join(base_url, "#{dependency.name}/#{dependency.version}/download")
105
+ response = http_get(download_url)
106
+ return nil unless response.status == 204
107
+
108
+ source_url = response.headers.fetch("X-Terraform-Get")
109
+ source_url = URI.join(download_url, source_url) if
110
+ source_url.start_with?("/") ||
111
+ source_url.start_with?("./") ||
112
+ source_url.start_with?("../")
113
+ source_url = RegistryClient.get_proxied_source(source_url) if source_url
114
+ when "provider", "providers"
115
+ response = http_get(URI.join(base_url, "#{dependency.name}/#{dependency.version}"))
116
+ return nil unless response.status == 200
117
+
118
+ source_url = JSON.parse(response.body).fetch("source")
119
+ end
69
120
 
70
- source_url = JSON.parse(response.body).fetch("source")
71
121
  Source.from_url(source_url) if source_url
72
122
  rescue JSON::ParserError, Excon::Error::Timeout
73
123
  nil
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.201.1
4
+ version: 0.204.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dependabot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-25 00:00:00.000000000 Z
11
+ date: 2022-08-03 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.201.1
19
+ version: 0.204.0
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.201.1
26
+ version: 0.204.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: debase
29
29
  requirement: !ruby/object:Gem::Requirement