From a041f67f4c294fb3534bcefe3d9b56d5a2fd37e8 Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Tue, 9 Mar 2021 16:30:46 +1300 Subject: [PATCH 01/11] Allow passing instances as hash to http_check --- functions/clean_empty.pp | 18 +++ manifests/integrations/http_check.pp | 100 +++++++++++----- ...adog_agent_integrations_http_check_spec.rb | 52 +-------- templates/agent-conf.d/http_check.yaml.erb | 110 +----------------- 4 files changed, 97 insertions(+), 183 deletions(-) create mode 100644 functions/clean_empty.pp diff --git a/functions/clean_empty.pp b/functions/clean_empty.pp new file mode 100644 index 00000000..8e71ca78 --- /dev/null +++ b/functions/clean_empty.pp @@ -0,0 +1,18 @@ +# For cleaning up empty elements on hashes and arrays +function datadog_agent::clean_empty ( + Any $var +) { + if $var.is_a(Array) { + $_var = $var.map |$item| { datadog_agent::clean_empty($item) } + $result = $_var.filter |$item| { !$item.empty } + + } elsif $var.is_a(Hash) { + $_var = Hash($var.map |$key, $value| { Tuple([$key, datadog_agent::clean_empty($value)]) }) + $result = $_var.filter |$key, $value| { !$value.empty } + + } else { + $result = $var + } + + $result +} diff --git a/manifests/integrations/http_check.pp b/manifests/integrations/http_check.pp index 4f1c3155..7ecc1326 100644 --- a/manifests/integrations/http_check.pp +++ b/manifests/integrations/http_check.pp @@ -164,35 +164,37 @@ class datadog_agent::integrations::http_check ( - $sitename = undef, - $url = undef, - $username = undef, - $password = undef, - $timeout = 1, - $method = 'get', - $data = undef, - $threshold = undef, - $window = undef, - $content_match = undef, - $reverse_content_match = false, - $include_content = false, - $http_response_status_code = undef, - $collect_response_time = true, - $disable_ssl_validation = false, - $ignore_ssl_warning = false, - $skip_event = true, - $no_proxy = false, - $check_certificate_expiration = true, - $days_warning = undef, - $days_critical = undef, + $sitename = undef, + $url = undef, + $username = undef, + $password = undef, + $timeout = 1, + $method = 'get', + $data = undef, + $threshold = undef, + $window = undef, + $content_match = undef, + $reverse_content_match = false, + $include_content = false, + $http_response_status_code = undef, + $collect_response_time = true, + $disable_ssl_validation = false, + $ignore_ssl_warning = false, + $skip_event = true, + $no_proxy = false, + $check_certificate_expiration = true, + $days_warning = undef, + $days_critical = undef, Optional[Boolean] $check_hostname = undef, Optional[String] $ssl_server_name = undef, - $headers = [], - $allow_redirects = true, - $tags = [], - $contact = [], - Optional[Array] $instances = undef, - $ca_certs = undef, + $headers = [], + $allow_redirects = true, + $tags = [], + $contact = [], + Optional[Hash] $init_config = undef, + Optional[Array] $instances = undef, + Optional[Array] $logs = undef, + $ca_certs = undef, ) inherits datadog_agent::params { include datadog_agent @@ -227,12 +229,54 @@ 'contact' => $contact, 'ca_certs' => $ca_certs, }] - } elsif !$instances{ + } elsif !$instances { $_instances = [] } else { $_instances = $instances } + $instances_array = $_instances.map |$instance| { + Hash($instance.map |$key, $value| { + case $key { + 'sitename': { + Tuple(['name', $value]) + } + + 'days_warning', 'days_critical', 'check_hostname', 'ssl_server_name': { + if $instance['check_certificate_expiration'] == false { + Tuple([undef, undef]).next + } + Tuple([$key, $value]) + } + + 'data', 'headers': { + $_value = datadog_agent::clean_empty($value) + if !$_value.is_a(Array) { + Tuple([$key, $_value]).next + } + + $value_array = $_value.filter |$item| { $item =~ /:/ } + $value_hash = Hash($_value.map |$item| { + $_item = $item.split(':') + $i_key = $_item[0].rstrip + $i_value = $_item[1, - 1].join(':').lstrip + + Tuple([$i_key, $i_value]) + }) + + Tuple([$key, datadog_agent::clean_empty($value_hash)]) + } + + 'tags': { + Tuple([$key, datadog_agent::clean_empty($value)]) + } + + default: { + Tuple([$key, $value]) } + } + }) + } + $legacy_dst = "${datadog_agent::params::legacy_conf_dir}/http_check.yaml" if $::datadog_agent::_agent_major_version > 5 { $dst_dir = "${datadog_agent::params::conf_dir}/http_check.d" diff --git a/spec/classes/datadog_agent_integrations_http_check_spec.rb b/spec/classes/datadog_agent_integrations_http_check_spec.rb index 4de07344..94b0de64 100644 --- a/spec/classes/datadog_agent_integrations_http_check_spec.rb +++ b/spec/classes/datadog_agent_integrations_http_check_spec.rb @@ -64,7 +64,7 @@ collect_response_time: false, disable_ssl_validation: true, skip_event: true, - http_response_status_code: '503', + http_response_status_code: 503, no_proxy: true, check_certificate_expiration: true, days_warning: 14, @@ -83,7 +83,7 @@ it { is_expected.to contain_file(conf_file).with_content(%r{data: key=value}) } it { is_expected.to contain_file(conf_file).with_content(%r{threshold: 456}) } it { is_expected.to contain_file(conf_file).with_content(%r{window: 789}) } - it { is_expected.to contain_file(conf_file).with_content(%r{content_match: 'foomatch'}) } + it { is_expected.to contain_file(conf_file).with_content(%r{content_match: foomatch}) } it { is_expected.to contain_file(conf_file).with_content(%r{reverse_content_match: true}) } it { is_expected.to contain_file(conf_file).with_content(%r{include_content: true}) } it { is_expected.to contain_file(conf_file).without_content(%r{collect_response_time: true}) } @@ -95,7 +95,7 @@ it { is_expected.to contain_file(conf_file).with_content(%r{days_warning: 14}) } it { is_expected.to contain_file(conf_file).with_content(%r{days_critical: 7}) } it { is_expected.to contain_file(conf_file).with_content(%r{allow_redirects: true}) } - it { is_expected.to contain_file(conf_file).with_content(%r{ca_certs: /dev/null}) } + it { is_expected.to contain_file(conf_file).with_content(%r{ca_certs: "/dev/null"}) } end context 'with json post data' do @@ -114,52 +114,6 @@ it { is_expected.to contain_file(conf_file).with_content(%r{headers:\s+Content-Type:\s+application/json}) } end - context 'with headers parameter array' do - let(:params) do - { - sitename: 'foo.bar.baz', - url: 'http://foo.bar.baz:4096', - headers: ['foo', 'bar', 'baz'], - } - end - - it { is_expected.to contain_file(conf_file).with_content(%r{headers:\s+foo\s+bar\s+baz\s*?[^-]}m) } - end - - context 'with headers parameter empty values' do - context 'mixed in with other headers' do - let(:params) do - { - sitename: 'foo.bar.baz', - url: 'http://foo.bar.baz:4096', - headers: ['foo', '', 'baz'], - } - end - - it { is_expected.to contain_file(conf_file).with_content(%r{headers:\s+foo\s+baz\s*?[^-]}m) } - end - - context 'single element array of an empty string' do - let(:params) do - { - headers: [''], - } - end - - skip('undefined behavior') - end - - context 'single value empty string' do - let(:params) do - { - headers: '', - } - end - - skip('doubly undefined behavior') - end - end - context 'with tags parameter array' do let(:params) do { diff --git a/templates/agent-conf.d/http_check.yaml.erb b/templates/agent-conf.d/http_check.yaml.erb index 30ebdbb2..638a920d 100644 --- a/templates/agent-conf.d/http_check.yaml.erb +++ b/templates/agent-conf.d/http_check.yaml.erb @@ -1,109 +1,7 @@ ### MANAGED BY PUPPET -init_config: +<% +require 'yaml' +%> -instances: -<%- (Array(@_instances)).each do |instance| -%> - - name: <%= instance['sitename'] %> - url: <%= instance['url'] %> -<% if instance['timeout'] -%> - timeout: <%= instance['timeout'] %> -<% end -%> -<% if instance['method'] -%> - method: <%= instance['method'] %> -<% end -%> -<% if instance['data'].is_a?(String) -%> - data: <%= instance['data'] %> -<% elsif instance['data'].is_a?(Array) -%> - data: - <%- instance['data'].each do |data| -%> - <%= data %> - <%- end -%> -<% end -%> -<% if instance['username'] -%> - username: <%= instance['username'] %> -<% end -%> -<% if instance['password'] -%> - password: <%= instance['password'] %> -<% end -%> -<% if instance['threshold'] -%> - threshold: <%= instance['threshold'] %> -<% end -%> -<% if instance['window'] -%> - window: <%= instance['window'] %> -<% end -%> -<% if instance['reverse_content_match'] -%> - reverse_content_match: <%= instance["reverse_content_match"] %> -<% end -%> -<% if instance['content_match'] -%> - content_match: '<%= instance["content_match"] %>' -<% end -%> -<% unless instance['include_content'].nil? -%> - include_content: <%= instance['include_content'] %> -<% end -%> -<% if instance['http_response_status_code'] -%> - http_response_status_code: <%= instance['http_response_status_code'] %> -<% end -%> -<% unless instance['collect_response_time'].nil? -%> - collect_response_time: <%= instance['collect_response_time'] %> -<% end -%> -<% unless instance['disable_ssl_validation'].nil? -%> - disable_ssl_validation: <%= instance['disable_ssl_validation'] %> -<% end -%> -<% unless instance['ignore_ssl_warning'].nil? -%> - ignore_ssl_warning: <%= instance['ignore_ssl_warning'] %> -<% end -%> -<% unless instance['skip_event'].nil? -%> - skip_event: <%= instance['skip_event'] %> -<% end -%> -<% unless instance['no_proxy'].nil? -%> - no_proxy: <%= instance['no_proxy'] %> -<% end -%> -<% if instance['ca_certs'] -%> - ca_certs: <%= instance['ca_certs'] %> -<% end -%> -<% unless instance['check_certificate_expiration'].nil? -%> - check_certificate_expiration: <%= instance['check_certificate_expiration'] %> -<% if instance['check_certificate_expiration'] == true -%> -<% if instance['days_warning'] -%> - days_warning: <%= instance['days_warning'] %> -<% end -%> -<% if instance['days_critical'] -%> - days_critical: <%= instance['days_critical'] %> -<% end -%> -<% if instance['check_hostname'] -%> - check_hostname: <%= instance['check_hostname'] %> -<% end -%> -<% if instance['ssl_server_name'] -%> - ssl_server_name: <%= instance['ssl_server_name'] %> -<% end -%> -<% end -%> -<% end -%> -<% if instance['headers'] and ! instance['headers'].empty? -%> - headers: - <%- Array(instance['headers']).each do |header| -%> - <%- if header != '' -%> - <%= header %> - <%- end -%> - <%- end -%> -<% end -%> -<% unless instance['allow_redirects'].nil? -%> - allow_redirects: <%= instance['allow_redirects'] %> -<% end -%> -<% if instance['tags'] and ! instance['tags'].empty? -%> - tags: - <%- Array(instance['tags']).each do |tag| -%> - <%- if tag != '' -%> - - <%= tag %> - <%- end -%> - <%- end -%> -<% end -%> -<% if instance['contacts'] and ! instance['contacts'].empty? -%> - notify: - <%- Array(instance['contacts']).each do |contact| -%> - <%- if contact != '' -%> - - <%= contact %> - <%- end -%> - <%- end -%> -<% end -%> -<% end -%> +<%= {'init_config'=>@init_config, 'instances'=>@instances_array, 'logs'=>@logs}.to_yaml %> From f94376d5f7e8d15b9b0d0459fbf6d58c5ce6bfec Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Tue, 9 Mar 2021 16:54:52 +1300 Subject: [PATCH 02/11] Add test case --- ...adog_agent_integrations_http_check_spec.rb | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/spec/classes/datadog_agent_integrations_http_check_spec.rb b/spec/classes/datadog_agent_integrations_http_check_spec.rb index 94b0de64..c985823b 100644 --- a/spec/classes/datadog_agent_integrations_http_check_spec.rb +++ b/spec/classes/datadog_agent_integrations_http_check_spec.rb @@ -172,6 +172,62 @@ it { is_expected.to contain_file(conf_file).with_content(%r{notify:\s+- alice\s+bob\s+carlo}) } end end + + context 'with instances hash' do + let(:params) do + { + instances: [ + { + 'name' => 'foo.bar.baz', + 'url' => 'http://foo.bar.baz:4096', + 'username' => 'foouser', + 'password' => 'barpassword', + 'timeout' => 123, + 'method' => 'post', + 'data' => 'key=value', + 'threshold' => 456, + 'window' => 789, + 'content_match' => 'foomatch', + 'reverse_content_match' => true, + 'include_content' => true, + 'collect_response_time' => false, + 'disable_ssl_validation' => true, + 'skip_event' => true, + 'http_response_status_code' => 503, + 'no_proxy' => true, + 'check_certificate_expiration' => true, + 'days_warning' => 14, + 'days_critical' => 7, + 'allow_redirects' => true, + 'ca_certs' => '/dev/null', + }, + ], + } + end + + it { is_expected.to contain_file(conf_file).with_content(%r{name: foo.bar.baz}) } + it { is_expected.to contain_file(conf_file).with_content(%r{url: http://foo.bar.baz:4096}) } + it { is_expected.to contain_file(conf_file).with_content(%r{username: foouser}) } + it { is_expected.to contain_file(conf_file).with_content(%r{password: barpassword}) } + it { is_expected.to contain_file(conf_file).with_content(%r{timeout: 123}) } + it { is_expected.to contain_file(conf_file).with_content(%r{method: post}) } + it { is_expected.to contain_file(conf_file).with_content(%r{data: key=value}) } + it { is_expected.to contain_file(conf_file).with_content(%r{threshold: 456}) } + it { is_expected.to contain_file(conf_file).with_content(%r{window: 789}) } + it { is_expected.to contain_file(conf_file).with_content(%r{content_match: foomatch}) } + it { is_expected.to contain_file(conf_file).with_content(%r{reverse_content_match: true}) } + it { is_expected.to contain_file(conf_file).with_content(%r{include_content: true}) } + it { is_expected.to contain_file(conf_file).without_content(%r{collect_response_time: true}) } + it { is_expected.to contain_file(conf_file).with_content(%r{disable_ssl_validation: true}) } + it { is_expected.to contain_file(conf_file).with_content(%r{skip_event: true}) } + it { is_expected.to contain_file(conf_file).with_content(%r{http_response_status_code: 503}) } + it { is_expected.to contain_file(conf_file).with_content(%r{no_proxy: true}) } + it { is_expected.to contain_file(conf_file).with_content(%r{check_certificate_expiration: true}) } + it { is_expected.to contain_file(conf_file).with_content(%r{days_warning: 14}) } + it { is_expected.to contain_file(conf_file).with_content(%r{days_critical: 7}) } + it { is_expected.to contain_file(conf_file).with_content(%r{allow_redirects: true}) } + it { is_expected.to contain_file(conf_file).with_content(%r{ca_certs: "/dev/null"}) } + end end end end From 1f2415254ab367e00efa64bae4d316fb083f06bd Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Tue, 9 Mar 2021 16:55:09 +1300 Subject: [PATCH 03/11] Remove unnecessary checks --- manifests/integrations/http_check.pp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/manifests/integrations/http_check.pp b/manifests/integrations/http_check.pp index 7ecc1326..326863ef 100644 --- a/manifests/integrations/http_check.pp +++ b/manifests/integrations/http_check.pp @@ -242,13 +242,6 @@ Tuple(['name', $value]) } - 'days_warning', 'days_critical', 'check_hostname', 'ssl_server_name': { - if $instance['check_certificate_expiration'] == false { - Tuple([undef, undef]).next - } - Tuple([$key, $value]) - } - 'data', 'headers': { $_value = datadog_agent::clean_empty($value) if !$_value.is_a(Array) { From e69e610a527af78f2bfee3d5e5a00dc39ba071b0 Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Tue, 9 Mar 2021 17:07:48 +1300 Subject: [PATCH 04/11] Cleanup template --- templates/agent-conf.d/http_check.yaml.erb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/templates/agent-conf.d/http_check.yaml.erb b/templates/agent-conf.d/http_check.yaml.erb index 638a920d..b6de23b9 100644 --- a/templates/agent-conf.d/http_check.yaml.erb +++ b/templates/agent-conf.d/http_check.yaml.erb @@ -1,7 +1,3 @@ ### MANAGED BY PUPPET - -<% -require 'yaml' -%> - +<% require 'yaml' -%> <%= {'init_config'=>@init_config, 'instances'=>@instances_array, 'logs'=>@logs}.to_yaml %> From c87d13c4756003fd8be19f4df10cfa7784de42c1 Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Wed, 10 Mar 2021 10:11:52 +1300 Subject: [PATCH 05/11] Allow passing instances as hash to apache --- manifests/integrations/apache.pp | 25 +++++++++++++++---- .../datadog_agent_integrations_apache_spec.rb | 19 ++++++++++++++ templates/agent-conf.d/apache.yaml.erb | 25 ++----------------- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/manifests/integrations/apache.pp b/manifests/integrations/apache.pp index 247d57a0..163a09b1 100644 --- a/manifests/integrations/apache.pp +++ b/manifests/integrations/apache.pp @@ -27,14 +27,29 @@ # } # class datadog_agent::integrations::apache ( - String $url = 'http://localhost/server-status?auto', - Optional[String] $username = undef, - Optional[String] $password = undef, - Array $tags = [], - Boolean $disable_ssl_validation = false + String $url = 'http://localhost/server-status?auto', + Optional[String] $username = undef, + Optional[String] $password = undef, + Array $tags = [], + Optional[Boolean] $disable_ssl_validation = undef, + Optional[Hash] $init_config = undef, + Optional[Array] $instances = undef, + Optional[Array] $logs = undef, ) inherits datadog_agent::params { include datadog_agent + if !$instances { + $_instances = datadog_agent::clean_empty([{ + 'apache_status_url' => $url, + 'apache_user' => $username, + 'apache_password' => $password, + 'tags' => $tags, + 'disable_ssl_validation' => $disable_ssl_validation, + }]) + } else { + $_instances = $instances + } + $legacy_dst = "${datadog_agent::params::legacy_conf_dir}/apache.yaml" if $::datadog_agent::_agent_major_version > 5 { $dst_dir = "${datadog_agent::params::conf_dir}/apache.d" diff --git a/spec/classes/datadog_agent_integrations_apache_spec.rb b/spec/classes/datadog_agent_integrations_apache_spec.rb index eef84648..3ab8dba6 100644 --- a/spec/classes/datadog_agent_integrations_apache_spec.rb +++ b/spec/classes/datadog_agent_integrations_apache_spec.rb @@ -100,6 +100,25 @@ skip('doubly undefined behavior') end + + context 'with instances hash' do + let(:params) do + { + instances: [ + { + 'apache_status_url' => 'http://foobar', + 'apache_user' => 'userfoo', + 'apache_password' => 'passfoo', + 'tags' => ['foo', 'bar', 'baz'], + }, + ], + } + end + + it { is_expected.to contain_file(conf_file).with_content(%r{apache_status_url: http://foobar}) } + it { is_expected.to contain_file(conf_file).with_content(%r{apache_user: userfoo}) } + it { is_expected.to contain_file(conf_file).with_content(%r{apache_password: passfoo}) } + end end end end diff --git a/templates/agent-conf.d/apache.yaml.erb b/templates/agent-conf.d/apache.yaml.erb index 93afc187..1570f936 100644 --- a/templates/agent-conf.d/apache.yaml.erb +++ b/templates/agent-conf.d/apache.yaml.erb @@ -1,24 +1,3 @@ ### MANAGED BY PUPPET - -init_config: - -instances: - - apache_status_url: <%= @url %> -<% if @disable_ssl_validation -%> - disable_ssl_validation: <%= @disable_ssl_validation %> -<% end -%> -<% if @username -%> - apache_user: <%= @username %> -<% end -%> -<% if @password -%> - apache_password: <%= @password %> -<% end -%> -<% if @tags and ! @tags.empty? -%> - tags: - <%- Array(@tags).each do |tag| -%> - <%- if tag != '' -%> - - <%= tag %> - <%- end -%> - <%- end -%> -<% end -%> - +<% require 'yaml' -%> +<%= {'init_config'=>@init_config, 'instances'=>@_instances, 'logs'=>@logs}.to_yaml %> From a108e55e36ab994ffdbfaee795fbe53c76476238 Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Sat, 19 Feb 2022 18:40:34 +1300 Subject: [PATCH 06/11] Remove Puppet 4.6 support --- .circleci/config.yml | 44 ++------------------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b280b331..d2f548b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,12 +2,12 @@ version: 2.1 orbs: win: circleci/windows@2.2.0 jobs: - specs-ruby21-puppet46: &specs + specs-ruby21-puppet410: &specs machine: true environment: STRICT_VARIABLES: 'yes' RUBY_VERSION: '2.1.9' - PUPPET_VERSION: '4.6.2' + PUPPET_VERSION: '4.10.9' steps: - checkout - run: @@ -23,13 +23,6 @@ jobs: name: Run tests command: rvm $RUBY_VERSION --verbose do bundle exec rake test - specs-ruby21-puppet410: - <<: *specs - environment: - STRICT_VARIABLES: 'yes' - RUBY_VERSION: '2.1.9' - PUPPET_VERSION: '4.10.9' - specs-ruby21-puppet50: <<: *specs environment: @@ -48,13 +41,6 @@ jobs: #specs-ruby21-puppet60 #specs-ruby21-puppet65 - specs-ruby22-puppet46: - <<: *specs - environment: - STRICT_VARIABLES: 'yes' - RUBY_VERSION: '2.2.3' - PUPPET_VERSION: '4.6.2' - specs-ruby22-puppet410: <<: *specs environment: @@ -80,13 +66,6 @@ jobs: #specs-ruby22-puppet60 #specs-ruby22-puppet65 - specs-ruby23-puppet46: - <<: *specs - environment: - STRICT_VARIABLES: 'yes' - RUBY_VERSION: '2.3.6' - PUPPET_VERSION: '4.6.2' - specs-ruby23-puppet410: <<: *specs environment: @@ -122,13 +101,6 @@ jobs: RUBY_VERSION: '2.3.6' PUPPET_VERSION: '6.5.0' - specs-ruby24-puppet46: - <<: *specs - environment: - STRICT_VARIABLES: 'yes' - RUBY_VERSION: '2.4.3' - PUPPET_VERSION: '4.6.2' - specs-ruby24-puppet410: <<: *specs environment: @@ -164,13 +136,6 @@ jobs: RUBY_VERSION: '2.4.3' PUPPET_VERSION: '6.5.0' - specs-ruby25-puppet46: - <<: *specs - environment: - STRICT_VARIABLES: 'yes' - RUBY_VERSION: '2.5.3' - PUPPET_VERSION: '4.6.2' - specs-ruby25-puppet410: <<: *specs environment: @@ -295,27 +260,22 @@ workflows: version: 2 build_and_test: jobs: - - specs-ruby21-puppet46 - specs-ruby21-puppet410 - specs-ruby21-puppet50 - specs-ruby21-puppet53 - - specs-ruby22-puppet46 - specs-ruby22-puppet410 - specs-ruby22-puppet50 - specs-ruby22-puppet53 - - specs-ruby23-puppet46 - specs-ruby23-puppet410 - specs-ruby23-puppet50 - specs-ruby23-puppet53 - specs-ruby23-puppet60 - specs-ruby23-puppet65 - - specs-ruby24-puppet46 - specs-ruby24-puppet410 - specs-ruby24-puppet50 - specs-ruby24-puppet53 - specs-ruby24-puppet60 - specs-ruby24-puppet65 - - specs-ruby25-puppet46 - specs-ruby25-puppet410 - specs-ruby25-puppet50 - specs-ruby25-puppet53 From d62d6a73e417f786e9bd216f3984672c2a4832d1 Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Sat, 19 Feb 2022 18:41:23 +1300 Subject: [PATCH 07/11] Update clean_empty.pp --- functions/clean_empty.pp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/functions/clean_empty.pp b/functions/clean_empty.pp index 8e71ca78..e146ae54 100644 --- a/functions/clean_empty.pp +++ b/functions/clean_empty.pp @@ -4,15 +4,13 @@ function datadog_agent::clean_empty ( ) { if $var.is_a(Array) { $_var = $var.map |$item| { datadog_agent::clean_empty($item) } - $result = $_var.filter |$item| { !$item.empty } + $_var.filter |$item| { !$item.empty } } elsif $var.is_a(Hash) { $_var = Hash($var.map |$key, $value| { Tuple([$key, datadog_agent::clean_empty($value)]) }) - $result = $_var.filter |$key, $value| { !$value.empty } + $_var.filter |$key, $value| { !$value.empty } - } else { - $result = $var + } elsif !$var.empty { + $var } - - $result } From 2fff883d5f0f6afec292ce5974f6bd9f4653070e Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Sat, 19 Feb 2022 19:01:42 +1300 Subject: [PATCH 08/11] Cleanup http_check.pp --- manifests/integrations/http_check.pp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/manifests/integrations/http_check.pp b/manifests/integrations/http_check.pp index a0b218b9..1c0e4f3a 100644 --- a/manifests/integrations/http_check.pp +++ b/manifests/integrations/http_check.pp @@ -235,7 +235,7 @@ 'contact' => $contact, 'ca_certs' => $ca_certs, }] - } elsif !$instances{ + } elsif !$instances { $_instances = [] } else { $_instances = $instances @@ -254,7 +254,6 @@ Tuple([$key, $_value]).next } - $value_array = $_value.filter |$item| { $item =~ /:/ } $value_hash = Hash($_value.map |$item| { $_item = $item.split(':') $i_key = $_item[0].rstrip @@ -271,7 +270,8 @@ } default: { - Tuple([$key, $value]) } + Tuple([$key, $value]) + } } }) } From e839962a98be79429383ac40e5e9559de5a26718 Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Sat, 19 Feb 2022 19:19:25 +1300 Subject: [PATCH 09/11] Update http_check.pp --- manifests/integrations/http_check.pp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/manifests/integrations/http_check.pp b/manifests/integrations/http_check.pp index 1c0e4f3a..51d73877 100644 --- a/manifests/integrations/http_check.pp +++ b/manifests/integrations/http_check.pp @@ -249,17 +249,16 @@ } 'data', 'headers': { - $_value = datadog_agent::clean_empty($value) - if !$_value.is_a(Array) { - Tuple([$key, $_value]).next + if !$value.is_a(Array) { + Tuple([$key, $value]).next } - $value_hash = Hash($_value.map |$item| { - $_item = $item.split(':') - $i_key = $_item[0].rstrip - $i_value = $_item[1, - 1].join(':').lstrip + $value_hash = Hash($value.map |$item| { + $sub_item_array = $item.split(':') + $sub_item_key = $sub_item_array[0].rstrip + $sub_item_value = $sub_item_array[1, - 1].join(':').lstrip - Tuple([$i_key, $i_value]) + Tuple([$sub_item_key, $sub_item_value]) }) Tuple([$key, datadog_agent::clean_empty($value_hash)]) From 76e968a5593a6e9555310ec023c7d9b98e5f008c Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Tue, 12 Jul 2022 01:42:10 +1200 Subject: [PATCH 10/11] Fix datadog_agent::clean_empty function --- functions/clean_empty.pp | 6 +++--- functions/is_empty.pp | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 functions/is_empty.pp diff --git a/functions/clean_empty.pp b/functions/clean_empty.pp index e146ae54..11e08b93 100644 --- a/functions/clean_empty.pp +++ b/functions/clean_empty.pp @@ -4,13 +4,13 @@ function datadog_agent::clean_empty ( ) { if $var.is_a(Array) { $_var = $var.map |$item| { datadog_agent::clean_empty($item) } - $_var.filter |$item| { !$item.empty } + $_var.filter |$item| { !datadog_agent::is_empty($item) } } elsif $var.is_a(Hash) { $_var = Hash($var.map |$key, $value| { Tuple([$key, datadog_agent::clean_empty($value)]) }) - $_var.filter |$key, $value| { !$value.empty } + $_var.filter |$key, $value| { !datadog_agent::is_empty($value) } - } elsif !$var.empty { + } elsif !datadog_agent::is_empty($var) { $var } } diff --git a/functions/is_empty.pp b/functions/is_empty.pp new file mode 100644 index 00000000..5b038998 --- /dev/null +++ b/functions/is_empty.pp @@ -0,0 +1,10 @@ +# For testing if variable is empty +function datadog_agent::is_empty ( + Any $var +) { + if $var.is_a(Collection) or $var.is_a(String) or $var.is_a(Numeric) or $var.is_a(Binary) or $var.is_a(Undef) { + $var.empty + } else { + false + } +} \ No newline at end of file From dee980f79f5f92ca685dcd16914d84cae6ad8c88 Mon Sep 17 00:00:00 2001 From: Andre Sencioles Date: Tue, 12 Jul 2022 01:48:37 +1200 Subject: [PATCH 11/11] Allow passing instances as hash to mysql --- manifests/integrations/mysql.pp | 72 +++++++++++++------ .../datadog_agent_integrations_mysql_spec.rb | 54 ++++++++++++-- templates/agent-conf.d/mysql.yaml.erb | 56 +-------------- 3 files changed, 99 insertions(+), 83 deletions(-) diff --git a/manifests/integrations/mysql.pp b/manifests/integrations/mysql.pp index 0781b121..05d409d9 100644 --- a/manifests/integrations/mysql.pp +++ b/manifests/integrations/mysql.pp @@ -63,13 +63,13 @@ # } # # -class datadog_agent::integrations::mysql( +class datadog_agent::integrations::mysql ( String $host = 'localhost', Optional[String] $user = 'datadog', Optional[Variant[String, Integer]] $port = 3306, Optional[String] $password = undef, Optional[String] $sock = undef, - Array $tags = [], + Optional[Array] $tags = undef, $replication = '0', $galera_cluster = '0', Boolean $extra_status_metrics = false, @@ -77,10 +77,11 @@ Boolean $extra_performance_metrics = false, Boolean $schema_size_metrics = false, Boolean $disable_innodb_metrics = false, - Optional[Array] $queries = [], + Optional[Array] $queries = undef, + Optional[Hash] $init_config = undef, Optional[Array] $instances = undef, - Optional[Array] $logs = [], - ) inherits datadog_agent::params { + Optional[Array] $logs = undef, +) inherits datadog_agent::params { require ::datadog_agent if ($host == undef and $sock == undef) or @@ -89,26 +90,51 @@ } if !$instances and $host { - $_instances = [{ - 'host' => $host, - 'password' => $password, - 'user' => $user, - 'port' => $port, - 'sock' => $sock, - 'tags' => $tags, - 'replication' => $replication, - 'galera_cluster' => $galera_cluster, - 'extra_status_metrics' => $extra_status_metrics, - 'extra_innodb_metrics' => $extra_innodb_metrics, - 'extra_performance_metrics' => $extra_performance_metrics, - 'schema_size_metrics' => $schema_size_metrics, - 'disable_innodb_metrics' => $disable_innodb_metrics, - 'queries' => $queries, - }] - } elsif !$instances{ + $_instances = datadog_agent::clean_empty([{ + 'server' => $host, + 'pass' => $password, + 'user' => $user, + 'port' => $port, + 'sock' => $sock, + 'tags' => $tags, + 'options' => { + 'replication' => $replication, + 'galera_cluster' => $galera_cluster, + 'extra_status_metrics' => $extra_status_metrics, + 'extra_innodb_metrics' => $extra_innodb_metrics, + 'extra_performance_metrics' => $extra_performance_metrics, + 'schema_size_metrics' => $schema_size_metrics, + 'disable_innodb_metrics' => $disable_innodb_metrics, + }, + 'queries' => $queries, + }]) + } elsif !$instances { $_instances = [] } else { - $_instances = $instances + $_instances = datadog_agent::clean_empty($instances.map |$instance| { + if $instance['host'] { + { + 'server' => $instance['host'], + 'pass' => $instance['password'], + 'user' => $instance['user'], + 'port' => $instance['port'], + 'sock' => $instance['sock'], + 'tags' => $instance['tags'], + 'options' => { + 'replication' => $instance['replication'], + 'galera_cluster' => $instance['galera_cluster'], + 'extra_status_metrics' => $instance['extra_status_metrics'], + 'extra_innodb_metrics' => $instance['extra_innodb_metrics'], + 'extra_performance_metrics' => $instance['extra_performance_metrics'], + 'schema_size_metrics' => $instance['schema_size_metrics'], + 'disable_innodb_metrics' => $instance['disable_innodb_metrics'], + }, + 'queries' => $queries, + } + } else { + $instance + } + }) } $legacy_dst = "${datadog_agent::params::legacy_conf_dir}/mysql.yaml" diff --git a/spec/classes/datadog_agent_integrations_mysql_spec.rb b/spec/classes/datadog_agent_integrations_mysql_spec.rb index 74c86804..746d5bad 100644 --- a/spec/classes/datadog_agent_integrations_mysql_spec.rb +++ b/spec/classes/datadog_agent_integrations_mysql_spec.rb @@ -40,8 +40,8 @@ it { is_expected.to contain_file(conf_file).with_content(%r{server: localhost}) } it { is_expected.to contain_file(conf_file).with_content(%r{user: datadog}) } it { is_expected.to contain_file(conf_file).without_content(%r{sock: }) } - it { is_expected.to contain_file(conf_file).with_content(%r{replication: 0}) } - it { is_expected.to contain_file(conf_file).with_content(%r{galera_cluster: 0}) } + it { is_expected.to contain_file(conf_file).with_content(%r{replication: '0'}) } + it { is_expected.to contain_file(conf_file).with_content(%r{galera_cluster: '0'}) } end end @@ -60,9 +60,9 @@ it { is_expected.to contain_file(conf_file).with_content(%r{pass: foobar}) } it { is_expected.to contain_file(conf_file).with_content(%r{server: mysql1}) } it { is_expected.to contain_file(conf_file).with_content(%r{user: baz}) } - it { is_expected.to contain_file(conf_file).with_content(%r{sock: /tmp/mysql.foo.sock}) } - it { is_expected.to contain_file(conf_file).with_content(%r{replication: 1}) } - it { is_expected.to contain_file(conf_file).with_content(%r{galera_cluster: 1}) } + it { is_expected.to contain_file(conf_file).with_content(%r{sock: "/tmp/mysql.foo.sock"}) } + it { is_expected.to contain_file(conf_file).with_content(%r{replication: '1'}) } + it { is_expected.to contain_file(conf_file).with_content(%r{galera_cluster: '1'}) } end context 'with tags parameter array' do @@ -103,7 +103,49 @@ end it { is_expected.to contain_file(conf_file).with_content(%r{- query}) } - it { is_expected.to contain_file(conf_file).with_content(%r{query: SELECT TIMESTAMPDIFF\(second,MAX\(create_time\),NOW\(\)\) as last_accessed FROM requests}) } + it { is_expected.to contain_file(conf_file).with_content(%r{query: SELECT TIMESTAMPDIFF\(second,MAX\(create_time\),NOW\(\)\) as last_accessed FROM}) } + it { is_expected.to contain_file(conf_file).with_content(%r{metric: app.seconds_since_last_request}) } + it { is_expected.to contain_file(conf_file).with_content(%r{type: gauge}) } + it { is_expected.to contain_file(conf_file).with_content(%r{field: last_accessed}) } + end + + context 'with instances hash' do + let(:params) do + { + instances: [ + { + 'server' => 'mysql1', + 'pass' => 'foobar', + 'user' => 'baz', + 'sock' => '/tmp/mysql.foo.sock', + 'tags' => ['foo', 'bar', 'baz'], + 'options' => { + 'replication' => 1, + 'galera_cluster' => 1, + }, + 'queries' => [ + { + 'query' => 'SELECT TIMESTAMPDIFF(second,MAX(create_time),NOW()) as last_accessed FROM requests', + 'metric' => 'app.seconds_since_last_request', + 'type' => 'gauge', + 'field' => 'last_accessed', + }, + ], + }, + ], + } + end + + it { is_expected.to contain_file(conf_file).with_content(%r{server: mysql1}) } + it { is_expected.to contain_file(conf_file).with_content(%r{pass: foobar}) } + it { is_expected.to contain_file(conf_file).with_content(%r{user: baz}) } + it { is_expected.to contain_file(conf_file).with_content(%r{sock: "/tmp/mysql.foo.sock"}) } + it { is_expected.to contain_file(conf_file).with_content(%r{tags:[^-]+- foo\s+- bar\s+- baz\s*?[^-]}m) } + it { is_expected.to contain_file(conf_file).with_content(%r{options:}) } + it { is_expected.to contain_file(conf_file).with_content(%r{replication: 1}) } + it { is_expected.to contain_file(conf_file).with_content(%r{galera_cluster: 1}) } + it { is_expected.to contain_file(conf_file).with_content(%r{- query}) } + it { is_expected.to contain_file(conf_file).with_content(%r{query: SELECT TIMESTAMPDIFF\(second,MAX\(create_time\),NOW\(\)\) as last_accessed FROM}) } it { is_expected.to contain_file(conf_file).with_content(%r{metric: app.seconds_since_last_request}) } it { is_expected.to contain_file(conf_file).with_content(%r{type: gauge}) } it { is_expected.to contain_file(conf_file).with_content(%r{field: last_accessed}) } diff --git a/templates/agent-conf.d/mysql.yaml.erb b/templates/agent-conf.d/mysql.yaml.erb index 44c82873..1570f936 100644 --- a/templates/agent-conf.d/mysql.yaml.erb +++ b/templates/agent-conf.d/mysql.yaml.erb @@ -1,55 +1,3 @@ ### MANAGED BY PUPPET - -<% -require 'yaml' -%> - -init_config: - -instances: -<%- (Array(@_instances)).each do |instance| -%> - - server: <%= instance['host'] %> -<% if instance['user'] and instance['user'] != :undef -%> - user: <%= instance['user'] %> -<% end -%> -<% if instance['password'] and instance['password'] != :undef -%> - pass: <%= instance['password'] %> -<% end -%> -<% if instance['port'] and instance['port'] != :undef -%> - port: <%= instance['port'] %> -<% end -%> -<% if instance['sock'] and instance['sock'] != :undef -%> - sock: <%= instance['sock'] %> -<% end -%> - -<% if instance['tags'] and ! instance['tags'].empty? -%> - tags: - <%- Array(instance['tags']).each do |tag| -%> - <%- if tag != '' -%> - - <%= tag %> - <%- end -%> - <%- end -%> -<% end -%> - - options: # Optional - replication: <%= instance['replication'] %> - galera_cluster: <%= instance['galera_cluster'] %> - extra_status_metrics: <%= instance['extra_status_metrics'] %> - extra_innodb_metrics: <%= instance['extra_innodb_metrics'] %> - extra_performance_metrics: <%= instance['extra_performance_metrics'] %> - schema_size_metrics: <%= instance['schema_size_metrics'] %> - disable_innodb_metrics: <%= instance['disable_innodb_metrics'] %> - - <% if instance['queries'] and ! instance['queries'].empty? %> - queries: - <%- Array(instance['queries']).each do |query| -%> - - query: <%= query['query'] %> - metric: <%= query['metric'] %> - type: <%= query['type'] %> - field: <%= query['field'] %> - <%- end -%> - <%- end -%> - -<% end -%> - -<%= (Array({'logs'=>@logs}.to_yaml.lines))[1..-1].join %> \ No newline at end of file +<% require 'yaml' -%> +<%= {'init_config'=>@init_config, 'instances'=>@_instances, 'logs'=>@logs}.to_yaml %>