Skip to content

Commit

Permalink
clusterctl: fix target namespace in v1beta CRDs and WebhookConfigurat…
Browse files Browse the repository at this point in the history
…ions

Signed-off-by: Stefan Büringer [email protected]
  • Loading branch information
sbueringer committed Aug 16, 2021
1 parent 8ff6ec8 commit 622d017
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 29 deletions.
96 changes: 68 additions & 28 deletions cmd/clusterctl/client/repository/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import (

"github.com/pkg/errors"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
rbacv1 "k8s.io/api/rbac/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
Expand Down Expand Up @@ -340,47 +342,85 @@ func fixWebHookNamespaceReferences(o unstructured.Unstructured, targetNamespace
o.SetAnnotations(annotations)
}

version := o.GetObjectKind().GroupVersionKind().Version
var err error
switch o.GetKind() {
case mutatingWebhookConfigurationKind:
b := &admissionregistrationv1.MutatingWebhookConfiguration{}
if err := scheme.Scheme.Convert(&o, b, nil); err != nil {
return o, err
}

for _, w := range b.Webhooks {
if w.ClientConfig.Service != nil {
w.ClientConfig.Service.Namespace = targetNamespace
switch version {
case "v1beta1":
b := &admissionregistrationv1beta1.MutatingWebhookConfiguration{}
if err := scheme.Scheme.Convert(&o, b, nil); err != nil {
return o, err
}
for _, w := range b.Webhooks {
if w.ClientConfig.Service != nil {
w.ClientConfig.Service.Namespace = targetNamespace
}
}
err = scheme.Scheme.Convert(b, &o, nil)
case "v1":
b := &admissionregistrationv1.MutatingWebhookConfiguration{}
if err := scheme.Scheme.Convert(&o, b, nil); err != nil {
return o, err
}
for _, w := range b.Webhooks {
if w.ClientConfig.Service != nil {
w.ClientConfig.Service.Namespace = targetNamespace
}
}
err = scheme.Scheme.Convert(b, &o, nil)
}

err = scheme.Scheme.Convert(b, &o, nil)

case validatingWebhookConfigurationKind:
b := &admissionregistrationv1.ValidatingWebhookConfiguration{}
if err := scheme.Scheme.Convert(&o, b, nil); err != nil {
return o, err
}

for _, w := range b.Webhooks {
if w.ClientConfig.Service != nil {
w.ClientConfig.Service.Namespace = targetNamespace
switch version {
case "v1beta1":
b := &admissionregistrationv1beta1.ValidatingWebhookConfiguration{}
if err := scheme.Scheme.Convert(&o, b, nil); err != nil {
return o, err
}
for _, w := range b.Webhooks {
if w.ClientConfig.Service != nil {
w.ClientConfig.Service.Namespace = targetNamespace
}
}
err = scheme.Scheme.Convert(b, &o, nil)
case "v1":
b := &admissionregistrationv1.ValidatingWebhookConfiguration{}
if err := scheme.Scheme.Convert(&o, b, nil); err != nil {
return o, err
}
for _, w := range b.Webhooks {
if w.ClientConfig.Service != nil {
w.ClientConfig.Service.Namespace = targetNamespace
}
}
err = scheme.Scheme.Convert(b, &o, nil)
}

err = scheme.Scheme.Convert(b, &o, nil)

case customResourceDefinitionKind:
crd := &apiextensionsv1.CustomResourceDefinition{}
if err := scheme.Scheme.Convert(&o, crd, nil); err != nil {
return o, err
}
switch version {
case "v1beta1":
crd := &apiextensionsv1beta1.CustomResourceDefinition{}
if err := scheme.Scheme.Convert(&o, crd, nil); err != nil {
return o, err
}
if crd.Spec.Conversion != nil && crd.Spec.Conversion.WebhookClientConfig != nil && crd.Spec.Conversion.WebhookClientConfig.Service != nil {
crd.Spec.Conversion.WebhookClientConfig.Service.Namespace = targetNamespace
}
err = scheme.Scheme.Convert(crd, &o, nil)

if crd.Spec.Conversion != nil && crd.Spec.Conversion.Webhook != nil && crd.Spec.Conversion.Webhook.ClientConfig != nil && crd.Spec.Conversion.Webhook.ClientConfig.Service != nil {
crd.Spec.Conversion.Webhook.ClientConfig.Service.Namespace = targetNamespace
case "v1":
crd := &apiextensionsv1.CustomResourceDefinition{}
if err := scheme.Scheme.Convert(&o, crd, nil); err != nil {
return o, err
}
if crd.Spec.Conversion != nil && crd.Spec.Conversion.Webhook != nil && crd.Spec.Conversion.Webhook.ClientConfig != nil && crd.Spec.Conversion.Webhook.ClientConfig.Service != nil {
crd.Spec.Conversion.Webhook.ClientConfig.Service.Namespace = targetNamespace
}
err = scheme.Scheme.Convert(crd, &o, nil)
default:
return o, errors.Errorf("unsupported CustomResourceDefinition version: %s", version)
}

err = scheme.Scheme.Convert(crd, &o, nil)
}
return o, err
}
Expand Down
125 changes: 124 additions & 1 deletion cmd/clusterctl/client/repository/components_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,63 @@ func Test_fixTargetNamespace(t *testing.T) {
},
},
{
name: "fix v1beta1 webhook configs",
objs: []unstructured.Unstructured{
{
Object: map[string]interface{}{
"apiVersion": "admissionregistration.k8s.io/v1beta1",
"kind": "MutatingWebhookConfiguration",
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{
"cert-manager.io/inject-ca-from": "capi-webhook-system/capm3-serving-cert",
},
"name": "capm3-mutating-webhook-configuration",
},
"webhooks": []interface{}{
map[string]interface{}{
"clientConfig": map[string]interface{}{
"caBundle": "Cg==",
"service": map[string]interface{}{
"name": "capm3-webhook-service",
"namespace": "capi-webhook-system",
"path": "/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-metal3cluster",
},
},
},
},
},
},
},
targetNamespace: "bar",
want: []unstructured.Unstructured{
{
Object: map[string]interface{}{
"apiVersion": "admissionregistration.k8s.io/v1beta1",
"kind": "MutatingWebhookConfiguration",
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{
"cert-manager.io/inject-ca-from": "bar/capm3-serving-cert",
},
"creationTimestamp": nil,
"name": "capm3-mutating-webhook-configuration",
},
"webhooks": []interface{}{
map[string]interface{}{
"name": "",
"clientConfig": map[string]interface{}{
"service": map[string]interface{}{
"name": "capm3-webhook-service",
"path": "/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-metal3cluster",
"namespace": "bar",
},
"caBundle": "Cg==",
},
},
},
},
},
},
}, {
name: "fix v1 webhook configs",
objs: []unstructured.Unstructured{
{
Expand Down Expand Up @@ -263,7 +320,73 @@ func Test_fixTargetNamespace(t *testing.T) {
},
},
{
name: "fix crd webhook namespace",
name: "fix v1beta1 crd webhook namespace",
objs: []unstructured.Unstructured{
{
Object: map[string]interface{}{
"apiVersion": "apiextensions.k8s.io/v1beta1",
"kind": "CustomResourceDefinition",
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{
"cert-manager.io/inject-ca-from": "capi-webhook-system/capm3-serving-cert",
},
"name": "aCoolName",
},
"spec": map[string]interface{}{
"conversion": map[string]interface{}{
"strategy": "Webhook",
"webhookClientConfig": map[string]interface{}{
"caBundle": "Cg==",
"service": map[string]interface{}{
"name": "capa-webhook-service",
"namespace": "capi-webhook-system",
"path": "/convert",
},
},
},
},
},
},
},
targetNamespace: "bar",
want: []unstructured.Unstructured{
{
Object: map[string]interface{}{
"apiVersion": "apiextensions.k8s.io/v1beta1",
"kind": "CustomResourceDefinition",
"metadata": map[string]interface{}{
"annotations": map[string]interface{}{
"cert-manager.io/inject-ca-from": "bar/capm3-serving-cert",
},
"creationTimestamp": nil,
"name": "aCoolName",
},
"spec": map[string]interface{}{
"group": "",
"names": map[string]interface{}{"plural": "", "kind": ""},
"scope": "",
"conversion": map[string]interface{}{
"strategy": "Webhook",
"webhookClientConfig": map[string]interface{}{
"caBundle": "Cg==",
"service": map[string]interface{}{
"name": "capa-webhook-service",
"namespace": "bar",
"path": "/convert",
},
},
},
},
"status": map[string]interface{}{
"storedVersions": nil,
"conditions": nil,
"acceptedNames": map[string]interface{}{"kind": "", "plural": ""},
},
},
},
},
}, {
name: "fix v1 crd webhook namespace",
objs: []unstructured.Unstructured{
{
Object: map[string]interface{}{
Expand Down
2 changes: 2 additions & 0 deletions cmd/clusterctl/internal/scheme/scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
admissionregistration "k8s.io/api/admissionregistration/v1"
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
Expand All @@ -38,6 +39,7 @@ func init() {
_ = clusterctlv1.AddToScheme(Scheme)
_ = clusterv1.AddToScheme(Scheme)
_ = apiextensionsv1.AddToScheme(Scheme)
_ = apiextensionsv1beta1.AddToScheme(Scheme)
_ = admissionregistration.AddToScheme(Scheme)
_ = admissionregistrationv1beta1.AddToScheme(Scheme)
_ = addonsv1.AddToScheme(Scheme)
Expand Down

0 comments on commit 622d017

Please sign in to comment.