chef 17.4.38-universal-mingw32 → 17.7.22-universal-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -0
- data/chef.gemspec +3 -0
- data/lib/chef/application/base.rb +11 -1
- data/lib/chef/chef_fs/file_pattern.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +1 -1
- data/lib/chef/client.rb +1 -2
- data/lib/chef/compliance/input.rb +115 -0
- data/lib/chef/compliance/input_collection.rb +139 -0
- data/lib/chef/compliance/profile.rb +122 -0
- data/lib/chef/compliance/profile_collection.rb +109 -0
- data/lib/chef/compliance/runner.rb +47 -5
- data/lib/chef/compliance/waiver.rb +115 -0
- data/lib/chef/compliance/waiver_collection.rb +143 -0
- data/lib/chef/data_collector/run_end_message.rb +1 -1
- data/lib/chef/dsl/compliance.rb +38 -0
- data/lib/chef/dsl/reader_helpers.rb +51 -0
- data/lib/chef/dsl/reboot_pending.rb +1 -1
- data/lib/chef/dsl/recipe.rb +4 -2
- data/lib/chef/dsl/secret.rb +2 -4
- data/lib/chef/dsl/universal.rb +2 -0
- data/lib/chef/event_dispatch/base.rb +44 -2
- data/lib/chef/exceptions.rb +10 -0
- data/lib/chef/formatters/doc.rb +46 -0
- data/lib/chef/http/basic_client.rb +15 -7
- data/lib/chef/http.rb +7 -3
- data/lib/chef/provider/cron.rb +4 -1
- data/lib/chef/provider/file.rb +2 -0
- data/lib/chef/provider/git.rb +1 -1
- data/lib/chef/provider/ifconfig/debian.rb +1 -1
- data/lib/chef/provider/link.rb +2 -2
- data/lib/chef/provider/registry_key.rb +3 -2
- data/lib/chef/provider/remote_file/http.rb +1 -1
- data/lib/chef/provider/subversion.rb +5 -5
- data/lib/chef/provider/template.rb +1 -1
- data/lib/chef/resource/archive_file.rb +17 -14
- data/lib/chef/resource/chef_client_scheduled_task.rb +45 -2
- data/lib/chef/resource/chocolatey_config.rb +14 -14
- data/lib/chef/resource/chocolatey_feature.rb +1 -1
- data/lib/chef/resource/chocolatey_source.rb +24 -2
- data/lib/chef/resource/directory.rb +1 -1
- data/lib/chef/resource/file/verification/json.rb +50 -0
- data/lib/chef/resource/file/verification/yaml.rb +52 -0
- data/lib/chef/resource/habitat_install.rb +3 -3
- data/lib/chef/resource/inspec_input.rb +127 -0
- data/lib/chef/resource/inspec_waiver.rb +184 -0
- data/lib/chef/resource/inspec_waiver_file_entry.rb +1 -1
- data/lib/chef/resource/kernel_module.rb +27 -2
- data/lib/chef/resource/macos_userdefaults.rb +43 -128
- data/lib/chef/resource/mount.rb +1 -1
- data/lib/chef/resource/openssl_x509_certificate.rb +1 -1
- data/lib/chef/resource/powershell_package_source.rb +234 -70
- data/lib/chef/resource/registry_key.rb +36 -48
- data/lib/chef/resource/remote_file.rb +98 -2
- data/lib/chef/resource/timezone.rb +2 -2
- data/lib/chef/resource/user_ulimit.rb +1 -0
- data/lib/chef/resource/windows_auto_run.rb +1 -1
- data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
- data/lib/chef/resource/windows_printer.rb +1 -1
- data/lib/chef/resource/windows_uac.rb +3 -1
- data/lib/chef/resource/windows_update_settings.rb +3 -3
- data/lib/chef/resource/windows_user_privilege.rb +1 -1
- data/lib/chef/resource.rb +1 -1
- data/lib/chef/resource_reporter.rb +1 -1
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/run_context/cookbook_compiler.rb +112 -28
- data/lib/chef/run_context.rb +31 -1
- data/lib/chef/secret_fetcher/akeyless_vault.rb +57 -0
- data/lib/chef/secret_fetcher/aws_secrets_manager.rb +1 -1
- data/lib/chef/secret_fetcher/azure_key_vault.rb +63 -9
- data/lib/chef/secret_fetcher/base.rb +1 -1
- data/lib/chef/secret_fetcher/hashi_vault.rb +100 -0
- data/lib/chef/secret_fetcher.rb +8 -3
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/version.rb +2 -1
- data/spec/data/archive_file/test_archive.tar.gz +0 -0
- data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
- data/spec/functional/dsl/registry_helper_spec.rb +1 -1
- data/spec/functional/resource/archive_file_spec.rb +87 -0
- data/spec/functional/resource/dsc_script_spec.rb +2 -2
- data/spec/functional/resource/group_spec.rb +5 -1
- data/spec/functional/resource/link_spec.rb +8 -0
- data/spec/functional/resource/macos_userdefaults_spec.rb +119 -0
- data/spec/functional/resource/powershell_package_source_spec.rb +5 -6
- data/spec/functional/resource/registry_spec.rb +81 -81
- data/spec/functional/win32/registry_spec.rb +8 -8
- data/spec/integration/compliance/compliance_spec.rb +60 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/platform_helpers.rb +4 -0
- data/spec/support/ruby_installer.rb +51 -0
- data/spec/unit/compliance/input_spec.rb +104 -0
- data/spec/unit/compliance/profile_spec.rb +120 -0
- data/spec/unit/compliance/waiver_spec.rb +104 -0
- data/spec/unit/data_collector_spec.rb +24 -1
- data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
- data/spec/unit/http/basic_client_spec.rb +30 -0
- data/spec/unit/http_spec.rb +8 -2
- data/spec/unit/mixin/default_paths_spec.rb +1 -1
- data/spec/unit/mixin/securable_spec.rb +3 -3
- data/spec/unit/provider/cron_spec.rb +45 -0
- data/spec/unit/provider/link_spec.rb +13 -7
- data/spec/unit/provider/package/rubygems_spec.rb +5 -5
- data/spec/unit/provider/package/windows_spec.rb +1 -1
- data/spec/unit/provider/registry_key_spec.rb +4 -4
- data/spec/unit/provider/remote_file/http_spec.rb +10 -0
- data/spec/unit/provider/service/windows_spec.rb +5 -5
- data/spec/unit/provider/subversion_spec.rb +4 -4
- data/spec/unit/provider/template_spec.rb +2 -2
- data/spec/unit/provider/windows_env_spec.rb +1 -1
- data/spec/unit/provider/zypper_repository_spec.rb +1 -1
- data/spec/unit/resource/archive_file_spec.rb +414 -3
- data/spec/unit/resource/chef_client_scheduled_task_spec.rb +69 -0
- data/spec/unit/resource/chocolatey_config_spec.rb +1 -1
- data/spec/unit/resource/chocolatey_feature_spec.rb +1 -1
- data/spec/unit/resource/chocolatey_source_spec.rb +1 -1
- data/spec/unit/resource/file/verification/json_spec.rb +72 -0
- data/spec/unit/resource/file/verification/yaml_spec.rb +67 -0
- data/spec/unit/resource/inspec_input_spec.rb +300 -0
- data/spec/unit/resource/inspec_waiver_spec.rb +312 -0
- data/spec/unit/resource/kernel_module_spec.rb +2 -1
- data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
- data/spec/unit/resource/mount_spec.rb +10 -0
- data/spec/unit/resource/powershell_package_source_spec.rb +63 -62
- data/spec/unit/resource/registry_key_spec.rb +10 -10
- data/spec/unit/resource/user_ulimit_spec.rb +14 -1
- data/spec/unit/resource/windows_auto_run_spec.rb +1 -1
- data/spec/unit/resource/windows_feature_powershell_spec.rb +1 -1
- data/spec/unit/resource/windows_firewall_rule_spec.rb +2 -2
- data/spec/unit/resource/windows_task_spec.rb +3 -3
- data/spec/unit/resource_reporter_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +5 -0
- data/spec/unit/secret_fetcher/akeyless_vault_spec.rb +37 -0
- data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +99 -20
- data/spec/unit/secret_fetcher/hashi_vault_spec.rb +80 -0
- data/spec/unit/util/backup_spec.rb +1 -1
- data/spec/unit/win32/registry_spec.rb +3 -3
- data/tasks/rspec.rb +2 -1
- metadata +75 -6
@@ -1,4 +1,5 @@
|
|
1
1
|
# Author:: Tor Magnus Rakvåg (tm@intility.no)
|
2
|
+
# Author:: John McCrae (john.mccrae@progress.com)
|
2
3
|
# Copyright:: 2018, Intility AS
|
3
4
|
# License:: Apache License, Version 2.0
|
4
5
|
#
|
@@ -24,29 +25,110 @@ class Chef
|
|
24
25
|
|
25
26
|
provides :powershell_package_source
|
26
27
|
|
27
|
-
description "Use the **powershell_package_source** resource to register a PowerShell package
|
28
|
+
description "Use the **powershell_package_source** resource to register a PowerShell package source and a Powershell package provider. There are 2 distinct objects we care about here. The first is a Package Source like a PowerShell Repository or a Nuget Source. The second object is a provider that PowerShell uses to get to that source with, like PowerShellGet, Nuget, Chocolatey, etc. "
|
28
29
|
introduced "14.3"
|
30
|
+
examples <<~DOC
|
31
|
+
**Add a new PSRepository that is not trusted and which requires credentials to connect to**:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
powershell_package_source 'PowerShellModules' do
|
35
|
+
source_name "PowerShellModules"
|
36
|
+
source_location "https://pkgs.dev.azure.com/some-org/some-project/_packaging/some_feed/nuget/v2"
|
37
|
+
publish_location "https://pkgs.dev.azure.com/some-org/some-project/_packaging/some_feed/nuget/v2"
|
38
|
+
trusted false
|
39
|
+
user "someuser@somelocation.io"
|
40
|
+
password "my_password"
|
41
|
+
provider_name "PSRepository"
|
42
|
+
action :register
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
**Add a new Package Source that uses Chocolatey as the Package Provider**:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
powershell_package_source 'PowerShellModules' do
|
50
|
+
source_name "PowerShellModules"
|
51
|
+
source_location "https://pkgs.dev.azure.com/some-org/some-project/_packaging/some_feed/nuget/v2"
|
52
|
+
publish_location "https://pkgs.dev.azure.com/some-org/some-project/_packaging/some_feed/nuget/v2"
|
53
|
+
trusted true
|
54
|
+
provider_name "chocolatey"
|
55
|
+
action :register
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
**Add a new PowerShell Script source that is trusted**:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
powershell_package_source 'MyDodgyScript' do
|
63
|
+
source_name "MyDodgyScript"
|
64
|
+
script_source_location "https://pkgs.dev.azure.com/some-org/some-project/_packaging/some_feed/nuget/v2"
|
65
|
+
script_publish_location "https://pkgs.dev.azure.com/some-org/some-project/_packaging/some_feed/nuget/v2"
|
66
|
+
trusted true
|
67
|
+
action :register
|
68
|
+
end
|
69
|
+
```
|
70
|
+
|
71
|
+
**Update my existing PSRepository to make it Trusted after all**:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
powershell_package_source 'MyPSModule' do
|
75
|
+
source_name "MyPSModule"
|
76
|
+
trusted true
|
77
|
+
action :set
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
**Update a Nuget package source with a new name and make it trusted**:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
powershell_package_source 'PowerShellModules -> GoldFishBowl' do
|
85
|
+
source_name "PowerShellModules"
|
86
|
+
new_name "GoldFishBowl"
|
87
|
+
provider_name "Nuget"
|
88
|
+
trusted true
|
89
|
+
action :set
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
**Update a Nuget package source with a new name when the source is secured with a username and password**:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
powershell_package_source 'PowerShellModules -> GoldFishBowl' do
|
97
|
+
source_name "PowerShellModules"
|
98
|
+
new_name "GoldFishBowl"
|
99
|
+
trusted true
|
100
|
+
user "user@domain.io"
|
101
|
+
password "some_secret_password"
|
102
|
+
action :set
|
103
|
+
end
|
104
|
+
```
|
105
|
+
|
106
|
+
**Unregister a package source**:
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
powershell_package_source 'PowerShellModules' do
|
110
|
+
source_name "PowerShellModules"
|
111
|
+
action :unregister
|
112
|
+
end
|
113
|
+
```
|
114
|
+
DOC
|
29
115
|
|
30
116
|
property :source_name, String,
|
31
|
-
description: "
|
117
|
+
description: "A label that names your package source.",
|
32
118
|
name_property: true
|
33
119
|
|
34
|
-
property :
|
35
|
-
|
36
|
-
|
120
|
+
property :new_name, String,
|
121
|
+
introduced: "17.6",
|
122
|
+
description: "Used to change the name of a standard package source."
|
37
123
|
|
38
|
-
property :
|
39
|
-
|
40
|
-
|
124
|
+
property :source_location, String,
|
125
|
+
introduced: "17.6",
|
126
|
+
description: "The URL to the location to retrieve modules from."
|
41
127
|
|
42
|
-
|
43
|
-
equal_to: %w{ Programs msi NuGet msu PowerShellGet psl chocolatey },
|
44
|
-
validation_message: "The following providers are supported: 'Programs', 'msi', 'NuGet', 'msu', 'PowerShellGet', 'psl' or 'chocolatey'",
|
45
|
-
description: "The package management provider for the source.",
|
46
|
-
default: "NuGet"
|
128
|
+
alias :url :source_location
|
47
129
|
|
48
130
|
property :publish_location, String,
|
49
|
-
description: "The URL where modules will be published to
|
131
|
+
description: "The URL where modules will be published to. Only valid if the provider is `PowerShellGet`."
|
50
132
|
|
51
133
|
property :script_source_location, String,
|
52
134
|
description: "The URL where scripts are located for this source. Only valid if the provider is `PowerShellGet`."
|
@@ -54,6 +136,24 @@ class Chef
|
|
54
136
|
property :script_publish_location, String,
|
55
137
|
description: "The location where scripts will be published to for this source. Only valid if the provider is `PowerShellGet`."
|
56
138
|
|
139
|
+
property :trusted, [TrueClass, FalseClass],
|
140
|
+
description: "Whether or not to trust packages from this source. Used when creating a NON-PSRepository Package Source",
|
141
|
+
default: false
|
142
|
+
|
143
|
+
property :user, String,
|
144
|
+
introduced: "17.6",
|
145
|
+
description: "A username that, as part of a credential object, is used to register a repository or other package source with."
|
146
|
+
|
147
|
+
property :password, String,
|
148
|
+
introduced: "17.6",
|
149
|
+
description: "A password that, as part of a credential object, is used to register a repository or other package source with."
|
150
|
+
|
151
|
+
property :provider_name, String,
|
152
|
+
equal_to: %w{ Programs msi NuGet msu PowerShellGet psl chocolatey winget },
|
153
|
+
validation_message: "The following providers are supported: 'Programs', 'msi', 'NuGet', 'msu', 'PowerShellGet', 'psl', 'chocolatey' or 'winget'",
|
154
|
+
description: "The package management provider for the package source. The default is PowerShellGet and this option need only be set otherwise in specific use cases.",
|
155
|
+
default: "NuGet"
|
156
|
+
|
57
157
|
load_current_value do
|
58
158
|
cmd = load_resource_state_script(source_name)
|
59
159
|
repo = powershell_exec!(cmd)
|
@@ -62,7 +162,9 @@ class Chef
|
|
62
162
|
else
|
63
163
|
status = repo.result
|
64
164
|
end
|
65
|
-
|
165
|
+
source_name status["source_name"]
|
166
|
+
new_name status["new_name"]
|
167
|
+
source_location status["source_location"]
|
66
168
|
trusted status["trusted"]
|
67
169
|
provider_name status["provider_name"]
|
68
170
|
publish_location status["publish_location"]
|
@@ -70,97 +172,159 @@ class Chef
|
|
70
172
|
script_publish_location status["script_publish_location"]
|
71
173
|
end
|
72
174
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
175
|
+
# Notes:
|
176
|
+
# There are 2 objects we care about with this code. 1) The Package Provider which can be Nuget, PowerShellGet, Chocolatey, et al. 2) The PackageSource where the files we want access to live. The Package Provider gets us access to the Package Source.
|
177
|
+
# Per the Microsoft docs you can only have one provider for one source. Enter the PSRepository. It is a sub-type of Package Source.
|
178
|
+
# If you register a new PSRepository you get both a PSRepository object AND a Package Source object which are distinct. If you call "Get-PSRepository -Name 'PSGallery'" from powershell, notice that the Packageprovider is Nuget
|
179
|
+
# now go execute "Get-PackageSource -Name 'PSGallery'" and notice that the PackageProvider is PowerShellGet. If you set a new PSRepository without specifying a PackageProvider ("Register-PSRepository -Name 'foo' -source...") the command will create both
|
180
|
+
# a PackageSource and a PSRepository with different providers.
|
181
|
+
|
182
|
+
# Unregistering a PackageSource (unregister-packagesource -name 'foo') where that source is also a PSRepository also causes that object to delete as well. This makes sense as PSRepository is a sub-type of packagesource.
|
183
|
+
# All PSRepositories are PackageSources, and all PackageSources with Provider PowerShellGet are PSRepositories. They are 2 different views of the same object.
|
184
|
+
|
185
|
+
action :register, description: "Registers a PowerShell package source." do
|
186
|
+
package_details = get_package_source_details
|
187
|
+
output = package_details.result
|
188
|
+
if output == "PSRepository" || output == "PackageSource"
|
189
|
+
action_set
|
190
|
+
elsif new_resource.provider_name.downcase.strip == "powershellget"
|
191
|
+
converge_by("register source: #{new_resource.source_name}") do
|
192
|
+
register_cmd = build_ps_repository_command("Register", new_resource)
|
193
|
+
res = powershell_exec(register_cmd)
|
194
|
+
raise "Failed to register #{new_resource.source_name}: #{res.errors}" if res.error?
|
88
195
|
end
|
89
196
|
else
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
197
|
+
converge_by("register source: #{new_resource.source_name}") do
|
198
|
+
register_cmd = build_package_source_command("Register", new_resource)
|
199
|
+
res = powershell_exec(register_cmd)
|
200
|
+
raise "Failed to register #{new_resource.source_name}: #{res.errors}" if res.error?
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
action :set, description: "Updates an existing PSRepository or Package Source" do
|
206
|
+
package_details = get_package_source_details
|
207
|
+
output = package_details.result
|
208
|
+
if output == "PSRepository"
|
209
|
+
converge_if_changed :source_location, :trusted, :publish_location, :script_source_location, :script_publish_location, :source_name do
|
210
|
+
set_cmd = build_ps_repository_command("Set", new_resource)
|
211
|
+
res = powershell_exec(set_cmd)
|
212
|
+
raise "Failed to Update #{new_resource.source_name}: #{res.errors}" if res.error?
|
213
|
+
end
|
214
|
+
elsif output == "PackageSource"
|
215
|
+
converge_if_changed :source_location, :trusted, :new_name, :provider_name do
|
216
|
+
set_cmd = build_package_source_command("Set", new_resource)
|
217
|
+
res = powershell_exec(set_cmd)
|
218
|
+
raise "Failed to Update #{new_resource.source_name}: #{res.errors}" if res.error?
|
102
219
|
end
|
103
220
|
end
|
104
221
|
end
|
105
222
|
|
106
223
|
action :unregister, description: "Unregisters the PowerShell package source." do
|
107
|
-
|
108
|
-
|
224
|
+
package_details = get_package_source_details
|
225
|
+
output = package_details.result
|
226
|
+
if output == "PackageSource" || output == "PSRepository"
|
227
|
+
unregister_cmd = "Unregister-PackageSource -Name '#{new_resource.source_name}'"
|
109
228
|
converge_by("unregister source: #{new_resource.source_name}") do
|
110
|
-
res = powershell_exec(unregister_cmd)
|
229
|
+
res = powershell_exec!(unregister_cmd)
|
111
230
|
raise "Failed to unregister #{new_resource.source_name}: #{res.errors}" if res.error?
|
112
231
|
end
|
232
|
+
else
|
233
|
+
logger.warn("*****************************************")
|
234
|
+
logger.warn("Failed to unregister #{new_resource.source_name}: Package Source does not exist")
|
235
|
+
logger.warn("*****************************************")
|
113
236
|
end
|
114
237
|
end
|
115
238
|
|
116
239
|
action_class do
|
117
|
-
def package_source_exists?
|
118
|
-
cmd = powershell_exec!("(Get-PackageSource -Name '#{new_resource.source_name}' -ErrorAction SilentlyContinue).Name")
|
119
|
-
!cmd.result.empty? && cmd.result.to_s.downcase.strip == new_resource.source_name.downcase
|
120
|
-
end
|
121
240
|
|
122
|
-
def
|
123
|
-
|
241
|
+
def get_package_source_details
|
242
|
+
powershell_exec! <<~EOH
|
243
|
+
$package_details = Get-PackageSource -Name '#{new_resource.source_name}' -ErrorAction SilentlyContinue
|
244
|
+
if ($package_details.ProviderName -match "PowerShellGet"){
|
245
|
+
return "PSRepository"
|
246
|
+
}
|
247
|
+
elseif ($package_details.ProviderName ) {
|
248
|
+
return "PackageSource"
|
249
|
+
}
|
250
|
+
elseif ($null -eq $package_details)
|
251
|
+
{
|
252
|
+
return "Unregistered"
|
253
|
+
}
|
254
|
+
EOH
|
124
255
|
end
|
125
256
|
|
126
257
|
def build_ps_repository_command(cmdlet_type, new_resource)
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
258
|
+
if new_resource.trusted == true
|
259
|
+
install_policy = "Trusted"
|
260
|
+
else
|
261
|
+
install_policy = "Untrusted"
|
262
|
+
end
|
263
|
+
if new_resource.user && new_resource.password
|
264
|
+
cmd = "$user = '#{new_resource.user}';"
|
265
|
+
cmd << "[securestring]$secure_password = Convertto-SecureString -String '#{new_resource.password}' -AsPlainText -Force;"
|
266
|
+
cmd << "$Credentials = New-Object System.Management.Automation.PSCredential -Argumentlist ($user, $secure_password);"
|
267
|
+
cmd << "#{cmdlet_type}-PSRepository -Name '#{new_resource.source_name}'"
|
268
|
+
cmd << " -SourceLocation '#{new_resource.source_location}'" if new_resource.source_location
|
269
|
+
cmd << " -InstallationPolicy '#{install_policy}'"
|
270
|
+
cmd << " -PublishLocation '#{new_resource.publish_location}'" if new_resource.publish_location
|
271
|
+
cmd << " -ScriptSourceLocation '#{new_resource.script_source_location}'" if new_resource.script_source_location
|
272
|
+
cmd << " -ScriptPublishLocation '#{new_resource.script_publish_location}'" if new_resource.script_publish_location
|
273
|
+
cmd << " -Credential $Credentials"
|
274
|
+
cmd << " | Out-Null"
|
275
|
+
else
|
276
|
+
cmd = "#{cmdlet_type}-PSRepository -Name '#{new_resource.source_name}'"
|
277
|
+
cmd << " -SourceLocation '#{new_resource.source_location}'" if new_resource.source_location
|
278
|
+
cmd << " -InstallationPolicy '#{install_policy}'"
|
279
|
+
cmd << " -PublishLocation '#{new_resource.publish_location}'" if new_resource.publish_location
|
280
|
+
cmd << " -ScriptSourceLocation '#{new_resource.script_source_location}'" if new_resource.script_source_location
|
281
|
+
cmd << " -ScriptPublishLocation '#{new_resource.script_publish_location}'" if new_resource.script_publish_location
|
282
|
+
cmd << " | Out-Null"
|
283
|
+
end
|
134
284
|
cmd
|
135
285
|
end
|
136
286
|
|
137
287
|
def build_package_source_command(cmdlet_type, new_resource)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
288
|
+
if new_resource.user && new_resource.password
|
289
|
+
cmd = "$user = '#{new_resource.user}';"
|
290
|
+
cmd << "[securestring]$secure_password = Convertto-SecureString -String '#{new_resource.password}' -AsPlainText -Force;"
|
291
|
+
cmd << "$Credentials = New-Object System.Management.Automation.PSCredential -Argumentlist ($user, $secure_password);"
|
292
|
+
cmd << "#{cmdlet_type}-PackageSource -Name '#{new_resource.source_name}'"
|
293
|
+
cmd << " -Location '#{new_resource.source_location}'" if new_resource.source_location
|
294
|
+
cmd << " -Trusted" if new_resource.trusted
|
295
|
+
cmd << " -ProviderName '#{new_resource.provider_name}'" if new_resource.provider_name
|
296
|
+
cmd << " -Credential $credentials"
|
297
|
+
cmd << " | Out-Null"
|
298
|
+
cmd
|
299
|
+
else
|
300
|
+
cmd = "#{cmdlet_type}-PackageSource -Name '#{new_resource.source_name}'"
|
301
|
+
cmd << " -NewName '#{new_resource.new_name}'" if new_resource.new_name
|
302
|
+
cmd << " -Location '#{new_resource.source_location}'" if new_resource.source_location
|
303
|
+
cmd << " -Trusted" if new_resource.trusted
|
304
|
+
cmd << " -ProviderName '#{new_resource.provider_name}'" if new_resource.provider_name
|
305
|
+
cmd << " | Out-Null"
|
306
|
+
cmd
|
307
|
+
end
|
144
308
|
end
|
145
309
|
end
|
146
310
|
end
|
147
311
|
|
148
312
|
private
|
149
313
|
|
150
|
-
def load_resource_state_script(
|
314
|
+
def load_resource_state_script(source_name)
|
151
315
|
<<-EOH
|
152
316
|
$PSDefaultParameterValues = @{
|
153
317
|
"*:WarningAction" = "SilentlyContinue"
|
154
318
|
}
|
155
|
-
if(Get-PackageSource -Name '#{
|
156
|
-
if ((Get-PackageSource -Name '#{
|
157
|
-
(Get-PSRepository -Name '#{
|
319
|
+
if(Get-PackageSource -Name '#{source_name}' -ErrorAction SilentlyContinue) {
|
320
|
+
if ((Get-PackageSource -Name '#{source_name}').ProviderName -eq 'PowerShellGet') {
|
321
|
+
(Get-PSRepository -Name '#{source_name}') | Select @{n='source_name';e={$_.Name}}, @{n='source_location';e={$_.SourceLocation}},
|
158
322
|
@{n='trusted';e={$_.Trusted}}, @{n='provider_name';e={$_.PackageManagementProvider}}, @{n='publish_location';e={$_.PublishLocation}},
|
159
323
|
@{n='script_source_location';e={$_.ScriptSourceLocation}}, @{n='script_publish_location';e={$_.ScriptPublishLocation}}
|
160
324
|
}
|
161
325
|
else {
|
162
|
-
(Get-PackageSource -Name '#{
|
163
|
-
@{n='provider_name';e={$_.ProviderName}}, @{n='trusted';e={$_.IsTrusted}}
|
326
|
+
(Get-PackageSource -Name '#{source_name}') | Select @{n='source_name';e={$_.Name}}, @{n='new_name';e={$_.Name}}, @{n='source_location';e={$_.Location}},
|
327
|
+
@{n='provider_name';e={$_.ProviderName}}, @{n='trusted';e={$_.IsTrusted}}, @{n='publish_location';e={$_.PublishLocation}}
|
164
328
|
}
|
165
329
|
}
|
166
330
|
EOH
|
@@ -18,6 +18,7 @@
|
|
18
18
|
|
19
19
|
require_relative "../resource"
|
20
20
|
require_relative "../digester"
|
21
|
+
require "chef-utils/dist" unless defined?(ChefUtils::Dist)
|
21
22
|
|
22
23
|
class Chef
|
23
24
|
class Resource
|
@@ -26,7 +27,7 @@ class Chef
|
|
26
27
|
|
27
28
|
provides(:registry_key) { true }
|
28
29
|
|
29
|
-
description "Use the **registry_key** resource to create and delete registry keys in Microsoft Windows."
|
30
|
+
description "Use the **registry_key** resource to create and delete registry keys in Microsoft Windows. Note: 64-bit versions of Microsoft Windows have a 32-bit compatibility layer in the registry that reflects and redirects certain keys (and their values) into specific locations (or logical views) of the registry hive.\n\n#{ChefUtils::Dist::Infra::PRODUCT} can access any reflected or redirected registry key. The machine architecture of the system on which #{ChefUtils::Dist::Infra::PRODUCT} is running is used as the default (non-redirected) location. Access to the SysWow64 location is redirected must be specified. Typically, this is only necessary to ensure compatibility with 32-bit applications that are running on a 64-bit operating system.\n\nFor more information, see: [Registry Reflection](https://docs.microsoft.com/en-us/windows/win32/winprog64/registry-reflection)."
|
30
31
|
examples <<~'DOC'
|
31
32
|
**Create a registry key**
|
32
33
|
|
@@ -66,7 +67,7 @@ class Chef
|
|
66
67
|
end
|
67
68
|
```
|
68
69
|
|
69
|
-
**Set proxy settings to be the same as those used by
|
70
|
+
**Set proxy settings to be the same as those used by #{ChefUtils::Dist::Infra::PRODUCT}**
|
70
71
|
|
71
72
|
```ruby
|
72
73
|
proxy = URI.parse(Chef::Config[:http_proxy])
|
@@ -115,14 +116,42 @@ class Chef
|
|
115
116
|
end
|
116
117
|
```
|
117
118
|
|
118
|
-
Note: Be careful when using the :delete_key action with the recursive attribute. This will delete the registry key, all of its values and all of the names, types, and data associated with them. This cannot be undone by
|
119
|
+
Note: Be careful when using the :delete_key action with the recursive attribute. This will delete the registry key, all of its values and all of the names, types, and data associated with them. This cannot be undone by #{ChefUtils::Dist::Infra::PRODUCT}.
|
119
120
|
DOC
|
120
121
|
|
121
|
-
state_attrs :values
|
122
|
-
|
123
122
|
default_action :create
|
124
123
|
allowed_actions :create, :create_if_missing, :delete, :delete_key
|
125
124
|
|
125
|
+
VALID_VALUE_HASH_KEYS = %i{name type data}.freeze
|
126
|
+
|
127
|
+
property :key, String, name_property: true
|
128
|
+
property :values, [Hash, Array],
|
129
|
+
default: [],
|
130
|
+
coerce: proc { |v|
|
131
|
+
@unscrubbed_values =
|
132
|
+
case v
|
133
|
+
when Hash
|
134
|
+
[ Mash.new(v).symbolize_keys ]
|
135
|
+
when Array
|
136
|
+
v.map { |value| Mash.new(value).symbolize_keys }
|
137
|
+
else
|
138
|
+
raise ArgumentError, "Bad type for RegistryKey resource, use Hash or Array"
|
139
|
+
end
|
140
|
+
scrub_values(@unscrubbed_values)
|
141
|
+
},
|
142
|
+
callbacks: {
|
143
|
+
"Missing name key in RegistryKey values hash" => lambda { |v| v.all? { |value| value.key?(:name) } },
|
144
|
+
"Bad key in RegistryKey values hash. Should be one of: #{VALID_VALUE_HASH_KEYS}" => lambda do |v|
|
145
|
+
v.all? do |value|
|
146
|
+
value.keys.all? { |key| VALID_VALUE_HASH_KEYS.include?(key) }
|
147
|
+
end
|
148
|
+
end,
|
149
|
+
"Type of name should be a string" => lambda { |v| v.all? { |value| value[:name].is_a?(String) } },
|
150
|
+
"Type of type should be a symbol" => lambda { |v| v.all? { |value| value[:type] ? value[:type].is_a?(Symbol) : true } },
|
151
|
+
}
|
152
|
+
property :recursive, [TrueClass, FalseClass], default: false
|
153
|
+
property :architecture, Symbol, default: :machine, equal_to: %i{machine x86_64 i386}
|
154
|
+
|
126
155
|
# Some registry key data types may not be safely reported as json.
|
127
156
|
# Example (CHEF-5323):
|
128
157
|
#
|
@@ -152,51 +181,10 @@ class Chef
|
|
152
181
|
# may want to extend the state_attrs API with the ability to rename POST'd attrs.
|
153
182
|
#
|
154
183
|
# See lib/chef/resource_reporter.rb for more information.
|
155
|
-
|
156
|
-
|
157
|
-
def initialize(name, run_context = nil)
|
158
|
-
super
|
159
|
-
@values, @unscrubbed_values = [], []
|
160
|
-
end
|
161
|
-
|
162
|
-
property :key, String, name_property: true
|
163
|
-
|
164
|
-
VALID_VALUE_HASH_KEYS = %i{name type data}.freeze
|
165
|
-
|
166
|
-
def values(arg = nil)
|
167
|
-
if not arg.nil?
|
168
|
-
if arg.is_a?(Hash)
|
169
|
-
@values = [ Mash.new(arg).symbolize_keys ]
|
170
|
-
elsif arg.is_a?(Array)
|
171
|
-
@values = []
|
172
|
-
arg.each do |value|
|
173
|
-
@values << Mash.new(value).symbolize_keys
|
174
|
-
end
|
175
|
-
else
|
176
|
-
raise ArgumentError, "Bad type for RegistryKey resource, use Hash or Array"
|
177
|
-
end
|
178
|
-
|
179
|
-
@values.each do |v|
|
180
|
-
raise ArgumentError, "Missing name key in RegistryKey values hash" unless v.key?(:name)
|
181
|
-
|
182
|
-
v.each_key do |key|
|
183
|
-
raise ArgumentError, "Bad key #{key} in RegistryKey values hash" unless VALID_VALUE_HASH_KEYS.include?(key)
|
184
|
-
end
|
185
|
-
raise ArgumentError, "Type of name => #{v[:name]} should be string" unless v[:name].is_a?(String)
|
186
|
-
|
187
|
-
if v[:type]
|
188
|
-
raise ArgumentError, "Type of type => #{v[:type]} should be symbol" unless v[:type].is_a?(Symbol)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
@unscrubbed_values = @values
|
192
|
-
elsif instance_variable_defined?(:@values)
|
193
|
-
scrub_values(@values)
|
194
|
-
end
|
184
|
+
def unscrubbed_values
|
185
|
+
@unscrubbed_values ||= []
|
195
186
|
end
|
196
187
|
|
197
|
-
property :recursive, [TrueClass, FalseClass], default: false
|
198
|
-
property :architecture, Symbol, default: :machine, equal_to: %i{machine x86_64 i386}
|
199
|
-
|
200
188
|
private
|
201
189
|
|
202
190
|
def scrub_values(values)
|
@@ -34,6 +34,78 @@ class Chef
|
|
34
34
|
|
35
35
|
description "Use the **remote_file** resource to transfer a file from a remote location using file specificity. This resource is similar to the **file** resource. Note: Fetching files from the `files/` directory in a cookbook should be done with the **cookbook_file** resource."
|
36
36
|
|
37
|
+
examples <<~'DOC'
|
38
|
+
**Download a file without checking the checksum**:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
remote_file '/tmp/remote.txt' do
|
42
|
+
source 'https://example.org/remote.txt'
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
**Download a file with a checksum to validate**:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
remote_file '/tmp/test_file' do
|
50
|
+
source 'http://www.example.com/tempfiles/test_file'
|
51
|
+
mode '0755'
|
52
|
+
checksum '3a7dac00b1' # A SHA256 (or portion thereof) of the file.
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
**Download a file only if it's not already present**:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
remote_file '/tmp/remote.txt' do
|
60
|
+
source 'https://example.org/remote.txt'
|
61
|
+
checksum '3a7dac00b1' # A SHA256 (or portion thereof) of the file.
|
62
|
+
action :create_if_missing
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
**Using HTTP Basic Authentication in Headers**:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
remote_file '/tmp/remote.txt' do
|
70
|
+
source 'https://example.org/remote.txt'
|
71
|
+
headers('Authorization' => "Basic #{Base64.encode64("USERNAME_VALUE:PASSWORD_VALUE").delete("\n")}")
|
72
|
+
checksum '3a7dac00b1' # A SHA256 (or portion thereof) of the file.
|
73
|
+
action :create_if_missing
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
**Downloading a file to the Chef file cache dir for execution**:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
remote_file '#{Chef::Config['file_cache_path']}/install.sh' do
|
81
|
+
source 'https://example.org/install.sh'
|
82
|
+
action :create_if_missing
|
83
|
+
end
|
84
|
+
|
85
|
+
execute '#{Chef::Config['file_cache_path']}/install.sh'
|
86
|
+
```
|
87
|
+
|
88
|
+
**Specify advanced HTTP connection options including Net::HTTP (nethttp) options:**
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
remote_file '/tmp/remote.txt' do
|
92
|
+
source 'https://example.org/remote.txt'
|
93
|
+
http_options({
|
94
|
+
http_retry_delay: 0,
|
95
|
+
http_retry_count: 0,
|
96
|
+
keepalives: false,
|
97
|
+
nethttp: {
|
98
|
+
continue_timeout: 5,
|
99
|
+
max_retries: 5,
|
100
|
+
read_timeout: 5,
|
101
|
+
write_timeout: 5,
|
102
|
+
ssl_timeout: 5,
|
103
|
+
},
|
104
|
+
})
|
105
|
+
end
|
106
|
+
```
|
107
|
+
DOC
|
108
|
+
|
37
109
|
def initialize(name, run_context = nil)
|
38
110
|
super
|
39
111
|
@source = []
|
@@ -96,9 +168,29 @@ class Chef
|
|
96
168
|
description: "Whether #{ChefUtils::Dist::Infra::PRODUCT} uses active or passive FTP. Set to `true` to use active FTP."
|
97
169
|
|
98
170
|
property :headers, Hash, default: {},
|
99
|
-
description:
|
171
|
+
description: <<~'DOCS'
|
172
|
+
A Hash of custom headers. For example:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
headers({ "Cookie" => "user=some_user; pass=p@ssw0rd!" })
|
176
|
+
```
|
100
177
|
|
101
|
-
|
178
|
+
or:
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
headers({ "Referer" => "#{header}" })
|
182
|
+
```
|
183
|
+
|
184
|
+
or:
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
headers( "Authorization"=>"Basic #{ Base64.encode64("#{username}:#{password}").gsub("\n", "") }" )
|
188
|
+
```
|
189
|
+
DOCS
|
190
|
+
|
191
|
+
property :show_progress, [ TrueClass, FalseClass ],
|
192
|
+
description: "Displays the progress of the file download.",
|
193
|
+
default: false
|
102
194
|
|
103
195
|
property :ssl_verify_mode, Symbol, equal_to: %i{verify_none verify_peer},
|
104
196
|
introduced: "16.2",
|
@@ -118,6 +210,10 @@ class Chef
|
|
118
210
|
|
119
211
|
property :authentication, Symbol, equal_to: %i{remote local}, default: :remote
|
120
212
|
|
213
|
+
property :http_options, Hash, default: {},
|
214
|
+
introduced: "17.5",
|
215
|
+
description: "A Hash of custom HTTP options. For example: `http_options({ http_retry_count: 0, http_retry_delay: 2 })`"
|
216
|
+
|
121
217
|
def after_created
|
122
218
|
validate_identity_platform(remote_user, remote_password, remote_domain)
|
123
219
|
identity = qualify_user(remote_user, remote_password, remote_domain)
|
@@ -38,7 +38,7 @@ class Chef
|
|
38
38
|
**Set the timezone to America/Los_Angeles with a friendly resource name on Linux/macOS**
|
39
39
|
|
40
40
|
```ruby
|
41
|
-
timezone
|
41
|
+
timezone "Set the host's timezone to America/Los_Angeles" do
|
42
42
|
timezone 'America/Los_Angeles'
|
43
43
|
end
|
44
44
|
```
|
@@ -46,7 +46,7 @@ class Chef
|
|
46
46
|
**Set the timezone to PST with a friendly resource name on Windows**
|
47
47
|
|
48
48
|
```ruby
|
49
|
-
timezone
|
49
|
+
timezone "Set the host's timezone to PST" do
|
50
50
|
timezone 'Pacific Standard time'
|
51
51
|
end
|
52
52
|
```
|