Merge pull request #1 from github/config-via-hash

Configuration via hashes, similar to `consul` module
This commit is contained in:
Ross McFarland 2016-06-24 11:08:56 -07:00 коммит произвёл GitHub
Родитель 4cddf41c09 e76ca2f5d2
Коммит 4bc7656ba3
8 изменённых файлов: 106 добавлений и 163 удалений

Просмотреть файл

@ -3,5 +3,6 @@ fixtures:
stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git" stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git"
staging: "https://github.com/nanliu/puppet-staging.git" staging: "https://github.com/nanliu/puppet-staging.git"
concat: "https://github.com/puppetlabs/puppet-concat.git" concat: "https://github.com/puppetlabs/puppet-concat.git"
consul: "https://github.com/solarkennedy/puppet-consul"
symlinks: symlinks:
consul_template: "#{source_dir}" consul_template: "#{source_dir}"

Просмотреть файл

@ -1,5 +1,12 @@
#consul_template for Puppet #consul_template for Puppet
### NOTICE:
This fork is not backwards compatible with its upstream. The configuration
mechanism has been modified to be driven by config_hash/config_defaults instead
of individual parameters to provide access to the full set of options and avoid
the need to make changes here as consul-template options evolve.
##Installation ##Installation
###What This Module Affects ###What This Module Affects
@ -33,14 +40,9 @@ set to 'package', its installed using the system package manager.
- `group` Default: root. - `group` Default: root.
- `manage_user` Default: false. Module handles creating the user. - `manage_user` Default: false. Module handles creating the user.
- `manage_group` Default: false. Module handles creating the group. - `manage_group` Default: false. Module handles creating the group.
- `consul_host` Default: localhost. Hostanme of consul agent to query
- `consul_port` Default: 8500. Port number the API is running on
- `consul_token` Default: ''. ACL token to use when querying consul
- `consul_retry` Default: 10s. Time in seconds to wait before retrying consul requests
- `consul_wait` Default: undef. Min:Max time to wait before consul-template renders a new template to disk and triggers refresh. Specified in the format min:max according to [Go time duration format](http://golang.org/pkg/time/#ParseDuration)
- `consul_max_stale` Default: undef. The maximum staleness of a query. If specified, Consul will distribute work among all servers instead of just the leader.
- `init_style` Init style to use for consul-template service. - `init_style` Init style to use for consul-template service.
- `log_level` Default: info. Logging level to use for consul-template service. Can be 'debug', 'warn', 'err', 'info' - `config_hash` Default: {}. Consul-template configuration options. See https://github.com/hashicorp/consul-template#options
- `config_defaults` Default: {}. Consul-template configuration option defaults.
@ -51,18 +53,31 @@ The simplest way to use this module is:
include consul_template include consul_template
``` ```
Or to specify parameters: consul-template options can be passed via hiera:
```
consul_template::config_defaults:
deduplicate:
enabled: true
log_level: info
retry: 10s
syslog: true
token: <consul token>
```
Or to specify class parameters:
```puppet ```puppet
class { 'consul_template': class { 'consul_template':
service_enable => false service_enable => false
log_level => 'debug',
init_style => 'upstart', init_style => 'upstart',
consul_wait => '5s:30s', config_hash => {
consul_max_stale => '1s' log_level => 'debug',
wait => '5s:30s',
max_stale => '1s'
}
} }
``` ```
## Watch files ## Watch files
To declare a file that you wish to populate from Consul key-values, you use the To declare a file that you wish to populate from Consul key-values, you use the
@ -76,8 +91,10 @@ consul_template::watch { 'common':
'var1' => 'foo', 'var1' => 'foo',
'var2' => 'bar', 'var2' => 'bar',
}, },
destination => '/tmp/common.json', config_hash => {
command => 'true', destination => '/tmp/common.json',
command => 'true',
},
} }
``` ```

Просмотреть файл

@ -31,6 +31,7 @@ exclude_paths = [
] ]
PuppetLint.configuration.ignore_paths = exclude_paths PuppetLint.configuration.ignore_paths = exclude_paths
PuppetSyntax.exclude_paths = exclude_paths PuppetSyntax.exclude_paths = exclude_paths
PuppetSyntax.future_parser = true
desc "Run acceptance tests" desc "Run acceptance tests"
RSpec::Core::RakeTask.new(:acceptance) do |t| RSpec::Core::RakeTask.new(:acceptance) do |t|

