Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
c20efb6b
Commit
c20efb6b
authored
Mar 20, 2015
by
gmarek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add validation for Endpoints
parent
e44ec497
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
217 additions
and
10 deletions
+217
-10
validation.go
pkg/api/validation/validation.go
+39
-5
validation_test.go
pkg/api/validation/validation_test.go
+174
-1
validation.go
pkg/util/validation.go
+2
-2
validation_test.go
pkg/util/validation_test.go
+2
-2
No files found.
pkg/api/validation/validation.go
View file @
c20efb6b
...
...
@@ -900,7 +900,7 @@ func ValidateService(service *api.Service) errs.ValidationErrorList {
for
_
,
ip
:=
range
service
.
Spec
.
PublicIPs
{
if
ip
==
"0.0.0.0"
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"spec.publicIPs"
,
ip
,
"is not an IP address"
))
}
else
if
util
.
IsValidIP
(
ip
)
&&
net
.
ParseIP
(
ip
)
.
IsLoopback
()
{
}
else
if
util
.
IsValidIP
v4
(
ip
)
&&
net
.
ParseIP
(
ip
)
.
IsLoopback
()
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"spec.publicIPs"
,
ip
,
"publicIP cannot be a loopback"
))
}
}
...
...
@@ -1276,17 +1276,51 @@ func validateEndpointSubsets(subsets []api.EndpointSubset) errs.ValidationErrorL
if
len
(
ss
.
Ports
)
==
0
{
ssErrs
=
append
(
ssErrs
,
errs
.
NewFieldRequired
(
"ports"
))
}
// TODO: validate each address and port
for
addr
:=
range
ss
.
Addresses
{
ssErrs
=
append
(
ssErrs
,
validateEndpointAddress
(
&
ss
.
Addresses
[
addr
])
.
PrefixIndex
(
addr
)
.
Prefix
(
"addresses"
)
...
)
}
for
port
:=
range
ss
.
Ports
{
ssErrs
=
append
(
ssErrs
,
validateEndpointPort
(
&
ss
.
Ports
[
port
],
len
(
ss
.
Ports
)
>
1
)
.
PrefixIndex
(
port
)
.
Prefix
(
"ports"
)
...
)
}
allErrs
=
append
(
allErrs
,
ssErrs
.
PrefixIndex
(
i
)
...
)
}
return
allErrs
}
func
validateEndpointAddress
(
address
*
api
.
EndpointAddress
)
errs
.
ValidationErrorList
{
allErrs
:=
errs
.
ValidationErrorList
{}
if
!
util
.
IsValidIPv4
(
address
.
IP
)
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"ip"
,
address
.
IP
,
"invalid IPv4 address"
))
}
return
allErrs
}
func
validateEndpointPort
(
port
*
api
.
EndpointPort
,
requireName
bool
)
errs
.
ValidationErrorList
{
allErrs
:=
errs
.
ValidationErrorList
{}
if
requireName
&&
port
.
Name
==
""
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldRequired
(
"name"
))
}
else
if
port
.
Name
!=
""
{
if
!
util
.
IsDNS1123Label
(
port
.
Name
)
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"name"
,
port
.
Name
,
dns1123LabelErrorMsg
))
}
}
if
!
util
.
IsValidPortNum
(
port
.
Port
)
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldInvalid
(
"port"
,
port
.
Port
,
portRangeErrorMsg
))
}
if
len
(
port
.
Protocol
)
==
0
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldRequired
(
"protocol"
))
}
else
if
!
supportedPortProtocols
.
Has
(
strings
.
ToUpper
(
string
(
port
.
Protocol
)))
{
allErrs
=
append
(
allErrs
,
errs
.
NewFieldNotSupported
(
"protocol"
,
port
.
Protocol
))
}
return
allErrs
}
// ValidateEndpointsUpdate tests to make sure an endpoints update can be applied.
func
ValidateEndpointsUpdate
(
oldEndpoints
*
api
.
Endpoints
,
e
ndpoints
*
api
.
Endpoints
)
errs
.
ValidationErrorList
{
func
ValidateEndpointsUpdate
(
oldEndpoints
,
newE
ndpoints
*
api
.
Endpoints
)
errs
.
ValidationErrorList
{
allErrs
:=
errs
.
ValidationErrorList
{}
allErrs
=
append
(
allErrs
,
ValidateObjectMetaUpdate
(
&
oldEndpoints
.
ObjectMeta
,
&
e
ndpoints
.
ObjectMeta
)
.
Prefix
(
"metadata"
)
...
)
allErrs
=
append
(
allErrs
,
validateEndpointSubsets
(
e
ndpoints
.
Subsets
)
.
Prefix
(
"subsets"
)
...
)
allErrs
=
append
(
allErrs
,
ValidateObjectMetaUpdate
(
&
oldEndpoints
.
ObjectMeta
,
&
newE
ndpoints
.
ObjectMeta
)
.
Prefix
(
"metadata"
)
...
)
allErrs
=
append
(
allErrs
,
validateEndpointSubsets
(
newE
ndpoints
.
Subsets
)
.
Prefix
(
"subsets"
)
...
)
return
allErrs
}
pkg/api/validation/validation_test.go
View file @
c20efb6b
...
...
@@ -2812,5 +2812,178 @@ func TestValidateSecret(t *testing.T) {
}
func
TestValidateEndpoints
(
t
*
testing
.
T
)
{
// TODO: implement this
successCases
:=
map
[
string
]
api
.
Endpoints
{
"simple endpoint"
:
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.1.1"
},
{
IP
:
"10.10.2.2"
}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
8675
,
Protocol
:
"TCP"
},
{
Name
:
"b"
,
Port
:
309
,
Protocol
:
"TCP"
}},
},
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.3.3"
}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
93
,
Protocol
:
"TCP"
},
{
Name
:
"b"
,
Port
:
76
,
Protocol
:
"TCP"
}},
},
},
},
"empty subsets"
:
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
},
"no name required for singleton port"
:
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.1.1"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
8675
,
Protocol
:
"TCP"
}},
},
},
},
}
for
k
,
v
:=
range
successCases
{
if
errs
:=
ValidateEndpoints
(
&
v
);
len
(
errs
)
!=
0
{
t
.
Errorf
(
"Expected success for %s, got %v"
,
k
,
errs
)
}
}
errorCases
:=
map
[
string
]
struct
{
endpoints
api
.
Endpoints
errorType
fielderrors
.
ValidationErrorType
errorDetail
string
}{
"missing namespace"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
}},
errorType
:
"FieldValueRequired"
,
},
"missing name"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Namespace
:
"namespace"
}},
errorType
:
"FieldValueRequired"
,
},
"invalid namespace"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"no@#invalid.;chars
\"
allowed"
}},
errorType
:
"FieldValueInvalid"
,
errorDetail
:
dnsSubdomainErrorMsg
,
},
"invalid name"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"-_Invliad^&Characters"
,
Namespace
:
"namespace"
}},
errorType
:
"FieldValueInvalid"
,
errorDetail
:
dnsSubdomainErrorMsg
,
},
"empty addresses"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
93
,
Protocol
:
"TCP"
}},
},
},
},
errorType
:
"FieldValueRequired"
,
},
"empty ports"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.3.3"
}},
},
},
},
errorType
:
"FieldValueRequired"
,
},
"invalid IP"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"2001:0db8:85a3:0042:1000:8a2e:0370:7334"
}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
93
,
Protocol
:
"TCP"
}},
},
},
},
errorType
:
"FieldValueInvalid"
,
errorDetail
:
"invalid IPv4 address"
,
},
"Multiple ports, one without name"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.1.1"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
8675
,
Protocol
:
"TCP"
},
{
Name
:
"b"
,
Port
:
309
,
Protocol
:
"TCP"
}},
},
},
},
errorType
:
"FieldValueRequired"
,
},
"Invalid port number"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.1.1"
}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
66000
,
Protocol
:
"TCP"
}},
},
},
},
errorType
:
"FieldValueInvalid"
,
errorDetail
:
portRangeErrorMsg
,
},
"Invalid protocol"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.1.1"
}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
93
,
Protocol
:
"Protocol"
}},
},
},
},
errorType
:
"FieldValueNotSupported"
,
},
"Address missing IP"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
93
,
Protocol
:
"TCP"
}},
},
},
},
errorType
:
"FieldValueInvalid"
,
errorDetail
:
"invalid IPv4 address"
,
},
"Port missing number"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.1.1"
}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Protocol
:
"TCP"
}},
},
},
},
errorType
:
"FieldValueInvalid"
,
errorDetail
:
portRangeErrorMsg
,
},
"Port missing protocol"
:
{
endpoints
:
api
.
Endpoints
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"mysvc"
,
Namespace
:
"namespace"
},
Subsets
:
[]
api
.
EndpointSubset
{
{
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"10.10.1.1"
}},
Ports
:
[]
api
.
EndpointPort
{{
Name
:
"a"
,
Port
:
93
}},
},
},
},
errorType
:
"FieldValueRequired"
,
},
}
for
k
,
v
:=
range
errorCases
{
if
errs
:=
ValidateEndpoints
(
&
v
.
endpoints
);
len
(
errs
)
==
0
||
errs
[
0
]
.
(
*
errors
.
ValidationError
)
.
Type
!=
v
.
errorType
||
errs
[
0
]
.
(
*
errors
.
ValidationError
)
.
Detail
!=
v
.
errorDetail
{
t
.
Errorf
(
"Expected error type %s with detail %s for %s, got %v"
,
v
.
errorType
,
v
.
errorDetail
,
k
,
errs
)
}
}
}
pkg/util/validation.go
View file @
c20efb6b
...
...
@@ -91,7 +91,7 @@ func IsValidPortNum(port int) bool {
return
0
<
port
&&
port
<
65536
}
// IsValidIP tests that the argument is a valid IPv4 address.
func
IsValidIP
(
value
string
)
bool
{
// IsValidIP
v4
tests that the argument is a valid IPv4 address.
func
IsValidIP
v4
(
value
string
)
bool
{
return
net
.
ParseIP
(
value
)
!=
nil
&&
net
.
ParseIP
(
value
)
.
To4
()
!=
nil
}
pkg/util/validation_test.go
View file @
c20efb6b
...
...
@@ -232,7 +232,7 @@ func TestIsValidIP(t *testing.T) {
"0.0.0.0"
,
}
for
_
,
val
:=
range
goodValues
{
if
!
IsValidIP
(
val
)
{
if
!
IsValidIP
v4
(
val
)
{
t
.
Errorf
(
"expected true for %q"
,
val
)
}
}
...
...
@@ -247,7 +247,7 @@ func TestIsValidIP(t *testing.T) {
"1.0.0.1."
,
}
for
_
,
val
:=
range
badValues
{
if
IsValidIP
(
val
)
{
if
IsValidIP
v4
(
val
)
{
t
.
Errorf
(
"expected false for %q"
,
val
)
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment