From 9d3d10bfb39cbab056239c8cb61521f2a27a43fb Mon Sep 17 00:00:00 2001 From: Quan Tian Date: Thu, 12 Nov 2020 13:41:22 +0800 Subject: [PATCH] Support NetworkPolicy Status for AntreaPolicy (#1442) This patch does the following to support NetworkPolicy Status: 1. Add "status" field to Antrea ClusterNetworkPolicy and Antrea NetworkPolicy CRD 2. Add subresource API "status" to controlplane NetworkPolicy API 3. Each antrea-agent reports controlplane NetworkPolicies' realization status on its own Node to antrea-controller. 4. antrea-controller calculates the aggregated status and syncs it with kube-apiserver. --- build/yamls/antrea-aks.yml | 60 ++ build/yamls/antrea-eks.yml | 60 ++ build/yamls/antrea-gke.yml | 60 ++ build/yamls/antrea-ipsec.yml | 60 ++ build/yamls/antrea.yml | 60 ++ build/yamls/base/agent-rbac.yml | 7 + build/yamls/base/controller-rbac.yml | 7 + build/yamls/base/crds.yml | 46 ++ cmd/antrea-controller/controller.go | 12 + pkg/agent/controller/networkpolicy/cache.go | 45 +- .../networkpolicy/networkpolicy_controller.go | 34 +- .../networkpolicy/status_controller.go | 234 +++++++ .../networkpolicy/status_controller_test.go | 197 ++++++ pkg/apis/controlplane/register.go | 1 + pkg/apis/controlplane/types.go | 17 + pkg/apis/controlplane/v1beta2/generated.pb.go | 633 +++++++++++++++--- pkg/apis/controlplane/v1beta2/generated.proto | 18 + pkg/apis/controlplane/v1beta2/register.go | 1 + pkg/apis/controlplane/v1beta2/types.go | 17 + .../v1beta2/zz_generated.conversion.go | 64 ++ .../v1beta2/zz_generated.deepcopy.go | 47 ++ .../controlplane/zz_generated.deepcopy.go | 47 ++ pkg/apis/security/v1alpha1/types.go | 31 +- .../v1alpha1/zz_generated.deepcopy.go | 18 + pkg/apiserver/apiserver.go | 57 +- pkg/apiserver/openapi/zz_generated.openapi.go | 76 +++ .../networkpolicy/subresources.go | 63 ++ .../fake/fake_networkpolicy_expansion.go | 25 + .../v1beta2/generated_expansion.go | 2 - .../v1beta2/networkpolicy_expansion.go | 30 + .../security/v1alpha1/clusternetworkpolicy.go | 16 + .../fake/fake_clusternetworkpolicy.go | 11 + .../v1alpha1/fake/fake_networkpolicy.go | 12 + .../typed/security/v1alpha1/networkpolicy.go | 17 + .../networkpolicy/antreanetworkpolicy.go | 1 + .../networkpolicy/clusternetworkpolicy.go | 3 +- .../networkpolicy/networkpolicy_controller.go | 7 +- .../networkpolicy/status_controller.go | 350 ++++++++++ .../networkpolicy/status_controller_test.go | 350 ++++++++++ .../networkpolicy/store/networkpolicy.go | 1 + pkg/controller/types/networkpolicy.go | 3 + test/e2e/antreapolicy_test.go | 63 ++ 42 files changed, 2716 insertions(+), 147 deletions(-) create mode 100644 pkg/agent/controller/networkpolicy/status_controller.go create mode 100644 pkg/agent/controller/networkpolicy/status_controller_test.go create mode 100644 pkg/apiserver/registry/networkpolicy/networkpolicy/subresources.go create mode 100644 pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_networkpolicy_expansion.go create mode 100644 pkg/client/clientset/versioned/typed/controlplane/v1beta2/networkpolicy_expansion.go create mode 100644 pkg/controller/networkpolicy/status_controller.go create mode 100644 pkg/controller/networkpolicy/status_controller_test.go diff --git a/build/yamls/antrea-aks.yml b/build/yamls/antrea-aks.yml index 9e6da08614a..5f9048f1f62 100644 --- a/build/yamls/antrea-aks.yml +++ b/build/yamls/antrea-aks.yml @@ -73,6 +73,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -182,9 +192,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -269,6 +292,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -381,9 +414,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -815,6 +861,13 @@ rules: - nodestatssummaries verbs: - create +- apiGroups: + - controlplane.antrea.tanzu.vmware.com + resources: + - networkpolicies/status + verbs: + - create + - get - apiGroups: - authentication.k8s.io resources: @@ -964,6 +1017,13 @@ rules: - get - watch - list +- apiGroups: + - security.antrea.tanzu.vmware.com + resources: + - clusternetworkpolicies/status + - networkpolicies/status + verbs: + - update - apiGroups: - security.antrea.tanzu.vmware.com resources: diff --git a/build/yamls/antrea-eks.yml b/build/yamls/antrea-eks.yml index f09f34cb3c4..95cf45e8ebd 100644 --- a/build/yamls/antrea-eks.yml +++ b/build/yamls/antrea-eks.yml @@ -73,6 +73,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -182,9 +192,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -269,6 +292,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -381,9 +414,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -815,6 +861,13 @@ rules: - nodestatssummaries verbs: - create +- apiGroups: + - controlplane.antrea.tanzu.vmware.com + resources: + - networkpolicies/status + verbs: + - create + - get - apiGroups: - authentication.k8s.io resources: @@ -964,6 +1017,13 @@ rules: - get - watch - list +- apiGroups: + - security.antrea.tanzu.vmware.com + resources: + - clusternetworkpolicies/status + - networkpolicies/status + verbs: + - update - apiGroups: - security.antrea.tanzu.vmware.com resources: diff --git a/build/yamls/antrea-gke.yml b/build/yamls/antrea-gke.yml index ac976c4bda8..99f89e83f6d 100644 --- a/build/yamls/antrea-gke.yml +++ b/build/yamls/antrea-gke.yml @@ -73,6 +73,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -182,9 +192,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -269,6 +292,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -381,9 +414,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -815,6 +861,13 @@ rules: - nodestatssummaries verbs: - create +- apiGroups: + - controlplane.antrea.tanzu.vmware.com + resources: + - networkpolicies/status + verbs: + - create + - get - apiGroups: - authentication.k8s.io resources: @@ -964,6 +1017,13 @@ rules: - get - watch - list +- apiGroups: + - security.antrea.tanzu.vmware.com + resources: + - clusternetworkpolicies/status + - networkpolicies/status + verbs: + - update - apiGroups: - security.antrea.tanzu.vmware.com resources: diff --git a/build/yamls/antrea-ipsec.yml b/build/yamls/antrea-ipsec.yml index 0297f66d3e8..34266e4cf5a 100644 --- a/build/yamls/antrea-ipsec.yml +++ b/build/yamls/antrea-ipsec.yml @@ -73,6 +73,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -182,9 +192,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -269,6 +292,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -381,9 +414,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -815,6 +861,13 @@ rules: - nodestatssummaries verbs: - create +- apiGroups: + - controlplane.antrea.tanzu.vmware.com + resources: + - networkpolicies/status + verbs: + - create + - get - apiGroups: - authentication.k8s.io resources: @@ -964,6 +1017,13 @@ rules: - get - watch - list +- apiGroups: + - security.antrea.tanzu.vmware.com + resources: + - clusternetworkpolicies/status + - networkpolicies/status + verbs: + - update - apiGroups: - security.antrea.tanzu.vmware.com resources: diff --git a/build/yamls/antrea.yml b/build/yamls/antrea.yml index 049df241db8..7ff33111fa6 100644 --- a/build/yamls/antrea.yml +++ b/build/yamls/antrea.yml @@ -73,6 +73,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -182,9 +192,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -269,6 +292,16 @@ spec: jsonPath: .spec.priority name: Priority type: number + - description: The total number of Nodes that should realize the NetworkPolicy. + format: int32 + jsonPath: .status.desiredNodesRealized + name: Desired Nodes + type: number + - description: The number of Nodes that have realized the NetworkPolicy. + format: int32 + jsonPath: .status.currentNodesRealized + name: Current Nodes + type: number - jsonPath: .metadata.creationTimestamp name: Age type: date @@ -381,9 +414,22 @@ spec: - appliedTo - priority type: object + status: + properties: + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + observedGeneration: + type: integer + phase: + type: string + type: object type: object served: true storage: true + subresources: + status: {} --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -815,6 +861,13 @@ rules: - nodestatssummaries verbs: - create +- apiGroups: + - controlplane.antrea.tanzu.vmware.com + resources: + - networkpolicies/status + verbs: + - create + - get - apiGroups: - authentication.k8s.io resources: @@ -964,6 +1017,13 @@ rules: - get - watch - list +- apiGroups: + - security.antrea.tanzu.vmware.com + resources: + - clusternetworkpolicies/status + - networkpolicies/status + verbs: + - update - apiGroups: - security.antrea.tanzu.vmware.com resources: diff --git a/build/yamls/base/agent-rbac.yml b/build/yamls/base/agent-rbac.yml index cc7f9d6cc51..4779a65f3cb 100644 --- a/build/yamls/base/agent-rbac.yml +++ b/build/yamls/base/agent-rbac.yml @@ -54,6 +54,13 @@ rules: - nodestatssummaries verbs: - create + - apiGroups: + - controlplane.antrea.tanzu.vmware.com + resources: + - networkpolicies/status + verbs: + - create + - get - apiGroups: - authentication.k8s.io resources: diff --git a/build/yamls/base/controller-rbac.yml b/build/yamls/base/controller-rbac.yml index a1706b06d61..c9ee499fe39 100644 --- a/build/yamls/base/controller-rbac.yml +++ b/build/yamls/base/controller-rbac.yml @@ -112,6 +112,13 @@ rules: - get - watch - list + - apiGroups: + - security.antrea.tanzu.vmware.com + resources: + - clusternetworkpolicies/status + - networkpolicies/status + verbs: + - update - apiGroups: - security.antrea.tanzu.vmware.com resources: diff --git a/build/yamls/base/crds.yml b/build/yamls/base/crds.yml index a00bf46096d..ba04008ad81 100644 --- a/build/yamls/base/crds.yml +++ b/build/yamls/base/crds.yml @@ -271,6 +271,16 @@ spec: format: float description: The Priority of this ClusterNetworkPolicy relative to other policies. jsonPath: .spec.priority + - name: Desired Nodes + type: number + format: int32 + description: The total number of Nodes that should realize the NetworkPolicy. + jsonPath: .status.desiredNodesRealized + - name: Current Nodes + type: number + format: int32 + description: The number of Nodes that have realized the NetworkPolicy. + jsonPath: .status.currentNodesRealized - name: Age type: date jsonPath: .metadata.creationTimestamp @@ -381,6 +391,19 @@ spec: type: string enableLogging: type: boolean + status: + type: object + properties: + phase: + type: string + observedGeneration: + type: integer + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + subresources: + status: {} scope: Cluster names: plural: clusternetworkpolicies @@ -411,6 +434,16 @@ spec: format: float description: The Priority of this Antrea NetworkPolicy relative to other policies. jsonPath: .spec.priority + - name: Desired Nodes + type: number + format: int32 + description: The total number of Nodes that should realize the NetworkPolicy. + jsonPath: .status.desiredNodesRealized + - name: Current Nodes + type: number + format: int32 + description: The number of Nodes that have realized the NetworkPolicy. + jsonPath: .status.currentNodesRealized - name: Age type: date jsonPath: .metadata.creationTimestamp @@ -524,6 +557,19 @@ spec: type: string enableLogging: type: boolean + status: + type: object + properties: + phase: + type: string + observedGeneration: + type: integer + currentNodesRealized: + type: integer + desiredNodesRealized: + type: integer + subresources: + status: {} scope: Namespaced names: plural: networkpolicies diff --git a/cmd/antrea-controller/controller.go b/cmd/antrea-controller/controller.go index 79091fbd71b..6e988167fa4 100644 --- a/cmd/antrea-controller/controller.go +++ b/cmd/antrea-controller/controller.go @@ -115,6 +115,11 @@ func run(o *Options) error { appliedToGroupStore, networkPolicyStore) + var networkPolicyStatusController *networkpolicy.StatusController + if features.DefaultFeatureGate.Enabled(features.AntreaPolicy) { + networkPolicyStatusController = networkpolicy.NewStatusController(crdClient, networkPolicyStore, cnpInformer, anpInformer) + } + endpointQuerier := networkpolicy.NewEndpointQuerier(networkPolicyController) controllerQuerier := querier.NewControllerQuerier(networkPolicyController, o.config.APIPort) @@ -144,6 +149,7 @@ func run(o *Options) error { controllerQuerier, endpointQuerier, networkPolicyController, + networkPolicyStatusController, statsAggregator, o.config.EnablePrometheusMetrics) if err != nil { @@ -187,6 +193,10 @@ func run(o *Options) error { go traceflowController.Run(stopCh) } + if features.DefaultFeatureGate.Enabled(features.AntreaPolicy) { + go networkPolicyStatusController.Run(stopCh) + } + <-stopCh klog.Info("Stopping Antrea controller") return nil @@ -203,6 +213,7 @@ func createAPIServerConfig(kubeconfig string, controllerQuerier querier.ControllerQuerier, endpointQuerier networkpolicy.EndpointQuerier, npController *networkpolicy.NetworkPolicyController, + networkPolicyStatusController *networkpolicy.StatusController, statsAggregator *stats.Aggregator, enableMetrics bool) (*apiserver.Config, error) { secureServing := genericoptions.NewSecureServingOptions().WithLoopback() @@ -254,6 +265,7 @@ func createAPIServerConfig(kubeconfig string, caCertController, statsAggregator, controllerQuerier, + networkPolicyStatusController, endpointQuerier, npController), nil } diff --git a/pkg/agent/controller/networkpolicy/cache.go b/pkg/agent/controller/networkpolicy/cache.go index 65dc8dd872f..4fbd12e506a 100644 --- a/pkg/agent/controller/networkpolicy/cache.go +++ b/pkg/agent/controller/networkpolicy/cache.go @@ -220,6 +220,26 @@ func (c *ruleCache) getAppliedNetworkPolicies(pod, namespace string, npFilter *q return policies } +func (c *ruleCache) getRule(ruleID string) (*rule, bool) { + obj, exists, _ := c.rules.GetByKey(ruleID) + if !exists { + return nil, false + } + return obj.(*rule), true +} + +func (c *ruleCache) getRulesByNetworkPolicy(uid string) []*rule { + objs, _ := c.rules.ByIndex(policyIndex, uid) + if len(objs) == 0 { + return nil + } + rules := make([]*rule, len(objs)) + for i, obj := range objs { + rules[i] = obj.(*rule) + } + return rules +} + func (c *ruleCache) GetAddressGroups() []v1beta.AddressGroup { var ret []v1beta.AddressGroup c.addressSetLock.RLock() @@ -566,8 +586,12 @@ func (c *ruleCache) ReplaceNetworkPolicies(policies []*v1beta.NetworkPolicy) { } for i := range policies { - oldKeys.Delete(string(policies[i].UID)) - c.addNetworkPolicyLocked(policies[i]) + if oldKeys.Has(string(policies[i].UID)) { + oldKeys.Delete(string(policies[i].UID)) + } else { + metrics.NetworkPolicyCount.Inc() + } + c.updateNetworkPolicyLocked(policies[i]) } for key := range oldKeys { @@ -581,21 +605,22 @@ func (c *ruleCache) ReplaceNetworkPolicies(policies []*v1beta.NetworkPolicy) { // watcher reconnects to the Apiserver, we use the same processing as // UpdateNetworkPolicy to ensure orphan rules are removed. func (c *ruleCache) AddNetworkPolicy(policy *v1beta.NetworkPolicy) error { + metrics.NetworkPolicyCount.Inc() c.policyMapLock.Lock() defer c.policyMapLock.Unlock() - - return c.addNetworkPolicyLocked(policy) -} - -func (c *ruleCache) addNetworkPolicyLocked(policy *v1beta.NetworkPolicy) error { - c.policyMap[string(policy.UID)] = policy - metrics.NetworkPolicyCount.Inc() - return c.UpdateNetworkPolicy(policy) + return c.updateNetworkPolicyLocked(policy) } // UpdateNetworkPolicy updates a cached *v1beta.NetworkPolicy. // The added rules and removed rules will be regarded as dirty. func (c *ruleCache) UpdateNetworkPolicy(policy *v1beta.NetworkPolicy) error { + c.policyMapLock.Lock() + defer c.policyMapLock.Unlock() + return c.updateNetworkPolicyLocked(policy) +} + +func (c *ruleCache) updateNetworkPolicyLocked(policy *v1beta.NetworkPolicy) error { + c.policyMap[string(policy.UID)] = policy existingRules, _ := c.rules.ByIndex(policyIndex, string(policy.UID)) ruleByID := map[string]interface{}{} for _, r := range existingRules { diff --git a/pkg/agent/controller/networkpolicy/networkpolicy_controller.go b/pkg/agent/controller/networkpolicy/networkpolicy_controller.go index 34d1c2f9d80..88c57b9eeb5 100644 --- a/pkg/agent/controller/networkpolicy/networkpolicy_controller.go +++ b/pkg/agent/controller/networkpolicy/networkpolicy_controller.go @@ -75,7 +75,9 @@ type Controller struct { reconciler Reconciler // ofClient registers packetin for Antrea Policy logging. ofClient openflow.Client - + // statusManager syncs NetworkPolicy statuses with the antrea-controller. + // It's only for Antrea NetworkPolicies. + statusManager StatusManager networkPolicyWatcher *watcher appliedToGroupWatcher *watcher addressGroupWatcher *watcher @@ -97,6 +99,10 @@ func NewNetworkPolicyController(antreaClientGetter agent.AntreaClientProvider, antreaPolicyEnabled: antreaPolicyEnabled, } c.ruleCache = newRuleCache(c.enqueueRule, podUpdates) + if antreaPolicyEnabled { + c.statusManager = newStatusController(antreaClientGetter, nodeName, c.ruleCache) + } + // Create a WaitGroup that is used to block network policy workers from asynchronously processing // NP rules until the events preceding bookmark are synced. It can also be used as part of the // solution to a deterministic mechanism for when to cleanup flows from previous round. @@ -182,6 +188,13 @@ func NewNetworkPolicyController(antreaClientGetter agent.AntreaClientProvider, return nil } klog.Infof("NetworkPolicy %s applied to Pods on this Node", policies[i].SourceRef.ToString()) + // When ReplaceFunc is called, either the controller restarted or this was a regular reconnection. + // For the former case, agent must resync the statuses as the controller lost the previous statuses. + // For the latter case, agent doesn't need to do anything. However, we are not able to differentiate the + // two cases. Anyway there's no harm to do a periodical resync. + if c.antreaPolicyEnabled && policies[i].SourceRef.Type != v1beta2.K8sNetworkPolicy { + c.statusManager.Resync(policies[i].UID) + } } c.ruleCache.ReplaceNetworkPolicies(policies) return nil @@ -381,6 +394,10 @@ func (c *Controller) Run(stopCh <-chan struct{}) { klog.Infof("Starting IDAllocator worker to maintain the async rule cache") go c.reconciler.RunIDAllocatorWorker(stopCh) + if c.antreaPolicyEnabled { + go c.statusManager.Run(stopCh) + } + <-stopCh } @@ -442,6 +459,11 @@ func (c *Controller) syncRule(key string) error { if err := c.reconciler.Forget(key); err != nil { return err } + if c.antreaPolicyEnabled { + // We don't know whether this is a rule owned by Antrea Policy, but + // harmless to delete it. + c.statusManager.DeleteRuleRealization(key) + } return nil } // If the rule is not complete, we can simply skip it as it will be marked as dirty @@ -453,6 +475,9 @@ func (c *Controller) syncRule(key string) error { if err := c.reconciler.Reconcile(rule); err != nil { return err } + if c.antreaPolicyEnabled && rule.SourceRef.Type != v1beta2.K8sNetworkPolicy { + c.statusManager.SetRuleRealization(key, rule.PolicyUID) + } return nil } @@ -477,6 +502,13 @@ func (c *Controller) syncRules(keys []string) error { if err := c.reconciler.BatchReconcile(allRules); err != nil { return err } + if c.antreaPolicyEnabled { + for _, rule := range allRules { + if rule.SourceRef.Type != v1beta2.K8sNetworkPolicy { + c.statusManager.SetRuleRealization(rule.ID, rule.PolicyUID) + } + } + } return nil } diff --git a/pkg/agent/controller/networkpolicy/status_controller.go b/pkg/agent/controller/networkpolicy/status_controller.go new file mode 100644 index 00000000000..8dd9d52db8f --- /dev/null +++ b/pkg/agent/controller/networkpolicy/status_controller.go @@ -0,0 +1,234 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package networkpolicy + +import ( + "context" + "fmt" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog" + + "github.com/vmware-tanzu/antrea/pkg/agent" + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2" +) + +const ( + realizedRulePolicyIndex = "policy" +) + +// StatusManager keeps track of the realized NetworkPolicy rules. It syncs the status of a NetworkPolicy to the +// antrea-controller once it is realized. A policy is considered realized when all of its desired rules have been +// realized and all of its undesired rules have been removed. +// For each new policy, SetRuleRealization is supposed to be called for each of its desired rules while +// DeleteRuleRealization is supposed to be called for the removed rules. +type StatusManager interface { + // SetRuleRealization updates the actual status for the given NetworkPolicy rule. + SetRuleRealization(ruleID string, policyID types.UID) + // DeleteRuleRealization deletes the actual status for the given NetworkPolicy rule. + DeleteRuleRealization(ruleID string) + // Resync triggers syncing status with the antrea-controller for the given NetworkPolicy. + Resync(policyID types.UID) + // Start the status sync loop. + Run(stopCh <-chan struct{}) +} + +// StatusController implements StatusManager. +type StatusController struct { + nodeName string + // statusControlInterface knows how to update control plane NetworkPolicy status. + statusControlInterface networkPolicyStatusControlInterface + // ruleCache provides the desired state of NetworkPolicy rules. + ruleCache *ruleCache + // realizedRules keeps track of the realized NetworkPolicy rules. + realizedRules cache.Indexer + // queue maintains the UIDs of the NetworkPolicy that need to be processed. + queue workqueue.RateLimitingInterface +} + +// realizedRule is the struct kept by StatusController for storing a realized rule. +// It has policyID because "ruleCache" only keeps desired state of policies, so if a rule is no longer in a policy it +// will be deleted immediately from "ruleCache" while we need to know these rules are actually uninstalled from +// dataplane before their policies are considered realized. +type realizedRule struct { + ruleID string + policyID types.UID +} + +func realizedRuleKeyFunc(obj interface{}) (string, error) { + return obj.(*realizedRule).ruleID, nil +} + +func realizedRulePolicyIndexFunc(obj interface{}) ([]string, error) { + rule := obj.(*realizedRule) + return []string{string(rule.policyID)}, nil +} + +func newStatusController(antreaClientProvider agent.AntreaClientProvider, nodeName string, ruleCache *ruleCache) *StatusController { + return &StatusController{ + statusControlInterface: &networkPolicyStatusControl{antreaClientProvider: antreaClientProvider}, + nodeName: nodeName, + ruleCache: ruleCache, + realizedRules: cache.NewIndexer(realizedRuleKeyFunc, cache.Indexers{ + realizedRulePolicyIndex: realizedRulePolicyIndexFunc, + }), + queue: workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(minRetryDelay, maxRetryDelay), "networkpolicystatus"), + } +} + +func (c *StatusController) SetRuleRealization(ruleID string, policyID types.UID) { + _, exists, _ := c.realizedRules.GetByKey(ruleID) + // This rule has been realized before. The current call must be triggered by group member updates, which doesn't + // affect the policy's realization status. + if exists { + return + } + c.realizedRules.Add(&realizedRule{ruleID: ruleID, policyID: policyID}) + c.queue.Add(policyID) +} + +func (c *StatusController) DeleteRuleRealization(ruleID string) { + obj, exists, _ := c.realizedRules.GetByKey(ruleID) + // This rule hasn't been realized before, so it doesn't affect the policy's realization status. + if !exists { + return + } + c.realizedRules.Delete(obj) + c.queue.Add(obj.(*realizedRule).policyID) +} + +func (c *StatusController) Resync(policyID types.UID) { + klog.V(2).Infof("Resyncing NetworkPolicyStatus for %s", policyID) + c.queue.Add(policyID) +} + +// worker is a long-running function that will continually call the processNextWorkItem function in +// order to read and process a message on the workqueue. +func (c *StatusController) worker() { + for c.processNextWorkItem() { + } +} + +func (c *StatusController) processNextWorkItem() bool { + obj, quit := c.queue.Get() + if quit { + return false + } + // We call Done here so the workqueue knows we have finished processing this item. We also + // must remember to call Forget if we do not want this work item being re-queued. For + // example, we do not call Forget if a transient error occurs, instead the item is put back + // on the workqueue and attempted again after a back-off period. + defer c.queue.Done(obj) + + // We expect NetworkPolicy UID to come off the workqueue. + if key, ok := obj.(types.UID); !ok { + // As the item in the workqueue is actually invalid, we call Forget here else we'd + // go into a loop of attempting to process a work item that is invalid. + // This should not happen: enqueueNode only enqueues UIDs. + c.queue.Forget(obj) + klog.Errorf("Expected UID in work queue but got %#v", obj) + return true + } else if err := c.syncHandler(key); err == nil { + // If no error occurs we Forget this item so it does not get queued again until + // another change happens. + c.queue.Forget(key) + } else { + // Put the item back on the workqueue to handle any transient errors. + c.queue.AddRateLimited(key) + klog.Errorf("Error syncing NetworkPolicyStatus for %s, requeuing. Error: %v", key, err) + } + return true +} + +func (c *StatusController) syncHandler(uid types.UID) error { + policy := c.ruleCache.getNetworkPolicy(string(uid)) + // The policy must have been deleted, no further processing. + if policy == nil { + return nil + } + desiredRules := c.ruleCache.getRulesByNetworkPolicy(string(uid)) + // The policy must have been deleted, no further processing. + if len(desiredRules) == 0 { + return nil + } + actualRules, _ := c.realizedRules.ByIndex(realizedRulePolicyIndex, string(uid)) + // desiredRules should match actualRules exactly. + if len(desiredRules) != len(actualRules) { + return nil + } + desiredRuleSet := sets.NewString() + for _, r := range desiredRules { + desiredRuleSet.Insert(r.ID) + } + for _, r := range actualRules { + ruleID := r.(*realizedRule).ruleID + if !desiredRuleSet.Has(ruleID) { + return nil + } + desiredRuleSet.Delete(ruleID) + } + if len(desiredRuleSet) > 0 { + return nil + } + + // At this point, all desired rules have been realized and all undesired rules have been removed, report it to the antrea-controller. + klog.V(2).Infof("Syncing NetworkPolicyStatus for %s, generation: %v", uid, policy.Generation) + status := &v1beta2.NetworkPolicyStatus{ + ObjectMeta: metav1.ObjectMeta{ + Name: policy.Name, + }, + Nodes: []v1beta2.NetworkPolicyNodeStatus{ + { + NodeName: c.nodeName, + Generation: policy.Generation, + }, + }, + } + return c.statusControlInterface.UpdateNetworkPolicyStatus(status.Name, status) +} + +func (c *StatusController) Run(stopCh <-chan struct{}) { + klog.Info("Starting NetworkPolicy StatusController") + defer klog.Info("Shutting down NetworkPolicy StatusController") + + for i := 0; i < defaultWorkers; i++ { + go wait.Until(c.worker, time.Second, stopCh) + } + <-stopCh +} + +// networkPolicyStatusControlInterface is an interface that knows how to get and update control plane NetworkPolicy status. +// It's created as an interface to allow testing. +type networkPolicyStatusControlInterface interface { + UpdateNetworkPolicyStatus(name string, status *v1beta2.NetworkPolicyStatus) error +} + +type networkPolicyStatusControl struct { + antreaClientProvider agent.AntreaClientProvider +} + +func (c *networkPolicyStatusControl) UpdateNetworkPolicyStatus(name string, status *v1beta2.NetworkPolicyStatus) error { + antreaClient, err := c.antreaClientProvider.GetAntreaClient() + if err != nil { + return fmt.Errorf("error getting antrea client: %v", err) + } + return antreaClient.ControlplaneV1beta2().NetworkPolicies().UpdateStatus(context.TODO(), name, status) +} diff --git a/pkg/agent/controller/networkpolicy/status_controller_test.go b/pkg/agent/controller/networkpolicy/status_controller_test.go new file mode 100644 index 00000000000..6cd9358489d --- /dev/null +++ b/pkg/agent/controller/networkpolicy/status_controller_test.go @@ -0,0 +1,197 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package networkpolicy + +import ( + "fmt" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2" +) + +const ( + testNode1 = "node1" +) + +type fakeNetworkPolicyControl struct { + sync.Mutex + status *v1beta2.NetworkPolicyStatus +} + +func (c *fakeNetworkPolicyControl) UpdateNetworkPolicyStatus(name string, status *v1beta2.NetworkPolicyStatus) error { + c.Lock() + defer c.Unlock() + c.status = status + return nil +} + +func (c *fakeNetworkPolicyControl) getNetworkPolicyStatus() *v1beta2.NetworkPolicyStatus { + c.Lock() + defer c.Unlock() + return c.status +} + +func newTestStatusController() (*StatusController, *ruleCache, *fakeNetworkPolicyControl) { + ruleCache := newRuleCache(func(s string) {}, make(<-chan v1beta2.PodReference)) + statusControl := &fakeNetworkPolicyControl{} + statusController := newStatusController(nil, testNode1, ruleCache) + statusController.statusControlInterface = statusControl + return statusController, ruleCache, statusControl +} + +func TestSyncStatusForNewPolicy(t *testing.T) { + policyWithSingleRule := newNetworkPolicy("policy1", "uid1", []string{"addressGroup1"}, []string{}, []string{"appliedToGroup1"}, nil) + policyWithSingleRule.Generation = 1 + policyWithMultipleRules := newNetworkPolicyWithMultipleRules("policy1", "uid1", []string{"addressGroup1"}, []string{}, []string{"appliedToGroup1"}, nil) + policyWithMultipleRules.Generation = 1 + tests := []struct { + name string + policy *v1beta2.NetworkPolicy + realizedRules int + expectedStatus *v1beta2.NetworkPolicyStatus + }{ + { + name: "no rules realized", + policy: policyWithSingleRule, + realizedRules: 0, + expectedStatus: nil, + }, + { + name: "some rules realized", + policy: policyWithMultipleRules, + realizedRules: 1, + expectedStatus: nil, + }, + { + name: "all rules realized", + policy: policyWithMultipleRules, + realizedRules: 2, + expectedStatus: &v1beta2.NetworkPolicyStatus{ + ObjectMeta: v1.ObjectMeta{ + Name: policyWithMultipleRules.Name, + }, + Nodes: []v1beta2.NetworkPolicyNodeStatus{ + { + NodeName: testNode1, + Generation: 1, + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + statusController, ruleCache, statusControl := newTestStatusController() + stopCh := make(chan struct{}) + defer close(stopCh) + go statusController.Run(stopCh) + + ruleCache.AddNetworkPolicy(tt.policy) + rules := ruleCache.getRulesByNetworkPolicy(string(tt.policy.UID)) + for i, rule := range rules { + // Only make specified number of rules realized. + if i >= tt.realizedRules { + break + } + statusController.SetRuleRealization(rule.ID, tt.policy.UID) + } + // TODO: Use a determinate mechanism. + time.Sleep(500 * time.Millisecond) + assert.Equal(t, tt.expectedStatus, statusControl.getNetworkPolicyStatus()) + }) + } +} + +func TestSyncStatusUpForUpdatedPolicy(t *testing.T) { + statusController, ruleCache, statusControl := newTestStatusController() + stopCh := make(chan struct{}) + defer close(stopCh) + go statusController.Run(stopCh) + + policy := newNetworkPolicy("policy1", "uid1", []string{"addressGroup1"}, []string{}, []string{"appliedToGroup1"}, nil) + policy.Generation = 1 + ruleCache.AddNetworkPolicy(policy) + rule1 := ruleCache.getRulesByNetworkPolicy(string(policy.UID))[0] + statusController.SetRuleRealization(rule1.ID, policy.UID) + + matchGeneration := func(generation int64) error { + return wait.PollImmediate(100*time.Millisecond, 1*time.Second, func() (done bool, err error) { + status := statusControl.getNetworkPolicyStatus() + if status == nil { + return false, nil + } + return status.Nodes[0].Generation == generation, nil + }) + } + assert.NoError(t, matchGeneration(policy.Generation), "The generation should be updated to %v but was not updated", policy.Generation) + + // Add a new rule to the policy. + policy.Rules = append(policy.Rules, newPolicyRule(v1beta2.DirectionOut, nil, []string{"addressGroup2"}, nil)) + policy.Generation = 2 + ruleCache.UpdateNetworkPolicy(policy) + assert.Error(t, matchGeneration(policy.Generation), "The generation should not be updated to %v but was updated", policy.Generation) + + rules := ruleCache.getRulesByNetworkPolicy(string(policy.UID)) + for _, rule := range rules { + // Only call SetRuleRealization for new rule. + if rule.ID != rule1.ID { + statusController.SetRuleRealization(rule.ID, policy.UID) + } + } + assert.NoError(t, matchGeneration(policy.Generation), "The generation should be updated to %v but was not updated", policy.Generation) + + // Remove the above new rule from the policy. + policy.Rules = policy.Rules[0:1] + policy.Generation = 3 + ruleCache.UpdateNetworkPolicy(policy) + assert.Error(t, matchGeneration(policy.Generation), "The generation should not be updated to %v but was updated", policy.Generation) + + for _, rule := range rules { + // Only call SetRuleRealization for new rule. + if rule.ID != rule1.ID { + statusController.DeleteRuleRealization(rule.ID) + } + } + assert.NoError(t, matchGeneration(policy.Generation), "The generation should be updated to %v but was not updated", policy.Generation) +} + +// BenchmarkSyncHandler benchmarks syncHandler when the policy has 100 rules. Its current result is: +// 47754 ns/op 15320 B/op 23 allocs/op +func BenchmarkSyncHandler(b *testing.B) { + statusController, ruleCache, _ := newTestStatusController() + + policy := newNetworkPolicy("policy1", "uid1", []string{"addressGroup1"}, []string{}, []string{"appliedToGroup1"}, nil) + policy.Generation = 1 + for i := 1; i < 100; i++ { + policy.Rules = append(policy.Rules, newPolicyRule(v1beta2.DirectionOut, nil, []string{fmt.Sprintf("addressGroup%d", i)}, nil)) + } + ruleCache.AddNetworkPolicy(policy) + rules := ruleCache.getRulesByNetworkPolicy(string(policy.UID)) + for _, rule := range rules { + statusController.SetRuleRealization(rule.ID, policy.UID) + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + statusController.syncHandler(policy.UID) + } +} diff --git a/pkg/apis/controlplane/register.go b/pkg/apis/controlplane/register.go index a46636d5ff4..7186f1a3def 100644 --- a/pkg/apis/controlplane/register.go +++ b/pkg/apis/controlplane/register.go @@ -53,6 +53,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { &AddressGroupList{}, &NetworkPolicy{}, &NetworkPolicyList{}, + &NetworkPolicyStatus{}, &NodeStatsSummary{}, ) return nil diff --git a/pkg/apis/controlplane/types.go b/pkg/apis/controlplane/types.go index d679fcad5cc..6a5cad1475a 100644 --- a/pkg/apis/controlplane/types.go +++ b/pkg/apis/controlplane/types.go @@ -264,3 +264,20 @@ type NetworkPolicyStats struct { // The stats of the NetworkPolicy. TrafficStats statsv1alpha1.TrafficStats } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// NetworkPolicyStatus is the status of a NetworkPolicy. +type NetworkPolicyStatus struct { + metav1.TypeMeta + metav1.ObjectMeta + // Nodes contains statuses produced on a list of Nodes. + Nodes []NetworkPolicyNodeStatus +} + +// NetworkPolicyNodeStatus is the status of a NetworkPolicy on a Node. +type NetworkPolicyNodeStatus struct { + // The name of the Node that produces the status. + NodeName string + // The generation realized by the Node. + Generation int64 +} diff --git a/pkg/apis/controlplane/v1beta2/generated.pb.go b/pkg/apis/controlplane/v1beta2/generated.pb.go index b1c169daad4..1be3bc5a0b6 100644 --- a/pkg/apis/controlplane/v1beta2/generated.pb.go +++ b/pkg/apis/controlplane/v1beta2/generated.pb.go @@ -409,10 +409,38 @@ func (m *NetworkPolicyList) XXX_DiscardUnknown() { var xxx_messageInfo_NetworkPolicyList proto.InternalMessageInfo +func (m *NetworkPolicyNodeStatus) Reset() { *m = NetworkPolicyNodeStatus{} } +func (*NetworkPolicyNodeStatus) ProtoMessage() {} +func (*NetworkPolicyNodeStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_d31898dc88dbbf6e, []int{13} +} +func (m *NetworkPolicyNodeStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NetworkPolicyNodeStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NetworkPolicyNodeStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_NetworkPolicyNodeStatus.Merge(m, src) +} +func (m *NetworkPolicyNodeStatus) XXX_Size() int { + return m.Size() +} +func (m *NetworkPolicyNodeStatus) XXX_DiscardUnknown() { + xxx_messageInfo_NetworkPolicyNodeStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_NetworkPolicyNodeStatus proto.InternalMessageInfo + func (m *NetworkPolicyPeer) Reset() { *m = NetworkPolicyPeer{} } func (*NetworkPolicyPeer) ProtoMessage() {} func (*NetworkPolicyPeer) Descriptor() ([]byte, []int) { - return fileDescriptor_d31898dc88dbbf6e, []int{13} + return fileDescriptor_d31898dc88dbbf6e, []int{14} } func (m *NetworkPolicyPeer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -440,7 +468,7 @@ var xxx_messageInfo_NetworkPolicyPeer proto.InternalMessageInfo func (m *NetworkPolicyReference) Reset() { *m = NetworkPolicyReference{} } func (*NetworkPolicyReference) ProtoMessage() {} func (*NetworkPolicyReference) Descriptor() ([]byte, []int) { - return fileDescriptor_d31898dc88dbbf6e, []int{14} + return fileDescriptor_d31898dc88dbbf6e, []int{15} } func (m *NetworkPolicyReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -468,7 +496,7 @@ var xxx_messageInfo_NetworkPolicyReference proto.InternalMessageInfo func (m *NetworkPolicyRule) Reset() { *m = NetworkPolicyRule{} } func (*NetworkPolicyRule) ProtoMessage() {} func (*NetworkPolicyRule) Descriptor() ([]byte, []int) { - return fileDescriptor_d31898dc88dbbf6e, []int{15} + return fileDescriptor_d31898dc88dbbf6e, []int{16} } func (m *NetworkPolicyRule) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -496,7 +524,7 @@ var xxx_messageInfo_NetworkPolicyRule proto.InternalMessageInfo func (m *NetworkPolicyStats) Reset() { *m = NetworkPolicyStats{} } func (*NetworkPolicyStats) ProtoMessage() {} func (*NetworkPolicyStats) Descriptor() ([]byte, []int) { - return fileDescriptor_d31898dc88dbbf6e, []int{16} + return fileDescriptor_d31898dc88dbbf6e, []int{17} } func (m *NetworkPolicyStats) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -521,10 +549,38 @@ func (m *NetworkPolicyStats) XXX_DiscardUnknown() { var xxx_messageInfo_NetworkPolicyStats proto.InternalMessageInfo +func (m *NetworkPolicyStatus) Reset() { *m = NetworkPolicyStatus{} } +func (*NetworkPolicyStatus) ProtoMessage() {} +func (*NetworkPolicyStatus) Descriptor() ([]byte, []int) { + return fileDescriptor_d31898dc88dbbf6e, []int{18} +} +func (m *NetworkPolicyStatus) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NetworkPolicyStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *NetworkPolicyStatus) XXX_Merge(src proto.Message) { + xxx_messageInfo_NetworkPolicyStatus.Merge(m, src) +} +func (m *NetworkPolicyStatus) XXX_Size() int { + return m.Size() +} +func (m *NetworkPolicyStatus) XXX_DiscardUnknown() { + xxx_messageInfo_NetworkPolicyStatus.DiscardUnknown(m) +} + +var xxx_messageInfo_NetworkPolicyStatus proto.InternalMessageInfo + func (m *NodeStatsSummary) Reset() { *m = NodeStatsSummary{} } func (*NodeStatsSummary) ProtoMessage() {} func (*NodeStatsSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_d31898dc88dbbf6e, []int{17} + return fileDescriptor_d31898dc88dbbf6e, []int{19} } func (m *NodeStatsSummary) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -552,7 +608,7 @@ var xxx_messageInfo_NodeStatsSummary proto.InternalMessageInfo func (m *PodReference) Reset() { *m = PodReference{} } func (*PodReference) ProtoMessage() {} func (*PodReference) Descriptor() ([]byte, []int) { - return fileDescriptor_d31898dc88dbbf6e, []int{18} + return fileDescriptor_d31898dc88dbbf6e, []int{20} } func (m *PodReference) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -580,7 +636,7 @@ var xxx_messageInfo_PodReference proto.InternalMessageInfo func (m *Service) Reset() { *m = Service{} } func (*Service) ProtoMessage() {} func (*Service) Descriptor() ([]byte, []int) { - return fileDescriptor_d31898dc88dbbf6e, []int{19} + return fileDescriptor_d31898dc88dbbf6e, []int{21} } func (m *Service) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -619,10 +675,12 @@ func init() { proto.RegisterType((*NamedPort)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NamedPort") proto.RegisterType((*NetworkPolicy)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicy") proto.RegisterType((*NetworkPolicyList)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicyList") + proto.RegisterType((*NetworkPolicyNodeStatus)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicyNodeStatus") proto.RegisterType((*NetworkPolicyPeer)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicyPeer") proto.RegisterType((*NetworkPolicyReference)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicyReference") proto.RegisterType((*NetworkPolicyRule)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicyRule") proto.RegisterType((*NetworkPolicyStats)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicyStats") + proto.RegisterType((*NetworkPolicyStatus)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NetworkPolicyStatus") proto.RegisterType((*NodeStatsSummary)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.NodeStatsSummary") proto.RegisterType((*PodReference)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.PodReference") proto.RegisterType((*Service)(nil), "github.com.vmware_tanzu.antrea.pkg.apis.controlplane.v1beta2.Service") @@ -633,105 +691,110 @@ func init() { } var fileDescriptor_d31898dc88dbbf6e = []byte{ - // 1556 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x58, 0xbb, 0x6f, 0x1b, 0x47, - 0x1a, 0xd7, 0xf2, 0x21, 0x89, 0x23, 0x52, 0x8f, 0x91, 0x7d, 0xe6, 0xf9, 0x7c, 0xa4, 0xcc, 0x3b, - 0x1c, 0x54, 0x9c, 0x97, 0x96, 0xce, 0x97, 0x18, 0x88, 0x53, 0x68, 0x2d, 0x59, 0x60, 0x22, 0xcb, - 0xc4, 0x48, 0x6e, 0x82, 0x00, 0xc9, 0x68, 0x77, 0x48, 0xad, 0xb5, 0xbb, 0xb3, 0x9e, 0x1d, 0xca, - 0x56, 0x8a, 0x20, 0x41, 0xaa, 0xa4, 0xc9, 0xab, 0x49, 0x95, 0xce, 0x48, 0xfe, 0x86, 0x74, 0xe9, - 0x5c, 0xba, 0x74, 0x13, 0x22, 0xa2, 0x91, 0xb4, 0xe9, 0x82, 0x40, 0x40, 0x80, 0x60, 0x66, 0x87, - 0xdc, 0x5d, 0x4a, 0xb4, 0x15, 0x50, 0x12, 0x02, 0x24, 0x95, 0xb4, 0x33, 0xdf, 0xf7, 0xfd, 0x7e, - 0xdf, 0x73, 0x66, 0x08, 0xd6, 0x9a, 0x36, 0xdf, 0x6e, 0x6d, 0xe9, 0x26, 0x75, 0xab, 0xbb, 0xee, - 0x03, 0xcc, 0xc8, 0x15, 0x8e, 0xbd, 0x77, 0x5a, 0x55, 0xec, 0x71, 0x46, 0x70, 0xd5, 0xdf, 0x69, - 0x56, 0xb1, 0x6f, 0x07, 0x55, 0x93, 0x7a, 0x9c, 0x51, 0xc7, 0x77, 0xb0, 0x47, 0xaa, 0xbb, 0x0b, - 0x5b, 0x84, 0xe3, 0xc5, 0x6a, 0x93, 0x78, 0x84, 0x61, 0x4e, 0x2c, 0xdd, 0x67, 0x94, 0x53, 0x78, - 0x23, 0xb2, 0xa6, 0x87, 0xd6, 0xde, 0x92, 0xd6, 0xf4, 0xd0, 0x9a, 0xee, 0xef, 0x34, 0x75, 0x61, - 0x4d, 0x8f, 0x5b, 0xd3, 0x95, 0xb5, 0x8b, 0x57, 0x62, 0x5c, 0x9a, 0xb4, 0x49, 0xab, 0xd2, 0xe8, - 0x56, 0xab, 0x21, 0xbf, 0xe4, 0x87, 0xfc, 0x2f, 0x04, 0xbb, 0x78, 0xeb, 0xb8, 0xd4, 0x03, 0x8e, - 0x79, 0x50, 0xdd, 0x5d, 0xc0, 0x8e, 0xbf, 0x8d, 0x17, 0xfa, 0x49, 0x5f, 0xbc, 0xb6, 0x73, 0x3d, - 0xd0, 0x6d, 0x2a, 0x64, 0x5d, 0x6c, 0x6e, 0xdb, 0x1e, 0x61, 0x7b, 0x91, 0xb2, 0x4b, 0x38, 0xae, - 0xee, 0x1e, 0xd6, 0xaa, 0x0e, 0xd2, 0x62, 0x2d, 0x8f, 0xdb, 0x2e, 0x39, 0xa4, 0xf0, 0xd2, 0x8b, - 0x14, 0x02, 0x73, 0x9b, 0xb8, 0xf8, 0x90, 0xde, 0xff, 0x06, 0xe9, 0xb5, 0xb8, 0xed, 0x54, 0x6d, - 0x8f, 0x07, 0x9c, 0xf5, 0x2b, 0x55, 0x7e, 0xd6, 0x40, 0x7e, 0xc9, 0xb2, 0x18, 0x09, 0x82, 0x55, - 0x46, 0x5b, 0x3e, 0x7c, 0x1b, 0x8c, 0x0b, 0x4f, 0x2c, 0xcc, 0x71, 0x51, 0x9b, 0xd3, 0xe6, 0x27, - 0x16, 0xaf, 0xea, 0xa1, 0x61, 0x3d, 0x6e, 0x38, 0xca, 0x90, 0x90, 0xd6, 0x77, 0x17, 0xf4, 0x3b, - 0x5b, 0xf7, 0x88, 0xc9, 0x6f, 0x13, 0x8e, 0x0d, 0xf8, 0xb8, 0x5d, 0x1e, 0xe9, 0xb4, 0xcb, 0x20, - 0x5a, 0x43, 0x3d, 0xab, 0xf0, 0x03, 0x0d, 0xe4, 0x9b, 0x02, 0xeb, 0x36, 0x71, 0xb7, 0x08, 0x0b, - 0x8a, 0xa9, 0xb9, 0xf4, 0xfc, 0xc4, 0x62, 0x4d, 0x1f, 0xa6, 0x26, 0xf4, 0xd5, 0xc8, 0xa2, 0x71, - 0x4e, 0xe1, 0xe7, 0x63, 0x8b, 0x01, 0x4a, 0x80, 0x56, 0xf6, 0x35, 0x30, 0x1d, 0x77, 0x7c, 0xcd, - 0x0e, 0x38, 0x7c, 0xf3, 0x90, 0xf3, 0xfa, 0xf1, 0x9c, 0x17, 0xda, 0xd2, 0xf5, 0x69, 0x05, 0x3d, - 0xde, 0x5d, 0x89, 0x39, 0x4e, 0x41, 0xd6, 0xe6, 0xc4, 0xed, 0x3a, 0xfc, 0xda, 0x70, 0x0e, 0xc7, - 0xc9, 0x1b, 0x05, 0x05, 0x9b, 0xad, 0x09, 0x00, 0x14, 0xe2, 0x54, 0x1e, 0xa5, 0xc1, 0x4c, 0x5c, - 0xac, 0x8e, 0xb9, 0xb9, 0x7d, 0x06, 0x19, 0xfe, 0x4c, 0x03, 0x33, 0xd8, 0xb2, 0x88, 0xb5, 0x7a, - 0xaa, 0x69, 0xfe, 0xbb, 0x22, 0x21, 0x7c, 0x4c, 0x62, 0xa1, 0xc3, 0xf0, 0xf0, 0x0b, 0x0d, 0xcc, - 0x32, 0xe2, 0xd2, 0xdd, 0x3e, 0x5a, 0xe9, 0x93, 0xa6, 0xf5, 0x0f, 0x45, 0x6b, 0x16, 0x1d, 0x46, - 0x43, 0x47, 0x51, 0xa8, 0xfc, 0xa2, 0x81, 0xc9, 0x25, 0xdf, 0x77, 0x6c, 0x62, 0x6d, 0xd2, 0x3f, - 0x57, 0x1b, 0xfe, 0xa0, 0x01, 0x98, 0x74, 0xfd, 0x0c, 0x1a, 0xf1, 0x7e, 0xb2, 0x11, 0xd7, 0x86, - 0x6c, 0xc4, 0x04, 0xfd, 0x01, 0xad, 0xf8, 0x55, 0x1a, 0xcc, 0x26, 0x05, 0xff, 0x6a, 0xc6, 0x3f, - 0x66, 0x33, 0x3a, 0xe0, 0xc2, 0xca, 0x43, 0x4e, 0x98, 0x87, 0x9d, 0x15, 0x8f, 0xdb, 0x7c, 0x0f, - 0x91, 0x06, 0x61, 0xc4, 0x33, 0x09, 0x9c, 0x03, 0x19, 0x0f, 0xbb, 0x44, 0x26, 0x2a, 0x67, 0xe4, - 0x95, 0xe9, 0xcc, 0x3a, 0x76, 0x09, 0x92, 0x3b, 0xb0, 0x0a, 0x72, 0xe2, 0x6f, 0xe0, 0x63, 0x93, - 0x14, 0x53, 0x52, 0x6c, 0x46, 0x89, 0xe5, 0xd6, 0xbb, 0x1b, 0x28, 0x92, 0xa9, 0x7c, 0x99, 0x06, - 0x13, 0x31, 0x78, 0x48, 0x40, 0xda, 0xa7, 0x96, 0x2a, 0x85, 0x21, 0x4f, 0x88, 0x3a, 0xb5, 0x7a, - 0xdc, 0x8d, 0xb1, 0x4e, 0xbb, 0x9c, 0x16, 0x2b, 0xc2, 0x3e, 0xfc, 0x54, 0x03, 0x93, 0x24, 0xe1, - 0xa5, 0x64, 0x3b, 0xb1, 0x78, 0x77, 0x38, 0xc8, 0x01, 0x91, 0x33, 0x60, 0xa7, 0x5d, 0x9e, 0xec, - 0xdb, 0xec, 0x23, 0x00, 0xff, 0x03, 0xd2, 0xb6, 0x1f, 0x96, 0x40, 0xde, 0x38, 0x27, 0xe8, 0xd6, - 0xea, 0xc1, 0x41, 0xbb, 0x9c, 0xab, 0xd5, 0xd5, 0x21, 0x86, 0x84, 0x00, 0x74, 0x40, 0xd6, 0xa7, - 0x8c, 0x07, 0xc5, 0x8c, 0x2c, 0x96, 0xd5, 0xe1, 0x18, 0x8b, 0xac, 0x58, 0x75, 0xca, 0x78, 0xd4, - 0xb8, 0xe2, 0x2b, 0x40, 0x21, 0x48, 0xe5, 0x3b, 0x0d, 0x8c, 0xd5, 0xea, 0x86, 0x43, 0xcd, 0x1d, - 0x48, 0x40, 0xc6, 0xb4, 0x2d, 0xa6, 0xb2, 0x73, 0x73, 0x38, 0xe0, 0x5a, 0x7d, 0x9d, 0xf0, 0xa8, - 0x88, 0x6e, 0xd6, 0x96, 0x11, 0x92, 0xe6, 0xe1, 0x0e, 0x18, 0x25, 0x0f, 0x4d, 0xe2, 0x73, 0xd5, - 0xa5, 0x27, 0x02, 0x34, 0xa9, 0x80, 0x46, 0x57, 0xa4, 0x69, 0xa4, 0x20, 0x2a, 0x0d, 0x90, 0x95, - 0x02, 0xf0, 0x5f, 0x20, 0x65, 0xfb, 0xd2, 0xb5, 0xbc, 0x31, 0xdb, 0x69, 0x97, 0x53, 0xb5, 0x7a, - 0x32, 0xf8, 0x29, 0xdb, 0x87, 0xd7, 0x41, 0xde, 0x67, 0xa4, 0x61, 0x3f, 0x5c, 0x23, 0x5e, 0x93, - 0x6f, 0xcb, 0xa2, 0xc9, 0x46, 0x83, 0xbe, 0x1e, 0xdb, 0x43, 0x09, 0xc9, 0xca, 0x87, 0x1a, 0xc8, - 0xf5, 0x62, 0x2d, 0x3a, 0x49, 0x84, 0x57, 0xc2, 0x65, 0xa3, 0x20, 0x88, 0x3d, 0x24, 0x77, 0x7a, - 0xbd, 0x96, 0x1a, 0xd8, 0x6b, 0xd7, 0xc1, 0xb8, 0xbc, 0xc3, 0x9a, 0xd4, 0x29, 0xa6, 0xa5, 0xd4, - 0xa5, 0xee, 0xcc, 0xaf, 0xab, 0xf5, 0x83, 0xd8, 0xff, 0xa8, 0x27, 0x5d, 0xf9, 0x28, 0x03, 0x0a, - 0xeb, 0x84, 0x3f, 0xa0, 0x6c, 0xa7, 0x4e, 0x1d, 0xdb, 0xdc, 0x3b, 0x83, 0x31, 0xcc, 0x41, 0x96, - 0xb5, 0x1c, 0xd2, 0x9d, 0xbc, 0x77, 0x86, 0xac, 0xda, 0x38, 0x7b, 0xd4, 0x72, 0x48, 0x54, 0xbd, - 0xe2, 0x2b, 0x40, 0x21, 0x18, 0x7c, 0x15, 0x4c, 0xe1, 0xc4, 0xa9, 0x13, 0xf6, 0x57, 0x4e, 0x66, - 0x78, 0x2a, 0x79, 0x20, 0x05, 0xa8, 0x5f, 0x16, 0xce, 0x8b, 0x10, 0xdb, 0x94, 0x89, 0xf9, 0x90, - 0x99, 0xd3, 0xe6, 0x35, 0x23, 0x1f, 0x86, 0x37, 0x5c, 0x43, 0xbd, 0x5d, 0x78, 0x0d, 0xe4, 0xb9, - 0x4d, 0x58, 0x77, 0xa7, 0x98, 0x95, 0x89, 0x9d, 0x16, 0x45, 0xb1, 0x19, 0x5b, 0x47, 0x09, 0x29, - 0xf8, 0xbe, 0x06, 0x72, 0x01, 0x6d, 0x31, 0x93, 0x20, 0xd2, 0x28, 0x8e, 0xca, 0xc0, 0x6f, 0x9e, - 0x64, 0x64, 0x7a, 0x03, 0xa8, 0x20, 0x26, 0xf0, 0x46, 0x17, 0x0a, 0x45, 0xa8, 0x95, 0x67, 0x1a, - 0x98, 0x49, 0x28, 0x9d, 0xc1, 0x05, 0xc4, 0x4f, 0x5e, 0x40, 0x5e, 0x3f, 0x41, 0x97, 0x07, 0xdc, - 0x3f, 0xbe, 0xed, 0xf7, 0xb2, 0x4e, 0x08, 0x83, 0x2f, 0x83, 0x02, 0x8e, 0xbd, 0x0f, 0x82, 0xa2, - 0x26, 0x8b, 0x63, 0xa6, 0xd3, 0x2e, 0x17, 0xe2, 0x0f, 0x87, 0x00, 0x25, 0xe5, 0x60, 0x00, 0xc6, - 0x6d, 0x5f, 0x0e, 0xc5, 0xae, 0x0f, 0x2b, 0xc3, 0x0e, 0x29, 0x69, 0x2d, 0x8a, 0x9a, 0x5a, 0x08, - 0x50, 0x0f, 0xa8, 0xf2, 0xa3, 0x06, 0xfe, 0x76, 0x74, 0x7a, 0xe1, 0xff, 0x41, 0x86, 0xef, 0xf9, - 0xdd, 0x93, 0xf9, 0x72, 0x77, 0x5a, 0x6c, 0xee, 0xf9, 0xe4, 0xa0, 0x5d, 0x4e, 0x7a, 0x2e, 0x16, - 0x91, 0x14, 0xff, 0xdd, 0xc7, 0x75, 0x6f, 0x2a, 0xa5, 0x07, 0x4e, 0x25, 0x03, 0xa4, 0x5b, 0xb6, - 0x25, 0xbb, 0x25, 0x67, 0x5c, 0x55, 0x02, 0xe9, 0xbb, 0xb5, 0xe5, 0x83, 0x76, 0xf9, 0xf2, 0xa0, - 0x17, 0xba, 0x20, 0x13, 0xe8, 0x77, 0x6b, 0xcb, 0x48, 0x28, 0x57, 0x7e, 0xcd, 0xf4, 0x25, 0x4b, - 0xf4, 0x34, 0xbc, 0x01, 0x72, 0x96, 0xcd, 0x88, 0xc9, 0x6d, 0xea, 0x29, 0x47, 0x4b, 0x5d, 0xb2, - 0xcb, 0xdd, 0x8d, 0x83, 0xf8, 0x07, 0x8a, 0x14, 0xe0, 0x7d, 0x90, 0x69, 0x30, 0xea, 0xaa, 0x63, - 0xfe, 0x24, 0xc7, 0x8f, 0xa8, 0xa4, 0x28, 0x14, 0xb7, 0x18, 0x75, 0x91, 0x84, 0x82, 0x3b, 0x20, - 0xc5, 0xa9, 0x0c, 0xd5, 0x29, 0x00, 0x02, 0x05, 0x98, 0xda, 0xa4, 0x28, 0xc5, 0xa9, 0xa8, 0xc8, - 0x80, 0xb0, 0x5d, 0xdb, 0x24, 0xdd, 0x8b, 0xc1, 0x90, 0x15, 0xb9, 0x11, 0x5a, 0x8b, 0x2a, 0x52, - 0x2d, 0x04, 0xa8, 0x07, 0x04, 0xff, 0x1b, 0x9b, 0x8f, 0x6a, 0xe2, 0x45, 0x47, 0xd0, 0xa1, 0x19, - 0x79, 0x0f, 0x8c, 0xe2, 0x30, 0x7b, 0xa3, 0x32, 0x7b, 0x48, 0x1c, 0xc7, 0x4b, 0xdd, 0xb4, 0x2d, - 0x1f, 0xfb, 0x57, 0x2a, 0x62, 0xb6, 0x84, 0xbd, 0xde, 0x0f, 0x55, 0xba, 0x28, 0x8f, 0xd0, 0x0e, - 0x52, 0x08, 0xf0, 0x15, 0x50, 0x20, 0x1e, 0xde, 0x72, 0xc8, 0x1a, 0x6d, 0x36, 0x6d, 0xaf, 0x59, - 0x1c, 0x9b, 0xd3, 0xe6, 0xc7, 0x8d, 0xf3, 0x8a, 0x5e, 0x61, 0x25, 0xbe, 0x89, 0x92, 0xb2, 0x95, - 0xaf, 0x53, 0x00, 0x26, 0x22, 0xbe, 0xc1, 0x31, 0x0f, 0xc4, 0xa5, 0xb1, 0xe0, 0xc5, 0x97, 0xd5, - 0x64, 0x3c, 0x9d, 0x89, 0xdd, 0xa3, 0x9a, 0xdc, 0x4f, 0x32, 0x80, 0xef, 0x82, 0x3c, 0x67, 0xb8, - 0xd1, 0xb0, 0x4d, 0xc9, 0x51, 0x95, 0xf7, 0xf2, 0xb1, 0x19, 0xc9, 0x9f, 0xfc, 0xf4, 0x5e, 0x24, - 0x37, 0x63, 0xb6, 0xa2, 0x6b, 0x4d, 0x7c, 0x15, 0x25, 0xf0, 0x2a, 0x3f, 0x65, 0xc0, 0xf4, 0x3a, - 0xb5, 0x88, 0xfc, 0xda, 0x68, 0xb9, 0x2e, 0x66, 0x67, 0x71, 0x9b, 0xf8, 0x5c, 0x03, 0x53, 0xf1, - 0x40, 0xd8, 0xbd, 0x8b, 0x45, 0xfd, 0x04, 0x93, 0x11, 0x86, 0xe1, 0x82, 0x62, 0x32, 0xb5, 0x9e, - 0x04, 0x44, 0xfd, 0x0c, 0xe0, 0x37, 0x1a, 0xb8, 0x14, 0xa2, 0xdc, 0x74, 0x5a, 0x01, 0x27, 0xac, - 0x4f, 0x43, 0x3d, 0xef, 0x4e, 0x9e, 0xe2, 0xbf, 0x15, 0xc5, 0x4b, 0x4b, 0xcf, 0x41, 0x47, 0xcf, - 0xe5, 0x06, 0x1f, 0x69, 0xe0, 0x7c, 0x28, 0xd0, 0xcf, 0x3a, 0x73, 0x4a, 0xac, 0xff, 0xa9, 0x58, - 0x9f, 0x5f, 0x3a, 0x0a, 0x16, 0x1d, 0xcd, 0xa6, 0x82, 0x41, 0x3e, 0xfe, 0xb0, 0x3b, 0x8d, 0x47, - 0xe9, 0xc7, 0x1a, 0x18, 0x53, 0xd3, 0x0e, 0x5e, 0x8b, 0xdd, 0xb2, 0x43, 0x88, 0xe2, 0x8b, 0x6f, - 0xd8, 0x70, 0x5d, 0xdd, 0xef, 0x53, 0x2f, 0xa8, 0xfe, 0x16, 0xb7, 0x1d, 0x3d, 0xfc, 0x69, 0x5a, - 0xaf, 0x79, 0xfc, 0x0e, 0xdb, 0xe0, 0xcc, 0xf6, 0x9a, 0xc6, 0x78, 0xf2, 0x35, 0x60, 0x5c, 0x79, - 0xbc, 0x5f, 0x1a, 0x79, 0xb2, 0x5f, 0x1a, 0x79, 0xba, 0x5f, 0x1a, 0x79, 0xaf, 0x53, 0xd2, 0x1e, - 0x77, 0x4a, 0xda, 0x93, 0x4e, 0x49, 0x7b, 0xda, 0x29, 0x69, 0xdf, 0x77, 0x4a, 0xda, 0x27, 0xcf, - 0x4a, 0x23, 0x6f, 0x8c, 0xa9, 0x60, 0xff, 0x16, 0x00, 0x00, 0xff, 0xff, 0x6f, 0x82, 0x9f, 0xf9, - 0xad, 0x18, 0x00, 0x00, + // 1635 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x59, 0xbb, 0x6f, 0x1b, 0x47, + 0x1a, 0xd7, 0xf2, 0x21, 0x89, 0x23, 0x52, 0x8f, 0x91, 0x7d, 0xe6, 0xf9, 0x7c, 0xa4, 0xbc, 0x77, + 0x38, 0xa8, 0x38, 0x2f, 0x2d, 0x9d, 0xef, 0xce, 0x40, 0x9c, 0x42, 0xb4, 0x64, 0x81, 0x89, 0x4c, + 0x13, 0x23, 0xa9, 0x09, 0x02, 0x24, 0xab, 0xdd, 0x21, 0xb5, 0xd6, 0x72, 0x77, 0x3d, 0x3b, 0x2b, + 0x5b, 0x0e, 0x10, 0x24, 0x48, 0x95, 0x34, 0x79, 0x35, 0xa9, 0xd2, 0x19, 0xc9, 0xdf, 0x90, 0x2e, + 0x9d, 0x4b, 0x97, 0x6e, 0x42, 0x44, 0x34, 0x92, 0x36, 0x45, 0x80, 0x20, 0x10, 0x10, 0x20, 0x98, + 0xd9, 0xd9, 0x17, 0x29, 0xda, 0x0a, 0x48, 0x09, 0x01, 0x92, 0xca, 0xe2, 0x37, 0xdf, 0x7c, 0xbf, + 0xdf, 0xf7, 0x9c, 0x99, 0x35, 0xd8, 0x68, 0x19, 0x74, 0xd7, 0xdb, 0x51, 0x34, 0xbb, 0x5d, 0xd9, + 0x6f, 0xdf, 0x57, 0x09, 0xbe, 0x42, 0x55, 0xeb, 0xa1, 0x57, 0x51, 0x2d, 0x4a, 0xb0, 0x5a, 0x71, + 0xf6, 0x5a, 0x15, 0xd5, 0x31, 0xdc, 0x8a, 0x66, 0x5b, 0x94, 0xd8, 0xa6, 0x63, 0xaa, 0x16, 0xae, + 0xec, 0x2f, 0xed, 0x60, 0xaa, 0x2e, 0x57, 0x5a, 0xd8, 0xc2, 0x44, 0xa5, 0x58, 0x57, 0x1c, 0x62, + 0x53, 0x1b, 0xde, 0x88, 0xac, 0x29, 0xbe, 0xb5, 0x37, 0xb8, 0x35, 0xc5, 0xb7, 0xa6, 0x38, 0x7b, + 0x2d, 0x85, 0x59, 0x53, 0xe2, 0xd6, 0x14, 0x61, 0xed, 0xe2, 0x95, 0x18, 0x97, 0x96, 0xdd, 0xb2, + 0x2b, 0xdc, 0xe8, 0x8e, 0xd7, 0xe4, 0xbf, 0xf8, 0x0f, 0xfe, 0x97, 0x0f, 0x76, 0xf1, 0xd6, 0x49, + 0xa9, 0xbb, 0x54, 0xa5, 0x6e, 0x65, 0x7f, 0x49, 0x35, 0x9d, 0x5d, 0x75, 0xa9, 0x97, 0xf4, 0xc5, + 0x6b, 0x7b, 0xd7, 0x5d, 0xc5, 0xb0, 0x99, 0x6e, 0x5b, 0xd5, 0x76, 0x0d, 0x0b, 0x93, 0x83, 0x68, + 0x73, 0x1b, 0x53, 0xb5, 0xb2, 0xdf, 0xbf, 0xab, 0x32, 0x68, 0x17, 0xf1, 0x2c, 0x6a, 0xb4, 0x71, + 0xdf, 0x86, 0xff, 0xbd, 0x68, 0x83, 0xab, 0xed, 0xe2, 0xb6, 0xda, 0xb7, 0xef, 0x3f, 0x83, 0xf6, + 0x79, 0xd4, 0x30, 0x2b, 0x86, 0x45, 0x5d, 0x4a, 0x7a, 0x37, 0xc9, 0x3f, 0x49, 0x20, 0xbf, 0xa2, + 0xeb, 0x04, 0xbb, 0xee, 0x3a, 0xb1, 0x3d, 0x07, 0xbe, 0x09, 0x26, 0x99, 0x27, 0xba, 0x4a, 0xd5, + 0xa2, 0xb4, 0x20, 0x2d, 0x4e, 0x2d, 0x5f, 0x55, 0x7c, 0xc3, 0x4a, 0xdc, 0x70, 0x94, 0x21, 0xa6, + 0xad, 0xec, 0x2f, 0x29, 0x77, 0x76, 0xee, 0x62, 0x8d, 0xde, 0xc6, 0x54, 0xad, 0xc2, 0xc7, 0x9d, + 0xf2, 0x58, 0xb7, 0x53, 0x06, 0x91, 0x0c, 0x85, 0x56, 0xe1, 0x7b, 0x12, 0xc8, 0xb7, 0x18, 0xd6, + 0x6d, 0xdc, 0xde, 0xc1, 0xc4, 0x2d, 0xa6, 0x16, 0xd2, 0x8b, 0x53, 0xcb, 0x35, 0x65, 0x98, 0x9a, + 0x50, 0xd6, 0x23, 0x8b, 0xd5, 0x73, 0x02, 0x3f, 0x1f, 0x13, 0xba, 0x28, 0x01, 0x2a, 0x1f, 0x4a, + 0x60, 0x36, 0xee, 0xf8, 0x86, 0xe1, 0x52, 0xf8, 0x7a, 0x9f, 0xf3, 0xca, 0xc9, 0x9c, 0x67, 0xbb, + 0xb9, 0xeb, 0xb3, 0x02, 0x7a, 0x32, 0x90, 0xc4, 0x1c, 0xb7, 0x41, 0xd6, 0xa0, 0xb8, 0x1d, 0x38, + 0xfc, 0xca, 0x70, 0x0e, 0xc7, 0xc9, 0x57, 0x0b, 0x02, 0x36, 0x5b, 0x63, 0x00, 0xc8, 0xc7, 0x91, + 0x1f, 0xa5, 0xc1, 0x5c, 0x5c, 0xad, 0xa1, 0x52, 0x6d, 0xf7, 0x0c, 0x32, 0xfc, 0x89, 0x04, 0xe6, + 0x54, 0x5d, 0xc7, 0xfa, 0xfa, 0xa9, 0xa6, 0xf9, 0xaf, 0x82, 0x04, 0xf3, 0x31, 0x89, 0x85, 0xfa, + 0xe1, 0xe1, 0x67, 0x12, 0x98, 0x27, 0xb8, 0x6d, 0xef, 0xf7, 0xd0, 0x4a, 0x8f, 0x9a, 0xd6, 0xdf, + 0x04, 0xad, 0x79, 0xd4, 0x8f, 0x86, 0x8e, 0xa3, 0x20, 0xff, 0x2c, 0x81, 0xe9, 0x15, 0xc7, 0x31, + 0x0d, 0xac, 0x6f, 0xd9, 0x7f, 0xac, 0x36, 0xfc, 0x4e, 0x02, 0x30, 0xe9, 0xfa, 0x19, 0x34, 0xe2, + 0xbd, 0x64, 0x23, 0x6e, 0x0c, 0xd9, 0x88, 0x09, 0xfa, 0x03, 0x5a, 0xf1, 0x8b, 0x34, 0x98, 0x4f, + 0x2a, 0xfe, 0xd9, 0x8c, 0xbf, 0xcf, 0x66, 0x34, 0xc1, 0x85, 0xb5, 0x07, 0x14, 0x13, 0x4b, 0x35, + 0xd7, 0x2c, 0x6a, 0xd0, 0x03, 0x84, 0x9b, 0x98, 0x60, 0x4b, 0xc3, 0x70, 0x01, 0x64, 0x2c, 0xb5, + 0x8d, 0x79, 0xa2, 0x72, 0xd5, 0xbc, 0x30, 0x9d, 0xa9, 0xab, 0x6d, 0x8c, 0xf8, 0x0a, 0xac, 0x80, + 0x1c, 0xfb, 0xd7, 0x75, 0x54, 0x0d, 0x17, 0x53, 0x5c, 0x6d, 0x4e, 0xa8, 0xe5, 0xea, 0xc1, 0x02, + 0x8a, 0x74, 0xe4, 0xcf, 0xd3, 0x60, 0x2a, 0x06, 0x0f, 0x31, 0x48, 0x3b, 0xb6, 0x2e, 0x4a, 0x61, + 0xc8, 0x13, 0xa2, 0x61, 0xeb, 0x21, 0xf7, 0xea, 0x44, 0xb7, 0x53, 0x4e, 0x33, 0x09, 0xb3, 0x0f, + 0x3f, 0x96, 0xc0, 0x34, 0x4e, 0x78, 0xc9, 0xd9, 0x4e, 0x2d, 0x6f, 0x0f, 0x07, 0x39, 0x20, 0x72, + 0x55, 0xd8, 0xed, 0x94, 0xa7, 0x7b, 0x16, 0x7b, 0x08, 0xc0, 0x7f, 0x81, 0xb4, 0xe1, 0xf8, 0x25, + 0x90, 0xaf, 0x9e, 0x63, 0x74, 0x6b, 0x0d, 0xf7, 0xa8, 0x53, 0xce, 0xd5, 0x1a, 0xe2, 0x10, 0x43, + 0x4c, 0x01, 0x9a, 0x20, 0xeb, 0xd8, 0x84, 0xba, 0xc5, 0x0c, 0x2f, 0x96, 0xf5, 0xe1, 0x18, 0xb3, + 0xac, 0xe8, 0x0d, 0x9b, 0xd0, 0xa8, 0x71, 0xd9, 0x2f, 0x17, 0xf9, 0x20, 0xf2, 0x37, 0x12, 0x98, + 0xa8, 0x35, 0xaa, 0xa6, 0xad, 0xed, 0x41, 0x0c, 0x32, 0x9a, 0xa1, 0x13, 0x91, 0x9d, 0x9b, 0xc3, + 0x01, 0xd7, 0x1a, 0x75, 0x4c, 0xa3, 0x22, 0xba, 0x59, 0x5b, 0x45, 0x88, 0x9b, 0x87, 0x7b, 0x60, + 0x1c, 0x3f, 0xd0, 0xb0, 0x43, 0x45, 0x97, 0x8e, 0x04, 0x68, 0x5a, 0x00, 0x8d, 0xaf, 0x71, 0xd3, + 0x48, 0x40, 0xc8, 0x4d, 0x90, 0xe5, 0x0a, 0xf0, 0x1f, 0x20, 0x65, 0x38, 0xdc, 0xb5, 0x7c, 0x75, + 0xbe, 0xdb, 0x29, 0xa7, 0x6a, 0x8d, 0x64, 0xf0, 0x53, 0x86, 0x03, 0xaf, 0x83, 0xbc, 0x43, 0x70, + 0xd3, 0x78, 0xb0, 0x81, 0xad, 0x16, 0xdd, 0xe5, 0x45, 0x93, 0x8d, 0x06, 0x7d, 0x23, 0xb6, 0x86, + 0x12, 0x9a, 0xf2, 0xfb, 0x12, 0xc8, 0x85, 0xb1, 0x66, 0x9d, 0xc4, 0xc2, 0xcb, 0xe1, 0xb2, 0x51, + 0x10, 0xd8, 0x1a, 0xe2, 0x2b, 0x61, 0xaf, 0xa5, 0x06, 0xf6, 0xda, 0x75, 0x30, 0xc9, 0xef, 0xb0, + 0x9a, 0x6d, 0x16, 0xd3, 0x5c, 0xeb, 0x52, 0x30, 0xf3, 0x1b, 0x42, 0x7e, 0x14, 0xfb, 0x1b, 0x85, + 0xda, 0xf2, 0x07, 0x19, 0x50, 0xa8, 0x63, 0x7a, 0xdf, 0x26, 0x7b, 0x0d, 0xdb, 0x34, 0xb4, 0x83, + 0x33, 0x18, 0xc3, 0x14, 0x64, 0x89, 0x67, 0xe2, 0x60, 0xf2, 0xde, 0x19, 0xb2, 0x6a, 0xe3, 0xec, + 0x91, 0x67, 0xe2, 0xa8, 0x7a, 0xd9, 0x2f, 0x17, 0xf9, 0x60, 0xf0, 0x65, 0x30, 0xa3, 0x26, 0x4e, + 0x1d, 0xbf, 0xbf, 0x72, 0x3c, 0xc3, 0x33, 0xc9, 0x03, 0xc9, 0x45, 0xbd, 0xba, 0x70, 0x91, 0x85, + 0xd8, 0xb0, 0x09, 0x9b, 0x0f, 0x99, 0x05, 0x69, 0x51, 0xaa, 0xe6, 0xfd, 0xf0, 0xfa, 0x32, 0x14, + 0xae, 0xc2, 0x6b, 0x20, 0x4f, 0x0d, 0x4c, 0x82, 0x95, 0x62, 0x96, 0x27, 0x76, 0x96, 0x15, 0xc5, + 0x56, 0x4c, 0x8e, 0x12, 0x5a, 0xf0, 0x5d, 0x09, 0xe4, 0x5c, 0xdb, 0x23, 0x1a, 0x46, 0xb8, 0x59, + 0x1c, 0xe7, 0x81, 0xdf, 0x1a, 0x65, 0x64, 0xc2, 0x01, 0x54, 0x60, 0x13, 0x78, 0x33, 0x80, 0x42, + 0x11, 0xaa, 0xfc, 0x4c, 0x02, 0x73, 0x89, 0x4d, 0x67, 0x70, 0x01, 0x71, 0x92, 0x17, 0x90, 0x57, + 0x47, 0xe8, 0xf2, 0x80, 0xfb, 0xc7, 0x5b, 0xe0, 0x42, 0x42, 0xad, 0x6e, 0xeb, 0x78, 0x93, 0xaa, + 0xd4, 0x73, 0xe1, 0xbf, 0xc1, 0xa4, 0x65, 0xeb, 0xb8, 0x1e, 0x9d, 0x6c, 0x21, 0xf5, 0xba, 0x90, + 0xa3, 0x50, 0x03, 0x2e, 0x03, 0x20, 0xde, 0x90, 0x86, 0x6d, 0xf1, 0xee, 0x4c, 0x47, 0x95, 0xbf, + 0x1e, 0xae, 0xa0, 0x98, 0x96, 0xfc, 0x75, 0x6f, 0x88, 0x1b, 0x18, 0x13, 0xf8, 0x7f, 0x50, 0x50, + 0x63, 0x8f, 0x13, 0xb7, 0x28, 0xf1, 0xca, 0x9c, 0xeb, 0x76, 0xca, 0x85, 0xf8, 0xab, 0xc5, 0x45, + 0x49, 0x3d, 0xe8, 0x82, 0x49, 0xc3, 0xe1, 0x13, 0x39, 0x08, 0xe0, 0xda, 0xb0, 0x13, 0x92, 0x5b, + 0x8b, 0xfc, 0x16, 0x02, 0x17, 0x85, 0x40, 0xf2, 0xf7, 0x12, 0xf8, 0xcb, 0xf1, 0xb5, 0x05, 0xff, + 0x0b, 0x32, 0xf4, 0xc0, 0x09, 0x82, 0x77, 0x39, 0x18, 0x55, 0x5b, 0x07, 0x0e, 0x3e, 0xea, 0x94, + 0x93, 0x9e, 0x33, 0x21, 0xe2, 0xea, 0xbf, 0xf9, 0xae, 0x10, 0x8e, 0xc4, 0xf4, 0xc0, 0x91, 0x58, + 0x05, 0x69, 0xcf, 0xd0, 0x79, 0xab, 0xe6, 0xaa, 0x57, 0x85, 0x42, 0x7a, 0xbb, 0xb6, 0x7a, 0xd4, + 0x29, 0x5f, 0x1e, 0xf4, 0x79, 0x80, 0x91, 0x71, 0x95, 0xed, 0xda, 0x2a, 0x62, 0x9b, 0xe5, 0x5f, + 0x32, 0x3d, 0xc9, 0x62, 0x03, 0x05, 0xde, 0x00, 0x39, 0xdd, 0x20, 0x58, 0xe3, 0x59, 0xf7, 0x1d, + 0x2d, 0x05, 0x64, 0x57, 0x83, 0x85, 0xa3, 0xf8, 0x0f, 0x14, 0x6d, 0x80, 0xf7, 0x40, 0xa6, 0x49, + 0xec, 0xb6, 0xb8, 0x63, 0x8c, 0x72, 0xf6, 0xb1, 0x4a, 0x8a, 0x42, 0x71, 0x8b, 0xd8, 0x6d, 0xc4, + 0xa1, 0xe0, 0x1e, 0x48, 0x51, 0x9b, 0x87, 0xea, 0x14, 0x00, 0x81, 0x00, 0x4c, 0x6d, 0xd9, 0x28, + 0x45, 0x6d, 0x56, 0x91, 0x2e, 0x26, 0xfb, 0x86, 0x86, 0x83, 0x5b, 0xc9, 0x90, 0x15, 0xb9, 0xe9, + 0x5b, 0x8b, 0x2a, 0x52, 0x08, 0x5c, 0x14, 0x02, 0xb1, 0xbe, 0x75, 0x7a, 0xc6, 0x6d, 0x74, 0xfe, + 0xf5, 0x0d, 0xe8, 0xbb, 0x60, 0x5c, 0xf5, 0xb3, 0x37, 0xce, 0xb3, 0x87, 0xd8, 0x5d, 0x60, 0x25, + 0x48, 0xdb, 0xea, 0x89, 0x3f, 0x91, 0x61, 0xcd, 0x63, 0xf6, 0xc2, 0xaf, 0x64, 0x0a, 0x2b, 0x0f, + 0xdf, 0x0e, 0x12, 0x08, 0xf0, 0x25, 0x50, 0xc0, 0x96, 0xba, 0x63, 0xe2, 0x0d, 0xbb, 0xd5, 0x32, + 0xac, 0x56, 0x71, 0x62, 0x41, 0x5a, 0x9c, 0xac, 0x9e, 0x17, 0xf4, 0x0a, 0x6b, 0xf1, 0x45, 0x94, + 0xd4, 0x95, 0xbf, 0x4c, 0x01, 0x98, 0x88, 0x38, 0x1b, 0x53, 0x2e, 0xbb, 0xb1, 0x16, 0xac, 0xb8, + 0x58, 0x8c, 0xe5, 0xd3, 0x39, 0x2e, 0x42, 0xaa, 0xc9, 0xf5, 0x24, 0x03, 0xf8, 0x36, 0xc8, 0x53, + 0xa2, 0x36, 0x9b, 0x86, 0xc6, 0x39, 0x8a, 0xf2, 0x5e, 0x3d, 0x31, 0x23, 0xfe, 0xbd, 0x51, 0x09, + 0x23, 0xb9, 0x15, 0xb3, 0x15, 0xdd, 0xa9, 0xe2, 0x52, 0x94, 0xc0, 0x93, 0x7f, 0x94, 0xc0, 0x7c, + 0x5f, 0xa8, 0x3c, 0xf7, 0x0c, 0x6e, 0x33, 0x0f, 0x41, 0x96, 0x9d, 0x08, 0xc1, 0xfc, 0xdd, 0x1e, + 0x61, 0x12, 0xa2, 0x93, 0x29, 0x3a, 0xca, 0x98, 0xcc, 0x45, 0x3e, 0xa4, 0xfc, 0x43, 0x06, 0xcc, + 0x06, 0x4a, 0xee, 0xa6, 0xd7, 0x6e, 0xab, 0xe4, 0x2c, 0x2e, 0x70, 0x9f, 0x4a, 0x60, 0x26, 0x9e, + 0x7e, 0x23, 0xf4, 0xbe, 0x31, 0x42, 0xef, 0xfd, 0xe4, 0x5f, 0x10, 0x4c, 0x66, 0xea, 0x49, 0x40, + 0xd4, 0xcb, 0x00, 0x7e, 0x25, 0x81, 0x4b, 0x3e, 0xca, 0x4d, 0xd3, 0x73, 0x29, 0x26, 0x3d, 0x3b, + 0xc4, 0x8b, 0x7a, 0xf4, 0x14, 0xff, 0x29, 0x28, 0x5e, 0x5a, 0x79, 0x0e, 0x3a, 0x7a, 0x2e, 0x37, + 0xf8, 0x48, 0x02, 0xe7, 0x7d, 0x85, 0x5e, 0xd6, 0x99, 0x53, 0x62, 0xfd, 0x77, 0xc1, 0xfa, 0xfc, + 0xca, 0x71, 0xb0, 0xe8, 0x78, 0x36, 0xb2, 0x0a, 0xf2, 0xf1, 0xb7, 0xf4, 0x69, 0x7c, 0x07, 0xf8, + 0x50, 0x02, 0x13, 0x62, 0xc6, 0xc3, 0x6b, 0xb1, 0x87, 0x8d, 0x0f, 0x51, 0x7c, 0xf1, 0xa3, 0x06, + 0xd6, 0xc5, 0x93, 0x2a, 0xf5, 0x82, 0xea, 0xf7, 0xa8, 0x61, 0x2a, 0xfe, 0xff, 0x06, 0x28, 0x35, + 0x8b, 0xde, 0x21, 0x9b, 0x94, 0x18, 0x56, 0xab, 0x3a, 0x99, 0x7c, 0x80, 0x55, 0xaf, 0x3c, 0x3e, + 0x2c, 0x8d, 0x3d, 0x39, 0x2c, 0x8d, 0x3d, 0x3d, 0x2c, 0x8d, 0xbd, 0xd3, 0x2d, 0x49, 0x8f, 0xbb, + 0x25, 0xe9, 0x49, 0xb7, 0x24, 0x3d, 0xed, 0x96, 0xa4, 0x6f, 0xbb, 0x25, 0xe9, 0xa3, 0x67, 0xa5, + 0xb1, 0xd7, 0x26, 0x44, 0xb0, 0x7f, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x95, 0xb9, 0x0c, 0x82, 0x20, + 0x1a, 0x00, 0x00, } func (m *AddressGroup) Marshal() (dAtA []byte, err error) { @@ -1389,6 +1452,37 @@ func (m *NetworkPolicyList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NetworkPolicyNodeStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NetworkPolicyNodeStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NetworkPolicyNodeStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i = encodeVarintGenerated(dAtA, i, uint64(m.Generation)) + i-- + dAtA[i] = 0x10 + i -= len(m.NodeName) + copy(dAtA[i:], m.NodeName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.NodeName))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *NetworkPolicyPeer) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1601,6 +1695,53 @@ func (m *NetworkPolicyStats) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *NetworkPolicyStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NetworkPolicyStatus) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NetworkPolicyStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Nodes) > 0 { + for iNdEx := len(m.Nodes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Nodes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ObjectMeta.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *NodeStatsSummary) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2013,6 +2154,18 @@ func (m *NetworkPolicyList) Size() (n int) { return n } +func (m *NetworkPolicyNodeStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.NodeName) + n += 1 + l + sovGenerated(uint64(l)) + n += 1 + sovGenerated(uint64(m.Generation)) + return n +} + func (m *NetworkPolicyPeer) Size() (n int) { if m == nil { return 0 @@ -2091,6 +2244,23 @@ func (m *NetworkPolicyStats) Size() (n int) { return n } +func (m *NetworkPolicyStatus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ObjectMeta.Size() + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Nodes) > 0 { + for _, e := range m.Nodes { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *NodeStatsSummary) Size() (n int) { if m == nil { return 0 @@ -2368,6 +2538,17 @@ func (this *NetworkPolicyList) String() string { }, "") return s } +func (this *NetworkPolicyNodeStatus) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NetworkPolicyNodeStatus{`, + `NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`, + `Generation:` + fmt.Sprintf("%v", this.Generation) + `,`, + `}`, + }, "") + return s +} func (this *NetworkPolicyPeer) String() string { if this == nil { return "nil" @@ -2429,6 +2610,22 @@ func (this *NetworkPolicyStats) String() string { }, "") return s } +func (this *NetworkPolicyStatus) String() string { + if this == nil { + return "nil" + } + repeatedStringForNodes := "[]NetworkPolicyNodeStatus{" + for _, f := range this.Nodes { + repeatedStringForNodes += strings.Replace(strings.Replace(f.String(), "NetworkPolicyNodeStatus", "NetworkPolicyNodeStatus", 1), `&`, ``, 1) + "," + } + repeatedStringForNodes += "}" + s := strings.Join([]string{`&NetworkPolicyStatus{`, + `ObjectMeta:` + strings.Replace(strings.Replace(fmt.Sprintf("%v", this.ObjectMeta), "ObjectMeta", "v1.ObjectMeta", 1), `&`, ``, 1) + `,`, + `Nodes:` + repeatedStringForNodes + `,`, + `}`, + }, "") + return s +} func (this *NodeStatsSummary) String() string { if this == nil { return "nil" @@ -4285,6 +4482,110 @@ func (m *NetworkPolicyList) Unmarshal(dAtA []byte) error { } return nil } +func (m *NetworkPolicyNodeStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyNodeStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyNodeStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Generation", wireType) + } + m.Generation = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Generation |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NetworkPolicyPeer) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -4961,6 +5262,126 @@ func (m *NetworkPolicyStats) Unmarshal(dAtA []byte) error { } return nil } +func (m *NetworkPolicyStatus) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkPolicyStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkPolicyStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ObjectMeta", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ObjectMeta.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Nodes = append(m.Nodes, NetworkPolicyNodeStatus{}) + if err := m.Nodes[len(m.Nodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NodeStatsSummary) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apis/controlplane/v1beta2/generated.proto b/pkg/apis/controlplane/v1beta2/generated.proto index 1130631797e..bf39ed231c5 100644 --- a/pkg/apis/controlplane/v1beta2/generated.proto +++ b/pkg/apis/controlplane/v1beta2/generated.proto @@ -176,6 +176,15 @@ message NetworkPolicyList { repeated NetworkPolicy items = 2; } +// NetworkPolicyNodeStatus is the status of a NetworkPolicy on a Node. +message NetworkPolicyNodeStatus { + // The name of the Node that produces the status. + optional string nodeName = 1; + + // The generation realized by the Node. + optional int64 generation = 2; +} + // NetworkPolicyPeer describes a peer of NetworkPolicyRules. // It could be a list of names of AddressGroups and/or a list of IPBlock. message NetworkPolicyPeer { @@ -238,6 +247,15 @@ message NetworkPolicyStats { optional github.com.vmware_tanzu.antrea.pkg.apis.stats.v1alpha1.TrafficStats trafficStats = 2; } +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// NetworkPolicyStatus is the status of a NetworkPolicy. +message NetworkPolicyStatus { + optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; + + // Nodes contains statuses produced on a list of Nodes. + repeated NetworkPolicyNodeStatus nodes = 2; +} + // NodeStatsSummary contains stats produced on a Node. It's used by the antrea-agents to report stats to the antrea-controller. message NodeStatsSummary { optional k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1; diff --git a/pkg/apis/controlplane/v1beta2/register.go b/pkg/apis/controlplane/v1beta2/register.go index 93048240814..01749aba51f 100644 --- a/pkg/apis/controlplane/v1beta2/register.go +++ b/pkg/apis/controlplane/v1beta2/register.go @@ -63,6 +63,7 @@ func addKnownTypes(scheme *runtime.Scheme) error { &AddressGroupList{}, &NetworkPolicy{}, &NetworkPolicyList{}, + &NetworkPolicyStatus{}, &NodeStatsSummary{}, ) diff --git a/pkg/apis/controlplane/v1beta2/types.go b/pkg/apis/controlplane/v1beta2/types.go index 54812b812ab..c81a0ba1aaf 100644 --- a/pkg/apis/controlplane/v1beta2/types.go +++ b/pkg/apis/controlplane/v1beta2/types.go @@ -276,3 +276,20 @@ type NetworkPolicyStats struct { // The stats of the NetworkPolicy. TrafficStats statsv1alpha1.TrafficStats `json:"trafficStats,omitempty" protobuf:"bytes,2,opt,name=trafficStats"` } + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// NetworkPolicyStatus is the status of a NetworkPolicy. +type NetworkPolicyStatus struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` + // Nodes contains statuses produced on a list of Nodes. + Nodes []NetworkPolicyNodeStatus `json:"nodes,omitempty" protobuf:"bytes,2,rep,name=nodes"` +} + +// NetworkPolicyNodeStatus is the status of a NetworkPolicy on a Node. +type NetworkPolicyNodeStatus struct { + // The name of the Node that produces the status. + NodeName string `json:"nodeName,omitempty" protobuf:"bytes,1,opt,name=nodeName"` + // The generation realized by the Node. + Generation int64 `json:"generation,omitempty" protobuf:"varint,2,opt,name=generation"` +} diff --git a/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go b/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go index 22cf789c062..953a041c0fe 100644 --- a/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go +++ b/pkg/apis/controlplane/v1beta2/zz_generated.conversion.go @@ -166,6 +166,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*NetworkPolicyNodeStatus)(nil), (*controlplane.NetworkPolicyNodeStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_NetworkPolicyNodeStatus_To_controlplane_NetworkPolicyNodeStatus(a.(*NetworkPolicyNodeStatus), b.(*controlplane.NetworkPolicyNodeStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*controlplane.NetworkPolicyNodeStatus)(nil), (*NetworkPolicyNodeStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_controlplane_NetworkPolicyNodeStatus_To_v1beta2_NetworkPolicyNodeStatus(a.(*controlplane.NetworkPolicyNodeStatus), b.(*NetworkPolicyNodeStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*NetworkPolicyPeer)(nil), (*controlplane.NetworkPolicyPeer)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_NetworkPolicyPeer_To_controlplane_NetworkPolicyPeer(a.(*NetworkPolicyPeer), b.(*controlplane.NetworkPolicyPeer), scope) }); err != nil { @@ -206,6 +216,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*NetworkPolicyStatus)(nil), (*controlplane.NetworkPolicyStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta2_NetworkPolicyStatus_To_controlplane_NetworkPolicyStatus(a.(*NetworkPolicyStatus), b.(*controlplane.NetworkPolicyStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*controlplane.NetworkPolicyStatus)(nil), (*NetworkPolicyStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_controlplane_NetworkPolicyStatus_To_v1beta2_NetworkPolicyStatus(a.(*controlplane.NetworkPolicyStatus), b.(*NetworkPolicyStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*NodeStatsSummary)(nil), (*controlplane.NodeStatsSummary)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta2_NodeStatsSummary_To_controlplane_NodeStatsSummary(a.(*NodeStatsSummary), b.(*controlplane.NodeStatsSummary), scope) }); err != nil { @@ -547,6 +567,28 @@ func Convert_controlplane_NetworkPolicyList_To_v1beta2_NetworkPolicyList(in *con return autoConvert_controlplane_NetworkPolicyList_To_v1beta2_NetworkPolicyList(in, out, s) } +func autoConvert_v1beta2_NetworkPolicyNodeStatus_To_controlplane_NetworkPolicyNodeStatus(in *NetworkPolicyNodeStatus, out *controlplane.NetworkPolicyNodeStatus, s conversion.Scope) error { + out.NodeName = in.NodeName + out.Generation = in.Generation + return nil +} + +// Convert_v1beta2_NetworkPolicyNodeStatus_To_controlplane_NetworkPolicyNodeStatus is an autogenerated conversion function. +func Convert_v1beta2_NetworkPolicyNodeStatus_To_controlplane_NetworkPolicyNodeStatus(in *NetworkPolicyNodeStatus, out *controlplane.NetworkPolicyNodeStatus, s conversion.Scope) error { + return autoConvert_v1beta2_NetworkPolicyNodeStatus_To_controlplane_NetworkPolicyNodeStatus(in, out, s) +} + +func autoConvert_controlplane_NetworkPolicyNodeStatus_To_v1beta2_NetworkPolicyNodeStatus(in *controlplane.NetworkPolicyNodeStatus, out *NetworkPolicyNodeStatus, s conversion.Scope) error { + out.NodeName = in.NodeName + out.Generation = in.Generation + return nil +} + +// Convert_controlplane_NetworkPolicyNodeStatus_To_v1beta2_NetworkPolicyNodeStatus is an autogenerated conversion function. +func Convert_controlplane_NetworkPolicyNodeStatus_To_v1beta2_NetworkPolicyNodeStatus(in *controlplane.NetworkPolicyNodeStatus, out *NetworkPolicyNodeStatus, s conversion.Scope) error { + return autoConvert_controlplane_NetworkPolicyNodeStatus_To_v1beta2_NetworkPolicyNodeStatus(in, out, s) +} + func autoConvert_v1beta2_NetworkPolicyPeer_To_controlplane_NetworkPolicyPeer(in *NetworkPolicyPeer, out *controlplane.NetworkPolicyPeer, s conversion.Scope) error { out.AddressGroups = *(*[]string)(unsafe.Pointer(&in.AddressGroups)) out.IPBlocks = *(*[]controlplane.IPBlock)(unsafe.Pointer(&in.IPBlocks)) @@ -661,6 +703,28 @@ func Convert_controlplane_NetworkPolicyStats_To_v1beta2_NetworkPolicyStats(in *c return autoConvert_controlplane_NetworkPolicyStats_To_v1beta2_NetworkPolicyStats(in, out, s) } +func autoConvert_v1beta2_NetworkPolicyStatus_To_controlplane_NetworkPolicyStatus(in *NetworkPolicyStatus, out *controlplane.NetworkPolicyStatus, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.Nodes = *(*[]controlplane.NetworkPolicyNodeStatus)(unsafe.Pointer(&in.Nodes)) + return nil +} + +// Convert_v1beta2_NetworkPolicyStatus_To_controlplane_NetworkPolicyStatus is an autogenerated conversion function. +func Convert_v1beta2_NetworkPolicyStatus_To_controlplane_NetworkPolicyStatus(in *NetworkPolicyStatus, out *controlplane.NetworkPolicyStatus, s conversion.Scope) error { + return autoConvert_v1beta2_NetworkPolicyStatus_To_controlplane_NetworkPolicyStatus(in, out, s) +} + +func autoConvert_controlplane_NetworkPolicyStatus_To_v1beta2_NetworkPolicyStatus(in *controlplane.NetworkPolicyStatus, out *NetworkPolicyStatus, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + out.Nodes = *(*[]NetworkPolicyNodeStatus)(unsafe.Pointer(&in.Nodes)) + return nil +} + +// Convert_controlplane_NetworkPolicyStatus_To_v1beta2_NetworkPolicyStatus is an autogenerated conversion function. +func Convert_controlplane_NetworkPolicyStatus_To_v1beta2_NetworkPolicyStatus(in *controlplane.NetworkPolicyStatus, out *NetworkPolicyStatus, s conversion.Scope) error { + return autoConvert_controlplane_NetworkPolicyStatus_To_v1beta2_NetworkPolicyStatus(in, out, s) +} + func autoConvert_v1beta2_NodeStatsSummary_To_controlplane_NodeStatsSummary(in *NodeStatsSummary, out *controlplane.NodeStatsSummary, s conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.NetworkPolicies = *(*[]controlplane.NetworkPolicyStats)(unsafe.Pointer(&in.NetworkPolicies)) diff --git a/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go b/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go index ba9f92c95b8..1b277e840bb 100644 --- a/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go +++ b/pkg/apis/controlplane/v1beta2/zz_generated.deepcopy.go @@ -461,6 +461,22 @@ func (in *NetworkPolicyList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkPolicyNodeStatus) DeepCopyInto(out *NetworkPolicyNodeStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyNodeStatus. +func (in *NetworkPolicyNodeStatus) DeepCopy() *NetworkPolicyNodeStatus { + if in == nil { + return nil + } + out := new(NetworkPolicyNodeStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NetworkPolicyPeer) DeepCopyInto(out *NetworkPolicyPeer) { *out = *in @@ -553,6 +569,37 @@ func (in *NetworkPolicyStats) DeepCopy() *NetworkPolicyStats { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkPolicyStatus) DeepCopyInto(out *NetworkPolicyStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Nodes != nil { + in, out := &in.Nodes, &out.Nodes + *out = make([]NetworkPolicyNodeStatus, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyStatus. +func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus { + if in == nil { + return nil + } + out := new(NetworkPolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NetworkPolicyStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeStatsSummary) DeepCopyInto(out *NodeStatsSummary) { *out = *in diff --git a/pkg/apis/controlplane/zz_generated.deepcopy.go b/pkg/apis/controlplane/zz_generated.deepcopy.go index 97dbfe14779..726ce8109f6 100644 --- a/pkg/apis/controlplane/zz_generated.deepcopy.go +++ b/pkg/apis/controlplane/zz_generated.deepcopy.go @@ -461,6 +461,22 @@ func (in *NetworkPolicyList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkPolicyNodeStatus) DeepCopyInto(out *NetworkPolicyNodeStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyNodeStatus. +func (in *NetworkPolicyNodeStatus) DeepCopy() *NetworkPolicyNodeStatus { + if in == nil { + return nil + } + out := new(NetworkPolicyNodeStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NetworkPolicyPeer) DeepCopyInto(out *NetworkPolicyPeer) { *out = *in @@ -553,6 +569,37 @@ func (in *NetworkPolicyStats) DeepCopy() *NetworkPolicyStats { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkPolicyStatus) DeepCopyInto(out *NetworkPolicyStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Nodes != nil { + in, out := &in.Nodes, &out.Nodes + *out = make([]NetworkPolicyNodeStatus, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyStatus. +func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus { + if in == nil { + return nil + } + out := new(NetworkPolicyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NetworkPolicyStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NodeStatsSummary) DeepCopyInto(out *NodeStatsSummary) { *out = *in diff --git a/pkg/apis/security/v1alpha1/types.go b/pkg/apis/security/v1alpha1/types.go index 08b2cf8bc93..ab31cbeb6fc 100644 --- a/pkg/apis/security/v1alpha1/types.go +++ b/pkg/apis/security/v1alpha1/types.go @@ -21,7 +21,6 @@ import ( ) // +genclient -// +genclient:noStatus // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type NetworkPolicy struct { @@ -31,6 +30,8 @@ type NetworkPolicy struct { // Specification of the desired behavior of NetworkPolicy. Spec NetworkPolicySpec `json:"spec"` + // Most recently observed status of the NetworkPolicy. + Status NetworkPolicyStatus `json:"status"` } // NetworkPolicySpec defines the desired state for NetworkPolicy. @@ -58,6 +59,31 @@ type NetworkPolicySpec struct { Egress []Rule `json:"egress"` } +// NetworkPolicyPhase defines the phase in which a NetworkPolicy is. +type NetworkPolicyPhase string + +// These are the valid values for NetworkPolicyPhase. +const ( + // NetworkPolicyPending means the NetworkPolicy has been accepted by the system, but it has not been processed by Antrea. + NetworkPolicyPending NetworkPolicyPhase = "Pending" + // NetworkPolicyRealizing means the NetworkPolicy has been observed by Antrea and is being realized. + NetworkPolicyRealizing NetworkPolicyPhase = "Realizing" + // NetworkPolicyRealized means the NetworkPolicy has been enforced to all Pods on all Nodes it applies to. + NetworkPolicyRealized NetworkPolicyPhase = "Realized" +) + +// NetworkPolicyStatus represents information about the status of a NetworkPolicy. +type NetworkPolicyStatus struct { + // The phase of a NetworkPolicy is a simple, high-level summary of the NetworkPolicy's status. + Phase NetworkPolicyPhase `json:"phase"` + // The generation observed by Antrea. + ObservedGeneration int64 `json:"observedGeneration"` + // The number of nodes that have realized the NetworkPolicy. + CurrentNodesRealized int32 `json:"currentNodesRealized"` + // The total number of nodes that should realize the NetworkPolicy. + DesiredNodesRealized int32 `json:"desiredNodesRealized"` +} + // Rule describes the traffic allowed to/from the workloads selected by // Spec.AppliedTo. Based on the action specified in the rule, traffic is either // allowed or denied which exactly match the specified ports and protocol. @@ -158,7 +184,6 @@ type NetworkPolicyList struct { // +genclient // +genclient:nonNamespaced -// +genclient:noStatus // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type ClusterNetworkPolicy struct { @@ -168,6 +193,8 @@ type ClusterNetworkPolicy struct { // Specification of the desired behavior of ClusterNetworkPolicy. Spec ClusterNetworkPolicySpec `json:"spec"` + // Most recently observed status of the NetworkPolicy. + Status NetworkPolicyStatus `json:"status"` } // ClusterNetworkPolicySpec defines the desired state for ClusterNetworkPolicy. diff --git a/pkg/apis/security/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/security/v1alpha1/zz_generated.deepcopy.go index 215177e116e..fffbdf1fba9 100644 --- a/pkg/apis/security/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/security/v1alpha1/zz_generated.deepcopy.go @@ -31,6 +31,7 @@ func (in *ClusterNetworkPolicy) DeepCopyInto(out *ClusterNetworkPolicy) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status return } @@ -144,6 +145,7 @@ func (in *NetworkPolicy) DeepCopyInto(out *NetworkPolicy) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status return } @@ -297,6 +299,22 @@ func (in *NetworkPolicySpec) DeepCopy() *NetworkPolicySpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkPolicyStatus) DeepCopyInto(out *NetworkPolicyStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkPolicyStatus. +func (in *NetworkPolicyStatus) DeepCopy() *NetworkPolicyStatus { + if in == nil { + return nil + } + out := new(NetworkPolicyStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Rule) DeepCopyInto(out *Rule) { *out = *in diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 779af169f45..451af6de9df 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -77,14 +77,15 @@ func init() { // ExtraConfig holds custom apiserver config. type ExtraConfig struct { - addressGroupStore storage.Interface - appliedToGroupStore storage.Interface - networkPolicyStore storage.Interface - controllerQuerier querier.ControllerQuerier - endpointQuerier controllernetworkpolicy.EndpointQuerier - networkPolicyController *controllernetworkpolicy.NetworkPolicyController - caCertController *certificate.CACertController - statsAggregator *stats.Aggregator + addressGroupStore storage.Interface + appliedToGroupStore storage.Interface + networkPolicyStore storage.Interface + controllerQuerier querier.ControllerQuerier + endpointQuerier controllernetworkpolicy.EndpointQuerier + networkPolicyController *controllernetworkpolicy.NetworkPolicyController + caCertController *certificate.CACertController + statsAggregator *stats.Aggregator + networkPolicyStatusController *controllernetworkpolicy.StatusController } // Config defines the config for Antrea apiserver. @@ -120,19 +121,21 @@ func NewConfig( caCertController *certificate.CACertController, statsAggregator *stats.Aggregator, controllerQuerier querier.ControllerQuerier, + networkPolicyStatusController *controllernetworkpolicy.StatusController, endpointQuerier controllernetworkpolicy.EndpointQuerier, npController *controllernetworkpolicy.NetworkPolicyController) *Config { return &Config{ genericConfig: genericConfig, extraConfig: ExtraConfig{ - addressGroupStore: addressGroupStore, - appliedToGroupStore: appliedToGroupStore, - networkPolicyStore: networkPolicyStore, - caCertController: caCertController, - statsAggregator: statsAggregator, - controllerQuerier: controllerQuerier, - endpointQuerier: endpointQuerier, - networkPolicyController: npController, + addressGroupStore: addressGroupStore, + appliedToGroupStore: appliedToGroupStore, + networkPolicyStore: networkPolicyStore, + caCertController: caCertController, + statsAggregator: statsAggregator, + controllerQuerier: controllerQuerier, + endpointQuerier: endpointQuerier, + networkPolicyController: npController, + networkPolicyStatusController: networkPolicyStatusController, }, } } @@ -145,14 +148,22 @@ func installAPIGroup(s *APIServer, c completedConfig) error { addressGroupStorage := addressgroup.NewREST(c.extraConfig.addressGroupStore) appliedToGroupStorage := appliedtogroup.NewREST(c.extraConfig.appliedToGroupStore) networkPolicyStorage := networkpolicy.NewREST(c.extraConfig.networkPolicyStore) + networkPolicyStatusStorage := networkpolicy.NewStatusREST(c.extraConfig.networkPolicyStatusController) + nodeStatsSummaryStorage := nodestatssummary.NewREST(c.extraConfig.statsAggregator) cpGroup := genericapiserver.NewDefaultAPIGroupInfo(controlplane.GroupName, Scheme, metav1.ParameterCodec, Codecs) - cpStorage := map[string]rest.Storage{} - cpStorage["addressgroups"] = addressGroupStorage - cpStorage["appliedtogroups"] = appliedToGroupStorage - cpStorage["networkpolicies"] = networkPolicyStorage - cpStorage["nodestatssummaries"] = nodestatssummary.NewREST(c.extraConfig.statsAggregator) - cpGroup.VersionedResourcesStorageMap["v1beta1"] = cpStorage - cpGroup.VersionedResourcesStorageMap["v1beta2"] = cpStorage + cpv1beta1Storage := map[string]rest.Storage{} + cpv1beta1Storage["addressgroups"] = addressGroupStorage + cpv1beta1Storage["appliedtogroups"] = appliedToGroupStorage + cpv1beta1Storage["networkpolicies"] = networkPolicyStorage + cpv1beta1Storage["nodestatssummaries"] = nodeStatsSummaryStorage + cpGroup.VersionedResourcesStorageMap["v1beta1"] = cpv1beta1Storage + cpv1beta2Storage := map[string]rest.Storage{} + cpv1beta2Storage["addressgroups"] = addressGroupStorage + cpv1beta2Storage["appliedtogroups"] = appliedToGroupStorage + cpv1beta2Storage["networkpolicies"] = networkPolicyStorage + cpv1beta2Storage["networkpolicies/status"] = networkPolicyStatusStorage + cpv1beta2Storage["nodestatssummaries"] = nodeStatsSummaryStorage + cpGroup.VersionedResourcesStorageMap["v1beta2"] = cpv1beta2Storage // TODO: networkingGroup is the legacy group of controlplane NetworkPolicy APIs. To allow live upgrades from up to // two minor versions, the APIs must be kept for two minor releases before it can be deleted. diff --git a/pkg/apiserver/openapi/zz_generated.openapi.go b/pkg/apiserver/openapi/zz_generated.openapi.go index 65b919f0b35..28fe82b7c8a 100644 --- a/pkg/apiserver/openapi/zz_generated.openapi.go +++ b/pkg/apiserver/openapi/zz_generated.openapi.go @@ -72,10 +72,12 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NamedPort": schema_pkg_apis_controlplane_v1beta2_NamedPort(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicy": schema_pkg_apis_controlplane_v1beta2_NetworkPolicy(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyList": schema_pkg_apis_controlplane_v1beta2_NetworkPolicyList(ref), + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyNodeStatus": schema_pkg_apis_controlplane_v1beta2_NetworkPolicyNodeStatus(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyPeer": schema_pkg_apis_controlplane_v1beta2_NetworkPolicyPeer(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyReference": schema_pkg_apis_controlplane_v1beta2_NetworkPolicyReference(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyRule": schema_pkg_apis_controlplane_v1beta2_NetworkPolicyRule(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyStats": schema_pkg_apis_controlplane_v1beta2_NetworkPolicyStats(ref), + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyStatus": schema_pkg_apis_controlplane_v1beta2_NetworkPolicyStatus(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NodeStatsSummary": schema_pkg_apis_controlplane_v1beta2_NodeStatsSummary(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.PodReference": schema_pkg_apis_controlplane_v1beta2_PodReference(ref), "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.Service": schema_pkg_apis_controlplane_v1beta2_Service(ref), @@ -2447,6 +2449,33 @@ func schema_pkg_apis_controlplane_v1beta2_NetworkPolicyList(ref common.Reference } } +func schema_pkg_apis_controlplane_v1beta2_NetworkPolicyNodeStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NetworkPolicyNodeStatus is the status of a NetworkPolicy on a Node.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "nodeName": { + SchemaProps: spec.SchemaProps{ + Description: "The name of the Node that produces the status.", + Type: []string{"string"}, + Format: "", + }, + }, + "generation": { + SchemaProps: spec.SchemaProps{ + Description: "The generation realized by the Node.", + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + }, + }, + } +} + func schema_pkg_apis_controlplane_v1beta2_NetworkPolicyPeer(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2625,6 +2654,53 @@ func schema_pkg_apis_controlplane_v1beta2_NetworkPolicyStats(ref common.Referenc } } +func schema_pkg_apis_controlplane_v1beta2_NetworkPolicyStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "NetworkPolicyStatus is the status of a NetworkPolicy.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "nodes": { + SchemaProps: spec.SchemaProps{ + Description: "Nodes contains statuses produced on a list of Nodes.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyNodeStatus"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2.NetworkPolicyNodeStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + func schema_pkg_apis_controlplane_v1beta2_NodeStatsSummary(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apiserver/registry/networkpolicy/networkpolicy/subresources.go b/pkg/apiserver/registry/networkpolicy/networkpolicy/subresources.go new file mode 100644 index 00000000000..417d0ecd940 --- /dev/null +++ b/pkg/apiserver/registry/networkpolicy/networkpolicy/subresources.go @@ -0,0 +1,63 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package networkpolicy + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/rest" + + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane" +) + +// StatusREST implements the REST endpoint for getting NetworkPolicy's status. +type StatusREST struct { + collector statusCollector +} + +// NewStatusREST returns a REST object that will work against API services. +func NewStatusREST(collector statusCollector) *StatusREST { + return &StatusREST{collector} +} + +// statusCollector is the interface required by the handler. +type statusCollector interface { + UpdateStatus(status *controlplane.NetworkPolicyStatus) error +} + +var _ rest.NamedCreater = &StatusREST{} + +func (s StatusREST) New() runtime.Object { + return &controlplane.NetworkPolicyStatus{} +} + +func (s StatusREST) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { + status, ok := obj.(*controlplane.NetworkPolicyStatus) + if !ok { + return nil, errors.NewBadRequest(fmt.Sprintf("not a NetworkPolicyStatus object: %T", obj)) + } + if name != status.Name { + return nil, errors.NewBadRequest("name in URL does not match name in NetworkPolicyStatus object") + } + err := s.collector.UpdateStatus(status) + if err != nil { + return nil, err + } + return &metav1.Status{Status: metav1.StatusSuccess}, nil +} diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_networkpolicy_expansion.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_networkpolicy_expansion.go new file mode 100644 index 00000000000..a111b497f29 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/fake/fake_networkpolicy_expansion.go @@ -0,0 +1,25 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package fake + +import ( + "context" + + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2" +) + +func (c *FakeNetworkPolicies) UpdateStatus(ctx context.Context, name string, status *v1beta2.NetworkPolicyStatus) error { + return nil +} diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go index d3820c6fab2..cf20e5b9841 100644 --- a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/generated_expansion.go @@ -20,6 +20,4 @@ type AddressGroupExpansion interface{} type AppliedToGroupExpansion interface{} -type NetworkPolicyExpansion interface{} - type NodeStatsSummaryExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/controlplane/v1beta2/networkpolicy_expansion.go b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/networkpolicy_expansion.go new file mode 100644 index 00000000000..c86d4185c5a --- /dev/null +++ b/pkg/client/clientset/versioned/typed/controlplane/v1beta2/networkpolicy_expansion.go @@ -0,0 +1,30 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1beta2 + +import ( + "context" + + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane/v1beta2" +) + +// The NetworkPolicyExpansion interface allows manually adding extra methods to the NetworkPolicyInterface. +type NetworkPolicyExpansion interface { + UpdateStatus(ctx context.Context, name string, status *v1beta2.NetworkPolicyStatus) error +} + +func (c *networkPolicies) UpdateStatus(ctx context.Context, name string, status *v1beta2.NetworkPolicyStatus) error { + return c.client.Post().Name(name).Resource("networkpolicies").SubResource("status").Body(status).Do(ctx).Error() +} diff --git a/pkg/client/clientset/versioned/typed/security/v1alpha1/clusternetworkpolicy.go b/pkg/client/clientset/versioned/typed/security/v1alpha1/clusternetworkpolicy.go index 77dc53e3cb4..27dc4e59524 100644 --- a/pkg/client/clientset/versioned/typed/security/v1alpha1/clusternetworkpolicy.go +++ b/pkg/client/clientset/versioned/typed/security/v1alpha1/clusternetworkpolicy.go @@ -38,6 +38,7 @@ type ClusterNetworkPoliciesGetter interface { type ClusterNetworkPolicyInterface interface { Create(ctx context.Context, clusterNetworkPolicy *v1alpha1.ClusterNetworkPolicy, opts v1.CreateOptions) (*v1alpha1.ClusterNetworkPolicy, error) Update(ctx context.Context, clusterNetworkPolicy *v1alpha1.ClusterNetworkPolicy, opts v1.UpdateOptions) (*v1alpha1.ClusterNetworkPolicy, error) + UpdateStatus(ctx context.Context, clusterNetworkPolicy *v1alpha1.ClusterNetworkPolicy, opts v1.UpdateOptions) (*v1alpha1.ClusterNetworkPolicy, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ClusterNetworkPolicy, error) @@ -126,6 +127,21 @@ func (c *clusterNetworkPolicies) Update(ctx context.Context, clusterNetworkPolic return } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *clusterNetworkPolicies) UpdateStatus(ctx context.Context, clusterNetworkPolicy *v1alpha1.ClusterNetworkPolicy, opts v1.UpdateOptions) (result *v1alpha1.ClusterNetworkPolicy, err error) { + result = &v1alpha1.ClusterNetworkPolicy{} + err = c.client.Put(). + Resource("clusternetworkpolicies"). + Name(clusterNetworkPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(clusterNetworkPolicy). + Do(ctx). + Into(result) + return +} + // Delete takes name of the clusterNetworkPolicy and deletes it. Returns an error if one occurs. func (c *clusterNetworkPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { return c.client.Delete(). diff --git a/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_clusternetworkpolicy.go b/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_clusternetworkpolicy.go index cc3ec8190aa..8f647325b12 100644 --- a/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_clusternetworkpolicy.go +++ b/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_clusternetworkpolicy.go @@ -94,6 +94,17 @@ func (c *FakeClusterNetworkPolicies) Update(ctx context.Context, clusterNetworkP return obj.(*v1alpha1.ClusterNetworkPolicy), err } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeClusterNetworkPolicies) UpdateStatus(ctx context.Context, clusterNetworkPolicy *v1alpha1.ClusterNetworkPolicy, opts v1.UpdateOptions) (*v1alpha1.ClusterNetworkPolicy, error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateSubresourceAction(clusternetworkpoliciesResource, "status", clusterNetworkPolicy), &v1alpha1.ClusterNetworkPolicy{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterNetworkPolicy), err +} + // Delete takes name of the clusterNetworkPolicy and deletes it. Returns an error if one occurs. func (c *FakeClusterNetworkPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. diff --git a/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_networkpolicy.go b/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_networkpolicy.go index 792948ae27f..dd59099d6c8 100644 --- a/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_networkpolicy.go +++ b/pkg/client/clientset/versioned/typed/security/v1alpha1/fake/fake_networkpolicy.go @@ -100,6 +100,18 @@ func (c *FakeNetworkPolicies) Update(ctx context.Context, networkPolicy *v1alpha return obj.(*v1alpha1.NetworkPolicy), err } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeNetworkPolicies) UpdateStatus(ctx context.Context, networkPolicy *v1alpha1.NetworkPolicy, opts v1.UpdateOptions) (*v1alpha1.NetworkPolicy, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(networkpoliciesResource, "status", c.ns, networkPolicy), &v1alpha1.NetworkPolicy{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.NetworkPolicy), err +} + // Delete takes name of the networkPolicy and deletes it. Returns an error if one occurs. func (c *FakeNetworkPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { _, err := c.Fake. diff --git a/pkg/client/clientset/versioned/typed/security/v1alpha1/networkpolicy.go b/pkg/client/clientset/versioned/typed/security/v1alpha1/networkpolicy.go index 990280ac053..56e046140f1 100644 --- a/pkg/client/clientset/versioned/typed/security/v1alpha1/networkpolicy.go +++ b/pkg/client/clientset/versioned/typed/security/v1alpha1/networkpolicy.go @@ -38,6 +38,7 @@ type NetworkPoliciesGetter interface { type NetworkPolicyInterface interface { Create(ctx context.Context, networkPolicy *v1alpha1.NetworkPolicy, opts v1.CreateOptions) (*v1alpha1.NetworkPolicy, error) Update(ctx context.Context, networkPolicy *v1alpha1.NetworkPolicy, opts v1.UpdateOptions) (*v1alpha1.NetworkPolicy, error) + UpdateStatus(ctx context.Context, networkPolicy *v1alpha1.NetworkPolicy, opts v1.UpdateOptions) (*v1alpha1.NetworkPolicy, error) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.NetworkPolicy, error) @@ -133,6 +134,22 @@ func (c *networkPolicies) Update(ctx context.Context, networkPolicy *v1alpha1.Ne return } +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *networkPolicies) UpdateStatus(ctx context.Context, networkPolicy *v1alpha1.NetworkPolicy, opts v1.UpdateOptions) (result *v1alpha1.NetworkPolicy, err error) { + result = &v1alpha1.NetworkPolicy{} + err = c.client.Put(). + Namespace(c.ns). + Resource("networkpolicies"). + Name(networkPolicy.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(networkPolicy). + Do(ctx). + Into(result) + return +} + // Delete takes name of the networkPolicy and deletes it. Returns an error if one occurs. func (c *networkPolicies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { return c.client.Delete(). diff --git a/pkg/controller/networkpolicy/antreanetworkpolicy.go b/pkg/controller/networkpolicy/antreanetworkpolicy.go index 82aad55b534..d57031dd585 100644 --- a/pkg/controller/networkpolicy/antreanetworkpolicy.go +++ b/pkg/controller/networkpolicy/antreanetworkpolicy.go @@ -167,6 +167,7 @@ func (n *NetworkPolicyController) processAntreaNetworkPolicy(np *secv1alpha1.Net }, Name: internalNetworkPolicyKeyFunc(np), UID: np.UID, + Generation: np.Generation, AppliedToGroups: appliedToGroupNames, Rules: rules, Priority: &np.Spec.Priority, diff --git a/pkg/controller/networkpolicy/clusternetworkpolicy.go b/pkg/controller/networkpolicy/clusternetworkpolicy.go index a5ec14dcf29..de6ecf54a65 100644 --- a/pkg/controller/networkpolicy/clusternetworkpolicy.go +++ b/pkg/controller/networkpolicy/clusternetworkpolicy.go @@ -158,7 +158,8 @@ func (n *NetworkPolicyController) processClusterNetworkPolicy(cnp *secv1alpha1.C } tierPriority := n.getTierPriority(cnp.Spec.Tier) internalNetworkPolicy := &antreatypes.NetworkPolicy{ - Name: internalNetworkPolicyKeyFunc(cnp), + Name: internalNetworkPolicyKeyFunc(cnp), + Generation: cnp.Generation, SourceRef: &controlplane.NetworkPolicyReference{ Type: controlplane.AntreaClusterNetworkPolicy, Name: cnp.Name, diff --git a/pkg/controller/networkpolicy/networkpolicy_controller.go b/pkg/controller/networkpolicy/networkpolicy_controller.go index 35983f64bf6..0359237d07a 100644 --- a/pkg/controller/networkpolicy/networkpolicy_controller.go +++ b/pkg/controller/networkpolicy/networkpolicy_controller.go @@ -353,9 +353,10 @@ func (n *NetworkPolicyController) GetAppliedToGroupNum() int { // GetConnectedAgentNum gets the number of Agents which are connected to this Controller. // Since Agent will watch all the three stores (internalNetworkPolicyStore, appliedToGroupStore, addressGroupStore), // the number of watchers of one of these three stores is equal to the number of connected Agents. -// Here, we uses the number of watchers of internalNetworkPolicyStore to represent the number of connected Agents. +// Here, we uses the number of watchers of appliedToGroupStore to represent the number of connected Agents as +// internalNetworkPolicyStore is also watched by the StatusController of the process itself. func (n *NetworkPolicyController) GetConnectedAgentNum() int { - return n.internalNetworkPolicyStore.GetWatchersNum() + return n.appliedToGroupStore.GetWatchersNum() } // toGroupSelector converts the podSelector, namespaceSelector and externalEntitySelector @@ -689,6 +690,7 @@ func (n *NetworkPolicyController) processNetworkPolicy(np *networkingv1.NetworkP }, AppliedToGroups: appliedToGroupNames, Rules: rules, + Generation: np.Generation, } return internalNetworkPolicy } @@ -1485,6 +1487,7 @@ func (n *NetworkPolicyController) syncInternalNetworkPolicy(key string) error { Priority: internalNP.Priority, TierPriority: internalNP.TierPriority, SpanMeta: antreatypes.SpanMeta{NodeNames: nodeNames}, + Generation: internalNP.Generation, } klog.V(4).Infof("Updating internal NetworkPolicy %s with %d Nodes", key, nodeNames.Len()) n.internalNetworkPolicyStore.Update(updatedNetworkPolicy) diff --git a/pkg/controller/networkpolicy/status_controller.go b/pkg/controller/networkpolicy/status_controller.go new file mode 100644 index 00000000000..585bb8a3f90 --- /dev/null +++ b/pkg/controller/networkpolicy/status_controller.go @@ -0,0 +1,350 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package networkpolicy + +import ( + "context" + "sync" + "time" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog" + + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane" + secv1alpha1 "github.com/vmware-tanzu/antrea/pkg/apis/security/v1alpha1" + "github.com/vmware-tanzu/antrea/pkg/apiserver/storage" + antreaclientset "github.com/vmware-tanzu/antrea/pkg/client/clientset/versioned" + secinformers "github.com/vmware-tanzu/antrea/pkg/client/informers/externalversions/security/v1alpha1" + seclisters "github.com/vmware-tanzu/antrea/pkg/client/listers/security/v1alpha1" + antreatypes "github.com/vmware-tanzu/antrea/pkg/controller/types" +) + +// StatusController is responsible for synchronizing the status of Antrea ClusterNetworkPolicy and Antrea NetworkPolicy. +type StatusController struct { + // npControlInterface knows how to update Antrea NetworkPolicy status. + npControlInterface networkPolicyControlInterface + + // queue maintains the keys of the NetworkPolicy objects that need to be synced. + queue workqueue.RateLimitingInterface + + // internalNetworkPolicyStore is the storage where the populated internal Network Policy are stored. + internalNetworkPolicyStore storage.Interface + + // statuses is a nested map that keeps the realization statuses reported by antrea-agents. + // The outer map's keys are the NetworkPolicy keys. The inner map's keys are the Node names. The inner map's values + // are statuses reported by each Node for a NetworkPolicy. + statuses map[string]map[string]*controlplane.NetworkPolicyNodeStatus + statusesLock sync.RWMutex + + // cnpLister is able to list/get ClusterNetworkPolicies and is populated by the shared informer passed to + // NewClusterNetworkPolicyController. + cnpLister seclisters.ClusterNetworkPolicyLister + // cnpListerSynced is a function which returns true if the ClusterNetworkPolicies shared informer has been synced at least once. + cnpListerSynced cache.InformerSynced + // anpLister is able to list/get AntreaNetworkPolicies and is populated by the shared informer passed to + // NewNetworkPolicyController. + anpLister seclisters.NetworkPolicyLister + // anpListerSynced is a function which returns true if the AntreaNetworkPolicies shared informer has been synced at least once. + anpListerSynced cache.InformerSynced +} + +func NewStatusController(antreaClient antreaclientset.Interface, internalNetworkPolicyStore storage.Interface, cnpInformer secinformers.ClusterNetworkPolicyInformer, anpInformer secinformers.NetworkPolicyInformer) *StatusController { + c := &StatusController{ + npControlInterface: &networkPolicyControl{ + antreaClient: antreaClient, + anpLister: anpInformer.Lister(), + cnpLister: cnpInformer.Lister(), + }, + queue: workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(minRetryDelay, maxRetryDelay), "networkpolicy"), + internalNetworkPolicyStore: internalNetworkPolicyStore, + statuses: map[string]map[string]*controlplane.NetworkPolicyNodeStatus{}, + cnpListerSynced: cnpInformer.Informer().HasSynced, + anpListerSynced: anpInformer.Informer().HasSynced, + } + // To save a "GET" query before each update, UpdateAntreaClusterNetworkPolicyStatus treats the cache of Lister as + // the state of kube-apiserver. In some cases the cache may not be in sync, then we might skip updating a policy's + // status by mistake. To resolve it, add update event handlers which trigger resync of a policy if its status is + // updated. This could also ensure we can reconcile a policy's status if it's updated by other clients by accident. + // However, a normal update made by the controller itself will trigger resync as well, which could lead to duplicate + // computation. + // TODO: Evaluate if we can avoid the duplicate computation by comparing the updated status with some internal state. + cnpInformer.Informer().AddEventHandlerWithResyncPeriod( + cache.ResourceEventHandlerFuncs{ + UpdateFunc: c.updateCNP, + }, + resyncPeriod, + ) + anpInformer.Informer().AddEventHandlerWithResyncPeriod( + cache.ResourceEventHandlerFuncs{ + UpdateFunc: c.updateANP, + }, + resyncPeriod, + ) + return c +} + +func (c *StatusController) updateCNP(old, cur interface{}) { + curCNP := cur.(*secv1alpha1.ClusterNetworkPolicy) + oldCNP := old.(*secv1alpha1.ClusterNetworkPolicy) + if oldCNP.Status == curCNP.Status { + return + } + key := internalNetworkPolicyKeyFunc(oldCNP) + c.queue.Add(key) +} + +func (c *StatusController) updateANP(old, cur interface{}) { + curANP := cur.(*secv1alpha1.NetworkPolicy) + oldANP := old.(*secv1alpha1.NetworkPolicy) + if oldANP.Status == curANP.Status { + return + } + key := internalNetworkPolicyKeyFunc(oldANP) + c.queue.Add(key) +} + +func (c *StatusController) UpdateStatus(status *controlplane.NetworkPolicyStatus) error { + key := status.Name + _, found, _ := c.internalNetworkPolicyStore.Get(key) + if !found { + klog.Infof("NetworkPolicy %s has been deleted, skip updating its status", key) + return nil + } + func() { + c.statusesLock.Lock() + defer c.statusesLock.Unlock() + statusPerNode, exists := c.statuses[key] + if !exists { + statusPerNode = map[string]*controlplane.NetworkPolicyNodeStatus{} + c.statuses[key] = statusPerNode + } + for i := range status.Nodes { + statusPerNode[status.Nodes[i].NodeName] = &status.Nodes[i] + } + }() + c.queue.Add(key) + return nil +} + +func (c *StatusController) getNodeStatuses(key string) []*controlplane.NetworkPolicyNodeStatus { + c.statusesLock.RLock() + defer c.statusesLock.RUnlock() + statusPerNode, exists := c.statuses[key] + if !exists { + return nil + } + statuses := make([]*controlplane.NetworkPolicyNodeStatus, 0, len(c.statuses[key])) + for _, status := range statusPerNode { + statuses = append(statuses, status) + } + return statuses +} + +func (c *StatusController) clearStatuses(key string) { + c.statusesLock.Lock() + defer c.statusesLock.Unlock() + delete(c.statuses, key) +} + +func (c *StatusController) deleteNodeStatus(key string, nodeName string) { + c.statusesLock.Lock() + defer c.statusesLock.Unlock() + statusPerNode, exists := c.statuses[key] + if !exists { + return + } + delete(statusPerNode, nodeName) +} + +// Run begins watching and syncing of a StatusController. +func (c *StatusController) Run(stopCh <-chan struct{}) { + defer c.queue.ShutDown() + + klog.Info("Starting NetworkPolicyStatus controller") + defer klog.Info("Shutting down NetworkPolicyStatus controller") + + klog.Info("Waiting for caches to sync for NetworkPolicyStatus controller") + if !cache.WaitForCacheSync(stopCh, c.cnpListerSynced, c.anpListerSynced) { + klog.Error("Unable to sync CNP caches for NetworkPolicy controller") + return + } + klog.Info("Caches are synced for NetworkPolicyStatus controller") + + go wait.NonSlidingUntil(c.watchInternelNetworkPolicy, 5*time.Second, stopCh) + + for i := 0; i < defaultWorkers; i++ { + go wait.Until(c.runWorker, time.Second, stopCh) + } + <-stopCh +} + +func (c *StatusController) watchInternelNetworkPolicy() { + watcher, err := c.internalNetworkPolicyStore.Watch(context.TODO(), "", labels.Everything(), fields.Everything()) + if err != nil { + klog.Errorf("Failed to start watch for internal NetworkPolicy: %v", err) + return + } + defer watcher.Stop() + resultCh := watcher.ResultChan() + for { + select { + case event, ok := <-resultCh: + if !ok { + return + } + // Skip handling Bookmark events. + if event.Type == watch.Bookmark { + continue + } + np := event.Object.(*controlplane.NetworkPolicy) + if np.SourceRef.Type == controlplane.K8sNetworkPolicy { + continue + } + c.queue.Add(np.Name) + } + } +} + +func (c *StatusController) runWorker() { + for c.processNextWorkItem() { + } +} + +// processNextWorkItem deals with one key off the queue. It returns false when it's time to quit. +func (c *StatusController) processNextWorkItem() bool { + key, quit := c.queue.Get() + if quit { + return false + } + defer c.queue.Done(key) + + err := c.syncHandler(key.(string)) + if err == nil { + c.queue.Forget(key) + return true + } + + klog.Errorf("Failed to sync NetworkPolicy status %s: %v", key, err) + c.queue.AddRateLimited(key) + + return true +} + +// syncHandler calculates the NetworkPolicy status based on the desired state from the internalNetworkPolicyStore and +// the actual state from the statuses map, and syncs it with the Kubernetes API. +// Each status update from agents can trigger syncHandler, however, the status updates' arrival time should not differ +// too much so some of them can be merged in workqueue. Besides, there are a limited number of workers. If there are +// many policies need to sync, some policies will have to wait in workqueue, during which their status updates can be +// merged. Therefore, it shouldn't happen that each status update leads to one CR update. +func (c *StatusController) syncHandler(key string) error { + klog.V(2).Infof("Syncing NetworkPolicy status for %s", key) + internalNPObj, found, _ := c.internalNetworkPolicyStore.Get(key) + if !found { + // It has been deleted, cleaning its statuses. + c.clearStatuses(key) + return nil + } + internalNP := internalNPObj.(*antreatypes.NetworkPolicy) + + // It means the NetworkPolicy hasn't been processed once. Set it to Pending to differentiate from NetworkPolicies + // that spans 0 Node. + if internalNP.SpanMeta.NodeNames == nil { + return c.npControlInterface.UpdateAntreaNetworkPolicyStatus(internalNP.SourceRef.Namespace, internalNP.SourceRef.Name, &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyPending, + ObservedGeneration: internalNP.Generation, + }) + } + desiredNodes := len(internalNP.SpanMeta.NodeNames) + currentNodes := 0 + statuses := c.getNodeStatuses(key) + for _, status := range statuses { + // The node is no longer in the span of this policy, delete its status. + if !internalNP.NodeNames.Has(status.NodeName) { + c.deleteNodeStatus(key, status.NodeName) + continue + } + if status.Generation == internalNP.Generation { + currentNodes += 1 + } + } + + phase := secv1alpha1.NetworkPolicyRealizing + if currentNodes == desiredNodes { + phase = secv1alpha1.NetworkPolicyRealized + } + + status := &secv1alpha1.NetworkPolicyStatus{ + Phase: phase, + ObservedGeneration: internalNP.Generation, + CurrentNodesRealized: int32(currentNodes), + DesiredNodesRealized: int32(desiredNodes), + } + klog.V(2).Infof("Updating NetworkPolicy %s status: %v", internalNP.SourceRef.ToString(), status) + if internalNP.SourceRef.Type == controlplane.AntreaNetworkPolicy { + return c.npControlInterface.UpdateAntreaNetworkPolicyStatus(internalNP.SourceRef.Namespace, internalNP.SourceRef.Name, status) + } else { + return c.npControlInterface.UpdateAntreaClusterNetworkPolicyStatus(internalNP.SourceRef.Name, status) + } +} + +// networkPolicyControlInterface is an interface that knows how to update Antrea NetworkPolicy status. +// It's created as an interface to allow testing. +type networkPolicyControlInterface interface { + UpdateAntreaNetworkPolicyStatus(namespace, name string, status *secv1alpha1.NetworkPolicyStatus) error + UpdateAntreaClusterNetworkPolicyStatus(name string, status *secv1alpha1.NetworkPolicyStatus) error +} + +type networkPolicyControl struct { + antreaClient antreaclientset.Interface + cnpLister seclisters.ClusterNetworkPolicyLister + anpLister seclisters.NetworkPolicyLister +} + +func (c *networkPolicyControl) UpdateAntreaNetworkPolicyStatus(namespace, name string, status *secv1alpha1.NetworkPolicyStatus) error { + anp, err := c.anpLister.NetworkPolicies(namespace).Get(name) + if err != nil { + klog.Infof("Didn't find the original Antrea NetworkPolicy %s/%s, skip updating status", namespace, name) + return nil + } + if anp.Status == *status { + return nil + } + toUpdate := anp.DeepCopy() + toUpdate.Status = *status + _, err = c.antreaClient.SecurityV1alpha1().NetworkPolicies(namespace).UpdateStatus(context.TODO(), toUpdate, v1.UpdateOptions{}) + return err +} + +func (c *networkPolicyControl) UpdateAntreaClusterNetworkPolicyStatus(name string, status *secv1alpha1.NetworkPolicyStatus) error { + cnp, err := c.cnpLister.Get(name) + if err != nil { + klog.Infof("Didn't find the original Antrea ClusterNetworkPolicy %s, skip updating status", name) + return nil + } + // If the current status equals to the desired status, no need to update. + if cnp.Status == *status { + return nil + } + toUpdate := cnp.DeepCopy() + toUpdate.Status = *status + _, err = c.antreaClient.SecurityV1alpha1().ClusterNetworkPolicies().UpdateStatus(context.TODO(), toUpdate, v1.UpdateOptions{}) + return err +} diff --git a/pkg/controller/networkpolicy/status_controller_test.go b/pkg/controller/networkpolicy/status_controller_test.go new file mode 100644 index 00000000000..277f6553260 --- /dev/null +++ b/pkg/controller/networkpolicy/status_controller_test.go @@ -0,0 +1,350 @@ +// Copyright 2020 Antrea Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package networkpolicy + +import ( + "fmt" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/client-go/util/workqueue" + + "github.com/vmware-tanzu/antrea/pkg/apis/controlplane" + secv1alpha1 "github.com/vmware-tanzu/antrea/pkg/apis/security/v1alpha1" + "github.com/vmware-tanzu/antrea/pkg/apiserver/storage" + antreaclientset "github.com/vmware-tanzu/antrea/pkg/client/clientset/versioned" + antreafakeclientset "github.com/vmware-tanzu/antrea/pkg/client/clientset/versioned/fake" + antreainformers "github.com/vmware-tanzu/antrea/pkg/client/informers/externalversions" + "github.com/vmware-tanzu/antrea/pkg/controller/networkpolicy/store" + "github.com/vmware-tanzu/antrea/pkg/controller/types" +) + +type fakeNetworkPolicyControl struct { + sync.Mutex + anpStatus *secv1alpha1.NetworkPolicyStatus + cnpStatus *secv1alpha1.NetworkPolicyStatus +} + +func (c *fakeNetworkPolicyControl) UpdateAntreaNetworkPolicyStatus(namespace, name string, status *secv1alpha1.NetworkPolicyStatus) error { + c.Lock() + defer c.Unlock() + c.anpStatus = status + return nil +} + +func (c *fakeNetworkPolicyControl) UpdateAntreaClusterNetworkPolicyStatus(name string, status *secv1alpha1.NetworkPolicyStatus) error { + c.Lock() + defer c.Unlock() + c.cnpStatus = status + return nil +} + +func (c *fakeNetworkPolicyControl) getAntreaNetworkPolicyStatus() *secv1alpha1.NetworkPolicyStatus { + c.Lock() + defer c.Unlock() + return c.anpStatus +} + +func (c *fakeNetworkPolicyControl) getAntreaClusterNetworkPolicyStatus() *secv1alpha1.NetworkPolicyStatus { + c.Lock() + defer c.Unlock() + return c.cnpStatus +} + +func newTestStatusController(initialObjects ...runtime.Object) (*StatusController, antreaclientset.Interface, antreainformers.SharedInformerFactory, storage.Interface, *fakeNetworkPolicyControl) { + //clientset := fake.NewSimpleClientset(initialObjects...) + networkPolicyStore := store.NewNetworkPolicyStore() + antreaClientset := antreafakeclientset.NewSimpleClientset(initialObjects...) + antreaInformerFactory := antreainformers.NewSharedInformerFactory(antreaClientset, 0) + networkPolicyControl := &fakeNetworkPolicyControl{} + + cnpInformer := antreaInformerFactory.Security().V1alpha1().ClusterNetworkPolicies() + anpInformer := antreaInformerFactory.Security().V1alpha1().NetworkPolicies() + statusController := &StatusController{ + npControlInterface: networkPolicyControl, + queue: workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(minRetryDelay, maxRetryDelay), "networkpolicy"), + internalNetworkPolicyStore: networkPolicyStore, + statuses: map[string]map[string]*controlplane.NetworkPolicyNodeStatus{}, + cnpListerSynced: cnpInformer.Informer().HasSynced, + anpListerSynced: anpInformer.Informer().HasSynced, + } + return statusController, antreaClientset, antreaInformerFactory, networkPolicyStore, networkPolicyControl +} + +func newNetworkPolicy(name string, generation int64, nodes []string, ref *controlplane.NetworkPolicyReference) *types.NetworkPolicy { + return &types.NetworkPolicy{ + SpanMeta: types.SpanMeta{NodeNames: sets.NewString(nodes...)}, + Generation: generation, + Name: name, + SourceRef: ref, + } +} + +func newNetworkPolicyStatus(name string, nodeName string, generation int64) *controlplane.NetworkPolicyStatus { + return &controlplane.NetworkPolicyStatus{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + }, + Nodes: []controlplane.NetworkPolicyNodeStatus{ + { + NodeName: nodeName, + Generation: generation, + }, + }, + } +} + +func toAntreaNetworkPolicy(inp *types.NetworkPolicy) runtime.Object { + if inp.SourceRef.Type == controlplane.AntreaNetworkPolicy { + return &secv1alpha1.NetworkPolicy{ + ObjectMeta: v1.ObjectMeta{ + Namespace: inp.SourceRef.Namespace, + Name: inp.SourceRef.Name, + Generation: inp.Generation, + }, + } + } else { + return &secv1alpha1.ClusterNetworkPolicy{ + ObjectMeta: v1.ObjectMeta{ + Name: inp.SourceRef.Name, + Generation: inp.Generation, + }, + } + } +} + +func newAntreaNetworkPolicyReference(namespace, name string) *controlplane.NetworkPolicyReference { + return &controlplane.NetworkPolicyReference{ + Type: controlplane.AntreaNetworkPolicy, + Namespace: namespace, + Name: name, + } +} + +func newAntreaClusterNetworkPolicyReference(name string) *controlplane.NetworkPolicyReference { + return &controlplane.NetworkPolicyReference{ + Type: controlplane.AntreaClusterNetworkPolicy, + Name: name, + } +} + +func TestCreateAntreaNetworkPolicy(t *testing.T) { + tests := []struct { + name string + networkPolicy []*types.NetworkPolicy + collectedNetworkPolicyStatus []*controlplane.NetworkPolicyStatus + expectedANPStatus *secv1alpha1.NetworkPolicyStatus + expectedCNPStatus *secv1alpha1.NetworkPolicyStatus + }{ + { + name: "no realization status", + networkPolicy: []*types.NetworkPolicy{ + newNetworkPolicy("anp1", 1, []string{"node1", "node2"}, newAntreaNetworkPolicyReference("ns1", "anp1")), + newNetworkPolicy("cnp1", 1, []string{"node1", "node2"}, newAntreaClusterNetworkPolicyReference("cnp1")), + }, + expectedANPStatus: &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealizing, + ObservedGeneration: 1, + CurrentNodesRealized: 0, + DesiredNodesRealized: 2, + }, + expectedCNPStatus: &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealizing, + ObservedGeneration: 1, + CurrentNodesRealized: 0, + DesiredNodesRealized: 2, + }, + }, + { + name: "partially realized", + networkPolicy: []*types.NetworkPolicy{ + newNetworkPolicy("anp1", 2, []string{"node1", "node2"}, newAntreaNetworkPolicyReference("ns1", "anp1")), + newNetworkPolicy("cnp1", 3, []string{"node1", "node2"}, newAntreaClusterNetworkPolicyReference("cnp1")), + }, + collectedNetworkPolicyStatus: []*controlplane.NetworkPolicyStatus{ + newNetworkPolicyStatus("anp1", "node1", 1), + newNetworkPolicyStatus("anp1", "node2", 2), + newNetworkPolicyStatus("cnp1", "node1", 2), + newNetworkPolicyStatus("cnp1", "node2", 3), + }, + expectedANPStatus: &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealizing, + ObservedGeneration: 2, + CurrentNodesRealized: 1, + DesiredNodesRealized: 2, + }, + expectedCNPStatus: &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealizing, + ObservedGeneration: 3, + CurrentNodesRealized: 1, + DesiredNodesRealized: 2, + }, + }, + { + name: "entirely realized", + networkPolicy: []*types.NetworkPolicy{ + newNetworkPolicy("anp1", 3, []string{"node1", "node2"}, newAntreaNetworkPolicyReference("ns1", "anp1")), + newNetworkPolicy("cnp1", 4, []string{"node1", "node2"}, newAntreaClusterNetworkPolicyReference("cnp1")), + }, + collectedNetworkPolicyStatus: []*controlplane.NetworkPolicyStatus{ + newNetworkPolicyStatus("anp1", "node1", 3), + newNetworkPolicyStatus("anp1", "node2", 3), + newNetworkPolicyStatus("cnp1", "node1", 4), + newNetworkPolicyStatus("cnp1", "node2", 4), + }, + expectedANPStatus: &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealized, + ObservedGeneration: 3, + CurrentNodesRealized: 2, + DesiredNodesRealized: 2, + }, + expectedCNPStatus: &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealized, + ObservedGeneration: 4, + CurrentNodesRealized: 2, + DesiredNodesRealized: 2, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var initObjects []runtime.Object + for _, policy := range tt.networkPolicy { + initObjects = append(initObjects, toAntreaNetworkPolicy(policy)) + } + statusController, _, antreaInformerFactory, networkPolicyStore, networkPolicyControl := newTestStatusController(initObjects...) + stopCh := make(chan struct{}) + defer close(stopCh) + antreaInformerFactory.Start(stopCh) + go statusController.Run(stopCh) + + for _, policy := range tt.networkPolicy { + networkPolicyStore.Create(policy) + } + for _, status := range tt.collectedNetworkPolicyStatus { + statusController.UpdateStatus(status) + } + + // TODO: Use a determinate mechanism. + time.Sleep(500 * time.Millisecond) + assert.Equal(t, tt.expectedANPStatus, networkPolicyControl.getAntreaNetworkPolicyStatus()) + assert.Equal(t, tt.expectedCNPStatus, networkPolicyControl.getAntreaClusterNetworkPolicyStatus()) + }) + } +} + +func TestUpdateAntreaNetworkPolicy(t *testing.T) { + anp1 := newNetworkPolicy("anp1", 1, []string{"node1", "node2"}, newAntreaNetworkPolicyReference("ns1", "anp1")) + cnp1 := newNetworkPolicy("cnp1", 2, []string{"node3", "node4", "node5"}, newAntreaClusterNetworkPolicyReference("cnp1")) + statusController, _, antreaInformerFactory, networkPolicyStore, networkPolicyControl := newTestStatusController(toAntreaNetworkPolicy(anp1), toAntreaNetworkPolicy(cnp1)) + stopCh := make(chan struct{}) + defer close(stopCh) + antreaInformerFactory.Start(stopCh) + go statusController.Run(stopCh) + + networkPolicyStore.Create(anp1) + networkPolicyStore.Create(cnp1) + statusController.UpdateStatus(newNetworkPolicyStatus("anp1", "node1", 1)) + statusController.UpdateStatus(newNetworkPolicyStatus("anp1", "node2", 1)) + statusController.UpdateStatus(newNetworkPolicyStatus("cnp1", "node3", 2)) + statusController.UpdateStatus(newNetworkPolicyStatus("cnp1", "node4", 2)) + statusController.UpdateStatus(newNetworkPolicyStatus("cnp1", "node5", 2)) + // TODO: Use a determinate mechanism. + time.Sleep(500 * time.Millisecond) + assert.Equal(t, &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealized, + ObservedGeneration: 1, + CurrentNodesRealized: 2, + DesiredNodesRealized: 2, + }, networkPolicyControl.getAntreaNetworkPolicyStatus()) + assert.Equal(t, &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealized, + ObservedGeneration: 2, + CurrentNodesRealized: 3, + DesiredNodesRealized: 3, + }, networkPolicyControl.getAntreaClusterNetworkPolicyStatus()) + + anp1Updated := newNetworkPolicy("anp1", 2, []string{"node1", "node2", "node3"}, newAntreaNetworkPolicyReference("ns1", "anp1")) + cnp1Updated := newNetworkPolicy("cnp1", 3, []string{"node4", "node5"}, newAntreaClusterNetworkPolicyReference("cnp1")) + networkPolicyStore.Update(anp1Updated) + networkPolicyStore.Update(cnp1Updated) + // TODO: Use a determinate mechanism. + time.Sleep(500 * time.Millisecond) + assert.Equal(t, &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealizing, + ObservedGeneration: 2, + CurrentNodesRealized: 0, + DesiredNodesRealized: 3, + }, networkPolicyControl.getAntreaNetworkPolicyStatus()) + assert.Equal(t, &secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealizing, + ObservedGeneration: 3, + CurrentNodesRealized: 0, + DesiredNodesRealized: 2, + }, networkPolicyControl.getAntreaClusterNetworkPolicyStatus()) +} + +func TestDeleteAntreaNetworkPolicy(t *testing.T) { + initialNetworkPolicy := newNetworkPolicy("anp1", 1, []string{"node1", "node2"}, newAntreaNetworkPolicyReference("ns1", "anp1")) + initialANP := toAntreaNetworkPolicy(initialNetworkPolicy) + statusController, _, antreaInformerFactory, networkPolicyStore, _ := newTestStatusController(initialANP) + stopCh := make(chan struct{}) + defer close(stopCh) + antreaInformerFactory.Start(stopCh) + go statusController.Run(stopCh) + + networkPolicyStore.Create(initialNetworkPolicy) + statuses := []*controlplane.NetworkPolicyStatus{ + newNetworkPolicyStatus("anp1", "node1", 1), + newNetworkPolicyStatus("anp1", "node2", 1), + } + for _, status := range statuses { + statusController.UpdateStatus(status) + } + assert.Equal(t, 2, len(statusController.getNodeStatuses(initialNetworkPolicy.Name))) + + networkPolicyStore.Delete(initialNetworkPolicy.Name) + // TODO: Use a determinate mechanism. + time.Sleep(500 * time.Millisecond) + assert.Empty(t, statusController.getNodeStatuses(initialNetworkPolicy.Name)) +} + +// BenchmarkSyncHandler benchmarks syncHandler when the policy spans 1000 Nodes. Its current result is: +// 70024 ns/op 8338 B/op 8 allocs/op +func BenchmarkSyncHandler(b *testing.B) { + nodeNum := 1000 + nodes := make([]string, 0, nodeNum) + for i := 0; i < nodeNum; i++ { + nodes = append(nodes, fmt.Sprintf("node%d", i)) + } + networkPolicy := newNetworkPolicy("anp1", 1, nodes, newAntreaNetworkPolicyReference("ns1", "anp1")) + statusController, _, _, networkPolicyStore, _ := newTestStatusController() + + networkPolicyStore.Create(networkPolicy) + for _, node := range nodes { + statusController.UpdateStatus(newNetworkPolicyStatus("anp1", node, 1)) + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + statusController.syncHandler("anp1") + } +} diff --git a/pkg/controller/networkpolicy/store/networkpolicy.go b/pkg/controller/networkpolicy/store/networkpolicy.go index 4970cfee347..971bad57805 100644 --- a/pkg/controller/networkpolicy/store/networkpolicy.go +++ b/pkg/controller/networkpolicy/store/networkpolicy.go @@ -105,6 +105,7 @@ func ToNetworkPolicyMsg(in *types.NetworkPolicy, out *controlplane.NetworkPolicy out.Name = in.Name out.UID = in.UID out.SourceRef = in.SourceRef + out.Generation = in.Generation if !includeBody { return } diff --git a/pkg/controller/types/networkpolicy.go b/pkg/controller/types/networkpolicy.go index b0da1aafd67..fd60af4795b 100644 --- a/pkg/controller/types/networkpolicy.go +++ b/pkg/controller/types/networkpolicy.go @@ -25,6 +25,7 @@ import ( // SpanMeta describes the span information of an object. type SpanMeta struct { // NodeNames is a set of node names that this object should be sent to. + // nil means it's not calculated yet while empty set means the span is 0 Node. NodeNames sets.String } @@ -97,6 +98,8 @@ type NetworkPolicy struct { UID types.UID // Name of the internal Network Policy, must be unique across all Network Policy types. Name string + // Generation of the internal Network Policy. It's inherited from the original Network Policy. + Generation int64 // Reference to the original Network Policy. SourceRef *controlplane.NetworkPolicyReference // Priority represents the relative priority of this Network Policy as compared to diff --git a/test/e2e/antreapolicy_test.go b/test/e2e/antreapolicy_test.go index d4d43e6e923..58b4744ef7c 100644 --- a/test/e2e/antreapolicy_test.go +++ b/test/e2e/antreapolicy_test.go @@ -15,6 +15,7 @@ package e2e import ( + "context" "fmt" "strings" "testing" @@ -25,6 +26,7 @@ import ( v1 "k8s.io/api/core/v1" v1net "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" secv1alpha1 "github.com/vmware-tanzu/antrea/pkg/apis/security/v1alpha1" "github.com/vmware-tanzu/antrea/pkg/features" @@ -882,3 +884,64 @@ func TestAntreaPolicy(t *testing.T) { }) k8sUtils.Cleanup(namespaces) } + +func TestAntreaPolicyStatus(t *testing.T) { + data, err := setupTest(t) + if err != nil { + t.Fatalf("Error when setting up test: %v", err) + } + defer teardownTest(t, data) + skipIfAntreaPolicyDisabled(t, data) + + _, _, cleanupFunc := createAndWaitForPod(t, data, data.createNginxPodOnNode, "server-0", masterNodeName()) + defer cleanupFunc() + _, _, cleanupFunc = createAndWaitForPod(t, data, data.createNginxPodOnNode, "server-1", workerNodeName(1)) + defer cleanupFunc() + + anpBuilder := &AntreaNetworkPolicySpecBuilder{} + anpBuilder = anpBuilder.SetName(testNamespace, "anp-applied-to-two-nodes"). + SetPriority(1.0). + SetAppliedToGroup(map[string]string{"app": "nginx"}, nil) + anpBuilder.AddIngress(v1.ProtocolTCP, &p80, nil, nil, map[string]string{"pod": "b"}, map[string]string{"ns": "x"}, + nil, nil, secv1alpha1.RuleActionAllow) + anp := anpBuilder.Get() + log.Debugf("creating ANP %v", anp.Name) + _, err = data.securityClient.NetworkPolicies(anp.Namespace).Create(context.TODO(), anp, metav1.CreateOptions{}) + assert.NoError(t, err) + defer data.securityClient.NetworkPolicies(anp.Namespace).Delete(context.TODO(), anp.Name, metav1.DeleteOptions{}) + + cnpBuilder := &ClusterNetworkPolicySpecBuilder{} + cnpBuilder = cnpBuilder.SetName("cnp-applied-to-two-nodes"). + SetPriority(1.0). + SetAppliedToGroup(map[string]string{"app": "nginx"}, nil, nil, nil) + cnpBuilder.AddIngress(v1.ProtocolTCP, &p80, nil, nil, map[string]string{"pod": "b"}, map[string]string{"ns": "x"}, + nil, nil, secv1alpha1.RuleActionAllow) + cnp := cnpBuilder.Get() + log.Debugf("creating CNP %v", cnp.Name) + _, err = data.securityClient.ClusterNetworkPolicies().Create(context.TODO(), cnp, metav1.CreateOptions{}) + assert.NoError(t, err) + defer data.securityClient.ClusterNetworkPolicies().Delete(context.TODO(), cnp.Name, metav1.DeleteOptions{}) + + expectedStatus := secv1alpha1.NetworkPolicyStatus{ + Phase: secv1alpha1.NetworkPolicyRealized, + ObservedGeneration: 1, + CurrentNodesRealized: 2, + DesiredNodesRealized: 2, + } + err = wait.Poll(100*time.Millisecond, 3*time.Second, func() (bool, error) { + anp, err := data.securityClient.NetworkPolicies(anp.Namespace).Get(context.TODO(), anp.Name, metav1.GetOptions{}) + if err != nil { + return false, err + } + return anp.Status == expectedStatus, nil + }) + assert.NoError(t, err, "Antrea NetworkPolicy failed to reach expected status") + err = wait.Poll(100*time.Millisecond, 3*time.Second, func() (bool, error) { + anp, err := data.securityClient.ClusterNetworkPolicies().Get(context.TODO(), cnp.Name, metav1.GetOptions{}) + if err != nil { + return false, err + } + return anp.Status == expectedStatus, nil + }) + assert.NoError(t, err, "Antrea ClusterNetworkPolicy failed to reach expected status") +}