Skip to content

Commit 09d44a4

Browse files
committed
OpenFaaS CE updates
Config for: TerminationGracePeriod, custom ServiceAccounts and HTTP probe configuration, runtimeClass moves into OpenFaaS Pro. As per the docs, OpenFaaS CE is for open source developers. OpenFaaS Pro is for profit-seeking companies. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <[email protected]>
1 parent b777236 commit 09d44a4

File tree

9 files changed

+89
-316
lines changed

9 files changed

+89
-316
lines changed

pkg/controller/deployment.go

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"encoding/json"
66
"strings"
7-
"time"
87

98
"github.com/google/go-cmp/cmp"
109
faasv1 "github.com/openfaas/faas-netes/pkg/apis/openfaas/v1"
@@ -48,34 +47,6 @@ func newDeployment(
4847

4948
annotations := makeAnnotations(function)
5049

51-
var serviceAccount string
52-
53-
if function.Spec.Annotations != nil {
54-
annotations := *function.Spec.Annotations
55-
if val, ok := annotations["com.openfaas.serviceaccount"]; ok && len(val) > 0 {
56-
serviceAccount = val
57-
}
58-
}
59-
60-
// add 2s jitter to avoid a race condition between write_timeout and grace period
61-
jitter := time.Second * 2
62-
terminationGracePeriod := time.Second*30 + jitter
63-
64-
if function.Spec.Environment != nil {
65-
e := *function.Spec.Environment
66-
if v, ok := e["write_timeout"]; ok && len(v) > 0 {
67-
period, err := time.ParseDuration(v)
68-
if err != nil {
69-
glog.Warningf("Function %s failed to parse write_timeout: %s",
70-
function.Spec.Name, err.Error())
71-
}
72-
73-
terminationGracePeriod = period + jitter
74-
}
75-
}
76-
77-
terminationGracePeriodSeconds := int64(terminationGracePeriod.Seconds())
78-
7950
allowPrivilegeEscalation := false
8051

8152
deploymentSpec := &appsv1.Deployment{
@@ -119,8 +90,7 @@ func newDeployment(
11990
Annotations: annotations,
12091
},
12192
Spec: corev1.PodSpec{
122-
NodeSelector: nodeSelector,
123-
TerminationGracePeriodSeconds: &terminationGracePeriodSeconds,
93+
NodeSelector: nodeSelector,
12494
Containers: []corev1.Container{
12595
{
12696
Name: function.Spec.Name,
@@ -143,10 +113,6 @@ func newDeployment(
143113
},
144114
}
145115

146-
if len(serviceAccount) > 0 {
147-
deploymentSpec.Spec.Template.Spec.ServiceAccountName = serviceAccount
148-
}
149-
150116
factory.ConfigureReadOnlyRootFilesystem(function, deploymentSpec)
151117
factory.ConfigureContainerUserID(deploymentSpec)
152118

pkg/controller/deployment_test.go

Lines changed: 25 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -10,117 +10,46 @@ import (
1010
"k8s.io/client-go/kubernetes/fake"
1111
)
1212

13-
func Test_GracePeriodFromWriteTimeout(t *testing.T) {
14-
15-
scenarios := []struct {
16-
name string
17-
wantSeconds int64
18-
envs map[string]string
19-
}{
20-
{"grace period is the default", 32, map[string]string{}},
21-
{"grace period is set from write_timeout", 62, map[string]string{"write_timeout": "60s"}},
22-
}
23-
24-
for _, s := range scenarios {
25-
t.Run(s.name, func(t *testing.T) {
26-
27-
want := int64(s.wantSeconds)
28-
function := &faasv1.Function{
29-
ObjectMeta: metav1.ObjectMeta{
30-
Name: "alpine",
31-
},
32-
Spec: faasv1.FunctionSpec{
33-
Name: "alpine",
34-
Image: "ghcr.io/openfaas/alpine:latest",
35-
Annotations: &map[string]string{},
36-
ReadOnlyRootFilesystem: true,
37-
Environment: &s.envs},
38-
}
39-
40-
factory := NewFunctionFactory(fake.NewSimpleClientset(),
41-
k8s.DeploymentConfig{
42-
HTTPProbe: false,
43-
SetNonRootUser: true,
44-
LivenessProbe: &k8s.ProbeConfig{
45-
PeriodSeconds: 1,
46-
TimeoutSeconds: 3,
47-
InitialDelaySeconds: 0,
48-
},
49-
ReadinessProbe: &k8s.ProbeConfig{
50-
PeriodSeconds: 1,
51-
TimeoutSeconds: 3,
52-
InitialDelaySeconds: 0,
53-
},
54-
})
55-
56-
secrets := map[string]*corev1.Secret{}
57-
58-
deployment := newDeployment(function, nil, secrets, factory)
59-
got := deployment.Spec.Template.Spec.TerminationGracePeriodSeconds
60-
if got == nil {
61-
t.Errorf("TerminationGracePeriodSeconds not set, but want %d", want)
62-
t.Fail()
63-
return
64-
}
65-
66-
if want != *got {
67-
t.Errorf("TerminationGracePeriodSeconds want %d, but got %d", want, got)
68-
t.Fail()
69-
}
70-
})
71-
}
72-
}
73-
74-
func Test_newDeployment_withHTTPProbe(t *testing.T) {
13+
func Test_newDeployment(t *testing.T) {
7514
function := &faasv1.Function{
7615
ObjectMeta: metav1.ObjectMeta{
7716
Name: "kubesec",
7817
},
7918
Spec: faasv1.FunctionSpec{
80-
Name: "kubesec",
81-
Image: "docker.io/kubesec/kubesec",
82-
Annotations: &map[string]string{
83-
"com.openfaas.serviceaccount": "kubesec",
84-
},
19+
Name: "kubesec",
20+
Image: "docker.io/kubesec/kubesec",
21+
Annotations: &map[string]string{},
8522
ReadOnlyRootFilesystem: true,
8623
},
8724
}
88-
k8sConfig := k8s.DeploymentConfig{
89-
HTTPProbe: true,
90-
SetNonRootUser: true,
91-
LivenessProbe: &k8s.ProbeConfig{
92-
PeriodSeconds: 1,
93-
TimeoutSeconds: 3,
94-
InitialDelaySeconds: 0,
95-
},
96-
ReadinessProbe: &k8s.ProbeConfig{
97-
PeriodSeconds: 1,
98-
TimeoutSeconds: 3,
99-
InitialDelaySeconds: 0,
100-
},
101-
}
102-
factory := NewFunctionFactory(fake.NewSimpleClientset(), k8sConfig)
25+
26+
factory := NewFunctionFactory(fake.NewSimpleClientset(),
27+
k8s.DeploymentConfig{
28+
HTTPProbe: true,
29+
SetNonRootUser: true,
30+
LivenessProbe: &k8s.ProbeConfig{
31+
PeriodSeconds: 1,
32+
TimeoutSeconds: 3,
33+
InitialDelaySeconds: 0,
34+
},
35+
ReadinessProbe: &k8s.ProbeConfig{
36+
PeriodSeconds: 1,
37+
TimeoutSeconds: 3,
38+
InitialDelaySeconds: 0,
39+
},
40+
})
10341

10442
secrets := map[string]*corev1.Secret{}
10543

10644
deployment := newDeployment(function, nil, secrets, factory)
10745

108-
if deployment.Spec.Template.Spec.ServiceAccountName != "kubesec" {
109-
t.Errorf("ServiceAccountName should be %s", "kubesec")
110-
t.Fail()
111-
}
112-
113-
if deployment.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet == nil {
114-
t.Fatalf("ReadinessProbe's HTTPGet should not be nil")
115-
}
116-
11746
if deployment.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet.Path != "/_/health" {
11847
t.Errorf("Readiness probe should have HTTPGet handler set to %s", "/_/health")
11948
t.Fail()
12049
}
12150

122-
if deployment.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds != k8sConfig.ReadinessProbe.InitialDelaySeconds {
123-
t.Errorf("Liveness probe should have initial delay seconds set to %s", "2m")
51+
if deployment.Spec.Template.Spec.Containers[0].LivenessProbe.InitialDelaySeconds != 0 {
52+
t.Errorf("Liveness probe should have initial delay seconds set to %s", "0")
12453
t.Fail()
12554
}
12655

@@ -141,11 +70,9 @@ func Test_newDeployment_withExecProbe(t *testing.T) {
14170
Name: "kubesec",
14271
},
14372
Spec: faasv1.FunctionSpec{
144-
Name: "kubesec",
145-
Image: "docker.io/kubesec/kubesec",
146-
Annotations: &map[string]string{
147-
"com.openfaas.serviceaccount": "kubesec",
148-
},
73+
Name: "kubesec",
74+
Image: "docker.io/kubesec/kubesec",
75+
Annotations: &map[string]string{},
14976
ReadOnlyRootFilesystem: true,
15077
},
15178
}
@@ -170,11 +97,6 @@ func Test_newDeployment_withExecProbe(t *testing.T) {
17097

17198
deployment := newDeployment(function, nil, secrets, factory)
17299

173-
if deployment.Spec.Template.Spec.ServiceAccountName != "kubesec" {
174-
t.Errorf("ServiceAccountName should be %s", "kubesec")
175-
t.Fail()
176-
}
177-
178100
if deployment.Spec.Template.Spec.Containers[0].ReadinessProbe.HTTPGet != nil {
179101
t.Fatalf("ReadinessProbe's HTTPGet should be nil due to exec probe")
180102
}

pkg/handlers/deploy.go

Lines changed: 3 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"sort"
1515
"strconv"
1616
"strings"
17-
"time"
1817

1918
"github.com/openfaas/faas-netes/pkg/k8s"
2019

@@ -25,7 +24,6 @@ import (
2524
"k8s.io/apimachinery/pkg/api/resource"
2625
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2726
"k8s.io/apimachinery/pkg/util/intstr"
28-
glog "k8s.io/klog"
2927
)
3028

3129
// initialReplicasCount how many replicas to start of creating for a function
@@ -160,23 +158,11 @@ func makeDeploymentSpec(request types.FunctionDeployment, existingSecrets map[st
160158

161159
annotations := buildAnnotations(request)
162160

163-
var serviceAccount string
164-
165-
if request.Annotations != nil {
166-
annotations := *request.Annotations
167-
if val, ok := annotations["com.openfaas.serviceaccount"]; ok && len(val) > 0 {
168-
serviceAccount = val
169-
}
170-
}
171-
172161
probes, err := factory.MakeProbes(request)
173162
if err != nil {
174163
return nil, err
175164
}
176165

177-
terminationGracePeriodSeconds :=
178-
getTerminationGracePeriodSeconds(request.EnvVars, request.Service)
179-
180166
enableServiceLinks := false
181167
allowPrivilegeEscalation := false
182168

@@ -216,9 +202,7 @@ func makeDeploymentSpec(request types.FunctionDeployment, existingSecrets map[st
216202
Annotations: annotations,
217203
},
218204
Spec: apiv1.PodSpec{
219-
NodeSelector: nodeSelector,
220-
TerminationGracePeriodSeconds: &terminationGracePeriodSeconds,
221-
205+
NodeSelector: nodeSelector,
222206
Containers: []apiv1.Container{
223207
{
224208
Name: request.Service,
@@ -241,9 +225,8 @@ func makeDeploymentSpec(request types.FunctionDeployment, existingSecrets map[st
241225
},
242226
},
243227
},
244-
ServiceAccountName: serviceAccount,
245-
RestartPolicy: corev1.RestartPolicyAlways,
246-
DNSPolicy: corev1.DNSClusterFirst,
228+
RestartPolicy: corev1.RestartPolicyAlways,
229+
DNSPolicy: corev1.DNSClusterFirst,
247230
// EnableServiceLinks injects ENV vars about every other service within
248231
// the namespace.
249232
EnableServiceLinks: &enableServiceLinks,
@@ -262,26 +245,6 @@ func makeDeploymentSpec(request types.FunctionDeployment, existingSecrets map[st
262245
return deploymentSpec, nil
263246
}
264247

265-
func getTerminationGracePeriodSeconds(envVars map[string]string, name string) int64 {
266-
// add 2s jitter to avoid a race condition between write_timeout and grace period
267-
jitter := time.Second * 2
268-
terminationGracePeriod := time.Second*30 + jitter
269-
270-
if envVars != nil {
271-
if v, ok := envVars["write_timeout"]; ok && len(v) > 0 {
272-
period, err := time.ParseDuration(v)
273-
if err != nil {
274-
glog.Warningf("Function %s failed to parse write_timeout: %s",
275-
name, err.Error())
276-
}
277-
278-
terminationGracePeriod = period + jitter
279-
}
280-
}
281-
282-
return int64(terminationGracePeriod.Seconds())
283-
}
284-
285248
func makeServiceSpec(request types.FunctionDeployment, factory k8s.FunctionFactory) *corev1.Service {
286249

287250
serviceSpec := &corev1.Service{

pkg/handlers/deploy_test.go

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,6 @@ import (
1313
apiv1 "k8s.io/api/core/v1"
1414
)
1515

16-
func Test_GracePeriodFromWriteTimeout(t *testing.T) {
17-
18-
scenarios := []struct {
19-
name string
20-
wantSeconds int64
21-
envs map[string]string
22-
}{
23-
{"grace period is the default", 32, map[string]string{}},
24-
{"grace period is set from write_timeout", 62, map[string]string{"write_timeout": "60s"}},
25-
}
26-
27-
for _, s := range scenarios {
28-
t.Run(s.name, func(t *testing.T) {
29-
request := types.FunctionDeployment{Service: "testfunc", Image: "ghcr.io/openfaas/alpine:latest"}
30-
factory := k8s.NewFunctionFactory(fake.NewSimpleClientset(), k8s.DeploymentConfig{
31-
LivenessProbe: &k8s.ProbeConfig{},
32-
ReadinessProbe: &k8s.ProbeConfig{},
33-
SetNonRootUser: false,
34-
}, nil)
35-
36-
request.EnvVars = s.envs
37-
deployment, err := makeDeploymentSpec(request, map[string]*apiv1.Secret{}, factory)
38-
if err != nil {
39-
t.Errorf("unexpected makeDeploymentSpec error: %s", err.Error())
40-
}
41-
want := s.wantSeconds
42-
got := deployment.Spec.Template.Spec.TerminationGracePeriodSeconds
43-
44-
if got == nil {
45-
t.Fatalf("want: %d, got: nil", want)
46-
}
47-
48-
if *got != want {
49-
t.Errorf("TerminationGracePeriodSeconds want: %d, got: %d", want, *got)
50-
}
51-
52-
})
53-
}
54-
}
55-
5616
func Test_buildAnnotations_Empty_In_CreateRequest(t *testing.T) {
5717
request := types.FunctionDeployment{}
5818

pkg/handlers/update.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,6 @@ func updateDeploymentSpec(
137137

138138
deployment.Spec.Template.Spec.Containers[0].Resources = *resources
139139

140-
var serviceAccount string
141-
142-
if request.Annotations != nil {
143-
annotations := *request.Annotations
144-
if val, ok := annotations["com.openfaas.serviceaccount"]; ok && len(val) > 0 {
145-
serviceAccount = val
146-
}
147-
}
148-
149-
deployment.Spec.Template.Spec.ServiceAccountName = serviceAccount
150-
151140
secrets := k8s.NewSecretsClient(factory.Client)
152141
existingSecrets, err := secrets.GetSecrets(functionNamespace, request.Secrets)
153142
if err != nil {
@@ -168,11 +157,6 @@ func updateDeploymentSpec(
168157
deployment.Spec.Template.Spec.Containers[0].LivenessProbe = probes.Liveness
169158
deployment.Spec.Template.Spec.Containers[0].ReadinessProbe = probes.Readiness
170159

171-
terminationGracePeriodSeconds :=
172-
getTerminationGracePeriodSeconds(request.EnvVars, request.Service)
173-
174-
deployment.Spec.Template.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds
175-
176160
// compare the annotations from args to the cache copy of the deployment annotations
177161
// at this point we have already updated the annotations to the new value, if we
178162
// compare to that it will produce an empty list

0 commit comments

Comments
 (0)