github.com/cilium/cilium@v1.16.2/pkg/endpointmanager/cell.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package endpointmanager
     5  
     6  import (
     7  	"context"
     8  	"net/netip"
     9  	"sync"
    10  
    11  	"github.com/cilium/hive/cell"
    12  
    13  	"github.com/cilium/cilium/pkg/endpoint"
    14  	"github.com/cilium/cilium/pkg/endpoint/regeneration"
    15  	"github.com/cilium/cilium/pkg/identity/cache"
    16  	"github.com/cilium/cilium/pkg/ipcache"
    17  	"github.com/cilium/cilium/pkg/k8s/client"
    18  	"github.com/cilium/cilium/pkg/metrics"
    19  	"github.com/cilium/cilium/pkg/node"
    20  	"github.com/cilium/cilium/pkg/option"
    21  	"github.com/cilium/cilium/pkg/policy"
    22  	"github.com/cilium/cilium/pkg/time"
    23  )
    24  
    25  // Cell provides the EndpointManager which maintains the collection of locally
    26  // running Cilium endpoints. Also exposed are EndpointsLookup and
    27  // EndpointsModify APIs that EndpointManager implements. If possible, choose
    28  // the minimal API as your dependency.
    29  var Cell = cell.Module(
    30  	"endpoint-manager",
    31  	"Manages the collection of local endpoints",
    32  
    33  	cell.Config(defaultEndpointManagerConfig),
    34  	cell.Provide(newDefaultEndpointManager),
    35  	cell.ProvidePrivate(newEndpointSynchronizer),
    36  )
    37  
    38  type EndpointsLookup interface {
    39  	// Lookup looks up endpoint by prefix ID
    40  	Lookup(id string) (*endpoint.Endpoint, error)
    41  
    42  	// LookupCiliumID looks up endpoint by endpoint ID
    43  	LookupCiliumID(id uint16) *endpoint.Endpoint
    44  
    45  	// LookupCNIAttachmentID looks up endpoint by CNI attachment ID
    46  	LookupCNIAttachmentID(id string) *endpoint.Endpoint
    47  
    48  	// LookupIPv4 looks up endpoint by IPv4 address
    49  	LookupIPv4(ipv4 string) *endpoint.Endpoint
    50  
    51  	// LookupIPv6 looks up endpoint by IPv6 address
    52  	LookupIPv6(ipv6 string) *endpoint.Endpoint
    53  
    54  	// LookupIP looks up endpoint by IP address
    55  	LookupIP(ip netip.Addr) (ep *endpoint.Endpoint)
    56  
    57  	// LookupCEPName looks up endpoints by namespace + cep name, e.g. "prod/cep-0"
    58  	LookupCEPName(name string) (ep *endpoint.Endpoint)
    59  
    60  	// GetEndpointsByPodName looks up endpoints by namespace + pod name, e.g. "prod/pod-0"
    61  	GetEndpointsByPodName(name string) []*endpoint.Endpoint
    62  
    63  	// GetEndpointsByContainerID looks up endpoints by container ID
    64  	GetEndpointsByContainerID(containerID string) []*endpoint.Endpoint
    65  
    66  	// GetEndpoints returns a slice of all endpoints present in endpoint manager.
    67  	GetEndpoints() []*endpoint.Endpoint
    68  
    69  	// EndpointExists returns whether the endpoint with id exists.
    70  	EndpointExists(id uint16) bool
    71  
    72  	// GetHostEndpoint returns the host endpoint.
    73  	GetHostEndpoint() *endpoint.Endpoint
    74  
    75  	// HostEndpointExists returns true if the host endpoint exists.
    76  	HostEndpointExists() bool
    77  
    78  	// GetIngressEndpoint returns the ingress endpoint.
    79  	GetIngressEndpoint() *endpoint.Endpoint
    80  
    81  	// IngressEndpointExists returns true if the ingress endpoint exists.
    82  	IngressEndpointExists() bool
    83  
    84  	// GetEndpointNetnsCookieByIP returns the netns cookie for the passed endpoint with ip address if found.
    85  	GetEndpointNetnsCookieByIP(ip netip.Addr) (uint64, error)
    86  }
    87  
    88  type EndpointsModify interface {
    89  	// AddEndpoint takes the prepared endpoint object and starts managing it.
    90  	AddEndpoint(owner regeneration.Owner, ep *endpoint.Endpoint) (err error)
    91  
    92  	// AddIngressEndpoint creates an Endpoint representing Cilium Ingress on this node without a
    93  	// corresponding container necessarily existing. This is needed to be able to ingest and
    94  	// sync network policies applicable to Cilium Ingress to Envoy.
    95  	AddIngressEndpoint(
    96  		ctx context.Context,
    97  		owner regeneration.Owner,
    98  		policyGetter policyRepoGetter,
    99  		ipcache *ipcache.IPCache,
   100  		proxy endpoint.EndpointProxy,
   101  		allocator cache.IdentityAllocator,
   102  	) error
   103  
   104  	AddHostEndpoint(
   105  		ctx context.Context,
   106  		owner regeneration.Owner,
   107  		policyGetter policyRepoGetter,
   108  		ipcache *ipcache.IPCache,
   109  		proxy endpoint.EndpointProxy,
   110  		allocator cache.IdentityAllocator,
   111  	) error
   112  
   113  	// RestoreEndpoint exposes the specified endpoint to other subsystems via the
   114  	// manager.
   115  	RestoreEndpoint(ep *endpoint.Endpoint) error
   116  
   117  	// UpdateReferences updates maps the contents of mappings to the specified endpoint.
   118  	UpdateReferences(ep *endpoint.Endpoint) error
   119  
   120  	// RemoveEndpoint stops the active handling of events by the specified endpoint,
   121  	// and prevents the endpoint from being globally acccessible via other packages.
   122  	RemoveEndpoint(ep *endpoint.Endpoint, conf endpoint.DeleteConfig) []error
   123  }
   124  
   125  type EndpointManager interface {
   126  	EndpointsLookup
   127  	EndpointsModify
   128  	EndpointResourceSynchronizer
   129  
   130  	// Subscribe to endpoint events.
   131  	Subscribe(s Subscriber)
   132  
   133  	// Unsubscribe from endpoint events.
   134  	Unsubscribe(s Subscriber)
   135  
   136  	// UpdatePolicyMaps returns a WaitGroup which is signaled upon once all endpoints
   137  	// have had their PolicyMaps updated against the Endpoint's desired policy state.
   138  	//
   139  	// Endpoints will wait on the 'notifyWg' parameter before updating policy maps.
   140  	UpdatePolicyMaps(ctx context.Context, notifyWg *sync.WaitGroup) *sync.WaitGroup
   141  
   142  	// RegenerateAllEndpoints calls a setState for each endpoint and
   143  	// regenerates if state transaction is valid. During this process, the endpoint
   144  	// list is locked and cannot be modified.
   145  	// Returns a waiting group that can be used to know when all the endpoints are
   146  	// regenerated.
   147  	RegenerateAllEndpoints(regenMetadata *regeneration.ExternalRegenerationMetadata) *sync.WaitGroup
   148  
   149  	// WaitForEndpointsAtPolicyRev waits for all endpoints which existed at the time
   150  	// this function is called to be at a given policy revision.
   151  	// New endpoints appearing while waiting are ignored.
   152  	WaitForEndpointsAtPolicyRev(ctx context.Context, rev uint64) error
   153  
   154  	// OverrideEndpointOpts applies the given options to all endpoints.
   155  	OverrideEndpointOpts(om option.OptionMap)
   156  
   157  	// InitHostEndpointLabels initializes the host endpoint's labels with the
   158  	// node's known labels.
   159  	InitHostEndpointLabels(ctx context.Context)
   160  
   161  	// GetPolicyEndpoints returns a map of all endpoints present in endpoint
   162  	// manager as policy.Endpoint interface set for the map key.
   163  	GetPolicyEndpoints() map[policy.Endpoint]struct{}
   164  
   165  	// HasGlobalCT returns true if the endpoints have a global CT, false otherwise.
   166  	HasGlobalCT() bool
   167  
   168  	// CallbackForEndpointsAtPolicyRev registers a callback on all endpoints that
   169  	// exist when invoked. It is similar to WaitForEndpointsAtPolicyRevision but
   170  	// each endpoint that reaches the desired revision calls 'done' independently.
   171  	// The provided callback should not block and generally be lightweight.
   172  	CallbackForEndpointsAtPolicyRev(ctx context.Context, rev uint64, done func(time.Time)) error
   173  
   174  	// GetEndpointNetnsCookieByIP returns the netns cookie for the passed endpoint with ip address if found.
   175  	GetEndpointNetnsCookieByIP(ip netip.Addr) (uint64, error)
   176  }
   177  
   178  // EndpointResourceSynchronizer is an interface which synchronizes CiliumEndpoint
   179  // resources with Kubernetes.
   180  type EndpointResourceSynchronizer interface {
   181  	RunK8sCiliumEndpointSync(ep *endpoint.Endpoint, hr cell.Health)
   182  	DeleteK8sCiliumEndpointSync(e *endpoint.Endpoint)
   183  }
   184  
   185  var (
   186  	_ EndpointsLookup = &endpointManager{}
   187  	_ EndpointsModify = &endpointManager{}
   188  	_ EndpointManager = &endpointManager{}
   189  )
   190  
   191  type endpointManagerParams struct {
   192  	cell.In
   193  
   194  	Lifecycle       cell.Lifecycle
   195  	Config          EndpointManagerConfig
   196  	Clientset       client.Clientset
   197  	MetricsRegistry *metrics.Registry
   198  	Health          cell.Health
   199  	EPSynchronizer  EndpointResourceSynchronizer
   200  	LocalNodeStore  *node.LocalNodeStore
   201  }
   202  
   203  type endpointManagerOut struct {
   204  	cell.Out
   205  
   206  	Lookup  EndpointsLookup
   207  	Modify  EndpointsModify
   208  	Manager EndpointManager
   209  }
   210  
   211  func newDefaultEndpointManager(p endpointManagerParams) endpointManagerOut {
   212  	checker := endpoint.CheckHealth
   213  
   214  	mgr := New(p.EPSynchronizer, p.LocalNodeStore, p.Health)
   215  	if p.Config.EndpointGCInterval > 0 {
   216  		ctx, cancel := context.WithCancel(context.Background())
   217  		p.Lifecycle.Append(cell.Hook{
   218  			OnStart: func(cell.HookContext) error {
   219  				mgr.WithPeriodicEndpointGC(ctx, checker, p.Config.EndpointGCInterval)
   220  				return nil
   221  			},
   222  			OnStop: func(cell.HookContext) error {
   223  				cancel()
   224  				mgr.controllers.RemoveAllAndWait()
   225  				return nil
   226  			},
   227  		})
   228  	}
   229  
   230  	mgr.InitMetrics(p.MetricsRegistry)
   231  
   232  	return endpointManagerOut{
   233  		Lookup:  mgr,
   234  		Modify:  mgr,
   235  		Manager: mgr,
   236  	}
   237  }
   238  
   239  type endpointSynchronizerParams struct {
   240  	cell.In
   241  
   242  	Clientset client.Clientset
   243  }
   244  
   245  func newEndpointSynchronizer(p endpointSynchronizerParams) EndpointResourceSynchronizer {
   246  	return &EndpointSynchronizer{Clientset: p.Clientset}
   247  }