github.com/imran-kn/cilium-fork@v1.6.9/pkg/policy/api/ingress.go (about) 1 // Copyright 2016-2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package api 16 17 import ( 18 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 19 ) 20 21 // IngressRule contains all rule types which can be applied at ingress, 22 // i.e. network traffic that originates outside of the endpoint and 23 // is entering the endpoint selected by the endpointSelector. 24 // 25 // - All members of this structure are optional. If omitted or empty, the 26 // member will have no effect on the rule. 27 // 28 // - If multiple members are set, all of them need to match in order for 29 // the rule to take effect. The exception to this rule is FromRequires field; 30 // the effects of any Requires field in any rule will apply to all other 31 // rules as well. 32 // 33 // - For now, combining ToPorts, FromCIDR, and FromEndpoints in the same rule 34 // is not supported and any such rules will be rejected. In the future, this 35 // will be supported and if multiple members of this structure are specified, 36 // then all members must match in order for the rule to take effect. The 37 // exception to this rule is the Requires field, the effects of any Requires 38 // field in any rule will apply to all other rules as well. 39 type IngressRule struct { 40 // FromEndpoints is a list of endpoints identified by an 41 // EndpointSelector which are allowed to communicate with the endpoint 42 // subject to the rule. 43 // 44 // Example: 45 // Any endpoint with the label "role=backend" can be consumed by any 46 // endpoint carrying the label "role=frontend". 47 // 48 // +optional 49 FromEndpoints []EndpointSelector `json:"fromEndpoints,omitempty"` 50 51 // FromRequires is a list of additional constraints which must be met 52 // in order for the selected endpoints to be reachable. These 53 // additional constraints do no by itself grant access privileges and 54 // must always be accompanied with at least one matching FromEndpoints. 55 // 56 // Example: 57 // Any Endpoint with the label "team=A" requires consuming endpoint 58 // to also carry the label "team=A". 59 // 60 // +optional 61 FromRequires []EndpointSelector `json:"fromRequires,omitempty"` 62 63 // ToPorts is a list of destination ports identified by port number and 64 // protocol which the endpoint subject to the rule is allowed to 65 // receive connections on. 66 // 67 // Example: 68 // Any endpoint with the label "app=httpd" can only accept incoming 69 // connections on port 80/tcp. 70 // 71 // +optional 72 ToPorts []PortRule `json:"toPorts,omitempty"` 73 74 // FromCIDR is a list of IP blocks which the endpoint subject to the 75 // rule is allowed to receive connections from. Only connections which 76 // do *not* originate from the cluster or from the local host are subject 77 // to CIDR rules. In order to allow in-cluster connectivity, use the 78 // FromEndpoints field. This will match on the source IP address of 79 // incoming connections. Adding a prefix into FromCIDR or into 80 // FromCIDRSet with no ExcludeCIDRs is equivalent. Overlaps are 81 // allowed between FromCIDR and FromCIDRSet. 82 // 83 // Example: 84 // Any endpoint with the label "app=my-legacy-pet" is allowed to receive 85 // connections from 10.3.9.1 86 // 87 // +optional 88 FromCIDR CIDRSlice `json:"fromCIDR,omitempty"` 89 90 // FromCIDRSet is a list of IP blocks which the endpoint subject to the 91 // rule is allowed to receive connections from in addition to FromEndpoints, 92 // along with a list of subnets contained within their corresponding IP block 93 // from which traffic should not be allowed. 94 // This will match on the source IP address of incoming connections. Adding 95 // a prefix into FromCIDR or into FromCIDRSet with no ExcludeCIDRs is 96 // equivalent. Overlaps are allowed between FromCIDR and FromCIDRSet. 97 // 98 // Example: 99 // Any endpoint with the label "app=my-legacy-pet" is allowed to receive 100 // connections from 10.0.0.0/8 except from IPs in subnet 10.96.0.0/12. 101 // 102 // +optional 103 FromCIDRSet CIDRRuleSlice `json:"fromCIDRSet,omitempty"` 104 105 // FromEntities is a list of special entities which the endpoint subject 106 // to the rule is allowed to receive connections from. Supported entities are 107 // `world`, `cluster` and `host` 108 // 109 // +optional 110 FromEntities EntitySlice `json:"fromEntities,omitempty"` 111 112 // TODO: Move this to the policy package (https://github.com/cilium/cilium/issues/8353) 113 aggregatedSelectors EndpointSelectorSlice 114 } 115 116 // SetAggregatedSelectors creates a single slice containing all of the following 117 // fields within the IngressRule, converted to EndpointSelector, to be stored 118 // within the IngressRule for easy lookup while performing policy evaluation 119 // for the rule: 120 // * FromEntities 121 // * FromCIDR 122 // * FromCIDRSet 123 // 124 // FromEndpoints is not aggregated due to requirement folding in 125 // GetSourceEndpointSelectorsWithRequirements() 126 func (i *IngressRule) SetAggregatedSelectors() { 127 res := make(EndpointSelectorSlice, 0, len(i.FromEntities)+len(i.FromCIDR)+len(i.FromCIDRSet)) 128 res = append(res, i.FromEntities.GetAsEndpointSelectors()...) 129 res = append(res, i.FromCIDR.GetAsEndpointSelectors()...) 130 res = append(res, i.FromCIDRSet.GetAsEndpointSelectors()...) 131 // Goroutines can race setting this, but they will all compute 132 // the same result, so it does not matter. 133 i.aggregatedSelectors = res 134 } 135 136 // GetSourceEndpointSelectorsWithRequirements returns a slice of endpoints selectors covering 137 // all L3 source selectors of the ingress rule 138 func (i *IngressRule) GetSourceEndpointSelectorsWithRequirements(requirements []metav1.LabelSelectorRequirement) EndpointSelectorSlice { 139 if i.aggregatedSelectors == nil { 140 i.SetAggregatedSelectors() 141 } 142 res := make(EndpointSelectorSlice, 0, len(i.FromEndpoints)+len(i.aggregatedSelectors)) 143 if len(requirements) > 0 && len(i.FromEndpoints) > 0 { 144 for idx := range i.FromEndpoints { 145 sel := *i.FromEndpoints[idx].DeepCopy() 146 sel.MatchExpressions = append(sel.MatchExpressions, requirements...) 147 sel.SyncRequirementsWithLabelSelector() 148 // Even though this string is deep copied, we need to override it 149 // because we are updating the contents of the MatchExpressions. 150 sel.cachedLabelSelectorString = sel.LabelSelector.String() 151 res = append(res, sel) 152 } 153 } else { 154 res = append(res, i.FromEndpoints...) 155 } 156 157 return append(res, i.aggregatedSelectors...) 158 } 159 160 // IsLabelBased returns true whether the L3 source endpoints are selected based 161 // on labels, i.e. either by setting FromEndpoints or FromEntities, or not 162 // setting any From field. 163 func (i *IngressRule) IsLabelBased() bool { 164 return len(i.FromRequires) == 0 165 }