chef 17.1.35-universal-mingw32 → 17.4.38-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -4
  3. data/chef.gemspec +1 -0
  4. data/lib/chef/action_collection.rb +6 -26
  5. data/lib/chef/application/base.rb +15 -0
  6. data/lib/chef/application.rb +4 -2
  7. data/lib/chef/client.rb +7 -1
  8. data/lib/chef/compliance/default_attributes.rb +5 -3
  9. data/lib/chef/compliance/reporter/automate.rb +1 -1
  10. data/lib/chef/compliance/runner.rb +16 -2
  11. data/lib/chef/cookbook_version.rb +26 -4
  12. data/lib/chef/data_collector/run_end_message.rb +1 -1
  13. data/lib/chef/data_collector.rb +0 -1
  14. data/lib/chef/deprecated.rb +14 -4
  15. data/lib/chef/dsl/render_helpers.rb +44 -0
  16. data/lib/chef/dsl/secret.rb +64 -0
  17. data/lib/chef/dsl/toml.rb +116 -0
  18. data/lib/chef/dsl/universal.rb +5 -0
  19. data/lib/chef/dsl.rb +1 -0
  20. data/lib/chef/event_dispatch/base.rb +2 -1
  21. data/lib/chef/exceptions.rb +23 -0
  22. data/lib/chef/formatters/doc.rb +14 -13
  23. data/lib/chef/formatters/error_mapper.rb +2 -2
  24. data/lib/chef/formatters/minimal.rb +6 -5
  25. data/lib/chef/handler/slow_report.rb +66 -0
  26. data/lib/chef/handler.rb +46 -8
  27. data/lib/chef/http.rb +5 -5
  28. data/lib/chef/json_compat.rb +1 -1
  29. data/lib/chef/node.rb +20 -19
  30. data/lib/chef/policy_builder/policyfile.rb +88 -45
  31. data/lib/chef/provider/execute.rb +1 -1
  32. data/lib/chef/provider/file.rb +2 -2
  33. data/lib/chef/provider/group/dscl.rb +1 -1
  34. data/lib/chef/provider/launchd.rb +6 -6
  35. data/lib/chef/provider/lwrp_base.rb +1 -1
  36. data/lib/chef/provider/package/habitat.rb +168 -0
  37. data/lib/chef/provider/package/powershell.rb +5 -0
  38. data/lib/chef/provider/subversion.rb +4 -4
  39. data/lib/chef/provider/support/yum_repo.erb +1 -1
  40. data/lib/chef/provider/support/zypper_repo.erb +4 -2
  41. data/lib/chef/provider/systemd_unit.rb +17 -16
  42. data/lib/chef/provider/user/mac.rb +3 -3
  43. data/lib/chef/provider/yum_repository.rb +27 -43
  44. data/lib/chef/provider/zypper_repository.rb +30 -34
  45. data/lib/chef/provider.rb +26 -1
  46. data/lib/chef/provider_resolver.rb +8 -2
  47. data/lib/chef/providers.rb +1 -0
  48. data/lib/chef/resource/alternatives.rb +5 -5
  49. data/lib/chef/resource/apt_preference.rb +2 -2
  50. data/lib/chef/resource/apt_repository.rb +2 -2
  51. data/lib/chef/resource/apt_update.rb +4 -4
  52. data/lib/chef/resource/build_essential.rb +1 -1
  53. data/lib/chef/resource/chef_client_config.rb +10 -5
  54. data/lib/chef/resource/chef_client_cron.rb +3 -3
  55. data/lib/chef/resource/chef_client_launchd.rb +3 -3
  56. data/lib/chef/resource/chef_client_scheduled_task.rb +15 -15
  57. data/lib/chef/resource/chef_client_systemd_timer.rb +3 -3
  58. data/lib/chef/resource/chef_client_trusted_certificate.rb +2 -2
  59. data/lib/chef/resource/chef_handler.rb +2 -2
  60. data/lib/chef/resource/chef_sleep.rb +1 -1
  61. data/lib/chef/resource/chef_vault_secret.rb +2 -2
  62. data/lib/chef/resource/chocolatey_feature.rb +2 -2
  63. data/lib/chef/resource/chocolatey_source.rb +1 -1
  64. data/lib/chef/resource/cron/cron_d.rb +4 -6
  65. data/lib/chef/resource/cron_access.rb +1 -1
  66. data/lib/chef/resource/dmg_package.rb +1 -1
  67. data/lib/chef/resource/dsc_resource.rb +1 -1
  68. data/lib/chef/resource/execute.rb +5 -5
  69. data/lib/chef/resource/gem_package.rb +2 -1
  70. data/lib/chef/resource/group.rb +4 -4
  71. data/lib/chef/resource/habitat/_habitat_shared.rb +28 -0
  72. data/lib/chef/resource/habitat/habitat_package.rb +129 -0
  73. data/lib/chef/resource/habitat/habitat_sup.rb +329 -0
  74. data/lib/chef/resource/habitat/habitat_sup_systemd.rb +67 -0
  75. data/lib/chef/resource/habitat/habitat_sup_windows.rb +90 -0
  76. data/lib/chef/resource/habitat_config.rb +107 -0
  77. data/lib/chef/resource/habitat_install.rb +247 -0
  78. data/lib/chef/resource/habitat_service.rb +451 -0
  79. data/lib/chef/resource/habitat_user_toml.rb +92 -0
  80. data/lib/chef/resource/homebrew_cask.rb +18 -7
  81. data/lib/chef/resource/homebrew_package.rb +1 -1
  82. data/lib/chef/resource/homebrew_tap.rb +4 -3
  83. data/lib/chef/resource/homebrew_update.rb +2 -2
  84. data/lib/chef/resource/hostname.rb +49 -7
  85. data/lib/chef/resource/inspec_waiver_file_entry.rb +8 -7
  86. data/lib/chef/resource/kernel_module.rb +6 -6
  87. data/lib/chef/resource/launchd.rb +3 -3
  88. data/lib/chef/resource/locale.rb +1 -1
  89. data/lib/chef/resource/lwrp_base.rb +1 -1
  90. data/lib/chef/resource/macos_userdefaults.rb +2 -2
  91. data/lib/chef/resource/ohai_hint.rb +2 -6
  92. data/lib/chef/resource/openbsd_package.rb +17 -0
  93. data/lib/chef/resource/openssl_dhparam.rb +1 -2
  94. data/lib/chef/resource/openssl_ec_private_key.rb +1 -3
  95. data/lib/chef/resource/openssl_ec_public_key.rb +1 -3
  96. data/lib/chef/resource/openssl_rsa_private_key.rb +1 -3
  97. data/lib/chef/resource/openssl_rsa_public_key.rb +1 -3
  98. data/lib/chef/resource/openssl_x509_certificate.rb +1 -4
  99. data/lib/chef/resource/openssl_x509_crl.rb +1 -3
  100. data/lib/chef/resource/openssl_x509_request.rb +1 -3
  101. data/lib/chef/resource/osx_profile.rb +3 -3
  102. data/lib/chef/resource/plist.rb +1 -1
  103. data/lib/chef/resource/powershell_package_source.rb +2 -4
  104. data/lib/chef/resource/reboot.rb +38 -9
  105. data/lib/chef/resource/remote_directory.rb +2 -2
  106. data/lib/chef/resource/remote_file.rb +1 -1
  107. data/lib/chef/resource/rhsm_errata.rb +0 -2
  108. data/lib/chef/resource/rhsm_errata_level.rb +1 -5
  109. data/lib/chef/resource/rhsm_repo.rb +15 -0
  110. data/lib/chef/resource/rhsm_subscription.rb +5 -5
  111. data/lib/chef/resource/ruby_block.rb +100 -0
  112. data/lib/chef/resource/scm/subversion.rb +1 -1
  113. data/lib/chef/resource/ssh_known_hosts_entry.rb +4 -7
  114. data/lib/chef/resource/sudo.rb +2 -6
  115. data/lib/chef/resource/support/HabService.dll.config.erb +19 -0
  116. data/lib/chef/resource/support/client.erb +8 -1
  117. data/lib/chef/resource/support/sup.toml.erb +179 -0
  118. data/lib/chef/resource/swap_file.rb +2 -6
  119. data/lib/chef/resource/sysctl.rb +2 -2
  120. data/lib/chef/resource/systemd_unit.rb +3 -3
  121. data/lib/chef/resource/timezone.rb +1 -1
  122. data/lib/chef/resource/user_ulimit.rb +2 -2
  123. data/lib/chef/resource/windows_ad_join.rb +2 -2
  124. data/lib/chef/resource/windows_audit_policy.rb +2 -2
  125. data/lib/chef/resource/windows_auto_run.rb +2 -2
  126. data/lib/chef/resource/windows_certificate.rb +1 -1
  127. data/lib/chef/resource/windows_defender.rb +163 -0
  128. data/lib/chef/resource/windows_defender_exclusion.rb +125 -0
  129. data/lib/chef/resource/windows_dfs_folder.rb +2 -2
  130. data/lib/chef/resource/windows_dfs_namespace.rb +2 -2
  131. data/lib/chef/resource/windows_dns_record.rb +2 -2
  132. data/lib/chef/resource/windows_dns_zone.rb +2 -2
  133. data/lib/chef/resource/windows_feature.rb +3 -3
  134. data/lib/chef/resource/windows_feature_dism.rb +3 -5
  135. data/lib/chef/resource/windows_feature_powershell.rb +3 -3
  136. data/lib/chef/resource/windows_firewall_profile.rb +2 -2
  137. data/lib/chef/resource/windows_firewall_rule.rb +20 -6
  138. data/lib/chef/resource/windows_font.rb +1 -1
  139. data/lib/chef/resource/windows_pagefile.rb +103 -64
  140. data/lib/chef/resource/windows_path.rb +2 -2
  141. data/lib/chef/resource/windows_printer.rb +80 -61
  142. data/lib/chef/resource/windows_printer_port.rb +48 -65
  143. data/lib/chef/resource/windows_security_policy.rb +2 -2
  144. data/lib/chef/resource/windows_share.rb +2 -2
  145. data/lib/chef/resource/windows_shortcut.rb +1 -1
  146. data/lib/chef/resource/windows_task.rb +1 -1
  147. data/lib/chef/resource/windows_uac.rb +3 -5
  148. data/lib/chef/resource/windows_update_settings.rb +259 -0
  149. data/lib/chef/resource/windows_user_privilege.rb +2 -2
  150. data/lib/chef/resource/windows_workgroup.rb +2 -2
  151. data/lib/chef/resource/yum_package.rb +11 -15
  152. data/lib/chef/resource/zypper_package.rb +4 -4
  153. data/lib/chef/resource/zypper_repository.rb +28 -8
  154. data/lib/chef/resource.rb +13 -17
  155. data/lib/chef/resource_inspector.rb +6 -2
  156. data/lib/chef/resource_reporter.rb +0 -1
  157. data/lib/chef/resources.rb +12 -1
  158. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +65 -0
  159. data/lib/chef/secret_fetcher/azure_key_vault.rb +78 -0
  160. data/lib/chef/secret_fetcher/base.rb +76 -0
  161. data/lib/chef/secret_fetcher/example.rb +46 -0
  162. data/lib/chef/secret_fetcher.rb +55 -0
  163. data/lib/chef/version.rb +1 -1
  164. data/spec/functional/mixin/from_file_spec.rb +1 -1
  165. data/spec/functional/resource/windows_hostname_spec.rb +91 -0
  166. data/spec/functional/resource/windows_pagefile_spec.rb +98 -0
  167. data/spec/integration/compliance/compliance_spec.rb +1 -0
  168. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -1
  169. data/spec/integration/recipes/resource_action_spec.rb +6 -6
  170. data/spec/support/shared/unit/provider/file.rb +2 -8
  171. data/spec/unit/compliance/runner_spec.rb +46 -2
  172. data/spec/unit/cookbook_version_spec.rb +52 -0
  173. data/spec/unit/data_collector_spec.rb +47 -1
  174. data/spec/unit/dsl/render_helpers_spec.rb +102 -0
  175. data/spec/unit/dsl/secret_spec.rb +71 -0
  176. data/spec/unit/formatters/doc_spec.rb +1 -1
  177. data/spec/unit/handler_spec.rb +8 -2
  178. data/spec/unit/policy_builder/dynamic_spec.rb +0 -5
  179. data/spec/unit/policy_builder/policyfile_spec.rb +144 -56
  180. data/spec/unit/provider/apt_update_spec.rb +3 -1
  181. data/spec/unit/provider/mount/aix_spec.rb +1 -1
  182. data/spec/unit/provider/package/powershell_spec.rb +74 -12
  183. data/spec/unit/provider/zypper_repository_spec.rb +3 -10
  184. data/spec/unit/provider_spec.rb +23 -0
  185. data/spec/unit/resource/homebrew_cask_spec.rb +29 -11
  186. data/spec/unit/resource/rhsm_subscription_spec.rb +50 -3
  187. data/spec/unit/resource/systemd_unit_spec.rb +1 -1
  188. data/spec/unit/resource/windows_defender_exclusion_spec.rb +62 -0
  189. data/spec/unit/resource/windows_defender_spec.rb +71 -0
  190. data/spec/unit/resource/windows_firewall_rule_spec.rb +12 -7
  191. data/spec/unit/resource/windows_pagefile_spec.rb +4 -9
  192. data/spec/unit/resource/windows_update_settings_spec.rb +64 -0
  193. data/spec/unit/resource/zypper_repository_spec.rb +1 -1
  194. data/spec/unit/resource_spec.rb +19 -8
  195. data/spec/unit/secret_fetcher/aws_secrets_manager_spec.rb +70 -0
  196. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +70 -0
  197. data/spec/unit/secret_fetcher_spec.rb +82 -0
  198. metadata +55 -7
