-
Notifications
You must be signed in to change notification settings - Fork 3
/
validate.go
160 lines (139 loc) · 5.94 KB
/
validate.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
package main
import (
"net"
"k8s.io/apimachinery/pkg/util/validation/field"
"github.com/crossplane/function-sdk-go/resource"
"github.com/upbound/function-cidr/input/v1beta1"
)
// ValidatePrefixParameter validates prefix parameter
func ValidatePrefixParameter(prefix, prefixField string, oxr *resource.Composite) *field.Error {
if len(prefix) > 0 && len(prefixField) > 0 {
return field.Required(field.NewPath("parameters"), "specify only one of prefix or prefixfield to avoid ambiguous function input")
}
if prefix == "" {
if prefixField == "" {
return field.Required(field.NewPath("parameters"), "either prefix or prefixfield function input is required")
}
oxrPrefix, err := oxr.Resource.GetString(prefixField)
prefix = oxrPrefix
if err != nil {
return field.Required(field.NewPath("parameters"), "cannot get prefix at prefixfield "+prefixField)
}
}
_, _, err := net.ParseCIDR(prefix)
if err != nil {
return field.Required(field.NewPath("parameters"), "invalid CIDR prefix address "+prefix)
}
return nil
}
// ValidateCidrHostParameters validates the Parameters object
// in the context of cidrhost
func ValidateCidrHostParameters(p *v1beta1.Parameters, oxr resource.Composite) *field.Error {
if p.HostNum > 0 && len(p.HostNumField) > 0 {
return field.Required(field.NewPath("parameters"), "specify only one of hostnum or hostnumfield to avoid ambiguous function input")
}
hostNum := p.HostNum
if hostNum == 0 {
if p.HostNumField == "" {
return field.Required(field.NewPath("parameters"), "either hostnum or hostnumfield function input is required")
}
_, err := oxr.Resource.GetInteger(p.HostNumField)
if err != nil {
return field.Required(field.NewPath("parameters"), "cannot get hostnum at hostnumfield "+p.HostNumField)
}
}
return nil
}
// ValidateCidrSubnetParameters validates the Parameters object
// in the context of cidrsubnet
func ValidateCidrSubnetParameters(p *v1beta1.Parameters) *field.Error {
if len(p.NewBits) > 0 && len(p.NewBitsField) > 0 {
return field.Required(field.NewPath("parameters"), "specify only one of newbits or newbitsfield to avoid ambiguous function input")
}
if len(p.NewBits) == 0 && p.NewBitsField == "" {
return field.Required(field.NewPath("parameters"), "either newbits or newbitsfield function input is required")
}
if p.NewBitsField == "" {
if len(p.NewBits) != 1 {
return field.Required(field.NewPath("parameters"), "cidrFunc cidrsubnet requires exactly 1 parameter in the array")
}
}
if p.NetNum > 0 && len(p.NetNumField) > 0 {
return field.Required(field.NewPath("parameters"), "cidrFunc cidrsubnet requires either one of netnum or netnumfield")
}
return nil
}
// ValidateCidrSubnetsParameters validates the Parameters object
// in the context of cidrsubnet
func ValidateCidrSubnetsParameters(p *v1beta1.Parameters, oxr resource.Composite) *field.Error {
var newBits []int
if len(p.NewBits) > 0 && len(p.NewBitsField) > 0 {
return field.Required(field.NewPath("parameters"), "cidrFunc cidrsubnets requires either one of newbits or newbitsfield")
}
if len(p.NewBitsField) > 0 {
err := oxr.Resource.GetValueInto(p.NewBitsField, &newBits)
if err != nil {
return field.Required(field.NewPath("parameters"), "cannot get newbits at newbitsfield "+p.NewBitsField)
}
}
return nil
}
// ValidateCidrSubnetloopParameters validates the Parameters object
// in the context of cidrsubnetloop
func ValidateCidrSubnetloopParameters(p *v1beta1.Parameters) *field.Error {
if p.NetNumCount > 0 && len(p.NetNumCountField) > 0 {
// only one of netnumcount or NetNumCountField
errStr := "cidrFunc cidrsubnetloop requires either one of netnumcount or netnumcountfield, "
errStr += "but only if nonetnumitems or netnumitemsfield have been specified"
return field.Required(field.NewPath("parameters"), errStr)
}
if len(p.NetNumItems) > 0 && len(p.NetNumItemsField) > 0 {
// only one of netnumitems or netnumitemsfield
errStr := "cidrFunc cidrsubnetloop requires either one of netnumitems or netnumitemsfield, "
errStr += "but only if nonetnumcount or netnumcountfield have been specified"
return field.Required(field.NewPath("parameters"), errStr)
}
netNumCountSpecified := bool(p.NetNumCount > 0 || len(p.NetNumCountField) > 0)
netNumItemsSpecified := bool(len(p.NetNumItems) > 0 || len(p.NetNumItemsField) > 0)
if netNumCountSpecified && netNumItemsSpecified {
// only either netnumcount or items
errStr := "cidrFunc cidrsubnetloop requires either one of netnumitems or netnumitemsfield, "
errStr += "or mutually exclusive one of netnumcount or netnumcountfield, but not both counts and items"
return field.Required(field.NewPath("parameters"), errStr)
}
if len(p.NewBits) > 0 && len(p.NewBitsField) > 0 {
return field.Required(field.NewPath("parameters"), "cidrFunc cidrsubnetloop requires either one of newbits or newbitsfield")
}
if p.Offset > 0 && len(p.OffsetField) > 0 {
return field.Required(field.NewPath("parameters"), "cidrFunc cidrsubnetloop requires either one of offset or offsetfield")
}
return nil
}
// ValidateParameters validates the Parameters object.
func ValidateParameters(p *v1beta1.Parameters, oxr *resource.Composite) *field.Error {
if p.CidrFunc == "" {
return field.Required(field.NewPath("parameters"), "cidrFunc is required")
}
fieldError := ValidatePrefixParameter(p.Prefix, p.PrefixField, oxr)
if fieldError != nil {
return fieldError
}
cidrFunc, err := oxr.Resource.GetString(p.CidrFunc)
if err != nil {
return field.Required(field.NewPath("parameters"), "cidrFunc is required")
}
switch cidrFunc {
case "cidrhost":
return ValidateCidrHostParameters(p, *oxr)
case "cidrnetmask":
return nil // cidrnetmask only relies on prefix which was checked above
case "cidrsubnet":
return ValidateCidrSubnetParameters(p)
case "cidrsubnets":
return ValidateCidrSubnetsParameters(p, *oxr)
case "cidrsubnetloop":
return ValidateCidrSubnetloopParameters(p)
default:
return field.Required(field.NewPath("parameters"), "unexpected cidrFunc "+p.CidrFunc)
}
}