github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/common/common_test.go (about) 1 /* 2 * Copyright contributors to the Hyperledger Fabric Operator project 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package common_test 20 21 import ( 22 "context" 23 "encoding/base64" 24 "encoding/json" 25 "errors" 26 "time" 27 28 . "github.com/onsi/ginkgo/v2" 29 . "github.com/onsi/gomega" 30 corev1 "k8s.io/api/core/v1" 31 k8serrors "k8s.io/apimachinery/pkg/api/errors" 32 "k8s.io/apimachinery/pkg/runtime" 33 "k8s.io/apimachinery/pkg/runtime/schema" 34 "k8s.io/apimachinery/pkg/types" 35 "sigs.k8s.io/controller-runtime/pkg/client" 36 37 current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1" 38 "github.com/IBM-Blockchain/fabric-operator/controllers/mocks" 39 "github.com/IBM-Blockchain/fabric-operator/pkg/offering/common" 40 ) 41 42 var _ = Describe("Common", func() { 43 44 const testcert = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo" 45 46 var ( 47 mockKubeClient *mocks.Client 48 instance *current.IBPPeer 49 50 crypto1 *current.MSP 51 crypto2 *current.MSP 52 crypto3 *current.MSP 53 54 encodedtestcert string 55 56 backupData map[string][]byte 57 ) 58 59 BeforeEach(func() { 60 mockKubeClient = &mocks.Client{} 61 62 instance = ¤t.IBPPeer{} 63 instance.Name = "peer1" 64 65 crypto1 = ¤t.MSP{SignCerts: "signcert1"} 66 crypto2 = ¤t.MSP{SignCerts: "signcert2"} 67 crypto3 = ¤t.MSP{SignCerts: "signcert3"} 68 69 backup := &common.Backup{ 70 List: []*current.MSP{crypto1}, 71 Timestamp: time.Now().String(), 72 } 73 backupBytes, err := json.Marshal(backup) 74 Expect(err).NotTo(HaveOccurred()) 75 76 backupData = map[string][]byte{ 77 "tls-backup.json": backupBytes, 78 "ecert-backup.json": backupBytes, 79 } 80 81 mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error { 82 o := obj.(*corev1.Secret) 83 switch types.Name { 84 case "tls-" + instance.Name + "-signcert": 85 o.Name = "tls-" + instance.Name + "-signcert" 86 o.Namespace = instance.Namespace 87 o.Data = map[string][]byte{"cert.pem": []byte(testcert)} 88 case "tls-" + instance.Name + "-keystore": 89 o.Name = "tls-" + instance.Name + "-keystore" 90 o.Namespace = instance.Namespace 91 o.Data = map[string][]byte{"key.pem": []byte(testcert)} 92 case "tls-" + instance.Name + "-cacerts": 93 o.Name = "tls-" + instance.Name + "-cacerts" 94 o.Namespace = instance.Namespace 95 o.Data = map[string][]byte{"key.pem": []byte(testcert)} 96 case "ecert-" + instance.Name + "-signcert": 97 o.Name = "ecert-" + instance.Name + "-signcert" 98 o.Namespace = instance.Namespace 99 o.Data = map[string][]byte{"cert.pem": []byte(testcert)} 100 case "ecert-" + instance.Name + "-cacerts": 101 o.Name = "ecert-" + instance.Name + "-cacerts" 102 o.Namespace = instance.Namespace 103 o.Data = map[string][]byte{"cacert-0.pem": []byte(testcert)} 104 case "peer1-crypto-backup": 105 o.Name = instance.Name + "-crypto-backup" 106 o.Namespace = instance.Namespace 107 o.Data = backupData 108 case "ca1-ca-crypto": 109 o.Name = instance.Name + "-ca-crypto" 110 o.Namespace = instance.Namespace 111 o.Data = map[string][]byte{ 112 "tls-cert.pem": []byte(testcert), 113 "tls-key.pem": []byte(testcert), 114 "cert.pem": []byte(testcert), 115 "key.pem": []byte(testcert), 116 "operations-cert.pem": []byte(testcert), 117 "operations-key.pem": []byte(testcert), 118 } 119 case "ca1-crypto-backup": 120 o.Name = "ca1-crypto-backup" 121 o.Namespace = instance.Namespace 122 o.Data = backupData 123 } 124 return nil 125 } 126 127 encodedtestcert = base64.StdEncoding.EncodeToString([]byte(testcert)) 128 }) 129 130 Context("backup crypto", func() { 131 132 Context("get crypto", func() { 133 It("returns nil if fails to get secret", func() { 134 mockKubeClient.GetReturns(errors.New("get error")) 135 crypto := common.GetCrypto("tls", mockKubeClient, instance) 136 Expect(crypto).To(BeNil()) 137 }) 138 139 It("returns nil if no secrets are found", func() { 140 mockKubeClient.GetReturns(k8serrors.NewNotFound(schema.GroupResource{}, "not found")) 141 crypto := common.GetCrypto("tls", mockKubeClient, instance) 142 Expect(crypto).To(BeNil()) 143 }) 144 145 It("returns tls crypto", func() { 146 crypto := common.GetCrypto("tls", mockKubeClient, instance) 147 Expect(crypto).NotTo(BeNil()) 148 Expect(crypto).To(Equal(¤t.MSP{ 149 SignCerts: encodedtestcert, 150 KeyStore: encodedtestcert, 151 CACerts: []string{encodedtestcert}, 152 })) 153 }) 154 155 It("returns ecert crypto", func() { 156 crypto := common.GetCrypto("ecert", mockKubeClient, instance) 157 Expect(crypto).NotTo(BeNil()) 158 Expect(crypto).To(Equal(¤t.MSP{ 159 SignCerts: encodedtestcert, 160 CACerts: []string{encodedtestcert}, 161 })) 162 }) 163 }) 164 165 Context("udpate secret data", func() { 166 var ( 167 data map[string][]byte 168 ) 169 170 BeforeEach(func() { 171 172 backup := &common.Backup{ 173 List: []*current.MSP{crypto1}, 174 Timestamp: time.Now().String(), 175 } 176 backupBytes, err := json.Marshal(backup) 177 Expect(err).NotTo(HaveOccurred()) 178 179 data = map[string][]byte{ 180 "tls-backup.json": backupBytes, 181 "ecert-backup.json": backupBytes, 182 } 183 }) 184 185 It("adds crypto to backup list", func() { 186 crypto := &common.Crypto{ 187 TLS: crypto2, 188 Ecert: crypto2, 189 } 190 updatedData, err := common.UpdateBackupSecretData(data, crypto) 191 Expect(err).NotTo(HaveOccurred()) 192 193 By("updating tls backup", func() { 194 tlsbackup := &common.Backup{} 195 err = json.Unmarshal(updatedData["tls-backup.json"], tlsbackup) 196 Expect(err).NotTo(HaveOccurred()) 197 Expect(tlsbackup.List).To(Equal([]*current.MSP{crypto1, crypto2})) 198 Expect(tlsbackup.Timestamp).NotTo(Equal("")) 199 }) 200 201 By("updating ecert backup", func() { 202 ecertbackup := &common.Backup{} 203 err = json.Unmarshal(updatedData["ecert-backup.json"], ecertbackup) 204 Expect(err).NotTo(HaveOccurred()) 205 Expect(ecertbackup.List).To(Equal([]*current.MSP{crypto1, crypto2})) 206 Expect(ecertbackup.Timestamp).NotTo(Equal("")) 207 }) 208 }) 209 210 It("removes oldest crypto from queue and inserts new crypto if list is longer than 10", func() { 211 backup := &common.Backup{ 212 List: []*current.MSP{crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto2}, 213 Timestamp: time.Now().String(), 214 } 215 backupBytes, err := json.Marshal(backup) 216 Expect(err).NotTo(HaveOccurred()) 217 218 data = map[string][]byte{ 219 "tls-backup.json": backupBytes, 220 "ecert-backup.json": backupBytes, 221 } 222 223 crypto := &common.Crypto{ 224 TLS: crypto3, 225 Ecert: crypto3, 226 } 227 updatedData, err := common.UpdateBackupSecretData(data, crypto) 228 Expect(err).NotTo(HaveOccurred()) 229 230 By("updating tls backup to contain 10 most recent backups", func() { 231 tlsbackup := &common.Backup{} 232 err = json.Unmarshal(updatedData["tls-backup.json"], tlsbackup) 233 Expect(err).NotTo(HaveOccurred()) 234 Expect(tlsbackup.List).To(Equal([]*current.MSP{crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto2, crypto3})) 235 Expect(tlsbackup.Timestamp).NotTo(Equal("")) 236 }) 237 238 By("updating ecert backup to contain 10 most recent backups", func() { 239 ecertbackup := &common.Backup{} 240 err = json.Unmarshal(updatedData["ecert-backup.json"], ecertbackup) 241 Expect(err).NotTo(HaveOccurred()) 242 Expect(ecertbackup.List).To(Equal([]*current.MSP{crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto1, crypto2, crypto3})) 243 Expect(ecertbackup.Timestamp).NotTo(Equal("")) 244 }) 245 }) 246 }) 247 248 Context("backup crypto", func() { 249 It("returns nil if neither TLS nor ecert crypto is found", func() { 250 mockKubeClient.GetReturns(errors.New("get error")) 251 err := common.BackupCrypto(mockKubeClient, &runtime.Scheme{}, instance, map[string]string{}) 252 Expect(err).NotTo(HaveOccurred()) 253 }) 254 255 It("returns error if fails to update backup secret", func() { 256 mockKubeClient.UpdateReturns(errors.New("create or update error")) 257 err := common.BackupCrypto(mockKubeClient, &runtime.Scheme{}, instance, map[string]string{}) 258 Expect(err).To(HaveOccurred()) 259 Expect(err.Error()).To(Equal("failed to update backup secret: create or update error")) 260 }) 261 262 It("updates backup secret if one exists for instance", func() { 263 err := common.BackupCrypto(mockKubeClient, &runtime.Scheme{}, instance, map[string]string{}) 264 Expect(err).NotTo(HaveOccurred()) 265 Expect(mockKubeClient.UpdateCallCount()).To(Equal(1)) 266 267 newCrypto := ¤t.MSP{ 268 SignCerts: encodedtestcert, 269 KeyStore: encodedtestcert, 270 CACerts: []string{encodedtestcert}, 271 } 272 273 By("updating tls backup", func() { 274 tlsbackup := &common.Backup{} 275 err = json.Unmarshal(backupData["tls-backup.json"], tlsbackup) 276 Expect(err).NotTo(HaveOccurred()) 277 Expect(tlsbackup.List).To(Equal([]*current.MSP{crypto1, newCrypto})) 278 Expect(tlsbackup.Timestamp).NotTo(Equal("")) 279 }) 280 281 By("updating ecert backup", func() { 282 newCrypto.KeyStore = "" 283 ecertbackup := &common.Backup{} 284 err = json.Unmarshal(backupData["ecert-backup.json"], ecertbackup) 285 Expect(err).NotTo(HaveOccurred()) 286 Expect(ecertbackup.List).To(Equal([]*current.MSP{crypto1, newCrypto})) 287 Expect(ecertbackup.Timestamp).NotTo(Equal("")) 288 }) 289 }) 290 }) 291 292 Context("backup CA crypto", func() { 293 var ( 294 instance *current.IBPCA 295 ) 296 297 BeforeEach(func() { 298 instance = ¤t.IBPCA{} 299 instance.Name = "ca1" 300 }) 301 302 It("returns nil if CA TLS crypto is not found", func() { 303 mockKubeClient.GetReturns(errors.New("get error")) 304 err := common.BackupCACrypto(mockKubeClient, &runtime.Scheme{}, instance, map[string]string{}) 305 Expect(err).NotTo(HaveOccurred()) 306 }) 307 308 It("updates backup secret if one exists for instance", func() { 309 err := common.BackupCACrypto(mockKubeClient, &runtime.Scheme{}, instance, map[string]string{}) 310 Expect(err).NotTo(HaveOccurred()) 311 Expect(mockKubeClient.UpdateCallCount()).To(Equal(1)) 312 313 newCrypto := ¤t.MSP{ 314 SignCerts: encodedtestcert, 315 KeyStore: encodedtestcert, 316 } 317 318 By("updating tls backup", func() { 319 tlsbackup := &common.Backup{} 320 err = json.Unmarshal(backupData["tls-backup.json"], tlsbackup) 321 Expect(err).NotTo(HaveOccurred()) 322 Expect(tlsbackup.List).To(Equal([]*current.MSP{crypto1, newCrypto})) 323 Expect(tlsbackup.Timestamp).NotTo(Equal("")) 324 }) 325 326 By("creating operations backup", func() { 327 opbackup := &common.Backup{} 328 err = json.Unmarshal(backupData["operations-backup.json"], opbackup) 329 Expect(err).NotTo(HaveOccurred()) 330 Expect(opbackup.List).To(Equal([]*current.MSP{newCrypto})) 331 Expect(opbackup.Timestamp).NotTo(Equal("")) 332 }) 333 334 By("creating ca backup", func() { 335 cabackup := &common.Backup{} 336 err = json.Unmarshal(backupData["ca-backup.json"], cabackup) 337 Expect(err).NotTo(HaveOccurred()) 338 Expect(cabackup.List).To(Equal([]*current.MSP{newCrypto})) 339 Expect(cabackup.Timestamp).NotTo(Equal("")) 340 }) 341 }) 342 }) 343 344 }) 345 346 })