Skip to content

Commit e1268f7

Browse files
committed
Additional validation for OpenFaaS CE scaling
A few users who haven't read the docs carefully enough were trying to use OpenFaaS Pro scaling labels with the CE edition. This improves the developer experience by showing them the mistake, so they can fix it instead of raising an issue and creating noise. The docs cover both scaling approaches clearly along with their labels. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent 5fcd08d commit e1268f7

File tree

3 files changed

+160
-4
lines changed

3 files changed

+160
-4
lines changed

pkg/handlers/deploy.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,10 @@ func makeDeploymentSpec(request types.FunctionDeployment, existingSecrets map[st
150150

151151
nodeSelector := createSelector(request.Constraints)
152152

153-
resources, resourceErr := createResources(request)
153+
resources, err := createResources(request)
154154

155-
if resourceErr != nil {
156-
return nil, resourceErr
155+
if err != nil {
156+
return nil, err
157157
}
158158

159159
var imagePullPolicy apiv1.PullPolicy

pkg/handlers/validate.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ package handlers
77
import (
88
"fmt"
99
"regexp"
10+
"strconv"
1011

1112
types "github.com/openfaas/faas-provider/types"
1213
)
1314

1415
// Regex for RFC-1123 validation:
15-
// k8s.io/kubernetes/pkg/util/validation/validation.go
16+
//
17+
// k8s.io/kubernetes/pkg/util/validation/validation.go
1618
var validDNS = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`)
1719

1820
// validates that the service name is valid for Kubernetes
@@ -41,5 +43,51 @@ func ValidateDeployRequest(request *types.FunctionDeployment) error {
4143
return fmt.Errorf("image: is required")
4244
}
4345

46+
if err := validateScalingLabels(request); err != nil {
47+
return err
48+
}
49+
50+
return nil
51+
}
52+
53+
func validateScalingLabels(request *types.FunctionDeployment) error {
54+
if request.Labels == nil {
55+
return nil
56+
}
57+
58+
labels := *request.Labels
59+
if v, ok := labels["com.openfaas.scale.zero"]; ok {
60+
if v == "true" {
61+
return fmt.Errorf("com.openfaas.scale.zero not available for Community Edition")
62+
}
63+
}
64+
if _, ok := labels["com.openfaas.scale.zero-duration"]; ok {
65+
return fmt.Errorf("com.openfaas.scale.zero-duration not available for Community Edition")
66+
}
67+
68+
if _, ok := labels["com.openfaas.scale.target"]; ok {
69+
return fmt.Errorf("com.openfaas.scale.target not available for Community Edition")
70+
}
71+
72+
if _, ok := labels["com.openfaas.scale.type"]; ok {
73+
return fmt.Errorf("com.openfaas.scale.type not available for Community Edition")
74+
}
75+
76+
if v, ok := labels["com.openfaas.scale.max"]; ok {
77+
if vv, err := strconv.Atoi(v); err == nil {
78+
if vv > MaxReplicas {
79+
return fmt.Errorf("com.openfaas.scale.max is set too high for Community Edition")
80+
}
81+
}
82+
}
83+
84+
if v, ok := labels["com.openfaas.scale.min"]; ok {
85+
if vv, err := strconv.Atoi(v); err == nil {
86+
if vv > MaxReplicas {
87+
return fmt.Errorf("com.openfaas.scale.min is set too high for Community Edition")
88+
}
89+
}
90+
}
91+
4492
return nil
4593
}

pkg/handlers/validate_test.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package handlers
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/openfaas/faas-provider/types"
8+
)
9+
10+
func Test_validateScalingLabels(t *testing.T) {
11+
12+
testCases := []struct {
13+
Name string
14+
Labels map[string]string
15+
Err error
16+
}{
17+
{
18+
Name: "empty labels",
19+
Labels: map[string]string{},
20+
Err: nil,
21+
},
22+
{
23+
Name: "com.openfaas.scale.zero",
24+
Labels: map[string]string{
25+
"com.openfaas.scale.zero": "true",
26+
},
27+
Err: fmt.Errorf("com.openfaas.scale.zero not available for Community Edition"),
28+
},
29+
{
30+
Name: "com.openfaas.scale.zero-duration",
31+
Labels: map[string]string{
32+
"com.openfaas.scale.zero-duration": "15m",
33+
},
34+
Err: fmt.Errorf("com.openfaas.scale.zero-duration not available for Community Edition"),
35+
},
36+
{
37+
Name: "com.openfaas.scale.target",
38+
Labels: map[string]string{
39+
"com.openfaas.scale.target": "10",
40+
},
41+
Err: fmt.Errorf("com.openfaas.scale.target not available for Community Edition"),
42+
},
43+
{
44+
Name: "com.openfaas.scale.type",
45+
Labels: map[string]string{
46+
"com.openfaas.scale.type": "cpu",
47+
},
48+
Err: fmt.Errorf("com.openfaas.scale.type not available for Community Edition"),
49+
},
50+
{
51+
Name: "com.openfaas.scale.min allowed",
52+
Labels: map[string]string{
53+
"com.openfaas.scale.min": "1",
54+
},
55+
},
56+
{
57+
Name: "com.openfaas.scale.min allowed within range",
58+
Labels: map[string]string{
59+
"com.openfaas.scale.min": "5",
60+
},
61+
},
62+
{
63+
Name: "com.openfaas.scale.max allowed within range",
64+
Labels: map[string]string{
65+
"com.openfaas.scale.max": "5",
66+
},
67+
},
68+
{
69+
Name: "com.openfaas.scale.min allowed within range",
70+
Labels: map[string]string{
71+
"com.openfaas.scale.min": "5",
72+
},
73+
},
74+
{
75+
Name: "com.openfaas.scale.max fails outside of range",
76+
Labels: map[string]string{
77+
"com.openfaas.scale.max": "6",
78+
},
79+
Err: fmt.Errorf("com.openfaas.scale.max is set too high for Community Edition"),
80+
},
81+
{
82+
Name: "com.openfaas.scale.min fails outside of range",
83+
Labels: map[string]string{
84+
"com.openfaas.scale.min": "6",
85+
},
86+
Err: fmt.Errorf("com.openfaas.scale.min is set too high for Community Edition"),
87+
},
88+
}
89+
90+
for _, tc := range testCases {
91+
t.Run(tc.Name, func(t *testing.T) {
92+
gotErr := validateScalingLabels(&types.FunctionDeployment{Labels: &tc.Labels})
93+
got := fmt.Errorf("")
94+
if gotErr != nil {
95+
got = gotErr
96+
}
97+
want := fmt.Errorf("")
98+
if tc.Err != nil {
99+
want = tc.Err
100+
}
101+
102+
if got.Error() != want.Error() {
103+
t.Errorf("got: %v, want: %v", got, want)
104+
}
105+
})
106+
}
107+
108+
}

0 commit comments

Comments
 (0)