Skip to content

Commit deb9900

Browse files
authored
Allow enabling CWS and CSPM (#843)
1 parent 56c0f61 commit deb9900

File tree

7 files changed

+177
-3
lines changed

7 files changed

+177
-3
lines changed

attributes/default.rb

+4
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,10 @@
360360
default['datadog']['process_agent']['container_interval'] = nil
361361
default['datadog']['process_agent']['rtcontainer_interval'] = nil
362362

363+
# Cloud Workload Security functionality settings
364+
default['datadog']['security_agent']['cws']['enabled'] = false
365+
default['datadog']['security_agent']['cspm']['enabled'] = false
366+
363367
# System probe functionality settings
364368

365369
# Whether this cookbook should write system-probe.yaml or not.

recipes/dd-agent.rb

+3
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ def template_vars
166166
# system-probe is a dependency of the agent on Linux or Windows
167167
include_recipe '::system-probe' if system_probe_managed && system_probe_supported
168168

169+
# security-agent is a dependency of the agent on Linux or Windows
170+
include_recipe '::security-agent' unless is_windows
171+
169172
# Installation metadata to let know the agent about installation method and its version
170173
include_recipe '::install_info'
171174

recipes/security-agent.rb

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#
2+
# Cookbook:: datadog
3+
# Recipe:: security-agent
4+
#
5+
# Copyright:: 2011-2022, Datadog
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
#
19+
20+
is_windows = platform_family?('windows')
21+
22+
# Set the correct agent startup action
23+
security_agent_enabled = !is_windows && node['datadog']['security_agent']['cws']['enabled'] || node['datadog']['security_agent']['cspm']['enabled']
24+
25+
#
26+
# Configures security-agent agent
27+
security_agent_config_file = '/etc/datadog-agent/security-agent.yaml'
28+
security_agent_config_file_exists = ::File.exist?(security_agent_config_file)
29+
30+
template security_agent_config_file do
31+
runtime_security_extra_config = {}
32+
if node['datadog']['extra_config'] && node['datadog']['extra_config']['security_agent'] && node['datadog']['extra_config']['security_agent']['runtime_security_config']
33+
node['datadog']['extra_config']['security_agent']['runtime_security_config'].each do |k, v|
34+
next if v.nil?
35+
runtime_security_extra_config[k] = v
36+
end
37+
end
38+
39+
compliance_extra_config = {}
40+
if node['datadog']['extra_config'] && node['datadog']['extra_config']['security_agent'] && node['datadog']['extra_config']['security_agent']['compliance_config']
41+
node['datadog']['extra_config']['security_agent']['compliance_config'].each do |k, v|
42+
next if v.nil?
43+
compliance_extra_config[k] = v
44+
end
45+
end
46+
47+
source 'security-agent.yaml.erb'
48+
variables(
49+
runtime_security_enabled: node['datadog']['security_agent']['cws']['enabled'],
50+
runtime_security_extra_config: runtime_security_extra_config,
51+
compliance_enabled: node['datadog']['security_agent']['cspm']['enabled'],
52+
compliance_extra_config: compliance_extra_config
53+
)
54+
55+
owner 'root'
56+
group 'dd-agent'
57+
mode '640'
58+
59+
notifies :restart, 'service[datadog-agent-security]', :delayed if security_agent_enabled
60+
61+
# Security agent is not enabled and the file doesn't exists, don't create it
62+
not_if { !security_agent_enabled && !security_agent_config_file_exists }
63+
end
64+
65+
# Common configuration
66+
service_provider = Chef::Datadog.service_provider(node)
67+
68+
service_name = 'datadog-agent-security'
69+
70+
if security_agent_enabled
71+
service 'datadog-agent-security' do
72+
service_name service_name
73+
action :start
74+
provider service_provider unless service_provider.nil?
75+
supports :restart => true, :status => true, :start => true, :stop => true
76+
subscribes :restart, "template[#{security_agent_config_file}]", :delayed
77+
end
78+
end

recipes/system-probe.rb

+14-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
is_windows = platform_family?('windows')
2121

2222
# Set the correct agent startup action
23+
cws_enabled = node['datadog']['security_agent']['cws']['enabled']
2324
sysprobe_enabled = if is_windows
2425
node['datadog']['system_probe']['network_enabled']
2526
else
26-
node['datadog']['system_probe']['enabled'] || node['datadog']['system_probe']['network_enabled']
27+
node['datadog']['system_probe']['enabled'] || node['datadog']['system_probe']['network_enabled'] || cws_enabled
2728
end
2829
sysprobe_agent_start = sysprobe_enabled ? :start : :stop
2930

@@ -47,14 +48,24 @@
4748
end
4849
end
4950

51+
runtime_security_extra_config = {}
52+
if node['datadog']['extra_config'] && node['datadog']['extra_config']['security_agent'] && node['datadog']['extra_config']['security_agent']['runtime_security_config']
53+
node['datadog']['extra_config']['security_agent']['runtime_security_config'].each do |k, v|
54+
next if v.nil?
55+
runtime_security_extra_config[k] = v
56+
end
57+
end
58+
5059
source 'system_probe.yaml.erb'
5160
variables(
5261
enabled: node['datadog']['system_probe']['enabled'],
5362
sysprobe_socket: node['datadog']['system_probe']['sysprobe_socket'],
5463
debug_port: node['datadog']['system_probe']['debug_port'],
5564
bpf_debug: node['datadog']['system_probe']['bpf_debug'],
5665
enable_conntrack: node['datadog']['system_probe']['enable_conntrack'],
57-
extra_config: extra_config
66+
system_probe_extra_config: extra_config,
67+
runtime_security_enabled: cws_enabled,
68+
runtime_security_extra_config: runtime_security_extra_config
5869
)
5970

6071
if is_windows
@@ -70,6 +81,7 @@
7081
notifies :restart, 'service[datadog-agent-sysprobe]', :delayed if sysprobe_enabled
7182
# since process-agent collects network info through system-probe, enabling system-probe should also restart process-agent
7283
notifies :restart, 'service[datadog-agent]', :delayed if sysprobe_enabled
84+
notifies :restart, 'service[datadog-agent-security]', :delayed if cws_enabled
7385

7486
# System probe is not enabled and the file doesn't exists, don't create it
7587
not_if { !sysprobe_enabled && !system_probe_config_file_exists }

spec/security-agent_spec.rb

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
require 'spec_helper'
2+
3+
describe 'datadog::security-agent' do
4+
context 'with CWS enabled' do
5+
cached(:solo) do
6+
ChefSpec::SoloRunner.new(
7+
platform: 'ubuntu',
8+
version: '16.04'
9+
) do |node|
10+
node.name 'chef-nodename' # expected to be used as the hostname in `datadog.yaml`
11+
node.normal['datadog'] = {
12+
'api_key' => 'somethingnotnil',
13+
'agent_major_version' => 6,
14+
'security_agent' => {
15+
'cws' => {
16+
'enabled' => true,
17+
}
18+
},
19+
'extra_config' => {
20+
'security_agent' => {
21+
'runtime_security_config' => {
22+
'activity_dump' => {
23+
'enabled' => true,
24+
}
25+
}
26+
}
27+
}
28+
}
29+
end
30+
end
31+
32+
cached(:chef_run) do
33+
solo.converge(described_recipe) do
34+
solo.resource_collection.insert(
35+
Chef::Resource::Service.new('datadog-agent', solo.run_context))
36+
end
37+
end
38+
39+
it 'security-agent.yaml is created' do
40+
expect(chef_run).to create_template('/etc/datadog-agent/security-agent.yaml')
41+
end
42+
43+
it 'security-agent.yaml contains expected YAML configuration' do
44+
expected_yaml = <<-EOF
45+
compliance_config:
46+
enabled: false
47+
runtime_security_config:
48+
enabled: true
49+
activity_dump:
50+
enabled: true
51+
EOF
52+
53+
expect(chef_run).to(render_file('/etc/datadog-agent/security-agent.yaml').with_content { |content|
54+
expect(YAML.safe_load(content).to_json).to be_json_eql(YAML.safe_load(expected_yaml).to_json)
55+
})
56+
end
57+
end
58+
end
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<%
2+
## Populate system_probe_config ##
3+
security_agent_config = {
4+
runtime_security_config: {
5+
enabled: @runtime_security_enabled,
6+
}.merge(@runtime_security_extra_config),
7+
compliance_config: {
8+
enabled: @compliance_enabled,
9+
}.merge(@compliance_extra_config),
10+
}
11+
-%>
12+
13+
<%= JSON.parse(security_agent_config.to_json).to_yaml %>

templates/default/system_probe.yaml.erb

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ system_probe_config = {
77
debug_port: @debug_port,
88
bpf_debug: @bpf_debug,
99
enable_conntrack: @enable_conntrack,
10-
}.merge(@extra_config),
10+
}.merge(@system_probe_extra_config),
1111
}
1212

13+
if @runtime_security_enabled
14+
system_probe_config['runtime_security_config'] = {
15+
enabled: @runtime_security_enabled
16+
}.merge(@runtime_security_extra_config)
17+
end
18+
1319
# We let the Agent default value take effect if user didn't explicitly
1420
# specify something else than nil for 'network_enabled'
1521
if !node['datadog']['system_probe']['network_enabled'].nil?

0 commit comments

Comments
 (0)