Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manual backport of Improvement- Added helm inputs for managing audit logs into release/1.1.x #2369

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/2369.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
(Consul Enterprise) Add support to provide inputs via helm for audit log related configuration
```
24 changes: 24 additions & 0 deletions charts/consul/templates/server-config-configmap.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }}
{{- if and .Values.server.auditLogs.enabled (not .Values.global.acls.manageSystemACLs) }}{{fail "ACLs must be enabled inorder to configure audit logs"}}{{ end -}}
# StatefulSet to run the actual Consul server cluster.
apiVersion: v1
kind: ConfigMap
Expand Down Expand Up @@ -178,4 +179,27 @@ data:
}
}
{{- end }}
{{- if and .Values.server.auditLogs.enabled .Values.global.acls.manageSystemACLs }}
audit-logging.json: |-
{
"audit": {
"enabled": "true",
"sink": {
{{- range $index, $element := .Values.server.auditLogs.sinks }}
{{- if ne $index 0 }},{{end}}
"{{ $element.name }}": {
{{- $firstKeyValuePair := false }}
{{- range $k, $v := $element }}
{{- if ne $k "name" }}
{{- if ne $firstKeyValuePair false }},{{end}}
{{- $firstKeyValuePair = true }}
"{{ $k }}": "{{ $v }}"
{{- end }}
{{- end }}
}
{{- end }}
}
}
}
{{- end }}
{{- end }}
140 changes: 140 additions & 0 deletions charts/consul/test/unit/server-config-configmap.bats
Original file line number Diff line number Diff line change
Expand Up @@ -965,3 +965,143 @@ load _helpers

[ "${actual}" = "true" ]
}

#--------------------------------------------------------------------
# server.auditLogs

@test "server/ConfigMap: server.auditLogs is disabled by default" {
cd `chart_dir`
local actual=$(helm template \
-s templates/server-config-configmap.yaml \
--set 'server.auditLogs.enabled=false' \
. | tee /dev/stderr |
yq -r '.data["audit-logging.json"]' | jq -r .audit | tee /dev/stderr)

[ "${actual}" = "null" ]
}

@test "server/ConfigMap: server.auditLogs is enabled but ACLs are disabled" {
cd `chart_dir`
run helm template \
-s templates/server-config-configmap.yaml \
--set 'server.auditLogs.enabled=true' \
--set 'server.auditLogs.sinks[0].name=MySink' \
--set 'server.auditLogs.sinks[0].type=file' \
--set 'server.auditLogs.sinks[0].format=json' \
--set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \
--set 'server.auditLogs.sinks[0].rotate_duration=24h' \
--set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \
.

[ "$status" -eq 1 ]
[[ "$output" =~ "ACLs must be enabled inorder to configure audit logs" ]]
}

@test "server/ConfigMap: server.auditLogs is enabled without sink inputs" {
cd `chart_dir`
local actual=$(helm template \
-s templates/server-config-configmap.yaml \
--set 'server.auditLogs.enabled=true' \
--set 'global.acls.manageSystemACLs=true' \
. | tee /dev/stderr |
yq -r '.data["audit-logging.json"]' | jq -r .audit.sink | tee /dev/stderr)

[ "${actual}" = "{}" ]
}

@test "server/ConfigMap: server.auditLogs is enabled with 1 sink input object" {
cd `chart_dir`
local object=$(helm template \
-s templates/server-config-configmap.yaml \
--set 'server.auditLogs.enabled=true' \
--set 'global.acls.manageSystemACLs=true' \
--set 'server.auditLogs.sinks[0].name=MySink' \
--set 'server.auditLogs.sinks[0].type=file' \
--set 'server.auditLogs.sinks[0].format=json' \
--set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \
--set 'server.auditLogs.sinks[0].rotate_duration=24h' \
--set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \
. | tee /dev/stderr |
yq -r '.data["audit-logging.json"]' | tee /dev/stderr)

local actual=$(echo $object | jq -r .audit.sink.MySink.path | tee /dev/stderr)
[ "${actual}" = "/tmp/audit.json" ]

local actual=$(echo $object | jq -r .audit.sink.MySink.delivery_guarantee | tee /dev/stderr)
[ "${actual}" = "best-effort" ]

local actual=$(echo $object | jq -r .audit.sink.MySink.rotate_duration | tee /dev/stderr)
[ "${actual}" = "24h" ]
}

@test "server/ConfigMap: server.auditLogs is enabled with 1 sink input object and it does not contain the name attribute" {
cd `chart_dir`
local actual=$(helm template \
-s templates/server-config-configmap.yaml \
--set 'server.auditLogs.enabled=true' \
--set 'global.acls.manageSystemACLs=true' \
--set 'server.auditLogs.sinks[0].name=MySink' \
--set 'server.auditLogs.sinks[0].type=file' \
--set 'server.auditLogs.sinks[0].format=json' \
--set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \
--set 'server.auditLogs.sinks[0].rotate_duration=24h' \
--set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \
. | tee /dev/stderr |
yq -r '.data["audit-logging.json"]' | jq -r .audit.sink.name | tee /dev/stderr)

[ "${actual}" = "null" ]
}

@test "server/ConfigMap: server.auditLogs is enabled with multiple sink input objects" {
cd `chart_dir`
local object=$(helm template \
-s templates/server-config-configmap.yaml \
--set 'server.auditLogs.enabled=true' \
--set 'global.acls.manageSystemACLs=true' \
--set 'server.auditLogs.sinks[0].name=MySink1' \
--set 'server.auditLogs.sinks[0].type=file' \
--set 'server.auditLogs.sinks[0].format=json' \
--set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \
--set 'server.auditLogs.sinks[0].rotate_duration=24h' \
--set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \
--set 'server.auditLogs.sinks[1].name=MySink2' \
--set 'server.auditLogs.sinks[1].type=file' \
--set 'server.auditLogs.sinks[1].format=json' \
--set 'server.auditLogs.sinks[1].delivery_guarantee=best-effort' \
--set 'server.auditLogs.sinks[1].rotate_max_files=15' \
--set 'server.auditLogs.sinks[1].rotate_duration=24h' \
--set 'server.auditLogs.sinks[1].path=/tmp/audit-2.json' \
--set 'server.auditLogs.sinks[2].name=MySink3' \
--set 'server.auditLogs.sinks[2].type=file' \
--set 'server.auditLogs.sinks[2].format=json' \
--set 'server.auditLogs.sinks[2].delivery_guarantee=best-effort' \
--set 'server.auditLogs.sinks[2].rotate_max_files=20' \
--set 'server.auditLogs.sinks[2].rotate_duration=18h' \
--set 'server.auditLogs.sinks[2].path=/tmp/audit-3.json' \
. | tee /dev/stderr |
yq -r '.data["audit-logging.json"]' | tee /dev/stderr)

local actual=$(echo $object | jq -r .audit.sink.MySink1.path | tee /dev/stderr)
[ "${actual}" = "/tmp/audit.json" ]

local actual=$(echo $object | jq -r .audit.sink.MySink3.path | tee /dev/stderr)
[ "${actual}" = "/tmp/audit-3.json" ]

local actual=$(echo $object | jq -r .audit.sink.MySink2.path | tee /dev/stderr)
[ "${actual}" = "/tmp/audit-2.json" ]

local actual=$(echo $object | jq -r .audit.sink.MySink1.name | tee /dev/stderr)
[ "${actual}" = "null" ]

local actual=$(echo $object | jq -r .audit.sink.MySink3.delivery_guarantee | tee /dev/stderr)
[ "${actual}" = "best-effort" ]

local actual=$(echo $object | jq -r .audit.sink.MySink2.rotate_duration | tee /dev/stderr)
[ "${actual}" = "24h" ]

local actual=$(echo $object | jq -r .audit.sink.MySink1.format | tee /dev/stderr)
[ "${actual}" = "json" ]

local actual=$(echo $object | jq -r .audit.sink.MySink3.type | tee /dev/stderr)
[ "${actual}" = "file" ]
}
6 changes: 3 additions & 3 deletions charts/consul/test/unit/server-statefulset.bats
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ load _helpers
-s templates/server-statefulset.yaml \
. | tee /dev/stderr |
yq -r '.spec.template.metadata.annotations."consul.hashicorp.com/config-checksum"' | tee /dev/stderr)
[ "${actual}" = 251dd23c6cc44bf8362acddc24c78440b6a65c4618785d027fae526958af5dde ]
[ "${actual}" = dc165411861bb45d37e20a0a337697336f333407f5fb29fca9252cdba652339c ]
}

@test "server/StatefulSet: adds config-checksum annotation when extraConfig is provided" {
Expand All @@ -696,7 +696,7 @@ load _helpers
--set 'server.extraConfig="{\"hello\": \"world\"}"' \
. | tee /dev/stderr |
yq -r '.spec.template.metadata.annotations."consul.hashicorp.com/config-checksum"' | tee /dev/stderr)
[ "${actual}" = 473d54d05b794be1526d42ef04fdc049f4f979a75d3394c897eef149d399207d ]
[ "${actual}" = d69874f33a862f6728265246a3e38b3f64702e013ecd4afc5dcdc33d34a66954 ]
}

@test "server/StatefulSet: adds config-checksum annotation when config is updated" {
Expand All @@ -706,7 +706,7 @@ load _helpers
--set 'global.acls.manageSystemACLs=true' \
. | tee /dev/stderr |
yq -r '.spec.template.metadata.annotations."consul.hashicorp.com/config-checksum"' | tee /dev/stderr)
[ "${actual}" = 6acd3761c0981d4d6194b3375b0f7a291e3927602ce7857344c26010381d3a61 ]
[ "${actual}" = 95a3d3b4816a0f183b8a9aac41ff386e659cd2a465f3030f01c5c4a2b9052a6c ]
}

#--------------------------------------------------------------------
Expand Down
54 changes: 54 additions & 0 deletions charts/consul/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,60 @@ server:
# ```
# @type: string
caCert: null

