Skip to content
This repository was archived by the owner on Mar 26, 2025. It is now read-only.

Commit cf1cdc4

Browse files
authored
Fix Kafka topic creation bug due to recent upgrade of AdmissionReview version (#796)
* Update admission pkg name; add API version and Kind to HTTP request * Fix lint error * Add deleted imports by * Specify Kind and APIVersion when initializing admissionReview * Make lint-fix
1 parent 6cdcb6a commit cf1cdc4

File tree

3 files changed

+29
-30
lines changed

3 files changed

+29
-30
lines changed

pkg/webhook/request.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"net/http"
2323
"reflect"
2424

25-
admissionv1beta1 "k8s.io/api/admission/v1beta1"
25+
admissionv1 "k8s.io/api/admission/v1"
2626
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2727

2828
"github.com/banzaicloud/koperator/pkg/util"
@@ -34,7 +34,7 @@ var (
3434
kafkaTopic = reflect.TypeOf(v1alpha1.KafkaTopic{}).Name()
3535
)
3636

37-
func (s *webhookServer) validate(ar *admissionv1beta1.AdmissionReview) *admissionv1beta1.AdmissionResponse {
37+
func (s *webhookServer) validate(ar *admissionv1.AdmissionReview) *admissionv1.AdmissionResponse {
3838
req := ar.Request
3939

4040
l := log.WithValues("kind", req.Kind, "namespace", req.Namespace, "name", req.Name, "uid", req.UID,
@@ -50,7 +50,7 @@ func (s *webhookServer) validate(ar *admissionv1beta1.AdmissionReview) *admissio
5050
}
5151
if ok := util.ObjectManagedByClusterRegistry(topic.GetObjectMeta()); ok {
5252
l.Info("Skip validation as the resource is managed by Cluster Registry")
53-
return &admissionv1beta1.AdmissionResponse{
53+
return &admissionv1.AdmissionResponse{
5454
Allowed: true,
5555
}
5656
}
@@ -85,16 +85,22 @@ func (s *webhookServer) serve(w http.ResponseWriter, r *http.Request) {
8585
return
8686
}
8787

88-
var admissionResponse *admissionv1beta1.AdmissionResponse
89-
ar := admissionv1beta1.AdmissionReview{}
88+
var admissionResponse *admissionv1.AdmissionResponse
89+
ar := admissionv1.AdmissionReview{}
9090
if _, _, err := s.deserializer.Decode(body, nil, &ar); err != nil {
9191
log.Error(err, "Can't decode body")
9292
admissionResponse = notAllowed(err.Error(), metav1.StatusReasonBadRequest)
9393
} else {
9494
admissionResponse = s.validate(&ar)
9595
}
9696

97-
admissionReview := admissionv1beta1.AdmissionReview{}
97+
admissionReview := admissionv1.AdmissionReview{
98+
// APIVersion and Kind must be set for admission/v1, or the request would fail
99+
TypeMeta: metav1.TypeMeta{
100+
APIVersion: admissionv1.SchemeGroupVersion.String(),
101+
Kind: "AdmissionReview",
102+
},
103+
}
98104
if admissionResponse != nil {
99105
admissionReview.Response = admissionResponse
100106
if ar.Request != nil {
@@ -113,8 +119,8 @@ func (s *webhookServer) serve(w http.ResponseWriter, r *http.Request) {
113119
}
114120
}
115121

116-
func notAllowed(msg string, reason metav1.StatusReason) *admissionv1beta1.AdmissionResponse {
117-
return &admissionv1beta1.AdmissionResponse{
122+
func notAllowed(msg string, reason metav1.StatusReason) *admissionv1.AdmissionResponse {
123+
return &admissionv1.AdmissionResponse{
118124
Result: &metav1.Status{
119125
Message: msg,
120126
Reason: reason,

pkg/webhook/request_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
"strings"
2525
"testing"
2626

27-
admissionv1beta1 "k8s.io/api/admission/v1beta1"
27+
admissionv1 "k8s.io/api/admission/v1"
2828
authv1 "k8s.io/api/authentication/v1"
2929
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3030

@@ -41,9 +41,9 @@ func newRawTopic() []byte {
4141
return out
4242
}
4343

44-
func newAdmissionReview() *admissionv1beta1.AdmissionReview {
45-
return &admissionv1beta1.AdmissionReview{
46-
Request: &admissionv1beta1.AdmissionRequest{
44+
func newAdmissionReview() *admissionv1.AdmissionReview {
45+
return &admissionv1.AdmissionReview{
46+
Request: &admissionv1.AdmissionRequest{
4747
Kind: metav1.GroupVersionKind{
4848
Kind: "non-topic-kind",
4949
},
@@ -170,7 +170,7 @@ func TestServe(t *testing.T) {
170170
if err != nil {
171171
t.Error("Expected admission review response, got error")
172172
}
173-
admissionReview := admissionv1beta1.AdmissionReview{}
173+
admissionReview := admissionv1.AdmissionReview{}
174174
if err := json.Unmarshal(body, &admissionReview); err != nil {
175175
t.Error("Expected no error got:", err)
176176
}
@@ -196,7 +196,7 @@ func TestServe(t *testing.T) {
196196
if err != nil {
197197
t.Error("Expected admission review response, got error")
198198
}
199-
admissionReview := admissionv1beta1.AdmissionReview{}
199+
admissionReview := admissionv1.AdmissionReview{}
200200
if err := json.Unmarshal(body, &admissionReview); err != nil {
201201
t.Error("Expected no error got:", err)
202202
}

pkg/webhook/topic_validator.go

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020

2121
"github.com/banzaicloud/koperator/pkg/util"
2222

23-
admissionv1beta1 "k8s.io/api/admission/v1beta1"
23+
admissionv1 "k8s.io/api/admission/v1"
2424
apierrors "k8s.io/apimachinery/pkg/api/errors"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2626
"k8s.io/apimachinery/pkg/types"
@@ -36,7 +36,7 @@ const (
3636
invalidReplicationFactorErrMsg = "Replication factor is larger than the number of nodes in the kafka cluster"
3737
)
3838

39-
func (s *webhookServer) validateKafkaTopic(topic *banzaicloudv1alpha1.KafkaTopic) *admissionv1beta1.AdmissionResponse {
39+
func (s *webhookServer) validateKafkaTopic(topic *banzaicloudv1alpha1.KafkaTopic) *admissionv1.AdmissionResponse {
4040
ctx := context.Background()
4141
log.Info(fmt.Sprintf("Doing pre-admission validation of kafka topic %s", topic.Spec.Name))
4242

@@ -54,25 +54,21 @@ func (s *webhookServer) validateKafkaTopic(topic *banzaicloudv1alpha1.KafkaTopic
5454
if apierrors.IsNotFound(err) {
5555
if k8sutil.IsMarkedForDeletion(topic.ObjectMeta) {
5656
log.Info("Deleted as a result of a cluster deletion")
57-
return &admissionv1beta1.AdmissionResponse{
57+
return &admissionv1.AdmissionResponse{
5858
Allowed: true,
5959
}
6060
}
6161
log.Error(err, "Referenced kafka cluster does not exist")
62-
return notAllowed(
63-
fmt.Sprintf("KafkaCluster '%s' in the namespace '%s' does not exist", topic.Spec.ClusterRef.Name, topic.Spec.ClusterRef.Namespace),
64-
metav1.StatusReasonNotFound,
65-
)
62+
return notAllowed(fmt.Sprintf("KafkaCluster '%s' in the namespace '%s' does not exist", topic.Spec.ClusterRef.Name, topic.Spec.ClusterRef.Namespace), metav1.StatusReasonNotFound)
6663
}
6764
log.Error(err, "API failure while running topic validation")
6865
return notAllowed("API failure while validating topic, please try again", metav1.StatusReasonServiceUnavailable)
6966
}
70-
7167
if k8sutil.IsMarkedForDeletion(cluster.ObjectMeta) {
7268
// Let this through, it's a delete topic request from a parent cluster being
7369
// deleted
7470
log.Info("Cluster is going down for deletion, assuming a delete topic request")
75-
return &admissionv1beta1.AdmissionResponse{
71+
return &admissionv1.AdmissionResponse{
7672
Allowed: true,
7773
}
7874
}
@@ -96,15 +92,15 @@ func (s *webhookServer) validateKafkaTopic(topic *banzaicloudv1alpha1.KafkaTopic
9692
}
9793

9894
// everything looks a-okay
99-
return &admissionv1beta1.AdmissionResponse{
95+
return &admissionv1.AdmissionResponse{
10096
Allowed: true,
10197
}
10298
}
10399

104100
// checkKafka creates a Kafka admin client and connects to the Kafka brokers to check
105101
// whether the referred topic exists, and what are its properties
106102
func (s *webhookServer) checkKafka(ctx context.Context, topic *banzaicloudv1alpha1.KafkaTopic,
107-
cluster *banzaicloudv1beta1.KafkaCluster) *admissionv1beta1.AdmissionResponse {
103+
cluster *banzaicloudv1beta1.KafkaCluster) *admissionv1.AdmissionResponse {
108104
// retrieve an admin client for the cluster
109105
broker, closeClient, err := s.newKafkaFromCluster(s.client, cluster)
110106
if err != nil {
@@ -128,10 +124,7 @@ func (s *webhookServer) checkKafka(ctx context.Context, topic *banzaicloudv1alph
128124
if apierrors.IsNotFound(err) {
129125
// User is trying to overwrite an existing topic - bad user
130126
log.Info("User attempted to create topic with name that already exists in the kafka cluster")
131-
return notAllowed(
132-
fmt.Sprintf("Topic '%s' already exists on kafka cluster '%s'", topic.Spec.Name, topic.Spec.ClusterRef.Name),
133-
metav1.StatusReasonAlreadyExists,
134-
)
127+
return notAllowed(fmt.Sprintf("Topic '%s' already exists on kafka cluster '%s'", topic.Spec.Name, topic.Spec.ClusterRef.Name), metav1.StatusReasonAlreadyExists)
135128
}
136129
log.Error(err, "API failure while running topic validation")
137130
return notAllowed("API failure while validating topic, please try again", metav1.StatusReasonServiceUnavailable)
@@ -160,7 +153,7 @@ func (s *webhookServer) checkKafka(ctx context.Context, topic *banzaicloudv1alph
160153
// checkExistingKafkaTopicCRs checks whether there's any other duplicate KafkaTopic CR exists
161154
// that refers to the same KafkaCluster's same topic
162155
func (s *webhookServer) checkExistingKafkaTopicCRs(ctx context.Context,
163-
clusterNamespace string, topic *banzaicloudv1alpha1.KafkaTopic) *admissionv1beta1.AdmissionResponse {
156+
clusterNamespace string, topic *banzaicloudv1alpha1.KafkaTopic) *admissionv1.AdmissionResponse {
164157
// check KafkaTopic in the referred KafkaCluster's namespace
165158
kafkaTopicList := banzaicloudv1alpha1.KafkaTopicList{}
166159
err := s.client.List(ctx, &kafkaTopicList, client.MatchingFields{"spec.name": topic.Spec.Name})

0 commit comments

Comments
 (0)