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

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package k8s
     5  
     6  import (
     7  	"context"
     8  
     9  	"github.com/cilium/hive/cell"
    10  	"github.com/sirupsen/logrus"
    11  
    12  	"github.com/cilium/cilium/pkg/k8s"
    13  	cilium_v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"
    14  	cilium_v2_alpha1 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2alpha1"
    15  	"github.com/cilium/cilium/pkg/k8s/client"
    16  	"github.com/cilium/cilium/pkg/k8s/resource"
    17  	slim_networking_v1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/networking/v1"
    18  	"github.com/cilium/cilium/pkg/k8s/synced"
    19  	"github.com/cilium/cilium/pkg/k8s/types"
    20  	"github.com/cilium/cilium/pkg/labels"
    21  	"github.com/cilium/cilium/pkg/option"
    22  	"github.com/cilium/cilium/pkg/policy"
    23  	"github.com/cilium/cilium/pkg/policy/api"
    24  	"github.com/cilium/cilium/pkg/promise"
    25  )
    26  
    27  const (
    28  	k8sAPIGroupNetworkingV1Core                 = "networking.k8s.io/v1::NetworkPolicy"
    29  	k8sAPIGroupCiliumNetworkPolicyV2            = "cilium/v2::CiliumNetworkPolicy"
    30  	k8sAPIGroupCiliumClusterwideNetworkPolicyV2 = "cilium/v2::CiliumClusterwideNetworkPolicy"
    31  	k8sAPIGroupCiliumCIDRGroupV2Alpha1          = "cilium/v2alpha1::CiliumCIDRGroup"
    32  )
    33  
    34  // Cell starts the K8s policy watcher. The K8s policy watcher watches all
    35  // policy related K8s resources (Kubernetes NetworkPolicy (KNP),
    36  // CiliumNetworkPolicy (CNP), ClusterwideCiliumNetworkPolicy (CCNP),
    37  // and CiliumCIDRGroup (CCG)), translates them to Cilium's own
    38  // policy representation (api.Rules) and updates the policy repository
    39  // (via PolicyManager) accordingly.
    40  var Cell = cell.Module(
    41  	"policy-k8s-watcher",
    42  	"Watches K8s policy related objects",
    43  
    44  	cell.Invoke(startK8sPolicyWatcher),
    45  )
    46  
    47  type PolicyManager interface {
    48  	PolicyAdd(rules api.Rules, opts *policy.AddOptions) (newRev uint64, err error)
    49  	PolicyDelete(labels labels.LabelArray, opts *policy.DeleteOptions) (newRev uint64, err error)
    50  }
    51  
    52  type serviceCache interface {
    53  	ForEachService(func(svcID k8s.ServiceID, svc *k8s.Service, eps *k8s.Endpoints) bool)
    54  }
    55  
    56  type PolicyWatcherParams struct {
    57  	cell.In
    58  
    59  	Lifecycle cell.Lifecycle
    60  
    61  	ClientSet client.Clientset
    62  	Config    *option.DaemonConfig
    63  	Logger    logrus.FieldLogger
    64  
    65  	K8sResourceSynced *synced.Resources
    66  	K8sAPIGroups      *synced.APIGroups
    67  
    68  	PolicyManager promise.Promise[PolicyManager]
    69  	ServiceCache  *k8s.ServiceCache
    70  
    71  	CiliumNetworkPolicies            resource.Resource[*cilium_v2.CiliumNetworkPolicy]
    72  	CiliumClusterwideNetworkPolicies resource.Resource[*cilium_v2.CiliumClusterwideNetworkPolicy]
    73  	CiliumCIDRGroups                 resource.Resource[*cilium_v2_alpha1.CiliumCIDRGroup]
    74  	NetworkPolicies                  resource.Resource[*slim_networking_v1.NetworkPolicy]
    75  }
    76  
    77  func startK8sPolicyWatcher(params PolicyWatcherParams) {
    78  	if !params.ClientSet.IsEnabled() {
    79  		return // skip watcher if K8s is not enabled
    80  	}
    81  
    82  	// We want to subscribe before the start hook is invoked in order to not miss
    83  	// any events
    84  	ctx, cancel := context.WithCancel(context.Background())
    85  	svcCacheNotifications := serviceNotificationsQueue(ctx, params.ServiceCache.Notifications())
    86  
    87  	p := &policyWatcher{
    88  		log:                              params.Logger,
    89  		config:                           params.Config,
    90  		k8sResourceSynced:                params.K8sResourceSynced,
    91  		k8sAPIGroups:                     params.K8sAPIGroups,
    92  		svcCache:                         params.ServiceCache,
    93  		svcCacheNotifications:            svcCacheNotifications,
    94  		ciliumNetworkPolicies:            params.CiliumNetworkPolicies,
    95  		ciliumClusterwideNetworkPolicies: params.CiliumClusterwideNetworkPolicies,
    96  		ciliumCIDRGroups:                 params.CiliumCIDRGroups,
    97  		networkPolicies:                  params.NetworkPolicies,
    98  
    99  		cnpCache:          make(map[resource.Key]*types.SlimCNP),
   100  		cidrGroupCache:    make(map[string]*cilium_v2_alpha1.CiliumCIDRGroup),
   101  		cidrGroupPolicies: make(map[resource.Key]struct{}),
   102  
   103  		toServicesPolicies: make(map[resource.Key]struct{}),
   104  		cnpByServiceID:     make(map[k8s.ServiceID]map[resource.Key]struct{}),
   105  	}
   106  
   107  	params.Lifecycle.Append(cell.Hook{
   108  		OnStart: func(startCtx cell.HookContext) error {
   109  			policyManager, err := params.PolicyManager.Await(startCtx)
   110  			if err != nil {
   111  				return err
   112  			}
   113  			p.policyManager = policyManager
   114  			p.watchResources(ctx)
   115  			return nil
   116  		},
   117  		OnStop: func(cell.HookContext) error {
   118  			if cancel != nil {
   119  				cancel()
   120  			}
   121  			return nil
   122  		},
   123  	})
   124  
   125  	if params.Config.EnableK8sNetworkPolicy {
   126  		p.registerResourceWithSyncFn(ctx, k8sAPIGroupNetworkingV1Core, func() bool {
   127  			return p.knpSynced.Load()
   128  		})
   129  	}
   130  	p.registerResourceWithSyncFn(ctx, k8sAPIGroupCiliumNetworkPolicyV2, func() bool {
   131  		return p.cnpSynced.Load() && p.cidrGroupSynced.Load()
   132  	})
   133  	p.registerResourceWithSyncFn(ctx, k8sAPIGroupCiliumClusterwideNetworkPolicyV2, func() bool {
   134  		return p.ccnpSynced.Load() && p.cidrGroupSynced.Load()
   135  	})
   136  	p.registerResourceWithSyncFn(ctx, k8sAPIGroupCiliumCIDRGroupV2Alpha1, func() bool {
   137  		return p.cidrGroupSynced.Load()
   138  	})
   139  }