analyzer

package
v2.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 7, 2024 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Overview

The analyzer package of cluster-topology-analyzer discovers the connectivity of a Kubernetes application by analyzing its YAML manifests and looking for network addresses that match. It can output a set of discovered connections or even Kubernetes NetworkPolicies to allow only these connections. For more information, see https://github.com/np-guard/cluster-topology-analyzer.

Index

Examples

Constants

View Source
const (
	DefaultDNSPort = 53 // DefaultDNSPort is the default DNS port to use in the generated policies
)

Variables

This section is empty.

Functions

func NetpolListFromNetpolSlice

func NetpolListFromNetpolSlice(netpols []*network.NetworkPolicy) network.NetworkPolicyList

NetpolListFromNetpolSlice converts a slice of Kubernetes NetworkPolicies to a Kubernetes NetworkPolicyList containing all the policies in the slice.

Types

type ConfigMapKeyNotFoundError

type ConfigMapKeyNotFoundError struct {
	// contains filtered or unexported fields
}

ConfigMapKeyNotFoundError is the error emitted when a config map key is referenced by a workload, but cannot be found

func (*ConfigMapKeyNotFoundError) Error

func (err *ConfigMapKeyNotFoundError) Error() string

type ConfigMapNotFoundError

type ConfigMapNotFoundError struct {
	// contains filtered or unexported fields
}

ConfigMapNotFoundError is the error emitted when a config map is referenced by a workload, but cannot be found

func (*ConfigMapNotFoundError) Error

func (err *ConfigMapNotFoundError) Error() string

type Connections

type Connections struct {
	Source *Resource `json:"source,omitempty"`
	Target *Resource `json:"target"`
	Link   *Service  `json:"link"`
}

Connections represents a connection from a source workload to a target workload using via a service.

type DefaultLogger

type DefaultLogger struct {
	// contains filtered or unexported fields
}

DefaultLogger is the package's built-in logger. It uses log.Default() as the underlying logger.

func (*DefaultLogger) Debugf

func (df *DefaultLogger) Debugf(format string, o ...interface{})

Debugf writes a debug message to the log (only if DefaultLogger verbosity is set to HighVerbosity)

func (*DefaultLogger) Errorf

func (df *DefaultLogger) Errorf(err error, format string, o ...interface{})

