Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
name: injection-dotnetchaining
name: chaining-dotnet
spec:
enabled: true
type: dotnet-core
selector:
labels:
- name: app
value: injection-dotnetchaining
value: chaining-dotnet
image:
pullPolicy: Never
connection:
Expand All @@ -19,20 +19,20 @@ spec:
apiVersion: apps/v1
kind: Deployment
metadata:
name: injection-dotnetchaining
name: chaining-dotnet
labels:
app: injection-dotnetchaining
app: chaining-dotnet
spec:
replicas: 1
selector:
matchLabels:
app: injection-dotnetchaining
app: chaining-dotnet
strategy:
type: Recreate
template:
metadata:
labels:
app: injection-dotnetchaining
app: chaining-dotnet
spec:
containers:
- image: k8s.gcr.io/pause:3.3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
name: injection-flexchaining
name: chaining-flex
spec:
enabled: true
type: flex
selector:
labels:
- name: app
value: injection-flexchaining
value: chaining-flex
image:
pullPolicy: Never
connection:
Expand All @@ -19,20 +19,20 @@ spec:
apiVersion: apps/v1
kind: Deployment
metadata:
name: injection-flexchaining
name: chaining-flex
labels:
app: injection-flexchaining
app: chaining-flex
spec:
replicas: 1
selector:
matchLabels:
app: injection-flexchaining
app: chaining-flex
strategy:
type: Recreate
template:
metadata:
labels:
app: injection-flexchaining
app: chaining-flex
spec:
containers:
- image: k8s.gcr.io/pause:3.3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
name: injection-javatooloptions
name: chaining-java
spec:
enabled: true
type: java
selector:
labels:
- name: app
value: injection-javatooloptions
value: chaining-java
image:
pullPolicy: Never
connection:
Expand All @@ -19,20 +19,20 @@ spec:
apiVersion: apps/v1
kind: Deployment
metadata:
name: injection-javatooloptions
name: chaining-java
labels:
app: injection-javatooloptions
app: chaining-java
spec:
replicas: 1
selector:
matchLabels:
app: injection-javatooloptions
app: chaining-java
strategy:
type: Recreate
template:
metadata:
labels:
app: injection-javatooloptions
app: chaining-java
spec:
containers:
- image: k8s.gcr.io/pause:3.3
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
name: chaining-python
spec:
enabled: true
type: python
selector:
labels:
- name: app
value: chaining-python
image:
pullPolicy: Never
connection:
name: testing-agent-connection
configuration:
name: testing-agent-configuration
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: chaining-python
labels:
app: chaining-python
spec:
replicas: 1
selector:
matchLabels:
app: chaining-python
strategy:
type: Recreate
template:
metadata:
labels:
app: chaining-python
spec:
containers:
- image: k8s.gcr.io/pause:3.3
name: pause
env:
- name: PYTHONPATH
value: something
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,21 @@ resources:
- ./glob-selecting.yaml
- ./init-container-overrides.yaml
- ./injection-dotnet.yaml
- ./injection-dotnetchaining.yaml
- ./injection-dummy.yaml
- ./injection-java.yaml
- ./injection-javatooloptions.yaml
- ./injection-nodejs-require.yaml
- ./injection-nodejs-import.yaml
- ./injection-php.yaml
- ./injection-python.yaml
- ./injection-flex.yaml
- ./injection-flexchaining.yaml
- ./missing-deps.yaml
- ./multiple-images.yaml
- ./namespace.yaml
- ./type-daemonset.yaml
- ./type-deployment.yaml
- ./type-statefulset.yaml
- ./unmatched.yaml
- ./chaining-dotnet.yaml
- ./chaining-flex.yaml
- ./chaining-java.yaml
- ./chaining-python.yaml
2 changes: 1 addition & 1 deletion manifests/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ operator:
# The name of the webhook to patch after certificate generation occurs.
# Should not normally need to change.
webhookConfiguration: contrast-web-hook-configuration
# Enable early chaining. Should normally be disabled unless DynaKube is used in classicStack mode.
# Enable early chaining. Should only be enabled if you are using a dotnet-core AgentInjector and DynaKube is used in classicStack mode.
enableEarlyChaining: false
# Metadata for the operator deployment.
labels: {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Task Handle(EntityReconciled<V1Beta1DynaKube> notification, CancellationT
if (oneAgentSpec?.ClassicFullStack != null)
{
Logger.Warn("Dynatrace Operator is present and in classicFullStack mode. "
+ "Please set the environment variable 'CONTRAST_ENABLE_EARLY_CHAINING=true' on the operator and restart the affected pods.");
+ "If you are using a 'dotnet-core' AgentInjector, please set the environment variable 'CONTRAST_ENABLE_EARLY_CHAINING=true' on the agent-operator and restart the affected pods.");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using Contrast.K8s.AgentOperator.Core.Reactions.Injecting.Patching.Utility;
using Contrast.K8s.AgentOperator.Core.State.Resources.Primitives;
using Contrast.K8s.AgentOperator.Options;
using k8s.Models;
Expand All @@ -24,8 +24,7 @@ public IEnumerable<V1EnvVar> GenerateEnvVars(PatchingContext context)
{
if (_injectorOptions.EnableEarlyChaining)
{
yield return new V1EnvVar("LD_PRELOAD",
$"{context.AgentMountPath}/runtimes/linux/native/ContrastChainLoader.so");
yield return new V1EnvVar("LD_PRELOAD", GetAgentPreloadPath(context));
}
else
{
Expand All @@ -49,26 +48,24 @@ public void PatchContainer(V1Container container, PatchingContext context)
// Either the users sets this on the pod manually, or we set it from our config file.
// We also assume the default is true.
var chainingEnabled = !string.Equals(
GetFirstOrDefaultEnvVar(container.Env, "CONTRAST__AGENT__DOTNET__ENABLE_CHAINING")?.Value,
container.Env.FirstOrDefault("CONTRAST__AGENT__DOTNET__ENABLE_CHAINING")?.Value,
"false",
StringComparison.OrdinalIgnoreCase
);

// Only modify this if CONTRAST_EXISTING_LD_PRELOAD isn't already set, or we are not already set from early chaining. This is to prevent infinite loops.
if (chainingEnabled
&& GetFirstOrDefaultEnvVar(container.Env, "LD_PRELOAD") is { Value: { } currentLdPreloadValue }
&& container.Env.FirstOrDefault("LD_PRELOAD") is { Value: { } currentLdPreloadValue }
&& !string.IsNullOrWhiteSpace(currentLdPreloadValue)
&& !currentLdPreloadValue.Contains("ContrastChainLoader.so", StringComparison.OrdinalIgnoreCase)
&& GetFirstOrDefaultEnvVar(container.Env, "CONTRAST_EXISTING_LD_PRELOAD") is null)
&& container.Env.FirstOrDefault("CONTRAST_EXISTING_LD_PRELOAD") is null)
{
container.Env.AddOrUpdate(new V1EnvVar("CONTRAST_EXISTING_LD_PRELOAD", currentLdPreloadValue));
container.Env.AddOrUpdate(new V1EnvVar("LD_PRELOAD",
$"{context.AgentMountPath}/runtimes/linux/native/ContrastChainLoader.so:{currentLdPreloadValue}"));
$"{GetAgentPreloadPath(context)}:{currentLdPreloadValue}"));
}
}

