Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

operator: v1alpha2 mitigations #1285

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ jobs:
- name: Update testdata
run: |
go test ./charts/redpanda -update -short
go test ./charts/operator -update -short

- name: Commit changes for testdata golden files
run: |
git add charts/redpanda/testdata
git add charts/operator/testdata
git commit -m "[Auto Commit] Update testdata golden files"
git push

Expand Down
19 changes: 19 additions & 0 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ tasks:
# Generate chart README.md's
- nix develop -c helm-docs -c ./charts/
- task: chart:generate:redpanda
- task: chart:generate:operator
# Ensure go deps are up to date
- go mod tidy
# Ensure go deps in the gotohelm test package are up to date
Expand All @@ -91,6 +92,24 @@ tasks:
# Generate helm templates from Go definitions
- go run ./cmd/gotohelm -write ./charts/redpanda/templates ./charts/redpanda

chart:generate:operator:
desc: "Generate files for the operator Helm chart"
vars:
OPERATOR_VERSION:
sh: yq -r .appVersion charts/operator/Chart.yaml
OPERATOR_URL: "https://github.com/redpanda-data/redpanda-operator//src/go/k8s/config"
# Couldn't come up with a better way to handle this.
KUSTOMIZATION_RESOURCES: '["{{.OPERATOR_URL}}/rbac?ref={{.OPERATOR_VERSION}}","{{.OPERATOR_URL}}/webhook?ref={{.OPERATOR_VERSION}}"]'
cmds:
# yq / jq suffer from the inability to edit a file it's reading. So we
# dump it out to a temp file and them move it into place of the
# kustomization.yaml we're reading.
- |
export TMP=$(mktemp)
yq -Y '.resources = {{ .KUSTOMIZATION_RESOURCES }}' charts/operator/kustomization.yaml > $TMP
mv $TMP ./charts/operator/kustomization.yaml
- kubectl kustomize ./charts/operator/ > ./charts/operator/kustomized-manifest.yaml

create-test-rack-awareness:
cmds:
- .github/annotate_kind_nodes.sh {{.KIND_CLUSTERNAME}}
Expand Down
6 changes: 6 additions & 0 deletions charts/operator/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.DS_Store
README.md.gotmpl

*.go
testdata/
ci/
8 changes: 4 additions & 4 deletions charts/operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ Sets resources requests/limits for Redpanda Operator Pods. By default requests a

### [scope](https://artifacthub.io/packages/helm/redpanda-data/operator?modal=values&path=scope)

Sets the scope of the Redpanda Operator. Valid values are `Cluster` or `Namespace`. The Cluster scope is deprecated because it deploys the deprecated version of the Redpanda Operator. Use the default Namespace scope. In the Namespace scope, the Redpanda Operator manages Redpanda resources that are deployed in the same namespace as itself.
Sets the scope of the Redpanda Operator. Valid values are `Cluster` or `Namespace`. The Cluster scope is deprecated because it deploys the deprecated version of the Redpanda Operator. Use the default Namespace scope. In the Namespace scope, the Redpanda Operator manages Redpanda resources that are deployed in the same namespace as itself. WARNING: This field does not do what you think it does. For historical purposes, scope controls the mode of operation for the operator. "Namespace" will run operator V2 AKA the Redpanda reconciler and "Cluster" will run operator V1 AKA the Cluster reconciler. Do not change this unless you know what this warning message means.

**Default:** `"Namespace"`

