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

[CECO-743] Secrets backend feature #1333

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from 16 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
2 changes: 2 additions & 0 deletions apis/datadoghq/common/envvar.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ const (
DDSBOMContainerOverlayFSDirectScan = "DD_SBOM_CONTAINER_IMAGE_OVERLAYFS_DIRECT_SCAN"
DDSBOMHostEnabled = "DD_SBOM_HOST_ENABLED"
DDSBOMHostAnalyzers = "DD_SBOM_HOST_ANALYZERS"
DDSecretBackendArguments = "DD_SECRET_BACKEND_ARGUMENTS"
DDSecretBackendCommand = "DD_SECRET_BACKEND_COMMAND"
DDSecretBackendTimeout = "DD_SECRET_BACKEND_TIMEOUT"
DDSite = "DD_SITE"
DDSystemProbeAgentEnabled = "DD_SYSTEM_PROBE_ENABLED"
DDSystemProbeBPFDebugEnabled = DDSystemProbeEnvPrefix + "BPF_DEBUG"
Expand Down
8 changes: 8 additions & 0 deletions apis/datadoghq/v2alpha1/datadogagent_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ const (
defaultHelmCheckEnabled bool = false
defaultHelmCheckCollectEvents bool = false

defaultSecretsBackendCommand string = ""

defaultFIPSEnabled bool = false
defaultFIPSImageName string = "fips-proxy"
defaultFIPSImageTag string = defaulting.FIPSProxyLatestVersion
Expand Down Expand Up @@ -514,4 +516,10 @@ func defaultFeaturesConfig(ddaSpec *DatadogAgentSpec) {
if *ddaSpec.Features.HelmCheck.Enabled {
apiutils.DefaultBooleanIfUnset(&ddaSpec.Features.HelmCheck.CollectEvents, defaultHelmCheckCollectEvents)
}

// Secrets backend Feature
if ddaSpec.Features.SecretsBackend == nil {
ddaSpec.Features.SecretsBackend = &SecretsBackendFeatureConfig{}
}
apiutils.DefaultStringIfUnset(&ddaSpec.Features.SecretsBackend.Command, defaultSecretsBackendCommand)
}
43 changes: 43 additions & 0 deletions apis/datadoghq/v2alpha1/datadogagent_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -356,6 +359,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(valueFalse),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
want: &DatadogAgentSpec{
Expand Down Expand Up @@ -455,6 +461,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(valueFalse),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -580,6 +589,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -710,6 +722,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -835,6 +850,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -962,6 +980,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -1094,6 +1115,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -1222,6 +1246,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -1347,6 +1374,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -1478,6 +1508,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -1604,6 +1637,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -1635,6 +1671,7 @@ func Test_defaultFeatures(t *testing.T) {
ClusterChecks: &ClusterChecksFeatureConfig{},
PrometheusScrape: &PrometheusScrapeFeatureConfig{},
HelmCheck: &HelmCheckFeatureConfig{},
SecretsBackend: &SecretsBackendFeatureConfig{},
},
},
want: &DatadogAgentSpec{
Expand Down Expand Up @@ -1750,6 +1787,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down Expand Up @@ -1888,6 +1928,9 @@ func Test_defaultFeatures(t *testing.T) {
HelmCheck: &HelmCheckFeatureConfig{
Enabled: apiutils.NewBoolPointer(defaultHelmCheckEnabled),
},
SecretsBackend: &SecretsBackendFeatureConfig{
Command: apiutils.NewStringPointer(defaultSecretsBackendCommand),
},
},
},
},
Expand Down
47 changes: 42 additions & 5 deletions apis/datadoghq/v2alpha1/datadogagent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ type DatadogFeatures struct {
PrometheusScrape *PrometheusScrapeFeatureConfig `json:"prometheusScrape,omitempty"`
// HelmCheck configuration.
HelmCheck *HelmCheckFeatureConfig `json:"helmCheck,omitempty"`
// SecretsBackend configuration.
SecretsBackend *SecretsBackendFeatureConfig `json:"secretsBackend,omitempty"`
tbavelier marked this conversation as resolved.
Show resolved Hide resolved
}

// Configuration structs for each feature in DatadogFeatures. All parameters are optional and have default values when necessary.
Expand Down Expand Up @@ -1099,13 +1101,48 @@ type DatadogCredentials struct {
AppSecret *commonv1.SecretConfig `json:"appSecret,omitempty"`
}

// SecretBackendConfig provides configuration for the secret backend.
type SecretBackendConfig struct {
// Command defines the secret backend command to use
// SecretsBackendRolesConfig provides configuration of the secrets Datadog agents can read for the Secrets Backend feature
// +k8s:openapi-gen=true
type SecretsBackendRolesConfig struct {
// Namespace defines the namespace in which the secrets reside.
// +required
Namespace *string `json:"namespace,omitempty"`

// Secrets defines the list of secrets for which a role should be created.
// +required
// +listType=set
Secrets []string `json:"secrets,omitempty"`
}

// SecretsBackendFeatureConfig provides configuration for the secret backend.
// +k8s:openapi-gen=true
type SecretsBackendFeatureConfig struct {
// Command defines the secret backend command to use.
// Datadog provides a pre-defined binary `/readsecret_multiple_providers.sh`.
// Read more about `/readsecret_multiple_providers.sh`: https://docs.datadoghq.com/agent/configuration/secrets-management/?tab=linux#script-for-reading-from-multiple-secret-providers
Command *string `json:"command,omitempty"`

// Args defines the list of arguments to pass to the command
Args []string `json:"args,omitempty"`
// Args defines the list of arguments to pass to the command (space-separated strings).
// +optional
Args *string `json:"args,omitempty"`

// Timeout defines the command timeout in seconds.
// Default: 30
// +optional
Timeout *int32 `json:"timeout,omitempty"`

// EnableGlobalPermissions defines whether to create a global permission allowing Datadog agents to read all Kubernetes secrets.
// Default: false
// +optional
EnableGlobalPermissions *bool `json:"enableGlobalPermissions,omitempty"`

// Roles defines roles for Datadog to read the specified secrets, replacing `enableGlobalPermissions`.
// They are defined as a list of namespace/secrets.
// Each defined namespace needs to be present in the DatadogAgent controller using `WATCH_NAMESPACE` / `DD_AGENT_WATCH_NAMESPACE`.
// See also: https://github.com/DataDog/datadog-operator/blob/main/docs/secret_management.md#how-to-deploy-the-agent-components-using-the-secret-backend-feature-with-datadogagent
// +optional
// +listType=atomic
Roles []*SecretsBackendRolesConfig `json:"roles,omitempty"`
}

// NetworkPolicyFlavor specifies which flavor of Network Policy to use.
Expand Down
42 changes: 42 additions & 0 deletions apis/datadoghq/v2alpha1/test/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,48 @@ func (builder *DatadogAgentBuilder) WithHelmCheckValuesAsTags(valuesAsTags map[s
return builder
}

// Secrets Backend

func (builder *DatadogAgentBuilder) initSecretsBackendFeature() {
if builder.datadogAgent.Spec.Features.SecretsBackend == nil {
builder.datadogAgent.Spec.Features.SecretsBackend = &v2alpha1.SecretsBackendFeatureConfig{}
}
}

func (builder *DatadogAgentBuilder) WithSecretsBackendCommand(command string) *DatadogAgentBuilder {
builder.initSecretsBackendFeature()
builder.datadogAgent.Spec.Features.SecretsBackend.Command = apiutils.NewStringPointer(command)
return builder
}

func (builder *DatadogAgentBuilder) WithSecretsBackendArgs(args string) *DatadogAgentBuilder {
builder.initSecretsBackendFeature()
builder.datadogAgent.Spec.Features.SecretsBackend.Args = apiutils.NewStringPointer(args)
return builder
}

func (builder *DatadogAgentBuilder) WithSecretsBackendTimeout(timeout int32) *DatadogAgentBuilder {
builder.initSecretsBackendFeature()
builder.datadogAgent.Spec.Features.SecretsBackend.Timeout = apiutils.NewInt32Pointer(timeout)
return builder
}

func (builder *DatadogAgentBuilder) WithSecretsBackendEnabledGlobalPermissions(enabled bool) *DatadogAgentBuilder {
builder.initSecretsBackendFeature()
builder.datadogAgent.Spec.Features.SecretsBackend.EnableGlobalPermissions = apiutils.NewBoolPointer(enabled)
return builder
}

func (builder *DatadogAgentBuilder) WithSecretsBackendRoles(roles []v2alpha1.SecretsBackendRolesConfig) *DatadogAgentBuilder {
builder.initSecretsBackendFeature()
var r []*v2alpha1.SecretsBackendRolesConfig
for i := range roles {
r = append(r, &roles[i])
}
builder.datadogAgent.Spec.Features.SecretsBackend.Roles = r
return builder
}

// Global Kubelet

func (builder *DatadogAgentBuilder) WithGlobalKubeletConfig(hostCAPath, agentCAPath string, tlsVerify bool) *DatadogAgentBuilder {
Expand Down
59 changes: 55 additions & 4 deletions apis/datadoghq/v2alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading