service

package
v3.1.3 Latest Latest
Warning

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

Go to latest
Published: Apr 10, 2024 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package service manages the main logic of Garm. It contains a token updater to periodically update the N-token for communicating with Athenz, and processing K8s webhook requests. The K8s webhook requests may requires authentication check by Athenz. However, base on the Garm configuration, some requests can be rejected directly.

Index

Constants

View Source
const (
	// ContentType represents a HTTP header name "Content-Type"
	ContentType = "Content-Type"

	// TextPlain represents a HTTP content type "text/plain"
	TextPlain = "text/plain"

	// CharsetUTF8 represents a UTF-8 charset for HTTP response "charset=UTF-8"
	CharsetUTF8 = "charset=UTF-8"
)

Variables

View Source
var (
	// ErrContextClosed represents the error that the context is closed
	ErrContextClosed = errors.New("context Closed")
)
View Source
var (
	// ErrTokenNotFound represents the error that the token is not found
	ErrTokenNotFound = errors.New("Error:\ttoken not found")
)

Functions

func NewTLSConfig

func NewTLSConfig(cfg config.TLS) (*tls.Config, error)

NewTLSConfig returns a *tls.Config struct or error. It reads TLS configuration and initializes *tls.Config struct. It initializes TLS configuration, for example the CA certificate and key to start TLS server. Server and CA Certificate, and private key will read from files from file paths defined in environment variables.

func NewX509CertPool

func NewX509CertPool(path string) (*x509.CertPool, error)

NewX509CertPool returns *x509.CertPool struct or error. The CertPool will read the certificate from the path, and append the content to the system certificate pool.

Types

type AKSResolve

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

AKSResolve implementation for Azure AKS platform.

func (*AKSResolve) BuildDomainsFromNamespace

func (r *AKSResolve) BuildDomainsFromNamespace(namespace string) []string

BuildDomainsFromNamespace returns domains by processing athenzDomains. if namespace != "", replace `/ = .`, then `.. => -`, then replace "_namespace_" in athenzDomains with namespace; else replace "._namespace_" in athenzDomains with namespace; trim ".", then "-", then ":"

func (*AKSResolve) BuildServiceAccountPrefixFromNamespace

func (r *AKSResolve) BuildServiceAccountPrefixFromNamespace(namespace string) []string
BuildServiceAccountPrefixFromNamespace returns domains by processing AthenzServiceAccountPrefix.

if namespace != "", replace `/ = .`, then `.. => -`, then replace "_namespace_" in AthenzServiceAccountPrefix with namespace; else replace "._namespace_" in AthenzServiceAccountPrefix with namespace; trim ".", then "-", then ":"

func (*AKSResolve) GetAdminDomain

func (r *AKSResolve) GetAdminDomain(namespace string) string

GetAdminDomain process cfg.AdminAthenzDomain by 1. replace `/ => .`, and then `.. => -` in namespace 2. replace "_namespace_" to replaced namespace in cfg.AdminAthenzDomain 3. trim ".", then trim "-", then trim ":"

func (*AKSResolve) GetEmptyNamespace

func (r *AKSResolve) GetEmptyNamespace() string

GetEmptyNamespace returns cfg.EmptyNamespace

func (*AKSResolve) GetNonResourceGroup

func (r *AKSResolve) GetNonResourceGroup() string

GetNonResourceGroup returns cfg.NonResourceAPIGroup

func (*AKSResolve) GetNonResourceNamespace

func (r *AKSResolve) GetNonResourceNamespace() string

GetNonResourceNamespace returns cfg.NonResourceNamespace

func (*AKSResolve) IsAdminAccess

func (r *AKSResolve) IsAdminAccess(verb, namespace, apiGroup, resource, name string) bool

IsAdminAccess returns true, if any admin access in config match

func (*AKSResolve) IsAllowed

func (r *AKSResolve) IsAllowed(verb, namespace, apiGroup, resource, name string) bool

IsAllowed returns true, if inside whitelist or not in both list returns false, only if inside blacklist i.e. return (in whitelist || not in blacklist)

func (*AKSResolve) MapAPIGroup

func (r *AKSResolve) MapAPIGroup(group string) string