Expand Down Expand Up @@ -350,15 +350,15 @@ Taints to be tolerated by Pods. For details, see the [Kubernetes documentation](

### [webhook](https://artifacthub.io/packages/helm/redpanda-data/operator?modal=values&path=webhook)

Specifies whether to create Webhook resources both to intercept and potentially modify or reject Kubernetes API requests as well as authenticate requests to the Kubernetes API. Only valid when `scope` is set to Cluster.
Specifies whether to create Webhook resources both to intercept and potentially modify or reject Kubernetes API requests as well as authenticate requests to the Kubernetes API.

**Default:** `{"enabled":false}`
**Default:** `{"enabled":true}`

### [webhook.enabled](https://artifacthub.io/packages/helm/redpanda-data/operator?modal=values&path=webhook.enabled)

Creates the Webhook resources.

**Default:** `false`
**Default:** `true`

### [webhookSecretName](https://artifacthub.io/packages/helm/redpanda-data/operator?modal=values&path=webhookSecretName)

Expand Down
179 changes: 179 additions & 0 deletions charts/operator/chart_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package operator

import (
"fmt"
"slices"
"strings"
"testing"

certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/redpanda-data/helm-charts/pkg/helm"
"github.com/redpanda-data/helm-charts/pkg/kube"
"github.com/redpanda-data/helm-charts/pkg/testutil"
"github.com/stretchr/testify/require"
rbacv1 "k8s.io/api/rbac/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
clientscheme "k8s.io/client-go/kubernetes/scheme"
)

func TestTemplate(t *testing.T) {
ctx := testutil.Context(t)
client, err := helm.New(helm.Options{ConfigHome: testutil.TempDir(t)})
require.NoError(t, err)

// Chart deps are kept within ./charts as a tgz archive, which is git
// ignored. Helm dep build will ensure that ./charts is in sync with
// Chart.lock, which is tracked by git.
require.NoError(t, client.RepoAdd(ctx, "kube-prometheus-stack", "https://prometheus-community.github.io/helm-charts"))
require.NoError(t, client.DependencyBuild(ctx, "."), "failed to refresh helm dependencies")

scheme := runtime.NewScheme()
require.NoError(t, apiextensionsv1.AddToScheme(scheme))
require.NoError(t, certmanagerv1.AddToScheme(scheme))
require.NoError(t, clientscheme.AddToScheme(scheme))

testCases := []struct {
Name string
Values any
Assert func(*testing.T, []kube.Object)
}{
{
Name: "defaults",
Values: map[string]any{},
Assert: func(t *testing.T, objs []kube.Object) {
hasCrds := slices.ContainsFunc(objs, func(obj kube.Object) bool {
_, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
return ok
})
require.False(t, hasCrds, "default values should NOT include CRDs")
},
},
{
Name: "all-the-rbac",
Values: map[string]any{
"rbac": map[string]any{
"createAdditionalControllerCRs": true,
"createRPKBundleCRs": true,
},
},
},
{
Name: "no-rbac",
Values: map[string]any{
"rbac": map[string]any{
"create": false,
},
},
},
{
Name: "webhook",
Values: map[string]any{
"webhook": map[string]any{
"enabled": true,
},
},
},
{
Name: "scope",
Values: map[string]any{
"scope": "Cluster",
"webhook": map[string]any{
"enabled": true,
},
},
},
}

for _, tc := range testCases {
out, err := client.Template(ctx, ".", helm.TemplateOptions{
Name: "redpanda-operator",
Values: tc.Values,
})
require.NoError(t, err)

testutil.AssertGolden(t, testutil.YAML, fmt.Sprintf("testdata/template-%s.golden", tc.Name), out)

manifests, err := kube.DecodeYAML(out, scheme)
require.NoError(t, err)

if tc.Assert != nil {
tc.Assert(t, manifests)
}
}
}

func TestTemplateRBAC(t *testing.T) {
ctx := testutil.Context(t)
client, err := helm.New(helm.Options{ConfigHome: testutil.TempDir(t)})
require.NoError(t, err)

scheme := runtime.NewScheme()
require.NoError(t, apiextensionsv1.AddToScheme(scheme))
require.NoError(t, certmanagerv1.AddToScheme(scheme))
require.NoError(t, clientscheme.AddToScheme(scheme))

testCases := []struct {
Name string
Values any
}{
{
Name: "namespace-scoped",
Values: map[string]any{
"scope": "Namespace",
"rbac": map[string]any{
"create": true,
"createAdditionalControllerCRs": true,
"createRPKBundleCRs": true,
},
},
},
{
Name: "cluster-scoped",
Values: map[string]any{
"scope": "Cluster",
"webhook": map[string]any{
"enabled": true,
},
"rbac": map[string]any{
"create": true,
"createAdditionalControllerCRs": true,
"createRPKBundleCRs": true,
},
},
},
}

for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
out, err := client.Template(ctx, ".", helm.TemplateOptions{
Name: "redpanda-operator",
Values: tc.Values,
})
require.NoError(t, err)

manifests, err := kube.DecodeYAML(out, scheme)
require.NoError(t, err)

i := -1
for j, obj := range manifests {
switch obj.(type) {
case *rbacv1.Role, *rbacv1.ClusterRole, *rbacv1.RoleBinding, *rbacv1.ClusterRoleBinding:
i++
manifests[i] = manifests[j]
default:
continue
}
}

manifests = manifests[:i:i]

slices.SortStableFunc(manifests, func(a, b kube.Object) int {
return strings.Compare(a.GetName(), b.GetName())
})

encoded, err := kube.EncodeYAML(scheme, manifests...)
testutil.AssertGolden(t, testutil.YAML, fmt.Sprintf("testdata/rbac-%s.golden", tc.Name), encoded)
})
}
}
2 changes: 1 addition & 1 deletion charts/operator/files/three_node_redpanda.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: cluster.redpanda.com/v1alpha1
apiVersion: cluster.redpanda.com/v1alpha2
kind: Redpanda
metadata:
name: cluster-tls
Expand Down
40 changes: 40 additions & 0 deletions charts/operator/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
resources:
- https://github.com/redpanda-data/redpanda-operator//src/go/k8s/config/rbac?ref=v2.1.19-24.1.2
- https://github.com/redpanda-data/redpanda-operator//src/go/k8s/config/webhook?ref=v2.1.19-24.1.2
namePrefix: '{{ include "redpanda-operator.fullname" $ }}-'
namespace: '{{ $.Release.Namespace }}'
patches:
- target:
kind: ClusterRoleBinding
patch: |-
- op: replace
path: /subjects/0/name
value: '{{ include "redpanda-operator.serviceAccountName" $ }}'
- op: replace
path: /subjects/0/namespace
value: '{{ $.Release.Namespace }}'
- target:
kind: RoleBinding
patch: |-
- op: replace
path: /subjects/0/name
value: '{{ include "redpanda-operator.serviceAccountName" $ }}'
- op: replace
path: /subjects/0/namespace
value: '{{ $.Release.Namespace }}'
- target:
kind: Service
patch: |-
- op: replace
path: /spec/selector
value:
app.kubernetes.io/name: '{{ include "redpanda-operator.name" $ }}'
app.kubernetes.io/instance: '{{ $.Release.Name }}'
- target:
name: "webhook-service"
kind: Service
patch: |-
- op: replace
path: /metadata/annotations
value:
cert-manager.io/inject-ca-from: '{{ $.Release.Name }}/redpanda-serving-cert'
Loading
Loading