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

NETOBSERV-1244: Add Kubernetes Infra transform rule #554

Merged
merged 2 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,15 @@ Following is the supported API format for network transformations:
add_location: add output location fields from input
add_service: add output network service field from input port and parameters protocol field
add_kubernetes: add output kubernetes fields from input
add_kubernetes_infra: add output kubernetes isInfra field from input
reinterpret_direction: reinterpret flow direction at the node level (instead of net interface), to ease the deduplication process
add_ip_category: categorize IPs based on known subnets configuration
parameters: parameters specific to type
assignee: value needs to assign to output field
kubernetes_infra: Kubernetes infra rule specific configuration
inputs: entry inputs fields
output: entry output field
infra_prefixes: Namespace prefixes that will be tagged as infra
kubeConfigPath: path to kubeconfig file (optional)
servicesFile: path to services file (optional, default: /etc/services)
protocolsFile: path to protocols file (optional, default: /etc/protocols)
Expand Down
1 change: 1 addition & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const (
AddLocationRuleType = "add_location"
AddServiceRuleType = "add_service"
AddKubernetesRuleType = "add_kubernetes"
AddKubernetesInfraRuleType = "add_kubernetes_infra"
ReinterpretDirectionRuleType = "reinterpret_direction"
PromFilterExact = "exact"
PromFilterPresence = "presence"
Expand Down
19 changes: 14 additions & 5 deletions pkg/api/transform_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (
OpAddLocation = "add_location"
OpAddService = "add_service"
OpAddKubernetes = "add_kubernetes"
OpAddKubernetesInfra = "add_kubernetes_infra"
OpReinterpretDirection = "reinterpret_direction"
OpAddIPCategory = "add_ip_category"
)
Expand All @@ -52,6 +53,7 @@ type TransformNetworkOperationEnum struct {
AddLocation string `yaml:"add_location" json:"add_location" doc:"add output location fields from input"`
AddService string `yaml:"add_service" json:"add_service" doc:"add output network service field from input port and parameters protocol field"`
AddKubernetes string `yaml:"add_kubernetes" json:"add_kubernetes" doc:"add output kubernetes fields from input"`
AddKubernetesInfra string `yaml:"add_kubernetes_infra" json:"add_kubernetes_infra" doc:"add output kubernetes isInfra field from input"`
ReinterpretDirection string `yaml:"reinterpret_direction" json:"reinterpret_direction" doc:"reinterpret flow direction at the node level (instead of net interface), to ease the deduplication process"`
AddIPCategory string `yaml:"add_ip_category" json:"add_ip_category" doc:"categorize IPs based on known subnets configuration"`
}
Expand All @@ -61,11 +63,18 @@ func TransformNetworkOperationName(operation string) string {
}

type NetworkTransformRule struct {
Input string `yaml:"input,omitempty" json:"input,omitempty" doc:"entry input field"`
Output string `yaml:"output,omitempty" json:"output,omitempty" doc:"entry output field"`
Type string `yaml:"type,omitempty" json:"type,omitempty" enum:"TransformNetworkOperationEnum" doc:"one of the following:"`
Parameters string `yaml:"parameters,omitempty" json:"parameters,omitempty" doc:"parameters specific to type"`
Assignee string `yaml:"assignee,omitempty" json:"assignee,omitempty" doc:"value needs to assign to output field"`
Input string `yaml:"input,omitempty" json:"input,omitempty" doc:"entry input field"`
Output string `yaml:"output,omitempty" json:"output,omitempty" doc:"entry output field"`
Type string `yaml:"type,omitempty" json:"type,omitempty" enum:"TransformNetworkOperationEnum" doc:"one of the following:"`
Parameters string `yaml:"parameters,omitempty" json:"parameters,omitempty" doc:"parameters specific to type"`
Assignee string `yaml:"assignee,omitempty" json:"assignee,omitempty" doc:"value needs to assign to output field"`
KubernetesInfra *K8sInfraRule `yaml:"kubernetes_infra,omitempty" json:"kubernetes_infra,omitempty" doc:"Kubernetes infra rule specific configuration"`
}

type K8sInfraRule struct {
Inputs []string `yaml:"inputs,omitempty" json:"inputs,omitempty" doc:"entry inputs fields"`
Output string `yaml:"output,omitempty" json:"output,omitempty" doc:"entry output field"`
InfraPrefix string `yaml:"infra_prefixes,omitempty" json:"infra_prefixes,omitempty" doc:"Namespace prefixes that will be tagged as infra"`
}

type NetworkTransformDirectionInfo struct {
Expand Down
47 changes: 47 additions & 0 deletions pkg/pipeline/transform/transform_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ func (n *Network) Transform(inputEntry config.GenericMap) (config.GenericMap, bo
outputEntry[rule.Output] = serviceName
case api.OpAddKubernetes:
fillInK8s(outputEntry, rule)

case api.OpAddKubernetesInfra:
fillInK8sInfra(outputEntry, rule)

case api.OpReinterpretDirection:
OlivierCazade marked this conversation as resolved.
Show resolved Hide resolved
reinterpretDirection(outputEntry, &n.DirectionInfo)
case api.OpAddIPCategory:
Expand Down Expand Up @@ -182,6 +186,47 @@ func fillInK8s(outputEntry config.GenericMap, rule api.NetworkTransformRule) {
}
}

func fillInK8sInfra(outputEntry config.GenericMap, rule api.NetworkTransformRule) {
if rule.KubernetesInfra == nil {
logrus.Error("transformation rule: Missing Kubernetes Infra configuration ")
return
}
Comment on lines +188 to +191
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we provide a default behavior here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The case here happens if a user added a K8sinfra rule but did not configure it.

In this case, for now we ignore the rule and log an error.

outputEntry[rule.KubernetesInfra.Output] = "infra"
for _, input := range rule.KubernetesInfra.Inputs {
if objectIsApp(fmt.Sprintf("%s", outputEntry[input]), rule.KubernetesInfra.InfraPrefix) {
outputEntry[rule.KubernetesInfra.Output] = "app"
return
}
}
}

const openshiftNamespacePrefix = "openshift-"
const openshiftPrefixLen = len(openshiftNamespacePrefix)

func objectIsApp(addr string, additionalInfraPrefix string) bool {
obj, err := kubernetes.Data.GetInfo(addr)
if err != nil {
logrus.WithError(err).Tracef("can't find kubernetes info for IP %s", addr)
return false
}
nsLen := len(obj.Namespace)
additionalPrefixLen := len(additionalInfraPrefix)
if nsLen == 0 {
return false
}
if nsLen >= openshiftPrefixLen && obj.Namespace[:openshiftPrefixLen] == openshiftNamespacePrefix {
return false
}
if nsLen >= additionalPrefixLen && obj.Namespace[:additionalPrefixLen] == additionalInfraPrefix {
return false
}
//Special case with openshift and kubernetes service in default namespace
if obj.Namespace == "default" && (obj.Name == "kubernetes" || obj.Name == "openshift") {
return false
}
return true
}

OlivierCazade marked this conversation as resolved.
Show resolved Hide resolved
func (n *Network) categorizeIP(ip net.IP) string {
if ip != nil {
for _, subnetCat := range n.categories {
Expand Down Expand Up @@ -211,6 +256,8 @@ func NewTransformNetwork(params config.StageParam) (Transformer, error) {
needToInitLocationDB = true
case api.OpAddKubernetes:
needToInitKubeData = true
case api.OpAddKubernetesInfra:
needToInitKubeData = true
case api.OpAddService:
needToInitNetworkServices = true
case api.OpReinterpretDirection:
Expand Down