Skip to content

Commit 5539cf4

Browse files
ewildealexellis
authored andcommitted
Add annotation support
Store stack.yml annotation meta data in deployment, pod, service and replicaset Relates to openfaas/faas#682 Signed-off-by: Edward Wilde <[email protected]>
1 parent e4a4477 commit 5539cf4

File tree

8 files changed

+172
-63
lines changed

8 files changed

+172
-63
lines changed

Gopkg.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
[[constraint]]
77
name = "github.com/openfaas/faas"
8-
version = "0.8.6"
8+
version = "0.8.8"
99

1010
[[constraint]]
1111
name = "github.com/openfaas/faas-provider"

handlers/deploy.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,15 @@ func makeDeploymentSpec(request requests.CreateFunctionRequest, existingSecrets
196196
imagePullPolicy = apiv1.PullAlways
197197
}
198198

199+
annotations := buildAnnotations(request)
199200
deploymentSpec := &v1beta1.Deployment{
200201
TypeMeta: metav1.TypeMeta{
201202
Kind: "Deployment",
202203
APIVersion: "extensions/v1beta1",
203204
},
204205
ObjectMeta: metav1.ObjectMeta{
205206
Name: request.Service,
207+
Annotations: annotations,
206208
},
207209
Spec: v1beta1.DeploymentSpec{
208210
Selector: &metav1.LabelSelector{
@@ -229,7 +231,7 @@ func makeDeploymentSpec(request requests.CreateFunctionRequest, existingSecrets
229231
ObjectMeta: metav1.ObjectMeta{
230232
Name: request.Service,
231233
Labels: labels,
232-
Annotations: map[string]string{"prometheus.io.scrape": "false"},
234+
Annotations: annotations,
233235
},
234236
Spec: apiv1.PodSpec{
235237
NodeSelector: nodeSelector,
@@ -267,14 +269,15 @@ func makeDeploymentSpec(request requests.CreateFunctionRequest, existingSecrets
267269
}
268270

269271
func makeServiceSpec(request requests.CreateFunctionRequest) *v1.Service {
272+
270273
serviceSpec := &v1.Service{
271274
TypeMeta: metav1.TypeMeta{
272275
Kind: "Service",
273276
APIVersion: "v1",
274277
},
275278
ObjectMeta: metav1.ObjectMeta{
276279
Name: request.Service,
277-
Annotations: map[string]string{"prometheus.io.scrape": "false"},
280+
Annotations: buildAnnotations(request),
278281
},
279282
Spec: v1.ServiceSpec{
280283
Type: v1.ServiceTypeClusterIP,
@@ -296,6 +299,18 @@ func makeServiceSpec(request requests.CreateFunctionRequest) *v1.Service {
296299
return serviceSpec
297300
}
298301

302+
func buildAnnotations(request requests.CreateFunctionRequest) map[string]string {
303+
var annotations map[string]string
304+
if request.Annotations != nil {
305+
annotations = *request.Annotations
306+
} else {
307+
annotations = map[string]string{}
308+
}
309+
310+
annotations["prometheus.io.scrape"] = "false"
311+
return annotations
312+
}
313+
299314
func buildEnvVars(request *requests.CreateFunctionRequest) []v1.EnvVar {
300315
envVars := []v1.EnvVar{}
301316

handlers/deploy_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,49 @@ func Test_configureReadOnlyRootFilesystem_Enabled_To_Enabled(t *testing.T) {
130130
readOnlyRootEnabled(t, deployment)
131131
}
132132

133+
func Test_buildAnnotations_Empty_In_CreateRequest(t *testing.T) {
134+
request := requests.CreateFunctionRequest{}
135+
136+
annotations := buildAnnotations(request)
137+
138+
if len(annotations) != 1 {
139+
t.Errorf("want: %d annotations got: %d", 1, len(annotations))
140+
}
141+
142+
v, ok := annotations["prometheus.io.scrape"]
143+
if !ok {
144+
t.Errorf("missing prometheus.io.scrape key")
145+
}
146+
147+
if v != "false" {
148+
t.Errorf("want: %s for annotation prometheus.io.scrape got: %s", "false", v)
149+
}
150+
}
151+
152+
func Test_buildAnnotations_From_CreateRequest(t *testing.T) {
153+
request := requests.CreateFunctionRequest{
154+
Annotations: &map[string]string{
155+
"date-created": "Wed 25 Jul 21:26:22 BST 2018",
156+
"foo" : "bar",
157+
},
158+
}
159+
160+
annotations := buildAnnotations(request)
161+
162+
if len(annotations) != 3 {
163+
t.Errorf("want: %d annotations got: %d", 1, len(annotations))
164+
}
165+
166+
v, ok := annotations["date-created"]
167+
if !ok {
168+
t.Errorf("missing date-created key")
169+
}
170+
171+
if v != "Wed 25 Jul 21:26:22 BST 2018" {
172+
t.Errorf("want: %s for annotation date-created got: %s", "Wed 25 Jul 21:26:22 BST 2018", v)
173+
}
174+
}
175+
133176
func readOnlyRootDisabled(t *testing.T, deployment *v1beta1.Deployment) {
134177
if len(deployment.Spec.Template.Spec.Volumes) != 0 {
135178
t.Error("Volumes should be empty if ReadOnlyRootFilesystem is false")

handlers/reader.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ func readFunction(item v1beta1.Deployment) *requests.Function {
9797
AvailableReplicas: uint64(item.Status.AvailableReplicas),
9898
InvocationCount: 0,
9999
Labels: &labels,
100+
Annotations: &item.Spec.Template.Annotations,
100101
}
101102

102103
return &function

handlers/update.go

Lines changed: 98 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -28,81 +28,123 @@ func MakeUpdateHandler(functionNamespace string, clientset *kubernetes.Clientset
2828
return
2929
}
3030

31-
getOpts := metav1.GetOptions{}
32-
33-
deployment, findDeployErr := clientset.ExtensionsV1beta1().
34-
Deployments(functionNamespace).
35-
Get(request.Service, getOpts)
31+
annotations := buildAnnotations(request)
32+
if err, status := updateDeploymentSpec(functionNamespace, clientset, request, annotations); err != nil {
33+
w.WriteHeader(status)
34+
w.Write([]byte(err.Error()))
35+
}
3636

37-
if findDeployErr != nil {
38-
w.WriteHeader(http.StatusNotFound)
39-
w.Write([]byte(findDeployErr.Error()))
40-
return
37+
if err, status := updateService(functionNamespace, clientset, request, annotations); err != nil {
38+
w.WriteHeader(status)
39+
w.Write([]byte(err.Error()))
4140
}
41+
}
42+
}
4243

43-
if len(deployment.Spec.Template.Spec.Containers) > 0 {
44-
deployment.Spec.Template.Spec.Containers[0].Image = request.Image
44+
func updateDeploymentSpec(
45+
functionNamespace string,
46+
clientset *kubernetes.Clientset,
47+
request requests.CreateFunctionRequest,
48+
annotations map[string]string) (err error, httpStatus int) {
49+
getOpts := metav1.GetOptions{}
4550

46-
// Disabling update support to prevent unexpected mutations of deployed functions,
47-
// since imagePullPolicy is now configurable. This could be reconsidered later depending
48-
// on desired behavior, but will need to be updated to take config.
49-
//deployment.Spec.Template.Spec.Containers[0].ImagePullPolicy = v1.PullAlways
51+
deployment, findDeployErr := clientset.ExtensionsV1beta1().
52+
Deployments(functionNamespace).
53+
Get(request.Service, getOpts)
5054

51-
deployment.Spec.Template.Spec.Containers[0].Env = buildEnvVars(&request)
55+
if findDeployErr != nil {
56+
return findDeployErr, http.StatusNotFound
57+
}
5258

53-
configureReadOnlyRootFilesystem(request, deployment)
59+
if len(deployment.Spec.Template.Spec.Containers) > 0 {
60+
deployment.Spec.Template.Spec.Containers[0].Image = request.Image
5461

55-
deployment.Spec.Template.Spec.NodeSelector = createSelector(request.Constraints)
62+
// Disabling update support to prevent unexpected mutations of deployed functions,
63+
// since imagePullPolicy is now configurable. This could be reconsidered later depending
64+
// on desired behavior, but will need to be updated to take config.
65+
//deployment.Spec.Template.Spec.Containers[0].ImagePullPolicy = v1.PullAlways
5666

57-
labels := map[string]string{
58-
"faas_function": request.Service,
59-
"uid": fmt.Sprintf("%d", time.Now().Nanosecond()),
60-
}
67+
deployment.Spec.Template.Spec.Containers[0].Env = buildEnvVars(&request)
6168

62-
if request.Labels != nil {
63-
if min := getMinReplicaCount(*request.Labels); min != nil {
64-
deployment.Spec.Replicas = min
65-
}
69+
configureReadOnlyRootFilesystem(request, deployment)
6670

67-
for k, v := range *request.Labels {
68-
labels[k] = v
69-
}
70-
}
71+
deployment.Spec.Template.Spec.NodeSelector = createSelector(request.Constraints)
7172

72-
deployment.Labels = labels
73-
deployment.Spec.Template.ObjectMeta.Labels = labels
73+
labels := map[string]string{
74+
"faas_function": request.Service,
75+
"uid": fmt.Sprintf("%d", time.Now().Nanosecond()),
76+
}
7477

75-
resources, resourceErr := createResources(request)
76-
if resourceErr != nil {
77-
w.WriteHeader(http.StatusBadRequest)
78-
w.Write([]byte(resourceErr.Error()))
79-
return
78+
if request.Labels != nil {
79+
if min := getMinReplicaCount(*request.Labels); min != nil {
80+
deployment.Spec.Replicas = min
8081
}
8182

82-
deployment.Spec.Template.Spec.Containers[0].Resources = *resources
83-
84-
existingSecrets, err := getSecrets(clientset, functionNamespace, request.Secrets)
85-
if err != nil {
86-
w.WriteHeader(http.StatusBadRequest)
87-
w.Write([]byte(err.Error()))
88-
return
83+
for k, v := range *request.Labels {
84+
labels[k] = v
8985
}
86+
}
9087

91-
err = UpdateSecrets(request, deployment, existingSecrets)
92-
if err != nil {
93-
log.Println(err)
94-
w.WriteHeader(http.StatusBadRequest)
95-
w.Write([]byte(err.Error()))
96-
return
97-
}
88+
deployment.Labels = labels
89+
deployment.Spec.Template.ObjectMeta.Labels = labels
90+
91+
deployment.Annotations = annotations
92+
deployment.Spec.Template.Annotations = annotations
93+
deployment.Spec.Template.ObjectMeta.Annotations = annotations
94+
95+
resources, resourceErr := createResources(request)
96+
if resourceErr != nil {
97+
return resourceErr, http.StatusBadRequest
9898
}
9999

100-
if _, updateErr := clientset.ExtensionsV1beta1().
101-
Deployments(functionNamespace).
102-
Update(deployment); updateErr != nil {
100+
deployment.Spec.Template.Spec.Containers[0].Resources = *resources
103101

104-
w.WriteHeader(http.StatusInternalServerError)
105-
w.Write([]byte(updateErr.Error()))
102+
existingSecrets, err := getSecrets(clientset, functionNamespace, request.Secrets)
103+
if err != nil {
104+
return err, http.StatusBadRequest
106105
}
106+
107+
err = UpdateSecrets(request, deployment, existingSecrets)
108+
if err != nil {
109+
log.Println(err)
110+
return err, http.StatusBadRequest
111+
}
112+
}
113+
114+
if _, updateErr := clientset.ExtensionsV1beta1().
115+
Deployments(functionNamespace).
116+
Update(deployment); updateErr != nil {
117+
118+
return updateErr, http.StatusInternalServerError
119+
}
120+
121+
return nil, http.StatusOK
122+
}
123+
124+
func updateService(
125+
functionNamespace string,
126+
clientset *kubernetes.Clientset,
127+
request requests.CreateFunctionRequest,
128+
annotations map[string]string) (err error, httpStatus int) {
129+
130+
getOpts := metav1.GetOptions{}
131+
132+
service, findServiceErr := clientset.CoreV1().
133+
Services(functionNamespace).
134+
Get(request.Service, getOpts)
135+
136+
if findServiceErr != nil {
137+
return findServiceErr, http.StatusNotFound
138+
}
139+
140+
service.Annotations = annotations
141+
142+
if _, updateErr := clientset.CoreV1().
143+
Services(functionNamespace).
144+
Update(service); updateErr != nil {
145+
146+
return updateErr, http.StatusInternalServerError
107147
}
148+
149+
return nil, http.StatusOK
108150
}

vendor/github.com/openfaas/faas/gateway/requests/requests.go

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

yaml/gateway-dep.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ spec:
1313
serviceAccountName: faas-controller
1414
containers:
1515
- name: gateway
16-
image: openfaas/gateway:0.8.7
16+
image: openfaas/gateway:0.8.8
1717
imagePullPolicy: Always
1818
livenessProbe:
1919
httpGet:

0 commit comments

Comments
 (0)