MapAPIGroup returns "" if cfg.APIGroupControlEnabled == false; else returns cfg.APIGroupMappings mapped value if found, else return original name;

func (*AKSResolve) MapK8sResourceAthenzResource

func (r *AKSResolve) MapK8sResourceAthenzResource(k8sRes string) string

MapK8sResourceAthenzResource returns mapped value in cfg.ResourceMappings, else returns the same value.

func (*AKSResolve) MapResourceName

func (r *AKSResolve) MapResourceName(name string) string

MapResourceName returns "" if cfg.ResourceNameControlEnabled == false; else returns cfg.ResourceNameMappings mapped value if found, else return original name;

func (*AKSResolve) MapVerbAction

func (r *AKSResolve) MapVerbAction(verb string) string

MapVerbAction returns mapped value in cfg.VerbMappings, else returns the same value.

func (*AKSResolve) PrincipalFromUser

func (r *AKSResolve) PrincipalFromUser(user string, groups []string) string

PrincipalFromUser maps K8s user to Athenz principal. 1. service account: if has ServiceAccountPrefixes, remove prefix, map to AthenzServiceAccountPrefix 1.1. if contains namespace, create domain by the namespace and AthenzServiceAccountPrefix 1.2. if no namespaces, create domain by EmptyNamespace and AthenzServiceAccountPrefix 2. athenz user: if has AthenzUserPrefix, OR not contains ".", map to AthenzUserPrefix 3. certificate: if not service account and athenz user, no mapping

func (*AKSResolve) TrimResource

func (r *AKSResolve) TrimResource(res string) string

TrimResource processes res by 1. `/ => .` 2. `.. => -` 3. `-:, :-, .:, :. => :` 4. trim ".", then trim "-", then trim ":" example: TrimResource(fmt.Sprintf("%s:%s.%s.%s", "domain", "group", "resource", "name")) => "domain:group.resource.name" TrimResource(fmt.Sprintf("%s:%s.%s.%s", ".-:domain", "group", "resource", "name:-.")) => "domain:group.resource.name" TrimResource(fmt.Sprintf("%s:%s.%s.%s", "do/ma//in", "gr..oup", "re-source", "n-:a:-m.:e:.")) => "do.ma-in:gr-oup.re-source.n:a:m:e"

type Athenz

type Athenz interface {
	// AthenzAuthorizer sends HTTP requests to Athenz server for authorization.
	AthenzAuthorizer(http.ResponseWriter, *http.Request) error
	// AthenzAuthenticator sends HTTP requests to Athenz server for authentication.
	AthenzAuthenticator(http.ResponseWriter, *http.Request) error
}

Athenz interface is used to send HTTP requests to Athenz server.

func NewAthenz

func NewAthenz(cfg config.Athenz, log Logger) (Athenz, error)

NewAthenz creates a new Athenz object that can handle HTTP requests based on the given configuration. The HTTP handlers will use the given logger for logging.

type EKSResolve

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

EKSResolve implementation for Amazon EKS platform.

func (*EKSResolve) BuildDomainsFromNamespace

func (r *EKSResolve) BuildDomainsFromNamespace(namespace string) []string

BuildDomainsFromNamespace returns domains by processing athenzDomains. if namespace != "", replace `/ = .`, then `.. => -`, then replace "_namespace_" in athenzDomains with namespace; else replace "._namespace_" in athenzDomains with namespace; trim ".", then "-", then ":"

func (*EKSResolve) BuildServiceAccountPrefixFromNamespace

func (r *EKSResolve) BuildServiceAccountPrefixFromNamespace(namespace string) []string
BuildServiceAccountPrefixFromNamespace returns domains by processing AthenzServiceAccountPrefix.

if namespace != "", replace `/ = .`, then `.. => -`, then replace "_namespace_" in AthenzServiceAccountPrefix with namespace; else replace "._namespace_" in AthenzServiceAccountPrefix with namespace; trim ".", then "-", then ":"

func (*EKSResolve) GetAdminDomain

func (r *EKSResolve) GetAdminDomain(namespace string) string

GetAdminDomain process cfg.AdminAthenzDomain by 1. replace `/ => .`, and then `.. => -` in namespace 2. replace "_namespace_" to replaced namespace in cfg.AdminAthenzDomain 3. trim ".", then trim "-", then trim ":"

func (*EKSResolve) GetEmptyNamespace

func (r *EKSResolve) GetEmptyNamespace() string

GetEmptyNamespace returns cfg.EmptyNamespace

func (*EKSResolve) GetNonResourceGroup

func (r *EKSResolve) GetNonResourceGroup() string

GetNonResourceGroup returns cfg.NonResourceAPIGroup

func (*EKSResolve) GetNonResourceNamespace

func (r *EKSResolve) GetNonResourceNamespace() string

GetNonResourceNamespace returns cfg.NonResourceNamespace

func (*EKSResolve) IsAdminAccess

func (r *EKSResolve) IsAdminAccess(verb, namespace, apiGroup, resource, name string) bool

IsAdminAccess returns true, if any admin access in config match

func (*EKSResolve) IsAllowed

func (r *EKSResolve) IsAllowed(verb, namespace, apiGroup, resource, name string) bool

IsAllowed returns true, if inside whitelist or not in both list returns false, only if inside blacklist i.e. return (in whitelist || not in blacklist)

func (*EKSResolve) MapAPIGroup

func (r *EKSResolve) MapAPIGroup(group string) string

MapAPIGroup returns "" if cfg.APIGroupControlEnabled == false; else returns cfg.APIGroupMappings mapped value if found, else return original name;

func (*EKSResolve) MapK8sResourceAthenzResource

func (r *EKSResolve) MapK8sResourceAthenzResource(k8sRes string) string

MapK8sResourceAthenzResource returns mapped value in cfg.ResourceMappings, else returns the same value.

func (*EKSResolve) MapResourceName

func (r *EKSResolve) MapResourceName(name string) string

MapResourceName returns "" if cfg.ResourceNameControlEnabled == false; else returns cfg.ResourceNameMappings mapped value if found, else return original name;

func (*EKSResolve) MapVerbAction

func (r *EKSResolve) MapVerbAction(verb string) string

MapVerbAction returns mapped value in cfg.VerbMappings, else returns the same value.

func (*EKSResolve) PrincipalFromUser

func (r *EKSResolve) PrincipalFromUser(user string, groups []string) string

PrincipalFromUser maps K8s user to Athenz principal. 1. service account: if has ServiceAccountPrefixes, remove prefix, map to AthenzServiceAccountPrefix 1.1. if contains namespace, create domain by the namespace and AthenzServiceAccountPrefix 1.2. if no namespaces, create domain by EmptyNamespace and AthenzServiceAccountPrefix 2. athenz user: if has AthenzUserPrefix, OR not contains ".", map to AthenzUserPrefix 3. certificate: if not service account and athenz user, no mapping

func (*EKSResolve) TrimResource

func (r *EKSResolve) TrimResource(res string) string

TrimResource processes res by 1. `/ => .` 2. `.. => -` 3. `-:, :-, .:, :. => :` 4. trim ".", then trim "-", then trim ":" example: TrimResource(fmt.Sprintf("%s:%s.%s.%s", "domain", "group", "resource", "name")) => "domain:group.resource.name" TrimResource(fmt.Sprintf("%s:%s.%s.%s", ".-:domain", "group", "resource", "name:-.")) => "domain:group.resource.name" TrimResource(fmt.Sprintf("%s:%s.%s.%s", "do/ma//in", "gr..oup", "re-source", "n-:a:-m.:e:.")) => "do.ma-in:gr-oup.re-source.n:a:m:e"

type K8SResolve

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

K8SResolve implementation for K8S platform.

func (*K8SResolve) BuildDomainsFromNamespace

func (r *K8SResolve) BuildDomainsFromNamespace(namespace string) []string

BuildDomainsFromNamespace returns domains by processing athenzDomains. if namespace != "", replace `/ = .`, then `.. => -`, then replace "_namespace_" in athenzDomains with namespace; else replace "._namespace_" in athenzDomains with namespace; trim ".", then "-", then ":"

func (*K8SResolve) BuildServiceAccountPrefixFromNamespace

func (r *K8SResolve) BuildServiceAccountPrefixFromNamespace(namespace string) []string
BuildServiceAccountPrefixFromNamespace returns domains by processing AthenzServiceAccountPrefix.

if namespace != "", replace `/ = .`, then `.. => -`, then replace "_namespace_" in AthenzServiceAccountPrefix with namespace; else replace "._namespace_" in AthenzServiceAccountPrefix with namespace; trim ".", then "-", then ":"

func (*K8SResolve) GetAdminDomain

func (r *K8SResolve) GetAdminDomain(namespace string) string

GetAdminDomain process cfg.AdminAthenzDomain by 1. replace `/ => .`, and then `.. => -` in namespace 2. replace "_namespace_" to replaced namespace in cfg.AdminAthenzDomain 3. trim ".", then trim "-", then trim ":"

func (*K8SResolve) GetEmptyNamespace

func (r *K8SResolve) GetEmptyNamespace() string

GetEmptyNamespace returns cfg.EmptyNamespace

func (*K8SResolve) GetNonResourceGroup

func (r *K8SResolve) GetNonResourceGroup() string

GetNonResourceGroup returns cfg.NonResourceAPIGroup

func (*K8SResolve) GetNonResourceNamespace

func (r *K8SResolve) GetNonResourceNamespace() string

GetNonResourceNamespace returns cfg.NonResourceNamespace

func (*K8SResolve) IsAdminAccess

func (r *K8SResolve) IsAdminAccess(verb, namespace, apiGroup, resource, name string) bool

IsAdminAccess returns true, if any admin access in config match

func (*K8SResolve) IsAllowed

func (r *K8SResolve) IsAllowed(verb, namespace, apiGroup, resource, name string) bool

IsAllowed returns true, if inside whitelist or not in both list returns false, only if inside blacklist i.e. return (in whitelist || not in blacklist)

func (*K8SResolve) MapAPIGroup

func (r *K8SResolve) MapAPIGroup(group string) string

MapAPIGroup returns "" if cfg.APIGroupControlEnabled == false; else returns cfg.APIGroupMappings mapped value if found, else return original name;

func (*K8SResolve) MapK8sResourceAthenzResource

func (r *K8SResolve) MapK8sResourceAthenzResource(k8sRes string) string

MapK8sResourceAthenzResource returns mapped value in cfg.ResourceMappings, else returns the same value.

func (*K8SResolve) MapResourceName

func (r *K8SResolve) MapResourceName(name string) string

MapResourceName returns "" if cfg.ResourceNameControlEnabled == false; else returns cfg.ResourceNameMappings mapped value if found, else return original name;

func (*K8SResolve) MapVerbAction

func (r *K8SResolve) MapVerbAction(verb string) string

MapVerbAction returns mapped value in cfg.VerbMappings, else returns the same value.

func (*K8SResolve) PrincipalFromUser

func (r *K8SResolve) PrincipalFromUser(user string, groups []string) string

PrincipalFromUser maps K8s user to Athenz principal. 1. service account: if has ServiceAccountPrefixes, remove prefix, map to AthenzServiceAccountPrefix 1.1. if contains namespace, create domain by the namespace and AthenzServiceAccountPrefix 1.2. if no namespaces, create domain by EmptyNamespace and AthenzServiceAccountPrefix 2. athenz user: if has AthenzUserPrefix, OR not contains ".", map to AthenzUserPrefix 3. certificate: if not service account and athenz user, no mapping

func (*K8SResolve) TrimResource

func (r *K8SResolve) TrimResource(res string) string

TrimResource processes res by 1. `/ => .` 2. `.. => -` 3. `-:, :-, .:, :. => :` 4. trim ".", then trim "-", then trim ":" example: TrimResource(fmt.Sprintf("%s:%s.%s.%s", "domain", "group", "resource", "name")) => "domain:group.resource.name" TrimResource(fmt.Sprintf("%s:%s.%s.%s", ".-:domain", "group", "resource", "name:-.")) => "domain:group.resource.name" TrimResource(fmt.Sprintf("%s:%s.%s.%s", "do/ma//in", "gr..oup", "re-source", "n-:a:-m.:e:.")) => "do.ma-in:gr-oup.re-source.n:a:m:e"

type Logger

