# # Copyright:: Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require_relative "../../resource" class Chef class Resource class HabitatSup < Chef::Resource provides :habitat_sup do |_node| false end description "Use the **habitat_sup** resource to runs a Chef Habitat supervisor for one or more Chef Habitat services. The resource is commonly used in conjunction with `habitat_service` which will manage the services loaded and started within the supervisor." introduced "17.3" examples <<~DOC **Set up with just the defaults** ```ruby habitat_sup 'default' ``` **Update listen ports and use Supervisor toml config** ```ruby habitat_sup 'test-options' do listen_http '0.0.0.0:9999' listen_gossip '0.0.0.0:9998' toml_config true end ``` **Use with an on-prem Habitat Builder. Note: Access to public builder may not be available due to your company policies** ```ruby habitat_sup 'default' do bldr_url 'https://bldr.example.com' end ``` **Using update_condition** ```ruby habitat_sup 'default' do bldr_url 'https://bldr.example.com' habitat_channel 'dev' update_condition 'track-channel' end ``` **Provide event stream information** ```ruby habitat_sup 'default' do license 'accept' event_stream_application 'myapp' event_stream_environment 'production' event_stream_site 'MySite' event_stream_url 'automate.example.com:4222' event_stream_token 'myawesomea2clitoken=' event_stream_cert '/hab/cache/ssl/mycert.crt' end ``` **Provide specific versions** ```ruby habitat_sup 'default' do bldr_url 'https://bldr.example.com' sup_version '1.5.50' launcher_version '13458' service_version '0.6.0' # WINDOWS ONLY end ``` **Set latest version of packages to retain** habitat_sup 'default' do bldr_url 'https://bldr.example.com' sup_version '1.5.86' launcher_version '13458' service_version '0.6.0' # WINDOWS ONLY keep_latest '2' end ``` DOC property :bldr_url, String, description: "The Habitat Builder URL for the `habitat_package` resource, if needed." property :permanent_peer, [true, false], default: false, description: "Only valid for `:run` action, passes `--permanent-peer` to the hab command." property :listen_ctl, String, description: "Only valid for `:run` action, passes `--listen-ctl` with the specified address and port, e.g., `0.0.0.0:9632`, to the hab command." property :listen_gossip, String, description: "Only valid for `:run` action, passes `--listen-gossip` with the specified address and port, e.g., `0.0.0.0:9638`, to the hab command." property :listen_http, String, description: "Only valid for `:run` action, passes `--listen-http` with the specified address and port, e.g., `0.0.0.0:9631`, to the hab command." property :org, String, default: "default", description: "Only valid for `:run` action, passes `--org` with the specified org name to the hab command." property :peer, [String, Array], coerce: proc { |b| b.is_a?(String) ? [b] : b }, description: "Only valid for `:run` action, passes `--peer` with the specified initial peer to the hab command." property :ring, String, description: "Only valid for `:run` action, passes `--ring` with the specified ring key name to the hab command." property :hab_channel, String, description: "The channel to install Habitat from. Defaults to stable" property :auto_update, [true, false], default: false, description: "Passes `--auto-update`. This will set the Habitat supervisor to automatically update itself any time a stable version has been released." property :auth_token, String, description: "Auth token for accessing a private organization on bldr. This value is templated into the appropriate service file." property :gateway_auth_token, String, description: "Auth token for accessing the supervisor's HTTP gateway. This value is templated into the appropriate service file." property :update_condition, String, 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_** - `latest`: Runs the latest package that can be found in the configured channel and local packages. - `track-channel`: Always run what is 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 packages newer than the package at the head of the channel will be automatically uninstalled during a service rollback." property :limit_no_files, String, description: "allows you to set LimitNOFILE in the systemd service when used Note: Linux Only." property :license, String, equal_to: ["accept"], description: "Specifies acceptance of habitat license when set to `accept`." property :health_check_interval, [String, Integer], coerce: proc { |h| h.is_a?(String) ? h : h.to_s }, description: "The interval (seconds) on which to run health checks." property :event_stream_application, String, description: "The name of your application that will be displayed in the Chef Automate Applications Dashboard." property :event_stream_environment, String, description: "The application environment for the supervisor, this is for grouping in the Applications Dashboard." property :event_stream_site, String, description: "Application Dashboard label for the 'site' of the application - can be filtered in the dashboard." property :event_stream_url, String, description: "`AUTOMATE_HOSTNAME:4222` - the Chef Automate URL with port 4222 specified Note: The port can be changed if needed." property :event_stream_token, String, description: "Chef Automate token for sending application event stream data." property :event_stream_cert, String, description: "With `Intermediary Certificates` or, Automate 2 being set to use TLS with a valid cert, you will need to provide `Habitat` with your certificate for communication with Automate to work. [Follow these steps!](https://automate.chef.io/docs/applications-setup/#share-the-tls-certificate-with-chef-habitat)." property :sup_version, String, description: "Allows you to choose which version of supervisor you would like to install. Note: If a version is provided, it will also install that version of habitat if not previously installed." property :launcher_version, String, description: "Allows you to choose which version of launcher to install." property :service_version, String, # Windows only description: "Allows you to choose which version of the **_Windows Service_** to install." property :keep_latest, String, description: "Automatically cleans up old packages. If this flag is enabled, service startup will initiate an uninstall of all previous versions of the associated package. This also applies when a service is restarted due to an update. If a number is passed to this argument, that number of latest versions will be kept. The same logic applies to the Supervisor package `env:HAB_KEEP_LATEST_PACKAGES=1` Note: This requires Habitat version `1.5.86+`" property :toml_config, [true, false], default: false, description: "Supports using the Supervisor toml configuration instead of passing exec parameters to the service, [reference](https://www.habitat.sh/docs/reference/#supervisor-config)." action :run, description: "The `run` action handles installing Habitat using the `habitat_install` resource, ensures that the appropriate versions of the `core/hab-sup` and `core/hab-launcher` packages are installed using `habitat_package`, and then drops off the appropriate init system definitions and manages the service." do habitat_install new_resource.name do license new_resource.license hab_version new_resource.sup_version if new_resource.sup_version not_if { ::File.exist?("/bin/hab") } not_if { ::File.exist?("/usr/bin/hab") } not_if { ::File.exist?("c:/habitat/hab.exe") } not_if { ::File.exist?("c:/ProgramData/Habitat/hab.exe") } end habitat_package "core/hab-sup" do bldr_url new_resource.bldr_url if new_resource.bldr_url version new_resource.sup_version if new_resource.sup_version end habitat_package "core/hab-launcher" do bldr_url new_resource.bldr_url if new_resource.bldr_url version new_resource.launcher_version if new_resource.launcher_version end if windows? directory "C:/hab/sup/default/config" do recursive true only_if { ::Dir.exist?("C:/hab") } only_if { use_toml_config } action :create end template "C:/hab/sup/default/config/sup.toml" do source ::File.expand_path("../support/sup.toml.erb", __dir__) local true sensitive true variables( bldr_url: new_resource.bldr_url, permanent_peer: new_resource.permanent_peer, listen_ctl: new_resource.listen_ctl, listen_gossip: new_resource.listen_gossip, listen_http: new_resource.listen_http, organization: new_resource.org, peer: peer_list_with_port, ring: new_resource.ring, auto_update: new_resource.auto_update, update_condition: new_resource.update_condition, health_check_interval: new_resource.health_check_interval, event_stream_application: new_resource.event_stream_application, event_stream_environment: new_resource.event_stream_environment, event_stream_site: new_resource.event_stream_site, event_stream_url: new_resource.event_stream_url, event_stream_token: new_resource.event_stream_token, event_stream_server_certificate: new_resource.event_stream_cert, keep_latest_packages: new_resource.keep_latest ) only_if { use_toml_config } only_if { ::Dir.exist?("C:/hab/sup/default/config") } end else directory "/hab/sup/default/config" do mode "0755" recursive true only_if { use_toml_config } only_if { ::Dir.exist?("/hab") } action :create end template "/hab/sup/default/config/sup.toml" do source ::File.expand_path("../support/sup.toml.erb", __dir__) local true sensitive true variables( bldr_url: new_resource.bldr_url, permanent_peer: new_resource.permanent_peer, listen_ctl: new_resource.listen_ctl, listen_gossip: new_resource.listen_gossip, listen_http: new_resource.listen_http, organization: new_resource.org, peer: peer_list_with_port, ring: new_resource.ring, auto_update: new_resource.auto_update, update_condition: new_resource.update_condition, health_check_interval: new_resource.health_check_interval, event_stream_application: new_resource.event_stream_application, event_stream_environment: new_resource.event_stream_environment, event_stream_site: new_resource.event_stream_site, event_stream_url: new_resource.event_stream_url, event_stream_token: new_resource.event_stream_token, event_stream_server_certificate: new_resource.event_stream_cert, keep_latest_packages: new_resource.keep_latest ) only_if { use_toml_config } only_if { ::Dir.exist?("/hab/sup/default/config") } end end end action_class do use "habitat_shared" # validate that peers have been passed with a port # for toml file def peer_list_with_port if new_resource.peer peer_list = [] new_resource.peer.each do |p| peer_list << if !/.*:.*/.match?(p) p + ":9632" else p end end peer_list end end # Specify whether toml configuration should be used in place of service arguments. def use_toml_config new_resource.toml_config end def exec_start_options # Populate exec_start_options which will pass to 'hab sup run' for platforms if use_toml_config is not 'true' unless use_toml_config opts = [] opts << "--permanent-peer" if new_resource.permanent_peer opts << "--listen-ctl #{new_resource.listen_ctl}" if new_resource.listen_ctl opts << "--listen-gossip #{new_resource.listen_gossip}" if new_resource.listen_gossip opts << "--listen-http #{new_resource.listen_http}" if new_resource.listen_http opts << "--org #{new_resource.org}" unless new_resource.org == "default" opts.push(*new_resource.peer.map { |b| "--peer #{b}" }) if new_resource.peer opts << "--ring #{new_resource.ring}" if new_resource.ring opts << "--auto-update" if new_resource.auto_update opts << "--update-condition #{new_resource.update_condition}" if new_resource.update_condition opts << "--health-check-interval #{new_resource.health_check_interval}" if new_resource.health_check_interval opts << "--event-stream-application #{new_resource.event_stream_application}" if new_resource.event_stream_application opts << "--event-stream-environment #{new_resource.event_stream_environment}" if new_resource.event_stream_environment opts << "--event-stream-site #{new_resource.event_stream_site}" if new_resource.event_stream_site opts << "--event-stream-url #{new_resource.event_stream_url}" if new_resource.event_stream_url opts << "--event-stream-token #{new_resource.event_stream_token}" if new_resource.event_stream_token opts << "--event-stream-server-certificate #{new_resource.event_stream_cert}" if new_resource.event_stream_cert opts << "--keep-latest-packages #{new_resource.keep_latest}" if new_resource.keep_latest opts.join(" ") end end end end end end