dependabot-terraform 0.367.0 → 0.368.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 70cf97fb42d98440944e843c09f2909b5206a0859715b170c17c94e355ade662
|
|
4
|
+
data.tar.gz: 6c8022c3e1a286992bbc83a1851c84ff293e29f6b5773d287e0498bc55b38150
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 45336906f1e79f9fb1d27945e1a52e0e40e2a760128dfb5ca6fca7389dc05b87fe0121b005a598f391eeb2128b92fda4a3cd8c66ad1c15aead11a58fba8d3a65
|
|
7
|
+
data.tar.gz: 7c33db9982823d3ae2d92cf7b2f8ba03eca0e7505a7a5a02ef957b28b616bb2be7a73905a42879e0b0f3bea57a31c210d6520bb969bac1e615a675746a4d3feb
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "sorbet-runtime"
|
|
5
|
+
require "json"
|
|
6
|
+
require "open3"
|
|
7
|
+
require "securerandom"
|
|
8
|
+
require "pathname"
|
|
9
|
+
require "dependabot/shared_helpers"
|
|
10
|
+
require "dependabot/terraform/file_updater"
|
|
11
|
+
|
|
12
|
+
module Dependabot
|
|
13
|
+
module Terraform
|
|
14
|
+
class FileUpdater < Dependabot::FileUpdaters::Base
|
|
15
|
+
# Builds a Terraform CLI config that uses dev_overrides for non-target
|
|
16
|
+
# providers, preventing Terraform from resolving private/custom providers
|
|
17
|
+
# during lockfile updates.
|
|
18
|
+
class ProviderCliConfigBuilder
|
|
19
|
+
extend T::Sig
|
|
20
|
+
|
|
21
|
+
DEFAULT_REGISTRY = "registry.terraform.io"
|
|
22
|
+
DEFAULT_NAMESPACE = "hashicorp"
|
|
23
|
+
|
|
24
|
+
sig do
|
|
25
|
+
params(
|
|
26
|
+
dependency: Dependabot::Dependency,
|
|
27
|
+
terraform_files: T::Array[Dependabot::DependencyFile]
|
|
28
|
+
).void
|
|
29
|
+
end
|
|
30
|
+
def initialize(dependency:, terraform_files:)
|
|
31
|
+
@dependency = dependency
|
|
32
|
+
@terraform_files = terraform_files
|
|
33
|
+
@terraform_cli_config_path = T.let(nil, T.nilable(String))
|
|
34
|
+
@dev_override_dir = T.let(nil, T.nilable(String))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
sig { returns(T::Hash[String, String]) }
|
|
38
|
+
def env
|
|
39
|
+
sources = non_target_provider_sources
|
|
40
|
+
return {} if sources.empty?
|
|
41
|
+
|
|
42
|
+
config_path = generate_provider_dev_overrides_config(sources)
|
|
43
|
+
{ "TF_CLI_CONFIG_FILE" => config_path }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
sig { void }
|
|
47
|
+
def cleanup
|
|
48
|
+
if @terraform_cli_config_path
|
|
49
|
+
FileUtils.rm_f(@terraform_cli_config_path)
|
|
50
|
+
@terraform_cli_config_path = nil
|
|
51
|
+
end
|
|
52
|
+
return unless @dev_override_dir
|
|
53
|
+
|
|
54
|
+
FileUtils.rm_rf(@dev_override_dir)
|
|
55
|
+
@dev_override_dir = nil
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
sig { returns(Dependabot::Dependency) }
|
|
61
|
+
attr_reader :dependency
|
|
62
|
+
|
|
63
|
+
sig { returns(T::Array[Dependabot::DependencyFile]) }
|
|
64
|
+
attr_reader :terraform_files
|
|
65
|
+
|
|
66
|
+
sig { returns(T::Array[String]) }
|
|
67
|
+
def non_target_provider_sources
|
|
68
|
+
target = target_provider_source
|
|
69
|
+
return [] unless target
|
|
70
|
+
|
|
71
|
+
collect_provider_sources_from_files.reject { |s| s == target }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
sig { returns(T.nilable(String)) }
|
|
75
|
+
def target_provider_source
|
|
76
|
+
req = dependency.requirements.first
|
|
77
|
+
return unless req
|
|
78
|
+
|
|
79
|
+
source = req[:source]
|
|
80
|
+
return unless source && source[:type] == "provider"
|
|
81
|
+
|
|
82
|
+
hostname = source[:registry_hostname] || DEFAULT_REGISTRY
|
|
83
|
+
identifier = source[:module_identifier]
|
|
84
|
+
return unless identifier
|
|
85
|
+
|
|
86
|
+
"#{hostname}/#{identifier}".downcase
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
sig { returns(T::Array[String]) }
|
|
90
|
+
def collect_provider_sources_from_files
|
|
91
|
+
sources = T.let([], T::Array[String])
|
|
92
|
+
terraform_files.each do |file|
|
|
93
|
+
parsed = parse_hcl_file(file)
|
|
94
|
+
parsed.fetch("terraform", []).each do |terraform_block|
|
|
95
|
+
terraform_block.fetch("required_providers", {}).each do |providers|
|
|
96
|
+
providers.each do |name, details|
|
|
97
|
+
next unless details.is_a?(Hash)
|
|
98
|
+
|
|
99
|
+
source_address = details.fetch("source", nil)
|
|
100
|
+
sources << normalize_provider_source(source_address, name)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
sources.uniq
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
sig { params(source_address: T.nilable(String), name: String).returns(String) }
|
|
109
|
+
def normalize_provider_source(source_address, name)
|
|
110
|
+
if source_address
|
|
111
|
+
parts = source_address.split("/")
|
|
112
|
+
if parts.length == 2
|
|
113
|
+
"#{DEFAULT_REGISTRY}/#{source_address}".downcase
|
|
114
|
+
else
|
|
115
|
+
source_address.downcase
|
|
116
|
+
end
|
|
117
|
+
else
|
|
118
|
+
"#{DEFAULT_REGISTRY}/#{DEFAULT_NAMESPACE}/#{name}".downcase
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
sig { params(file: Dependabot::DependencyFile).returns(T::Hash[String, T.untyped]) }
|
|
123
|
+
def parse_hcl_file(file)
|
|
124
|
+
return {} unless file.content
|
|
125
|
+
|
|
126
|
+
SharedHelpers.in_a_temporary_directory do
|
|
127
|
+
File.write("tmp.tf", file.content)
|
|
128
|
+
command = "#{terraform_hcl2_parser_path} < tmp.tf"
|
|
129
|
+
stdout, _stderr, process = Open3.capture3(command)
|
|
130
|
+
return {} unless process.success?
|
|
131
|
+
|
|
132
|
+
JSON.parse(stdout)
|
|
133
|
+
end
|
|
134
|
+
rescue StandardError
|
|
135
|
+
{}
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
sig { params(provider_sources: T::Array[String]).returns(String) }
|
|
139
|
+
def generate_provider_dev_overrides_config(provider_sources)
|
|
140
|
+
dev_override_dir = File.join(Dir.tmpdir, "dependabot-tf-dev-#{SecureRandom.hex(4)}")
|
|
141
|
+
FileUtils.mkdir_p(dev_override_dir)
|
|
142
|
+
@dev_override_dir = dev_override_dir
|
|
143
|
+
|
|
144
|
+
overrides = provider_sources.map do |source|
|
|
145
|
+
" \"#{source}\" = \"#{dev_override_dir}\""
|
|
146
|
+
end.join("\n")
|
|
147
|
+
|
|
148
|
+
config_content = <<~CONFIG
|
|
149
|
+
provider_installation {
|
|
150
|
+
dev_overrides {
|
|
151
|
+
#{overrides}
|
|
152
|
+
}
|
|
153
|
+
direct {}
|
|
154
|
+
}
|
|
155
|
+
CONFIG
|
|
156
|
+
|
|
157
|
+
config_path = File.join(Dir.tmpdir, "dependabot-terraform-#{SecureRandom.hex(4)}.rc")
|
|
158
|
+
File.write(config_path, config_content)
|
|
159
|
+
@terraform_cli_config_path = config_path
|
|
160
|
+
|
|
161
|
+
config_path
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
sig { returns(String) }
|
|
165
|
+
def terraform_hcl2_parser_path
|
|
166
|
+
helper_bin_dir = File.join(native_helpers_root, "terraform/bin")
|
|
167
|
+
Pathname.new(File.join(helper_bin_dir, "hcl2json")).cleanpath.to_path
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
sig { returns(String) }
|
|
171
|
+
def native_helpers_root
|
|
172
|
+
default_path = File.join(__dir__, "../../../../helpers/install-dir")
|
|
173
|
+
ENV.fetch("DEPENDABOT_NATIVE_HELPERS_PATH", default_path)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -14,6 +14,8 @@ module Dependabot
|
|
|
14
14
|
class FileUpdater < Dependabot::FileUpdaters::Base
|
|
15
15
|
extend T::Sig
|
|
16
16
|
|
|
17
|
+
require_relative "file_updater/provider_cli_config_builder"
|
|
18
|
+
|
|
17
19
|
include FileSelector
|
|
18
20
|
|
|
19
21
|
PRIVATE_MODULE_ERROR = /Could not download module.*code from\n.*\"(?<repo>\S+)\":/
|
|
@@ -46,6 +48,8 @@ module Dependabot
|
|
|
46
48
|
raise "No files changed!" if updated_files.none?
|
|
47
49
|
|
|
48
50
|
updated_files
|
|
51
|
+
ensure
|
|
52
|
+
cleanup_terraform_cli_config
|
|
49
53
|
end
|
|
50
54
|
|
|
51
55
|
private
|
|
@@ -215,7 +219,8 @@ module Dependabot
|
|
|
215
219
|
|
|
216
220
|
SharedHelpers.run_shell_command(
|
|
217
221
|
"terraform providers lock -platform=#{arch} #{provider_source} -no-color",
|
|
218
|
-
fingerprint: "terraform providers lock -platform=<arch> <provider_source> -no-color"
|
|
222
|
+
fingerprint: "terraform providers lock -platform=<arch> <provider_source> -no-color",
|
|
223
|
+
env: terraform_env
|
|
219
224
|
)
|
|
220
225
|
|
|
221
226
|
updated_lockfile = File.read(".terraform.lock.hcl")
|
|
@@ -282,7 +287,8 @@ module Dependabot
|
|
|
282
287
|
|
|
283
288
|
SharedHelpers.run_shell_command(
|
|
284
289
|
"terraform providers lock #{platforms} #{provider_source}",
|
|
285
|
-
fingerprint: "terraform providers lock <platforms> <provider_source>"
|
|
290
|
+
fingerprint: "terraform providers lock <platforms> <provider_source>",
|
|
291
|
+
env: terraform_env
|
|
286
292
|
)
|
|
287
293
|
|
|
288
294
|
updated_lockfile = File.read(".terraform.lock.hcl")
|
|
@@ -319,7 +325,10 @@ module Dependabot
|
|
|
319
325
|
# -backend=false option used to ignore any backend configuration, as these won't be accessible
|
|
320
326
|
# -input=false option used to immediately fail if it needs user input
|
|
321
327
|
# -no-color option used to prevent any color characters being printed in the output
|
|
322
|
-
SharedHelpers.run_shell_command(
|
|
328
|
+
SharedHelpers.run_shell_command(
|
|
329
|
+
"terraform init -backend=false -input=false -no-color",
|
|
330
|
+
env: terraform_env
|
|
331
|
+
)
|
|
323
332
|
rescue SharedHelpers::HelperSubprocessFailed => e
|
|
324
333
|
output = e.message
|
|
325
334
|
|
|
@@ -428,6 +437,30 @@ module Dependabot
|
|
|
428
437
|
(?:(?!^\}).)*}
|
|
429
438
|
/mix
|
|
430
439
|
end
|
|
440
|
+
|
|
441
|
+
sig { returns(T::Hash[String, String]) }
|
|
442
|
+
def terraform_env
|
|
443
|
+
@terraform_env ||= T.let(
|
|
444
|
+
provider_cli_config_builder.env,
|
|
445
|
+
T.nilable(T::Hash[String, String])
|
|
446
|
+
)
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
sig { void }
|
|
450
|
+
def cleanup_terraform_cli_config
|
|
451
|
+
provider_cli_config_builder.cleanup
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
sig { returns(ProviderCliConfigBuilder) }
|
|
455
|
+
def provider_cli_config_builder
|
|
456
|
+
@provider_cli_config_builder ||= T.let(
|
|
457
|
+
ProviderCliConfigBuilder.new(
|
|
458
|
+
dependency: dependency,
|
|
459
|
+
terraform_files: terraform_files
|
|
460
|
+
),
|
|
461
|
+
T.nilable(ProviderCliConfigBuilder)
|
|
462
|
+
)
|
|
463
|
+
end
|
|
431
464
|
end
|
|
432
465
|
|
|
433
466
|
class FileUpdaterErrorHandler
|
|
@@ -227,8 +227,11 @@ module Dependabot
|
|
|
227
227
|
return uri.to_s if uri.scheme == "https"
|
|
228
228
|
raise error("Unsupported scheme provided") if uri.host && uri.scheme
|
|
229
229
|
|
|
230
|
-
|
|
230
|
+
parsed_hostname = URI.parse("https://#{hostname}")
|
|
231
|
+
uri.host = parsed_hostname.host
|
|
231
232
|
uri.scheme = "https"
|
|
233
|
+
# Only set port explicitly when it differs from the default HTTPS port
|
|
234
|
+
uri.port = parsed_hostname.port unless parsed_hostname.port == URI::HTTPS.default_port
|
|
232
235
|
uri.to_s
|
|
233
236
|
end
|
|
234
237
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dependabot-terraform
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.368.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dependabot
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.
|
|
18
|
+
version: 0.368.0
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.
|
|
25
|
+
version: 0.368.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: debug
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -248,6 +248,7 @@ files:
|
|
|
248
248
|
- lib/dependabot/terraform/file_parser.rb
|
|
249
249
|
- lib/dependabot/terraform/file_selector.rb
|
|
250
250
|
- lib/dependabot/terraform/file_updater.rb
|
|
251
|
+
- lib/dependabot/terraform/file_updater/provider_cli_config_builder.rb
|
|
251
252
|
- lib/dependabot/terraform/metadata_finder.rb
|
|
252
253
|
- lib/dependabot/terraform/package/package_details_fetcher.rb
|
|
253
254
|
- lib/dependabot/terraform/package_manager.rb
|
|
@@ -262,7 +263,7 @@ licenses:
|
|
|
262
263
|
- MIT
|
|
263
264
|
metadata:
|
|
264
265
|
bug_tracker_uri: https://github.com/dependabot/dependabot-core/issues
|
|
265
|
-
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.
|
|
266
|
+
changelog_uri: https://github.com/dependabot/dependabot-core/releases/tag/v0.368.0
|
|
266
267
|
rdoc_options: []
|
|
267
268
|
require_paths:
|
|
268
269
|
- lib
|