type Logger interface {
	// GetProvider returns the LogProvider function that returns the actual logger instance.
	GetProvider() webhook.LogProvider
	// GetLogFlags returns the LogFlags for log filter inside the actual logger instance.
	GetLogFlags() webhook.LogFlags
	// Close closes the output resources used by the logger.
	Close() error
}

Logger is an intermediate interface to create an actual logger.

func NewLogger

func NewLogger(cfg config.Logger) Logger

NewLogger creates a Logger based on the input configuration.

type Resolver

type Resolver interface {
	// MapVerbAction maps K8s verb to Athenz action.
	MapVerbAction(string) string
	// MapK8sResourceAthenzResource maps K8s resources to resources in Athenz resource.
	MapK8sResourceAthenzResource(string) string
	// BuildDomainsFromNamespace creates Athenz domains with namespace.
	BuildDomainsFromNamespace(string) []string
	// BuildServiceAccountPrefixFromNamespace creates Athenz domains for service account with namespace.
	BuildServiceAccountPrefixFromNamespace(string) []string
	// PrincipalFromUser creates principal name from user.
	PrincipalFromUser(user string, groups []string) string
	// GetAdminDomain creates Athenz admin domain with namespace.
	GetAdminDomain(string) string
	// MapAPIGroup maps K8s API group to API group in Athenz resource.
	MapAPIGroup(group string) string

	MapResourceName(name string) string
	// GetEmptyNamespace returns the mapped value for empty K8s namespace.
	GetEmptyNamespace() string
	// GetNonResourceGroup returns the mapped value for K8s non-resource API group.
	GetNonResourceGroup() string
	// GetNonResourceNamespace returns the mapped value for K8s non-resource namespace.
	GetNonResourceNamespace() string
	// TrimResource sterilizes resources to match Athenz resource naming convention.
	TrimResource(string) string
	// IsAllowed returns true if the K8s request should to Athenz, else returns false if directly reject.
	IsAllowed(verb, namespace, apiGroup, resource, name string) bool
	// IsAdminAccess returns true if the K8s request should use Athenz admin domain.
	IsAdminAccess(verb, namespace, apiGroup, resource, name string) bool
}

Resolver is used to map K8s webhook requests to Athenz requests. (Athenz cannot use ":", hence, needs mapping.)

func NewResolver

func NewResolver(cfg config.Mapping) Resolver

NewResolver returns a new resolver using cfg.TLD.Platform. The actual return type depends on cfg.TLD.Platform.Name. k8s => K8SResolve aks => AKSResolve eks => EKSResolve

type ResourceMapper

type ResourceMapper interface {
	webhook.ResourceMapper
}

ResourceMapper allows for mapping from an authorization request to Athenz principals. Wrapper of webhook.ResourceMapper.

func NewResourceMapper

func NewResourceMapper(resolver Resolver) ResourceMapper

NewResourceMapper creates a new ResourceMapper for mapping K8s resources to Athenz principals.

type Server

type Server interface {
	ListenAndServe(context.Context) chan []error
}

Server represents a Garm server behaviour.

func NewServer

func NewServer(cfg config.Server, h http.Handler) Server

NewServer returns a Server interface, which includes Webhook server and health check server structs. The webhook server is a http.Server instance, which the port number is read from "config.Server.Port" , and make use of the given handler.

The health check server is a http.Server instance, which the port number is read from "config.Server.HealthzPort" , and its handler always return HTTP Status OK (200) response on HTTP GET request.

type TokenService

type TokenService interface {
	StartTokenUpdater(context.Context) TokenService
	GetToken() (string, error)
	// contains filtered or unexported methods
}

TokenService represents an interface for user to get the token, and automatically update the token.

func NewTokenService

func NewTokenService(cfg config.Token) (TokenService, error)

NewTokenService returns a TokenService. It initializes information that required to generate the token (for example, RefreshDuration, Expiration, PrivateKey, etc).

type UserMapper

type UserMapper interface {
	webhook.UserMapper
}

UserMapper allows for mapping from Athenz principals to k8s objects.

func NewUserMapper

func NewUserMapper(resolver Resolver) UserMapper

NewUserMapper returns a UserMapper instance with given Resolver.

Jump to

Keyboard shortcuts

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