capactio / capact

Simple way to manage applications and infrastructure.
https://capact.io
Apache License 2.0
80 stars 19 forks source link

During rendering, engine panics when Action has an empty Secret #593

Closed mszostok closed 2 years ago

mszostok commented 2 years ago

Description

Action created via GraphQL, results in panic in engine which is continuously restarting.

2021-12-23T18:57:35.006Z    INFO    controllers.Action  controller/action_controller.go:145 Execute runner  {"action": "default/sample2"}
panic: assignment to entry in nil map

goroutine 464 [running]:
capact.io/capact/internal/k8s-engine/controller.(*ActionService).EnsureRunnerInputDataCreated(0xc000128000, 0x203b628, 0xc00063f0b0, 0xc000f3ab34, 0x7, 0xc0003a0960, 0x0, 0x0)
    /capact.io/capact/internal/k8s-engine/controller/action_service.go:281 +0x6f2
capact.io/capact/internal/k8s-engine/controller.(*ActionReconciler).executeAction(0xc000281320, 0x203b628, 0xc00063f0b0, 0xc0003a0960, 0x0, 0x0, 0x7, 0x2063420)
    /capact.io/capact/internal/k8s-engine/controller/action_controller.go:227 +0x1e9
capact.io/capact/internal/k8s-engine/controller.(*ActionReconciler).Reconcile(0xc000281320, 0x203b628, 0xc00063f0b0, 0xc000f3ab49, 0x7, 0xc000f3ab34, 0x7, 0xc00063f0b0, 0xc00003a000, 0x1c1c5e0, ...)
    /capact.io/capact/internal/k8s-engine/controller/action_controller.go:146 +0x7bc
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler(0xc0001285a0, 0x203b580, 0xc000941500, 0x1bbb0a0, 0xc000bbaa60)
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.9.6/pkg/internal/controller/controller.go:298 +0x30d
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem(0xc0001285a0, 0x203b580, 0xc000941500, 0xc0000df800)
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.9.6/pkg/internal/controller/controller.go:253 +0x205
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2(0xc000b2cdc0, 0xc0001285a0, 0x203b580, 0xc000941500)
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.9.6/pkg/internal/controller/controller.go:214 +0x6b
created by sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2
    /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.9.6/pkg/internal/controller/controller.go:210 +0x425

Expected behavior

Actions created via GraphQL call cannot result in panic.

Steps to reproduce

In general, we don't create secret if not needed: https://github.com/capactio/capact/blob/21a4f72a6507340ba925d4b06fdff054e34b00fd/internal/k8s-engine/graphql/domain/action/converter.go#L207-L210

But it can be easily bypassed just by sending empty params:

# Example variables: {"actionName": "sample"}
mutation CreateActionWithInput($actionName: String!) {
    createAction(
        in: {
            name: $actionName
            actionRef: {
                path: "cap.interface.capactio.capact.validation.hub.install"
            }
            dryRun: true
            advancedRendering: false
            input: {
                parameters: "{}"
            }
        }
    ) {
        name
    }
}

As a result, an empty Secret is created. During render process, the engine wants to update it, but the data map is not initialized and we don't check that, so writing into nil object results in panic.