Errorf writes an error message to the log (regardless of DefaultLogger's verbosity)

func (*DefaultLogger) Infof

func (df *DefaultLogger) Infof(format string, o ...interface{})

Infof writes an informative message to the log (only if DefaultLogger verbosity is set to HighVerbosity)

func (*DefaultLogger) Warnf

func (df *DefaultLogger) Warnf(format string, o ...interface{})

Warnf writes a warning message to the log (unless DefaultLogger verbosity is set to LowVerbosity)

type FailedAccessingDirError

type FailedAccessingDirError struct {
	// contains filtered or unexported fields
}

FailedAccessingDirError is the error emitted when there are problems scanning a directory for YAML files

func (*FailedAccessingDirError) Error

func (err *FailedAccessingDirError) Error() string

func (*FailedAccessingDirError) Unwrap

func (err *FailedAccessingDirError) Unwrap() error

type FailedReadingFileError

type FailedReadingFileError struct {
	// contains filtered or unexported fields
}

FailedReadingFileError is the error emitted for a variety of file-reading issues

func (*FailedReadingFileError) Error

func (err *FailedReadingFileError) Error() string

func (*FailedReadingFileError) Unwrap

func (err *FailedReadingFileError) Unwrap() error

type FailedScanningResource

type FailedScanningResource struct {
	// contains filtered or unexported fields
}

FailedScanningResource is the error emitted when a known resource cannot be properly deciphered

func (*FailedScanningResource) Error

func (err *FailedScanningResource) Error() string

func (*FailedScanningResource) Unwrap

func (err *FailedScanningResource) Unwrap() error

type FileProcessingError

type FileProcessingError struct {
	// contains filtered or unexported fields
}

FileProcessingError holds all information about a single error/warning that occurred during the discovery and processing of the connectivity of a given K8s-app.

func (*FileProcessingError) DocumentID

func (e *FileProcessingError) DocumentID() (int, error)

DocumentID returns the file's YAML document ID (0-based) in which the error occurred (or an error if not applicable)

func (*FileProcessingError) Error

func (e *FileProcessingError) Error() error

Error returns the actual error

func (*FileProcessingError) File

func (e *FileProcessingError) File() string

File returns the file in which the error occurred (or an empty string if no file context is available)

func (*FileProcessingError) IsFatal

func (e *FileProcessingError) IsFatal() bool

IsFatal returns whether the error is considered fatal (no further processing is possible)

func (*FileProcessingError) IsSevere

func (e *FileProcessingError) IsSevere() bool

IsSevere returns whether the error is considered severe (further processing is possible, but results may not be useable)

func (*FileProcessingError) LineNo

func (e *FileProcessingError) LineNo() int

LineNo returns the file's line-number in which the error occurred (or 0 if not applicable)

func (*FileProcessingError) Location

func (e *FileProcessingError) Location() string

Location returns file location (filename, line-number, document ID) of an error (or an empty string if not applicable)

type Logger

type Logger interface {
	Debugf(format string, o ...interface{})
	Infof(format string, o ...interface{})
	Warnf(format string, o ...interface{})
	Errorf(err error, format string, o ...interface{})
}

The Logger interface defines the API for loggers in this package.

func NewDefaultLogger

func NewDefaultLogger() Logger

NewDefaultLogger creates an instance of DefaultLogger with the highest verbosity.

func NewDefaultLoggerWithVerbosity

func NewDefaultLoggerWithVerbosity(verbosity Verbosity) Logger

NewDefaultLoggerWithVerbosity creates an instance of DefaultLogger with a user-defined verbosity.

type NoK8sResourcesFoundError

type NoK8sResourcesFoundError struct {
}

NoK8sResourcesFoundError is the error emitted when no relevant K8s resources can be found in the YAMLs

func (*NoK8sResourcesFoundError) Error

func (err *NoK8sResourcesFoundError) Error() string

type NoYamlsFoundError

type NoYamlsFoundError struct {
}

NoYamlsFoundError is the error emitted when directory scanning finds no YAML files

func (*NoYamlsFoundError) Error

func (err *NoYamlsFoundError) Error() string

type PoliciesSynthesizer

type PoliciesSynthesizer struct {
	// contains filtered or unexported fields
}

A PoliciesSynthesizer provides API to recursively scan a directory for Kubernetes resources and extract the required connectivity between the workloads of the K8s application managed in this directory. It is possible to get either a slice with all the discovered connections or a slice with K8s NetworkPolicies that allow only the discovered connections and nothing more.

Example
package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/np-guard/cluster-topology-analyzer/v2/pkg/analyzer"
)

func main() {
	logger := analyzer.NewDefaultLogger()
	synth := analyzer.NewPoliciesSynthesizer(analyzer.WithLogger(logger))

	netpols, err := synth.PoliciesFromFolderPath("../../tests/k8s_wordpress_example")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error synthesizing policies: %v\n", err)
		os.Exit(1)
	}
	buf, _ := json.MarshalIndent(netpols, "", "    ")
	fmt.Printf("%v\n", string(buf))
}
Output:

[
    {
        "kind": "NetworkPolicy",
        "apiVersion": "networking.k8s.io/v1",
        "metadata": {
            "name": "wordpress-netpol",
            "creationTimestamp": null
        },
        "spec": {
            "podSelector": {
                "matchLabels": {
                    "app": "wordpress",
                    "tier": "frontend"
                }
            },
            "ingress": [
                {
                    "ports": [
                        {
                            "protocol": "TCP",
                            "port": 80
                        }
                    ]
                }
            ],
            "egress": [
                {
                    "ports": [
                        {
                            "protocol": "TCP",
                            "port": 3306
                        }
                    ],
                    "to": [
                        {
                            "podSelector": {
                                "matchLabels": {
                                    "app": "wordpress",
                                    "tier": "mysql"
                                }
                            }
                        }
                    ]
                },
                {
                    "ports": [
                        {
                            "protocol": "UDP",
                            "port": 53
                        }
                    ],
                    "to": [
                        {
                            "namespaceSelector": {}
                        }
                    ]
                }
            ],
            "policyTypes": [
                "Ingress",
                "Egress"
            ]
        }
    },
    {
        "kind": "NetworkPolicy",
        "apiVersion": "networking.k8s.io/v1",
        "metadata": {
            "name": "wordpress-mysql-netpol",
            "creationTimestamp": null
        },
        "spec": {
            "podSelector": {
                "matchLabels": {
                    "app": "wordpress",
                    "tier": "mysql"
                }
            },
            "ingress": [
                {
                    "ports": [
                        {
                            "protocol": "TCP",
                            "port": 3306
                        }
                    ],
                    "from": [
                        {
                            "podSelector": {
                                "matchLabels": {
                                    "app": "wordpress",
                                    "tier": "frontend"
                                }
                            }
                        }
                    ]
                }
            ],
            "policyTypes": [
                "Ingress",
                "Egress"
            ]
        }
    },
    {
        "kind": "NetworkPolicy",
        "apiVersion": "networking.k8s.io/v1",
        "metadata": {
            "name": "default-deny-in-namespace",
            "creationTimestamp": null
        },
        "spec": {
            "podSelector": {},
            "policyTypes": [
                "Ingress",
                "Egress"
            ]
        }
    }
]

func NewPoliciesSynthesizer

func NewPoliciesSynthesizer(options ...PoliciesSynthesizerOption) *PoliciesSynthesizer

NewPoliciesSynthesizer creates a new instance of PoliciesSynthesizer, and applies the provided functional options.

func (*PoliciesSynthesizer) ConnectionsFromFolderPath

func (ps *PoliciesSynthesizer) ConnectionsFromFolderPath(dirPath string) ([]*Connections, error)

ConnectionsFromFolderPath returns a slice of Connections, listing the connections discovered while processing K8s resources under the provided directory or one of its subdirectories (recursively).

func (*PoliciesSynthesizer) ConnectionsFromFolderPaths

func (ps *PoliciesSynthesizer) ConnectionsFromFolderPaths(dirPaths []string) ([]*Connections, error)

ConnectionsFromFolderPaths returns a slice of Connections, listing the connections discovered while processing K8s resources under the provided directories or one of their subdirectories (recursively).

func (*PoliciesSynthesizer) ConnectionsFromInfos

func (ps *PoliciesSynthesizer) ConnectionsFromInfos(infos []*resource.Info) ([]*Connections, error)

ConnectionsFromInfos returns a slice of Connections, listing the connections discovered while processing the K8s resources provided as a slice of Info objects.

func (*PoliciesSynthesizer) ErrorPtrs added in v2.2.0

func (ps *PoliciesSynthesizer) ErrorPtrs() []*FileProcessingError

ErrorPtrs returns a slice of pointers to FileProcessingError with all warnings and errors encountered during processing. Might be easier to use than Errors() if the returned slice is to be used as a slice of interfaces.

func (*PoliciesSynthesizer) Errors

Errors returns a slice of FileProcessingError with all warnings and errors encountered during processing.

func (*PoliciesSynthesizer) PoliciesFromFolderPath

func (ps *PoliciesSynthesizer) PoliciesFromFolderPath(dirPath string) ([]*networking.NetworkPolicy, error)

PoliciesFromFolderPath returns a slice of Kubernetes NetworkPolicies that allow only the connections discovered while processing K8s resources under the provided directory or one of its subdirectories (recursively).

func (*PoliciesSynthesizer) PoliciesFromFolderPaths

func (ps *PoliciesSynthesizer) PoliciesFromFolderPaths(dirPaths []string) ([]*networking.NetworkPolicy, error)

PoliciesFromFolderPaths returns a slice of Kubernetes NetworkPolicies that allow only the connections discovered while processing K8s resources under the provided directories or one of their subdirectories (recursively).

func (*PoliciesSynthesizer) PoliciesFromInfos

func (ps *PoliciesSynthesizer) PoliciesFromInfos(infos []*resource.Info) ([]*networking.NetworkPolicy, error)

PoliciesFromInfos returns a slice of Kubernetes NetworkPolicies that allow only the connections discovered while processing K8s resources in the given slice of Info objects.

type PoliciesSynthesizerOption

type PoliciesSynthesizerOption func(*PoliciesSynthesizer)

PoliciesSynthesizerOption is the type for specifying options for PoliciesSynthesizer, using Golang's Options Pattern (https://golang.cafe/blog/golang-functional-options-pattern.html).

func WithDNSPort

func WithDNSPort(dnsPort int) PoliciesSynthesizerOption

WithDNSPort is a functional option to set the DNS port in the generated policies to a non-default value

func WithLogger

func WithLogger(logger Logger) PoliciesSynthesizerOption

WithLogger is a functional option which sets the logger for a PoliciesSynthesizer to use. The provided logger must conform with the package's Logger interface.

func WithStopOnError

func WithStopOnError() PoliciesSynthesizerOption

WithStopOnError is a functional option which directs PoliciesSynthesizer to stop any processing after the first severe error.

func WithWalkFn

func WithWalkFn(walkFn WalkFunction) PoliciesSynthesizerOption

WithWalkFn is a functional option, allowing user to provide their own dir-scanning function. The function will be used when searching for YAML files; it must have the same signature as filepath.WalkDir.

type Resource

type Resource struct {
	Resource struct {
		Name               string            `json:"name,omitempty"`
		Namespace          string            `json:"namespace,omitempty"`
		Labels             map[string]string `json:"labels,omitempty"`
		ServiceAccountName string            `json:"serviceaccountname,omitempty"`
		FilePath           string            `json:"filepath,omitempty"`
		Kind               string            `json:"kind,omitempty"`
		Image              struct {
			ID string `json:"id,omitempty"`
		} `json:"image"`
		NetworkAddrs     []string
		ConfigMapRefs    []string       `json:"-"`
		ConfigMapKeyRefs []cfgMapKeyRef `json:"-"`
		UsedPorts        []SvcNetworkAttr
	} `json:"resource,omitempty"`
}

Resource is an abstraction of a k8s workload resource (e.g., pod, deployment). It also stores additional information that is later being used in the analysis

type Service

type Service struct {
	Resource struct {
		Name             string             `json:"name,omitempty"`
		Namespace        string             `json:"namespace,omitempty"`
		Selectors        []string           `json:"selectors,omitempty"`
		Type             corev1.ServiceType `json:"type,omitempty"`
		FilePath         string             `json:"filepath,omitempty"`
		Kind             string             `json:"kind,omitempty"`
		Network          []SvcNetworkAttr   `json:"network,omitempty"`
		ExposeToCluster  bool               `json:"-"`
		ExposeExternally bool               `json:"-"`
	} `json:"resource,omitempty"`
}

Service is used to store information about a K8s Service

type SvcNetworkAttr

type SvcNetworkAttr struct {
	Port       int                `json:"port,omitempty"`
	TargetPort intstr.IntOrString `json:"target_port,omitempty"`
	Protocol   corev1.Protocol    `json:"protocol,omitempty"`
}

SvcNetworkAttr is used to store port information

type Verbosity

type Verbosity int

Verbosity is an enumerated type for defining the level of verbosity.

const (
	LowVerbosity    Verbosity = iota // LowVerbosity only reports errors
	MediumVerbosity                  // MediumVerbosity reports warnings and errors
	HighVerbosity                    // HighVerbosity reports infos, warnings and errors
)

type WalkFunction

type WalkFunction func(root string, fn fs.WalkDirFunc) error

WalkFunction is a function for recursively scanning a directory, in the spirit of Go's native filepath.WalkDir() See https://pkg.go.dev/path/filepath#WalkDir for full description on how such a function should work

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL