Skip to content

Commit

Permalink
remove typing of cloud_storage_enabled
Browse files Browse the repository at this point in the history
When `v1alpha2` was added it was set as the storage version with a
"none" conversion strategy. Due to the type change on the
`cloud_storage_enabled` field, this resulted in a litany of issues
largely revolving around type validation at the Kube API level.

This commit changes the definitions `v1alpha1` and `v1alpha2` to be the
exact same bUT removes type validation of the `cloud_storage_enabled`
field. This ensures that both `v1alpha1` and `v1alpha2` versions are
accepted by Kubernetes and are appropriately handled by our controllers.
The updated data type will now correctly marshal both string and boolean
JSON types to booleans values which fixes any incompatibilities with the
helm chart's now correctly typed `cloud_storage_enabled` field.

See also:
110831b
redpanda-data/helm-charts@b733738
  • Loading branch information
chrisseto committed May 20, 2024
1 parent c655eb2 commit 52079ad
Show file tree
Hide file tree
Showing 17 changed files with 217 additions and 1,231 deletions.
34 changes: 34 additions & 0 deletions src/go/k8s/api/apiutil/apiutil.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Package apiutil is a collection of types to aid in defining CRDs.
package apiutil

import (
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
)

// JSONBoolean is a workaround for accidental mistyping of the
// cloud_storage_enabled key and the attempted fix of v1alpha2.
// As the conversion was not correctly configured, v1alpha2 could contain
// cloud_storage_enabled fields with either a string or a boolean. This is not
// a type describable by the Kubernetes API.
// To work around any potential issue, we remove all Kubernetes API validation
// by extending the apiextensionsv1.JSON type. When we're marshaling this data
// back to JSON, this field will coalesce the value back into a boolean,
// falling back to false for any unknown values.
// +kubebuilder:object:generate=true
type JSONBoolean apiextensionsv1.JSON

func (in *JSONBoolean) MarshalJSON() ([]byte, error) {
// Marshal any "known" true value to the boolean true and everything else
// to false.
switch string(in.Raw) {
case `true`, `"true"`:
return []byte(`true`), nil
default:
return []byte(`false`), nil
}
}

func (in *JSONBoolean) UnmarshalJSON(data []byte) error {
in.Raw = data
return nil
}
42 changes: 42 additions & 0 deletions src/go/k8s/api/apiutil/apiutil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package apiutil_test

import (
"encoding/json"
"fmt"
"testing"

"github.com/redpanda-data/redpanda-operator/src/go/k8s/api/apiutil"
"github.com/stretchr/testify/require"
)

func TestJSONBoolean(t *testing.T) {
for _, tc := range []struct {
Value any
Expected bool
}{
{true, true},
{false, false},
{"true", true},
{"false", false},
{"invalid", false},
{map[string]any{}, false},
{[]int{}, false},
} {
raw, err := json.Marshal(tc.Value)
require.NoError(t, err)

marshaled, err := json.Marshal(&apiutil.JSONBoolean{Raw: raw})
require.NoError(t, err)

require.JSONEq(t, fmt.Sprintf("%v", tc.Expected), string(marshaled))

// Assert that we can unmarshal into JSONBoolean.
var b *apiutil.JSONBoolean
require.NoError(t, json.Unmarshal(marshaled, &b))

// JSONBoolean's marshal implementation will have coalesced this value
// into an actual boolean. Assert that we're re-marshaled it as
// expected.
require.JSONEq(t, fmt.Sprintf("%v", tc.Expected), string(b.Raw))
}
}
36 changes: 36 additions & 0 deletions src/go/k8s/api/apiutil/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 0 additions & 17 deletions src/go/k8s/api/redpanda/v1alpha1/events_redpanda.go

This file was deleted.

213 changes: 0 additions & 213 deletions src/go/k8s/api/redpanda/v1alpha1/redpanda_clusterspec_types.go

This file was deleted.

Loading

0 comments on commit 52079ad

Please sign in to comment.