github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/k8s/peer/peer_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 k8speer_test 20 21 import ( 22 "context" 23 24 current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1" 25 cmocks "github.com/IBM-Blockchain/fabric-operator/controllers/mocks" 26 config "github.com/IBM-Blockchain/fabric-operator/operatorconfig" 27 "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common/enroller" 28 peerinit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/peer" 29 managermocks "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/mocks" 30 basepeer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer" 31 "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer/mocks" 32 k8speer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/k8s/peer" 33 "github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors" 34 "github.com/IBM-Blockchain/fabric-operator/version" 35 . "github.com/onsi/ginkgo/v2" 36 . "github.com/onsi/gomega" 37 "github.com/pkg/errors" 38 corev1 "k8s.io/api/core/v1" 39 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 40 "k8s.io/apimachinery/pkg/runtime" 41 "k8s.io/apimachinery/pkg/types" 42 "k8s.io/apimachinery/pkg/util/intstr" 43 "sigs.k8s.io/controller-runtime/pkg/client" 44 ) 45 46 var _ = Describe("K8s Peer", func() { 47 var ( 48 peer *k8speer.Peer 49 instance *current.IBPPeer 50 mockKubeClient *cmocks.Client 51 cfg *config.Config 52 53 deploymentMgr *mocks.DeploymentManager 54 serviceMgr *managermocks.ResourceManager 55 pvcMgr *managermocks.ResourceManager 56 couchPvcMgr *managermocks.ResourceManager 57 configMapMgr *managermocks.ResourceManager 58 roleMgr *managermocks.ResourceManager 59 roleBindingMgr *managermocks.ResourceManager 60 serviceAccountMgr *managermocks.ResourceManager 61 ingressMgr *managermocks.ResourceManager 62 update *mocks.Update 63 certificateMgr *mocks.CertificateManager 64 ) 65 66 BeforeEach(func() { 67 mockKubeClient = &cmocks.Client{} 68 update = &mocks.Update{} 69 70 replicas := int32(1) 71 instance = ¤t.IBPPeer{ 72 TypeMeta: metav1.TypeMeta{ 73 Kind: "IBPPeer", 74 }, 75 ObjectMeta: metav1.ObjectMeta{ 76 Name: "peer1", 77 Namespace: "random", 78 }, 79 Spec: current.IBPPeerSpec{ 80 PeerExternalEndpoint: "address", 81 Domain: "domain", 82 StateDb: "couchdb", 83 Replicas: &replicas, 84 Images: ¤t.PeerImages{}, 85 FabricVersion: "1.4.9", 86 }, 87 Status: current.IBPPeerStatus{ 88 CRStatus: current.CRStatus{ 89 Version: version.Operator, 90 }, 91 }, 92 } 93 94 mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error { 95 switch obj.(type) { 96 case *current.IBPPeer: 97 o := obj.(*current.IBPPeer) 98 o.Kind = "IBPPeer" 99 instance = o 100 case *corev1.Service: 101 o := obj.(*corev1.Service) 102 o.Spec.Type = corev1.ServiceTypeNodePort 103 o.Spec.Ports = append(o.Spec.Ports, corev1.ServicePort{ 104 Name: "peer-api", 105 TargetPort: intstr.IntOrString{ 106 IntVal: 7051, 107 }, 108 NodePort: int32(7051), 109 }) 110 case *corev1.Secret: 111 o := obj.(*corev1.Secret) 112 switch types.Name { 113 case "ecert-" + instance.Name + "-cacerts": 114 o.Name = "tls-" + instance.Name + "-signcert" 115 o.Namespace = instance.Namespace 116 o.Data = map[string][]byte{"cacert-0.pem": []byte("")} 117 default: 118 o.Name = "tls-" + instance.Name + "-signcert" 119 o.Namespace = instance.Namespace 120 o.Data = map[string][]byte{"cert.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")} 121 } 122 } 123 return nil 124 } 125 instance.Status.Version = version.Operator 126 127 deploymentMgr = &mocks.DeploymentManager{} 128 serviceMgr = &managermocks.ResourceManager{} 129 pvcMgr = &managermocks.ResourceManager{} 130 couchPvcMgr = &managermocks.ResourceManager{} 131 configMapMgr = &managermocks.ResourceManager{} 132 roleMgr = &managermocks.ResourceManager{} 133 roleBindingMgr = &managermocks.ResourceManager{} 134 serviceAccountMgr = &managermocks.ResourceManager{} 135 ingressMgr = &managermocks.ResourceManager{} 136 certificateMgr = &mocks.CertificateManager{} 137 restartMgr := &mocks.RestartManager{} 138 139 scheme := &runtime.Scheme{} 140 cfg = &config.Config{ 141 PeerInitConfig: &peerinit.Config{ 142 OUFile: "../../../../defaultconfig/peer/ouconfig.yaml", 143 CorePeerFile: "../../../../defaultconfig/peer/core.yaml", 144 }, 145 } 146 initializer := &mocks.InitializeIBPPeer{} 147 initializer.GetInitPeerReturns(&peerinit.Peer{}, nil) 148 peer = &k8speer.Peer{ 149 Peer: &basepeer.Peer{ 150 Client: mockKubeClient, 151 Scheme: scheme, 152 Config: cfg, 153 154 DeploymentManager: deploymentMgr, 155 ServiceManager: serviceMgr, 156 PVCManager: pvcMgr, 157 StateDBPVCManager: couchPvcMgr, 158 FluentDConfigMapManager: configMapMgr, 159 RoleManager: roleMgr, 160 RoleBindingManager: roleBindingMgr, 161 ServiceAccountManager: serviceAccountMgr, 162 Initializer: initializer, 163 CertificateManager: certificateMgr, 164 Restart: restartMgr, 165 }, 166 IngressManager: ingressMgr, 167 } 168 }) 169 170 Context("Reconciles", func() { 171 It("returns an error if pvc manager fails to reconcile", func() { 172 pvcMgr.ReconcileReturns(errors.New("failed to reconcile pvc")) 173 _, err := peer.Reconcile(instance, update) 174 Expect(err).To(HaveOccurred()) 175 Expect(err.Error()).To(Equal("failed to reconcile managers: failed PVC reconciliation: failed to reconcile pvc")) 176 }) 177 178 It("returns an error if couch pvc manager fails to reconcile", func() { 179 couchPvcMgr.ReconcileReturns(errors.New("failed to reconcile couch pvc")) 180 _, err := peer.Reconcile(instance, update) 181 Expect(err).To(HaveOccurred()) 182 Expect(err.Error()).To(Equal("failed to reconcile managers: failed CouchDB PVC reconciliation: failed to reconcile couch pvc")) 183 }) 184 185 It("returns an error if service manager fails to reconcile", func() { 186 serviceMgr.ReconcileReturns(errors.New("failed to reconcile service")) 187 _, err := peer.Reconcile(instance, update) 188 Expect(err).To(HaveOccurred()) 189 Expect(err.Error()).To(Equal("failed to reconcile managers: failed Service reconciliation: failed to reconcile service")) 190 }) 191 192 It("returns an error if deployment manager fails to reconcile", func() { 193 deploymentMgr.ReconcileReturns(errors.New("failed to reconcile deployment")) 194 _, err := peer.Reconcile(instance, update) 195 Expect(err).To(HaveOccurred()) 196 Expect(err.Error()).To(Equal("failed to reconcile managers: failed Deployment reconciliation: failed to reconcile deployment")) 197 }) 198 199 It("returns an error if role manager fails to reconcile", func() { 200 roleMgr.ReconcileReturns(errors.New("failed to reconcile role")) 201 _, err := peer.Reconcile(instance, update) 202 Expect(err).To(HaveOccurred()) 203 Expect(err.Error()).To(ContainSubstring("failed to reconcile role")) 204 }) 205 206 It("returns an error if role binding manager fails to reconcile", func() { 207 roleBindingMgr.ReconcileReturns(errors.New("failed to reconcile role binding")) 208 _, err := peer.Reconcile(instance, update) 209 Expect(err).To(HaveOccurred()) 210 Expect(err.Error()).To(ContainSubstring("failed to reconcile role binding")) 211 }) 212 213 It("returns an error if service account binding manager fails to reconcile", func() { 214 serviceAccountMgr.ReconcileReturns(errors.New("failed to reconcile service account")) 215 _, err := peer.Reconcile(instance, update) 216 Expect(err).To(HaveOccurred()) 217 Expect(err.Error()).To(ContainSubstring("failed to reconcile service account")) 218 }) 219 220 It("returns an error if config map manager fails to reconcile", func() { 221 configMapMgr.ReconcileReturns(errors.New("failed to reconcile config map")) 222 _, err := peer.Reconcile(instance, update) 223 Expect(err).To(HaveOccurred()) 224 Expect(err.Error()).To(Equal("failed to reconcile managers: failed FluentD ConfigMap reconciliation: failed to reconcile config map")) 225 }) 226 227 It("returns a breaking error if initialization fails", func() { 228 cfg.PeerInitConfig.CorePeerFile = "../../../../../defaultconfig/peer/badfile.yaml" 229 peer.Initializer = peerinit.New(cfg.PeerInitConfig, nil, nil, nil, nil, enroller.HSMEnrollJobTimeouts{}) 230 _, err := peer.Reconcile(instance, update) 231 Expect(err).To(HaveOccurred()) 232 Expect(err.Error()).To(ContainSubstring("Code: 22 - failed to initialize peer: open")) 233 Expect(operatorerrors.IsBreakingError(err, "msg", nil)).NotTo(HaveOccurred()) 234 }) 235 236 It("does not return an error on a successful reconcile", func() { 237 _, err := peer.Reconcile(instance, update) 238 Expect(err).NotTo(HaveOccurred()) 239 }) 240 }) 241 242 Context("ExternalEndpoint", func() { 243 It("Updates the external endpoint, When external endpoint is not defined", func() { 244 instance.Namespace = "namespace" 245 instance.Name = "name" 246 instance.Spec.PeerExternalEndpoint = "" 247 instance.Spec.Domain = "1.2.3.4" 248 249 updated := peer.UpdateExternalEndpoint(instance) 250 Expect(updated).To(Equal(true)) 251 Expect(instance.Spec.PeerExternalEndpoint).To(Equal("namespace-name-peer.1.2.3.4:443")) 252 }) 253 }) 254 })