-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
rule.go
136 lines (117 loc) · 4.17 KB
/
rule.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
// Copyright 2016-2019 Authors of Cilium
//
// 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 api
import (
"context"
"reflect"
"github.com/cilium/cilium/pkg/labels"
)
// Rule is a policy rule which must be applied to all endpoints which match the
// labels contained in the endpointSelector
//
// Each rule is split into an ingress section which contains all rules
// applicable at ingress, and an egress section applicable at egress. For rule
// types such as `L4Rule` and `CIDR` which can be applied at both ingress and
// egress, both ingress and egress side have to either specifically allow the
// connection or one side has to be omitted.
//
// Either ingress, egress, or both can be provided. If both ingress and egress
// are omitted, the rule has no effect.
type Rule struct {
// EndpointSelector selects all endpoints which should be subject to
// this rule. Cannot be empty.
EndpointSelector EndpointSelector `json:"endpointSelector"`
// Ingress is a list of IngressRule which are enforced at ingress.
// If omitted or empty, this rule does not apply at ingress.
//
// +optional
Ingress []IngressRule `json:"ingress,omitempty"`
// Egress is a list of EgressRule which are enforced at egress.
// If omitted or empty, this rule does not apply at egress.
//
// +optional
Egress []EgressRule `json:"egress,omitempty"`
// Labels is a list of optional strings which can be used to
// re-identify the rule or to store metadata. It is possible to lookup
// or delete strings based on labels. Labels are not required to be
// unique, multiple rules can have overlapping or identical labels.
//
// +optional
Labels labels.LabelArray `json:"labels,omitempty"`
// Description is a free form string, it can be used by the creator of
// the rule to store human readable explanation of the purpose of this
// rule. Rules cannot be identified by comment.
//
// +optional
Description string `json:"description,omitempty"`
}
// NewRule builds a new rule with no selector and no policy.
func NewRule() *Rule {
return &Rule{}
}
// DeepEquals returns true if the specified rule is deeply the same.
func (r *Rule) DeepEquals(r2 *Rule) bool {
if reflect.DeepEqual(r, r2) {
return true
}
return false
}
// WithEndpointSelector configures the Rule with the specified selector.
func (r *Rule) WithEndpointSelector(es EndpointSelector) *Rule {
r.EndpointSelector = es
return r
}
// WithIngressRules configures the Rule with the specified rules.
func (r *Rule) WithIngressRules(rules []IngressRule) *Rule {
r.Ingress = rules
return r
}
// WithEgressRules configures the Rule with the specified rules.
func (r *Rule) WithEgressRules(rules []EgressRule) *Rule {
r.Egress = rules
return r
}
// WithLabels configures the Rule with the specified labels metadata.
func (r *Rule) WithLabels(labels labels.LabelArray) *Rule {
r.Labels = labels
return r
}
// WithDescription configures the Rule with the specified description metadata.
func (r *Rule) WithDescription(desc string) *Rule {
r.Description = desc
return r
}
// RequiresDerivative it return true if the rule has a derivative rule.
func (r *Rule) RequiresDerivative() bool {
for _, rule := range r.Egress {
if rule.RequiresDerivative() {
return true
}
}
return false
}
// CreateDerivative will return a new Rule with the new data based gather
// by the rules that autogenerated new Rule
func (r *Rule) CreateDerivative(ctx context.Context) (*Rule, error) {
newRule := r.DeepCopy()
newRule.Egress = []EgressRule{}
for _, egressRule := range r.Egress {
derivativeEgressRule, err := egressRule.CreateDerivative(ctx)
if err != nil {
return newRule, err
}
newRule.Egress = append(newRule.Egress, *derivativeEgressRule)
}
return newRule, nil
}