private static V1EnvVar? GetFirstOrDefaultEnvVar(IEnumerable<V1EnvVar> collection, string name)
{
return collection.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
}
private static string GetAgentPreloadPath(PatchingContext context) => $"{context.AgentMountPath}/runtimes/linux/native/ContrastChainLoader.so";

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using Contrast.K8s.AgentOperator.Core.Reactions.Injecting.Patching.Utility;
using Contrast.K8s.AgentOperator.Core.State.Resources.Primitives;
using k8s.Models;

Expand All @@ -15,7 +15,7 @@ public class FlexAgentPatcher : IAgentPatcher

public IEnumerable<V1EnvVar> GenerateEnvVars(PatchingContext context)
{
yield return new V1EnvVar("LD_PRELOAD", $"{context.AgentMountPath}/injector/agent_injector.so");
yield return new V1EnvVar("LD_PRELOAD", GetInjectorPreloadPath(context));
yield return new V1EnvVar("CONTRAST_INSTALLATION_TOOL", "KUBERNETES_OPERATOR");

yield return new V1EnvVar("CONTRAST_FLEX_AGENTS_PARENT_DIR", context.AgentMountPath);
Expand All @@ -26,19 +26,17 @@ public IEnumerable<V1EnvVar> GenerateEnvVars(PatchingContext context)
public void PatchContainer(V1Container container, PatchingContext context)
{
// Only modify this if CONTRAST_EXISTING_LD_PRELOAD isn't already set. This is to prevent infinite loops.
if (GetFirstOrDefaultEnvVar(container.Env, "LD_PRELOAD") is { Value: { } currentLdPreloadValue }
if (container.Env.FirstOrDefault("LD_PRELOAD") is { Value: { } currentLdPreloadValue }
&& !string.IsNullOrWhiteSpace(currentLdPreloadValue)
&& !currentLdPreloadValue.Contains("agent_injector.so", StringComparison.OrdinalIgnoreCase)
&& GetFirstOrDefaultEnvVar(container.Env, "CONTRAST_EXISTING_LD_PRELOAD") is null)
&& container.Env.FirstOrDefault("CONTRAST_EXISTING_LD_PRELOAD") is null)
{
container.Env.AddOrUpdate(new V1EnvVar("CONTRAST_EXISTING_LD_PRELOAD", currentLdPreloadValue));
container.Env.AddOrUpdate(new V1EnvVar("LD_PRELOAD",
$"{context.AgentMountPath}/injector/agent_injector.so:{currentLdPreloadValue}"));
$"{GetInjectorPreloadPath(context)}:{currentLdPreloadValue}"));
}
}

