Skip to content

Commit fa83efc

Browse files
Add ci test
1 parent 78a05d5 commit fa83efc

File tree

8 files changed

+232
-32
lines changed

8 files changed

+232
-32
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
apiVersion: compute.functionmesh.io/v1alpha1
2+
kind: FunctionMesh
3+
metadata:
4+
name: functionmesh-generic-resources-sample
5+
spec:
6+
genericResources:
7+
- apiVersion: "compute.functionmesh.io/v1alpha1"
8+
kind: "Function"
9+
name: java-function
10+
spec:
11+
name: java-function
12+
image: streamnative/pulsar-functions-java-sample:3.2.2.1
13+
className: org.apache.pulsar.functions.api.examples.ExclamationFunction
14+
replicas: 1
15+
maxReplicas: 1
16+
input:
17+
topics:
18+
- persistent://public/default/functionmesh-generic-resource-input-topic
19+
typeClassName: java.lang.String
20+
output:
21+
topic: persistent://public/default/functionmesh-generic-resource-java-topic
22+
typeClassName: java.lang.String
23+
pulsar:
24+
pulsarConfig: "mesh-test-pulsar"
25+
java:
26+
jar: /pulsar/examples/api-examples.jar
27+
forwardSourceMessageProperty: true
28+
autoAck: true
29+
resources:
30+
requests:
31+
cpu: "0.1"
32+
memory: 1G
33+
limits:
34+
cpu: "0.2"
35+
memory: 1.1G
36+
clusterName: test
37+
readyFields:
38+
- "StatefulSet"
39+
- "Service"
40+
- apiVersion: "compute.functionmesh.io/v1alpha1"
41+
kind: "Function"
42+
name: golang-function
43+
spec:
44+
name: golang-function
45+
image: streamnative/pulsar-functions-go-sample:3.2.2.1
46+
replicas: 1
47+
maxReplicas: 1
48+
input:
49+
topics:
50+
- persistent://public/default/functionmesh-generic-resource-java-topic
51+
typeClassName: java.lang.String
52+
output:
53+
topic: persistent://public/default/functionmesh-generic-resource-golang-topic
54+
typeClassName: java.lang.String
55+
pulsar:
56+
pulsarConfig: "mesh-test-pulsar"
57+
golang:
58+
go: /pulsar/examples/go-exclamation-func
59+
forwardSourceMessageProperty: true
60+
autoAck: true
61+
resources:
62+
requests:
63+
cpu: "0.1"
64+
memory: 1G
65+
limits:
66+
cpu: "0.2"
67+
memory: 1.1G
68+
clusterName: test
69+
readyFields:
70+
- "StatefulSet"
71+
- "Service"
72+
- apiVersion: "compute.functionmesh.io/v1alpha1"
73+
kind: "Function"
74+
name: python-function
75+
spec:
76+
name: python-function
77+
image: streamnative/pulsar-functions-python-sample:3.2.2.1
78+
className: exclamation_function.ExclamationFunction
79+
replicas: 1
80+
maxReplicas: 1
81+
input:
82+
topics:
83+
- persistent://public/default/functionmesh-generic-resource-golang-topic
84+
typeClassName: java.lang.String
85+
output:
86+
topic: persistent://public/default/functionmesh-generic-resource-python-topic
87+
typeClassName: java.lang.String
88+
pulsar:
89+
pulsarConfig: "mesh-test-pulsar"
90+
python:
91+
py: /pulsar/examples/python-examples/exclamation_function.py
92+
forwardSourceMessageProperty: true
93+
autoAck: true
94+
resources:
95+
requests:
96+
cpu: "0.1"
97+
memory: 1G
98+
limits:
99+
cpu: "0.2"
100+
memory: 1.1G
101+
clusterName: test
102+
readyFields:
103+
- "StatefulSet"
104+
- "Service"
105+
---
106+
apiVersion: v1
107+
kind: ConfigMap
108+
metadata:
109+
name: mesh-test-pulsar
110+
data:
111+
webServiceURL: http://sn-platform-pulsar-broker.default.svc.cluster.local:8080
112+
brokerServiceURL: pulsar://sn-platform-pulsar-broker.default.svc.cluster.local:6650
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
#
20+
21+
set -e
22+
23+
E2E_DIR=$(dirname "$0")
24+
BASE_DIR=$(cd "${E2E_DIR}"/../../../../..;pwd)
25+
PULSAR_NAMESPACE=${PULSAR_NAMESPACE:-"default"}
26+
PULSAR_RELEASE_NAME=${PULSAR_RELEASE_NAME:-"sn-platform"}
27+
E2E_KUBECONFIG=${E2E_KUBECONFIG:-"/tmp/e2e-k8s.config"}
28+
29+
source "${BASE_DIR}"/.ci/helm.sh
30+
31+
if [ ! "$KUBECONFIG" ]; then
32+
export KUBECONFIG=${E2E_KUBECONFIG}
33+
fi
34+
35+
manifests_file="${BASE_DIR}"/.ci/tests/integration/cases/functionmesh-with-generic-resources/manifests.yaml
36+
37+
kubectl apply -f "${manifests_file}" > /dev/null 2>&1
38+
39+
verify_fm_result=$(ci::verify_function_mesh functionmesh-generic-resources-sample-java-function 2>&1)
40+
if [ $? -ne 0 ]; then
41+
echo "$verify_fm_result"
42+
kubectl delete -f "${manifests_file}" > /dev/null 2>&1 || true
43+
exit 1
44+
fi
45+
46+
verify_fm_result=$(ci::verify_function_mesh functionmesh-generic-resources-sample-golang-function 2>&1)
47+
if [ $? -ne 0 ]; then
48+
echo "$verify_fm_result"
49+
kubectl delete -f "${manifests_file}" > /dev/null 2>&1 || true
50+
exit 1
51+
fi
52+
53+
verify_fm_result=$(ci::verify_function_mesh functionmesh-generic-resources-sample-python-function 2>&1)
54+
if [ $? -ne 0 ]; then
55+
echo "$verify_fm_result"
56+
kubectl delete -f "${manifests_file}" > /dev/null 2>&1 || true
57+
exit 1
58+
fi
59+
60+
verify_fm_result=$(NAMESPACE=${PULSAR_NAMESPACE} CLUSTER=${PULSAR_RELEASE_NAME} ci::verify_exclamation_function "persistent://public/default/functionmesh-generic-resource-input-topic" "persistent://public/default/functionmesh-generic-resource-python-topic" "test-message" "test-message!!!" 10 2>&1)
61+
if [ $? -eq 0 ]; then
62+
echo "e2e-test: ok" | yq eval -
63+
else
64+
echo "$verify_fm_result"
65+
fi
66+
kubectl delete -f "${manifests_file}" > /dev/null 2>&1 || true

api/compute/v1alpha1/functionmesh_types.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ type GenericResourceSpec struct {
5858
// +kubebuilder:pruning:PreserveUnknownFields
5959
Spec *Config `json:"spec,omitempty"`
6060

61-
// The filed in the `Status` field of Resource used to check whether the resource is ready
61+
// The fields in the `Status` field of Resource used to check whether the resource is ready
6262
// should equal to ConditionTrue when it's ready
63-
ReadyField string `json:"readyField,omitempty"`
63+
ReadyFields []string `json:"readyFields,omitempty"`
6464
}
6565

6666
// FunctionMeshStatus defines the observed state of FunctionMesh
@@ -70,7 +70,7 @@ type FunctionMeshStatus struct {
7070
SourceConditions map[string]ResourceCondition `json:"sourceConditions,omitempty"`
7171
SinkConditions map[string]ResourceCondition `json:"sinkConditions,omitempty"`
7272
FunctionConditions map[string]ResourceCondition `json:"functionConditions,omitempty"`
73-
GenericResourceConditions map[string]ResourceCondition `json:"genericCRConditions,omitempty"`
73+
GenericResourceConditions map[string]ResourceCondition `json:"genericResourceConditions,omitempty"`
7474
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
7575
Condition *ResourceCondition `json:"condition,omitempty"`
7676
}

api/compute/v1alpha1/zz_generated.deepcopy.go

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

charts/function-mesh-operator/charts/admission-webhook/templates/crd-compute.functionmesh.io-functionmeshes.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,8 +3817,10 @@ spec:
38173817
type: string
38183818
name:
38193819
type: string
3820-
readyField:
3821-
type: string
3820+
readyFields:
3821+
items:
3822+
type: string
3823+
type: array
38223824
spec:
38233825
type: object
38243826
x-kubernetes-preserve-unknown-fields: true
@@ -10846,7 +10848,7 @@ spec:
1084610848
type: string
1084710849
type: object
1084810850
type: object
10849-
genericCRConditions:
10851+
genericResourceConditions:
1085010852
additionalProperties:
1085110853
properties:
1085210854
action:

config/crd/bases/compute.functionmesh.io_functionmeshes.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,8 +3817,10 @@ spec:
38173817
type: string
38183818
name:
38193819
type: string
3820-
readyField:
3821-
type: string
3820+
readyFields:
3821+
items:
3822+
type: string
3823+
type: array
38223824
spec:
38233825
type: object
38243826
x-kubernetes-preserve-unknown-fields: true
@@ -10846,7 +10848,7 @@ spec:
1084610848
type: string
1084710849
type: object
1084810850
type: object
10849-
genericCRConditions:
10851+
genericResourceConditions:
1085010852
additionalProperties:
1085110853
properties:
1085210854
action:

controllers/function_mesh.go

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ func (r *FunctionMeshReconciler) observeGenericResources(ctx context.Context, me
267267

268268
err := r.Get(ctx, types.NamespacedName{
269269
Namespace: mesh.Namespace,
270-
Name: resource.Name,
270+
Name: makeComponentName(mesh.Name, resource.Name),
271271
}, obj)
272272
if err != nil {
273273
if errors.IsNotFound(err) {
@@ -289,15 +289,19 @@ func (r *FunctionMeshReconciler) observeGenericResources(ctx context.Context, me
289289
condition.SetCondition(v1alpha1.GenericResourceReady, v1alpha1.NoAction, metav1.ConditionTrue)
290290
}
291291

292-
if resource.ReadyField != "" {
293-
readyValue, ok := status[resource.ReadyField].(metav1.ConditionStatus)
294-
if ok && readyValue == metav1.ConditionTrue {
295-
condition.SetCondition(v1alpha1.GenericResourceReady, v1alpha1.NoAction, metav1.ConditionTrue)
296-
} else {
297-
// resource created but not ready, we need to wait
298-
condition.SetCondition(v1alpha1.GenericResourceReady, v1alpha1.Wait, metav1.ConditionFalse)
292+
componentReady := true
293+
for _, readyField := range resource.ReadyFields {
294+
readyValue, ok := status[readyField].(metav1.ConditionStatus)
295+
if !ok || readyValue != metav1.ConditionTrue {
296+
componentReady = false
297+
break
299298
}
300299
}
300+
if componentReady {
301+
condition.SetCondition(v1alpha1.GenericResourceReady, v1alpha1.NoAction, metav1.ConditionTrue)
302+
} else {
303+
condition.SetCondition(v1alpha1.GenericResourceReady, v1alpha1.Wait, metav1.ConditionFalse)
304+
}
301305
}
302306

303307
for resourceName, isOrphaned := range orphanedResources {
@@ -400,20 +404,20 @@ func (r *FunctionMeshReconciler) UpdateFunctionMesh(ctx context.Context, req ctr
400404
}
401405
}
402406

403-
for _, genericCRSpec := range mesh.Spec.GenericResources {
404-
condition := mesh.Status.SourceConditions[genericCRSpec.Name]
407+
for _, genericResource := range mesh.Spec.GenericResources {
408+
condition := mesh.Status.SourceConditions[genericResource.Name]
405409
if !newGeneration &&
406410
condition.Status == metav1.ConditionTrue &&
407411
condition.Action == v1alpha1.NoAction {
408412
continue
409413
}
410-
obj := spec.MakeGenericCRComponent(mesh, &genericCRSpec)
414+
obj := spec.MakeGenericResourceComponent(makeComponentName(mesh.Name, genericResource.Name), mesh, &genericResource)
411415

412416
// Create or update the resource
413417
if _, err := ctrl.CreateOrUpdate(ctx, r.Client, obj, func() error {
414418
return nil
415419
}); err != nil {
416-
r.Log.Error(err, "failed to handle "+genericCRSpec.Kind, "name", genericCRSpec.Name, "action", "createOrUpdate")
420+
r.Log.Error(err, "failed to handle "+genericResource.Kind, "name", genericResource.Name, "action", "createOrUpdate")
417421
return err
418422
}
419423
}
@@ -495,19 +499,28 @@ func (r *FunctionMeshReconciler) UpdateFunctionMesh(ctx context.Context, req ctr
495499
}
496500

497501
if len(mesh.Spec.GenericResources) != len(mesh.Status.GenericResourceConditions) {
498-
for crName, crCondition := range mesh.Status.GenericResourceConditions {
499-
if crCondition.Condition == v1alpha1.Orphaned {
500-
// clean up the orphaned genericCRs
502+
for resourceName, resourceCondition := range mesh.Status.GenericResourceConditions {
503+
if resourceCondition.Condition == v1alpha1.Orphaned {
504+
// clean up the orphaned generic resource
501505
obj := &unstructured.Unstructured{}
502-
obj.SetAPIVersion(crCondition.ApiVersion)
503-
obj.SetKind(crCondition.Kind)
504-
obj.SetName(crName)
505-
obj.SetNamespace(mesh.Namespace)
506+
obj.SetAPIVersion(resourceCondition.ApiVersion)
507+
obj.SetKind(resourceCondition.Kind)
508+
if err := r.Get(ctx, types.NamespacedName{
509+
Namespace: mesh.Namespace,
510+
Name: makeComponentName(mesh.Name, resourceName),
511+
}, obj); err != nil {
512+
if errors.IsNotFound(err) {
513+
delete(mesh.Status.GenericResourceConditions, resourceName)
514+
continue
515+
}
516+
r.Log.Error(err, "failed to get orphaned generic resource", "name", resourceName)
517+
return err
518+
}
506519
if err := r.Delete(ctx, obj); err != nil && !errors.IsNotFound(err) {
507-
r.Log.Error(err, "failed to delete orphaned genericCR", "name", crName)
520+
r.Log.Error(err, "failed to delete orphaned generic resource", "name", resourceName)
508521
return err
509522
}
510-
delete(mesh.Status.GenericResourceConditions, crName)
523+
delete(mesh.Status.GenericResourceConditions, resourceName)
511524
}
512525
}
513526
}

controllers/spec/function_mesh.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,11 @@ func MakeSinkComponent(sinkName string, mesh *v1alpha1.FunctionMesh, spec *v1alp
7575
}
7676
}
7777

78-
func MakeGenericCRComponent(mesh *v1alpha1.FunctionMesh, spec *v1alpha1.GenericResourceSpec) *unstructured.Unstructured {
78+
func MakeGenericResourceComponent(resourceName string, mesh *v1alpha1.FunctionMesh, spec *v1alpha1.GenericResourceSpec) *unstructured.Unstructured {
7979
obj := &unstructured.Unstructured{}
8080
obj.SetAPIVersion(spec.APIVersion)
8181
obj.SetKind(spec.Kind)
82-
obj.SetName(spec.Name)
82+
obj.SetName(resourceName)
8383
obj.SetNamespace(mesh.Namespace)
8484

8585
specFieldName := "spec"

0 commit comments

Comments
 (0)