Skip to content

Commit

Permalink
Added Windows Support
Browse files Browse the repository at this point in the history
* Fixes #236
* Added Windows Support (binary install_method only) using NSSM
  to manage the service. NSSM runs consul as the local SYSTEM user.
  Support for running it as another user can/should be added later.
* Prevented the firewall cookbook from creating rules for disabled
  ports
* Added & Updated spec tests
* Disabled Style/ModuleFunction cop
  • Loading branch information
Ginja committed Jan 19, 2016
1 parent 8b640fa commit ad2fcf5
Show file tree
Hide file tree
Showing 14 changed files with 340 additions and 174 deletions.
2 changes: 2 additions & 0 deletions .rubocop.yml
Expand Up @@ -42,3 +42,5 @@ Style/GuardClause:
Enabled: false
Style/PercentLiteralDelimiters:
Enabled: false
Style/ModuleFunction:
Enabled: false
19 changes: 13 additions & 6 deletions attributes/default.rb
Expand Up @@ -4,18 +4,23 @@
#
# Copyright 2014-2016, Bloomberg Finance L.P.
#
::Chef::Node.send(:include, ConsulCookbook::Helpers)

# Only used on Linux
default['consul']['service_name'] = 'consul'
default['consul']['service_user'] = 'consul'
default['consul']['service_group'] = 'consul'

default['consul']['config']['path'] = '/etc/consul.json'
default['consul']['config']['bag_name'] = 'secrets'
default['consul']['config']['bag_item'] = 'consul'
default['consul']['config']['data_dir'] = '/var/lib/consul'
default['consul']['config']['ca_file'] = '/etc/consul/ssl/CA/ca.crt'
default['consul']['config']['cert_file'] = '/etc/consul/ssl/certs/consul.crt'

default['consul']['config']['path'] = join_path prefix_path, 'consul.json'
default['consul']['config']['data_dir'] = join_path prefix_path, 'data'
default['consul']['config']['ca_file'] = join_path prefix_path, 'ssl', 'CA', 'ca.crt'
default['consul']['config']['cert_file'] = join_path prefix_path, 'ssl', 'certs', 'consul.crt'
default['consul']['config']['key_file'] = join_path prefix_path, 'ssl', 'private', 'consul.key'