@@ -0,0 +1,451 @@
1
+ # Copyright:: Chef Software, Inc.
2
+ # License:: Apache License, Version 2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require_relative "../resource"
18
+ require "chef-utils/dist" unless defined?(ChefUtils::Dist)
19
+
20
+ class Chef
21
+ class Resource
22
+ class HabitatService < Chef::Resource
23
+ unified_mode true
24
+ provides :habitat_service
25
+
26
+ description "Use the **habitat_service** resource to manage Chef Habitat services. This requires that `core/hab-sup` be running as a service. See the `habitat_sup` resource documentation for more information. Note: Applications may run as a specific user. Often with Habitat, the default is `hab`, or `root`. If the application requires another user, then it should be created with Chef's `user` resource."
27
+ introduced "17.3"
28
+ examples <<~DOC
29
+ **Install and load nginx**
30
+
31
+ ```ruby
32
+ habitat_package 'core/nginx'
33
+ habitat_service 'core/nginx'
34
+
35
+ habitat_service 'core/nginx unload' do
36
+ service_name 'core/nginx'
37
+ action :unload
38
+ end
39
+ ```
40
+
41
+ **Pass the `strategy` and `topology` options to hab service commands**
42
+
43
+ ```ruby
44
+ habitat_service 'core/redis' do
45
+ strategy 'rolling'
46
+ topology 'standalone'
47
+ end
48
+ ```
49
+
50
+ **Using update_condition**
51
+
52
+ ```ruby
53
+ habitat_service 'core/redis' do
54
+ strategy 'rolling'
55
+ update_condition 'track-channel'
56
+ topology 'standalone'
57
+ end
58
+ ```
59
+
60
+ **If the service has it's own user specified that is not the `hab` user, don't create the `hab` user on install, and instead create the application user with Chef's `user` resource**
61
+
62
+ ```ruby
63
+ habitat_install 'install habitat' do
64
+ create_user false
65
+ end
66
+
67
+ user 'acme-apps' do
68
+ system true
69
+ end
70
+
71
+ habitat_service 'acme/apps'
72
+ ```
73
+ DOC
74
+
75
+ property :service_name, String, name_property: true,
76
+ description: "The name of the service, must be in the form of `origin/name`"
77
+
78
+ property :loaded, [true, false], default: false, skip_docs: true,
79
+ description: "state property indicating whether the service is loaded in the supervisor"
80
+
81
+ property :running, [true, false], default: false, skip_docs: true,
82
+ description: "state property indicating whether the service is running in the supervisor"
83
+
84
+ # hab svc options which get included based on the action of the resource
85
+ property :strategy, [Symbol, String], equal_to: [:none, "none", :'at-once', "at-once", :rolling, "rolling"], default: :none, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s },
86
+ description: "Passes `--strategy` with the specified update strategy to the hab command. Defaults to `:none`. Other options are `:'at-once'` and `:rolling`"
87
+
88
+ property :topology, [Symbol, String], equal_to: [:standalone, "standalone", :leader, "leader"], default: :standalone, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s },
89
+ description: "Passes `--topology` with the specified service topology to the hab command"
90
+
91
+ property :bldr_url, String, default: "https://bldr.habitat.sh/",
92
+ description: "Passes `--url` with the specified Habitat Builder URL to the hab command. Depending on the type of Habitat Builder you are connecting to, this URL will look different, here are the **3** current types:
93
+ - Public Habitat Builder (default) - `https://bldr.habitat.sh`
94
+ - On-Prem Habitat Builder installed using the [Source Install Method](https://github.com/habitat-sh/on-prem-builder) - `https://your.bldr.url`
95
+ - On-Prem Habitat Builder installed using the [Automate Installer](https://automate.chef.io/docs/on-prem-builder/) - `https://your.bldr.url/bldr/v1`"
96
+
97
+ property :channel, [Symbol, String], default: :stable, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s },
98
+ description: "Passes `--channel` with the specified channel to the hab command"
99
+
100
+ property :bind, [String, Array], coerce: proc { |b| b.is_a?(String) ? [b] : b }, default: [],
101
+ description: "Passes `--bind` with the specified services to bind to the hab command. If an array of multiple service binds are specified then a `--bind` flag is added for each."
102
+
103
+ property :binding_mode, [Symbol, String], equal_to: [:strict, "strict", :relaxed, "relaxed"], default: :strict, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s },
104
+ description: "Passes `--binding-mode` with the specified binding mode. Defaults to `:strict`. Options are `:strict` or `:relaxed`"
105
+
106
+ property :service_group, String, default: "default",
107
+ description: " Passes `--group` with the specified service group to the hab command"
108
+
109
+ property :shutdown_timeout, Integer, default: 8,
110
+ description: "The timeout in seconds allowed during shutdown."
111
+
112
+ property :health_check_interval, Integer, default: 30,
113
+ description: "The interval (seconds) on which to run health checks."
114
+
115
+ property :remote_sup, String, default: "127.0.0.1:9632", desired_state: false,
116
+ description: "Address to a remote Supervisor's Control Gateway"
117
+
118
+ # Http port needed for querying/comparing current config value
119
+ property :remote_sup_http, String, default: "127.0.0.1:9631", desired_state: false,
120
+ description: "IP address and port used to communicate with the remote supervisor. If this value is invalid, the resource will update the supervisor configuration each time #{ChefUtils::Dist::Server::PRODUCT} runs."
121
+
122
+ property :gateway_auth_token, String, desired_state: false,
123
+ description: "Auth token for accessing the remote supervisor's http port."
124
+
125
+ property :update_condition, [Symbol, String], equal_to: [:latest, "latest", :'track-channel', "track-channel"], default: :latest, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s },
126
+ description: "Passes `--update-condition` dictating when this service should updated. Defaults to `latest`. Options are `latest` or `track-channel` **_Note: This requires a minimum habitat version of 1.5.71_**
127
+ - `latest`: Runs the latest package that can be found in the configured channel and local packages.
128
+ - `track-channel`: Always run the package at the head of a given channel. This enables service rollback, where demoting a package from a channel will cause the package to rollback to an older version of the package. A ramification of enabling this condition is that packages that are newer than the package at the head of the channel are also uninstalled during a service rollback."
129
+
130
+ load_current_value do
131
+ service_details = get_service_details(service_name)
132
+
133
+ running service_up?(service_details)
134
+ loaded service_loaded?(service_details)
135
+
136
+ if loaded
137
+ service_name get_spec_identifier(service_details)
138
+ strategy get_update_strategy(service_details)
139
+ update_condition get_update_condition(service_details)
140
+ topology get_topology(service_details)
141
+ bldr_url get_builder_url(service_details)
142
+ channel get_channel(service_details)
143
+ bind get_binds(service_details)
144
+ binding_mode get_binding_mode(service_details)
145
+ service_group get_service_group(service_details)
146
+ shutdown_timeout get_shutdown_timeout(service_details)
147
+ health_check_interval get_health_check_interval(service_details)
148
+ end
149
+
150
+ Chef::Log.debug("service #{service_name} service name: #{service_name}")
151
+ Chef::Log.debug("service #{service_name} running state: #{running}")
152
+ Chef::Log.debug("service #{service_name} loaded state: #{loaded}")
153
+ Chef::Log.debug("service #{service_name} strategy: #{strategy}")
154
+ Chef::Log.debug("service #{service_name} update condition: #{update_condition}")
155
+ Chef::Log.debug("service #{service_name} topology: #{topology}")
156
+ Chef::Log.debug("service #{service_name} builder url: #{bldr_url}")
157
+ Chef::Log.debug("service #{service_name} channel: #{channel}")
158
+ Chef::Log.debug("service #{service_name} binds: #{bind}")
159
+ Chef::Log.debug("service #{service_name} binding mode: #{binding_mode}")
160
+ Chef::Log.debug("service #{service_name} service group: #{service_group}")
161
+ Chef::Log.debug("service #{service_name} shutdown timeout: #{shutdown_timeout}")
162
+ Chef::Log.debug("service #{service_name} health check interval: #{health_check_interval}")
163
+ end
164
+
165
+ # This method is defined here otherwise it isn't usable in the
166
+ # `load_current_value` method.
167
+ #
168
+ # It performs a check with TCPSocket to ensure that the HTTP API is
169
+ # available first. If it cannot connect, it assumes that the service
170
+ # is not running. It then attempts to reach the `/services` path of
171
+ # the API to get a list of services. If this fails for some reason,
172
+ # then it assumes the service is not running.
173
+ #
174
+ # Finally, it walks the services returned by the API to look for the
175
+ # service we're configuring. If it is "Up", then we know the service
176
+ # is running and fully operational according to Habitat. This is
177
+ # wrapped in a begin/rescue block because if the service isn't
178
+ # present and `sup_for_service_name` will be nil and we will get a
179
+ # NoMethodError.
180
+ #
181
+ def get_service_details(svc_name)
182
+ http_uri = "http://#{remote_sup_http}"
183
+
184
+ begin
185
+ TCPSocket.new(URI(http_uri).host, URI(http_uri).port).close
186
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
187
+ Chef::Log.debug("Could not connect to #{http_uri} to retrieve status for #{service_name}")
188
+ return false
189
+ end
190
+
191
+ begin
192
+ headers = {}
193
+ headers["Authorization"] = "Bearer #{gateway_auth_token}" if property_is_set?(:gateway_auth_token)
194
+ svcs = Chef::HTTP::SimpleJSON.new(http_uri).get("/services", headers)
195
+ rescue
196
+ Chef::Log.debug("Could not connect to #{http_uri}/services to retrieve status for #{service_name}")
197
+ return false
198
+ end
199
+
200
+ origin, name, _version, _release = svc_name.split("/")
201
+ svcs.find do |s|
202
+ s["pkg"]["origin"] == origin && s["pkg"]["name"] == name
203
+ end
204
+ end
205
+
206
+ def service_up?(service_details)
207
+ service_details["process"]["state"] == "up"
208
+ rescue
209
+ Chef::Log.debug("#{service_name} not found on the Habitat supervisor")
210
+ false
211
+ end
212
+
213
+ def service_loaded?(service_details)
214
+ if service_details
215
+ true
216
+ else
217
+ false
218
+ end
219
+ end
220
+
221
+ def get_spec_identifier(service_details)
222
+ service_details["spec_ident"]["spec_identifier"]
223
+ rescue
224
+ Chef::Log.debug("#{service_name} not found on the Habitat supervisor")
225
+ nil
226
+ end
227
+
228
+ def get_update_strategy(service_details)
229
+ service_details["update_strategy"].to_sym
230
+ rescue
231
+ Chef::Log.debug("Update Strategy for #{service_name} not found on Supervisor API")
232
+ "none"
233
+ end
234
+
235
+ def get_update_condition(service_details)
236
+ service_details["update_condition"].to_sym
237
+ rescue
238
+ Chef::Log.debug("Update condition #{service_name} not found on Supervisor API")
239
+ "latest"
240
+ end
241
+
242
+ def get_topology(service_details)
243
+ service_details["topology"].to_sym
244
+ rescue
245
+ Chef::Log.debug("Topology for #{service_name} not found on Supervisor API")
246
+ "standalone"
247
+ end
248
+
249
+ def get_builder_url(service_details)
250
+ service_details["bldr_url"]
251
+ rescue
252
+ Chef::Log.debug("Habitat Builder URL for #{service_name} not found on Supervisor API")
253
+ "https://bldr.habitat.sh"
254
+ end
255
+
256
+ def get_channel(service_details)
257
+ service_details["channel"].to_sym
258
+ rescue
259
+ Chef::Log.debug("Channel for #{service_name} not found on Supervisor API")
260
+ "stable"
261
+ end
262
+
263
+ def get_binds(service_details)
264
+ service_details["binds"]
265
+ rescue
266
+ Chef::Log.debug("Update Strategy for #{service_name} not found on Supervisor API")
267
+ []
268
+ end
269
+
270
+ def get_binding_mode(service_details)
271
+ service_details["binding_mode"].to_sym
272
+ rescue
273
+ Chef::Log.debug("Binding mode for #{service_name} not found on Supervisor API")
274
+ "strict"
275
+ end
276
+
277
+ def get_service_group(service_details)
278
+ service_details["service_group"].split(".").last
279
+ rescue
280
+ Chef::Log.debug("Service Group for #{service_name} not found on Supervisor API")
281
+ "default"
282
+ end
283
+
284
+ def get_shutdown_timeout(service_details)
285
+ service_details["pkg"]["shutdown_timeout"]
286
+ rescue
287
+ Chef::Log.debug("Shutdown Timeout for #{service_name} not found on Supervisor API")
288
+ 8
289
+ end
290
+
291
+ def get_health_check_interval(service_details)
292
+ service_details["health_check_interval"]["secs"]
293
+ rescue
294
+ Chef::Log.debug("Health Check Interval for #{service_name} not found on Supervisor API")
295
+ 30
296
+ end
297
+
298
+ action :load, description: "(default action) runs `hab service load` to load and start the specified application service" do
299
+ modified = false
300
+ converge_if_changed :service_name do
301
+ modified = true
302
+ end
303
+ converge_if_changed :strategy do
304
+ modified = true
305
+ end
306
+ converge_if_changed :update_condition do
307
+ modified = true
308
+ end
309
+ converge_if_changed :topology do
310
+ modified = true
311
+ end
312
+ converge_if_changed :bldr_url do
313
+ modified = true
314
+ end
315
+ converge_if_changed :channel do
316
+ modified = true
317
+ end
318
+ converge_if_changed :bind do
319
+ modified = true
320
+ end
321
+ converge_if_changed :binding_mode do
322
+ modified = true
323
+ end
324
+ converge_if_changed :service_group do
325
+ modified = true
326
+ end
327
+ converge_if_changed :shutdown_timeout do
328
+ modified = true
329
+ end
330
+ converge_if_changed :health_check_interval do
331
+ modified = true
332
+ end
333
+
334
+ options = svc_options
335
+ if current_resource.loaded && modified
336
+ Chef::Log.debug("Reloading #{current_resource.service_name} using --force due to parameter change")
337
+ options << "--force"
338
+ end
339
+
340
+ unless current_resource.loaded && !modified
341
+ execute "test" do
342
+ command "hab svc load #{new_resource.service_name} #{options.join(" ")}"
343
+ retry_delay 10
344
+ retries 5
345
+ end
346
+ end
347
+ end
348
+
349
+ action :unload, description: "runs `hab service unload` to unload and stop the specified application service" do
350
+ if current_resource.loaded
351
+ execute "hab svc unload #{new_resource.service_name} #{svc_options.join(" ")}"
352
+ wait_for_service_unloaded
353
+ end
354
+ end
355
+
356
+ action :start, description: "runs `hab service start` to start the specified application service" do
357
+ unless current_resource.loaded
358
+ Chef::Log.fatal("No service named #{new_resource.service_name} is loaded on the Habitat supervisor")
359
+ raise "No service named #{new_resource.service_name} is loaded on the Habitat supervisor"
360
+ end
361
+
362
+ execute "hab svc start #{new_resource.service_name} #{svc_options.join(" ")}" unless current_resource.running
363
+ end
364
+
365
+ action :stop, description: "runs `hab service stop` to stop the specified application service" do
366
+ unless current_resource.loaded
367
+ Chef::Log.fatal("No service named #{new_resource.service_name} is loaded on the Habitat supervisor")
368
+ raise "No service named #{new_resource.service_name} is loaded on the Habitat supervisor"
369
+ end
370
+
371
+ if current_resource.running
372
+ execute "hab svc stop #{new_resource.service_name} #{svc_options.join(" ")}"
373
+ wait_for_service_stopped
374
+ end
375
+ end
376
+
377
+ action :restart, description: "runs the `:stop` and then `:start` actions" do
378
+ action_stop
379
+ action_start
380
+ end
381
+
382
+ action :reload, description: "runs the `:unload` and then `:load` actions" do
383
+ action_unload
384
+ action_load
385
+ end
386
+
387
+ action_class do
388
+ def svc_options
389
+ opts = []
390
+
391
+ # certain options are only valid for specific `hab svc` subcommands.
392
+ case action
393
+ when :load
394
+ opts.push(*new_resource.bind.map { |b| "--bind #{b}" }) if new_resource.bind
395
+ opts << "--binding-mode #{new_resource.binding_mode}"
396
+ opts << "--url #{new_resource.bldr_url}" if new_resource.bldr_url
397
+ opts << "--channel #{new_resource.channel}" if new_resource.channel
398
+ opts << "--group #{new_resource.service_group}" if new_resource.service_group
399
+ opts << "--strategy #{new_resource.strategy}" if new_resource.strategy
400
+ opts << "--update-condition #{new_resource.update_condition}" if new_resource.update_condition
401
+ opts << "--topology #{new_resource.topology}" if new_resource.topology
402
+ opts << "--health-check-interval #{new_resource.health_check_interval}" if new_resource.health_check_interval
403
+ opts << "--shutdown-timeout #{new_resource.shutdown_timeout}" if new_resource.shutdown_timeout
404
+ when :unload, :stop
405
+ opts << "--shutdown-timeout #{new_resource.shutdown_timeout}" if new_resource.shutdown_timeout
406
+ end
407
+
408
+ opts << "--remote-sup #{new_resource.remote_sup}" if new_resource.remote_sup
409
+
410
+ opts.map(&:split).flatten.compact
411
+ end
412
+
413
+ def wait_for_service_unloaded
414
+ ruby_block "wait-for-service-unloaded" do
415
+ block do
416
+ raise "#{new_resource.service_name} still loaded" if service_loaded?(get_service_details(new_resource.service_name))
417
+ end
418
+ retries get_shutdown_timeout(new_resource.service_name) + 1
419
+ retry_delay 1
420
+ end
421
+
422
+ ruby_block "update current_resource" do
423
+ block do
424
+ current_resource.loaded = service_loaded?(get_service_details(new_resource.service_name))
425
+ end
426
+ action :nothing
427
+ subscribes :run, "ruby_block[wait-for-service-unloaded]", :immediately
428
+ end
429
+ end
430
+
431
+ def wait_for_service_stopped
432
+ ruby_block "wait-for-service-stopped" do
433
+ block do
434
+ raise "#{new_resource.service_name} still running" if service_up?(get_service_details(new_resource.service_name))
435
+ end
436
+ retries get_shutdown_timeout(new_resource.service_name) + 1
437
+ retry_delay 1
438
+
439
+ ruby_block "update current_resource" do
440
+ block do
441
+ current_resource.running = service_up?(get_service_details(new_resource.service_name))
442
+ end
443
+ action :nothing
444
+ subscribes :run, "ruby_block[wait-for-service-stopped]", :immediately
445
+ end
446
+ end
447
+ end
448
+ end
449
+ end
450
+ end
451
+ end
@@ -0,0 +1,92 @@
1
+ # Copyright:: Chef Software Inc.
2
+ # License:: Apache License, Version 2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing
14
+
15
+ require_relative "../resource"
16
+ class Chef
17
+ class Resource
18
+ class HabitatUserToml < Chef::Resource
19
+ unified_mode true
20
+ provides :habitat_user_toml
21
+
22
+ description "Use the **habitat_user_toml** to template a `user.toml` for Chef Habitat services. Configurations set in the `user.toml` override the `default.toml` for a given package, which makes it an alternative to applying service group level configuration."
23
+ introduced "17.3"
24
+ examples <<~DOC
25
+ **Configure user specific settings to nginx**
26
+
27
+ ```ruby
28
+ habitat_user_toml 'nginx' do
29
+ config({
30
+ worker_count: 2,
31
+ http: {
32
+ keepalive_timeout: 120
33
+ }
34
+ })
35
+ end
36
+ ```
37
+ DOC
38
+
39
+ property :config, Mash, required: true, coerce: proc { |m| m.is_a?(Hash) ? Mash.new(m) : m },
40
+ description: "Only valid for `:create` action. The configuration to apply as a ruby hash, for example, `{ worker_count: 2, http: { keepalive_timeout: 120 } }`."
41
+
42
+ property :service_name, String, name_property: true, desired_state: false,
43
+ description: "The service group to apply the configuration to, for example, `nginx.default`."
44
+
45
+ action :create, description: "(default action) Create the user.toml from the specified config." do
46
+ directory config_directory do
47
+ mode "0755"
48
+ owner root_owner
49
+ group node["root_group"]
50
+ recursive true
51
+ end
52
+
53
+ file "#{config_directory}/user.toml" do
54
+ mode "0600"
55
+ owner root_owner
56
+ group node["root_group"]
57
+ content render_toml(new_resource.config)
58
+ sensitive true
59
+ end
60
+ end
61
+
62
+ action :delete, description: "Delete the user.toml" do
63
+ file "#{config_directory}/user.toml" do
64
+ sensitive true
65
+ action :delete
66
+ end
67
+ end
68
+
69
+ action_class do
70
+ def config_directory
71
+ windows? ? "C:/hab/user/#{new_resource.service_name}/config" : "/hab/user/#{new_resource.service_name}/config"
72
+ end
73
+
74
+ def wmi_property_from_query(wmi_property, wmi_query)
75
+ @wmi = ::WIN32OLE.connect("winmgmts://")
76
+ result = @wmi.ExecQuery(wmi_query)
77
+ return unless result.each.count > 0
78
+
79
+ result.each.next.send(wmi_property)
80
+ end
81
+
82
+ def root_owner
83
+ if windows?
84
+ wmi_property_from_query(:name, "select * from Win32_UserAccount where sid like 'S-1-5-21-%-500' and LocalAccount=True")
85
+ else
86
+ "root"
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end