Skip to content

Commit

Permalink
Add recipe for go-metro integration (#484)
Browse files Browse the repository at this point in the history
Fixes #35
  • Loading branch information
iancward authored and olivielpeau committed Nov 30, 2017
1 parent 38ba0cc commit 736b884
Show file tree
Hide file tree
Showing 4 changed files with 312 additions and 0 deletions.
23 changes: 23 additions & 0 deletions attributes/go-metro.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# The implementation for the go-metro recipe allows any package resource
# property to be defined as an attribute underneath the
# node['datadog']['go-metro']['libcap_package'] namespace
#
# For example, if you want to set the package version, you can do something
# like:
# default['datadog']['go-metro']['libcap_package']['version'] = 'foo'

# The only required option is package_name:
# valid values for RHEL-based system are: libcap, compat-libcap1
# valid values for Debian-based systems are: libcap, libcap2-bin
default['datadog']['go-metro']['libcap_package']['package_name'] = 'libcap'

# init config
default['datadog']['go-metro']['init_config'] = {
'snaplen' => 512,
'idle_ttl' => 300,
'exp_ttl' => 60,
'statsd_ip' => '127.0.0.1',
'statsd_port' => 8125,
'log_to_file' => true,
'log_level' => 'info'
}
81 changes: 81 additions & 0 deletions recipes/go-metro.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
include_recipe 'datadog::dd-agent'

# Go-Metro (TCP RTT) Integration: Passively monitor TCP Round Trip Time
# between the monitored host and others nodes on the network

# Recommended default init_config:
# (these are set in the go-metro attributes file in this cookbook)
# node['datadog']['go-metro']['init_config'] = {
# 'snaplen' => 512,
# 'idle_ttl' => 300,
# 'exp_ttl' => 60,
# 'statsd_ip' => '127.0.0.1',
# 'statsd_port' => 8125,
# 'log_to_file' => true,
# 'log_level' => 'info'
# }

# Assuming you want to monitor connections to
# 10.0.0.1, 10.0.0.2, 10.0.0.3, and app.datadoghq.com from eth0,
# create an instance configuration like this:
# node['datadog']['go-metro']['instances'] = [
# {
# 'interface' => 'eth0',
# 'tags' => [
# 'env:prod'
# ],
# 'ips' => [
# '10.0.0.1',
# '10.0.0.2',
# '10.0.0.3'
# ],
# 'hosts' => [
# 'app.datadoghq.com'
# ]
# }
# ]

####
# At the time of writing, the Go-Metro (TCP Round Trip Time) integration
# is only available as part of the 64-bit DEB and RPM agent distribution
#
# Bail if we're not 64-bit or not linux
if node['kernel']['machine'] != 'x86_64' || node['os'] != 'linux'
Chef::Log.fatal('The Go-Metro (TCP RTT) integration is only available')
Chef::Log.fatal('as part of the 64-bit DEB and RPM agent distribution')
if node['os'] == 'linux'
Chef::Log.fatal(
"And Chef thinks this machine is #{node['kernel']['machine']}", \
"not 'x86_64'"
)
else
Chef::Log.fatal(
"And Chef thinks this machine is #{node['os']}, not 'linux'"
)
end
raise
end

# install desired package for libcap
# This implementation allows you to set any valid package resourece property
# as an attribute underneath node['datadog']['go-metro']['libcap-package']
package 'libcap' do
# handle scenario when entire attribute is nil
unless node['datadog']['go-metro']['libcap_package'].nil?
# send each attribute as a property to the resource
node['datadog']['go-metro']['libcap_package'].each do |prop, value|
send(prop.to_sym, value) unless value.nil?
end
end
end

# add cap_net_raw+ep to the go-metro binary
execute 'setcap go-metro' do
command 'setcap cap_net_raw+ep /opt/datadog-agent/bin/go-metro'
not_if 'setcap -v cap_net_raw+ep /opt/datadog-agent/bin/go-metro'
end

datadog_monitor 'go-metro' do
init_config node['datadog']['go-metro']['init_config']
instances node['datadog']['go-metro']['instances']
end
204 changes: 204 additions & 0 deletions spec/integrations/go-metro_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
describe 'datadog::go-metro' do
context 'with default init_config and libcap package on RHEL7' do
expected_yaml = <<-EOF
init_config:
snaplen: 512
idle_ttl: 300
exp_ttl: 60
statsd_ip: 127.0.0.1
statsd_port: 8125
log_to_file: true
log_level: info
instances:
- interface: eth0
tags:
- env:prod
ips:
- 10.0.0.1
- 10.0.0.2
- 10.0.0.3
hosts:
- app.datadoghq.com
- interface: eth1
tags:
- env:qa
ips:
- 192.168.0.22
hosts:
- docs.datadoghq.com
EOF

cached(:chef_run) do
ChefSpec::SoloRunner.new(
step_into: ['datadog_monitor'], platform: 'redhat', version: '7.3'
) do |node|
node.automatic['languages'] = { python: { version: '2.7.2' } }

node.set['datadog'] = {
api_key: 'someapikey',
'go-metro' => {
instances: [
{
interface: 'eth0',
tags: ['env:prod'],
ips: ['10.0.0.1', '10.0.0.2', '10.0.0.3'],
hosts: ['app.datadoghq.com']
},
{
interface: 'eth1',
tags: ['env:qa'],
ips: ['192.168.0.22'],
hosts: ['docs.datadoghq.com']
}
]
}
}
end.converge(described_recipe)
end

before(:each) do
stub_command('setcap -v cap_net_raw+ep /opt/datadog-agent/bin/go-metro')
end

subject { chef_run }

it_behaves_like 'datadog-agent'

it { is_expected.to include_recipe('datadog::dd-agent') }

it { is_expected.to install_package('libcap') }

it {
is_expected.to run_execute('setcap go-metro').with(
command: 'setcap cap_net_raw+ep /opt/datadog-agent/bin/go-metro'
)
}

it { is_expected.to add_datadog_monitor('go-metro') }

it 'renders expected YAML config file' do
expect(chef_run).to(
render_file('/etc/dd-agent/conf.d/go-metro.yaml')
.with_content { |content|
expect(YAML.safe_load(content).to_json).to be_json_eql(
YAML.safe_load(expected_yaml).to_json
)
}
)
end
end

context 'with modified init_config, libcap package on Ubuntu 16.04' do
expected_yaml = <<-EOF
init_config:
snaplen: 1024
idle_ttl: 300
exp_ttl: 120
statsd_ip: 127.0.0.5
statsd_port: 8125
log_to_file: true
log_level: debug
instances:
- interface: eth0
tags:
- env:prod
ips:
- 10.0.0.1
- 10.0.0.2
- 10.0.0.3
hosts:
- app.datadoghq.com
EOF

cached(:chef_run) do
ChefSpec::SoloRunner.new(
step_into: ['datadog_monitor'], platform: 'ubuntu', version: '16.04'
) do |node|
node.automatic['languages'] = { python: { version: '2.7.2' } }

node.set['datadog'] = {
api_key: 'someapikey',
'go-metro' => {
libcap_package: {
package_name: 'libcap2-bin',
version: '123'
},
init_config: {
snaplen: 1024,
idle_ttl: 300,
exp_ttl: 120,
statsd_ip: '127.0.0.5',
log_level: 'debug'
},
instances: [
{
interface: 'eth0',
tags: ['env:prod'],
ips: ['10.0.0.1', '10.0.0.2', '10.0.0.3'],
hosts: ['app.datadoghq.com']
}
]
}
}
end.converge(described_recipe)
end

before(:each) do
stub_command('setcap -v cap_net_raw+ep /opt/datadog-agent/bin/go-metro')
end

subject { chef_run }

it_behaves_like 'datadog-agent'

it { is_expected.to include_recipe('datadog::dd-agent') }

it {
is_expected.to install_package('libcap').with(
package_name: 'libcap2-bin',
version: '123'
)
}

it {
is_expected.to run_execute('setcap go-metro').with(
command: 'setcap cap_net_raw+ep /opt/datadog-agent/bin/go-metro'
)
}

it { is_expected.to add_datadog_monitor('go-metro') }

it 'renders expected YAML config file' do
expect(chef_run).to(
render_file('/etc/dd-agent/conf.d/go-metro.yaml')
.with_content { |content|
expect(YAML.safe_load(content).to_json).to be_json_eql(
YAML.safe_load(expected_yaml).to_json
)
}
)
end
end

context 'on a windows platform' do
cached(:chef_run) do
ChefSpec::SoloRunner.new(
step_into: ['datadog_monitor'], platform: 'windows', version: '2012R2'
) do |node|
node.automatic['languages'] = { python: { version: '2.7.2' } }

node.set['datadog'] = {
api_key: 'someapikey'
}
end
end

it 'bails out with a fatal log message' do
allow(Chef::Log).to receive(:fatal).and_call_original
expect(Chef::Log).to receive(:fatal).with("And Chef thinks this machine is windows, not 'linux'")
expect { chef_run.converge(described_recipe) }.to raise_error(RuntimeError)
end
end
end
4 changes: 4 additions & 0 deletions templates/default/go-metro.yaml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Generated by Chef, local modifications will be overwritten

<%= JSON.parse(({ 'init_config' => @init_config, 'instances' => @instances}).to_json).to_yaml %>

0 comments on commit 736b884

Please sign in to comment.