Skip to content

Commit c24ee97

Browse files
RafalKoreptachrisseto
authored andcommitted
operator: synchronize {Cluster,}Roles with operator manifests
Prior to this commit the operator chart's declared permissions had grown out of sync with those declared by the operator itself. This commit re-synchronizes the permissions, adds in regression tests to prevent such drift from happening again, and releases the updated chart. Co-authored-by: Rafal Korepta <rafal.korepta@gmail.com>
1 parent e326f1f commit c24ee97

File tree

14 files changed

+9479
-8001
lines changed

14 files changed

+9479
-8001
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@
225225
#### Fixed
226226
#### Removed
227227
228+
### [0.4.33](https://github.com/redpanda-data/helm-charts/releases/tag/operator-0.4.33) - 2024-11-6
229+
#### Added
230+
* Missing permissions for ClusterRoles, ClusterRoleBindings, Horizontal Pod Autoscaler, cert-manager/Certificate,
231+
cert-manager/Issuer, redpanda/Users, and redpanda/Schemas.
232+
#### Changed
233+
#### Fixed
234+
#### Removed
235+
228236
### [0.4.32](https://github.com/redpanda-data/helm-charts/releases/tag/operator-0.4.32) - 2024-10-31
229237
#### Added
230238
* Strategic merge of Pod volumes

charts/operator/Chart.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ type: application
66
# The chart version and the app version are not the same and will not track
77
# together. The chart version is a semver representation of changes to this
88
# chart.
9-
version: 0.4.32
9+
version: 0.4.33
1010

1111
# This is the default version of the operator being deployed.
1212
# ** NOTE for maintainers: please enssure the artifacthub image annotation is updated before merging
13-
appVersion: v2.2.5-24.2.7
13+
appVersion: v2.3.0-24.2.10
1414

1515
kubeVersion: ">= 1.25.0-0"
1616

@@ -36,11 +36,11 @@ annotations:
3636
url: https://helm.sh/docs/intro/install/
3737
artifacthub.io/images: |
3838
- name: redpanda-operator
39-
image: docker.redpanda.com/redpandadata/redpanda-operator:v2.2.5-24.2.7
39+
image: docker.redpanda.com/redpandadata/redpanda-operator:v2.3.0-24.2.10
4040
- name: configurator
41-
image: docker.redpanda.com/redpandadata/configurator:v2.2.5-24.2.7
41+
image: docker.redpanda.com/redpandadata/configurator:v2.3.0-24.2.10
4242
- name: redpanda
43-
image: docker.redpanda.com/redpandadata/redpanda:v24.2.7
43+
image: docker.redpanda.com/redpandadata/redpanda:v24.2.10
4444
- name: kube-rbac-proxy
4545
image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.0
4646
artifacthub.io/crds: |

charts/operator/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
description: Find the default values and descriptions of settings in the Redpanda Operator Helm chart.
44
---
55

6-
![Version: 0.4.32](https://img.shields.io/badge/Version-0.4.32-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.2.5-24.2.7](https://img.shields.io/badge/AppVersion-v2.2.5--24.2.7-informational?style=flat-square)
6+
![Version: 0.4.33](https://img.shields.io/badge/Version-0.4.33-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v2.2.5-24.2.7](https://img.shields.io/badge/AppVersion-v2.2.5--24.2.7-informational?style=flat-square)
77

88
This page describes the official Redpanda Operator Helm Chart. In particular, this page describes the contents of the chart’s [`values.yaml` file](https://github.com/redpanda-data/helm-charts/blob/main/charts/operator/values.yaml). Each of the settings is listed and described on this page, along with any default values.
99

charts/operator/chart_test.go

Lines changed: 109 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,103 @@
11
package operator
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"fmt"
7+
"log"
68
"os"
9+
"os/exec"
710
"regexp"
811
"slices"
912
"strconv"
1013
"testing"
1114

1215
fuzz "github.com/google/gofuzz"
1316
"github.com/redpanda-data/helm-charts/pkg/helm"
17+
"github.com/redpanda-data/helm-charts/pkg/kube"
1418
"github.com/redpanda-data/helm-charts/pkg/testutil"
1519
"github.com/santhosh-tekuri/jsonschema/v5"
20+
"github.com/stretchr/testify/assert"
1621
"github.com/stretchr/testify/require"
1722
"golang.org/x/tools/txtar"
1823
corev1 "k8s.io/api/core/v1"
24+
rbacv1 "k8s.io/api/rbac/v1"
25+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1926
"k8s.io/apimachinery/pkg/api/resource"
2027
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2128
"k8s.io/apimachinery/pkg/util/intstr"
2229
"k8s.io/utils/ptr"
30+
"sigs.k8s.io/kustomize/api/konfig"
31+
"sigs.k8s.io/kustomize/kustomize/v5/commands/build"
32+
"sigs.k8s.io/kustomize/kyaml/filesys"
2333
"sigs.k8s.io/yaml"
2434
)
2535

36+
func TestMain(m *testing.M) {
37+
// Chart deps are kept within ./charts as a tgz archive, which is git
38+
// ignored. Helm dep build will ensure that ./charts is in sync with
39+
// Chart.lock, which is tracked by git.
40+
// This is performed in TestMain as there may be many tests that run the
41+
// redpanda helm chart.
42+
out, err := exec.Command("helm", "repo", "add", "prometheus", "https://prometheus-community.github.io/helm-charts").CombinedOutput()
43+
if err != nil {
44+
log.Fatalf("failed to run helm repo add: %s", out)
45+
}
46+
47+
out, err = exec.Command("helm", "dep", "build", ".").CombinedOutput()
48+
if err != nil {
49+
log.Fatalf("failed to run helm dep build: %s", out)
50+
}
51+
52+
os.Exit(m.Run())
53+
}
54+
55+
func TestHelmKustomizeEquivalence(t *testing.T) {
56+
ctx := testutil.Context(t)
57+
client, err := helm.New(helm.Options{ConfigHome: testutil.TempDir(t)})
58+
require.NoError(t, err)
59+
60+
kustomization, err := os.ReadFile("testdata/kustomization.yaml")
61+
require.NoError(t, err)
62+
require.Containsf(t, string(kustomization), ChartMeta().AppVersion, "kustomization.yaml should reference the current appVersion: %s", chartMeta.AppVersion)
63+
64+
values := PartialValues{FullnameOverride: ptr.To("redpanda"), RBAC: &PartialRBAC{CreateAdditionalControllerCRs: ptr.To(true)}}
65+
66+
rendered, err := client.Template(ctx, ".", helm.TemplateOptions{
67+
Name: "redpanda",
68+
Namespace: "",
69+
Values: values,
70+
})
71+
require.NoError(t, err)
72+
73+
fSys := filesys.MakeFsOnDisk()
74+
buffy := new(bytes.Buffer)
75+
cmd := build.NewCmdBuild(
76+
fSys, build.MakeHelp(konfig.ProgramName, "build"), buffy)
77+
require.NoError(t, cmd.RunE(cmd, []string{"testdata"}))
78+
79+
helmObjs, err := kube.DecodeYAML(rendered, Scheme)
80+
require.NoError(t, err)
81+
82+
require.NoError(t, apiextensionsv1.AddToScheme(Scheme))
83+
kustomizeObjs, err := kube.DecodeYAML(buffy.Bytes(), Scheme)
84+
require.NoError(t, err)
85+
86+
helmClusterRoleRules, helmRoleRules := ExtractRules(helmObjs)
87+
kClusterRoleRules, kRoleRules := ExtractRules(kustomizeObjs)
88+
89+
assert.JSONEq(t, jsonStr(helmRoleRules), jsonStr(kRoleRules), "difference in Roles\n--- Helm / Missing from Kustomize\n+++ Kustomize / Missing from Helm")
90+
assert.JSONEq(t, jsonStr(helmClusterRoleRules), jsonStr(kClusterRoleRules), "difference in ClusterRoles\n--- Helm / Missing from Kustomize\n+++ Kustomize / Missing from Helm")
91+
}
92+
93+
func jsonStr(in any) string {
94+
out, err := json.Marshal(in)
95+
if err != nil {
96+
panic(err)
97+
}
98+
return string(out)
99+
}
100+
26101
// TestValues asserts that the chart's values.yaml file can be losslessly
27102
// loaded into our type [Values] struct.
28103
// NB: values.yaml should round trip through [Values], not [PartialValues], as
@@ -48,12 +123,6 @@ func TestTemplate(t *testing.T) {
48123
client, err := helm.New(helm.Options{ConfigHome: testutil.TempDir(t)})
49124
require.NoError(t, err)
50125

51-
// Chart deps are kept within ./charts as a tgz archive, which is git
52-
// ignored. Helm dep build will ensure that ./charts is in sync with
53-
// Chart.lock, which is tracked by git.
54-
require.NoError(t, client.RepoAdd(ctx, "prometheus", "https://prometheus-community.github.io/helm-charts"))
55-
require.NoError(t, client.DependencyBuild(ctx, "."), "failed to refresh helm dependencies")
56-
57126
casesArchive, err := txtar.ParseFile("testdata/template-cases.txtar")
58127
require.NoError(t, err)
59128

@@ -222,3 +291,37 @@ func makeSureTagIsNotEmptyString(values PartialValues, fuzzer *fuzz.Fuzzer) {
222291
}
223292
}
224293
}
294+
295+
func CalculateRoleRules(rules []rbacv1.PolicyRule) map[string]map[string]struct{} {
296+
flattened := map[string]map[string]struct{}{}
297+
for _, rule := range rules {
298+
for _, api := range rule.APIGroups {
299+
for _, res := range rule.Resources {
300+
key := fmt.Sprintf("%s#%s", api, res)
301+
302+
if _, ok := flattened[key]; !ok {
303+
flattened[key] = map[string]struct{}{}
304+
}
305+
306+
for _, verb := range rule.Verbs {
307+
flattened[key][verb] = struct{}{}
308+
}
309+
}
310+
}
311+
}
312+
return flattened
313+
}
314+
315+
func ExtractRules(objs []kube.Object) (map[string]map[string]struct{}, map[string]map[string]struct{}) {
316+
var rules []rbacv1.PolicyRule
317+
var clusterRules []rbacv1.PolicyRule
318+
for _, o := range objs {
319+
switch obj := o.(type) {
320+
case *rbacv1.Role:
321+
rules = append(rules, obj.Rules...)
322+
case *rbacv1.ClusterRole:
323+
clusterRules = append(clusterRules, obj.Rules...)
324+
}
325+
}
326+
return CalculateRoleRules(clusterRules), CalculateRoleRules(rules)
327+
}

0 commit comments

Comments
 (0)