# [Enterprise Only] Added in Consul 1.8, the audit object allow users to enable auditing
# and configure a sink and filters for their audit logs. Please refer to
# [audit logs](https://developer.hashicorp.com/consul/docs/enterprise/audit-logging) documentation
# for further information.
auditLogs:
# Controls whether Consul logs out each time a user performs an operation.
# global.acls.manageSystemACLs must be enabled to use this feature.
enabled: false

# A single entry of the sink object provides configuration for the destination to which Consul
# will log auditing events.
#
# Example:
#
# ```yaml
# sinks:
# - name: My Sink
# type: file
# format: json
# path: /tmp/audit.json
# delivery_guarantee: best-effort
# rotate_duration: 24h
# rotate_max_files: 15
# rotate_bytes: 25165824
#
# ```
#
# The sink object supports the following keys:
#
# - `name` - Name of the sink.
#
# - `type` - Type specifies what kind of sink this is. Currently only file sinks are available
#
# - `format` - Format specifies what format the events will be emitted with. Currently only `json`
# events are emitted.
#
# - `path` - The directory and filename to write audit events to.
#
# - `delivery_guarantee` - Specifies the rules governing how audit events are written. Consul
# only supports `best-effort` event delivery.
#
# - `mode` - The permissions to set on the audit log files.
#
# - `rotate_duration` - Specifies the interval by which the system rotates to a new log file.
# At least one of `rotate_duration` or `rotate_bytes` must be configured to enable audit logging.
#
# - `rotate_bytes` - Specifies how large an individual log file can grow before Consul rotates to a new file.
# At least one of rotate_bytes or rotate_duration must be configured to enable audit logging.
#
# - `rotate_max_files` - Defines the limit that Consul should follow before it deletes old log files.
#
# @type: array<map>
sinks: []

# Configuration for Consul servers when the servers are running outside of Kubernetes.
# When running external servers, configuring these values is recommended
Expand Down
Loading