forked from crossplane-contrib/provider-cloudflare
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rule_types.go
178 lines (145 loc) · 6.24 KB
/
rule_types.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
Copyright 2021 The Crossplane 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 v1alpha1
import (
"context"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/crossplane/crossplane-runtime/pkg/reference"
zone "github.com/benagricola/provider-cloudflare/apis/zone/v1alpha1"
"github.com/pkg/errors"
)
// RuleBypassProduct identifies a product that will be
// bypassed when the bypass action is used.
// +kubebuilder:validation:Enum=zoneLockdown;uaBlock;bic;hot;securityLevel;rateLimit;waf
type RuleBypassProduct string
// RuleParameters are the configurable fields of a Rule.
type RuleParameters struct {
// Action is the action to apply to a matching request.
// +kubebuilder:validation:Enum=block;challenge;js_challenge;allow;log;bypass
Action string `json:"action"`
// BypassProducts lists the products by identifier that should be
// bypassed when the bypass action is used.
// +optional
BypassProducts []RuleBypassProduct `json:"bypassProducts,omitempty"`
// Description is a human readable description of this rule.
// +kubebuilder:validation:MaxLength=500
// +optional
Description *string `json:"description,omitempty"`
// Filter refers to a Filter ID that this rule uses to match
// traffic.
// +optional
Filter *string `json:"filter,omitempty"`
// FilterRef references the filter object this rule uses to match traffic.
// +optional
FilterRef *xpv1.Reference `json:"filterRef,omitempty"`
// FilterSelector selects the filter object this rule uses to match traffic.
// +optional
FilterSelector *xpv1.Selector `json:"filterSelector,omitempty"`
// Paused indicates if this rule is paused or not.
// +optional
Paused *bool `json:"paused,omitempty"`
// NOTE(bagricola): Cloudflare's API documentation says this has a range of
// 0 - 2147483647 - but in reality, you get an error trying to set it to 0 and
// it seems you can set it HIGHER than 2147483647.
// I'm going off their API documentation here, except setting the minimum to
// 1 to avoid the 400 error that causes.
// Priority is the priority of this Firewall Rule, that controls
// processing order. Rules without a priority set will be sequenced
// after rules with a priority set.
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=2147483647
// +optional
Priority *int32 `json:"priority,omitempty"`
// ZoneID this Firewall Rule is for.
// +immutable
// +optional
Zone *string `json:"zone,omitempty"`
// ZoneRef references the zone object this Firewall Rule is for.
// +immutable
// +optional
ZoneRef *xpv1.Reference `json:"zoneRef,omitempty"`
// ZoneSelector selects the zone object this Firewall Rule is for.
// +immutable
// +optional
ZoneSelector *xpv1.Selector `json:"zoneSelector,omitempty"`
}
// RuleObservation is the observable fields of a Rule.
type RuleObservation struct{}
// A RuleSpec defines the desired state of a Rule.
type RuleSpec struct {
xpv1.ResourceSpec `json:",inline"`
ForProvider RuleParameters `json:"forProvider"`
}
// A RuleStatus represents the observed state of a Rule.
type RuleStatus struct {
xpv1.ResourceStatus `json:",inline"`
AtProvider RuleObservation `json:"atProvider,omitempty"`
}
// +kubebuilder:object:root=true
// A Rule applies a firewall filter in a particular order to a Zone.
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status"
// +kubebuilder:printcolumn:name="SYNCED",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status"
// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp"
// +kubebuilder:resource:scope=Cluster,categories={crossplane,managed,cloudflare}
type Rule struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec RuleSpec `json:"spec"`
Status RuleStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// RuleList contains a list of Rule
type RuleList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Rule `json:"items"`
}
// ResolveReferences of this Rule
func (fr *Rule) ResolveReferences(ctx context.Context, c client.Reader) error {
r := reference.NewAPIResolver(c, fr)
// Resolve spec.forProvider.zone
rsp, err := r.Resolve(ctx, reference.ResolutionRequest{
CurrentValue: reference.FromPtrValue(fr.Spec.ForProvider.Zone),
Reference: fr.Spec.ForProvider.ZoneRef,
Selector: fr.Spec.ForProvider.ZoneSelector,
To: reference.To{Managed: &zone.Zone{}, List: &zone.ZoneList{}},
Extract: reference.ExternalName(),
})
if err != nil {
return errors.Wrap(err, "spec.forProvider.zone")
}
fr.Spec.ForProvider.Zone = reference.ToPtrValue(rsp.ResolvedValue)
fr.Spec.ForProvider.ZoneRef = rsp.ResolvedReference
// Resolve spec.forProvider.filter
// NOTE(bagricola): It is _possible_ for poor implementation during usage
// of this resource to resolve a Filter that is not on the Zone we resolved
// above. We rely on the Cloudflare API returning an error here, in that it
// should reject our creation attempt if the Filter ID we pass is not
// valid on the Zone in question.
rsp, err = r.Resolve(ctx, reference.ResolutionRequest{
CurrentValue: reference.FromPtrValue(fr.Spec.ForProvider.Filter),
Reference: fr.Spec.ForProvider.FilterRef,
Selector: fr.Spec.ForProvider.FilterSelector,
To: reference.To{Managed: &Filter{}, List: &FilterList{}},
Extract: reference.ExternalName(),
})
if err != nil {
return errors.Wrap(err, "spec.forProvider.filter")
}
fr.Spec.ForProvider.Filter = reference.ToPtrValue(rsp.ResolvedValue)
fr.Spec.ForProvider.FilterRef = rsp.ResolvedReference
return nil
}