diff --git a/manifests/integrations/jmx.pp b/manifests/integrations/jmx.pp new file mode 100644 index 00000000..038a7a97 --- /dev/null +++ b/manifests/integrations/jmx.pp @@ -0,0 +1,80 @@ +# Class: datadog_agent::integrations::jmx +# +# This class will install the necessary configuration for the jmx integration +# +# Parameters: +# $init_config: +# Hash of inital configuration, consisting of the following keys: +# +# custom_jar_paths: +# Array of paths to jars. Optional. +# +# $instances: +# Array of instance hashes, consisting of the following keys: +# +# name: +# Used in conjunction with jmx_url. Optional. +# tags: +# Hash of tags { 'env' => 'prod' }. Optional. +# host: +# The host jmx is running on. +# port: +# The JMX port. +# jmx_url: +# If the agent needs to connect to a non-default JMX URL, specify it here +# instead of a host and a port. If you use this you need to specify a ‘name’ +# for the instance. Optional. +# user: +# The username for connecting to the running JVM. Optional. +# password: +# The password for connecting to the running JVM. Optional. +# process_name_regex: +# Instead of specifying a host and port or jmx_url, the agent can +# connect using the attach api. This requires the JDK to be installed +# and the path to tools.jar to be set. Optional. +# tools_jar_path: +# To be set when process_name_regex is set. Optional. +# java_bin_path: +# The path to the Java binary. Should be set if the agent cannot find your java executable. Optional. +# java_options: +# Java JVM options. Optional. +# trust_store_path: +# The path to the trust store. Should be set if ssl is enabled. Optional. +# trust_store_password: +# The trust store password. Should be set if ssl is enabled. Optional. +# conf: +# Array of include/exclude hash pairs. Optional. +# Read http://docs.datadoghq.com/integrations/java/ to learn how to customize it. +# +# Sample Usage: +# +# class { 'datadog_agent::integrations::jmx': +# init_config => { +# custom_jar_paths => ['/path/to/custom.jar'] +# }, +# instances => [{ +# host => 'localhost', +# port => 7199, +# user => 'username', +# password => 'password', +# jmx_url => 'service:jmx:rmi:///jndi/rmi://myhost.host:9999/custompath' +# }], +# } +# +class datadog_agent::integrations::jmx( + $init_config = {}, + $instances = [], +) inherits datadog_agent::params { + include datadog_agent + + file { "${datadog_agent::params::conf_dir}/jmx.yaml": + ensure => file, + owner => $datadog_agent::params::dd_user, + group => $datadog_agent::params::dd_group, + mode => '0600', + content => template('datadog_agent/agent-conf.d/jmx.yaml.erb'), + require => Package[$datadog_agent::params::package_name], + notify => Service[$datadog_agent::params::service_name] + } + +} diff --git a/spec/classes/datadog_agent_integrations_jmx_spec.rb b/spec/classes/datadog_agent_integrations_jmx_spec.rb new file mode 100644 index 00000000..19c55712 --- /dev/null +++ b/spec/classes/datadog_agent_integrations_jmx_spec.rb @@ -0,0 +1,81 @@ +require 'spec_helper' + +describe 'datadog_agent::integrations::jmx' do + let(:facts) {{ + operatingsystem: 'Ubuntu', + }} + let(:conf_dir) { '/etc/dd-agent/conf.d' } + let(:dd_user) { 'dd-agent' } + let(:dd_group) { 'root' } + let(:dd_package) { 'datadog-agent' } + let(:dd_service) { 'datadog-agent' } + let(:conf_file) { "#{conf_dir}/jmx.yaml" } + + it { should compile.with_all_deps } + it { should contain_file(conf_file).with( + owner: dd_user, + group: dd_group, + mode: '0600', + )} + it { should contain_file(conf_file).that_requires("Package[#{dd_package}]") } + it { should contain_file(conf_file).that_notifies("Service[#{dd_service}]") } + + context 'with default parameters' do + it { should contain_file(conf_file).with_content(%r{init_config: \{\}}) } + it { should contain_file(conf_file).with_content(%r{instances: \[\]}) } + end + + context 'with parameters set' do + let(:params) do + { + 'init_config' => { + 'custom_jar_paths' => [ + '/path/to/custom/jarfile.jar', + '/path/to/another/custom/jarfile2.jar' + ] + }, + 'instances' => [{ + 'host' => 'jmx1', + 'port' => '867', + 'user' => 'userfoo', + 'password' => 'passbar', + 'jmx_url' => 'service:jmx:rmi:///jndi/rmi://myhost.host:9999/custompath', + 'tools_jar_path' => '/usr/lib/jvm/java-7-openjdk-amd64/lib/tools.jar', + 'java_options' => '-Xmx200m -Xms50m', + 'java_bin_path' => '/usr/java/jdk1.7.0_101/bin/java', + 'trust_store_path' => '/var/lib/jmx/trust_store_path', + 'trust_store_password' => 'hunter2', + 'tags' => { + 'foo' => 'bar', + 'baz' => 'bat' + }, + 'conf' => [{ + 'include' => { + 'domain' => 'my_domain' + } + }] + }] + } + end + it { should contain_file(conf_file).with_content(%r{- ["']?/path/to/custom/jarfile.jar["']?}) } + it { should contain_file(conf_file).with_content(%r{- ["']?/path/to/another/custom/jarfile2.jar["']?}) } + it { should contain_file(conf_file).with_content(%r{host: jmx1}) } + + # Stringification of integers. + # Puppet treats everything as a string, and then there seems to be + # quoting differences between YAML export deps for Puppet 3.x and Puppet 4.x. + # YAML defaults to string representation, but supports other types, so ends + # up quoting integers from Puppet to explicitly mark out they're strings. + it { should contain_file(conf_file).with_content(%r{port: ["']?867["']?}) } + + it { should contain_file(conf_file).with_content(%r{jmx_url: ["']?service:jmx:rmi:///jndi/rmi://myhost.host:9999/custompath["']?}) } + it { should contain_file(conf_file).with_content(%r{user: userfoo}) } + it { should contain_file(conf_file).with_content(%r{password: passbar}) } + it { should contain_file(conf_file).with_content(%r{java_bin_path: ["']?/usr/java/jdk1.7.0_101/bin/java["']?}) } + it { should contain_file(conf_file).with_content(%r{java_options: ["']?-Xmx200m -Xms50m["']?}) } + it { should contain_file(conf_file).with_content(%r{trust_store_path: ["']?/var/lib/jmx/trust_store_path["']?}) } + it { should contain_file(conf_file).with_content(%r{trust_store_password: hunter2}) } + it { should contain_file(conf_file).with_content(%r{tags:\s+foo: bar\s+baz: bat}) } + it { should contain_file(conf_file).with_content(%r{domain: my_domain}) } + end +end diff --git a/templates/agent-conf.d/jmx.yaml.erb b/templates/agent-conf.d/jmx.yaml.erb new file mode 100644 index 00000000..82816cb9 --- /dev/null +++ b/templates/agent-conf.d/jmx.yaml.erb @@ -0,0 +1,26 @@ +<% +require 'yaml' + +if RUBY_VERSION < "1.9" +# Hack to avoid ruby 1.8 always reordering the hashes and +# changing this template resource at every run +# See https://github.com/DataDog/puppet-datadog-agent/issues/43 +# Taken from http://www.dzone.com/snippets/generating-yaml-hashes-sorted +class Hash + # Replacing the to_yaml function so it'll serialize hashes sorted (by their keys) + # + # Original function is in /usr/lib/ruby/1.8/yaml/rubytypes.rb + def to_yaml( opts = {} ) + YAML::quick_emit( object_id, opts ) do |out| + out.map( taguri, to_yaml_style ) do |map| + sort.each do |k, v| # <-- here's my addition (the 'sort') + map.add( k, v ) + end + end + end + end +end +end +%> + +<%= {'init_config'=>@init_config, 'instances'=>@instances}.to_yaml %>