Skip to content

Negating glob patterns not usable in AgentInjector resource #189

@lkallas

Description

@lkallas

Background

Consider a case where there are many pods running with main container and some sidecar container (e.g. db-proxy) inside a Kubernetes cluster.

Contrast Kuberentes operator AgentInjector custom resource allows one to specify to which containers the agent is injected to inside a pod.

spec.selector.images allows specifying a glob pattern which is used to find a matching container where agent is injected.

I can see that there is C# Glob package in use.

Problem

In my case, I would like to inject nodejs agent into every container in many pods. But I do not want to inject it to db-proxy container which is not a nodejs workload and also does not need any instrumentation.

I struggle to find a good glob pattern for this purpose.
Seems that there actually isn't one for my case - well, Glob package does not implement it (not correctly at least IMO).

So to illustrate this problem, take this small program snippet I used to determine the glob pattern for my case.
I would like to match any Docker image that does not have "some-proxy" in it's name using negating pattern.

using System;
using GlobExpressions;

public interface IGlobMatcher
{
	bool Matches(string pattern, string value);
}

public class GlobMatcher : IGlobMatcher
{
	public bool Matches(string pattern, string value)
	{
		var glob = new Glob(pattern, GlobOptions.CaseInsensitive | GlobOptions.Compiled);
		return glob.IsMatch(value);
	}
}

public class Program
{
	public static void Main()
	{
		var matcher = new GlobMatcher();		
		var pattern = "!(*some-proxy*)";  // Trying to use negating pattern
		
		var result1 = matcher.Matches(pattern, "europe-docker.pkg.dev/project/docker-images/whatever:latest"); // This should return True
		Console.WriteLine(result1); // False
		
		var result2 = matcher.Matches(pattern, "europe-docker.pkg.dev/project/docker-images/some-proxy:latest"); // This should return False
		Console.WriteLine(result2); // False
	}
}

I see that you do not have a such test-case either in your tests.

I could use something like:

var pattern = "**/[!some-proxy]*";

But it will match characters "s", "o", "m", "e", "-", "p", "r", "o", "x", "y" and not in that particular order + char "o" does not have to repeat.
So it matches any permutation of those characters e.g. "oepx-msyro" and "sexy-prom". Not accurate enough.

Workaround

The only workaround right now is to specify each image name in the manifest I wish to have agent injected to. The list grows really long if there are hundreds of unique microservices/images.

apiVersion: agents.contrastsecurity.com/v1beta1
kind: AgentInjector
metadata:
  name: contrast-agent-injector
  namespace: somenamespace
spec:
  enabled: true
  version: latest
  type: nodejs
  selector:
    images:
      - "*important-web*"
      - "*some-other-web*"
      - "*restful-api*"
    labels:
      - name: contrast
        value: enabled

Could you assist/profide a fix?
@Silvenga @gamingrobot

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions