Skip to content

Commit 9daabd3

Browse files
committed
fix: read owner GVK from object metadata instead of scheme
The operator does not know the CNPG API group at runtime (it is not a sidecar injected by the CNPG operator, so CUSTOM_CNPG_GROUP and CUSTOM_CNPG_VERSION are not available). Move SetControllerReference to the specs package and read the GVK from the decoded Cluster's TypeMeta rather than looking it up in the scheme. Remove CNPG types from the operator's scheme and the env var bindings from cmd/operator since they are no longer needed. Signed-off-by: Marco Nenciarini <marco.nenciarini@enterprisedb.com>
1 parent 8899349 commit 9daabd3

10 files changed

Lines changed: 203 additions & 23 deletions

File tree

internal/cmd/operator/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ func NewCmd() *cobra.Command {
102102
_ = viper.BindPFlag("server-address", cmd.Flags().Lookup("server-address"))
103103

104104
_ = viper.BindEnv("sidecar-image", "SIDECAR_IMAGE")
105-
_ = viper.BindEnv("custom-cnpg-group", "CUSTOM_CNPG_GROUP")
106-
_ = viper.BindEnv("custom-cnpg-version", "CUSTOM_CNPG_VERSION")
107105

108106
return cmd
109107
}

internal/cnpgi/operator/manager.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,33 +37,24 @@ import (
3737

3838
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
3939
"github.com/cloudnative-pg/plugin-barman-cloud/internal/controller"
40-
pluginscheme "github.com/cloudnative-pg/plugin-barman-cloud/internal/scheme"
4140

4241
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
4342
// to ensure that exec-entrypoint and run can make use of them.
4443
_ "k8s.io/client-go/plugin/pkg/client/auth"
4544
)
4645

47-
// generateScheme creates a runtime.Scheme with all type definitions
48-
// needed by the operator. CNPG types are registered under a
49-
// configurable API group to support custom CNPG-based operators.
50-
func generateScheme(ctx context.Context) *runtime.Scheme {
51-
result := runtime.NewScheme()
46+
var scheme = runtime.NewScheme()
5247

53-
utilruntime.Must(clientgoscheme.AddToScheme(result))
54-
utilruntime.Must(barmancloudv1.AddToScheme(result))
55-
pluginscheme.AddCNPGToScheme(ctx, result)
48+
func init() {
49+
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
50+
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
5651
// +kubebuilder:scaffold:scheme
57-
58-
return result
5952
}
6053

6154
// Start starts the manager
6255
func Start(ctx context.Context) error {
6356
setupLog := log.FromContext(ctx)
6457

65-
scheme := generateScheme(ctx)
66-
6758
var tlsOpts []func(*tls.Config)
6859

6960
// if the enable-http2 flag is false (the default), http/2 should be disabled
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
Copyright © contributors to CloudNativePG, established as
3+
CloudNativePG a Series of LF Projects, LLC.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
SPDX-License-Identifier: Apache-2.0
18+
*/
19+
20+
// Package rbac contains utilities to reconcile RBAC resources
21+
// for the barman-cloud plugin.
22+
package rbac

internal/cnpgi/operator/rbac/ensure.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ limitations under the License.
1717
SPDX-License-Identifier: Apache-2.0
1818
*/
1919

20-
// Package rbac contains utilities to reconcile RBAC resources
21-
// for the barman-cloud plugin.
2220
package rbac
2321

2422
import (
@@ -31,7 +29,6 @@ import (
3129
apierrs "k8s.io/apimachinery/pkg/api/errors"
3230
"k8s.io/client-go/util/retry"
3331
"sigs.k8s.io/controller-runtime/pkg/client"
34-
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3532

3633
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
3734
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
@@ -106,7 +103,7 @@ func ensureRoleExists(
106103
return err
107104
}
108105

109-
if err := controllerutil.SetControllerReference(cluster, newRole, c.Scheme()); err != nil {
106+
if err := specs.SetControllerReference(cluster, newRole); err != nil {
110107
return err
111108
}
112109

internal/cnpgi/operator/rbac/ensure_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ func newScheme() *runtime.Scheme {
4949

5050
func newCluster(name, namespace string) *cnpgv1.Cluster {
5151
return &cnpgv1.Cluster{
52+
TypeMeta: metav1.TypeMeta{
53+
APIVersion: cnpgv1.SchemeGroupVersion.String(),
54+
Kind: cnpgv1.ClusterKind,
55+
},
5256
ObjectMeta: metav1.ObjectMeta{
5357
Name: name,
5458
Namespace: namespace,

internal/cnpgi/operator/reconciler.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
rbacv1 "k8s.io/api/rbac/v1"
3131
apierrs "k8s.io/apimachinery/pkg/api/errors"
3232
"sigs.k8s.io/controller-runtime/pkg/client"
33-
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
3433

3534
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
3635
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
@@ -163,7 +162,7 @@ func (r ReconcilerImplementation) createRoleBinding(
163162
cluster *cnpgv1.Cluster,
164163
) error {
165164
roleBinding := specs.BuildRoleBinding(cluster)
166-
if err := controllerutil.SetControllerReference(cluster, roleBinding, r.Client.Scheme()); err != nil {
165+
if err := specs.SetControllerReference(cluster, roleBinding); err != nil {
167166
return err
168167
}
169168
return r.Client.Create(ctx, roleBinding)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
Copyright © contributors to CloudNativePG, established as
3+
CloudNativePG a Series of LF Projects, LLC.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
SPDX-License-Identifier: Apache-2.0
18+
*/
19+
20+
package specs
21+
22+
import (
23+
"fmt"
24+
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/apimachinery/pkg/runtime"
27+
"k8s.io/utils/ptr"
28+
)
29+
30+
// SetControllerReference sets an owner reference on controlled
31+
// pointing to owner, reading the GVK from the owner object's
32+
// metadata rather than from a scheme. This is necessary because
33+
// the operator does not know the CNPG API group at compile time
34+
// (it may be customized), while the Cluster object decoded from
35+
// the gRPC request carries the correct GVK in its TypeMeta.
36+
func SetControllerReference(owner, controlled metav1.Object) error {
37+
ro, ok := owner.(runtime.Object)
38+
if !ok {
39+
return fmt.Errorf("%T is not a runtime.Object, cannot call SetControllerReference", owner)
40+
}
41+
42+
gvk := ro.GetObjectKind().GroupVersionKind()
43+
if gvk.Kind == "" {
44+
return fmt.Errorf("%T has no GVK set in its metadata, cannot call SetControllerReference", owner)
45+
}
46+
47+
controlled.SetOwnerReferences([]metav1.OwnerReference{
48+
{
49+
APIVersion: gvk.GroupVersion().String(),
50+
Kind: gvk.Kind,
51+
Name: owner.GetName(),
52+
UID: owner.GetUID(),
53+
BlockOwnerDeletion: ptr.To(true),
54+
Controller: ptr.To(true),
55+
},
56+
})
57+
58+
return nil
59+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright © contributors to CloudNativePG, established as
3+
CloudNativePG a Series of LF Projects, LLC.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
SPDX-License-Identifier: Apache-2.0
18+
*/
19+
20+
package specs
21+
22+
import (
23+
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
24+
. "github.com/onsi/ginkgo/v2"
25+
. "github.com/onsi/gomega"
26+
rbacv1 "k8s.io/api/rbac/v1"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/apimachinery/pkg/types"
29+
)
30+
31+
var _ = Describe("SetControllerReference", func() {
32+
It("should set the owner reference from the owner's TypeMeta", func() {
33+
owner := &cnpgv1.Cluster{
34+
TypeMeta: metav1.TypeMeta{
35+
APIVersion: "postgresql.cnpg.io/v1",
36+
Kind: "Cluster",
37+
},
38+
ObjectMeta: metav1.ObjectMeta{
39+
Name: "my-cluster",
40+
Namespace: "default",
41+
UID: types.UID("test-uid"),
42+
},
43+
}
44+
controlled := &rbacv1.Role{
45+
ObjectMeta: metav1.ObjectMeta{
46+
Name: "my-role",
47+
Namespace: "default",
48+
},
49+
}
50+
51+
Expect(SetControllerReference(owner, controlled)).To(Succeed())
52+
Expect(controlled.OwnerReferences).To(HaveLen(1))
53+
Expect(controlled.OwnerReferences[0].APIVersion).To(Equal("postgresql.cnpg.io/v1"))
54+
Expect(controlled.OwnerReferences[0].Kind).To(Equal("Cluster"))
55+
Expect(controlled.OwnerReferences[0].Name).To(Equal("my-cluster"))
56+
Expect(controlled.OwnerReferences[0].UID).To(Equal(types.UID("test-uid")))
57+
Expect(*controlled.OwnerReferences[0].Controller).To(BeTrue())
58+
Expect(*controlled.OwnerReferences[0].BlockOwnerDeletion).To(BeTrue())
59+
})
60+
61+
It("should work with a custom CNPG API group", func() {
62+
owner := &cnpgv1.Cluster{
63+
TypeMeta: metav1.TypeMeta{
64+
APIVersion: "mycompany.io/v1",
65+
Kind: "Cluster",
66+
},
67+
ObjectMeta: metav1.ObjectMeta{
68+
Name: "my-cluster",
69+
UID: types.UID("test-uid"),
70+
},
71+
}
72+
controlled := &rbacv1.Role{}
73+
74+
Expect(SetControllerReference(owner, controlled)).To(Succeed())
75+
Expect(controlled.OwnerReferences[0].APIVersion).To(Equal("mycompany.io/v1"))
76+
})
77+
78+
It("should fail when the owner has no GVK set", func() {
79+
owner := &cnpgv1.Cluster{
80+
ObjectMeta: metav1.ObjectMeta{
81+
Name: "my-cluster",
82+
},
83+
}
84+
controlled := &rbacv1.Role{}
85+
86+
err := SetControllerReference(owner, controlled)
87+
Expect(err).To(HaveOccurred())
88+
Expect(err.Error()).To(ContainSubstring("has no GVK set"))
89+
})
90+
})

internal/scheme/cnpg.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ limitations under the License.
1717
SPDX-License-Identifier: Apache-2.0
1818
*/
1919

20-
// Package scheme provides utilities for building runtime schemes
21-
// with support for custom CNPG API groups.
2220
package scheme
2321

2422
import (

internal/scheme/doc.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
Copyright © contributors to CloudNativePG, established as
3+
CloudNativePG a Series of LF Projects, LLC.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
SPDX-License-Identifier: Apache-2.0
18+
*/
19+
20+
// Package scheme provides utilities for building runtime schemes
21+
// with support for custom CNPG API groups.
22+
package scheme

0 commit comments

Comments
 (0)