diff --git a/.gitattributes b/.gitattributes index f5bf9825..c9a5faed 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,8 @@ +Gemfile export-ignore +Berksfile export-ignore +Vagrantfile export-ignore +Thorfile export-ignore +Guardfile export-ignore +.gitattributes export-ignore .gitignore export-ignore .gitmodules export-ignore -.gitattributes export-ignore diff --git a/.gitignore b/.gitignore index fcaab8d9..0360a014 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,55 @@ +# Ignore docs files +_gh_pages +_site +.ruby-version +.node-version +Gemfile.lock + +# Numerous always-ignore extensions +*.diff +*.err +*.orig +*.log +*.rej +*.swo +*.swp +*.zip +*.vi *~ -*# -.#* -\#*# -.*.sw[a-z] -*.un~ -pkg/ -# Berkshelf -.vagrant -/cookbooks -Berksfile.lock +# OS or Editor folders +.DS_Store +._* +Thumbs.db +.cache +.project +.settings +.tmproj +*.esproj +nbproject +*.sublime-project +*.sublime-workspace +.idea -# Bundler -Gemfile.lock -bin/* -.bundle/* +# Komodo +*.komodoproject +.komodotools + +# grunt-html-validation +validation-status.json +validation-report.json -.kitchen/ -.kitchen.local.yml +# Folders to ignore +bin +node_modules +tmp +vendor +.bundle +# Chef specifics to ignore +.chef +.chefdk +.kitchen +.vagrant +Berksfile.lock coverage/ diff --git a/.kitchen.yml b/.kitchen.yml index 47f61728..c88cd5cc 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -8,96 +8,41 @@ provisioner: platforms: - name: ubuntu-14.04 - name: ubuntu-12.04 - - name: centos-7.0 - - name: centos-6.5 + - name: centos-7.1 + - name: centos-6.6 - name: windows-2012r2 - driver_config: - network: - - ["forwarded_port", {guest: 5985, host: 5985}] - communicator: winrm - gui: true - box_url: https://wrock.blob.core.windows.net/vhds/vbox2012r2.box - customize: - usbehci: "off" suites: - name: default - excludes: - - windows-2012r2 - run_list: - - recipe[consul::default] - attributes: - consul: - datacenter: FortMeade - bind_interface: eth0 - advertise_interface: eth0 - encrypt: CGXC2NsXW4AvuB4h5ODYzQ== - - name: source - excludes: - - windows-2012r2 - run_list: - - recipe[consul::default] - attributes: - consul: - install_method: source - - name: packages - run_list: - - recipe[consul::default] - attributes: - consul: - datacenter: FortMeade - bind_interface: eth0 - advertise_interface: eth0 - encrypt: CGXC2NsXW4AvuB4h5ODYzQ== - install_method: packages - excludes: - - centos-7.0 - - centos-6.5 - - windows-2012r2 - - name: runit - excludes: - - windows-2012r2 run_list: - recipe[consul::default] attributes: consul: - datacenter: FortMeade - init_style: runit - - name: ui + config: &default-config + bootstrap: true + server: true + datacenter: FortMeade + encrypt: CGXC2NsXW4AvuB4h5ODYzQ== excludes: - windows-2012r2 + - name: source run_list: - recipe[consul::default] - - recipe[consul::ui] attributes: consul: - serve_ui: true - client_interface: eth0 - - name: cluster + config: *default-config + service: + install_method: source excludes: - windows-2012r2 + - name: package run_list: - recipe[consul::default] attributes: consul: - service_mode: cluster - bootstrap_expect: 1 - - name: atlas + config: *default-config + service: + install_method: package excludes: - - windows-2012r2 - run_list: - - recipe[consul::default] - attributes: - consul: - atlas_autojoin: true - atlas_cluster: <%= ENV.fetch('ATLAS_CLUSTER', 'example/cluster') %> - atlas_token: <%= ENV.fetch('ATLAS_TOKEN', 'NOT_REAL') %> - - name: windows - includes: - - windows-2012r2 - run_list: - - recipe[consul::default] - attributes: - consul: - install_method: windows - service_user: vagrant + - centos-7.1 + - centos-6.6 diff --git a/.rspec b/.rspec index 83e16f80..4b0b8f98 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,2 @@ --color ---require spec_helper +--default-path test/spec diff --git a/.rubocop.yml b/.rubocop.yml index d4fdfa73..4e10fefd 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,9 +1,41 @@ --- -inherit_from: .rubocop_todo.yml +AlignParameters: + Enabled: false + +Encoding: + Enabled: false + +ClassLength: + Enabled: false + +MethodLength: + Enabled: false + +LineLength: + Enabled: false + +Documentation: + Enabled: false + +PerceivedComplexity: + Enabled: false + +CyclomaticComplexity: + Enabled: false + +Style/FileName: + Enabled: false + +Style/ClassAndModuleChildren: + Enabled: false + +Metrics/AbcSize: + Enabled: false AllCops: Exclude: - - 'bin/**/*' - - 'vendor/**/*' - - 'test/**/*' - - 'spec/**/*' + - 'Guardfile' + - 'test/**/*_spec.rb' + +Style/GuardClause: + Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml deleted file mode 100644 index 075130f4..00000000 --- a/.rubocop_todo.yml +++ /dev/null @@ -1,51 +0,0 @@ -# This configuration was generated by `rubocop --auto-gen-config` -# on 2014-07-04 11:27:45 -0400 using RuboCop version 0.24.1. -# The point is for the user to remove these configuration records -# one by one as the offenses are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of RuboCop, may require this file to be generated again. - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/AlignParameters: - Enabled: false - -# Offense count: 1 -Style/CyclomaticComplexity: - Max: 7 - -# Offense count: 4 -# Configuration parameters: MaxLineLength. -Style/IfUnlessModifier: - Enabled: false - -# Offense count: 1 -Style/Lambda: - Enabled: false - -# Offense count: 9 -# Configuration parameters: AllowURI. -Style/LineLength: - Max: 119 - -# Offense count: 1 -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/Next: - Enabled: false - -# Offense count: 4 -# Configuration parameters: MaxSlashes. -Style/RegexpLiteral: - Enabled: false - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/StringLiterals: - Enabled: false - -# Offense count: 2 -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -Style/TrailingComma: - Enabled: false diff --git a/.tailor b/.tailor deleted file mode 100644 index e7b9f312..00000000 --- a/.tailor +++ /dev/null @@ -1,30 +0,0 @@ -# -*- mode: ruby -*- -Tailor.config do |config| - config.formatters "text" - config.file_set 'recipes/**/*.rb' do |style| - style.allow_camel_case_methods false, level: :error - style.allow_conditional_parentheses false, level: :warn - style.allow_hard_tabs false, level: :error - style.allow_screaming_snake_case_classes false, level: :error - style.allow_trailing_line_spaces false, level: :error - style.allow_unnecessary_interpolation false, level: :warn - style.allow_unnecessary_double_quotes false, level: :warn - style.allow_invalid_ruby false, level: :warn - style.indentation_spaces 2, level: :error - style.max_code_lines_in_class 300, level: :error - style.max_code_lines_in_method 30, level: :error - style.max_line_length 80, level: :error - style.spaces_after_comma 1, level: :error - style.spaces_after_conditional 1, level: :error - style.spaces_after_lbrace 1, level: :error - style.spaces_after_lbracket 0, level: :error - style.spaces_after_lparen 0, level: :error - style.spaces_before_comma 0, level: :error - style.spaces_before_lbrace 1, level: :error - style.spaces_before_rbrace 1, level: :error - style.spaces_before_rbracket 0, level: :error - style.spaces_before_rparen 0, level: :error - style.spaces_in_empty_braces 0, level: :error - style.trailing_newlines 1, level: :error - end -end diff --git a/.travis.yml b/.travis.yml index 4faed68c..7c6959e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,14 @@ --- language: ruby +notifications: + slack: blpsi:eHp3Czg42iGzaTgG8sAFeD9v script: bin/rspec rvm: - 2.1 + - 2.2 branches: only: - master builder_args: --jobs 7 -notifications: - irc: - channels: - - 'chat.freenode.net#bloomberg' - use_notice: true - skip_join: true - template: - - "%{message} (%{author}): %{build_url}" matrix: fast_finish: true diff --git a/Berksfile b/Berksfile index 95238856..9042e42c 100644 --- a/Berksfile +++ b/Berksfile @@ -1,7 +1,3 @@ -source 'https://supermarket.getchef.com' - +source 'https://supermarket.chef.io' +cookbook 'chef-vault', git: 'https://github.com/johnbellone/chef-vault-cookbook' metadata - -group :test do - cookbook "consul_spec", path: "spec/fixtures/cookbooks/consul_spec" -end diff --git a/CHANGELOG.md b/CHANGELOG.md index 1184e28e..0fb3dc94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,4 @@ -# 0.11.1 -Minor fixes and README updates. - -# 0.11 -Minor fixes. (Actually) last release prior to 1.0.0. - -* Enhancements - - Windows support. [@gdavison](https://github.com/gdavison) - -# 0.10.1 -Minor fixes. Last major release prior to 1.0.0. +# 1.0.0 # 0.10 Fixes several bugs, minor enhancements and changes default version of @@ -33,7 +23,6 @@ Consul to 0.5.2. * Lock to Chef 11 compatible version of libarchive cookbook # 0.9.0 - * Enhancements - Adds support for publishing to statsd URL. [@akerekes](https://github.com/akerekes) - Adds support for Arch Linux. ([@logankoester](https://github.com/logankoester)) diff --git a/Gemfile b/Gemfile index 9fb0da36..548e8a69 100644 --- a/Gemfile +++ b/Gemfile @@ -1,16 +1,43 @@ source 'https://rubygems.org' -gem 'berkshelf' -gem 'rake' -gem 'rspec' -gem 'rubocop' -gem 'foodcritic' -gem 'tailor' -gem 'coveralls', require: false -gem 'stove' - -group :test, :integration do +gem 'chef-vault', '~> 2.6' +gem 'poise', '~> 2.0' +gem 'poise-boiler' + +group :lint do + gem 'rubocop' +end + +group :kitchen_common do + gem 'test-kitchen', '~> 1.4' +end + +group :kitchen_vagrant do + gem 'kitchen-vagrant', '~> 0.17' +end + +group :kitchen_cloud do + gem 'kitchen-openstack', '~> 1.8' +end + +group :unit do + gem 'berkshelf' gem 'chefspec' - gem 'test-kitchen' - gem 'kitchen-vagrant' +end + +group :integration do gem 'serverspec' end + +group :development do + gem 'awesome_print' + gem 'guard' + gem 'guard-kitchen' + gem 'guard-rspec' + gem 'guard-rubocop' + gem 'rake' + gem 'stove' +end + +group :doc do + gem 'yard' +end diff --git a/Guardfile b/Guardfile new file mode 100644 index 00000000..2ca644c1 --- /dev/null +++ b/Guardfile @@ -0,0 +1,16 @@ +# More info at https://github.com/guard/guard#readme +guard 'rubocop' do + watch(%r{^attributes/.+\.rb$}) + watch(%r{^providers/.+\.rb$}) + watch(%r{^recipes/.+\.rb$}) + watch(%r{^resources/.+\.rb$}) + watch(%r{^libraries/.+\.rb$}) + watch('metadata.rb') +end + +guard :rspec, :cmd => 'chef exec /opt/chefdk/embedded/bin/rspec', all_on_start: false, notification: false do + watch(%r{^(recipes|libraries|providers|resources)/(.+)\.rb$}) do |m| + "test/spec/#{m[0]}/#{m[1]}_spec.rb" + end + watch('test/spec/spec_helper.rb') { 'test/spec' } +end diff --git a/LICENSE b/LICENSE index ca60bb87..4f55d866 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,4 @@ -Copyright 2014 John Bellone -Copyright 2014 Bloomberg Finance L.P. +Copyright 2014, 2015 Bloomberg Finance L.P. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -11,4 +10,4 @@ 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. \ No newline at end of file +limitations under the License. diff --git a/README.md b/README.md index 4e2ec945..a29eae3b 100644 --- a/README.md +++ b/README.md @@ -1,555 +1,113 @@ consul-cookbook =============== - [![Join the chat at https://gitter.im/johnbellone/consul-cookbook](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/johnbellone/consul-cookbook?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ![Release](http://img.shields.io/github/release/johnbellone/consul-cookbook.svg) -[![Build Status](http://img.shields.io/travis/johnbellone/consul-cookbook.svg)][5] -[![Code Coverage](http://img.shields.io/coveralls/johnbellone/consul-cookbook.svg)][6] - -Installs and configures [Consul][1] client, server and UI. +[![Build Status](http://img.shields.io/travis/johnbellone/consul-cookbook.svg)](http://travis-ci.org/johnbellone/consul-cookbook) +[![Code Coverage](http://img.shields.io/coveralls/johnbellone/consul-cookbook.svg)](https://coveralls.io/r/johnbellone/consul-cookbook) -## Supported Platforms -- CentOS 6.5, 7.0 -- RHEL 6.5, 7.0 -- Ubuntu 12.04, 14.04 -- Arch Linux -- Windows +[Application cookbook][0] which installs and configures [Consul][1]. ## Attributes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyTypeDescriptionDefault
['consul']['version']StringVersion to install0.5.0
['consul']['base_url']StringBase URL for binary downloadshttps://dl.bintray.com/mitchellh/consul/
['consul']['encrypt']StringEncryption string for consul cluster.nil
['consul']['install_method']StringMethod to install consul with when using default recipe: 'binary', 'source' or 'windows' - \*nix: binary
- Windows: binary -
['consul']['choco_source']StringSource to use for fetching the chocolatey package. Defaults to the chocolatey public feedhttps://chocolatey.org/api/v2/
['consul']['install_dir']StringDirectory to install binary to. - \*nix: /usr/local/bin
- Windows: {chocolatey_install_dir}\lib\consul.{consul_version} -
['consul']['service_mode']StringMode to run consul as: bootstrap, cluster, server, or clientbootstrap
['consul']['bootstrap_expect']StringWhen bootstrapping a cluster, the number of server nodes to expect.nil
['consul']['data_dir']StringLocation to store consul's data in - \*nix: /var/lib/consul
- Windows: C:\ProgramData\consul\data -
['consul']['config_dir']StringLocation to read service definitions from (directoy will be created) - \*nix: /etc/consul.d
- Windows: C:\ProgramData\consul\config -
['consul']['etc_config_dir']StringMisc. configuration directory that might need to be execute during service start - Debian: /etc/default/consul
- Windows: {chocolatey_install_dir}\lib\consul.{consul_version}\tools
- Other: /etc/sysconfig/consul -
['consul']['servers']Array StringsConsul servers to join[]
['consul']['retry_on_join']BooleanSet to true to wait for servers to be up before try to elect a leaderfalse
['consul']['bind_addr']Stringaddress that should be bound to for internal cluster communications0.0.0.0
['consul']['datacenter']StringName of Datacenterdc1
['consul']['domain']StringDomain for service lookup dns queriesconsul
['consul']['enable_syslog']Booleanenables logging to syslognil
['consul']['log_level']String - The level of logging to show after the Consul agent has started: 'trace', 'debug', 'info', 'warn', or 'err' - info
['consul']['node_name']StringThe name of this node in the clusterhostname of the machine
['consul']['advertise_addr']Stringaddress that we advertise to other nodes in the clusterValue of bind_addr
['consul']['init_style']StringService init mode for running consul as: 'init', 'runit', 'systemd', or 'windows' - \*nix: init
- Windows: windows -
['consul']['service_user']StringFor runit/systemd service: run consul as this user (init uses 'root')consul
['consul']['service_group']StringFor runit/systemd service: run consul as this group (init uses 'root')consul
['consul']['bind_interface']String - Interface to bind to, such as 'eth1'. Sets bind_addr - attribute to the IP of the specified interface if it exists. - nil
['consul']['advertise_interface']String - Interface to advertise, such as 'eth1'. Sets advertise_addr - attribute to the IP of the specified interface if it exists. - nil
['consul']['extra_params']hash - Pass a hash of extra params to the default.json config file - {}
['consul']['encrypt_enabled']Boolean - To enable Consul gossip encryption - false
['consul']['verify_incoming']Boolean - If set to True, Consul requires that all incoming connections make use of TLS. - false
['consul']['verify_outgoing']Boolean - If set to True, Consul requires that all outgoing connections make use of TLS. - false
['consul']['key_file']String - The content of PEM encoded private key - nil
['consul']['key_file_path']String - Path where the private key is stored on the disk - /etc/consul.d/key.pem
['consul']['ca_file']String - The content of PEM encoded ca cert - nil
['consul']['ca_file_path']String - Path where ca is stored on the disk - /etc/consul.d/ca.pem
['consul']['cert_file']String - The content of PEM encoded cert. It should only contain the public key. - nil
['consul']['cert_file_path']String - Path where cert is stored on the disk - /etc/consul.d/cert.pem
['consul']['statsd_addr']StringThis provides the address of a statsd instance (UDP).nil
['consul']['atlas_autojoin']Boolean - Determines whether Consul attempts to auto-join the cluster provided by atlas_cluster using the value of atlas_token - false
['consul']['atlas_cluster']String - Name of Atlas cluster to auto-join - nil
['consul']['atlas_token']String - API token used for Atlas integration - nil
['consul']['startup_sleep']Integer - Delay to return-of-control when invoked via an init.d script. Protects consul from an early HUP. - 3
- -### Databag Attributes (optional) -Following attributes, if exist in the [encrypted databag][7], override the node attributes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyDatabag itemTypeDescription
key_file['consul']['encrypt']StringThe content of PEM encoded private key
key_file_{fqdn}['consul']['encrypt']StringNode's(identified by fqdn) unique PEM encoded private key. If it exists, it will override the databag and node key_file attribute
ca_file['consul']['encrypt']StringThe content of PEM encoded ca cert
encrypt['consul']['encrypt']StringConsul Gossip encryption key
cert_file['consul']['encrypt']StringThe content of PEM encoded cert
cert_file_{fqdn}['consul']['encrypt']StringNode's(identified by fqdn) unique PEM encoded cert. If it exists, it will override the databag and node cert_file attribute
- -### Consul UI Attributes - - - - - - - - - - - - - - - - - - - - - - - - - - -
KeyTypeDescriptionDefault
['consul']['client_addr']StringAddress to bind to0.0.0.0
['consul']['client_interface']String - Interface to advertise, such as 'eth1'. Sets advertise_addr - attribute to the IP of the specified interface if it exists. - nil
['consul']['serve_ui']BooleanDetermines whether the consul service also serve's the UIfalse
- -## Usage -The easiest way to bootstrap a cluster is to use the cluster recipe -and use [Chef provisioning][8] which is a relatively new -extension. This extension allows you to use any driver and easily -stand up a cluster. Once the [Chef Development Kit][9] has been -installed you can run the following command to provision a cluster. +This cookbook provides node attributes which can be used to fine tune +how the recipes install and configure the Consul client, server and +UI. These values are passed into the resource/providers for +validation prior to converging. + +| Key | Type | Description | Default | +|---------|--------|----------------|-----------| +| ['consul']['version'] | String | Installation version | 0.5.1 | +| ['consul']['remote_url'] | String | Remote URL for download. | https://dl.bintray.com/mitchellh/consul | +| ['consul']['service_name'] | String | Name of the service (operating system) | consul | +| ['consul']['service_user'] | String | Name of the service user | consul | +| ['consul']['service_group'] | String | Name of the service group | consul | + +## Resources/Providers +This cookbook provides resource and provider primitives to manage the +Consul client, server and UI. These primitives are what is used in the +recipes, and should be used in your own [wrapper cookbooks][2]. + +### consul_config +| Parameter | Type | Description | Default | +| --------- | ---- | ----------- | ------- | +| path | String | File system path to write configuration. | name | +| user | String | System username for configuration ownership. | consul | +| group | String | System groupname for configuration ownership. | consul | +| bag_name | String | Name of the chef-vault data bag for TLS configuration. | secrets | +| bag_item | String | Item of the chef-vault data bag for TLS configuration. | consul | ```ruby -gem install chef-provisioning chef-provisioning-fog -export CHEF_DRIVER=fog:AWS -chef-client -z cluster.rb +consul_config '/etc/consul.json' do + user 'jbellone' + group 'staff' +end ``` +### consul_service +| Parameter | Type | Description | Default | +| --------- | ---- | ----------- | ------- | +| user | String | System username for configuration ownership. | consul | +| group | String | System groupname for configuration ownership. | consul | +| install_method | String | Determines method of installing Consul agent on node. | source, binary, package | +| install_path | String | Absolute path to where Consul agent is unpacked. | /srv | +| version | String | The version of Consul agent to install. | nil | +| config_file | String | Absolute path to the Consul agent's configuration file. | /etc/consul.json | +| config_dir | String | Absolute path to configuration directory (for definitions, watches). | /etc/consul | +| data_dir | String | Absolute path to the Consul agent's data directory. | /var/lib/consul | -Please follow the [Chef provisioning README][10] which provides more -detailed information about provisioning. You'll need to configure -your credentials prior to provisioning. - -### consul::default -The default recipe will install the Consul agent using the -`consul::install_binary` recipe. It will also configure and -start consul at the machine boot. - -### consul::install_binary -If you only wish to simply install the binary from the official -mirror you simply include `consul::install_binary` in your node's -`run_list`: - -```json -{ - "run_list": [ - "recipe[consul::install_binary]" - ] -} +```ruby +consul_service 'consul' do + user 'consul' + group 'consul' + install_method :binary + binary_url node['consul']['binary_url'] +end ``` +### consul_watch +| Parameter | Type | Description | Default | +| --------- | ---- | ----------- | ------- | +| path | String | File system path to write configuration. | name | +| user | String | System username for configuration ownership. | consul | +| group | String | System groupname for configuration ownership. | consul | +| type | String | Type of the Consul watch to configure. | key, keyprefix, service, event | +| parameters | Hash | Parameters to configure; depends on type of watch. | {} | -### consul::install_source -Instead if you wish to install Consul from source you simply need -to include `consul::install_source` in your node's `run_list`. This -will also configure the Go language framework on the node to build -the application. - -```json -{ - "run_list": [ - "recipe[consul::install_source]" - ] -} +```ruby +consul_watch '/etc/consul/foobarbaz.json' do + type 'key' + parameters(key: 'foo/bar/baz', handler: '/bin/false') +end ``` - -### consul::ui -Installing the separate Consul UI simply requires you to include -the `consul::ui` recipe in your node's `run_list`. Consul UI is not supported -on Windows platform. - -```json -{ - "run_list": [ - "recipe[consul::ui]" - ] -} +```ruby +consul_watch '/etc/consul/foobarbaz.json' do + type 'keyprefix' + parameters(prefix: 'foo/', handler: '/bin/false') +end +``` +```ruby +consul_watch '/etc/consul/foobarbaz.json' do + type 'service' + parameters(service: 'redis', handler: '/bin/false') +end +``` +```ruby +consul_watch '/etc/consul/foobarbaz.json' do + type 'event' + parameters(event: 'web-deploy', handler: '/bin/false') +end +``` +### consul_definition +| Parameter | Type | Description | Default | +| --------- | ---- | ----------- | ------- | +| path | String | File system path to write configuration. | name | +| user | String | System username for configuration ownership. | consul | +| group | String | System groupname for configuration ownership. | consul | +| type | String | Type of definition | service, check | +```ruby +consul_definition '/etc/consul/redis.json' do + type 'service' + parameters(tags: %w{master}, address: '127.0.0.1', port: 6379) +end ``` -### LWRP - -##### Adding key watch - consul_key_watch_def 'key-watch-name' do - key "/key/path" - handler "chef-client" - end - - -##### Adding event watch - consul_event_watch_def 'event-name' do - handler "chef-client" - end - -##### Adding services watch - consul_services_watch_def 'services-name' do - handler "chef-client" - end - -##### Adding service watch - consul_service_watch_def 'service-name' do - passingonly true - handler "chef-client" - end - -##### Adding service without check - - consul_service_def 'voice1' do - port 5060 - tags ['_sip._udp'] - notifies :reload, 'service[consul]' - end - -##### Adding services with checks - - consul_service_def 'voice1' do - port 5060 - tags ['_sip._udp'] - check( - interval: '10s', - script: 'echo ok' - ) - notifies :reload, 'service[consul]' - end - - consul_service_def 'server1' do - port 80 - tags ['http'] - check( - interval: '10s', - http: 'http://localhost:80' - ) - notifies :reload, 'service[consul]' - end - -##### Removing service - - consul_service_def 'voice1' do - action :delete - notifies :reload, 'service[consul]' - end - -> Be sure to notify the Consul resource to restart when your service def changes. - -#### Getting Started - -To bootstrap a consul cluster follow the following steps: - 0. Make sure that ports 8300-8302 (by default, if you configured different ones open those) UDP/TCP are all open. - 1. Bootstrap a few (preferablly 3 nodes) to be your consul servers, these will be the KV masters. - 2. Put `node['consul']['servers'] =["Array of the bootstrapped servers ips or dns names"]` in your environment. - 3. Apply the consul cookbook to these nodes with `node['consul']['service_mode'] = 'cluster'` (I put this in this in a CONSUL_MASTER role). - 4. Let these machines converge, once you can run `consul members` and get a list of all of the servers your ready to move on - 5. Apply the consul cookbook to the rest of your nodes with `node['consul']['service_mode'] = 'client'` (I put this in the environment) - 6. Start adding services and checks to your cookbooks. - 7. If you want to get values out of consul to power your chef, curl localhost:8500/v1/kv/key/path?raw in your cookbook. - -## Authors - -Created and maintained by [John Bellone][3] [@johnbellone][2] () and a growing community of [contributors][4]. - +[0]: http://blog.vialstudios.com/the-environment-cookbook-pattern/#theapplicationcookbook [1]: http://consul.io -[2]: https://twitter.com/johnbellone -[3]: https://github.com/johnbellone -[4]: https://github.com/johnbellone/consul-cookbook/graphs/contributors -[5]: http://travis-ci.org/johnbellone/consul-cookbook -[6]: https://coveralls.io/r/johnbellone/consul-cookbook -[7]: https://docs.getchef.com/essentials_data_bags.html -[8]: https://github.com/opscode/chef-provisioning -[9]: https://github.com/opscode/chef-dk -[10]: https://github.com/opscode/chef-provisioning/blob/master/README.md +[2]: http://blog.vialstudios.com/the-environment-cookbook-pattern#thewrappercookbook diff --git a/Rakefile b/Rakefile deleted file mode 100644 index a483f66f..00000000 --- a/Rakefile +++ /dev/null @@ -1,10 +0,0 @@ -require 'rspec/core/rake_task' -require 'stove/rake_task' - -Stove::RakeTask.new - -RSpec::Core::RakeTask.new(:test) do |t| - t.pattern = 'spec/**/*_spec.rb' -end - -task default: :spec diff --git a/Thorfile b/Thorfile deleted file mode 100644 index b23ee163..00000000 --- a/Thorfile +++ /dev/null @@ -1,12 +0,0 @@ -# encoding: utf-8 - -require 'bundler' -require 'bundler/setup' -require 'berkshelf/thor' - -begin - require 'kitchen/thor_tasks' - Kitchen::ThorTasks.new -rescue LoadError - puts ">>>>> Kitchen gem not loaded, omitting tasks" unless ENV['CI'] -end diff --git a/Vagrantfile b/Vagrantfile index 13c92636..beb4dd3d 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,22 +1,23 @@ Vagrant.configure('2') do |config| - # Set the version of chef to install using the vagrant-omnibus plugin - config.omnibus.chef_version = :latest - - # Enabling the Berkshelf plugin. To enable this globally, add this configuration - # option to your ~/.vagrant.d/Vagrantfile file config.berkshelf.enabled = true + config.omnibus.chef_version = :latest - # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = 'opscode-ubuntu-12.04' - - # The url from where the 'config.vm.box' box will be fetched if it - # doesn't already exist on the user's system. - config.vm.box_url = "https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_provisionerless.box" + config.vm.box = ENV.fetch('VAGRANT_VM_BOX', 'opscode-ubuntu-14.04') + config.vm.box_url = ENV.fetch('VAGRANT_VM_BOX_URL', 'https://opscode-vm-bento.s3.amazonaws.com/vagrant/opscode_ubuntu-14.04_provisionerless.box') config.vm.define :bootstrap, primary: true do |guest| guest.vm.network :private_network, ip: '172.16.38.10' - guest.vm.provision :chef_solo do |chef| - chef.run_list = ['recipe[consul::default]', 'recipe[consul::ui]'] + guest.vm.provision :chef_zero do |chef| + chef.nodes_path = File.expand_path('../.vagrant/chef/nodes', __FILE__) + chef.run_list = %w(recipe[consul::default]) + chef.json = { + consul: { + config: { + bootstrap: true, + server: true + } + } + } end end end diff --git a/attributes/default.rb b/attributes/default.rb index b242952d..8d95a105 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -1,54 +1,38 @@ # -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. +# Cookbook: consul +# License: Apache 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. +# Copyright 2014, 2015 Bloomberg Finance L.P. # +default['consul']['service_name'] = 'consul' +default['consul']['service_user'] = 'consul' +default['consul']['service_group'] = 'consul' + +default['consul']['bag_name'] = 'secrets' +default['consul']['bag_item'] = 'consul' + +default['consul']['config']['path'] = '/etc/consul.json' +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']['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, + 'rpc' => 8400, + 'serf_lan' => 8301, + 'serf_wan' => 8302, + "server" => 8300, +} -default['consul']['base_url'] = "https://dl.bintray.com/mitchellh/consul/%{version}.zip" -default['consul']['version'] = '0.5.2' -if node['platform_family'] == 'windows' - default['consul']['version'] = '0.5.0' -end -default['consul']['install_method'] = 'binary' -default['consul']['install_dir'] = '/usr/local/bin' -default['consul']['choco_source'] = "https://chocolatey.org/api/v2/" +default['consul']['service']['install_method'] = 'binary' +default['consul']['service']['config_dir'] = '/etc/consul' +default['consul']['service']['binary_url'] = "https://dl.bintray.com/mitchellh/consul/%{filename}.zip" +default['consul']['service']['source_url'] = 'https://github.com/hashicorp/consul' +default['consul']['version'] = '0.5.2' default['consul']['checksums'] = { - '0.3.0_darwin_amd64' => '9dfbc70c01ebbc3e7dba0e4b31baeddbdcbd36ef99f5ac87ca6bbcc7405df405', - '0.3.0_linux_386' => '2513496374f8f15bda0da4da33122e93f82ce39f661ee3e668c67a5b7e98fd5f', - '0.3.0_linux_amd64' => 'da1337ab3b236bad19b791a54a8df03a8c2a340500a392000c21608696957b15', - '0.3.0_web_ui' => '0ab215e6aa7c94ccdb2c074732b8706940d37386b88c9421f1e4bc2501065476', - '0.3.0_windows_386' => '5d42e143eeb7c348ed8f7e15c6223e02ce0221dc0e076d15c8e6bdf88c8cd5d2', - - '0.3.1_darwin_amd64' => 'e310d54244b207702143f1667d61bf0147d1bd656a29496d8b58eea07078d1dc', - '0.3.1_linux_386' => '9b8340fdf464a99fc9dc108115602c761b703a16277fbd9f4f164123cf2a9f11', - '0.3.1_linux_amd64' => 'c33da8ac24f01eefe8549e8d4d301b4e18a71b61f06ae1377a88ccd6eab2cfbb', - '0.3.1_web_ui' => 'd8982803fffb84d3202260161f6310bd6bddb5b12bf690cf00210cd659a31ddd', - '0.3.1_windows_386' => '102bda6e02b193a9417e80795875bf7d18259fc5daff3d048d274beef690eb26', - - '0.4.0_darwin_amd64' => '87a1b0f37e773d92c939ca7dd6a50985acc4fb4aaec31384756ef896aef4035b', - '0.4.0_linux_386' => 'e2d494654cfed1b9248734f5cb9d34dba9f356dffdcc8a09ab0ab85d170dba7c', - '0.4.0_linux_amd64' => '4f8cd1cc5d90be9e1326fee03d3c96289a4f8b9b6ccb062d228125a1adc9ea0c', - '0.4.0_windows_386' => '895387de34352f29e8cb91066b44750a958d4a44a88ac39e164cf9c62b521b08', - '0.4.0_web_ui' => '0ee574e616864b658ba6ecf16db1183b63c5a4a36401880fb0404a2ea18536a6', - - '0.4.1_darwin_amd64' => '957fe9ba27bbaf99539cd534db8ac8ec4c9fa1c6b3b4675d0c0eb3a7fbfb646c', - '0.4.1_linux_386' => 'a496d6fd8ff5b460aea50be5d20fbd95cb5d30e9018259a0540273a17fae1c25', - '0.4.1_linux_amd64' => '2cf6e59edf348c3094c721eb77436e8c789afa2c35e6e3123a804edfeb1744ac', - '0.4.1_windows_386' => '61906f5d73a0d991dae5d75a25299f183670efa473cd155c715eefc98ce49cc8', - '0.4.1_web_ui' => 'e02929ed44f5392cadd5513bdc60b7ab7363d1670d59e64d2422123229962fa0', - '0.5.0_darwin_amd64' => '24d9758c873e9124e0ce266f118078f87ba8d8363ab16c2e59a3cd197b77e964', '0.5.0_linux_386' => '4b6147c30596a30361d4753d409f8a1af9518f54f5ed473a4c4ac973738ac0fd', '0.5.0_linux_amd64' => '161f2a8803e31550bd92a00e95a3a517aa949714c19d3124c46e56cfdc97b088', @@ -67,96 +51,3 @@ '0.5.2_windows_386' => '2e866812de16f1a6138a0fd1eebc76143f1314826e3b52597a55ac510ae94be6', '0.5.2_web_ui' => 'ad883aa52e1c0136ab1492bbcedad1210235f26d59719fb6de3ef6464f1ff3b1', } -default['consul']['source_revision'] = 'master' -default['consul']['use_packagecloud_repo'] = true - -# Service attributes -default['consul']['service_mode'] = 'bootstrap' -default['consul']['retry_on_join'] = false - -# In the cluster mode, set the default cluster size to 3 -default['consul']['bootstrap_expect'] = 3 -default['consul']['data_dir'] = '/var/lib/consul' -default['consul']['config_dir'] = '/etc/consul.d' -default['consul']['logfile'] = '/var/log/consul.log' -default['consul']['init_style'] = 'init' # 'init', 'runit', 'systemd' -case node['platform_family'] -when 'windows' - default['consul']['install_method'] = 'windows' - default['consul']['init_style'] = 'windows' - default['consul']['config_dir'] = "#{ENV['SystemDrive']}\\ProgramData\\consul\\config" - default['consul']['data_dir'] = "#{ENV['SystemDrive']}\\ProgramData\\consul\\data" - default['consul']['install_dir'] = "#{ChocolateyHelpers.chocolatey_install}\\lib\\consul.#{node['consul']['version']}" - default['consul']['etc_config_dir'] = "#{ChocolateyHelpers.chocolatey_install}\\lib\\consul.#{node['consul']['version']}\\tools" -when 'debian' - default['consul']['etc_config_dir'] = '/etc/default/consul' -when 'rhel' - default['consul']['etc_config_dir'] = '/etc/sysconfig/consul' -else - default['consul']['etc_config_dir'] = '/etc/sysconfig/consul' -end - -default['consul']['servers'] = [] - -case node['consul']['init_style'] -when 'runit' || 'systemd' - default['consul']['service_user'] = 'consul' - default['consul']['service_group'] = 'consul' -when 'windows' - default['consul']['service_user'] = 'Administrator' - default['consul']['service_group'] = 'Administrators' -else - default['consul']['service_user'] = 'root' - default['consul']['service_group'] = 'root' -end -default['consul']['system_account'] = false - -default['consul']['ports'] = { - 'dns' => 8600, - 'http' => 8500, - 'rpc' => 8400, - 'serf_lan' => 8301, - 'serf_wan' => 8302, - "server" => 8300, -} - -# Ubuntu Upstart Open Files Limit -default['consul']['files_soft_limit'] = 2048 -default['consul']['files_hard_limit'] = 4096 - -# Consul DataBag -default['consul']['data_bag'] = 'consul' -default['consul']['data_bag_encrypt_item'] = 'encrypt' - -# Gossip encryption -default['consul']['encrypt_enabled'] = false -default['consul']['encrypt'] = nil -# TLS support -default['consul']['verify_incoming'] = false -default['consul']['verify_outgoing'] = false -# Cert in pem format -default['consul']['ca_cert'] = nil -default['consul']['ca_path'] = "%{config_dir}/ca.pem" -default['consul']['cert_file'] = nil -default['consul']['cert_path'] = "%{config_dir}/cert.pem" -# Cert in pem format. It can be unique for each host -default['consul']['key_file'] = nil -default['consul']['key_file_path'] = "%{config_dir}/key.pem" - -# Optionally bind to a specific interface -default['consul']['bind_interface'] = nil -default['consul']['advertise_interface'] = nil -default['consul']['client_interface'] = nil - -# UI attributes -default['consul']['client_addr'] = '0.0.0.0' -default['consul']['serve_ui'] = false -default['consul']['extra_params'] = {} - -# Atlas support -default['consul']['atlas_autojoin'] = false -default['consul']['atlas_cluster'] = nil -default['consul']['atlas_token'] = nil - -# Init script startup delay -default['consul']['startup_sleep'] = 3 diff --git a/cluster.rb b/cluster.rb deleted file mode 100644 index 12a515af..00000000 --- a/cluster.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# -include_recipe 'chef-provisioning::default' - -num_quorum = ENV.fetch('CONSUL_QUORUM', 3) - -batch = machine_batch do - 1.upto(num_quorum).each do |index| - machine "consul-#{index}" do - recipe 'consul::default' - attributes(consul: { service_mode: 'cluster' }) - end - end -end - -include_recipe 'chef-sugar::default' -node.default['consul']['servers'] = batch.machines.each { |m| best_ip_for(m.node) } - -machine 'consul-ui' do - recipe 'consul::ui' - attributes(consul: { - service_mode: 'client', - servers: node['consul']['servers'] - }) -end diff --git a/libraries/consul.rb b/libraries/consul.rb deleted file mode 100644 index ca59249e..00000000 --- a/libraries/consul.rb +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2014-2015 John Bellone -# Copyright 2014-2015 Bloomberg Finance L.P. -# -# 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. -# - -class Chef - module Consul - class << self - def active_binary(node) - File.join(node['consul']['install_dir'], 'consul') - end - - def cached_archive(node) - File.join(Chef::Config[:file_cache_path], File.basename(remote_url(node))) - end - - def latest_binary(node) - File.join(install_path(node), 'consul') - end - - def remote_checksum(node) - node['consul']['checksums'].fetch(remote_filename(node)) - end - - def remote_filename(node) - [node['consul']['version'], node['os'], arch(node)].join('_') - end - - def remote_url(node) - node['consul']['base_url'] % { version: remote_filename(node) } - end - - def source_binary(node) - File.join(node['go']['gobin'], 'consul') - end - - def install_path(node) - File.join(['/opt', 'consul', node['consul']['version']]) - end - - private - - def arch(node) - node['kernel']['machine'] =~ /x86_64/ ? 'amd64' : '386' - end - end - end -end diff --git a/libraries/consul_config.rb b/libraries/consul_config.rb new file mode 100644 index 00000000..4b807119 --- /dev/null +++ b/libraries/consul_config.rb @@ -0,0 +1,166 @@ +# +# Cookbook: consul +# License: Apache 2.0 +# +# Copyright (C) 2014, 2015 Bloomberg Finance L.P. +# +require 'poise' + +class Chef::Resource::ConsulConfig < Chef::Resource + include Poise(fused: true) + provides(:consul_config) + + # @!attribute path + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + + # @!attribute owner + # @return [String] + attribute(:user, kind_of: String, default: 'consul') + + # @!attribute group + # @return [String] + attribute(:group, kind_of: String, default: 'consul') + + # @!attribute bag_name + # @return [String] + attribute(:bag_name, kind_of: String, default: 'consul') + + # @!attribute bag_item + # @return [String] + attribute(:bag_item, kind_of: String, default: 'secrets') + + # @see: http://www.consul.io/docs/agent/options.html + attribute(:acl_datacenter, kind_of: String) + attribute(:acl_default_policy, kind_of: String) + attribute(:acl_down_policy, kind_of: String) + attribute(:acl_master_token, kind_of: String) + attribute(:acl_token, kind_of: String) + attribute(:acl_ttl, kind_of: String) + attribute(:addresses, kind_of: [Hash, Mash]) + attribute(:advertise_addr, kind_of: String) + attribute(:bind_addr, kind_of: String) + attribute(:bootstrap, equal_to: [true, false], default: false) + attribute(:bootstrap_expect, kind_of: Integer, default: 3) + attribute(:ca_file, kind_of: String) + attribute(:cert_file, kind_of: String) + attribute(:check_update_interval, kind_of: String) + attribute(:client_addr, kind_of: String) + attribute(:data_dir, kind_of: String) + attribute(:datacenter, kind_of: String) + attribute(:disable_anonymous_signature, equal_to: [true, false], default: false) + attribute(:disable_remote_exec, equal_to: [true, false], default: false) + attribute(:disable_update_check, equal_to: [true, false], default: false) + attribute(:dns_config, kind_of: [Hash, Mash]) + attribute(:domain, kind_of: String) + attribute(:enable_debug, equal_to: [true, false], default: false) + attribute(:enable_syslog, equal_to: [true, false], default: false) + attribute(:encrypt, kind_of: String) + attribute(:key_file, kind_of: String) + attribute(:leave_on_terminate, equal_to: [true, false], default: false) + attribute(:log_level, equal_to: %w(INFO DEBUG WARN), default: 'INFO') + attribute(:node_name, kind_of: String) + attribute(:ports, kind_of: [Hash, Mash]) + attribute(:protocol, kind_of: String) + attribute(:recurser, kind_of: String) + attribute(:retry_interval, kind_of: Integer) + attribute(:server, equal_to: [true, false], default: true) + attribute(:server_name, kind_of: String) + attribute(:skip_leave_on_interrupt, equal_to: [true, false], default: false) + attribute(:start_join, kind_of: Array) + attribute(:statsd_addr, kind_of: String) + attribute(:statsite_addr, kind_of: String) + attribute(:syslog_facility, kind_of: String) + attribute(:ui_dir, kind_of: String) + attribute(:verify_incoming, equal_to: [true, false], default: false) + attribute(:verify_outgoing, equal_to: [true, false], default: false) + attribute(:verify_server_hostname, equal_to: [true, false], default: false) + attribute(:watches, kind_of: [Hash, Mash], default: {}) + + # Transforms the resource into a JSON format which matches the + # Consul service's configuration format. + def to_json + for_keeps = %i{acl_datacenter acl_default_policy acl_down_policy acl_master_token acl_token acl_ttl addresses advertise_addr bind_addr bootstrap bootstrap_expect check_update_interval client_addr data_dir datacenter disable_anonymous_signature disable_remote_exec disable_update_check dns_config domain enable_debug enable_syslog encrypt leave_on_terminate log_level node_name ports protocol recurser retry_interval server server_name skip_leave_on_interrupt start_join statsd_addr statsite_addr syslog_facility ui_dir verify_incoming verify_outgoing verify_server_hostname watches} + for_keeps << %i{ca_file cert_file key_file} if tls? + config = to_hash.keep_if do |k, v| + for_keeps.include?(k.to_sym) + end + JSON.pretty_generate(config, quirks_mode: true) + end + + def tls? + verify_incoming || verify_outgoing + end + + action(:create) do + notifying_block do + if new_resource.tls? + include_recipe 'chef-vault::default' + + directory ::File.dirname(new_resource.ca_file) do + recursive true + 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.user + group new_resource.group + end + + directory ::File.dirname(new_resource.cert_file) do + recursive true + end + + file new_resource.cert_file do + content item['certificate'] + mode '0644' + owner new_resource.user + group new_resource.group + end + + directory ::File.dirname(new_resource.key_file) do + recursive true + end + + file new_resource.key_file do + sensitive true + content item['private_key'] + mode '0640' + owner new_resource.user + group new_resource.group + end + end + + directory ::File.dirname(new_resource.path) do + recursive true + end + + file new_resource.path do + owner new_resource.user + group new_resource.group + content new_resource.to_json + mode '0640' + end + end + end + + action(:delete) do + notifying_block do + if new_resource.tls? + file new_resource.cert_file do + action :delete + end + + file new_resource.key_file do + action :delete + end + end + + file new_resource.path do + action :delete + end + end + end +end diff --git a/libraries/consul_definition.rb b/libraries/consul_definition.rb new file mode 100644 index 00000000..4de78106 --- /dev/null +++ b/libraries/consul_definition.rb @@ -0,0 +1,60 @@ +# +# Cookbook: consul +# License: Apache 2.0 +# +# Copyright (C) 2014, 2015 Bloomberg Finance L.P. +# +require 'poise' + +class Chef::Resource::ConsulDefinition < Chef::Resource + include Poise(fused: true) + provides(:consul_definition) + default_action(:create) + + # @!attribute path + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + + # @!attribute user + # @return [String] + attribute(:user, kind_of: String, default: 'consul') + + # @!attribute group + # @return [String] + attribute(:group, kind_of: String, default: 'consul') + + # @!attribute type + # @return [String] + attribute(:type, equal_to: %w{check service}) + + # @!attribute parameters + # @return [Hash] + attribute(:parameters, option_collector: true, default: {}) + + def to_json + JSON.pretty_generate(type => parameters, quicks_mode: true) + end + + action(:create) do + notifying_block do + directory ::File.dirname(new_resource.path) do + recursive true + end + + file new_resource.path do + owner new_resource.user + group new_resource.group + content new_resource.to_json + mode '0640' + end + end + end + + action(:delete) do + notifying_block do + file new_resource.path do + action :delete + end + end + end +end diff --git a/libraries/consul_service.rb b/libraries/consul_service.rb new file mode 100644 index 00000000..10bec896 --- /dev/null +++ b/libraries/consul_service.rb @@ -0,0 +1,179 @@ +# +# Cookbook: consul +# License: Apache 2.0 +# +# Copyright (C) 2014, 2015 Bloomberg Finance L.P. +# +require 'poise_service/service_mixin' + +# Resource for managing the Consul service on an instance. +# @since 1.0.0 +class Chef::Resource::ConsulService < Chef::Resource + include Poise + provides(:consul_service) + include PoiseService::ServiceMixin + actions(:create) + default_action(:create) + + # @!attribute version + # @return [String] + attribute(:version, kind_of: String, required: true) + + # @!attribute install_method + # @return [Symbol] + attribute(:install_method, default: 'binary', equal_to: %w{source binary package}) + + # @!attribute install_path + # @return [String] + attribute(:install_path, kind_of: String, default: '/srv') + + # @!attribute config_filename + # @return [String] + attribute(:config_file, kind_of: String, default: '/etc/consul.json') + + # @!attribute user + # @return [String] + attribute(:user, kind_of: String, default: 'consul') + + # @!attribute group + # @return [String] + attribute(:group, kind_of: String, default: 'consul') + + # @!attribute environment + # @return [String] + attribute(:environment, kind_of: Hash, default: lazy { default_environment }) + + # @!attribute package_name + # @return [String] + attribute(:package_name, kind_of: String, default: 'consul') + + # @!attribute binary_url + # @return [String] + attribute(:binary_url, kind_of: String) + + # @!attribute source_url + # @return [String] + attribute(:source_url, kind_of: String) + + # @!attribute data_dir + # @return [String] + attribute(:data_dir, kind_of: String, default: '/var/lib/consul') + + # @!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' + [version, node['os'], arch].join('_') + end +end + +# Provider for managing the Consul service on an instance. +# @since 1.0.0 +class Chef::Provider::ConsulService < Chef::Provider + include Poise + provides(:consul_service) + include PoiseService::ServiceMixin + + def action_create + 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 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 % { 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 + 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') + + link ::File.join(new_resource.install_path, 'bin', 'consul') do + to ::File.join(source_dir.path, "consul-#{new_resource.version}", 'consul') + end + end + end + end + + def action_enable + notifying_block do + directory new_resource.data_dir do + recursive true + owner new_resource.user + group new_resource.group + mode '0744' + end + + directory new_resource.config_dir do + recursive true + mode '0644' + end + end + super + end + + def action_disable + notifying_block do + file new_resource.filename do + action :delete + end + + directory new_resource.config_dir do + action :delete + end + + directory new_resource.data_dir 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 +end diff --git a/libraries/consul_ui.rb b/libraries/consul_ui.rb deleted file mode 100644 index 33194a8e..00000000 --- a/libraries/consul_ui.rb +++ /dev/null @@ -1,50 +0,0 @@ -# -# Copyright 2014-2015 John Bellone -# Copyright 2014-2015 Bloomberg Finance L.P. -# -# 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. -# - -class Chef - module ConsulUI - class << self - def active_path(node) - File.join(node['consul']['data_dir'], 'ui') - end - - def cached_archive(node) - File.join(Chef::Config[:file_cache_path], File.basename(remote_url(node))) - end - - def install_path(node) - File.join(['/opt', 'consul_ui', node['consul']['version']]) - end - - def latest_dist(node) - File.join(install_path(node), 'dist') - end - - def remote_filename(node) - [node['consul']['version'], 'web_ui'].join('_') - end - - def remote_checksum(node) - node['consul']['checksums'].fetch(remote_filename(node)) - end - - def remote_url(node) - node['consul']['base_url'] % { version: remote_filename(node) } - end - end - end -end diff --git a/libraries/consul_watch.rb b/libraries/consul_watch.rb new file mode 100644 index 00000000..9037fba8 --- /dev/null +++ b/libraries/consul_watch.rb @@ -0,0 +1,60 @@ +# +# Cookbook: consul +# License: Apache 2.0 +# +# Copyright (C) 2014, 2015 Bloomberg Finance L.P. +# +require 'poise' + +class Chef::Resource::ConsulWatch < Chef::Resource + include Poise(fused: true) + provides(:consul_watch) + default_action(:create) + + # @!attribute path + # @return [String] + attribute(:path, kind_of: String, name_attribute: true) + + # @!attribute user + # @return [String] + attribute(:user, kind_of: String, default: 'consul') + + # @!attribute group + # @return [String] + attribute(:group, kind_of: String, default: 'consul') + + # @!attribute type + # @return [String] + attribute(:type, equal_to: %w{checks event key keyprefix service}) + + # @!attribute parameters + # @return [Hash] + attribute(:parameters, option_collector: true, default: {}) + + def to_json + JSON.pretty_generate({ type: type }.merge(parameters), quicks_mode: true) + end + + action(:create) do + notifying_block do + directory ::File.dirname(new_resource.path) do + recursive true + end + + file new_resource.path do + owner new_resource.user + group new_resource.group + content new_resource.to_json + mode '0640' + end + end + end + + action(:delete) do + notifying_block do + file new_resource.path do + action :delete + end + end + end +end diff --git a/libraries/encrypt.rb b/libraries/encrypt.rb deleted file mode 100644 index 8dd65488..00000000 --- a/libraries/encrypt.rb +++ /dev/null @@ -1,21 +0,0 @@ -class Chef - class Recipe - # Don't throw the error if it doesn't exist - def consul_encrypted_dbi - begin - # loads the secret from /etc/chef/encrypted_data_bag_secret - Chef::EncryptedDataBagItem.load(node['consul']['data_bag'], node['consul']['data_bag_encrypt_item']) - rescue Net::HTTPServerException => e - raise e unless e.response.code == '404' - end - end - - def consul_dbi_key_with_node_default(dbi, key) - value = dbi[key] - Chef::Log.warn "Consul encrypt key=#{key} doesn't exist in the databag. \ -Reading it from node's attributes" if value.nil? - value ||= node['consul'][key] - value - end - end -end diff --git a/libraries/matchers.rb b/libraries/matchers.rb index 1485ac28..1f87917f 100644 --- a/libraries/matchers.rb +++ b/libraries/matchers.rb @@ -1,17 +1,25 @@ if defined?(ChefSpec) - def create_consul_service_def(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:consul_service_def, :create, resource_name) - end + %i{create delete}.each do |action| + define_method(:"#{action}_consul_client") do |resource_name| + ChefSpec::Matchers::ResourceMatcher.new(:consul_client, action, resource_name) + end - def delete_consul_service_def(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:consul_service_def, :delete, resource_name) - end + define_method(:"#{action}_consul_config") do |resource_name| + ChefSpec::Matchers::ResourceMatcher.new(:consul_config, action, resource_name) + end + + define_method(:"#{action}_consul_definition") do |resource_name| + ChefSpec::Matchers::ResourceMatcher.new(:consul_definition, action, resource_name) + end - def create_consul_event_watch_def(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:consul_event_watch_def, :create, resource_name) + define_method(:"#{action}_consul_watch") do |resource_name| + ChefSpec::Matchers::ResourceMatcher.new(:consul_watch, action, resource_name) + end end - def delete_consul_key_watch_def(resource_name) - ChefSpec::Matchers::ResourceMatcher.new(:consul_key_watch_def, :create, resource_name) + %i{enable disable stop start restart reload}.each do |action| + define_method(:"#{action}_consul_service") do |resource_name| + ChefSpec::Matchers::ResourceMatcher.new(:consul_service, action, resource_name) + end end end diff --git a/metadata.rb b/metadata.rb index 10f275de..ead34a8a 100644 --- a/metadata.rb +++ b/metadata.rb @@ -1,34 +1,21 @@ name 'consul' maintainer 'John Bellone' maintainer_email 'jbellone@bloomberg.net' -license 'Apache v2.0' -description 'Installs/Configures Consul client, server and UI.' -long_description 'Installs/Configures Consul client, server and UI.' -version '0.11.1' +license 'Apache 2.0' +description 'Application cookbook which installs and configures Consul.' +long_description 'Application cookbook which installs and configures Consul.' +version '1.0.0' -recipe 'consul', 'Installs and starts consul service.' -recipe 'consul::install_binary', 'Installs consul service from binary.' -recipe 'consul::install_source', 'Installs consul service from source.' -recipe 'consul::ui', 'Installs consul ui service.' +recipe 'consul::default', 'Installs, configures and starts the Consul service.' -%w(redhat centos).each do |name| - supports name, '~> 7.0' - supports name, '~> 6.5' -end - -supports 'ubuntu', '= 12.04' -supports 'ubuntu', '= 14.04' +supports 'centos', '>= 6.5' +supports 'redhat', '>= 6.5' +supports 'ubuntu', '>= 12.04' supports 'arch' -supports 'windows' - -recommends 'chef-provisioning' -depends 'libarchive', ">= 0.6.0" +depends 'chef-vault' +depends 'libartifact', '~> 1.3' depends 'golang', '~> 1.4' -depends 'runit' -depends 'yum-repoforge' -depends 'packagecloud' - -# for windows -depends 'windows' -depends "chocolatey" +depends 'poise', '~> 2.0' +depends 'poise-service' +depends 'selinux' diff --git a/providers/check_def.rb b/providers/check_def.rb deleted file mode 100644 index 15f40a2e..00000000 --- a/providers/check_def.rb +++ /dev/null @@ -1,44 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# - -use_inline_resources - -action :create do - file new_resource.path_with_name do - action :delete - only_if { new_resource.id } - end - - file new_resource.path do - if node['platform'] == 'windows' - rights :full_control, node['consul']['service_user'], :applies_to_children => true - else - user node['consul']['service_user'] - group node['consul']['service_group'] - end - mode 0600 - content new_resource.to_json - - action :create - end -end - -action :delete do - file new_resource.path do - action :delete - end -end diff --git a/providers/event_watch_def.rb b/providers/event_watch_def.rb deleted file mode 100644 index ca87cbc7..00000000 --- a/providers/event_watch_def.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# - -use_inline_resources - -action :create do - file new_resource.path do - if node['platform'] == 'windows' - rights :full_control, node['consul']['service_user'], :applies_to_children => true - else - user node['consul']['service_user'] - group node['consul']['service_group'] - end - mode 0600 - content new_resource.to_json - - action :create - end -end - -action :delete do - file new_resource.path do - action :delete - end -end diff --git a/providers/key_watch_def.rb b/providers/key_watch_def.rb deleted file mode 100644 index ca87cbc7..00000000 --- a/providers/key_watch_def.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# - -use_inline_resources - -action :create do - file new_resource.path do - if node['platform'] == 'windows' - rights :full_control, node['consul']['service_user'], :applies_to_children => true - else - user node['consul']['service_user'] - group node['consul']['service_group'] - end - mode 0600 - content new_resource.to_json - - action :create - end -end - -action :delete do - file new_resource.path do - action :delete - end -end diff --git a/providers/service_def.rb b/providers/service_def.rb deleted file mode 100644 index 112991ce..00000000 --- a/providers/service_def.rb +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# - -use_inline_resources if defined? use_inline_resources - -def set_updated - r = yield - new_resource.updated_by_last_action(r.updated_by_last_action?) -end - -action :create do - set_updated do - file new_resource.path do - if node['platform'] == 'windows' - rights :full_control, node['consul']['service_user'], :applies_to_children => true - else - user node['consul']['service_user'] - group node['consul']['service_group'] - end - mode 0600 - content new_resource.to_json - action :create - end - end -end - -action :delete do - set_updated do - file new_resource.path do - action :delete - end - end -end diff --git a/providers/service_watch_def.rb b/providers/service_watch_def.rb deleted file mode 100644 index ca87cbc7..00000000 --- a/providers/service_watch_def.rb +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# - -use_inline_resources - -action :create do - file new_resource.path do - if node['platform'] == 'windows' - rights :full_control, node['consul']['service_user'], :applies_to_children => true - else - user node['consul']['service_user'] - group node['consul']['service_group'] - end - mode 0600 - content new_resource.to_json - - action :create - end -end - -action :delete do - file new_resource.path do - action :delete - end -end diff --git a/providers/services_watch_def.rb b/providers/services_watch_def.rb deleted file mode 100644 index 9f9506a6..00000000 --- a/providers/services_watch_def.rb +++ /dev/null @@ -1,18 +0,0 @@ -use_inline_resources - -action :create do - file new_resource.path do - user node['consul']['service_user'] - group node['consul']['service_group'] - mode 0600 - content new_resource.to_json - - action :create - end -end - -action :delete do - file new_resource.path do - action :delete - end -end diff --git a/recipes/default.rb b/recipes/default.rb index 87e6ed87..452f31c0 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -1,31 +1,30 @@ # -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. +# Cookbook: consul +# License: Apache 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. +# Copyright 2014, 2015 Bloomberg Finance L.P. # +include_recipe 'selinux::permissive' -case node['consul']['install_method'] -when 'binary' - include_recipe 'consul::install_binary' -when 'source' - include_recipe 'consul::install_source' -when 'packages' - include_recipe 'consul::install_packages' -when 'windows' - include_recipe 'consul::install_windows' -else - Chef::Application.fatal!("[consul::default] unknown install method, method=#{node['consul']['install_method']}") +poise_service_user node['consul']['service_user'] do + group node['consul']['service_group'] + action :create end -include_recipe 'consul::service' +config = consul_config node['consul']['service_name'] do |r| + user node['consul']['service_user'] + group node['consul']['service_group'] + + node['consul']['config'].each_pair { |k, v| r.send(k, v) } +end + +consul_service node['consul']['service_name'] do |r| + user node['consul']['service_user'] + group node['consul']['service_group'] + version node['consul']['version'] + config_file config.path + + node['consul']['service'].each_pair { |k, v| r.send(k, v) } + subscribes :restart, "consul_config[#{config.name}]", :delayed + action [:create, :enable] +end diff --git a/recipes/install_binary.rb b/recipes/install_binary.rb deleted file mode 100644 index 5c244ede..00000000 --- a/recipes/install_binary.rb +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# - -include_recipe 'libarchive::default' - -archive = remote_file Chef::Consul.cached_archive(node) do - source Chef::Consul.remote_url(node) - checksum Chef::Consul.remote_checksum(node) -end - -libarchive_file 'consul.zip' do - path archive.path - extract_to Chef::Consul.install_path(node) - extract_options :no_overwrite - - action :extract -end - -directory File.basename(Chef::Consul.active_binary(node)) do - recursive true - action :create -end - -# JW TODO: Remove after next major release. -file Chef::Consul.active_binary(node) do - action :delete - not_if "test -L #{Chef::Consul.active_binary(node)}" -end - -link Chef::Consul.active_binary(node) do - to Chef::Consul.latest_binary(node) -end diff --git a/recipes/install_packages.rb b/recipes/install_packages.rb deleted file mode 100644 index 3f5f70fa..00000000 --- a/recipes/install_packages.rb +++ /dev/null @@ -1,32 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# -# NOTE: This is only supported for Ubuntu 12.04LTS and 14.04LTS. - -if node['consul']['use_packagecloud_repo'] - - packagecloud_repo "darron/consul" do - type "deb" - end - - packagecloud_repo "darron/consul-webui" do - type "deb" - end - -end - -package 'consul' -package 'consul-webui' diff --git a/recipes/install_source.rb b/recipes/install_source.rb deleted file mode 100644 index d0fec1e2..00000000 --- a/recipes/install_source.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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. -# - -include_recipe 'golang::default' - -directory File.join(node['go']['gopath'], 'src/github.com/hashicorp') do - owner 'root' - group 'root' - mode '00755' - recursive true - action :create -end - -git File.join(node['go']['gopath'], '/src/github.com/hashicorp/consul') do - repository 'https://github.com/hashicorp/consul.git' - reference node['consul']['source_revision'] - action :checkout -end - -golang_package 'github.com/hashicorp/consul' do - action :install -end - -directory File.basename(Chef::Consul.active_binary(node)) do - recursive true - action :create -end - -link Chef::Consul.active_binary(node) do - to Chef::Consul.source_binary(node) -end diff --git a/recipes/install_windows.rb b/recipes/install_windows.rb deleted file mode 100644 index ba83397d..00000000 --- a/recipes/install_windows.rb +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2015 Rohit Amarnath -# Copyright 2015 Full 360 Inc. -# -# 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. -# - -if node['platform'] == 'windows' - - include_recipe 'chocolatey::default' - - chocolatey 'consul' do - version node['consul']['version'] - source node['consul']['choco_source'] - end -end diff --git a/recipes/service.rb b/recipes/service.rb deleted file mode 100644 index 8dc9d30e..00000000 --- a/recipes/service.rb +++ /dev/null @@ -1,306 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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 'json' - -# Configure directories -consul_directories = [] -consul_directories << node['consul']['data_dir'] -consul_directories << node['consul']['config_dir'] - -case node['consul']['init_style'] -when 'runit' - include_recipe 'runit::default' - consul_directories << '/var/log/consul' -when 'windows' - # already added, move along -else - consul_directories << '/var/lib/consul' -end - - -# Select service user & group -consul_user = node['consul']['service_user'] -consul_group = node['consul']['service_group'] - -# Create service user -case node['consul']['init_style'] -when 'windows' - user "consul service user: #{consul_user}" do - not_if { consul_user == 'Administrator' } - username consul_user - comment 'consul service user' - end -else - user "consul service user: #{consul_user}" do - not_if { consul_user == 'root' } - username consul_user - home '/dev/null' - shell '/bin/false' - system node['consul']['system_account'] - comment 'consul service user' - end -end - -# Create service group -group "consul service group: #{consul_group}" do - not_if { consul_group == 'root' && node['platform'] != 'windows'} - not_if { consul_group == 'Administrators' && node['platform'] == 'windows'} - group_name consul_group - members consul_user - system node['consul']['system_account'] - append true -end - -# Create service directories -consul_directories.uniq.each do |dirname| - directory dirname do - if node['platform'] == 'windows' - rights :full_control, node['consul']['service_user'], :applies_to_children => true - recursive true - else - user consul_user - group consul_group - end - mode 0755 - end - - execute "chown -R #{consul_user}:#{consul_group} #{dirname}" do - not_if { node['platform'] == 'windows' } - only_if do - Etc.getpwuid(File.stat(dirname).uid).name != consul_user or - Etc.getgrgid(File.stat(dirname).gid).name != consul_group - end - end -end - -# Determine service params -service_config = JSON.parse(node['consul']['extra_params'].to_json) -service_config['data_dir'] = node['consul']['data_dir'] -num_cluster = node['consul']['bootstrap_expect'].to_i -join_mode = node['consul']['retry_on_join'] ? 'retry_join' : 'start_join' - -case node['consul']['service_mode'] -when 'bootstrap' - service_config['server'] = true - service_config['bootstrap'] = true -when 'cluster' - service_config['server'] = true - if num_cluster > 1 - service_config['bootstrap_expect'] = num_cluster - service_config[join_mode] = node['consul']['servers'] - else - service_config['bootstrap'] = true - end -when 'server' - service_config['server'] = true - service_config[join_mode] = node['consul']['servers'] -when 'client' - service_config[join_mode] = node['consul']['servers'] -else - Chef::Application.fatal! %Q(node['consul']['service_mode'] must be "bootstrap", "cluster", "server", or "client") -end - -iface_addr_map = { - bind_interface: :bind_addr, - advertise_interface: :advertise_addr, - client_interface: :client_addr -} - -iface_addr_map.each_pair do |interface,addr| - next unless node['consul'][interface] - - if node["network"]["interfaces"][node['consul'][interface]] - ip = node["network"]["interfaces"][node['consul'][interface]]["addresses"].detect{|k,v| v[:family] == "inet"}.first - node.default['consul'][addr] = ip - else - Chef::Application.fatal!("Interface specified in node['consul'][#{interface}] does not exist!") - end -end - -if node['consul']['serve_ui'] - service_config['ui_dir'] = Chef::ConsulUI.active_path(node) - service_config['client_addr'] = node['consul']['client_addr'] -end - -additional_options = ['recursor', 'statsd_addr', 'leave_on_terminate', 'rejoin_after_leave', 'disable_remote_exec', 'acl_datacenter', 'acl_token', 'acl_default_policy', 'acl_down_policy', 'acl_master_token'] - -additional_options.each do |option| - if node['consul'][option] - service_config[option] = node['consul'][option] - end -end - -copy_params = [ - :bind_addr, :datacenter, :domain, :log_level, :node_name, :advertise_addr, :ports, :enable_syslog, :statsd_addr -] -copy_params.each do |key| - if node['consul'][key] - if key == :ports - Chef::Application.fatal! 'node[:consul][:ports] must be a Hash' unless node[:consul][key].kind_of?(Hash) - end - - service_config[key] = node['consul'][key] - end -end - -dbi = nil -# Gossip encryption -if node.consul.encrypt_enabled - # Fetch the databag only once, and use empty hash if it doesn't exists - dbi = consul_encrypted_dbi || {} - secret = consul_dbi_key_with_node_default(dbi, 'encrypt') - raise "Consul encrypt key is empty or nil" if secret.nil? or secret.empty? - service_config['encrypt'] = secret -else - # for backward compatibilty - service_config['encrypt'] = node.consul.encrypt unless node.consul.encrypt.nil? -end - -# TLS encryption -if node.consul.verify_incoming || node.consul.verify_outgoing - dbi = consul_encrypted_dbi || {} if dbi.nil? - service_config['verify_outgoing'] = node.consul.verify_outgoing - service_config['verify_incoming'] = node.consul.verify_incoming - - ca_path = node.consul.ca_path % { config_dir: node.consul.config_dir } - service_config['ca_file'] = ca_path - - cert_path = node.consul.cert_path % { config_dir: node.consul.config_dir } - service_config['cert_file'] = cert_path - - key_path = node.consul.key_file_path % { config_dir: node.consul.config_dir } - service_config['key_file'] = key_path - - # Search for key_file_hostname since key and cert file can be unique/host - key_content = dbi['key_file_' + node.fqdn] || consul_dbi_key_with_node_default(dbi, 'key_file') - cert_content = dbi['cert_file_' + node.fqdn] || consul_dbi_key_with_node_default(dbi, 'cert_file') - ca_content = consul_dbi_key_with_node_default(dbi, 'ca_cert') - - # Save the certs if exists - {ca_path => ca_content, key_path => key_content, cert_path => cert_content}.each do |path, content| - unless content.nil? or content.empty? - file path do - user consul_user - group consul_group - mode 0600 - action :create - content content - end - end - end -end - -# Atlas integration -if node['consul']['atlas_autojoin'] or node['consul']['atlas_token'] - cluster = node['consul']['atlas_cluster'] - token = node['consul']['atlas_token'] - raise "atlas_cluster is empty or nil" if cluster.empty? or cluster.nil? - raise "atlas_token is empty or nil" if token.empty? or token.nil? - service_config['atlas_infrastructure'] = cluster - service_config['atlas_join'] = node['consul']['atlas_autojoin'] - service_config['atlas_token'] = token -end - -consul_config_filename = File.join(node['consul']['config_dir'], 'default.json') - -file consul_config_filename do - user consul_user - group consul_group - mode 0600 - action :create - content JSON.pretty_generate(service_config, quirks_mode: true) - # https://github.com/johnbellone/consul-cookbook/issues/72 - notifies :restart, "service[consul]" -end - -case node['consul']['init_style'] -when 'init' - if platform?("ubuntu") - init_file = '/etc/init/consul.conf' - init_tmpl = 'consul.conf.erb' - init_mode = 0644 - else - init_file = '/etc/init.d/consul' - init_tmpl = 'consul-init.erb' - init_mode = 0755 - end - - template node['consul']['etc_config_dir'] do - source 'consul-sysconfig.erb' - mode 0644 - notifies :create, "template[#{init_file}]", :immediately - end - - template init_file do - source init_tmpl - mode init_mode - variables( - consul_logfile: node['consul']['logfile'], - startup_sleep: node['consul']['startup_sleep'], - soft_limit: node['consul']['files_soft_limit'], - hard_limit: node['consul']['files_hard_limit'] - ) - notifies :restart, 'service[consul]', :immediately - end - - service 'consul' do - provider Chef::Provider::Service::Upstart if platform?("ubuntu") - supports status: true, restart: true, reload: true - action [:enable, :start] - subscribes :restart, "file[#{consul_config_filename}]" - subscribes :restart, "link[#{Chef::Consul.active_binary(node)}]" - end -when 'runit' - runit_service 'consul' do - supports status: true, restart: true, reload: true - action [:enable, :start] - subscribes :restart, "file[#{consul_config_filename}]" - subscribes :restart, "link[#{Chef::Consul.active_binary(node)}]" - log true - end - - service 'consul' do - supports status: true, restart: true, reload: true - reload_command "'#{node['runit']['sv_bin']}' hup consul" - end -when 'systemd' - template node['consul']['etc_config_dir'] do - source 'consul-sysconfig.erb' - mode 0644 - notifies :create, "template[/etc/systemd/system/consul.service]", :immediately - end - - template '/etc/systemd/system/consul.service' do - source 'consul-systemd.erb' - mode 0644 - notifies :restart, 'service[consul]', :immediately - end - - service 'consul' do - supports status: true, restart: true, reload: true - action [:enable, :start] - subscribes :restart, "file[#{consul_config_filename}]" - subscribes :restart, "link[#{Chef::Consul.active_binary(node)}]" - end -when 'windows' - # Windows service for consul has been create by Chocolatey and - # config is managed by the chocolatey package - service 'consul' do - subscribes :restart, "file[#{consul_config_filename}]" - end -end diff --git a/recipes/ui.rb b/recipes/ui.rb deleted file mode 100644 index 6133f1a3..00000000 --- a/recipes/ui.rb +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2014 Benny Wong -# -# 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. -# - -if node['platform'] == 'windows' - Chef::Log.error "UI Installation not supported for Windows" -else - include_recipe 'libarchive::default' - - archive = remote_file Chef::ConsulUI.cached_archive(node) do - source Chef::ConsulUI.remote_url(node) - checksum Chef::ConsulUI.remote_checksum(node) - end - - libarchive_file 'consul_ui.zip' do - path archive.path - extract_to Chef::ConsulUI.install_path(node) - extract_options :no_overwrite - - action :extract - end - - # JW TODO: Remove after next major release. - directory Chef::ConsulUI.active_path(node) do - action :delete - recursive true - not_if "test -L #{Chef::ConsulUI.active_path(node)}" - end - - link Chef::ConsulUI.active_path(node) do - to Chef::ConsulUI.latest_dist(node) - end -end diff --git a/resources/check_def.rb b/resources/check_def.rb deleted file mode 100644 index 1efb45ff..00000000 --- a/resources/check_def.rb +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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 'json' - -actions :create, :delete -default_action :create - -attribute :name, name_attribute: true, required: true, kind_of: String -attribute :id, kind_of: String -attribute :script, kind_of: String -attribute :http, kind_of: String -attribute :ttl, kind_of: String -attribute :interval, kind_of: String -attribute :notes, kind_of: String - -def path - ::File.join(node['consul']['config_dir'], "check-#{id || name}.json") -end - -def path_with_name - ::File.join(node['consul']['config_dir'], "check-#{name}.json") -end - -def to_json - JSON.pretty_generate(to_hash) -end - -def to_hash - hash = { - check: { - name: name - } - } - hash[:check][:id] = id unless id.nil? - hash[:check][:script] = script unless script.nil? - hash[:check][:ttl] = ttl unless ttl.nil? - hash[:check][:http] = http unless http.nil? - hash[:check][:interval] = interval unless interval.nil? - hash[:check][:notes] = notes unless notes.nil? - hash -end diff --git a/resources/event_watch_def.rb b/resources/event_watch_def.rb deleted file mode 100644 index 1772d76f..00000000 --- a/resources/event_watch_def.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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 'json' - -actions :create, :delete -default_action :create - -attribute :name, name_attribute: true, required: true, kind_of: String -attribute :handler, required: true, kind_of: String - -def path - ::File.join(node['consul']['config_dir'], "event-watch-#{name}.json") -end - -def to_json - JSON.pretty_generate(to_hash) -end - -def to_hash - hash = { - watches:[ - { - type: 'event', - name: name, - handler: handler - } - ] - } - hash -end diff --git a/resources/key_watch_def.rb b/resources/key_watch_def.rb deleted file mode 100644 index 4d698fba..00000000 --- a/resources/key_watch_def.rb +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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 'json' - -actions :create, :delete -default_action :create - -attribute :name, name_attribute: true, required: true, kind_of: String -attribute :key, required: true, kind_of: String -attribute :handler, required: true, kind_of: String - -def path - ::File.join(node['consul']['config_dir'], "key-watch-#{name}.json") -end - -def to_json - JSON.pretty_generate(to_hash) -end - -def to_hash - hash = { - watches:[ - { - type: 'key', - key: key, - handler: handler - } - ] - } - hash -end diff --git a/resources/service_def.rb b/resources/service_def.rb deleted file mode 100644 index 33b972d1..00000000 --- a/resources/service_def.rb +++ /dev/null @@ -1,72 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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 'json' - -actions :create, :delete -default_action :create - -attribute :name, name_attribute: true, required: true, kind_of: String -attribute :id, kind_of: String -attribute :port, kind_of: Integer -attribute :tags, kind_of: Array, default: nil -attribute :check, kind_of: Hash, default: nil, callbacks: { - 'Checks must be a hash containing either a `:ttl` key/value or a `:script/:http` and `:interval` key/value' => ->(check) do - Chef::Resource::ConsulServiceDef.validate_check(check) - end -} - -def self.validate_check(check) - unless check.is_a?(Hash) - return false - end - - if check.key?(:ttl) && ( [:interval, :script, :http].none?{|key| check.key?(key)} ) - return true - end - - if check.key?(:interval) && check.key?(:script) - return true - end - - if check.key?(:interval) && check.key?(:http) - return true - end - - false -end - -def path - ::File.join(node['consul']['config_dir'], "service-#{id || name}.json") -end - -def to_json - JSON.pretty_generate(to_hash) -end - -def to_hash - hash = { - service: { - name: name - } - } - hash[:service][:id] = id unless id.nil? - hash[:service][:port] = port unless port.nil? - hash[:service][:tags] = tags unless tags.nil? - hash[:service][:check] = check unless check.nil? - hash -end diff --git a/resources/service_watch_def.rb b/resources/service_watch_def.rb deleted file mode 100644 index 4f469aa0..00000000 --- a/resources/service_watch_def.rb +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright 2014 John Bellone -# Copyright 2014 Bloomberg Finance L.P. -# -# 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 'json' - -actions :create, :delete -default_action :create - -attribute :service, name_attribute: true, required: true, kind_of: String -attribute :handler, required: true, kind_of: String -attribute :passingonly, required: false, kind_of: [TrueClass, FalseClass] -attribute :tag, required: false, kind_of: String - -def path - ::File.join(node['consul']['config_dir'], "service-watch-#{name}.json") -end - -def to_json - JSON.pretty_generate({'watches'=> [to_hash]}) -end - -def to_hash - hash = { - type: "service" - } - hash[:service] = name - hash[:handler] = handler unless handler.nil? - hash[:tag] = tag unless tag.nil? - hash[:passingonly] = passingonly unless passingonly.nil? - hash -end diff --git a/resources/services_watch_def.rb b/resources/services_watch_def.rb deleted file mode 100644 index d1fdaf19..00000000 --- a/resources/services_watch_def.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'json' - -actions :create, :delete -default_action :create - -attribute :name, name_attribute: true, required: true, kind_of: String -attribute :handler, required: true, kind_of: String - -def path - ::File.join(node['consul']['config_dir'], "watch-services.json") -end - -def to_json - JSON.pretty_generate(to_hash) -end - -def to_hash - hash = { - watches:[ - { - type: 'services', - handler: handler - } - ] - } - hash -end diff --git a/spec/fixtures/cookbooks/consul_spec/metadata.rb b/spec/fixtures/cookbooks/consul_spec/metadata.rb deleted file mode 100644 index a40a72e5..00000000 --- a/spec/fixtures/cookbooks/consul_spec/metadata.rb +++ /dev/null @@ -1,3 +0,0 @@ -name 'consul_spec' - -depends 'consul' diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_with_id_create.rb b/spec/fixtures/cookbooks/consul_spec/recipes/check_def_with_id_create.rb deleted file mode 100644 index ad49a705..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_with_id_create.rb +++ /dev/null @@ -1,9 +0,0 @@ -include_recipe "consul" -consul_check_def "dummy name" do - id "uniqueid" - script "curl http://localhost:8888/health" - interval "10s" - ttl "50s" - http "http://localhost:8888/health" - notes "Blahblah" -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_with_id_delete.rb b/spec/fixtures/cookbooks/consul_spec/recipes/check_def_with_id_delete.rb deleted file mode 100644 index 0ebaa855..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_with_id_delete.rb +++ /dev/null @@ -1,5 +0,0 @@ -include_recipe "consul" -consul_check_def "dummy name" do - id "uniqueid" - action :delete -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_without_id_create.rb b/spec/fixtures/cookbooks/consul_spec/recipes/check_def_without_id_create.rb deleted file mode 100644 index 563686a5..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_without_id_create.rb +++ /dev/null @@ -1,7 +0,0 @@ -include_recipe "consul" -consul_check_def "dummy name" do - script "curl http://localhost:8888/health" - interval "10s" - ttl "50s" - notes "Blahblah" -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_without_id_delete.rb b/spec/fixtures/cookbooks/consul_spec/recipes/check_def_without_id_delete.rb deleted file mode 100644 index 7d314cec..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/check_def_without_id_delete.rb +++ /dev/null @@ -1,4 +0,0 @@ -include_recipe "consul" -consul_check_def "dummy name" do - action :delete -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/event_watch_create.rb b/spec/fixtures/cookbooks/consul_spec/recipes/event_watch_create.rb deleted file mode 100644 index fad2acf5..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/event_watch_create.rb +++ /dev/null @@ -1,4 +0,0 @@ -include_recipe "consul" -consul_event_watch_def "dummy" do - handler "chef-client" -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/event_watch_delete.rb b/spec/fixtures/cookbooks/consul_spec/recipes/event_watch_delete.rb deleted file mode 100644 index ff1318c2..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/event_watch_delete.rb +++ /dev/null @@ -1,4 +0,0 @@ -include_recipe "consul" -consul_event_watch_def "dummy" do - action :delete -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/key_watch_create.rb b/spec/fixtures/cookbooks/consul_spec/recipes/key_watch_create.rb deleted file mode 100644 index 26c6a9b8..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/key_watch_create.rb +++ /dev/null @@ -1,5 +0,0 @@ -include_recipe "consul" -consul_key_watch_def "dummy" do - key "/key/path" - handler "chef-client" -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/key_watch_delete.rb b/spec/fixtures/cookbooks/consul_spec/recipes/key_watch_delete.rb deleted file mode 100644 index 679f115a..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/key_watch_delete.rb +++ /dev/null @@ -1,4 +0,0 @@ -include_recipe "consul" -consul_key_watch_def "dummy" do - action :delete -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/service_def_create.rb b/spec/fixtures/cookbooks/consul_spec/recipes/service_def_create.rb deleted file mode 100644 index 6b6be73e..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/service_def_create.rb +++ /dev/null @@ -1,7 +0,0 @@ -include_recipe "consul" -consul_service_def "dummy" do - id "uniqueid" - port 8888 - tags ['releases', 'v1'] - check :interval => "10s", :script => "curl http://localhost:8888/health" -end diff --git a/spec/fixtures/cookbooks/consul_spec/recipes/service_def_delete.rb b/spec/fixtures/cookbooks/consul_spec/recipes/service_def_delete.rb deleted file mode 100644 index 8a78f6a5..00000000 --- a/spec/fixtures/cookbooks/consul_spec/recipes/service_def_delete.rb +++ /dev/null @@ -1,5 +0,0 @@ -include_recipe "consul" -consul_service_def "dummy" do - id "uniqueid" - action :delete -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb deleted file mode 100644 index ceae4944..00000000 --- a/spec/spec_helper.rb +++ /dev/null @@ -1,97 +0,0 @@ -require 'chefspec' -require 'chefspec/berkshelf' -require 'chefspec/cacher' -require 'chefspec/server' -require 'coveralls' - -require_relative 'support/matchers' - -Coveralls.wear! - -RSpec.configure do |config| - config.color = true - config.alias_example_group_to :describe_recipe, type: :recipe - config.alias_example_group_to :describe_resource, type: :resource - - config.filter_run :focus - config.run_all_when_everything_filtered = true - - Kernel.srand config.seed - config.order = :random - - if config.files_to_run.one? - config.default_formatter = 'doc' - end - - config.expect_with :rspec do |expectations| - expectations.syntax = :expect - end - - config.mock_with :rspec do |mocks| - mocks.syntax = :expect - mocks.verify_partial_doubles = true - end -end - -at_exit { ChefSpec::Coverage.report! } - -RSpec.shared_context 'recipe tests', type: :recipe do - before do - stub_command("test -L /usr/local/bin/consul").and_return(true) - end - - let(:chef_run) { ChefSpec::Runner.new(node_attributes).converge(described_recipe) } - - def node_attributes - { - platform: 'ubuntu', - version: '12.04' - } - end -end - -RSpec.shared_context "resource tests", type: :resource do - before do - stub_command("test -L /usr/local/bin/consul").and_return(true) - end - - let(:chef_run) do - ChefSpec::SoloRunner.new(node_attributes.merge(step_into)).converge(example_recipe) - end - - let(:example_recipe) do - fail %( -Please specify the name of the test recipe that executes your recipe: - - let(:example_recipe) do - "consul_spec::service_def" - end - -) - end - - let(:node) { chef_run.node } - - def node_attributes - { - platform: 'ubuntu', - version: '12.04' - } - end - - let(:step_into) do - { step_into: [cookbook_name] } - end - - def cookbook_recipe_names - described_recipe.split("::", 2) - end - - def cookbook_name - cookbook_recipe_names.first - end - - def recipe_name - cookbook_recipe_names.last - end -end diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb deleted file mode 100644 index 422b8a5f..00000000 --- a/spec/support/matchers.rb +++ /dev/null @@ -1,35 +0,0 @@ -def start_runit_service(name) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :start, name) -end - -def stop_runit_service(name) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :stop, name) -end - -def enable_runit_service(name) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :enable, name) -end - -def disable_runit_service(name) - ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :disable, name) -end - -def install_golang_package(name) - ChefSpec::Matchers::ResourceMatcher.new(:golang_package, :install, name) -end - -def uninstall_golang_package(name) - ChefSpec::Matchers::ResourceMatcher.new(:golang_package, :uninstall, name) -end - -def put_ark(name) - ChefSpec::Matchers::ResourceMatcher.new(:ark, :put, name) -end - -def dump_ark(name) - ChefSpec::Matchers::ResourceMatcher.new(:ark, :dump, name) -end - -def install_ark(name) - ChefSpec::Matchers::ResourceMatcher.new(:ark, :install, name) -end diff --git a/spec/unit/resources/check_def_spec.rb b/spec/unit/resources/check_def_spec.rb deleted file mode 100644 index 0e037421..00000000 --- a/spec/unit/resources/check_def_spec.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'spec_helper' -require 'chefspec/berkshelf' - -describe_resource "consul_check_def" do - describe "with id" do - let(:check_def_path) { "/etc/consul.d/check-uniqueid.json" } - - describe "create" do - let(:example_recipe) { "consul_spec::check_def_with_id_create" } - - it "removes any check previously registered by name" do - expect(chef_run).to delete_file("/etc/consul.d/check-dummy name.json") - end - - it "register the check" do - ['"name": "dummy name"', - '"id": "uniqueid"', - '"script": "curl http://localhost:8888/health"', - '"http": "http://localhost:8888/health"', - '"interval": "10s"', - '"ttl": "50s"', - '"notes": "Blahblah"'].each do |content| - expect(chef_run).to render_file(check_def_path) - .with_content(content) - end - end - end - - describe "delete" do - let(:example_recipe) { "consul_spec::check_def_with_id_delete" } - - it "de-register the check" do - expect(chef_run).to delete_file(check_def_path) - end - end - end - - describe "without id" do - let(:check_def_path) { "/etc/consul.d/check-dummy name.json" } - - describe "create" do - let(:example_recipe) { "consul_spec::check_def_without_id_create" } - - it "does not remove checks previously registered by name" do - expect(chef_run).not_to delete_file("/etc/consul.d/check-dummy name.json") - end - - it "register the check" do - ['"name": "dummy name"', '"script": "curl http://localhost:8888/health"', - '"interval": "10s"', '"ttl": "50s"', '"notes": "Blahblah"'].each do |content| - expect(chef_run).to render_file(check_def_path) - .with_content(content) - end - end - end - - describe "delete" do - let(:example_recipe) { "consul_spec::check_def_without_id_delete" } - - it "de-register the check" do - expect(chef_run).to delete_file(check_def_path) - end - end - end -end diff --git a/spec/unit/resources/event_watch_def_spec.rb b/spec/unit/resources/event_watch_def_spec.rb deleted file mode 100644 index 040cc377..00000000 --- a/spec/unit/resources/event_watch_def_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' -require 'chefspec/berkshelf' - -describe_resource "consul_event_watch_def" do - let(:service_def_path) { "/etc/consul.d/event-watch-dummy.json" } - - describe "create" do - let(:example_recipe) { "consul_spec::event_watch_create" } - - it "register the service" do - ['"name": "dummy"', '"type": "event"', - '"handler": "chef-client"'].each do |content| - expect(chef_run).to render_file(service_def_path) - .with_content(content) - end - end - end - - describe "delete" do - let(:example_recipe) { "consul_spec::event_watch_delete" } - - it "de-register the service" do - expect(chef_run).to delete_file(service_def_path) - expect(chef_run.file(service_def_path)) - end - end -end diff --git a/spec/unit/resources/key_watch_def_spec.rb b/spec/unit/resources/key_watch_def_spec.rb deleted file mode 100644 index c807fa0c..00000000 --- a/spec/unit/resources/key_watch_def_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'spec_helper' -require 'chefspec/berkshelf' - -describe_resource "consul_key_watch_def" do - let(:service_def_path) { "/etc/consul.d/key-watch-dummy.json" } - - describe "create" do - let(:example_recipe) { "consul_spec::key_watch_create" } - - it "register the service" do - ['"key": "/key/path"', '"type": "key"', - '"handler": "chef-client"'].each do |content| - expect(chef_run).to render_file(service_def_path) - .with_content(content) - end - end - end - - describe "delete" do - let(:example_recipe) { "consul_spec::key_watch_delete" } - - it "de-register the service" do - expect(chef_run).to delete_file(service_def_path) - expect(chef_run.file(service_def_path)) - end - end -end diff --git a/spec/unit/resources/service_def_spec.rb b/spec/unit/resources/service_def_spec.rb deleted file mode 100644 index bc139d98..00000000 --- a/spec/unit/resources/service_def_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -require 'spec_helper' -require 'chefspec/berkshelf' - -describe_resource "consul_service_def" do - let(:service_def_path) { "/etc/consul.d/service-uniqueid.json" } - - describe "create" do - let(:example_recipe) { "consul_spec::service_def_create" } - - it "register the service" do - ['"name": "dummy"', '"port": 8888', - '"script": "curl http://localhost:8888/health"'].each do |content| - expect(chef_run).to render_file(service_def_path) - .with_content(content) - end - end - end - - describe "delete" do - let(:example_recipe) { "consul_spec::service_def_delete" } - - it "de-register the service" do - expect(chef_run).to delete_file(service_def_path) - end - end -end diff --git a/templates/default/consul-init.erb b/templates/default/consul-init.erb deleted file mode 100644 index 14fc07e7..00000000 --- a/templates/default/consul-init.erb +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/bash -### BEGIN INIT INFO -# Provides: consul -# Required-Start: $network $remote_fs $syslog -# Required-Stop: $network $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Consul Service Discovery Platform -# Description: Consul is a tool for discovering and configuring services -# in your infrastructure. It provides several key features: -# * Service Discovery -# * Health Checking -# * Key/Valuye Store -# * Multi Datacenter -### END INIT INFO - -if [ -f <%= node['consul']['etc_config_dir'] %> ]; then -. <%= node['consul']['etc_config_dir'] %> -fi - -export GOMAXPROCS=${GOMAXPROCS} - -CMD="<%= Chef::Consul.active_binary(node) %> agent -config-dir <%= node['consul']['config_dir'] %>" -NAME="consul" - -PIDFILE="/var/run/$NAME.pid" -LOGFILE="<%= @consul_logfile %>" - -STARTIMEOUT=5 -STOPTIMEOUT=30 - -get_pid() { - cat "$PIDFILE" -} - -is_running() { - [ -f "$PIDFILE" ] && ps `get_pid` > /dev/null 2>&1 -} - -case "$1" in - start) - if is_running; then - echo "$NAME already running" - else - echo "Starting $NAME" - exec 2> >(while IFS= read -r line; do logger -t consul "$line"; done) - ${CMD[@]} >> "$LOGFILE" & - CONSULPID=$! - echo $CONSULPID > "$PIDFILE" - TIMEOUT="$STARTIMEOUT" - sleep <%= @startup_sleep %> - while [ $TIMEOUT -gt 0 ]; do - if is_running; then - break - sleep 1 - let TIMEOUT=${TIMEOUT}-1 - fi - done - if [ $TIMEOUT -eq 0 ]; then - echo "Unable to start $NAME, see $LOGFILE" - exit 1 - fi - exit 0 - fi - ;; - stop) - if is_running; then - echo -n "Stopping $NAME..." - CONSULPID=`get_pid` - /bin/kill -INT "$CONSULPID" >/dev/null 2>&1 - ret=$? - if [ $ret -eq 0 ]; then - TIMEOUT="$STOPTIMEOUT" - while [ $TIMEOUT -gt 0 ]; do - kill -0 "$CONSULPID" >/dev/null 2>&1 || break - sleep 1 - let TIMEOUT=${TIMEOUT}-1 - done - if is_running; then - echo "$NAME not stopped, sending SIGKILL" - kill -9 $CONSULPID - sleep 1 - fi - if is_running; then - echo "$NAME not stopped; may still be shutting down or shutdown may have failed" - exit 1 - else - echo "$NAME stopped" - if [ -f "$PIDFILE" ]; then - rm "$PIDFILE" - fi - exit 0 - fi - fi - else - echo "$NAME not running" - fi - ;; - restart) - $0 stop - if is_running; then - echo "Unable to stop $NAME, will not attempt to start" - exit 1 - fi - $0 start - ;; - status) - if is_running; then - echo "$NAME is running" - else - echo "$NAME is stopped" - exit 1 - fi - ;; - reload) - if is_running; then - echo -n "Reloading $NAME..." - kill -HUP `get_pid` - sleep 1 - echo - - if ! is_running; then - echo "$NAME has died, see $LOGFILE" - exit 1 - fi - else - echo "$NAME not running" - fi - ;; - *) - echo "Usage: $0 {start|stop|restart|reload|status}" - exit 1 - ;; -esac - -exit 0 diff --git a/templates/default/consul-sysconfig.erb b/templates/default/consul-sysconfig.erb deleted file mode 100644 index 1c8c50c9..00000000 --- a/templates/default/consul-sysconfig.erb +++ /dev/null @@ -1 +0,0 @@ -GOMAXPROCS=<%= [node['cpu']['total'], 2].max %> diff --git a/templates/default/consul-systemd.erb b/templates/default/consul-systemd.erb deleted file mode 100644 index 07d403e7..00000000 --- a/templates/default/consul-systemd.erb +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Consul Agent -Wants=basic.target -After=basic.target network.target - -[Service] -User=<%= node['consul']['service_user'] %> -Group=<%= node['consul']['service_group'] %> -EnvironmentFile=-<%= node['consul']['etc_config_dir'] %> -ExecStart=<%= Chef::Consul.active_binary(node) %> agent \ - -config-dir <%= node['consul']['config_dir'] %> -ExecReload=/bin/kill -HUP $MAINPID -KillMode=process -Restart=on-failure -RestartSec=15s - -[Install] -WantedBy=multi-user.target diff --git a/templates/default/consul.conf.erb b/templates/default/consul.conf.erb deleted file mode 100644 index bf8078bf..00000000 --- a/templates/default/consul.conf.erb +++ /dev/null @@ -1,26 +0,0 @@ -description "Consul Service Discovery Platform" - -emits consul-up - -start on runlevel [2345] -stop on runlevel [!2345] - -# set max open files -limit nofile <%= @soft_limit %> <%= @hard_limit %> - -script - if [ -f <%= node['consul']['etc_config_dir'] %> ]; then - . <%= node['consul']['etc_config_dir'] %> - fi - export GOMAXPROCS=${GOMAXPROCS} - CMD="<%= Chef::Consul.active_binary(node) %> agent -config-dir <%= node['consul']['config_dir'] %>" - LOGFILE="<%= @consul_logfile %>" - exec $CMD >> "$LOGFILE" -end script - -post-start exec initctl emit consul-up - -kill signal INT - -respawn -respawn limit 10 10 diff --git a/templates/default/sv-consul-log-run.erb b/templates/default/sv-consul-log-run.erb deleted file mode 100644 index 42cd1197..00000000 --- a/templates/default/sv-consul-log-run.erb +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -exec chpst -u '<%= node[:consul][:service_user] %>':'<%= node[:consul][:service_group] %>' \ - svlogd \ - /var/log/consul \ -# # diff --git a/templates/default/sv-consul-run.erb b/templates/default/sv-consul-run.erb deleted file mode 100644 index eda48517..00000000 --- a/templates/default/sv-consul-run.erb +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -export GOMAXPROCS=<%= [node['cpu']['total'], 2].max %> - -exec 2>&1 -exec <%= node['runit']['chpst_bin'] %> \ - -u <%= node['consul']['service_user'] %>:<%= node['consul']['service_group'] %> \ - <%= Chef::Consul.active_binary(node) %> agent -config-dir <%= node['consul']['config_dir'] %> diff --git a/test/fixtures/data_bags/secrets/consul.json b/test/fixtures/data_bags/secrets/consul.json new file mode 100644 index 00000000..98db07f5 --- /dev/null +++ b/test/fixtures/data_bags/secrets/consul.json @@ -0,0 +1,6 @@ +{ + "id": "consul", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIDjzCCAnegAwIBAgIBCjANBgkqhkiG9w0BAQUFADB8MQswCQYDVQQGEwJVUzER\nMA8GA1UECBMITmV3IFlvcmsxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxHzAdBgNV\nBAoTFkJsb29tYmVyZyBGaW5hbmNlIEwuUC4xITAfBgNVBAsUGFImRCBQbGF0Zm9y\nbSBFbmdpbmVlcmluZzAeFw0xNTA2MTUxMTM1MDhaFw0yNTA2MTIxMTM1MDhaMIGi\nMRUwEwYDVQQDEwxKb2huIEJlbGxvbmUxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD\nVQQGEwJVUzElMCMGCSqGSIb3DQEJARYWamJlbGxvbmVAYmxvb21iZXJnLm5ldDEf\nMB0GA1UEChMWQmxvb21iZXJnIEZpbmFuY2UgTC5QLjEhMB8GA1UECxQYUiZEIFBs\nYXRmb3JtIEVuZ2luZWVyaW5nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO\nJTDt2WDTCKeB2ubzvBbE5ziCQZwGj1T4/uzlXlrybQ9q5M+oQDD44WRzSANx3Vx+\nI6ao57z6QtA5qOG9cw3csFgsMn6lVLzoegm2wQ7UhvqfcD2SOOWHBBsXp8VmX+ay\nOXpKRT5UOdLx3AczoUTua7aVsXDk/FJ9D4NV8NOF5wIDAQABo3kwdzAJBgNVHRME\nAjAAMB0GA1UdDgQWBBRo/0cnJ6coZaWuE+M7oqSsZ52vBjAfBgNVHSMEGDAWgBS5\nzSJ2wMBbmqDs6IlOdrUynXj8gTALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB\nBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQCzqVLJ+v+yzvA0RFif\nf6j4DMj8MT/bxyaaX6SwYoC4ILIZjJ9Pn/1LwxZUfOkpEXwOQnT4G1epvuJIhXL7\nkILMoewMxseY6laHW4vCo3w4UJsKKlSnGinSkUun+CtI2CpPaIZ4bRnKsYGdqzeN\nShbn7xVc+oVS4tQA72T4g7WltVGTM+At6EKhKCvbEUiZ3OznFHEmvxYzrGZGii18\nyamF6DtSIS4a6E1G5zDGr2ba4THcHBuV9JsZeQhg9UlGdyA30n9zz5M8QJpUr34Z\nfRGmyGq+fIwpH639F/I2sLNIcZKsPbjfVojK+4e6d4t4rQiqo1jv9YZUvgvDIiu8\nWatv\n-----END CERTIFICATE-----\n", + "ca_certificate": "-----BEGIN CERTIFICATE-----\nMIIEXjCCA0agAwIBAgIJAJ4alkWMxGdeMA0GCSqGSIb3DQEBBQUAMHwxCzAJBgNV\nBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0\neTEfMB0GA1UEChMWQmxvb21iZXJnIEZpbmFuY2UgTC5QLjEhMB8GA1UECxQYUiZE\nIFBsYXRmb3JtIEVuZ2luZWVyaW5nMB4XDTE1MDYxNTExMzEyMVoXDTI1MDYxMjEx\nMzEyMVowfDELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMRYwFAYDVQQH\nEw1OZXcgWW9yayBDaXR5MR8wHQYDVQQKExZCbG9vbWJlcmcgRmluYW5jZSBMLlAu\nMSEwHwYDVQQLFBhSJkQgUGxhdGZvcm0gRW5naW5lZXJpbmcwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQDnEeVEYXozw1TPU15hyGN89eD07MOLHF4eAU7n\neZXNNHNYuuX4Ub2nbpAbekO7Muq2s9I3x+CzGfMSkKSxSh8aT+S1Fu9xxA91VE8L\nMIFZTy+O4CFWYzYaRXI+hJ5Hf0JF/pHPyfZbYX2gSUIWmxjBDnpUNeCfr/LrWRpn\nXL8GoIeKrINXGwJJas7ZLuW/TmaOIlwFD+mRl6hAlyYbekozSnCLL8PfE+F5iVK2\nRbra1z3WFiHNvMnBRaZIiUdci0JRmccdc3IEM301ZJjD0PbXpoW+4r/bAiJxT3Gw\n6X2rjES6du/MnlApr3yUuGhF46Eb5RrTRZSRRWDiqOqWNSy/AgMBAAGjgeIwgd8w\nHQYDVR0OBBYEFLnNInbAwFuaoOzoiU52tTKdePyBMIGvBgNVHSMEgacwgaSAFLnN\nInbAwFuaoOzoiU52tTKdePyBoYGApH4wfDELMAkGA1UEBhMCVVMxETAPBgNVBAgT\nCE5ldyBZb3JrMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MR8wHQYDVQQKExZCbG9v\nbWJlcmcgRmluYW5jZSBMLlAuMSEwHwYDVQQLFBhSJkQgUGxhdGZvcm0gRW5naW5l\nZXJpbmeCCQCeGpZFjMRnXjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IB\nAQBGyM0eOlHYyGFyYs/mPZv+UMifwITnUqnDBpbMZmoWUFBQMqAbc/XRbrBH5bpm\nXuEoV4PqEnkzSsMZN2bHulyor2wrgh5AoO1rEW6QghGlMG0dbwcqtA0D+JPzb13c\nw3TLD6LOo8O+1lymNe18nhdye3xxN+IYzxwAvQwszbupFqQ1f8EiNcTgxTfiVr56\n84ca5/3YRtV12CiFy0RICjw062UeJ03ki15HNp0bLWXnZFcK+MqL7sH9/ZoKBfKq\n3WXH3r45LJlMpNxZJYIAODMKe8WGj8Y61cfyYEed3wszEYqe7u6L+2Hee5XWDSi4\n91WN5l6KnBpBpYOERH1BfEie\n-----END CERTIFICATE-----\n", + "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDOJTDt2WDTCKeB2ubzvBbE5ziCQZwGj1T4/uzlXlrybQ9q5M+o\nQDD44WRzSANx3Vx+I6ao57z6QtA5qOG9cw3csFgsMn6lVLzoegm2wQ7UhvqfcD2S\nOOWHBBsXp8VmX+ayOXpKRT5UOdLx3AczoUTua7aVsXDk/FJ9D4NV8NOF5wIDAQAB\nAoGBAKmI+KaD4hdsxKYM62eERo2FQ3oMj07tzgpBTX6NjOpXOxjEOOu8bwogA8az\ncPHSBWFP3J6Ih2iiTjE9bPmrh7d/feEArjNUAL0ntcM3VFDX3IcZis8ZjgVqQG1J\nwvpn2o1qP37FJE1JSVdzN0MvWzFzgmhewxLqJcnFbUJysbaBAkEA8oW5EEd5beZO\nZ7V71C6EfOQw3HeCo34M5ndhI7rIa4MeLnLMVYBYodIezNdWHsFV7lqSkJamrKH9\nfLzjrsvMYQJBANmZ8d9QmfYJfBlJqZQziUqmEXQ8a7A0zW8WnFWgQrpLojs+eEMm\nx0Xb1IdyQT3Irl9+cE8lVoAiF8RxWd+FN0cCQQCR2IE2nQUVZk74Z1eUfnUGdmQ7\n8VMK5x7y6g/s4MLuhOd9n2Pqd0jV5/rFzSnpTPNUZ/uEIFUTtEcw4Jc74yuBAkBh\n15KmMvvHYWRninOxq6qj4iAe/7v8MwHcXXJWHgVi9vcvZFt29kzL4JijfoBPY5jk\nX1nofIV0f9/n+H/MvX2pAkBtiZ0gtW35QOmWdhqnOqpToOcNdzw6ON8d2bAx2mA1\nQm5P2pmsxEBJ3cSElRvOK+36OMWr0uMjUz5IogI6Fas7\n-----END RSA PRIVATE KEY-----\n" +} diff --git a/test/integration/atlas/serverspec/localhost/atlas_spec.rb b/test/integration/atlas/serverspec/localhost/atlas_spec.rb deleted file mode 100644 index 0da40b2b..00000000 --- a/test/integration/atlas/serverspec/localhost/atlas_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe command('which consul') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match '/usr/local/bin/consul' } -end - -describe service('consul') do - it { should be_enabled } - it { should be_running } -end - -describe file('/etc/consul.d') do - it { should be_directory } -end - -describe command('grep atlas /etc/consul.d/default.json') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match %r{"atlas_infrastructure":\s"([^"]*)"} } - its(:stdout) { should match %r{"atlas_join":\s(true|false)} } - its(:stdout) { should match %r{"atlas_token":\s"([^"]*)"} } -end diff --git a/test/integration/atlas/serverspec/spec_helper.rb b/test/integration/atlas/serverspec/spec_helper.rb deleted file mode 100644 index c0925118..00000000 --- a/test/integration/atlas/serverspec/spec_helper.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'serverspec' - -set :backend, :exec - -RSpec.configure do |c| - c.path = '/usr/local/bin:/sbin:/bin:/usr/bin' -end diff --git a/test/integration/default/serverspec/localhost/consul_spec.rb b/test/integration/default/serverspec/localhost/consul_spec.rb deleted file mode 100644 index 75161787..00000000 --- a/test/integration/default/serverspec/localhost/consul_spec.rb +++ /dev/null @@ -1,51 +0,0 @@ -require 'spec_helper' - -describe command('which consul') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match '/usr/local/bin/consul' } -end - -describe service('consul') do - it { should be_enabled } - it { should be_running } -end - -describe file('/etc/consul.d') do - it { should be_directory } -end - -describe file('/var/lib/consul') do - it { should be_directory } -end - -[8300, 8400, 8500, 8600].each do |p| - describe port(p) do - it { should be_listening } - end -end - -describe command 'consul members -detailed' do - its(:exit_status) { should eq 0 } - its(:stdout) { should match %r{\balive\b} } - its(:stdout) { should match %r{\brole=consul\b} } - its(:stdout) { should match %r{\bbootstrap=1\b} } -end - -describe 'config file attributes' do - context command 'consul members -detailed' do - its(:stdout) { should match %r{\bdc=FortMeade\b}i } - end -end - -eth0_ip = command("/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'").stdout.strip -describe command("grep #{eth0_ip} /etc/consul.d/default.json") do - its(:exit_status) { should eq 0 } - # bind_addr should only be in the config if node[:consul][:bind_addr] is set - its(:stdout) { should match %r{"bind_addr":\s"#{eth0_ip}"}} - its(:stdout) { should match %r{"advertise_addr":\s"#{eth0_ip}"}} -end - -describe command('grep encrypt /etc/consul.d/default.json') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match %r{"encrypt":\s"([^\"]*)"} } -end diff --git a/test/integration/default/serverspec/localhost/default_spec.rb b/test/integration/default/serverspec/localhost/default_spec.rb new file mode 100644 index 00000000..c561f14a --- /dev/null +++ b/test/integration/default/serverspec/localhost/default_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe file('/srv/consul/current/consul') do + it { should be_file } + it { should be_executable } +end + +describe file('/usr/local/bin/consul') do + it { should be_symlink } + it { should be_linked_to '/srv/consul/current/consul' } +end + +describe service('consul') do + it { should be_enabled } + it { should be_running } +end + +[8300, 8400, 8500, 8600].each do |p| + describe port(p) do + it { should be_listening } + end +end + +describe command('/usr/local/bin/consul members -detailed') do + its(:exit_status) { should eq 0 } + its(:stdout) { should match %r{\balive\b} } + its(:stdout) { should match %r{\brole=consul\b} } + its(:stdout) { should match %r{\bbootstrap=1\b} } + its(:stdout) { should match %r{\bdc=fortmeade\b} } +end diff --git a/test/integration/default/serverspec/spec_helper.rb b/test/integration/default/serverspec/spec_helper.rb deleted file mode 100644 index c0925118..00000000 --- a/test/integration/default/serverspec/spec_helper.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'serverspec' - -set :backend, :exec - -RSpec.configure do |c| - c.path = '/usr/local/bin:/sbin:/bin:/usr/bin' -end diff --git a/test/integration/helpers/serverspec/spec_helper.rb b/test/integration/helpers/serverspec/spec_helper.rb new file mode 100644 index 00000000..37af1b45 --- /dev/null +++ b/test/integration/helpers/serverspec/spec_helper.rb @@ -0,0 +1,3 @@ +require 'serverspec' + +set :backend, :exec diff --git a/test/integration/packages/serverspec/localhost/consul_spec.rb b/test/integration/packages/serverspec/localhost/consul_spec.rb deleted file mode 100644 index aee11c01..00000000 --- a/test/integration/packages/serverspec/localhost/consul_spec.rb +++ /dev/null @@ -1,55 +0,0 @@ -require 'spec_helper' - -describe command('which consul') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match '/usr/local/bin/consul' } -end - -describe service('consul') do - it { should be_enabled } - it { should be_running } -end - -describe file('/etc/consul.d') do - it { should be_directory } -end - -describe file('/var/lib/consul') do - it { should be_directory } -end - -[8300, 8400, 8500, 8600].each do |p| - describe port(p) do - it { should be_listening } - end -end - -describe command 'consul members -detailed' do - its(:exit_status) { should eq 0 } - its(:stdout) { should match %r{\balive\b} } - its(:stdout) { should match %r{\brole=consul\b} } - its(:stdout) { should match %r{\bbootstrap=1\b} } -end - -describe 'config file attributes' do - context command 'consul members -detailed' do - its(:stdout) { should match %r{\bdc=fortmeade\b} } - end -end - -eth0_ip = command("/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'").stdout.strip -describe command("grep #{eth0_ip} /etc/consul.d/default.json") do - its(:exit_status) { should eq 0 } - # bind_addr should only be in the config if node[:consul][:bind_addr] is set - its(:stdout) { should match %r{"bind_addr":\s"#{eth0_ip}"}} - its(:stdout) { should match %r{"advertise_addr":\s"#{eth0_ip}"}} -end - -describe command('grep encrypt /etc/consul.d/default.json') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match %r{"encrypt":\s"([^\"]*)"} } -end - -describe file('/var/lib/consul/ui/index.html') do - it { should be_file } -end diff --git a/test/integration/packages/serverspec/spec_helper.rb b/test/integration/packages/serverspec/spec_helper.rb deleted file mode 100644 index c0925118..00000000 --- a/test/integration/packages/serverspec/spec_helper.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'serverspec' - -set :backend, :exec - -RSpec.configure do |c| - c.path = '/usr/local/bin:/sbin:/bin:/usr/bin' -end diff --git a/test/integration/ui/serverspec/localhost/consul_spec.rb b/test/integration/ui/serverspec/localhost/consul_spec.rb deleted file mode 100644 index 69c84958..00000000 --- a/test/integration/ui/serverspec/localhost/consul_spec.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'spec_helper' - -describe file('/var/lib/consul/ui/index.html') do - it { should be_file } -end - -eth0_ip = command("/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'").stdout.strip -describe command("wget -q -O- http://#{eth0_ip}:8500/ui/index.html") do - its(:exit_status) { should eq 0 } - its(:stdout) { should eq File.read('/var/lib/consul/ui/index.html') } -end diff --git a/test/integration/ui/serverspec/spec_helper.rb b/test/integration/ui/serverspec/spec_helper.rb deleted file mode 100644 index 1f1bebea..00000000 --- a/test/integration/ui/serverspec/spec_helper.rb +++ /dev/null @@ -1,4 +0,0 @@ -require 'serverspec' - -set :backend, :exec -set :path, '$PATH:/usr/local/bin:/sbin:/bin:/usr/bin' diff --git a/test/integration/windows/serverspec/localhost/consul_spec.rb b/test/integration/windows/serverspec/localhost/consul_spec.rb deleted file mode 100644 index 7e7f92cb..00000000 --- a/test/integration/windows/serverspec/localhost/consul_spec.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'spec_helper' - -describe command('where.exe /R C:\ProgramData\chocolatey\bin consul') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match "C:\\ProgramData\\chocolatey\\bin\\consul.exe\n" } -end - -describe service('consul') do - it { should be_enabled } - it { should be_running } -end - -describe file('C:\ProgramData\consul\config') do - it { should be_directory } -end - -describe file('C:\ProgramData\consul\data') do - it { should be_directory } -end - -describe port(8300) do - it { should be_listening } -end - -# For some reason, the check can't find the port -#[8400, 8500, 8600].each do |p| -# describe port(p) do -# it { should be_listening.on('127.0.0.1') } -# end -#end diff --git a/test/integration/windows/serverspec/spec_helper.rb b/test/integration/windows/serverspec/spec_helper.rb deleted file mode 100644 index ede13c0e..00000000 --- a/test/integration/windows/serverspec/spec_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -require 'serverspec' - -set :backend, :cmd -set :os, :family => 'windows' -set :architecture, :x86_64 diff --git a/test/spec/libraries/consul_config_spec.rb b/test/spec/libraries/consul_config_spec.rb new file mode 100644 index 00000000..e0213c46 --- /dev/null +++ b/test/spec/libraries/consul_config_spec.rb @@ -0,0 +1,77 @@ +require 'poise_boiler/spec_helper' +require 'poise' + +RSpec.configure do |config| + config.include Halite::SpecHelper +end + +require_relative '../../../libraries/consul_config' + +describe Chef::Resource::ConsulConfig do + step_into(:consul_config) + + context '#action_create' do + before do + recipe = double('Chef::Recipe') + allow_any_instance_of(Chef::RunContext).to receive(:include_recipe).and_return([recipe]) + allow_any_instance_of(Chef::DSL::Recipe).to receive(:chef_vault_item).and_return( + { 'ca_certificate' => 'foo', 'certificate' => 'bar', 'private_key' => 'baz' } + ) + end + + recipe do + consul_config '/etc/consul/default.json' do + key_file '/etc/consul/ssl/private/consul.key' + ca_file '/etc/consul/ssl/CA/ca.crt' + cert_file '/etc/consul/ssl/certs/consul.crt' + verify_incoming true + verify_outgoing true + end + end + + it { is_expected.to create_directory('/etc/consul/ssl/CA') } + it { is_expected.to create_directory('/etc/consul/ssl/certs') } + it { is_expected.to create_directory('/etc/consul/ssl/private') } + + it do + is_expected.to create_file('/etc/consul/ssl/CA/ca.crt') + .with(content: 'foo') + .with(owner: 'consul') + .with(group: 'consul') + .with(mode: '0644') + end + + it do + is_expected.to create_file('/etc/consul/ssl/certs/consul.crt') + .with(content: 'bar') + .with(owner: 'consul') + .with(group: 'consul') + .with(mode: '0644') + end + + it do + is_expected.to create_file('/etc/consul/ssl/private/consul.key') + .with(content: 'baz') + .with(sensitive: true) + .with(owner: 'consul') + .with(group: 'consul') + .with(mode: '0640') + end + + it { is_expected.to create_directory('/etc/consul') } + it { is_expected.to create_file('/etc/consul/default.json') } + + it { run_chef } + end + + context '#action_delete' do + recipe do + consul_config '/etc/consul/default.json' do + action :delete + end + + it { is_expected.to delete_file('/etc/consul/default.json') } + it { run_chef } + end + end +end diff --git a/test/spec/libraries/consul_definition_spec.rb b/test/spec/libraries/consul_definition_spec.rb new file mode 100644 index 00000000..1c032dc3 --- /dev/null +++ b/test/spec/libraries/consul_definition_spec.rb @@ -0,0 +1,40 @@ +require 'poise_boiler/spec_helper' +require 'poise' + +RSpec.configure do |config| + config.include Halite::SpecHelper +end + +require_relative '../../../libraries/consul_definition' + +describe Chef::Resource::ConsulDefinition do + step_into(:consul_definition) + + context '#action_create' do + recipe do + consul_definition '/etc/consul/default.json' do + end + end + + it do + is_expected.to create_file() + end + + it { run_chef } + end + + context '#action_create' do + recipe do + consul_definition '/etc/consul/default.json' do + action :delete + end + end + + it do + is_expected.to delete_file() + end + + it { run_chef } + end + +end diff --git a/test/spec/libraries/consul_service_spec.rb b/test/spec/libraries/consul_service_spec.rb new file mode 100644 index 00000000..94102541 --- /dev/null +++ b/test/spec/libraries/consul_service_spec.rb @@ -0,0 +1,28 @@ +require 'poise_boiler/spec_helper' +require 'poise' + +RSpec.configure do |config| + config.include Halite::SpecHelper +end + +require_relative '../../../libraries/consul_service' + +describe Chef::Resource::ConsulService do + step_into(:consul_service) + + context '#action_create' do + it { run_chef } + end + + context '#action_enable' do + it { run_chef } + end + + context '#action_disable' do + it { run_chef } + end + + context '#action_delete' do + it { run_chef } + end +end diff --git a/test/spec/libraries/consul_watch_spec.rb b/test/spec/libraries/consul_watch_spec.rb new file mode 100644 index 00000000..ecce1458 --- /dev/null +++ b/test/spec/libraries/consul_watch_spec.rb @@ -0,0 +1,35 @@ +require 'poise_boiler/spec_helper' +require 'poise' + +RSpec.configure do |config| + config.include Halite::SpecHelper +end + +require_relative '../../../libraries/consul_watch' + +describe Chef::Resource::ConsulWatch do + step_into(:consul_watch) + + context 'defines key watch' do + recipe do + consul_watch '/etc/consul/watches/foo.json' do + type 'key' + parameters(key: 'foo/bar/baz', handler: '/bin/false') + end + end + + it { is_expected.to create_directory('/etc/consul/watches') } + it do + is_expected.to create_file('/etc/consul/watches/foo.json') + .with(user: 'consul', group: 'consul', mode: '0640') + .with(content: JSON.pretty_generate( + { + type: 'key', + key: 'foo/bar/baz', + handler: '/bin/false' + }, + quicks_mode: true + )) + end + end +end diff --git a/test/spec/recipes/default_spec.rb b/test/spec/recipes/default_spec.rb new file mode 100644 index 00000000..a25e4dbe --- /dev/null +++ b/test/spec/recipes/default_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe_recipe 'consul::default' do + cached(:chef_run) { ChefSpec::SoloRunner.converge(described_recipe) } + + context 'with default attributes' do + it { expect(chef_run).to include_recipe('selinux::permissive') } + it { expect(chef_run).to create_poise_service_user('consul').with(group: 'consul') } + it { expect(chef_run).to create_consul_config('consul').with(path: '/etc/consul.json') } + it { expect(chef_run).to create_consul_service('consul').with(config_file: '/etc/consul.json') } + it { expect(chef_run).to enable_consul_service('consul').with(config_file: '/etc/consul.json') } + + it 'converges successfully' do + chef_run + end + end +end diff --git a/test/spec/spec_helper.rb b/test/spec/spec_helper.rb new file mode 100644 index 00000000..8bea8b88 --- /dev/null +++ b/test/spec/spec_helper.rb @@ -0,0 +1,41 @@ +require 'chefspec' +require 'chefspec/berkshelf' +require 'chefspec/cacher' +require 'chef-vault' +require 'poise_boiler/spec_helper' + +RSpec.configure do |config| + config.include Halite::SpecHelper + + config.platform = 'ubuntu' + config.version = '14.04' + + config.color = true + config.alias_example_group_to :describe_recipe, type: :recipe + + config.filter_run :focus + config.run_all_when_everything_filtered = true + + Kernel.srand config.seed + config.order = :random + + if config.files_to_run.one? + config.default_formatter = 'doc' + end + + config.expect_with :rspec do |expectations| + expectations.syntax = :expect + end + + config.mock_with :rspec do |mocks| + mocks.syntax = :expect + mocks.verify_partial_doubles = true + end +end + +RSpec.shared_context 'recipe tests', type: :recipe do + before do + stub_command("test -L /usr/local/bin/consul").and_return(true) + stub_command("/usr/local/go/bin/go version | grep \"go1.4 \"").and_return(true) + end +end