Просмотреть файл

@ -3,89 +3,31 @@
# This class is called from consul_template for service config. # This class is called from consul_template for service config.
# #
class consul_template::config ( class consul_template::config (
$consul_host, $config_hash = {},
$consul_port, $purge = true,
$consul_token,
$consul_retry,
$purge = true,
) { ) {
# Using our parent module's pretty_config & pretty_config_indent just because
$content_full = consul_sorted_json($config_hash, $consul::pretty_config, $consul::pretty_config_indent)
# remove the closing } and it's surrounding newlines
$content = regsubst($content_full, "\n}\n$", '')
concat::fragment { 'header': $config_file = "${consul_template::config_dir}/config/config.json"
target => 'consul-template/config.json', concat::fragment { 'consul-service-pre':
content => inline_template("consul = \"<%= @consul_host %>:<%= @consul_port %>\"\ntoken = \"<%= @consul_token %>\"\nretry = \"<%= @consul_retry %>\"\n\n"), target => $config_file,
order => '00', # add the opening template array so that we can insert watch fragments
content => "${content},\n \"template\": [\n",
order => '1',
} }
# Set the log level # Realizes concat::fragments from consul_template::watches that make up 1 or
concat::fragment { 'log_level': # more template configs.
target => 'consul-template/config.json', Concat::Fragment <| target == 'consul-template/config.json' |>
content => inline_template("log_level = \"${::consul_template::log_level}\"\n"),
order => '01'
}
# Set wait param if specified concat::fragment { 'consul-service-post':
if $::consul_template::consul_wait { target => $config_file,
concat::fragment { 'consul_wait': # close off the template array and the whole object
target => 'consul-template/config.json', content => " ],\n}",
content => inline_template("wait = \"${::consul_template::consul_wait}\"\n\n"), order => '99',
order => '02',
}
}
# Set max_stale param if specified
if $::consul_template::consul_max_stale {
concat::fragment { 'consul_max_stale':
target => 'consul-template/config.json',
content => inline_template("max_stale = \"${::consul_template::consul_max_stale}\"\n\n"),
order => '03',
}
}
if $::consul_template::deduplicate {
concat::fragment { 'dedup-base':
target => 'consul-template/config.json',
content => inline_template("deduplicate {\n enabled = true\n"),
order => '04',
}
if $::consul_template::deduplicate_prefix {
concat::fragment { 'dedup-prefix':
target => 'consul-template/config.json',
content => inline_template(" prefix = \"${::consul_template::deduplicate_prefix}\"\n"),
order => '05',
}
}
concat::fragment { 'dedup-close':
target => 'consul-template/config.json',
content => inline_template("}\n"),
order => '06',
}
}
if $::consul_template::vault_enabled {
concat::fragment { 'vault-base':
target => 'consul-template/config.json',
content => inline_template("vault {\n address = \"${::consul_template::vault_address}\"\n token = \"${::consul_template::vault_token}\"\n"),
order => '07',
}
if $::consul_template::vault_ssl {
concat::fragment { 'vault-ssl1':
target => 'consul-template/config.json',
content => inline_template(" ssl {\n enabled = true\n verify = ${::consul_template::vault_ssl_verify}\n"),
order => '08',
}
concat::fragment { 'vault-ssl2':
target => 'consul-template/config.json',
content => inline_template(" cert = \"${::consul_template::vault_ssl_cert}\"\n ca_cert = \"${::consul_template::vault_ssl_ca_cert}\"\n }\n"),
order => '09',
}
}
concat::fragment { 'vault-baseclose':
target => 'consul-template/config.json',
content => "}\n\n",
order => '10',
}
} }
file { [$consul_template::config_dir, "${consul_template::config_dir}/config"]: file { [$consul_template::config_dir, "${consul_template::config_dir}/config"]:
@ -97,7 +39,7 @@ class consul_template::config (
mode => '0755', mode => '0755',
} -> } ->
concat { 'consul-template/config.json': concat { 'consul-template/config.json':
path => "${consul_template::config_dir}/config/config.json", path => $config_file,
owner => $consul_template::user, owner => $consul_template::user,
group => $consul_template::group, group => $consul_template::group,
mode => $consul_template::config_mode, mode => $consul_template::config_mode,

Просмотреть файл

@ -22,33 +22,15 @@
# [*init_style*] # [*init_style*]
# What style of init system your system uses. # What style of init system your system uses.
# #
# [*config_hash*]
# Consul-template configuration options. See https://github.com/hashicorp/consul-template#options
#
# [*config_mode*] # [*config_mode*]
# Set config file mode # Set config file mode
# #
# [*purge_config_dir*] # [*purge_config_dir*]
# Purge config files no longer generated by Puppet # Purge config files no longer generated by Puppet
# #
# [*vault_enabled*]
# Do we want to configure Hashicopr Vault? Defaults to false.
#
# [*vault_address*]
# HTTP/HTTPS URL of the vault service
#
# [*vault_token*]
# Auth token to use for Vault
#
# [*vault_ssl*]
# Should we use SSL? Defaults to true
#
# [*vault_ssl_verify*]
# Should we verify the SSL certificate? Defaults to true
#
# [*vault_ssl_cert*]
# What is the path to the cert.pem
#
# [*vault_ssl_ca_cert*]
# What is the path to the ca cert.pem
#
# [*data_dir*] # [*data_dir*]
# Path to a directory to create to hold some data. Defaults to '' # Path to a directory to create to hold some data. Defaults to ''
# #
@ -84,27 +66,13 @@ class consul_template (
$extra_options = '', $extra_options = '',
$service_enable = true, $service_enable = true,
$service_ensure = 'running', $service_ensure = 'running',
$consul_host = 'localhost', $config_hash = {},
$consul_port = '8500', $config_defaults = {},
$consul_token = '',
$consul_retry = '10s',
$consul_wait = undef,
$consul_max_stale = undef,
$deduplicate = false,
$deduplicate_prefix = undef,
$init_style = $consul_template::params::init_style, $init_style = $consul_template::params::init_style,
$log_level = $consul_template::params::log_level,
$logrotate_compress = 'nocompress', $logrotate_compress = 'nocompress',
$logrotate_files = 4, $logrotate_files = 4,
$logrotate_on = false, $logrotate_on = false,
$logrotate_period = 'daily', $logrotate_period = 'daily',
$vault_enabled = false,
$vault_address = '',
$vault_token = '',
$vault_ssl = true,
$vault_ssl_verify = true,
$vault_ssl_cert = '',
$vault_ssl_ca_cert = '',
$data_dir = '', $data_dir = '',
$user = $consul_template::params::user, $user = $consul_template::params::user,
$group = $consul_template::params::group, $group = $consul_template::params::group,
@ -119,6 +87,8 @@ class consul_template (
validate_bool($manage_user) validate_bool($manage_user)
validate_bool($manage_group) validate_bool($manage_group)
validate_hash($watches) validate_hash($watches)
validate_hash($config_hash)
validate_hash($config_defaults)
$real_download_url = pick($download_url, "${download_url_base}${version}/${package_name}_${version}_${os}_${arch}.${download_extension}") $real_download_url = pick($download_url, "${download_url_base}${version}/${package_name}_${version}_${os}_${arch}.${download_extension}")
@ -126,13 +96,15 @@ class consul_template (
create_resources(consul_template::watch, $watches) create_resources(consul_template::watch, $watches)
} }
$config_base = {
consul => 'localhost:8500',
}
$config_hash_real = deep_merge($config_base, $config_defaults, $config_hash)
anchor { '::consul_template::begin': } -> anchor { '::consul_template::begin': } ->
class { '::consul_template::install': } -> class { '::consul_template::install': } ->
class { '::consul_template::config': class { '::consul_template::config':
consul_host => $consul_host, config_hash => $config_hash_real,
consul_port => $consul_port,
consul_token => $consul_token,
consul_retry => $consul_retry,
purge => $purge_config_dir, purge => $purge_config_dir,
} ~> } ~>
class { '::consul_template::service': } -> class { '::consul_template::service': } ->

Просмотреть файл

@ -6,7 +6,6 @@
class consul_template::params { class consul_template::params {
$install_method = 'url' $install_method = 'url'
$log_level = 'info'
$package_name = 'consul-template' $package_name = 'consul-template'
$package_ensure = 'latest' $package_ensure = 'latest'
$version = '0.11.0' $version = '0.11.0'

Просмотреть файл

@ -4,24 +4,33 @@
# This is a single instance of a configuration file to watch # This is a single instance of a configuration file to watch
# for changes in Consul and update the local file # for changes in Consul and update the local file
define consul_template::watch ( define consul_template::watch (
$command, $config_hash = {},
$destination, $config_defaults = {},
$source = undef, $template = undef,
$template = undef, $template_vars = {},
$template_vars = {},
) { ) {
include consul_template include consul_template
if $template == undef and $source == undef { $config_hash_real = deep_merge($config_defaults, $config_hash)
err ('Specify either template or source parameter for consul_template::watch') if $template == undef and $config_hash_real['source'] == undef {
err ('Specify either template parameter or config_hash["source"] for consul_template::watch')
} }
if $template != undef and $source != undef { if $template != undef and $config_hash_real['source'] != undef {
err ('Specify either template or source parameter for consul_template::watch - but not both') err ('Specify either template parameter or config_hash["source"] for consul_template::watch - but not both')
} }
if $template != undef { if $template == undef {
file { "${consul_template::config_dir}/${name}.ctmpl": # source is specified in config_hash
$config_source = {}
$frag_name = $config_hash_real['source']
} else {
# source is specified as a template
$source = "${consul_template::config_dir}/${name}.ctmpl"
$config_source = {
source => $source,
}
file { $source:
ensure => present, ensure => present,
owner => $consul_template::user, owner => $consul_template::user,
group => $consul_template::group, group => $consul_template::group,
@ -30,20 +39,18 @@ define consul_template::watch (
before => Concat::Fragment["${name}.ctmpl"], before => Concat::Fragment["${name}.ctmpl"],
notify => Service['consul-template'], notify => Service['consul-template'],
} }
$frag_name = $source
} }
if $source != undef { $config_hash_all = deep_merge($config_hash_real, $config_source)
$source_name = $source $content_full = consul_sorted_json($config_hash_all, $consul::pretty_config, $consul::pretty_config_indent)
$frag_name = $source $content = regsubst(regsubst($content_full, "}\n$", '}'), "\n", "\n ", 'G')
} else { @concat::fragment { $frag_name:
$source_name = "${consul_template::config_dir}/${name}.ctmpl"
$frag_name = "${name}.ctmpl"
}
concat::fragment { $frag_name:
target => 'consul-template/config.json', target => 'consul-template/config.json',
content => "template {\n source = \"${source_name}\"\n destination = \"${destination}\"\n command = \"${command}\"\n}\n\n", # NOTE: this will result in all watches having , after them in the JSON
order => '10', # array. That won't pass strict JSON parsing, but luckily HCL is fine with it.
notify => Service['consul-template'] content => " $content,\n",
order => '50',
notify => Service['consul-template'],
} }
} }

Просмотреть файл

@ -7,8 +7,10 @@ describe 'consul_template::watch', :type => :define do
describe "consul_template::watch define on OS family #{osfamily}" do describe "consul_template::watch define on OS family #{osfamily}" do
let(:title) { 'test_watcher' } let(:title) { 'test_watcher' }
let(:params) {{ let(:params) {{
:destination => '/var/tmp/consul_template', :config_hash => {
:command => '/bin/test', 'destination' => '/var/tmp/consul_template',
'command' => '/bin/test',
}
}} }}
let(:facts) {{ let(:facts) {{
:osfamily => osfamily, :osfamily => osfamily,
@ -30,10 +32,12 @@ describe 'consul_template::watch', :type => :define do
describe "consul_template::watch define on OS family #{osfamily}" do describe "consul_template::watch define on OS family #{osfamily}" do
let(:title) { 'test_watcher' } let(:title) { 'test_watcher' }
let(:params) {{ let(:params) {{
:template => 'consul_template_spec/test_template', :template => 'consul_template_spec/test_template',
:template_vars => { 'foo' => 'bar' }, :template_vars => { 'foo' => 'bar' },
:destination => '/var/tmp/consul_template', :config_hash => {
:command => '/bin/test', 'destination' => '/var/tmp/consul_template',
'command' => '/bin/test',
}
}} }}
let(:facts) {{ let(:facts) {{
:osfamily => osfamily, :osfamily => osfamily,