private static V1EnvVar? GetFirstOrDefaultEnvVar(IEnumerable<V1EnvVar> collection, string name)
{
return collection.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
}
private static string GetInjectorPreloadPath(PatchingContext context) => $"{context.AgentMountPath}/injector/agent_injector.so";

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public IEnumerable<V1EnvVar> GenerateEnvVars(PatchingContext context)

public void PatchContainer(V1Container container, PatchingContext context)
{
if (GetFirstOrDefaultEnvVar(container.Env, "JAVA_TOOL_OPTIONS") is { Value: { } currentJavaToolOptions }
if (container.Env.FirstOrDefault("JAVA_TOOL_OPTIONS") is { Value: { } currentJavaToolOptions }
&& !string.IsNullOrWhiteSpace(currentJavaToolOptions)
&& !currentJavaToolOptions.EndsWith("contrast-agent.jar", StringComparison.OrdinalIgnoreCase)
&& GetFirstOrDefaultEnvVar(container.Env, "CONTRAST_EXISTING_JAVA_TOOL_OPTIONS") is null)
&& container.Env.FirstOrDefault("CONTRAST_EXISTING_JAVA_TOOL_OPTIONS") is null)
{
var contrastAgentArgument = GetContrastAgentArgument(context);

Expand Down Expand Up @@ -65,11 +65,6 @@ public void PatchContainer(V1Container container, PatchingContext context)
}
}

private static V1EnvVar? GetFirstOrDefaultEnvVar(IEnumerable<V1EnvVar> collection, string name)
{
return collection.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
}

private static string GetContrastAgentArgument(PatchingContext context) => $"-javaagent:{context.AgentMountPath}/contrast-agent.jar";

public string GetOverrideAgentMountPath() => "/opt/contrast";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Contrast Security, Inc licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using Contrast.K8s.AgentOperator.Core.Reactions.Injecting.Patching.Utility;
using Contrast.K8s.AgentOperator.Core.State.Resources.Primitives;
using Contrast.K8s.AgentOperator.Options;
using k8s.Models;
using System;
using System.Collections.Generic;

namespace Contrast.K8s.AgentOperator.Core.Reactions.Injecting.Patching.Agents;

Expand All @@ -20,7 +22,7 @@ public PythonAgentPatcher(InjectorOptions injectorOptions)

public IEnumerable<V1EnvVar> GenerateEnvVars(PatchingContext context)
{
yield return new V1EnvVar("PYTHONPATH", $"{context.AgentMountPath}:{context.AgentMountPath}/contrast/loader");
yield return new V1EnvVar("PYTHONPATH", GetAgentPythonPath(context));
if (_injectorOptions.EnablePythonRewriter)
{
yield return new V1EnvVar("CONTRAST__AGENT__PYTHON__REWRITE", "true");
Expand All @@ -29,4 +31,21 @@ public IEnumerable<V1EnvVar> GenerateEnvVars(PatchingContext context)
yield return new V1EnvVar("CONTRAST__AGENT__LOGGER__PATH", $"{context.WritableMountPath}/logs/contrast_agent.log");
yield return new V1EnvVar("CONTRAST_INSTALLATION_TOOL", "KUBERNETES_OPERATOR");
}

public void PatchContainer(V1Container container, PatchingContext context)
{
// Only modify this if CONTRAST_EXISTING_PYTHONPATH isn't already set. This is to prevent infinite loops.
if (container.Env.FirstOrDefault("PYTHONPATH") is { Value: { } currentPath }
&& !string.IsNullOrWhiteSpace(currentPath)
&& !currentPath.Contains("contrast/loader", StringComparison.OrdinalIgnoreCase)
&& container.Env.FirstOrDefault("CONTRAST_EXISTING_PYTHONPATH") is null)
{
container.Env.AddOrUpdate(new V1EnvVar("CONTRAST_EXISTING_PYTHONPATH", currentPath));
container.Env.AddOrUpdate(new V1EnvVar("PYTHONPATH",
$"{GetAgentPythonPath(context)}:{currentPath}"));
}
}

private static string GetAgentPythonPath(PatchingContext context) => $"{context.AgentMountPath}:{context.AgentMountPath}/contrast/loader";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Contrast Security, Inc licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using k8s.Models;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Contrast.K8s.AgentOperator.Core.Reactions.Injecting.Patching.Utility;

public static class PatchingExtensions
{
public static V1EnvVar? FirstOrDefault(this IEnumerable<V1EnvVar> collection, string name)
{
return collection.FirstOrDefault(x => string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase));
}
}
Loading
Loading