chef 17.5.22 → 17.7.29
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 +1 -0
- data/lib/chef/chef_fs/file_pattern.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +1 -1
- data/lib/chef/data_collector/run_end_message.rb +1 -1
- data/lib/chef/dsl/reboot_pending.rb +1 -1
- data/lib/chef/exceptions.rb +10 -0
- data/lib/chef/provider/cron.rb +4 -1
- data/lib/chef/provider/git.rb +1 -1
- data/lib/chef/provider/ifconfig/debian.rb +1 -1
- data/lib/chef/provider/package/habitat.rb +1 -1
- data/lib/chef/provider/subversion.rb +5 -5
- data/lib/chef/resource/archive_file.rb +1 -1
- data/lib/chef/resource/chef_client_trusted_certificate.rb +1 -0
- data/lib/chef/resource/chocolatey_config.rb +1 -1
- 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/habitat_install.rb +5 -5
- data/lib/chef/resource/inspec_input.rb +7 -8
- data/lib/chef/resource/inspec_waiver.rb +7 -8
- 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 +45 -133
- data/lib/chef/resource/openssl_x509_certificate.rb +1 -1
- data/lib/chef/resource/powershell_package_source.rb +234 -70
- 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_update_settings.rb +3 -3
- data/lib/chef/resource.rb +1 -1
- data/lib/chef/resource_reporter.rb +1 -1
- data/lib/chef/secret_fetcher/azure_key_vault.rb +62 -8
- data/lib/chef/secret_fetcher.rb +0 -1
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/version.rb +2 -1
- data/spec/functional/dsl/reboot_pending_spec.rb +3 -3
- data/spec/functional/dsl/registry_helper_spec.rb +1 -1
- data/spec/functional/resource/dsc_script_spec.rb +2 -2
- 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/unit/data_collector_spec.rb +24 -1
- data/spec/unit/dsl/reboot_pending_spec.rb +1 -1
- 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/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/service/windows_spec.rb +5 -5
- data/spec/unit/provider/subversion_spec.rb +4 -4
- data/spec/unit/provider/windows_env_spec.rb +1 -1
- data/spec/unit/provider/zypper_repository_spec.rb +1 -1
- data/spec/unit/resource/chef_client_trusted_certificate_spec.rb +14 -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/kernel_module_spec.rb +2 -1
- data/spec/unit/resource/macos_user_defaults_spec.rb +36 -96
- 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/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/azure_key_vault_spec.rb +99 -20
- data/spec/unit/util/backup_spec.rb +1 -1
- data/spec/unit/win32/registry_spec.rb +3 -3
- metadata +21 -6
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
require_relative "../resource"
|
19
19
|
require "chef-utils/dist" unless defined?(ChefUtils::Dist)
|
20
|
+
require "corefoundation" if RUBY_PLATFORM.match?(/darwin/)
|
20
21
|
autoload :Plist, "plist"
|
21
22
|
|
22
23
|
class Chef
|
@@ -78,173 +79,84 @@ class Chef
|
|
78
79
|
required: true
|
79
80
|
|
80
81
|
property :host, [String, Symbol],
|
81
|
-
description: "Set either :current or a hostname to set the user default at the host level.",
|
82
|
+
description: "Set either :current, :all or a hostname to set the user default at the host level.",
|
82
83
|
desired_state: false,
|
83
|
-
introduced: "16.3"
|
84
|
+
introduced: "16.3",
|
85
|
+
coerce: proc { |value| to_cf_host(value) }
|
84
86
|
|
85
87
|
property :value, [Integer, Float, String, TrueClass, FalseClass, Hash, Array],
|
86
88
|
description: "The value of the key. Note: With the `type` property set to `bool`, `String` forms of Boolean true/false values that Apple accepts in the defaults command will be coerced: 0/1, 'TRUE'/'FALSE,' 'true'/false', 'YES'/'NO', or 'yes'/'no'.",
|
87
|
-
required: [:write]
|
88
|
-
coerce: proc { |v| v.is_a?(Hash) ? v.transform_keys(&:to_s) : v } # make sure keys are all strings for comparison
|
89
|
+
required: [:write]
|
89
90
|
|
90
91
|
property :type, String,
|
91
92
|
description: "The value type of the preference key.",
|
92
93
|
equal_to: %w{bool string int float array dict},
|
93
|
-
desired_state: false
|
94
|
+
desired_state: false,
|
95
|
+
deprecated: true
|
94
96
|
|
95
|
-
property :user, String,
|
96
|
-
description: "The system user that the default will be applied to.",
|
97
|
-
desired_state: false
|
97
|
+
property :user, [String, Symbol],
|
98
|
+
description: "The system user that the default will be applied to. Set :current for current user, :all for all users or pass a valid username",
|
99
|
+
desired_state: false,
|
100
|
+
coerce: proc { |value| to_cf_user(value) }
|
98
101
|
|
99
102
|
property :sudo, [TrueClass, FalseClass],
|
100
103
|
description: "Set to true if the setting you wish to modify requires privileged access. This requires passwordless sudo for the `/usr/bin/defaults` command to be setup for the user running #{ChefUtils::Dist::Infra::PRODUCT}.",
|
101
104
|
default: false,
|
102
|
-
desired_state: false
|
105
|
+
desired_state: false,
|
106
|
+
deprecated: true
|
103
107
|
|
104
108
|
load_current_value do |new_resource|
|
105
|
-
Chef::Log.debug "#load_current_value:
|
106
|
-
state = shell_out(defaults_export_cmd(new_resource), user: new_resource.user)
|
109
|
+
Chef::Log.debug "#load_current_value: attempting to read \"#{new_resource.domain}\" value from preferences to determine state"
|
107
110
|
|
108
|
-
|
109
|
-
|
110
|
-
current_value_does_not_exist!
|
111
|
-
end
|
111
|
+
pref = get_preference(new_resource)
|
112
|
+
current_value_does_not_exist! if pref.nil?
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
# handle the situation where the key doesn't exist in the domain
|
116
|
-
if plist_data.key?(new_resource.key)
|
117
|
-
key new_resource.key
|
118
|
-
else
|
119
|
-
current_value_does_not_exist!
|
120
|
-
end
|
121
|
-
|
122
|
-
value plist_data[new_resource.key]
|
123
|
-
end
|
124
|
-
|
125
|
-
#
|
126
|
-
# The defaults command to export a domain
|
127
|
-
#
|
128
|
-
# @return [Array] defaults command
|
129
|
-
#
|
130
|
-
def defaults_export_cmd(resource)
|
131
|
-
state_cmd = ["/usr/bin/defaults"]
|
132
|
-
|
133
|
-
if resource.host == "current"
|
134
|
-
state_cmd.concat(["-currentHost"])
|
135
|
-
elsif resource.host # they specified a non-nil value, which is a hostname
|
136
|
-
state_cmd.concat(["-host", resource.host])
|
137
|
-
end
|
138
|
-
|
139
|
-
state_cmd.concat(["export", resource.domain, "-"])
|
140
|
-
state_cmd
|
114
|
+
key new_resource.key
|
115
|
+
value pref
|
141
116
|
end
|
142
117
|
|
143
118
|
action :write, description: "Write the value to the specified domain/key." do
|
144
119
|
converge_if_changed do
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
shell_out!(cmd, user: new_resource.user)
|
120
|
+
Chef::Log.debug("Updating defaults value for #{new_resource.key} in #{new_resource.domain}")
|
121
|
+
CF::Preferences.set!(new_resource.key, new_resource.value, new_resource.domain, new_resource.user, new_resource.host)
|
149
122
|
end
|
150
123
|
end
|
151
124
|
|
152
125
|
action :delete, description: "Delete a key from a domain." do
|
153
126
|
# if it's not there there's nothing to remove
|
154
|
-
return
|
127
|
+
return if current_resource.nil?
|
155
128
|
|
156
129
|
converge_by("delete domain:#{new_resource.domain} key:#{new_resource.key}") do
|
157
|
-
|
158
|
-
|
159
|
-
Chef::Log.debug("Removing defaults key by shelling out: #{cmd.join(" ")}")
|
160
|
-
|
161
|
-
shell_out!(cmd, user: new_resource.user)
|
130
|
+
Chef::Log.debug("Removing defaults key: #{new_resource.key}")
|
131
|
+
CF::Preferences.set!(new_resource.key, nil, new_resource.domain, new_resource.user, new_resource.host)
|
162
132
|
end
|
163
133
|
end
|
164
134
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
#
|
169
|
-
# @return [Array] Array representation of defaults command to run
|
170
|
-
#
|
171
|
-
def defaults_modify_cmd
|
172
|
-
cmd = ["/usr/bin/defaults"]
|
173
|
-
|
174
|
-
if new_resource.host == :current
|
175
|
-
cmd.concat(["-currentHost"])
|
176
|
-
elsif new_resource.host # they specified a non-nil value, which is a hostname
|
177
|
-
cmd.concat(["-host", new_resource.host])
|
178
|
-
end
|
179
|
-
|
180
|
-
cmd.concat([action.to_s, new_resource.domain, new_resource.key])
|
181
|
-
cmd.concat(processed_value) if action == :write
|
182
|
-
cmd.prepend("sudo") if new_resource.sudo
|
183
|
-
cmd
|
184
|
-
end
|
185
|
-
|
186
|
-
#
|
187
|
-
# convert the provided value into the format defaults expects
|
188
|
-
#
|
189
|
-
# @return [array] array of values starting with the type if applicable
|
190
|
-
#
|
191
|
-
def processed_value
|
192
|
-
type = new_resource.type || value_type(new_resource.value)
|
193
|
-
|
194
|
-
# when dict this creates an array of values ["Key1", "Value1", "Key2", "Value2" ...]
|
195
|
-
cmd_values = ["-#{type}"]
|
196
|
-
|
197
|
-
case type
|
198
|
-
when "dict"
|
199
|
-
cmd_values.concat(new_resource.value.flatten)
|
200
|
-
when "array"
|
201
|
-
cmd_values.concat(new_resource.value)
|
202
|
-
when "bool"
|
203
|
-
cmd_values.concat(bool_to_defaults_bool(new_resource.value))
|
204
|
-
else
|
205
|
-
cmd_values.concat([new_resource.value])
|
206
|
-
end
|
207
|
-
|
208
|
-
cmd_values
|
209
|
-
end
|
135
|
+
def get_preference(new_resource)
|
136
|
+
CF::Preferences.get(new_resource.key, new_resource.domain, new_resource.user, new_resource.host)
|
137
|
+
end
|
210
138
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
return ["FALSE"] if [false, "FALSE", "0", "false", "NO", "no"].include?(input)
|
221
|
-
|
222
|
-
# make sure it's very clear bad input was given
|
223
|
-
raise ArgumentError, "#{input} cannot be converted to a boolean value for use with Apple's defaults command. Acceptable values are: 'TRUE', 'YES', 'true, 'yes', '0', true, 'FALSE', 'false', 'NO', 'no', '1', or false."
|
139
|
+
# Return valid hostname based on the input from host property
|
140
|
+
def to_cf_host(value)
|
141
|
+
case value
|
142
|
+
when :all
|
143
|
+
CF::Preferences::ALL_HOSTS
|
144
|
+
when :current
|
145
|
+
CF::Preferences::CURRENT_HOST
|
146
|
+
else
|
147
|
+
value
|
224
148
|
end
|
149
|
+
end
|
225
150
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
when true, false
|
236
|
-
"bool"
|
237
|
-
when Integer
|
238
|
-
"int"
|
239
|
-
when Float
|
240
|
-
"float"
|
241
|
-
when Hash
|
242
|
-
"dict"
|
243
|
-
when Array
|
244
|
-
"array"
|
245
|
-
when String
|
246
|
-
"string"
|
247
|
-
end
|
151
|
+
# Return valid username based on the input from user property
|
152
|
+
def to_cf_user(value)
|
153
|
+
case value
|
154
|
+
when :all
|
155
|
+
CF::Preferences::ALL_USERS
|
156
|
+
when :current
|
157
|
+
CF::Preferences::CURRENT_USER
|
158
|
+
else
|
159
|
+
value
|
248
160
|
end
|
249
161
|
end
|
250
162
|
end
|
@@ -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
|
@@ -38,7 +38,7 @@ class Chef
|
|
38
38
|
|
39
39
|
property :full_users, Array,
|
40
40
|
description: "Determines which users should have full access to the share.",
|
41
|
-
default: [
|
41
|
+
default: ["BUILTIN\\administrators"]
|
42
42
|
|
43
43
|
property :change_users, Array,
|
44
44
|
description: "Determines which users should have change access to the share.",
|
@@ -50,7 +50,7 @@ class Chef
|
|
50
50
|
|
51
51
|
property :root, String,
|
52
52
|
description: "The root from which to create the DFS tree. Defaults to C:\\DFSRoots.",
|
53
|
-
default:
|
53
|
+
default: "C:\\DFSRoots"
|
54
54
|
|
55
55
|
action :create, description: "Creates the dfs namespace on the server." do
|
56
56
|
directory file_path do
|