Skip to content
This repository was archived by the owner on Jun 26, 2024. It is now read-only.

Commit 2c7ab9e

Browse files
authored
Fix: Remove volume and volumemount from app resource when unbinding (#950)
When projecting bindings as files, we inject volume and volume mount carrying the same name as binding resource, but when binding is removed, we wrongly look to remove volume and volume mount having the name equal to the binding secret. This change fixes it and introduces the missing acceptance tests. Signed-off-by: Predrag Knezevic <[email protected]>
1 parent 73ae16a commit 2c7ab9e

File tree

5 files changed

+74
-8
lines changed

5 files changed

+74
-8
lines changed

pkg/reconcile/pipeline/handler/project/impl.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ func Unbind(ctx pipeline.Context) {
237237
return
238238
}
239239
secretName := ctx.BindingSecretName()
240+
bindingName := ctx.BindingName()
240241
if secretName == "" {
241242
ctx.StopProcessing()
242243
return
@@ -254,7 +255,7 @@ func Unbind(ctx pipeline.Context) {
254255
volumeResources, found, _ := resources(&corev1.Volume{}, podSpecMap, "volumes")
255256
if found {
256257
for i, vol := range volumeResources {
257-
if val, found, err := unstructured.NestedString(vol, "name"); found && err == nil && val == secretName {
258+
if val, found, err := unstructured.NestedString(vol, "name"); found && err == nil && val == bindingName {
258259
s := append(volumeResources[:i], volumeResources[i+1:]...)
259260
if len(s) == 0 {
260261
delete(podSpecMap, "volumes")
@@ -288,7 +289,7 @@ func Unbind(ctx pipeline.Context) {
288289
volumeMounts, found, _ := resources(&corev1.VolumeMount{}, container, "volumeMounts")
289290
if found {
290291
for i, vm := range volumeMounts {
291-
if val, found, err := unstructured.NestedString(vm, "name"); found && err == nil && val == secretName {
292+
if val, found, err := unstructured.NestedString(vm, "name"); found && err == nil && val == bindingName {
292293
s := append(volumeMounts[:i], volumeMounts[i+1:]...)
293294
if len(s) == 0 {
294295
delete(container, "volumeMounts")

pkg/reconcile/pipeline/handler/project/impl_test.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -519,12 +519,15 @@ var _ = Describe("Unbind handler", func() {
519519
deploymentsUnstructured []*unstructured.Unstructured
520520
deploymentsUnstructuredOld []*unstructured.Unstructured
521521
secretName string
522+
bindingName string
522523
)
523524

524525
BeforeEach(func() {
525526
var apps []pipeline.Application
526527
secretName = "secret1"
528+
bindingName = "binding1"
527529
ctx.EXPECT().BindingSecretName().Return(secretName)
530+
ctx.EXPECT().BindingName().Return(bindingName)
528531
d1 := deployment("d1", []corev1.Container{
529532
{
530533
Image: "foo",
@@ -570,7 +573,7 @@ var _ = Describe("Unbind handler", func() {
570573
Image: "foo",
571574
VolumeMounts: []corev1.VolumeMount{
572575
{
573-
Name: secretName,
576+
Name: bindingName,
574577
MountPath: "/bla",
575578
},
576579
},
@@ -581,7 +584,7 @@ var _ = Describe("Unbind handler", func() {
581584
Image: "foo",
582585
VolumeMounts: []corev1.VolumeMount{
583586
{
584-
Name: secretName,
587+
Name: bindingName,
585588
MountPath: "/bla",
586589
},
587590
{
@@ -598,7 +601,7 @@ var _ = Describe("Unbind handler", func() {
598601
})
599602
d6.Spec.Template.Spec.Volumes = []corev1.Volume{
600603
{
601-
Name: secretName,
604+
Name: bindingName,
602605
VolumeSource: corev1.VolumeSource{
603606
Secret: &corev1.SecretVolumeSource{
604607
SecretName: secretName,
@@ -613,7 +616,7 @@ var _ = Describe("Unbind handler", func() {
613616
})
614617
d7.Spec.Template.Spec.Volumes = []corev1.Volume{
615618
{
616-
Name: secretName,
619+
Name: bindingName,
617620
VolumeSource: corev1.VolumeSource{
618621
Secret: &corev1.SecretVolumeSource{
619622
SecretName: secretName,

test/acceptance/features/steps/generic_testapp.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ def get_file_value(self, file_path):
3434
print(f'file endpoint response: {resp.text} code: {resp.status_code}')
3535
return resp.text
3636

37+
def assert_file_not_exist(self, file_path):
38+
polling2.poll(lambda: requests.get(url=f"http://{self.route_url}{file_path}"),
39+
check_success=lambda r: r.status_code == 404, step=5, timeout=400, ignore_exceptions=(requests.exceptions.ConnectionError,))
40+
3741

3842
@step(u'Generic test application "{application_name}" is running')
3943
@step(u'Generic test application "{application_name}" is running with binding root as "{bindingRoot}"')
@@ -65,3 +69,8 @@ def check_env_var_existence(context, name):
6569
def check_file_value(context, file_path):
6670
value = context.text.strip()
6771
polling2.poll(lambda: context.application.get_file_value(file_path) == value, step=5, timeout=400)
72+
73+
74+
@step(u'File "{file_path}" is unavailable in application pod')
75+
def check_file_unavailable(context, file_path):
76+
context.application.assert_file_not_exist(file_path)

test/acceptance/features/steps/steps.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,10 +532,14 @@ def validate_secret_empty(context):
532532
assert False, "sbr_name not in context"
533533

534534

535+
def assert_generation(context, count):
536+
context.latest_application_generation = context.application.get_generation()
537+
return context.latest_application_generation - context.original_application_generation == int(count)
538+
539+
535540
@then(u'The application got redeployed {count} times so far')
536541
def check_generation(context, count):
537-
context.latest_application_generation = context.application.get_generation()
538-
assert context.latest_application_generation - context.original_application_generation == int(count), "Unexpected number of application redeployments"
542+
polling2.poll(lambda: assert_generation(context, count), step=5, timeout=400)
539543

540544

541545
@then(u'The application does not get redeployed again with {time} minutes')

test/acceptance/features/unbindAppToService.feature

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,52 @@ Feature: Unbind an application from a service
107107

108108
Then The env var "BACKEND_HOST" is not available to the application
109109
And The env var "BACKEND_USERNAME" is not available to the application
110+
111+
Scenario: Remove bindings projected as files from generic test application
112+
Given Generic test application "remove-bindings-as-files-app" is running
113+
* The Custom Resource is present
114+
"""
115+
apiVersion: "stable.example.com/v1"
116+
kind: Backend
117+
metadata:
118+
name: remove-bindings-as-files-app-backend
119+
annotations:
120+
"service.binding/host": "path={.spec.host}"
121+
"service.binding/port": "path={.spec.port}"
122+
spec:
123+
host: example.common
124+
port: 8080
125+
"""
126+
* Service Binding is applied
127+
"""
128+
apiVersion: binding.operators.coreos.com/v1alpha1
129+
kind: ServiceBinding
130+
metadata:
131+
name: remove-bindings-as-files-app-sb
132+
spec:
133+
services:
134+
- group: stable.example.com
135+
version: v1
136+
kind: Backend
137+
name: remove-bindings-as-files-app-backend
138+
139+
application:
140+
name: remove-bindings-as-files-app
141+
group: apps
142+
version: v1
143+
resource: deployments
144+
"""
145+
* Service Binding "remove-bindings-as-files-app-sb" is ready
146+
147+
* Content of file "/bindings/remove-bindings-as-files-app-sb/host" in application pod is
148+
"""
149+
example.common
150+
"""
151+
* Content of file "/bindings/remove-bindings-as-files-app-sb/port" in application pod is
152+
"""
153+
8080
154+
"""
155+
When Service Binding "remove-bindings-as-files-app-sb" is deleted
156+
Then The application got redeployed 2 times so far
157+
* File "/bindings/remove-bindings-as-files-app-sb/host" is unavailable in application pod
158+
* File "/bindings/remove-bindings-as-files-app-sb/port" is unavailable in application pod

0 commit comments

Comments
 (0)