Skip to content

Commit

Permalink
Add custom tags to hosts, containers, pods (#2398)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramanan-ravi authored Dec 17, 2024
1 parent ea45b65 commit 5a10fbf
Show file tree
Hide file tree
Showing 26 changed files with 94 additions and 113 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ docker run -dit \
-v /var/log/fenced \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /:/fenced/mnt/host/:ro \
-e USER_DEFINED_TAGS="" \
-e CUSTOM_TAGS="" \
-e MGMT_CONSOLE_URL="---CONSOLE-IP---" \
-e MGMT_CONSOLE_PORT="443" \
-e DEEPFENCE_KEY="---DEEPFENCE-API-KEY---" \
Expand Down
21 changes: 21 additions & 0 deletions deepfence_agent/tools/apache/deepfence/df-utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ const (
maxIdleConnsPerHost = 1024
)

func GetCustomTags() []string {
var customTags []string
// User defined tags
customTagsStr := os.Getenv("CUSTOM_TAGS")
if customTagsStr != "" {
for _, tag := range strings.Split(customTagsStr, ",") {
customTags = append(customTags, strings.TrimSpace(tag))
}
}
return customTags
}

func RemoveLastCharacter(s string) string {
r := []rune(s)
return string(r[:len(r)-1])
Expand Down Expand Up @@ -218,6 +230,15 @@ func GetKubernetesDetails() (string, string, string, string, error) {
return kubeSystemNamespaceUid, kubeClusterName, kubernetesVersion, kubernetesNodeRole, err
}

func InSlice[T comparable](e T, s []T) bool {
for _, v := range s {
if v == e {
return true
}
}
return false
}

func InArray(val interface{}, array interface{}) (exists bool, index int) {
exists = false
index = -1
Expand Down
3 changes: 3 additions & 0 deletions deepfence_agent/tools/apache/scope/probe/cri/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type Reporter struct {
criImageClient client.ImageServiceClient
kubernetesClusterId string
kubernetesClusterName string
customTags []string
}

// NewReporter makes a new Reporter
Expand All @@ -33,6 +34,7 @@ func NewReporter(cri client.RuntimeServiceClient, hostID string, criImageClient
isConsoleVm: dfUtils.IsThisConsoleAgent(),
kubernetesClusterName: os.Getenv(report.KubernetesClusterName),
kubernetesClusterId: os.Getenv(report.KubernetesClusterId),
customTags: dfUtils.GetCustomTags(),
}

return reporter
Expand Down Expand Up @@ -137,6 +139,7 @@ func (r *Reporter) getNode(c *client.Container, imageMetadataMap map[string]Imag
PodName: c.Labels[report.PodNameLabel],
PodID: c.Labels[report.PodIDLabel],
KubernetesNamespace: c.Labels[report.PodNamespaceLabel],
Tags: r.customTags,
}
if c.Labels[report.DeepfenceSystemLabelKey] == report.DeepfenceSystemLabelValue {
metadata.IsDeepfenceSystem = true
Expand Down
51 changes: 12 additions & 39 deletions deepfence_agent/tools/apache/scope/probe/docker/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,11 @@ type Registry interface {
GetContainer(string) (Container, bool)
GetContainerByPrefix(string) (Container, bool)
GetContainerImage(string) (docker_client.APIImages, bool)
GetContainerTags() map[string][]string
GetImageTags() map[string][]string
}

// ContainerUpdateWatcher is the type of functions that get called when containers are updated.
type ContainerUpdateWatcher func(metadata report.TopologyNode)

type UserDefinedTags struct {
tags map[string][]string
sync.RWMutex
}

type registry struct {
sync.RWMutex
quit chan chan struct{}
Expand All @@ -66,17 +59,15 @@ type registry struct {
noCommandLineArguments bool
noEnvironmentVariables bool

watchers []ContainerUpdateWatcher
containers *radix.Tree
containersByPID map[int]Container
images map[string]docker_client.APIImages
networks []docker_client.Network
pipeIDToexecID map[string]string
userDefinedContainerTags UserDefinedTags
userDefinedImageTags UserDefinedTags
isConsoleVm bool
kubernetesClusterId string
kubernetesClusterName string
watchers []ContainerUpdateWatcher
containers *radix.Tree
containersByPID map[int]Container
images map[string]docker_client.APIImages
networks []docker_client.Network
pipeIDToexecID map[string]string
isConsoleVm bool
kubernetesClusterId string
kubernetesClusterName string
}

// Client interface for mocking.
Expand Down Expand Up @@ -128,15 +119,9 @@ func NewRegistry(options RegistryOptions) (Registry, error) {
quit: make(chan chan struct{}),
noCommandLineArguments: options.NoCommandLineArguments,
noEnvironmentVariables: options.NoEnvironmentVariables,
userDefinedContainerTags: UserDefinedTags{
tags: make(map[string][]string),
},
userDefinedImageTags: UserDefinedTags{
tags: make(map[string][]string),
},
isConsoleVm: dfUtils.IsThisConsoleAgent(),
kubernetesClusterId: os.Getenv(report.KubernetesClusterId),
kubernetesClusterName: os.Getenv(report.KubernetesClusterName),
isConsoleVm: dfUtils.IsThisConsoleAgent(),
kubernetesClusterId: os.Getenv(report.KubernetesClusterId),
kubernetesClusterName: os.Getenv(report.KubernetesClusterName),
}
go r.loop()
return r, nil
Expand Down Expand Up @@ -442,18 +427,6 @@ func (r *registry) GetContainerImage(id string) (docker_client.APIImages, bool)
return image, ok
}

func (r *registry) GetContainerTags() map[string][]string {
r.userDefinedContainerTags.RLock()
defer r.userDefinedContainerTags.RUnlock()
return r.userDefinedContainerTags.tags
}

func (r *registry) GetImageTags() map[string][]string {
r.userDefinedImageTags.RLock()
defer r.userDefinedImageTags.RUnlock()
return r.userDefinedImageTags.tags
}

// WalkImages runs f on every image of running containers the registry
// knows of. f may be run on the same image more than once.
func (r *registry) WalkImages(f func(docker_client.APIImages)) {
Expand Down
21 changes: 4 additions & 17 deletions deepfence_agent/tools/apache/scope/probe/docker/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Reporter struct {
probe *probe.Probe
kubernetesClusterId string
kubernetesClusterName string
customTags []string
}

// NewReporter makes a new Reporter
Expand All @@ -37,6 +38,7 @@ func NewReporter(registry Registry, hostID string, probeID string, probe *probe.
probe: probe,
kubernetesClusterName: os.Getenv(report.KubernetesClusterName),
kubernetesClusterId: os.Getenv(report.KubernetesClusterId),
customTags: dfUtils.GetCustomTags(),
}
return reporter
}
Expand Down Expand Up @@ -113,7 +115,6 @@ func (r *Reporter) containerTopology(localAddrs []net.IP, imageIDTagMap map[stri

return container.NetworkInfo(localAddrs), false
}
containerImageTags := r.registry.GetContainerTags()
for _, node := range nodes {
if node.Metadata.NodeID == "" {
continue
Expand All @@ -125,12 +126,8 @@ func (r *Reporter) containerTopology(localAddrs []net.IP, imageIDTagMap map[stri
}
var isInHostNamespace bool
node.Sets, isInHostNamespace = networkInfo(node.Metadata.NodeID)
tags, ok := containerImageTags[node.Metadata.NodeID]
if !ok {
tags = []string{}
}
node.Metadata.Tags = r.customTags
node.Metadata.IsConsoleVm = r.isConsoleVm
node.Metadata.UserDefinedTags = tags
// Indicate whether the container is in the host network
// The container's NetworkMode is not enough due to
// delegation (e.g. NetworkMode="container:foo" where
Expand All @@ -155,7 +152,6 @@ type basicImage struct {

func (r *Reporter) containerImageTopology() (report.Topology, map[string]basicImage) {
result := report.MakeTopology()
imageTagsMap := r.registry.GetImageTags()
imageIDTagMap := make(map[string]basicImage)
r.registry.WalkImages(func(image docker_client.APIImages) {
imageID := trimImageID(image.ID)
Expand Down Expand Up @@ -184,18 +180,9 @@ func (r *Reporter) containerImageTopology() (report.Topology, map[string]basicIm
ImageTag: metadata.ImageTag,
}
}
var tags []string
var ok bool
if metadata.ImageNameWithTag != "" {
tags, ok = imageTagsMap[metadata.ImageNameWithTag]
if !ok {
tags = []string{}
}
} else {
if metadata.ImageNameWithTag == "" {
metadata.NodeName = imageID
}

metadata.UserDefinedTags = tags
if image.Labels[report.DeepfenceSystemLabelKey] == report.DeepfenceSystemLabelValue {
metadata.IsDeepfenceSystem = true
}
Expand Down
32 changes: 8 additions & 24 deletions deepfence_agent/tools/apache/scope/probe/host/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"net"
"os"
"runtime"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -59,16 +58,6 @@ type CloudMeta struct {
mtx sync.RWMutex
}

func GetUserDefinedTags() []string {
var agentTags []string
// User defined tags can be set from agent side also
agentTagsStr := os.Getenv("USER_DEFINED_TAGS")
if agentTagsStr != "" {
agentTags = strings.Split(agentTagsStr, ",")
}
return agentTags
}

func getCloudMetadata(cloudProvider string) (string, cloud_metadata.CloudMetadata) {
var cloudMetadata cloud_metadata.CloudMetadata
if cloudProvider == "aws" {
Expand Down Expand Up @@ -116,11 +105,6 @@ func (r *Reporter) updateCloudMetadata(cloudProvider string) {
r.cloudMeta.mtx.Unlock()
}

type UserDefinedTags struct {
tags []string // Tags given by user. Eg: production, test
sync.RWMutex
}

type HostDetailsEveryMinute struct {
Uptime int
InterfaceNames []string
Expand Down Expand Up @@ -220,7 +204,7 @@ type Reporter struct {
KernelVersion string
AgentVersion string
IsConsoleVm bool
UserDefinedTags []string
CustomTags []string
}

// NewReporter returns a Reporter which produces a report containing host
Expand All @@ -241,10 +225,9 @@ func NewReporter(hostName, probeID, version string) (*Reporter, string, string)
AgentVersion: agentCommitID + "-" + agentBuildTime,
IsConsoleVm: isConsoleVm,
hostDetailsMinute: HostDetailsEveryMinute{},
CustomTags: dfUtils.GetCustomTags(),
}

r.UserDefinedTags = GetUserDefinedTags()

cloudProvider := cloud_metadata.DetectCloudServiceProvider()
r.updateCloudMetadata(cloudProvider)
r.cloudMeta.mtx.RLock()
Expand Down Expand Up @@ -335,10 +318,11 @@ func (r *Reporter) Report() (report.Report, error) {
memoryUsage := r.hostDetailsMetrics.MemoryUsage
r.hostDetailsMetrics.RUnlock()

if len(cloudMetadata.Tags) > 0 {
cloudMetadata.Tags = append(cloudMetadata.Tags, r.UserDefinedTags...)
} else {
cloudMetadata.Tags = r.UserDefinedTags
customTags := append([]string{}, r.CustomTags...)
for _, cloudTag := range cloudMetadata.Tags {
if !dfUtils.InSlice(cloudTag, r.CustomTags) {
customTags = append(customTags, cloudTag)
}
}

rep.CloudProvider.AddNode(
Expand Down Expand Up @@ -400,7 +384,7 @@ func (r *Reporter) Report() (report.Report, error) {
MemoryMax: memoryMax,
MemoryUsage: memoryUsage,
KubernetesClusterId: r.k8sClusterId,
Tags: cloudMetadata.Tags,
Tags: customTags,
},
Parents: &report.Parent{
CloudProvider: cloudProvider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

"github.com/deepfence/ThreatMapper/deepfence_utils/log"
dfUtils "github.com/deepfence/df-utils"
"github.com/deepfence/df-utils/cloud_metadata"
"github.com/weaveworks/scope/report"
)
Expand Down Expand Up @@ -77,6 +78,7 @@ func (k *kubernetesCluster) GetNode() report.TopologyNode {
CloudProvider: cloudMetadata.CloudProvider,
AgentRunning: true,
CloudAccountID: cloudMetadata.AccountID,
Tags: dfUtils.GetCustomTags(),
}
return report.TopologyNode{
Metadata: metadata,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,6 @@ func (m namespaceMeta) MetaNode(id string, nodeType string) report.Metadata {
NodeName: m.Name() + " / " + kubernetesClusterName,
KubernetesLabels: labels,
KubernetesCreated: m.Created(),
Tags: customTags,
}
}
1 change: 1 addition & 0 deletions deepfence_agent/tools/apache/scope/probe/kubernetes/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func (p *pod) GetNode() report.TopologyNode {
HostName: hostname,
KubernetesCreated: p.Created(),
KubernetesLabels: labelsStr,
Tags: customTags,
}
if appLabel, found := p.Labels()[report.DeepfenceK8sAppLabelKey]; found {
if appLabel == report.DeepfenceK8sConsoleAppLabelValue || appLabel == report.DeepfenceK8sAgentAppLabelValue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"
"strings"

dfUtils "github.com/deepfence/df-utils"
"k8s.io/apimachinery/pkg/labels"

"github.com/weaveworks/scope/probe"
Expand All @@ -20,6 +21,7 @@ const (
var (
kubernetesClusterId string
kubernetesClusterName string
customTags []string
)

// Reporter generate Reports containing Container and ContainerImage topologies
Expand All @@ -36,6 +38,7 @@ type Reporter struct {
func NewReporter(client Client, probeID string, hostID string, probe *probe.Probe, nodeName string) *Reporter {
kubernetesClusterId = os.Getenv(k8sClusterId)
kubernetesClusterName = os.Getenv(k8sClusterName)
customTags = dfUtils.GetCustomTags()

reporter := &Reporter{
client: client,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func (s *service) GetNode() report.TopologyNode {
KubernetesType: string(s.Spec.Type),
KubernetesClusterId: kubernetesClusterId,
KubernetesClusterName: kubernetesClusterName,
Tags: customTags,
KubernetesIP: s.Spec.ClusterIP,
KubernetesNamespace: s.GetNamespace(),
}
Expand Down
Loading

0 comments on commit 5a10fbf

Please sign in to comment.