knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/webhook/resourcesemantics/conversion/table_test.go (about)

     1  /*
     2  Copyright 2020 The Knative Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package conversion
    18  
    19  import (
    20  	"context"
    21  	"testing"
    22  
    23  	corev1 "k8s.io/api/core/v1"
    24  	apixv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    25  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	clientgotesting "k8s.io/client-go/testing"
    28  	apixclient "knative.dev/pkg/client/injection/apiextensions/client/fake"
    29  	"knative.dev/pkg/configmap"
    30  	"knative.dev/pkg/controller"
    31  	"knative.dev/pkg/ptr"
    32  	"knative.dev/pkg/system"
    33  	certresources "knative.dev/pkg/webhook/certificates/resources"
    34  
    35  	. "knative.dev/pkg/reconciler/testing"
    36  	. "knative.dev/pkg/webhook/testing"
    37  )
    38  
    39  func TestReconcile(t *testing.T) {
    40  	key := "some.crd.group.dev"
    41  	path := "/some/path"
    42  	secretName := "webhook-secret"
    43  
    44  	secret := &corev1.Secret{
    45  		ObjectMeta: metav1.ObjectMeta{
    46  			Name:      secretName,
    47  			Namespace: system.Namespace(),
    48  		},
    49  		Data: map[string][]byte{
    50  			certresources.ServerKey:  []byte("present"),
    51  			certresources.ServerCert: []byte("present"),
    52  			certresources.CACert:     []byte("present"),
    53  		},
    54  	}
    55  
    56  	table := TableTest{{
    57  		Name:    "no secret",
    58  		Key:     key,
    59  		WantErr: true,
    60  	}, {
    61  		Name: "secret missing CA Cert",
    62  		Key:  key,
    63  		Objects: []runtime.Object{&corev1.Secret{
    64  			ObjectMeta: metav1.ObjectMeta{
    65  				Name:      secretName,
    66  				Namespace: system.Namespace(),
    67  			},
    68  			Data: map[string][]byte{
    69  				certresources.ServerKey:  []byte("present"),
    70  				certresources.ServerCert: []byte("present"),
    71  				// certresources.CACert:     []byte("missing"),
    72  			},
    73  		}},
    74  		WantErr: true,
    75  	}, {
    76  		Name:    "secret exists, but CRD does not",
    77  		Key:     key,
    78  		Objects: []runtime.Object{secret},
    79  		WantErr: true,
    80  	}, {
    81  		Name: "secret and CRD exist, missing service reference",
    82  		Key:  key,
    83  		Objects: []runtime.Object{
    84  			secret,
    85  			&apixv1.CustomResourceDefinition{
    86  				ObjectMeta: metav1.ObjectMeta{
    87  					Name: key,
    88  				},
    89  				Spec: apixv1.CustomResourceDefinitionSpec{
    90  					Conversion: &apixv1.CustomResourceConversion{},
    91  				},
    92  			},
    93  		},
    94  		WantErr: true,
    95  	}, {
    96  		Name: "secret and CRD exist, missing other stuff",
    97  		Key:  key,
    98  		Objects: []runtime.Object{
    99  			secret,
   100  			&apixv1.CustomResourceDefinition{
   101  				ObjectMeta: metav1.ObjectMeta{
   102  					Name: key,
   103  				},
   104  				Spec: apixv1.CustomResourceDefinitionSpec{
   105  					Conversion: &apixv1.CustomResourceConversion{
   106  						Strategy: apixv1.WebhookConverter,
   107  						Webhook: &apixv1.WebhookConversion{
   108  							ClientConfig: &apixv1.WebhookClientConfig{
   109  								Service: &apixv1.ServiceReference{
   110  									Namespace: system.Namespace(),
   111  									Name:      "webhook",
   112  								},
   113  							},
   114  						},
   115  					},
   116  				},
   117  			},
   118  		},
   119  		WantUpdates: []clientgotesting.UpdateActionImpl{{
   120  			Object: &apixv1.CustomResourceDefinition{
   121  				ObjectMeta: metav1.ObjectMeta{
   122  					Name: key,
   123  				},
   124  				Spec: apixv1.CustomResourceDefinitionSpec{
   125  					Conversion: &apixv1.CustomResourceConversion{
   126  						Strategy: apixv1.WebhookConverter,
   127  						Webhook: &apixv1.WebhookConversion{
   128  							ClientConfig: &apixv1.WebhookClientConfig{
   129  								Service: &apixv1.ServiceReference{
   130  									Namespace: system.Namespace(),
   131  									Name:      "webhook",
   132  									// Path is added.
   133  									Path: ptr.String(path),
   134  								},
   135  								// CABundle is added.
   136  								CABundle: []byte("present"),
   137  							},
   138  						},
   139  					},
   140  				},
   141  			},
   142  		}},
   143  	}, {
   144  		Name: "secret and CRD exist, incorrect fields",
   145  		Key:  key,
   146  		Objects: []runtime.Object{
   147  			secret,
   148  			&apixv1.CustomResourceDefinition{
   149  				ObjectMeta: metav1.ObjectMeta{
   150  					Name: key,
   151  				},
   152  				Spec: apixv1.CustomResourceDefinitionSpec{
   153  					Conversion: &apixv1.CustomResourceConversion{
   154  						Strategy: apixv1.WebhookConverter,
   155  						Webhook: &apixv1.WebhookConversion{
   156  							ClientConfig: &apixv1.WebhookClientConfig{
   157  								Service: &apixv1.ServiceReference{
   158  									Namespace: system.Namespace(),
   159  									Name:      "webhook",
   160  									// Incorrect path
   161  									Path: ptr.String("/incorrect"),
   162  								},
   163  								// CABundle is added.
   164  								CABundle: []byte("incorrect"),
   165  							},
   166  						},
   167  					},
   168  				},
   169  			},
   170  		},
   171  		WantUpdates: []clientgotesting.UpdateActionImpl{{
   172  			Object: &apixv1.CustomResourceDefinition{
   173  				ObjectMeta: metav1.ObjectMeta{
   174  					Name: key,
   175  				},
   176  				Spec: apixv1.CustomResourceDefinitionSpec{
   177  					Conversion: &apixv1.CustomResourceConversion{
   178  						Strategy: apixv1.WebhookConverter,
   179  						Webhook: &apixv1.WebhookConversion{
   180  							ClientConfig: &apixv1.WebhookClientConfig{
   181  								Service: &apixv1.ServiceReference{
   182  									Namespace: system.Namespace(),
   183  									Name:      "webhook",
   184  									// Path is added.
   185  									Path: ptr.String(path),
   186  								},
   187  								// CABundle is added.
   188  								CABundle: []byte("present"),
   189  							},
   190  						},
   191  					},
   192  				},
   193  			},
   194  		}},
   195  	}, {
   196  		Name:    "failed to update custom resource definition",
   197  		Key:     key,
   198  		WantErr: true,
   199  		WithReactors: []clientgotesting.ReactionFunc{
   200  			InduceFailure("update", "customresourcedefinitions"),
   201  		},
   202  		Objects: []runtime.Object{
   203  			secret,
   204  			&apixv1.CustomResourceDefinition{
   205  				ObjectMeta: metav1.ObjectMeta{
   206  					Name: key,
   207  				},
   208  				Spec: apixv1.CustomResourceDefinitionSpec{
   209  					Conversion: &apixv1.CustomResourceConversion{
   210  						Strategy: apixv1.WebhookConverter,
   211  						Webhook: &apixv1.WebhookConversion{
   212  							ClientConfig: &apixv1.WebhookClientConfig{
   213  								Service: &apixv1.ServiceReference{
   214  									Namespace: system.Namespace(),
   215  									Name:      "webhook",
   216  									// Incorrect path
   217  									Path: ptr.String("/incorrect"),
   218  								},
   219  								// CABundle is added.
   220  								CABundle: []byte("incorrect"),
   221  							},
   222  						},
   223  					},
   224  				},
   225  			},
   226  		},
   227  		WantUpdates: []clientgotesting.UpdateActionImpl{{
   228  			Object: &apixv1.CustomResourceDefinition{
   229  				ObjectMeta: metav1.ObjectMeta{
   230  					Name: key,
   231  				},
   232  				Spec: apixv1.CustomResourceDefinitionSpec{
   233  					Conversion: &apixv1.CustomResourceConversion{
   234  						Strategy: apixv1.WebhookConverter,
   235  						Webhook: &apixv1.WebhookConversion{
   236  							ClientConfig: &apixv1.WebhookClientConfig{
   237  								Service: &apixv1.ServiceReference{
   238  									Namespace: system.Namespace(),
   239  									Name:      "webhook",
   240  									// Path is added.
   241  									Path: ptr.String(path),
   242  								},
   243  								// CABundle is added.
   244  								CABundle: []byte("present"),
   245  							},
   246  						},
   247  					},
   248  				},
   249  			},
   250  		}},
   251  	}, {
   252  		Name: "stable",
   253  		Key:  key,
   254  		Objects: []runtime.Object{
   255  			secret,
   256  			&apixv1.CustomResourceDefinition{
   257  				ObjectMeta: metav1.ObjectMeta{
   258  					Name: key,
   259  				},
   260  				Spec: apixv1.CustomResourceDefinitionSpec{
   261  					Conversion: &apixv1.CustomResourceConversion{
   262  						Strategy: apixv1.WebhookConverter,
   263  						Webhook: &apixv1.WebhookConversion{
   264  							ClientConfig: &apixv1.WebhookClientConfig{
   265  								Service: &apixv1.ServiceReference{
   266  									Namespace: system.Namespace(),
   267  									Name:      "webhook",
   268  									Path:      ptr.String(path),
   269  								},
   270  								// CABundle is added.
   271  								CABundle: []byte("present"),
   272  							},
   273  						},
   274  					},
   275  				},
   276  			},
   277  		},
   278  	}}
   279  
   280  	table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler {
   281  		return &reconciler{
   282  			kinds:        kinds,
   283  			path:         path,
   284  			secretName:   secretName,
   285  			secretLister: listers.GetSecretLister(),
   286  			crdLister:    listers.GetCustomResourceDefinitionLister(),
   287  			client:       apixclient.Get(ctx),
   288  		}
   289  	}))
   290  }