/
group.go
138 lines (127 loc) · 6.75 KB
/
group.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2021 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 types
import (
"fmt"
"net"
"sort"
"strings"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
"antrea.io/antrea/pkg/apis/controlplane"
)
// GroupSelector describes how to select GroupMembers.
type GroupSelector struct {
// The normalized name is calculated from Namespace, PodSelector, ExternalEntitySelector and NamespaceSelector.
// If multiple policies have same standalone selectors, they should share this group by comparing NormalizedName.
// It's also used to generate Name and UUID of AddressGroup or AppliedToGroup.
// Internal Groups corresponding to the ClusterGroups use the NormalizedName to detect if there is a change in
// the selectors.
NormalizedName string
// If Namespace is set, NamespaceSelector can not be set. It means only GroupMembers in this Namespace will be matched.
Namespace string
// This is a label selector which selects GroupMembers. If Namespace is also set, it selects the GroupMembers in the Namespace.
// If NamespaceSelector is set instead, it selects the GroupMembers in the Namespaces selected by NamespaceSelector.
// If Namespace and NamespaceSelector both are unset, it selects the GroupMembers in all the Namespaces.
PodSelector labels.Selector
// This is a label selector which selects Namespaces. If this field is set, Namespace can not be set.
NamespaceSelector labels.Selector
// This is a label selector which selects ExternalEntities. Within a group, ExternalEntitySelector cannot be
// set concurrently with PodSelector. If Namespace is also set, it selects the ExternalEntities in the Namespace.
// If NamespaceSelector is set instead, it selects ExternalEntities in the Namespaces selected by NamespaceSelector.
// If Namespace and NamespaceSelector both are unset, it selects the ExternalEntities in all the Namespaces.
// TODO: Add validation in API to not allow externalEntitySelector and podSelector in the same group.
ExternalEntitySelector labels.Selector
// This is a label selector which selects certain Node IPs. Within a group NodeSelector cannot be set together with
// other selectors: Namespace/NamespaceSelector/PodSelector/ExternalEntitySelector.
NodeSelector labels.Selector
}
// NewGroupSelector converts the podSelector, namespaceSelector, externalEntitySelector and nodeSelector
// and NetworkPolicy Namespace to a networkpolicy.GroupSelector object.
func NewGroupSelector(namespace string, podSelector, nsSelector, extEntitySelector, nodeSelector *metav1.LabelSelector) *GroupSelector {
groupSelector := GroupSelector{}
if podSelector != nil {
groupSelector.PodSelector, _ = metav1.LabelSelectorAsSelector(podSelector)
}
if extEntitySelector != nil {
groupSelector.ExternalEntitySelector, _ = metav1.LabelSelectorAsSelector(extEntitySelector)
}
if nsSelector == nil {
// No namespaceSelector indicates that the pods must be selected within
// the NetworkPolicy's Namespace.
groupSelector.Namespace = namespace
} else {
groupSelector.NamespaceSelector, _ = metav1.LabelSelectorAsSelector(nsSelector)
}
if nodeSelector != nil {
groupSelector.NodeSelector, _ = metav1.LabelSelectorAsSelector(nodeSelector)
}
name := GenerateNormalizedName(groupSelector.Namespace, groupSelector.PodSelector,
groupSelector.NamespaceSelector, groupSelector.ExternalEntitySelector, groupSelector.NodeSelector)
groupSelector.NormalizedName = name
return &groupSelector
}
// GenerateNormalizedName generates a string, based on the selectors, in
// the following format: "namespace=NamespaceName And podSelector=normalizedPodSelector".
// Note: Namespace and nsSelector may or may not be set depending on the
// selector. However, they cannot be set simultaneously.
func GenerateNormalizedName(namespace string, podSelector, nsSelector, eeSelector labels.Selector, nodeSelector labels.Selector) string {
normalizedName := []string{}
if nsSelector != nil {
normalizedName = append(normalizedName, fmt.Sprintf("namespaceSelector=%s", nsSelector.String()))
} else if namespace != "" {
normalizedName = append(normalizedName, fmt.Sprintf("namespace=%s", namespace))
}
if podSelector != nil {
normalizedName = append(normalizedName, fmt.Sprintf("podSelector=%s", podSelector.String()))
}
if eeSelector != nil {
normalizedName = append(normalizedName, fmt.Sprintf("eeSelector=%s", eeSelector.String()))
}
if nodeSelector != nil {
normalizedName = append(normalizedName, fmt.Sprintf("nodeSelector=%s", nodeSelector.String()))
}
sort.Strings(normalizedName)
return strings.Join(normalizedName, " And ")
}
// Group describes a set of GroupMembers which can be referenced in Antrea-native NetworkPolicies. These Groups can
// then be converted to AppliedToGroup or AddressGroup. Each internal Group corresponds to a single ClusterGroup,
// i.e. unlike AppliedTo/AddressGroups created for standalone selectors, these internal Groups are not shared by
// ClusterGroups created with same selectors.
type Group struct {
// UID is a unique identifier of this internal Group. It is same as that of the ClusterGroup
// resource UID.
UID types.UID
// Reference of the ClusterGroup/Group for which this internal Group is created.
SourceReference *controlplane.GroupReference
// MembersComputed knows whether the controller has computed the comprehensive members
// of the Group. It is updated during the syncInternalGroup process.
MembersComputed v1.ConditionStatus
// Selector describes how the internal group selects Pods to get their addresses.
// Selector is nil if Group is defined with ipBlock, or if it has ServiceReference
// and has not been processed by the controller yet / Service cannot be found.
Selector *GroupSelector
IPBlocks []controlplane.IPBlock
// IPNets stores net.IPNet objects for each CIDR defined in the IPBlocks field.
// It is used for IP association query tests, so that for IP membership tests
// we do not need to instantiate an IPNet object each time.
IPNets []net.IPNet
// ServiceReference is reference to a v1.Service, which this Group keeps in sync
// and updates Selector based on the Service's selector.
ServiceReference *controlplane.ServiceReference
// ChildGroups is the list of Group names that belong to this Group.
ChildGroups []string
}