default['consul']['config']['client_addr'] = '0.0.0.0'
default['consul']['config']['key_file'] = '/etc/consul/ssl/private/consul.key'
default['consul']['config']['ports'] = {
'dns' => 8600,
'http' => 8500,
Expand All @@ -27,8 +32,10 @@

default['consul']['diplomat_version'] = nil

default['consul']['service']['config_dir'] = join_path prefix_path, 'conf.d'
default['consul']['service']['data_dir'] = join_path prefix_path, 'data'

default['consul']['service']['install_method'] = 'binary'
default['consul']['service']['config_dir'] = '/etc/consul'
default['consul']['service']['binary_url'] = "https://releases.hashicorp.com/consul/%{version}/%{filename}.zip" # rubocop:disable Style/StringLiterals

default['consul']['service']['source_url'] = 'https://github.com/hashicorp/consul'
Expand Down
50 changes: 32 additions & 18 deletions libraries/consul_config.rb
Expand Up @@ -5,12 +5,14 @@
# Copyright 2014-2016, Bloomberg Finance L.P.
#
require 'poise'
require_relative 'helpers'

module ConsulCookbook
module Resource
# @since 1.0.0
class ConsulConfig < Chef::Resource
include Poise(fused: true)
include ConsulCookbook::Helpers
provides(:consul_config)

# @!attribute path
Expand Down Expand Up @@ -114,49 +116,61 @@ def tls?
[new_resource.ca_file, new_resource.cert_file, new_resource.key_file].each do |filename|
directory ::File.dirname(filename) do
recursive true
owner new_resource.owner
group new_resource.group
mode '0755'
if node['os'].eql? 'linux'
owner new_resource.owner
group new_resource.group
mode '0755'
end
end
end

item = chef_vault_item(new_resource.bag_name, new_resource.bag_item)
file new_resource.ca_file do
content item['ca_certificate']
mode '0644'
owner new_resource.owner
group new_resource.group
if node['os'].eql? 'linux'
owner new_resource.owner
group new_resource.group
mode '0644'
end
end

file new_resource.cert_file do
content item['certificate']
mode '0644'
owner new_resource.owner
group new_resource.group
if node['os'].eql? 'linux'
owner new_resource.owner
group new_resource.group
mode '0644'
end
end

file new_resource.key_file do
sensitive true
content item['private_key']
mode '0640'
owner new_resource.owner
group new_resource.group
if node['os'].eql? 'linux'
owner new_resource.owner
group new_resource.group
mode '0640'
end
end
end

directory ::File.dirname(new_resource.path) do
recursive true
owner new_resource.owner
group new_resource.group
mode '0755'
if node['os'].eql? 'linux'
owner new_resource.owner
group new_resource.group
mode '0755'
end
not_if { ::File.dirname(new_resource.path) == '/etc' }
end

file new_resource.path do
owner new_resource.owner
group new_resource.group
if node['os'].eql? 'linux'
owner new_resource.owner
group new_resource.group
mode '0640'
end
content new_resource.to_json
mode '0640'
end
end
end
Expand Down
133 changes: 8 additions & 125 deletions libraries/consul_service.rb
Expand Up @@ -5,15 +5,18 @@
# Copyright 2014-2016, Bloomberg Finance L.P.
#
require 'poise_service/service_mixin'
require_relative 'helpers'

module ConsulCookbook
module Resource
# Resource for managing the Consul service on an instance.
# @since 1.0.0
class ConsulService < Chef::Resource
include Poise
provides(:consul_service)
provides :consul_service
actions :enable, :disable
include PoiseService::ServiceMixin
include ConsulCookbook::Helpers

# @!attribute version
# @return [String]
Expand All @@ -25,11 +28,11 @@ class ConsulService < Chef::Resource

# @!attribute install_path
# @return [String]
attribute(:install_path, kind_of: String, default: '/srv')
attribute(:install_path, kind_of: String, default: lazy { windows? ? "#{program_files}\\consul" : '/srv' })

# @!attribute config_file
# @return [String]
attribute(:config_file, kind_of: String, default: '/etc/consul.json')
attribute(:config_file, kind_of: String, default: lazy { node['consul']['config']['path'] })

# @!attribute user
# @return [String]
Expand Down Expand Up @@ -57,131 +60,11 @@ class ConsulService < Chef::Resource

# @!attribute data_dir
# @return [String]
attribute(:data_dir, kind_of: String, default: '/var/lib/consul')
attribute(:data_dir, kind_of: String, default: lazy { node['consul']['service']['data_dir'] })

# @!attribute config_dir
# @return [String]
attribute(:config_dir, kind_of: String, default: '/etc/consul')

def default_environment
{
'GOMAXPROCS' => [node['cpu']['total'], 2].max.to_s,
'PATH' => '/usr/local/bin:/usr/bin:/bin'
}
end

def command
"/usr/bin/env consul agent -config-file=#{config_file} -config-dir=#{config_dir}"
end

def binary_checksum
node['consul']['checksums'].fetch(binary_filename)
end

def binary_filename
arch = node['kernel']['machine'] =~ /x86_64/ ? 'amd64' : '386'
['consul', version, node['os'], arch].join('_')
end
end
end

module Provider
# Provider for managing the Consul service on an instance.
# @since 1.0.0
class ConsulService < Chef::Provider
include Poise
provides(:consul_service)
include PoiseService::ServiceMixin

def action_enable
notifying_block do
package new_resource.package_name do
version new_resource.version unless new_resource.version.nil?
only_if { new_resource.install_method == 'package' }
end

if node['platform'] == 'windows'
include_recipe 'chocolatey::default'

chocolatey new_resource.package_name do
version new_resource.version
end
end

if new_resource.install_method == 'binary'
artifact = libartifact_file "consul-#{new_resource.version}" do
artifact_name 'consul'
artifact_version new_resource.version
install_path new_resource.install_path
remote_url new_resource.binary_url % { version: new_resource.version, filename: new_resource.binary_filename }
remote_checksum new_resource.binary_checksum
end

link '/usr/local/bin/consul' do
to ::File.join(artifact.current_path, 'consul')
end
end

if new_resource.install_method == 'source'
include_recipe 'golang::default'

source_dir = directory ::File.join(new_resource.install_path, 'consul', 'src') do
recursive true
owner new_resource.user
group new_resource.group
mode '0755'
end

git ::File.join(source_dir.path, "consul-#{new_resource.version}") do
repository new_resource.source_url
reference new_resource.version
action :checkout
end

golang_package 'github.com/hashicorp/consul' do
action :install
end

directory ::File.join(new_resource.install_path, 'bin') do
recursive true
owner new_resource.user
group new_resource.group
mode '0755'
end

link ::File.join(new_resource.install_path, 'bin', 'consul') do
to ::File.join(source_dir.path, "consul-#{new_resource.version}", 'consul')
end
end

[new_resource.data_dir, new_resource.config_dir].each do |dirname|
directory dirname do
recursive true
owner new_resource.user
group new_resource.group
mode '0755'
end
end
end
super
end

def action_disable
notifying_block do
file new_resource.config_file do
action :delete
end
end
super
end

def service_options(service)
service.command(new_resource.command)
service.directory(new_resource.data_dir)
service.user(new_resource.user)
service.environment(new_resource.environment)
service.restart_on_update(true)
end
attribute(:config_dir, kind_of: String, default: lazy { node['consul']['config']['config_dir'] })
end
end
end

0 comments on commit ad2fcf5

Please sign in to comment.