Commit 1ff19929 authored by Olivier Vielpeau's avatar Olivier Vielpeau

[custom_checks] Extend `monitor` LWRP to allow installing custom checks

Along with a recipe.

WIP, only on Linux for now.
parent a5108c00
......@@ -2,6 +2,10 @@ source 'https://supermarket.chef.io'
metadata
group :spec do
cookbook 'datadog_test', path: './spec/fixtures/site-cookbooks/datadog_test'
end
group :integration do
cookbook 'sudo'
end
......@@ -112,3 +112,18 @@ Usage
We are not making use of data_bags in this recipe at this time, as it is unlikely that you will have more than one API key and one application key.
For more deployment details, visit the [Datadog Documentation site](http://docs.datadoghq.com/).
Custom checks
-------------
To install your own custom checks with this cookbook, please follow the examples in the related [recipe](https://github.com/DataDog/chef-datadog/tree/master/recipes/custom_checks.rb).
The python check needs to live as a cookbook file in one of your cookbooks.
Alternatively, you can use the `datadog_monitor` resource from your own cookbooks:
```ruby
datadog_monitor 'my_custom_check' do
init_config {}
instances [{'parameter1': 'value1'}]
custom_check true
end
```
......@@ -230,6 +230,10 @@ default['datadog']['extra_config']['forwarder_timeout'] = nil
# extra_packages to install
default['datadog']['extra_packages'] = {}
# Custom check files, sourced from other cookbooks
# See the datadog::custom_checks recipe for example usage
default['datadog']['custom_checks'] = {}
# For service-specific configuration, use the integration recipes included
# in this cookbook, and apply them to the appropirate node's run list.
# Read more at http://docs.datadoghq.com/
......
......@@ -7,8 +7,19 @@ def whyrun_supported?
true
end
def install_custom_check(name, cookbook, source)
cookbook_file ::File.join(node['datadog']['config_dir'], 'checks.d', "#{name}.py") do
cookbook cookbook unless cookbook.nil?
source source unless source.nil?
owner 'dd-agent'
mode '644'
end
end
action :add do
Chef::Log.debug "Adding monitoring for #{new_resource.name}"
install_custom_check(new_resource.name, new_resource.check_cookbook, new_resource.check_source) if new_resource.custom_check
template ::File.join(node['datadog']['config_dir'], 'conf.d', "#{new_resource.name}.yaml") do
if node['platform_family'] == 'windows'
owner 'Administrators'
......@@ -19,7 +30,7 @@ action :add do
mode '600'
end
source 'integration.yaml.erb' if new_resource.use_integration_template
source 'integration.yaml.erb' if new_resource.use_integration_template || new_resource.custom_check
variables(
init_config: new_resource.init_config,
......
#
# Cookbook Name:: datadog
# Recipe:: custom_checks
#
# Copyright 2011-2017, Datadog
#
# 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.
#
# Install your custom checks
# The custom check file will be pulled from the files of another cookbook, using
# the `cookbook_file` resource
# This recipe is included from datadog::dd-agent
# Examples:
# default['datadog']['custom_checks']['my_custom_check_1'] = {
# 'enabled' => true,
# 'cookbook' => 'my_cookbook_name', # cookbook to source the custom check file from
# }
# default['datadog']['my_custom_check_1']['instances'] = [
# {
# 'url' => 'http://localhost:22222'
# }
# ]
# default['datadog']['custom_checks']['my_custom_check_2'] = {
# 'enabled' => true,
# 'cookbook' => 'my_cookbook_name',
# 'source' => 'custom/path/my_custom_check.py' # custom path to where the check file resides relative to my_cookbook_name/files/
# }
# default['datadog']['my_custom_check_2']['init_config'] = {
# 'default_timeout' => 10
# }
# default['datadog']['my_custom_check_2']['instances'] = [
# {
# 'url' => 'http://localhost:22222'
# }
# ]
node['datadog']['custom_checks'].each do |check_name, custom_check|
next unless custom_check['enabled']
datadog_monitor check_name do
init_config node['datadog'][check_name]['init_config']
instances node['datadog'][check_name]['instances']
custom_check true
check_cookbook custom_check['cookbook']
check_source custom_check['source']
end
end
......@@ -103,3 +103,6 @@ end
# Install integration packages
include_recipe 'datadog::integrations' unless is_windows
# Install custom checks
include_recipe 'datadog::custom_checks' unless is_windows # FIXME: implement this on windows?
......@@ -16,3 +16,7 @@ attribute :instances, :kind_of => Array, :required => false, :default => []
attribute :version, :kind_of => Integer, :required => false, :default => nil
attribute :use_integration_template, :kind_of => [TrueClass, FalseClass], :required => false, :default => false
attribute :custom_check, :kind_of => [TrueClass, FalseClass], :default => false
attribute :check_cookbook, :kind_of => String, :default => nil
attribute :check_source, :kind_of => [String, Array], :default => nil
This cookbook is used with ChefSpec to test the parent cookbook, datadog
from checks import AgentCheck
class CustomCheck1(AgentCheck):
def check(self, instance):
pass
from checks import AgentCheck
class CustomCheck2(AgentCheck):
def check(self, instance):
pass
name 'datadog_test'
maintainer 'Datadog'
maintainer_email 'package@datadoghq.com'
license 'Apache 2.0'
description 'This cookbook is used with ChefSpec to test the parent cookbook, datadog'
version '1.0.0'
describe 'datadog::custom_checks' do
expected_yaml1 = <<-EOF
instances:
- url: 'http://localhost:11111'
init_config:
default_timeout: 10
EOF
expected_yaml2 = <<-EOF
instances:
- url: 'http://localhost:22222'
init_config:
default_timeout: 5
EOF
cached(:chef_run) do
ChefSpec::SoloRunner.new(step_into: ['datadog_monitor']) do |node|
node.automatic['languages'] = { python: { version: '2.7.2' } }
node.set['datadog'] = {
api_key: 'someapikey',
custom_checks: {
custom_check_1: {
enabled: true,
cookbook: 'datadog_test'
},
custom_check_2: {
enabled: true,
cookbook: 'datadog_test',
source: 'custom_folder/custom_check_2.py'
},
custom_check_3: {
enabled: false,
cookbook: 'datadog_test'
}
},
custom_check_1: {
init_config: {
default_timeout: 10
},
instances: [
{
url: 'http://localhost:11111'
}
]
},
custom_check_2: {
init_config: {
default_timeout: 5
},
instances: [
{
url: 'http://localhost:22222'
}
]
},
custom_check_3: {
init_config: {
default_timeout: 5
},
instances: [
{
url: 'http://localhost:33333'
}
]
}
}
end.converge(described_recipe)
end
subject { chef_run }
it { is_expected.to add_datadog_monitor('custom_check_1') }
it { is_expected.to add_datadog_monitor('custom_check_2') }
it { is_expected.not_to add_datadog_monitor('custom_check_3') }
it 'copies the cookbook file from datadog_test to the agent custom check folder' do
expect(chef_run).to render_file('/etc/dd-agent/checks.d/custom_check_1.py').with_content(
File.read('spec/fixtures/site-cookbooks/datadog_test/files/custom_check_1.py')
)
expect(chef_run).to render_file('/etc/dd-agent/checks.d/custom_check_2.py').with_content(
File.read('spec/fixtures/site-cookbooks/datadog_test/files/custom_folder/custom_check_2.py')
)
end
it 'renders expected YAML config file' do
expect(chef_run).to render_file('/etc/dd-agent/conf.d/custom_check_1.yaml').with_content { |content|
expect(YAML.load(content).to_json).to be_json_eql(YAML.load(expected_yaml1).to_json)
}
expect(chef_run).to render_file('/etc/dd-agent/conf.d/custom_check_2.yaml').with_content { |content|
expect(YAML.load(content).to_json).to be_json_eql(YAML.load(expected_yaml2).to_json)
}
end
end
......@@ -9,6 +9,8 @@ require 'yaml'
require 'shared_examples'
RSpec.configure do |config|
config.berkshelf_options = { except: :integration }
# Use color not only in STDOUT but also in pagers and files
config.tty = true
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment