Skip to content

Commit 0e8bd06

Browse files
Prevent External Route Changes To ISVCs From Creating New Revisions (#549) (#578)
* adding networking.knative.io/visibility annotation to ServiceAnnotationDisallowedList * adding comments and fixing python linter error * add unit test * correcting annotation name * removing visibility annotation from the ServiceAnnotationDisallowedList constant as it is not needed for backward compatibility * fix unit test * improving unit test structure * removing visibilityAnnotation constant --------- Signed-off-by: Brett Thompson <[email protected]> Co-authored-by: Brett Thompson <[email protected]>
1 parent 3061f27 commit 0e8bd06

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

config/overlays/odh/inferenceservice-config-patch.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ data:
9292
"autoscaling.knative.dev/max-scale",
9393
"internal.serving.kserve.io/storage-initializer-sourceuri",
9494
"kubectl.kubernetes.io/last-applied-configuration",
95-
"security.opendatahub.io/enable-auth"
95+
"security.opendatahub.io/enable-auth",
96+
"networking.knative.dev/visibility"
9697
]
9798
}
9899

pkg/constants/constants.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,18 @@ const (
370370
)
371371

372372
var (
373+
// ServiceAnnotationDisallowedList is a list of annotations that are not allowed to be propagated to Knative
374+
// revisions, which prevents the reconciliation loop to be triggered if the annotations is
375+
// configured here are used.
373376
ServiceAnnotationDisallowedList = []string{
374377
autoscaling.MinScaleAnnotationKey,
375378
autoscaling.MaxScaleAnnotationKey,
376379
StorageInitializerSourceUriInternalAnnotationKey,
377380
"kubectl.kubernetes.io/last-applied-configuration",
378381
"security.opendatahub.io/enable-auth",
379382
}
380-
383+
// RevisionTemplateLabelDisallowedList is a list of labels that are not allowed to be propagated to Knative
384+
// revisions, which prevents the reconciliation loop to be triggered if the labels is configured here are used.
381385
RevisionTemplateLabelDisallowedList = []string{
382386
VisibilityLabel,
383387
}

pkg/controller/v1beta1/inferenceservice/controller_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,73 @@ var _ = Describe("v1beta1 inference service controller", func() {
9292
}`,
9393
}
9494
)
95+
Context("an annotation is applied to an InferenceService resource", func() {
96+
When("the annotation is a member of the serviceAnnotationDisallowedList in the inferenceservice-config configmap", func() {
97+
It("should not be propagated to any knative revisions", func() {
98+
// Add the annotation to the inferenceservice-config inferenceService serviceAnnotationDisallowedList
99+
sampleAnnotation := "test.dev/testing"
100+
configs["inferenceService"] = fmt.Sprintf("{\"serviceAnnotationDisallowedList\": [\"%s\"]}", sampleAnnotation)
101+
defer delete(configs, "inferenceService")
102+
103+
// Create configmap
104+
var configMap = &v1.ConfigMap{
105+
ObjectMeta: metav1.ObjectMeta{
106+
Name: constants.InferenceServiceConfigMapName,
107+
Namespace: constants.KServeNamespace,
108+
},
109+
Data: configs,
110+
}
111+
Expect(k8sClient.Create(context.TODO(), configMap)).NotTo(HaveOccurred())
112+
defer k8sClient.Delete(context.TODO(), configMap)
113+
114+
// Create InferenceService
115+
serviceName := "annotated"
116+
var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: serviceName, Namespace: "default"}}
117+
var serviceKey = expectedRequest.NamespacedName
118+
var storageUri = "s3://test/mnist/export"
119+
ctx := context.Background()
120+
isvc := &v1beta1.InferenceService{
121+
ObjectMeta: metav1.ObjectMeta{
122+
Name: serviceKey.Name,
123+
Namespace: serviceKey.Namespace,
124+
Annotations: map[string]string{
125+
sampleAnnotation: "test",
126+
},
127+
},
128+
Spec: v1beta1.InferenceServiceSpec{
129+
Predictor: v1beta1.PredictorSpec{
130+
ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{
131+
MinReplicas: v1beta1.GetIntReference(1),
132+
MaxReplicas: 1,
133+
},
134+
Tensorflow: &v1beta1.TFServingSpec{
135+
PredictorExtensionSpec: v1beta1.PredictorExtensionSpec{
136+
StorageURI: &storageUri,
137+
RuntimeVersion: proto.String("1.14.0"),
138+
Container: v1.Container{
139+
Name: constants.InferenceServiceContainerName,
140+
Resources: defaultResource,
141+
},
142+
},
143+
},
144+
},
145+
},
146+
}
147+
Expect(k8sClient.Create(ctx, isvc)).Should(Succeed())
148+
defer k8sClient.Delete(ctx, isvc)
149+
150+
actualService := &knservingv1.Service{}
151+
predictorServiceKey := types.NamespacedName{Name: constants.PredictorServiceName(serviceKey.Name),
152+
Namespace: serviceKey.Namespace}
153+
Eventually(func() error { return k8sClient.Get(context.TODO(), predictorServiceKey, actualService) }, timeout).
154+
Should(Succeed())
155+
156+
Expect(sampleAnnotation).ShouldNot(BeKeyOf(actualService.Annotations))
157+
Expect(sampleAnnotation).ShouldNot(BeKeyOf(actualService.Spec.Template.Annotations))
158+
})
159+
})
160+
})
161+
95162
Context("When creating inference service with predictor", func() {
96163
It("Should have knative service created", func() {
97164
By("By creating a new InferenceService")

0 commit comments

Comments
 (0)