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 }