Skip to content
This repository was archived by the owner on Oct 12, 2021. It is now read-only.

Commit 57bd050

Browse files
authored
Merge pull request #27 from triggermesh/empty-ce-overrides
Function Response Mode and empty overrides support added
2 parents ebe3cbd + 25647c2 commit 57bd050

File tree

6 files changed

+74
-55
lines changed

6 files changed

+74
-55
lines changed

config/300-function.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ spec:
6060
public:
6161
description: 'Should the function be publicly available.'
6262
type: boolean
63+
responseMode:
64+
description: 'Whether function responds with CE payload only or with full event.'
65+
type: string
6366
ceOverrides:
6467
type: object
6568
description: "Defines overrides to control modifications of the event attributes."

config/controller.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ spec:
5656
value: triggermesh.io/routing
5757

5858
- name: RUNTIME_KLR_PYTHON
59-
value: gcr.io/triggermesh/knative-lambda-python37:v1.5.1
59+
value: gcr.io/triggermesh/knative-lambda-python37:v1.8.1
6060
- name: RUNTIME_KLR_NODE
61-
value: gcr.io/triggermesh/knative-lambda-node10:v1.5.1
61+
value: gcr.io/triggermesh/knative-lambda-node10:v1.8.1
6262
- name: RUNTIME_KLR_RUBY
63-
value: gcr.io/triggermesh/knative-lambda-ruby25:v1.5.1
63+
value: gcr.io/triggermesh/knative-lambda-ruby25:v1.8.1

config/samples/python.yaml

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,33 @@ metadata:
1818
name: inline-python-function
1919
spec:
2020
runtime: python
21+
responseMode: event
2122
public: true
2223
ceOverrides:
2324
extensions:
2425
type: io.triggermesh.python.sample
25-
entrypoint: foo
26+
entrypoint: endpoint
2627
code: |
27-
import urllib.request
28+
from random import randrange
2829
29-
def foo(event, context):
30-
resp = urllib.request.urlopen(event['url'])
31-
page = resp.read()
30+
def endpoint(event, context):
31+
val = randrange(10)
32+
if (val % 2) == 0:
33+
result = {
34+
"type" : "io.triggermesh.klr.even",
35+
"datacontenttype" : "application/json",
36+
"data" : {
37+
"value" : val
38+
}
39+
}
3240
33-
response = {
34-
"statusCode": resp.status,
35-
"body": str(page)
36-
}
41+
else:
42+
result = {
43+
"type" : "io.triggermesh.klr.odd",
44+
"datacontenttype" : "application/json",
45+
"data" : {
46+
"value" : val
47+
}
48+
}
49+
return result
3750
38-
return response

pkg/apis/function/v1alpha1/function_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type FunctionSpec struct {
5555
Entrypoint string `json:"entrypoint"`
5656
Public bool `json:"public,omitempty"`
5757
Code string `json:"code"`
58+
ResponseMode string `json:"responseMode,omitempty"`
5859
CloudEventOverrides *duckv1.CloudEventOverrides `json:"ceOverrides"`
5960
Sink *duckv1.Destination `json:"sink"`
6061
}

pkg/reconciler/function/function.go

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,11 @@ import (
4646
)
4747

4848
const (
49-
klrEntrypoint = "/opt/aws-custom-runtime"
50-
labelKey = "flow.trigermesh.io/function"
49+
klrEntrypoint = "/opt/aws-custom-runtime"
50+
labelKey = "flow.trigermesh.io/function"
51+
ceDefaultTypePrefix = "io.triggermesh.function."
5152
)
5253

53-
type ceAttributes struct {
54-
Type string
55-
Source string
56-
Subject string
57-
}
58-
5954
// Reconciler implements addressableservicereconciler.Interface for
6055
// AddressableService resources.
6156
type Reconciler struct {
@@ -107,11 +102,8 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, o *functionv1alpha1.Func
107102
}
108103
o.Status.MarkConfigmapAvailable()
109104

110-
// Parse CE overrides
111-
ceAttr := r.ceAttributes(o)
112-
113105
// Reconcile Transformation Adapter
114-
ksvc, err := r.reconcileKnService(ctx, o, cm, ceAttr)
106+
ksvc, err := r.reconcileKnService(ctx, o, cm)
115107
if err != nil {
116108
logger.Error("Error reconciling Kn Service", zap.Error(err))
117109
o.Status.MarkServiceUnavailable(o.Name)
@@ -141,7 +133,12 @@ func (r *Reconciler) ReconcileKind(ctx context.Context, o *functionv1alpha1.Func
141133
}
142134
o.Status.MarkServiceAvailable()
143135

144-
o.Status.CloudEventAttributes = r.statusAttributes(ceAttr)
136+
if o.Spec.CloudEventOverrides != nil {
137+
// in status we can set default attributes only;
138+
// there is no reliable way to get dynamic CE attributes from function source code
139+
o.Status.CloudEventAttributes = r.statusAttributes(o.Spec.CloudEventOverrides.Extensions)
140+
}
141+
145142
o.Status.MarkSinkAvailable()
146143

147144
logger.Debug("Transformation reconciled")
@@ -177,7 +174,7 @@ func (r *Reconciler) reconcileConfigmap(ctx context.Context, f *functionv1alpha1
177174
return actualCm, nil
178175
}
179176

180-
func (r *Reconciler) reconcileKnService(ctx context.Context, f *functionv1alpha1.Function, cm *corev1.ConfigMap, ceAttr ceAttributes) (*servingv1.Service, error) {
177+
func (r *Reconciler) reconcileKnService(ctx context.Context, f *functionv1alpha1.Function, cm *corev1.ConfigMap) (*servingv1.Service, error) {
181178
logger := logging.FromContext(ctx)
182179

183180
image, err := r.lookupRuntimeImage(f.Spec.Runtime)
@@ -206,16 +203,27 @@ func (r *Reconciler) reconcileKnService(ctx context.Context, f *functionv1alpha1
206203
filename := fmt.Sprintf("source.%s", fileExtension(f.Spec.Runtime))
207204
handler := fmt.Sprintf("source.%s", f.Spec.Entrypoint)
208205

206+
overrides := map[string]string{
207+
// Default values for required attributes
208+
"type": ceDefaultTypePrefix + f.Spec.Runtime,
209+
"source": filename,
210+
}
211+
212+
if f.Spec.CloudEventOverrides != nil {
213+
for k, v := range f.Spec.CloudEventOverrides.Extensions {
214+
overrides[k] = v
215+
}
216+
}
217+
209218
expectedKsvc := resources.NewKnService(f.Name+"-"+rand.String(6), f.Namespace,
210219
resources.KnSvcImage(image),
211220
resources.KnSvcMountCm(cm.Name, filename),
212221
resources.KnSvcEntrypoint(klrEntrypoint),
213222
resources.KnSvcEnvVar("K_SINK", sink),
214223
resources.KnSvcEnvVar("_HANDLER", handler),
215224
resources.KnSvcEnvVar("RESPONSE_FORMAT", "CLOUDEVENTS"),
216-
resources.KnSvcEnvVar("CE_TYPE", ceAttr.Type),
217-
resources.KnSvcEnvVar("CE_SOURCE", ceAttr.Source),
218-
resources.KnSvcEnvVar("CE_SUBJECT", ceAttr.Subject),
225+
resources.KnSvcEnvVar("CE_FUNCTION_RESPONSE_MODE", f.Spec.ResponseMode),
226+
resources.KnSvcEnvFromMap("CE_OVERRIDES_", overrides),
219227
resources.KnSvcAnnotation("extensions.triggermesh.io/codeVersion", cm.ResourceVersion),
220228
resources.KnSvcVisibility(f.Spec.Public),
221229
resources.KnSvcLabel(map[string]string{labelKey: f.Name}),
@@ -241,36 +249,18 @@ func (r *Reconciler) reconcileKnService(ctx context.Context, f *functionv1alpha1
241249
return actualKsvc, nil
242250
}
243251

244-
func (r *Reconciler) ceAttributes(f *functionv1alpha1.Function) ceAttributes {
245-
res := ceAttributes{
246-
Source: f.SelfLink,
247-
Subject: f.Spec.Entrypoint,
248-
}
252+
func (r *Reconciler) statusAttributes(attributes map[string]string) []duckv1.CloudEventAttributes {
253+
res := duckv1.CloudEventAttributes{}
249254

250-
if f.Spec.CloudEventOverrides == nil {
251-
return res
255+
if typ, ok := attributes["type"]; ok {
256+
res.Type = typ
252257
}
253258

254-
for k, v := range f.Spec.CloudEventOverrides.Extensions {
255-
switch strings.ToLower(k) {
256-
case "type":
257-
res.Type = v
258-
case "source":
259-
res.Source = v
260-
case "subject":
261-
res.Subject = v
262-
}
259+
if source, ok := attributes["source"]; ok {
260+
res.Source = source
263261
}
264-
return res
265-
}
266262

267-
func (r *Reconciler) statusAttributes(ceAttr ceAttributes) []duckv1.CloudEventAttributes {
268-
return []duckv1.CloudEventAttributes{
269-
{
270-
Type: ceAttr.Type,
271-
Source: ceAttr.Source,
272-
},
273-
}
263+
return []duckv1.CloudEventAttributes{res}
274264
}
275265

276266
func (r *Reconciler) lookupRuntimeImage(runtime string) (string, error) {

pkg/reconciler/function/resources/knservice.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package resources
1818

1919
import (
2020
"path"
21+
"strings"
2122

2223
corev1 "k8s.io/api/core/v1"
2324
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -183,3 +184,15 @@ func firstContainer(svc *servingv1.Service) *corev1.Container {
183184
}
184185
return &(*containers)[0]
185186
}
187+
188+
func KnSvcEnvFromMap(prefix string, vars map[string]string) knSvcOption {
189+
return func(svc *servingv1.Service) {
190+
svcEnvVars := envVarsFrom(svc)
191+
for k, v := range vars {
192+
*svcEnvVars = append(*svcEnvVars, corev1.EnvVar{
193+
Name: strings.ToUpper(prefix + k),
194+
Value: v,
195+
})
196+
}
197+
}
198+
}

0 commit comments

Comments
 (0)