github.com/IBM-Blockchain/fabric-operator@v1.0.4/integration/orderer/orderer_test.go (about) 1 //go:build !pkcs11 2 // +build !pkcs11 3 4 /* 5 * Copyright contributors to the Hyperledger Fabric Operator project 6 * 7 * SPDX-License-Identifier: Apache-2.0 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at: 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package orderer_test 23 24 import ( 25 "context" 26 "encoding/json" 27 "fmt" 28 "time" 29 30 "k8s.io/utils/pointer" 31 "sigs.k8s.io/yaml" 32 33 current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1" 34 "github.com/IBM-Blockchain/fabric-operator/integration" 35 "github.com/IBM-Blockchain/fabric-operator/integration/helper" 36 v1 "github.com/IBM-Blockchain/fabric-operator/pkg/apis/orderer/v1" 37 v2 "github.com/IBM-Blockchain/fabric-operator/pkg/apis/orderer/v2" 38 config "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/orderer/config/v2" 39 baseorderer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/orderer" 40 "github.com/IBM-Blockchain/fabric-operator/pkg/util" 41 . "github.com/onsi/ginkgo/v2" 42 . "github.com/onsi/gomega" 43 appsv1 "k8s.io/api/apps/v1" 44 corev1 "k8s.io/api/core/v1" 45 "k8s.io/apimachinery/pkg/api/resource" 46 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 47 "k8s.io/apimachinery/pkg/runtime" 48 "k8s.io/apimachinery/pkg/types" 49 "k8s.io/apimachinery/pkg/util/wait" 50 ) 51 52 type OrdererConfig interface { 53 ToBytes() ([]byte, error) 54 } 55 56 var ( 57 orderer *Orderer 58 orderer2 *Orderer 59 orderer3 *Orderer 60 orderer4 *Orderer 61 orderer5 *Orderer 62 orderer1nodes []Orderer 63 orderer2nodes []Orderer 64 orderer3nodes []Orderer 65 orderer4nodes []Orderer 66 orderer5nodes []Orderer 67 ) 68 69 var ( 70 defaultRequestsOrderer = corev1.ResourceList{ 71 corev1.ResourceCPU: resource.MustParse("20m"), 72 corev1.ResourceMemory: resource.MustParse("40M"), 73 corev1.ResourceEphemeralStorage: resource.MustParse("100M"), 74 } 75 76 defaultLimitsOrderer = corev1.ResourceList{ 77 corev1.ResourceCPU: resource.MustParse("200m"), 78 corev1.ResourceMemory: resource.MustParse("400M"), 79 corev1.ResourceEphemeralStorage: resource.MustParse("1G"), 80 } 81 82 defaultRequestsProxy = corev1.ResourceList{ 83 corev1.ResourceCPU: resource.MustParse("10m"), 84 corev1.ResourceMemory: resource.MustParse("20M"), 85 corev1.ResourceEphemeralStorage: resource.MustParse("100M"), 86 } 87 88 defaultLimitsProxy = corev1.ResourceList{ 89 corev1.ResourceCPU: resource.MustParse("100m"), 90 corev1.ResourceMemory: resource.MustParse("200M"), 91 corev1.ResourceEphemeralStorage: resource.MustParse("1G"), 92 } 93 94 testMSPSpec = ¤t.MSPSpec{ 95 Component: ¤t.MSP{ 96 KeyStore: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR0hBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJHMHdhd0lCQVFRZ2FYb2MwNkxoWmliYjFsSEUKU0ZaY2NSeThmcWUySjROQW1rdEtXZEpFZVBxaFJBTkNBQVJ4UGVOKy94WHRLeTdXNGlZajUxQ29LQ2NmZ2Y4NApnMDBkamEzSStNeHNLSDZncVNQUGpXbThvUi9sYnZhbW9jay84bURoRi9yZTd3SU5qWkpGeG80aAotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==", 97 SignCerts: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNUVENDQWZPZ0F3SUJBZ0lVTUw4NVhXVVJLZURqV1ZjelNWZ0ZoWDdtWlFjd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVGN3TUZvWERUSTFNVEV5T1RJd01qSXdNRm93WFRFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdZMnhwWlc1ME1RNHdEQVlEVlFRREV3VmhaRzFwYmpCWk1CTUdCeXFHClNNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJIRTk0MzcvRmUwckx0YmlKaVBuVUtnb0p4K0IvemlEVFIyTnJjajQKekd3b2ZxQ3BJOCtOYWJ5aEgrVnU5cWFoeVQveVlPRVgrdDd2QWcyTmtrWEdqaUdqZ1lVd2dZSXdEZ1lEVlIwUApBUUgvQkFRREFnZUFNQXdHQTFVZEV3RUIvd1FDTUFBd0hRWURWUjBPQkJZRUZNSGxPTGthZTFSbFRaZ1BNQ0ZQCkxKai80MHBzTUI4R0ExVWRJd1FZTUJhQUZNeTZicUR5Q1p1UThEeTBQWkhtVUNJTDRzNmlNQ0lHQTFVZEVRUWIKTUJtQ0YxTmhZV1J6TFUxaFkwSnZiMnN0VUhKdkxteHZZMkZzTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFERAowY1Z6aEJFcGo1aFhYVXQzQSsxQVZOc2IyZDgxNVpZSVVVTG0xQXZ5T1FJZ1d1eldoVzQ5QUNWSG8zWkhNRE1vCmU5d3FRbUpTNDB2UGJtMEtOVUVkdURjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==", 98 CACerts: []string{"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNGakNDQWIyZ0F3SUJBZ0lVS2dNc2pwYlFSNlRHUUs3QVBhMEZmUVZxT1pvd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVFV3TUZvWERUTTFNVEV5TnpJd01UVXdNRm93YURFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdSbUZpY21sak1Sa3dGd1lEVlFRREV4Qm1ZV0p5YVdNdFkyRXRjMlZ5CmRtVnlNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUrb2lXeWdGNWpLY081cWtzaG8zN3lzRSsKdXYxMEF5WWZrUGxVWXlBVkJOeGtlSGN1RUlWSmY5LzZRL2x2S2NvUyt6cFp2dlFiSTEzT1pSTDNMK25IZXFORgpNRU13RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUV3SFFZRFZSME9CQllFCkZNeTZicUR5Q1p1UThEeTBQWkhtVUNJTDRzNmlNQW9HQ0NxR1NNNDlCQU1DQTBjQU1FUUNJQmdSTXNqN3Azc1YKMHNieEQxa2t0amloVEpHVFJBWlZRQXVyY0hhRVVENFVBaUFoN0o4U2ZPQTc5VjN4RDdvaExFcmVpZHVnZnhIbAozWWxZS0g3MG9qQXhRZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}, 99 AdminCerts: []string{"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNUVENDQWZPZ0F3SUJBZ0lVTUw4NVhXVVJLZURqV1ZjelNWZ0ZoWDdtWlFjd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVGN3TUZvWERUSTFNVEV5T1RJd01qSXdNRm93WFRFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdZMnhwWlc1ME1RNHdEQVlEVlFRREV3VmhaRzFwYmpCWk1CTUdCeXFHClNNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJIRTk0MzcvRmUwckx0YmlKaVBuVUtnb0p4K0IvemlEVFIyTnJjajQKekd3b2ZxQ3BJOCtOYWJ5aEgrVnU5cWFoeVQveVlPRVgrdDd2QWcyTmtrWEdqaUdqZ1lVd2dZSXdEZ1lEVlIwUApBUUgvQkFRREFnZUFNQXdHQTFVZEV3RUIvd1FDTUFBd0hRWURWUjBPQkJZRUZNSGxPTGthZTFSbFRaZ1BNQ0ZQCkxKai80MHBzTUI4R0ExVWRJd1FZTUJhQUZNeTZicUR5Q1p1UThEeTBQWkhtVUNJTDRzNmlNQ0lHQTFVZEVRUWIKTUJtQ0YxTmhZV1J6TFUxaFkwSnZiMnN0VUhKdkxteHZZMkZzTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFERAowY1Z6aEJFcGo1aFhYVXQzQSsxQVZOc2IyZDgxNVpZSVVVTG0xQXZ5T1FJZ1d1eldoVzQ5QUNWSG8zWkhNRE1vCmU5d3FRbUpTNDB2UGJtMEtOVUVkdURjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="}, 100 }, 101 TLS: ¤t.MSP{ 102 KeyStore: "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR0hBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJHMHdhd0lCQVFRZzZuNit4cDJod1hrTzBrWHUKbUFiY2Z3aGNUcllDOEQ4SDJFNUZPUmNpMFBTaFJBTkNBQVFCMDBTNDhwbGlmd2tIN1RucGtZUTQrd1hJQ1piSwpnL1Z0U3ZoVUQyOC93dkd4VXdBZXBwSVZCRElCUUZBaE9xZ1F5SkpBQTZWbTVyd2RKaG1aR3M5SQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==", 103 SignCerts: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNiRENDQWhLZ0F3SUJBZ0lVT3RnTGwwR0orSjU2T1llcXI3UFI1ckhKakhNd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVGt3TUZvWERUSTFNVEV5T1RJd01qUXdNRm93WFRFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdZMnhwWlc1ME1RNHdEQVlEVlFRREV3VmhaRzFwYmpCWk1CTUdCeXFHClNNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJBSFRSTGp5bVdKL0NRZnRPZW1SaERqN0JjZ0psc3FEOVcxSytGUVAKYnovQzhiRlRBQjZta2hVRU1nRkFVQ0U2cUJESWtrQURwV2JtdkIwbUdaa2F6MGlqZ2FRd2dhRXdEZ1lEVlIwUApBUUgvQkFRREFnT29NQjBHQTFVZEpRUVdNQlFHQ0NzR0FRVUZCd01CQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CCkFmOEVBakFBTUIwR0ExVWREZ1FXQkJTOTY4MUFxUEZ1dndHNUZsVFROS0J2Z2FKdk56QWZCZ05WSFNNRUdEQVcKZ0JUTXVtNmc4Z21ia1BBOHREMlI1bEFpQytMT29qQWlCZ05WSFJFRUd6QVpnaGRUWVdGa2N5MU5ZV05DYjI5cgpMVkJ5Ynk1c2IyTmhiREFLQmdncWhrak9QUVFEQWdOSUFEQkZBaUVBK0RzckZlUkxEQXJ1eVNxVWJmc2hVWkFCCmhMNXpqZ2k2ckpFZzFtQW1iSFVDSUUwSjFQOUlxVFZHMU54UjdEQ1lBdVZkbmJ4eWJHWkUyMDA5eDl3Y0pudksKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=", 104 CACerts: []string{"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNGakNDQWIyZ0F3SUJBZ0lVS2dNc2pwYlFSNlRHUUs3QVBhMEZmUVZxT1pvd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVFV3TUZvWERUTTFNVEV5TnpJd01UVXdNRm93YURFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdSbUZpY21sak1Sa3dGd1lEVlFRREV4Qm1ZV0p5YVdNdFkyRXRjMlZ5CmRtVnlNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUrb2lXeWdGNWpLY081cWtzaG8zN3lzRSsKdXYxMEF5WWZrUGxVWXlBVkJOeGtlSGN1RUlWSmY5LzZRL2x2S2NvUyt6cFp2dlFiSTEzT1pSTDNMK25IZXFORgpNRU13RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUV3SFFZRFZSME9CQllFCkZNeTZicUR5Q1p1UThEeTBQWkhtVUNJTDRzNmlNQW9HQ0NxR1NNNDlCQU1DQTBjQU1FUUNJQmdSTXNqN3Azc1YKMHNieEQxa2t0amloVEpHVFJBWlZRQXVyY0hhRVVENFVBaUFoN0o4U2ZPQTc5VjN4RDdvaExFcmVpZHVnZnhIbAozWWxZS0g3MG9qQXhRZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"}, 105 }, 106 } 107 ) 108 109 var _ = Describe("Interaction between IBP-Operator and Kubernetes cluster", func() { 110 SetDefaultEventuallyTimeout(420 * time.Second) 111 SetDefaultEventuallyPollingInterval(time.Second) 112 113 BeforeEach(func() { 114 orderer, orderer1nodes = GetOrderer() 115 err := helper.CreateOrderer(ibpCRClient, orderer.CR) 116 Expect(err).NotTo(HaveOccurred()) 117 118 integration.ClearOperatorConfig(kclient, namespace) 119 }) 120 121 AfterEach(func() { 122 // Set flag if a test falls 123 if CurrentGinkgoTestDescription().Failed { 124 testFailed = true 125 } 126 }) 127 128 Context("IBPOrderer controller", func() { 129 130 Context("applying first instance of IBPOrderer CR", func() { 131 var ( 132 err error 133 dep *appsv1.Deployment 134 ) 135 136 It("creates a IBPOrderer custom resource", func() { 137 By("setting the CR status to precreate", func() { 138 for _, node := range orderer1nodes { 139 Eventually(node.pollForCRStatus).Should((Equal(current.Precreated))) 140 } 141 // TODO flake 142 // Eventually(orderer.pollForCRStatus).Should((Equal(current.Deploying))) 143 }) 144 145 By("creating a pvc", func() { 146 for _, node := range orderer1nodes { 147 Eventually(node.PVCExists).Should((Equal(true))) 148 } 149 }) 150 151 By("creating a service", func() { 152 for _, node := range orderer1nodes { 153 Eventually(node.ServiceExists).Should((Equal(true))) 154 } 155 }) 156 157 By("creating a configmap", func() { 158 for _, node := range orderer1nodes { 159 Eventually(node.ConfigMapExists).Should((Equal(true))) 160 } 161 }) 162 163 By("starting a ingress", func() { 164 for _, node := range orderer1nodes { 165 Eventually(node.IngressExists).Should((Equal(true))) 166 } 167 }) 168 169 By("creating a deployment", func() { 170 for _, node := range orderer1nodes { 171 Eventually(node.DeploymentExists).Should((Equal(true))) 172 } 173 }) 174 175 By("creating init secrets", func() { 176 for _, node := range orderer1nodes { 177 Eventually(node.allInitSecretsExist).Should((Equal(true))) 178 } 179 }) 180 181 By("starting a pod", func() { 182 for _, node := range orderer1nodes { 183 Eventually(node.PodIsRunning).Should((Equal(true))) 184 } 185 }) 186 187 By("creating config map that contains spec", func() { 188 for _, node := range orderer1nodes { 189 Eventually(func() bool { 190 _, err := kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), node.Name+"-spec", metav1.GetOptions{}) 191 if err != nil { 192 return false 193 } 194 return true 195 }).Should(Equal(true)) 196 } 197 }) 198 199 By("setting the CR status to deployed when pod is running", func() { 200 for _, node := range orderer1nodes { 201 Eventually(node.pollForCRStatus).Should((Equal(current.Deployed))) 202 } 203 Eventually(orderer.pollForCRStatus).Should((Equal(current.Deployed))) 204 }) 205 206 By("overriding general section in orderer.yaml", func() { 207 cm, err := kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), orderer.Name+"node1-config", metav1.GetOptions{}) 208 Expect(err).NotTo(HaveOccurred()) 209 210 ordererBytes := cm.BinaryData["orderer.yaml"] 211 ordererConfig, err := config.ReadOrdererFromBytes(ordererBytes) 212 Expect(err).NotTo(HaveOccurred()) 213 configOverride, err := orderer.CR.GetConfigOverride() 214 Expect(err).NotTo(HaveOccurred()) 215 bytes, err := configOverride.(OrdererConfig).ToBytes() 216 Expect(err).NotTo(HaveOccurred()) 217 oConfig := &config.Orderer{} 218 err = yaml.Unmarshal(bytes, oConfig) 219 Expect(err).NotTo(HaveOccurred()) 220 Expect(ordererConfig.General.ListenPort).To(Equal(oConfig.General.ListenPort)) 221 }) 222 }) 223 224 It("should not find zone and region", func() { 225 // Wait for new deployment before querying deployment for updates 226 err = wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) { 227 ready := true 228 for _, node := range orderer1nodes { 229 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 230 if dep != nil { 231 if dep.Status.UpdatedReplicas != 1 || dep.Status.Conditions[0].Type != appsv1.DeploymentAvailable { 232 ready = false 233 } 234 } 235 } 236 237 return ready, nil 238 }) 239 Expect(err).NotTo(HaveOccurred()) 240 for _, node := range orderer1nodes { 241 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 242 Expect(err).NotTo(HaveOccurred()) 243 244 By("checking zone", func() { 245 Expect(node.TestAffinityZone(dep)).To((Equal(false))) 246 }) 247 248 By("checking region", func() { 249 Expect(node.TestAffinityRegion(dep)).To((Equal(false))) 250 }) 251 } 252 }) 253 254 When("the custom resource is updated", func() { 255 var ( 256 dep *appsv1.Deployment 257 newResourceRequestsOrderer corev1.ResourceList 258 newResourceLimitsOrderer corev1.ResourceList 259 newResourceRequestsProxy corev1.ResourceList 260 newResourceLimitsProxy corev1.ResourceList 261 ) 262 263 BeforeEach(func() { 264 newResourceRequestsOrderer = map[corev1.ResourceName]resource.Quantity{ 265 corev1.ResourceCPU: resource.MustParse("240m"), 266 corev1.ResourceMemory: resource.MustParse("480M"), 267 corev1.ResourceEphemeralStorage: resource.MustParse("100M"), 268 } 269 newResourceLimitsOrderer = map[corev1.ResourceName]resource.Quantity{ 270 corev1.ResourceCPU: resource.MustParse("240m"), 271 corev1.ResourceMemory: resource.MustParse("480M"), 272 corev1.ResourceEphemeralStorage: resource.MustParse("1G"), 273 } 274 275 newResourceRequestsProxy = map[corev1.ResourceName]resource.Quantity{ 276 corev1.ResourceCPU: resource.MustParse("90m"), 277 corev1.ResourceMemory: resource.MustParse("180M"), 278 corev1.ResourceEphemeralStorage: resource.MustParse("100M"), 279 } 280 newResourceLimitsProxy = map[corev1.ResourceName]resource.Quantity{ 281 corev1.ResourceCPU: resource.MustParse("90m"), 282 corev1.ResourceMemory: resource.MustParse("180M"), 283 corev1.ResourceEphemeralStorage: resource.MustParse("1G"), 284 } 285 286 for _, node := range orderer1nodes { 287 Eventually(node.DeploymentExists).Should((Equal(true))) 288 } 289 }) 290 291 It("updates the instance of IBPOrderer if resources are updated in CR", func() { 292 for _, node := range orderer1nodes { 293 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 294 295 ordererResources := dep.Spec.Template.Spec.Containers[0].Resources 296 Expect(ordererResources.Requests).To(Equal(defaultRequestsOrderer)) 297 Expect(ordererResources.Limits).To(Equal(defaultLimitsOrderer)) 298 299 proxyResources := dep.Spec.Template.Spec.Containers[1].Resources 300 Expect(proxyResources.Requests).To(Equal(defaultRequestsProxy)) 301 Expect(proxyResources.Limits).To(Equal(defaultLimitsProxy)) 302 303 updatenode := ¤t.IBPOrderer{} 304 result := ibpCRClient.Get().Namespace(namespace).Resource("ibporderers").Name(node.Name).Do(context.TODO()) 305 result.Into(updatenode) 306 307 updatenode.Spec.Resources = ¤t.OrdererResources{ 308 Orderer: &corev1.ResourceRequirements{ 309 Requests: newResourceRequestsOrderer, 310 Limits: newResourceLimitsOrderer, 311 }, 312 GRPCProxy: &corev1.ResourceRequirements{ 313 Requests: newResourceRequestsProxy, 314 Limits: newResourceLimitsProxy, 315 }, 316 } 317 configOverride := &config.Orderer{ 318 Orderer: v2.Orderer{ 319 FileLedger: v1.FileLedger{ 320 Location: "/temp", 321 }, 322 }, 323 } 324 configBytes, err := json.Marshal(configOverride) 325 Expect(err).NotTo(HaveOccurred()) 326 updatenode.Spec.ConfigOverride = &runtime.RawExtension{Raw: configBytes} 327 328 bytes, err := json.Marshal(updatenode) 329 Expect(err).NotTo(HaveOccurred()) 330 331 result = ibpCRClient.Patch(types.MergePatchType).Namespace(namespace).Resource("ibporderers").Name(node.Name).Body(bytes).Do(context.TODO()) 332 Expect(result.Error()).NotTo(HaveOccurred()) 333 334 // Wait for new deployment before querying deployment for updates 335 Eventually(func() bool { 336 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 337 if dep != nil { 338 if dep.Status.UpdatedReplicas == 1 && dep.Status.Conditions[0].Type == appsv1.DeploymentAvailable { 339 if dep.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().MilliValue() == newResourceRequestsOrderer.Cpu().MilliValue() { 340 return true 341 } 342 } 343 } 344 return false 345 }).Should(Equal(true)) 346 347 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 348 Expect(err).NotTo(HaveOccurred()) 349 350 updatedOrdererResources := dep.Spec.Template.Spec.Containers[0].Resources 351 Expect(updatedOrdererResources.Requests).To(Equal(newResourceRequestsOrderer)) 352 Expect(updatedOrdererResources.Limits).To(Equal(newResourceLimitsOrderer)) 353 354 updatedProxyResources := dep.Spec.Template.Spec.Containers[1].Resources 355 Expect(updatedProxyResources.Requests).To(Equal(newResourceRequestsProxy)) 356 Expect(updatedProxyResources.Limits).To(Equal(newResourceLimitsProxy)) 357 358 By("updating the config map with new values from override", func() { 359 Eventually(func() bool { 360 cm, err := kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), orderer.Name+"node1-config", metav1.GetOptions{}) 361 Expect(err).NotTo(HaveOccurred()) 362 363 configBytes := cm.BinaryData["orderer.yaml"] 364 ordererConfig, err := config.ReadOrdererFromBytes(configBytes) 365 Expect(err).NotTo(HaveOccurred()) 366 367 if ordererConfig.FileLedger.Location == "/temp" { 368 return true 369 } 370 371 return false 372 }).Should(Equal(true)) 373 }) 374 } 375 }) 376 }) 377 378 When("a deployment managed by operator is manually edited", func() { 379 var ( 380 err error 381 dep *appsv1.Deployment 382 ) 383 384 BeforeEach(func() { 385 for _, node := range orderer1nodes { 386 Eventually(node.DeploymentExists).Should((Equal(true))) 387 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 388 Expect(err).NotTo(HaveOccurred()) 389 } 390 }) 391 392 It("restores states", func() { 393 for _, node := range orderer1nodes { 394 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 395 Expect(err).NotTo(HaveOccurred()) 396 397 origRequests := dep.Spec.Template.Spec.Containers[0].Resources.Requests 398 dep.Spec.Template.Spec.Containers[0].Resources.Requests = map[corev1.ResourceName]resource.Quantity{ 399 corev1.ResourceCPU: resource.MustParse("100m"), 400 corev1.ResourceMemory: resource.MustParse("200M"), 401 } 402 403 depBytes, err := json.Marshal(dep) 404 Expect(err).NotTo(HaveOccurred()) 405 406 _, err = kclient.AppsV1().Deployments(namespace).Patch(context.TODO(), node.NodeName, types.MergePatchType, depBytes, metav1.PatchOptions{}) 407 Expect(util.IgnoreOutdatedResourceVersion(err)).NotTo(HaveOccurred()) 408 409 // Wait for new deployment before querying deployment for updates 410 wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) { 411 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 412 if dep != nil { 413 if dep.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().MilliValue() == origRequests.Cpu().MilliValue() { 414 return true, nil 415 } 416 } 417 return false, nil 418 }) 419 420 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 421 Expect(err).NotTo(HaveOccurred()) 422 423 Expect(dep.Spec.Template.Spec.Containers[0].Resources.Requests).To(Equal(origRequests)) 424 } 425 }) 426 }) 427 }) 428 429 Context("applying last instance of IBPOrderer CR, with channel-less config", func() { 430 431 // NOTE: THIS COUNTER MUST BE EQUAL TO THE NUMBER OF It() ROUTINES IN THIS CONTEXT 432 checks_remaining := 2 433 434 // Set up the orderer before the FIRST It() of this context 435 BeforeEach(func() { 436 if orderer5 == nil { 437 orderer5, orderer5nodes = GetOrderer5() 438 err := helper.CreateOrderer(ibpCRClient, orderer5.CR) 439 Expect(err).NotTo(HaveOccurred()) 440 } 441 }) 442 443 // Tear down the orderer after the LAST It() in this context 444 AfterEach(func() { 445 checks_remaining-- 446 if checks_remaining == 0 { 447 result := ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(orderer5.Name).Do(context.TODO()) 448 Expect(result.Error()).NotTo(HaveOccurred()) 449 450 orderer5 = nil 451 orderer5nodes = nil 452 } 453 }) 454 455 It("creates a IBPOrderer custom resource", func() { 456 By("creating a pvc", func() { 457 for _, node := range orderer5nodes { 458 Eventually(node.PVCExists).Should((Equal(true))) 459 } 460 }) 461 462 By("creating a service", func() { 463 for _, node := range orderer5nodes { 464 Eventually(node.ServiceExists).Should((Equal(true))) 465 } 466 }) 467 468 By("creating a configmap", func() { 469 for _, node := range orderer5nodes { 470 Eventually(node.ConfigMapExists).Should((Equal(true))) 471 } 472 }) 473 474 By("starting a ingress", func() { 475 for _, node := range orderer5nodes { 476 Eventually(node.IngressExists).Should((Equal(true))) 477 } 478 }) 479 480 By("creating a deployment", func() { 481 for _, node := range orderer5nodes { 482 Eventually(node.DeploymentExists).Should((Equal(true))) 483 } 484 }) 485 486 By("creating init secrets", func() { 487 for _, node := range orderer5nodes { 488 Eventually(node.allInitSecretsExist).Should((Equal(true))) 489 } 490 }) 491 492 By("starting a pod", func() { 493 for _, node := range orderer5nodes { 494 Eventually(node.PodIsRunning).Should((Equal(true))) 495 } 496 }) 497 498 By("creating config map that contains spec", func() { 499 for _, node := range orderer5nodes { 500 Eventually(func() bool { 501 _, err := kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), node.Name+"-spec", metav1.GetOptions{}) 502 if err != nil { 503 return false 504 } 505 return true 506 }).Should(Equal(true)) 507 } 508 }) 509 510 By("setting the CR status to deployed when pod is running", func() { 511 for _, node := range orderer5nodes { 512 Eventually(node.pollForCRStatus).Should((Equal(current.Deployed))) 513 } 514 Eventually(orderer5.pollForCRStatus).Should((Equal(current.Deployed))) 515 }) 516 }) 517 518 When("a deployment managed by operator is manually edited", func() { 519 var ( 520 err error 521 dep *appsv1.Deployment 522 ) 523 524 BeforeEach(func() { 525 for _, node := range orderer5nodes { 526 Eventually(node.DeploymentExists).Should((Equal(true))) 527 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 528 Expect(err).NotTo(HaveOccurred()) 529 } 530 }) 531 532 It("restores states", func() { 533 for _, node := range orderer5nodes { 534 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 535 Expect(err).NotTo(HaveOccurred()) 536 537 origRequests := dep.Spec.Template.Spec.Containers[0].Resources.Requests 538 dep.Spec.Template.Spec.Containers[0].Resources.Requests = map[corev1.ResourceName]resource.Quantity{ 539 corev1.ResourceCPU: resource.MustParse("100m"), 540 corev1.ResourceMemory: resource.MustParse("200M"), 541 } 542 543 depBytes, err := json.Marshal(dep) 544 Expect(err).NotTo(HaveOccurred()) 545 546 _, err = kclient.AppsV1().Deployments(namespace).Patch(context.TODO(), node.NodeName, types.MergePatchType, depBytes, metav1.PatchOptions{}) 547 Expect(util.IgnoreOutdatedResourceVersion(err)).NotTo(HaveOccurred()) 548 549 // Wait for new deployment before querying deployment for updates 550 wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) { 551 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 552 if dep != nil { 553 if dep.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().MilliValue() == origRequests.Cpu().MilliValue() { 554 return true, nil 555 } 556 } 557 return false, nil 558 }) 559 560 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 561 Expect(err).NotTo(HaveOccurred()) 562 563 Expect(dep.Spec.Template.Spec.Containers[0].Resources.Requests).To(Equal(origRequests)) 564 } 565 }) 566 }) 567 }) 568 569 Context("applying the second instance of IBPOrderer CR", func() { 570 var ( 571 err error 572 dep *appsv1.Deployment 573 ) 574 575 // NOTE: THIS COUNTER MUST BE EQUAL TO THE NUMBER OF It() ROUTINES IN THIS CONTEXT 576 checks_remaining := 2 577 578 // Set up the orderer before the FIRST It() of this context 579 BeforeEach(func() { 580 if orderer2 == nil { 581 orderer2, orderer2nodes = GetOrderer2() 582 err := helper.CreateOrderer(ibpCRClient, orderer2.CR) 583 Expect(err).NotTo(HaveOccurred()) 584 } 585 }) 586 587 // Tear down the orderer after the LAST It() in this context 588 AfterEach(func() { 589 checks_remaining-- 590 if checks_remaining == 0 { 591 result := ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(orderer2.Name).Do(context.TODO()) 592 Expect(result.Error()).NotTo(HaveOccurred()) 593 594 orderer2 = nil 595 orderer2nodes = nil 596 } 597 }) 598 599 It("creates a second IBPOrderer custom resource", func() { 600 By("starting a pod", func() { 601 for _, node := range orderer2nodes { 602 Eventually(node.PodIsRunning).Should((Equal(true))) 603 } 604 }) 605 }) 606 607 PIt("should find zone and region", func() { 608 for _, node := range orderer2nodes { 609 // Wait for new deployment before querying deployment for updates 610 wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) { 611 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 612 if dep != nil { 613 if dep.Status.UpdatedReplicas >= 1 && dep.Status.Conditions[0].Type == appsv1.DeploymentAvailable { 614 return true, nil 615 } 616 } 617 return false, nil 618 }) 619 620 dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), node.NodeName, metav1.GetOptions{}) 621 Expect(err).NotTo(HaveOccurred()) 622 623 By("checking zone", func() { 624 Expect(orderer2.TestAffinityZone(dep)).To((Equal(true))) 625 }) 626 627 By("checking region", func() { 628 Expect(orderer2.TestAffinityRegion(dep)).To((Equal(true))) 629 }) 630 } 631 }) 632 633 It("adjust cluster size should not change number of orderers", func() { 634 By("increase number of nodes", func() { 635 orderer2.CR.Spec.ClusterSize = 5 636 bytes, err := json.Marshal(orderer2.CR) 637 Expect(err).NotTo(HaveOccurred()) 638 639 result := ibpCRClient.Patch(types.MergePatchType).Namespace(namespace).Resource("ibporderers").Name(orderer2.Name).Body(bytes).Do(context.TODO()) 640 Expect(result.Error()).NotTo(HaveOccurred()) 641 642 Eventually(orderer2.NumberOfOrdererNodeDeployments).Should((Equal(3))) 643 }) 644 645 By("reducing cluster size should not change the number of nodes", func() { 646 orderer2.CR.Spec.ClusterSize = 1 647 bytes, err := json.Marshal(orderer2.CR) 648 Expect(err).NotTo(HaveOccurred()) 649 650 result := ibpCRClient.Patch(types.MergePatchType).Namespace(namespace).Resource("ibporderers").Name(orderer2.Name).Body(bytes).Do(context.TODO()) 651 Expect(result.Error()).NotTo(HaveOccurred()) 652 653 Eventually(orderer2.NumberOfOrdererNodeDeployments).Should((Equal(3))) 654 655 secretResult := ibpCRClient.Get().Namespace(namespace).Resource("secrets").Name(fmt.Sprintf("ecert-%s%s%d-signcert", orderer2.Name, baseorderer.NODE, 3)).Do(context.TODO()) 656 Expect(secretResult.Error()).To(HaveOccurred()) 657 658 serviceResult := ibpCRClient.Get().Namespace(namespace).Resource("services").Name(fmt.Sprintf("%s%s%dservice", orderer2.Name, baseorderer.NODE, 3)).Do(context.TODO()) 659 Expect(serviceResult.Error()).To(HaveOccurred()) 660 661 cm := ibpCRClient.Get().Namespace(namespace).Resource("configmaps").Name(fmt.Sprintf("%s-%s%d-cm", orderer2.Name, baseorderer.NODE, 3)).Do(context.TODO()) 662 Expect(cm.Error()).To(HaveOccurred()) 663 664 pvc := ibpCRClient.Get().Namespace(namespace).Resource("persistentvolumeclaims").Name(fmt.Sprintf("%s-%s%d-pvc", orderer2.Name, baseorderer.NODE, 3)).Do(context.TODO()) 665 Expect(pvc.Error()).To(HaveOccurred()) 666 }) 667 }) 668 }) 669 670 Context("applying incorrectly configured third instance of IBPOrderer CR", func() { 671 672 // NOTE: THIS COUNTER MUST BE EQUAL TO THE NUMBER OF It() ROUTINES IN THIS CONTEXT 673 checks_remaining := 1 674 675 // Set up the orderer before the FIRST It() of this context 676 BeforeEach(func() { 677 if orderer3 == nil { 678 orderer3, orderer3nodes = GetOrderer3() 679 err := helper.CreateOrderer(ibpCRClient, orderer3.CR) 680 Expect(err).NotTo(HaveOccurred()) 681 } 682 }) 683 684 // Tear down the orderer after the LAST It() in this context 685 AfterEach(func() { 686 checks_remaining-- 687 if checks_remaining == 0 { 688 result := ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(orderer3.Name).Do(context.TODO()) 689 Expect(result.Error()).NotTo(HaveOccurred()) 690 691 orderer3 = nil 692 orderer3nodes = nil 693 } 694 }) 695 696 It("should set the CR status to error", func() { 697 Eventually(orderer3.pollForCRStatus).Should((Equal(current.Error))) 698 699 crStatus := ¤t.IBPOrderer{} 700 result := ibpCRClient.Get().Namespace(namespace).Resource("ibporderers").Name(orderer3.Name).Do(context.TODO()) 701 result.Into(crStatus) 702 703 Expect(crStatus.Status.Message).To(ContainSubstring("Number of Cluster Node Locations does not match cluster size")) 704 }) 705 }) 706 707 Context("deleting all child nodes should delete parent of fourth instance of IBPOrderer CR", func() { 708 709 // NOTE: THIS COUNTER MUST BE EQUAL TO THE NUMBER OF It() ROUTINES IN THIS CONTEXT 710 checks_remaining := 3 711 712 // Set up the orderer before the FIRST It() of this context 713 BeforeEach(func() { 714 if orderer4 == nil { 715 orderer4, orderer4nodes = GetOrderer4() 716 err := helper.CreateOrderer(ibpCRClient, orderer4.CR) 717 Expect(err).NotTo(HaveOccurred()) 718 } 719 }) 720 721 // Tear down the orderer after the LAST It() in this context 722 AfterEach(func() { 723 checks_remaining-- 724 if checks_remaining == 0 { 725 // Orderer4 will have been deleted during the test context - expect an error on get() 726 result := ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(orderer4.Name).Do(context.TODO()) 727 Expect(result.Error()).To(HaveOccurred()) 728 729 orderer4 = nil 730 orderer4nodes = nil 731 } 732 }) 733 734 It("creates a fourth IBPOrderer custom resource", func() { 735 By("starting a pod", func() { 736 for _, node := range orderer4nodes { 737 Eventually(node.PodIsRunning).Should((Equal(true))) 738 } 739 }) 740 }) 741 742 It("does not delete the parent if few child nodes are deleted", func() { 743 node := orderer4nodes[0] 744 result := ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(node.Name).Do(context.TODO()) 745 Expect(result.Error()).NotTo(HaveOccurred()) 746 747 node = orderer4nodes[1] 748 result = ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(node.Name).Do(context.TODO()) 749 Expect(result.Error()).NotTo(HaveOccurred()) 750 751 // Wait for second node to be deleted 752 err := wait.Poll(500*time.Millisecond, 30*time.Second, func() (bool, error) { 753 result := ibpCRClient.Get().Namespace(namespace).Resource("ibporderers").Name(node.Name).Do(context.TODO()) 754 755 if result.Error() == nil { 756 return false, nil 757 } 758 return true, nil 759 }) 760 Expect(err).NotTo(HaveOccurred()) 761 762 parent := ¤t.IBPOrderer{} 763 result = ibpCRClient.Get().Namespace(namespace).Resource("ibporderers").Name(orderer4.CR.GetName()).Do(context.TODO()) 764 Expect(result.Error()).NotTo(HaveOccurred()) 765 err = result.Into(parent) 766 Expect(err).NotTo(HaveOccurred()) 767 }) 768 769 It("deletes the parent if all child nodes are deleted", func() { 770 node := orderer4nodes[2] 771 result := ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(node.Name).Do(context.TODO()) 772 Expect(result.Error()).NotTo(HaveOccurred()) 773 774 err := wait.Poll(500*time.Millisecond, 30*time.Second, func() (bool, error) { 775 parent := ¤t.IBPOrderer{} 776 result := ibpCRClient.Get().Namespace(namespace).Resource("ibporderers").Name(orderer4.CR.Name).Do(context.TODO()) 777 if result.Error() == nil { 778 err := result.Into(parent) 779 Expect(err).NotTo(HaveOccurred()) 780 return false, nil 781 } 782 return true, nil 783 }) 784 Expect(err).NotTo(HaveOccurred()) 785 }) 786 }) 787 788 Context("pod restart", func() { 789 var ( 790 orderernode *Orderer 791 ) 792 793 BeforeEach(func() { 794 _, nodes := GetOrderer() 795 orderernode = &nodes[0] 796 }) 797 798 Context("should not trigger deployment restart if config overrides not updated", func() { 799 var ( 800 oldPodName string 801 ) 802 803 BeforeEach(func() { 804 Eventually(orderernode.PodIsRunning).Should((Equal(true))) 805 806 pods := orderernode.GetPods() 807 if len(pods) > 0 { 808 oldPodName = pods[0].Name 809 } 810 }) 811 812 It("does not restart the orderer node pod", func() { 813 Eventually(orderernode.PodIsRunning).Should((Equal(true))) 814 815 Eventually(func() bool { 816 pods := orderernode.GetPods() 817 if len(pods) != 1 { 818 return false 819 } 820 821 newPodName := pods[0].Name 822 if newPodName == oldPodName { 823 return true 824 } 825 826 return false 827 }).Should(Equal(true)) 828 }) 829 }) 830 831 Context("should trigger deployment restart if config overrides is updated", func() { 832 var ( 833 oldPodName string 834 ) 835 836 BeforeEach(func() { 837 Eventually(orderernode.PodIsRunning).Should((Equal(true))) 838 pods := orderernode.GetPods() 839 Expect(len(pods)).To(Equal(1)) 840 oldPodName = pods[0].Name 841 842 configOverride := &config.Orderer{ 843 Orderer: v2.Orderer{ 844 FileLedger: v1.FileLedger{ 845 Location: "/temp1", 846 }, 847 }, 848 } 849 configBytes, err := json.Marshal(configOverride) 850 Expect(err).NotTo(HaveOccurred()) 851 orderernode.CR.Spec.ConfigOverride = &runtime.RawExtension{Raw: configBytes} 852 853 bytes, err := json.Marshal(orderernode.CR) 854 Expect(err).NotTo(HaveOccurred()) 855 856 result := ibpCRClient.Patch(types.MergePatchType).Namespace(namespace).Resource("ibporderers").Name(orderernode.Name).Body(bytes).Do(context.TODO()) 857 Expect(result.Error()).NotTo(HaveOccurred()) 858 }) 859 860 It("restarts the pod", func() { 861 Eventually(orderernode.PodIsRunning).Should((Equal(false))) 862 Eventually(orderernode.PodIsRunning).Should((Equal(true))) 863 864 Eventually(func() bool { 865 pods := orderernode.GetPods() 866 if len(pods) != 1 { 867 return false 868 } 869 870 newPodName := pods[0].Name 871 if newPodName == oldPodName { 872 return false 873 } 874 875 return true 876 }).Should(Equal(true)) 877 }) 878 }) 879 }) 880 881 Context("delete crs", func() { 882 It("should delete IBPOrderer CR", func() { 883 By("deleting the first instance of IBPOrderer CR", func() { 884 result := ibpCRClient.Delete().Namespace(namespace).Resource("ibporderers").Name(orderer.Name).Do(context.TODO()) 885 Expect(result.Error()).NotTo(HaveOccurred()) 886 }) 887 }) 888 }) 889 }) 890 }) 891 892 func GetOrderer() (*Orderer, []Orderer) { 893 name := "ibporderer" 894 configOverride := &config.Orderer{ 895 Orderer: v2.Orderer{ 896 General: v2.General{ 897 ListenPort: uint16(7052), 898 }, 899 }, 900 } 901 configBytes, err := json.Marshal(configOverride) 902 Expect(err).NotTo(HaveOccurred()) 903 cr := ¤t.IBPOrderer{ 904 ObjectMeta: metav1.ObjectMeta{ 905 Name: name, 906 Namespace: namespace, 907 }, 908 Spec: current.IBPOrdererSpec{ 909 License: current.License{ 910 Accept: true, 911 }, 912 OrdererType: "etcdraft", 913 SystemChannelName: "testchainid", 914 OrgName: "orderermsp", 915 MSPID: "orderermsp", 916 ImagePullSecrets: []string{"regcred"}, 917 GenesisProfile: "Initial", 918 Domain: integration.TestAutomation1IngressDomain, 919 Images: ¤t.OrdererImages{ 920 GRPCWebImage: integration.GrpcwebImage, 921 GRPCWebTag: integration.GrpcwebTag, 922 OrdererImage: integration.OrdererImage, 923 OrdererTag: integration.OrdererTag, 924 OrdererInitImage: integration.InitImage, 925 OrdererInitTag: integration.InitTag, 926 }, 927 ClusterSecret: []*current.SecretSpec{ 928 ¤t.SecretSpec{ 929 MSP: testMSPSpec, 930 }, 931 }, 932 Resources: ¤t.OrdererResources{ 933 Orderer: &corev1.ResourceRequirements{ 934 Requests: defaultRequestsOrderer, 935 Limits: defaultLimitsOrderer, 936 }, 937 GRPCProxy: &corev1.ResourceRequirements{ 938 Requests: defaultRequestsProxy, 939 Limits: defaultLimitsProxy, 940 }, 941 }, 942 ConfigOverride: &runtime.RawExtension{Raw: configBytes}, 943 DisableNodeOU: pointer.Bool(true), 944 FabricVersion: integration.FabricVersion + "-1", 945 }, 946 } 947 cr.Name = name 948 949 nodes := []Orderer{ 950 Orderer{ 951 Name: name + "node1", 952 CR: cr.DeepCopy(), 953 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 954 NativeResourcePoller: integration.NativeResourcePoller{ 955 Name: name + "node1", 956 Namespace: namespace, 957 Client: kclient, 958 }, 959 }, 960 } 961 962 nodes[0].CR.ObjectMeta.Name = name + "node1" 963 964 return &Orderer{ 965 Name: name, 966 CR: cr, 967 NodeName: fmt.Sprintf("%s-%s%d", name, baseorderer.NODE, 1), 968 NativeResourcePoller: integration.NativeResourcePoller{ 969 Name: name, 970 Namespace: namespace, 971 Client: kclient, 972 }, 973 }, nodes 974 } 975 976 func GetOrderer2() (*Orderer, []Orderer) { 977 name := "ibporderer2" 978 cr := ¤t.IBPOrderer{ 979 ObjectMeta: metav1.ObjectMeta{ 980 Name: name, 981 Namespace: namespace, 982 }, 983 Spec: current.IBPOrdererSpec{ 984 License: current.License{ 985 Accept: true, 986 }, 987 OrdererType: "etcdraft", 988 ClusterSize: 3, 989 SystemChannelName: "channel1", 990 OrgName: "orderermsp", 991 MSPID: "orderermsp", 992 ImagePullSecrets: []string{"regcred"}, 993 Domain: integration.TestAutomation1IngressDomain, 994 GenesisProfile: "Initial", 995 Images: ¤t.OrdererImages{ 996 GRPCWebImage: integration.GrpcwebImage, 997 GRPCWebTag: integration.GrpcwebTag, 998 OrdererImage: integration.OrdererImage, 999 OrdererTag: integration.OrdererTag, 1000 OrdererInitImage: integration.InitImage, 1001 OrdererInitTag: integration.InitTag, 1002 }, 1003 ClusterSecret: []*current.SecretSpec{ 1004 ¤t.SecretSpec{ 1005 MSP: testMSPSpec, 1006 }, 1007 ¤t.SecretSpec{ 1008 MSP: testMSPSpec, 1009 }, 1010 ¤t.SecretSpec{ 1011 MSP: testMSPSpec, 1012 }, 1013 }, 1014 Zone: "select", 1015 Region: "select", 1016 Resources: ¤t.OrdererResources{ 1017 Orderer: &corev1.ResourceRequirements{ 1018 Requests: defaultRequestsOrderer, 1019 Limits: defaultLimitsOrderer, 1020 }, 1021 GRPCProxy: &corev1.ResourceRequirements{ 1022 Requests: defaultRequestsProxy, 1023 Limits: defaultLimitsProxy, 1024 }, 1025 }, 1026 DisableNodeOU: pointer.Bool(true), 1027 FabricVersion: integration.FabricVersion + "-1", 1028 }, 1029 } 1030 cr.Name = name 1031 1032 nodes := []Orderer{ 1033 Orderer{ 1034 Name: name + "node1", 1035 CR: cr.DeepCopy(), 1036 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1037 NativeResourcePoller: integration.NativeResourcePoller{ 1038 Name: name + "node1", 1039 Namespace: namespace, 1040 Client: kclient, 1041 }, 1042 }, 1043 Orderer{ 1044 Name: name + "node2", 1045 CR: cr.DeepCopy(), 1046 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1047 NativeResourcePoller: integration.NativeResourcePoller{ 1048 Name: name + "node2", 1049 Namespace: namespace, 1050 Client: kclient, 1051 }, 1052 }, 1053 Orderer{ 1054 Name: name + "node3", 1055 CR: cr.DeepCopy(), 1056 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1057 NativeResourcePoller: integration.NativeResourcePoller{ 1058 Name: name + "node3", 1059 Namespace: namespace, 1060 Client: kclient, 1061 }, 1062 }, 1063 } 1064 1065 nodes[0].CR.ObjectMeta.Name = name + "node1" 1066 nodes[1].CR.ObjectMeta.Name = name + "node2" 1067 nodes[2].CR.ObjectMeta.Name = name + "node3" 1068 1069 return &Orderer{ 1070 Name: name, 1071 CR: cr, 1072 NodeName: fmt.Sprintf("%s-%s%d", name, baseorderer.NODE, 1), 1073 NativeResourcePoller: integration.NativeResourcePoller{ 1074 Name: name, 1075 Namespace: namespace, 1076 Client: kclient, 1077 }, 1078 }, nodes 1079 } 1080 1081 func GetOrderer3() (*Orderer, []Orderer) { 1082 name := "ibporderer3" 1083 cr := ¤t.IBPOrderer{ 1084 ObjectMeta: metav1.ObjectMeta{ 1085 Name: name, 1086 Namespace: namespace, 1087 }, 1088 Spec: current.IBPOrdererSpec{ 1089 License: current.License{ 1090 Accept: true, 1091 }, 1092 OrdererType: "etcdraft", 1093 ClusterSize: 1, 1094 SystemChannelName: "channel1", 1095 OrgName: "ordererorg", 1096 MSPID: "orderermsp", 1097 ImagePullSecrets: []string{"regcred"}, 1098 Domain: integration.TestAutomation1IngressDomain, 1099 GenesisProfile: "Initial", 1100 Images: ¤t.OrdererImages{ 1101 GRPCWebImage: integration.GrpcwebImage, 1102 GRPCWebTag: integration.GrpcwebTag, 1103 OrdererImage: integration.OrdererImage, 1104 OrdererTag: integration.OrdererTag, 1105 OrdererInitImage: integration.InitImage, 1106 OrdererInitTag: integration.InitTag, 1107 }, 1108 Secret: ¤t.SecretSpec{ 1109 MSP: testMSPSpec, 1110 }, 1111 ClusterLocation: []current.IBPOrdererClusterLocation{ 1112 current.IBPOrdererClusterLocation{ 1113 Zone: "dal1", 1114 Region: "us-south1", 1115 }, 1116 current.IBPOrdererClusterLocation{ 1117 Zone: "dal2", 1118 Region: "us-south2", 1119 }, 1120 }, 1121 DisableNodeOU: pointer.Bool(true), 1122 FabricVersion: integration.FabricVersion + "-1", 1123 }, 1124 } 1125 cr.Name = name 1126 1127 nodes := []Orderer{ 1128 Orderer{ 1129 Name: name + "node1", 1130 CR: cr.DeepCopy(), 1131 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1132 NativeResourcePoller: integration.NativeResourcePoller{ 1133 Name: name + "node1", 1134 Namespace: namespace, 1135 Client: kclient, 1136 }, 1137 }, 1138 } 1139 1140 nodes[0].CR.ObjectMeta.Name = name + "node1" 1141 1142 return &Orderer{ 1143 Name: name, 1144 CR: cr, 1145 NodeName: fmt.Sprintf("%s-%s%d", name, baseorderer.NODE, 1), 1146 NativeResourcePoller: integration.NativeResourcePoller{ 1147 Name: name, 1148 Namespace: namespace, 1149 Client: kclient, 1150 }, 1151 }, nodes 1152 } 1153 1154 func GetOrderer4() (*Orderer, []Orderer) { 1155 name := "ibporderer4" 1156 cr := ¤t.IBPOrderer{ 1157 ObjectMeta: metav1.ObjectMeta{ 1158 Name: name, 1159 Namespace: namespace, 1160 }, 1161 Spec: current.IBPOrdererSpec{ 1162 License: current.License{ 1163 Accept: true, 1164 }, 1165 OrdererType: "etcdraft", 1166 ClusterSize: 3, 1167 SystemChannelName: "channel1", 1168 OrgName: "orderermsp", 1169 MSPID: "orderermsp", 1170 ImagePullSecrets: []string{"regcred"}, 1171 Domain: integration.TestAutomation1IngressDomain, 1172 GenesisProfile: "Initial", 1173 Images: ¤t.OrdererImages{ 1174 GRPCWebImage: integration.GrpcwebImage, 1175 GRPCWebTag: integration.GrpcwebTag, 1176 OrdererImage: integration.OrdererImage, 1177 OrdererTag: integration.OrdererTag, 1178 OrdererInitImage: integration.InitImage, 1179 OrdererInitTag: integration.InitTag, 1180 }, 1181 ClusterSecret: []*current.SecretSpec{ 1182 ¤t.SecretSpec{ 1183 MSP: testMSPSpec, 1184 }, 1185 ¤t.SecretSpec{ 1186 MSP: testMSPSpec, 1187 }, 1188 ¤t.SecretSpec{ 1189 MSP: testMSPSpec, 1190 }, 1191 }, 1192 Zone: "select", 1193 Region: "select", 1194 Resources: ¤t.OrdererResources{ 1195 Orderer: &corev1.ResourceRequirements{ 1196 Requests: defaultRequestsOrderer, 1197 Limits: defaultLimitsOrderer, 1198 }, 1199 GRPCProxy: &corev1.ResourceRequirements{ 1200 Requests: defaultRequestsProxy, 1201 Limits: defaultLimitsProxy, 1202 }, 1203 }, 1204 DisableNodeOU: pointer.Bool(true), 1205 FabricVersion: integration.FabricVersion + "-1", 1206 }, 1207 } 1208 cr.Name = name 1209 1210 nodes := []Orderer{ 1211 Orderer{ 1212 Name: name + "node1", 1213 CR: cr.DeepCopy(), 1214 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1215 NativeResourcePoller: integration.NativeResourcePoller{ 1216 Name: name + "node1", 1217 Namespace: namespace, 1218 Client: kclient, 1219 }, 1220 }, 1221 Orderer{ 1222 Name: name + "node2", 1223 CR: cr.DeepCopy(), 1224 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1225 NativeResourcePoller: integration.NativeResourcePoller{ 1226 Name: name + "node2", 1227 Namespace: namespace, 1228 Client: kclient, 1229 }, 1230 }, 1231 Orderer{ 1232 Name: name + "node3", 1233 CR: cr.DeepCopy(), 1234 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1235 NativeResourcePoller: integration.NativeResourcePoller{ 1236 Name: name + "node3", 1237 Namespace: namespace, 1238 Client: kclient, 1239 }, 1240 }, 1241 } 1242 1243 nodes[0].CR.ObjectMeta.Name = name + "node1" 1244 nodes[1].CR.ObjectMeta.Name = name + "node2" 1245 nodes[2].CR.ObjectMeta.Name = name + "node3" 1246 1247 return &Orderer{ 1248 Name: name, 1249 CR: cr, 1250 NodeName: fmt.Sprintf("%s-%s%d", name, baseorderer.NODE, 1), 1251 NativeResourcePoller: integration.NativeResourcePoller{ 1252 Name: name, 1253 Namespace: namespace, 1254 Client: kclient, 1255 }, 1256 }, nodes 1257 } 1258 1259 func GetOrderer5() (*Orderer, []Orderer) { 1260 name := "ibporderer5" 1261 cr := ¤t.IBPOrderer{ 1262 ObjectMeta: metav1.ObjectMeta{ 1263 Name: name, 1264 Namespace: namespace, 1265 }, 1266 Spec: current.IBPOrdererSpec{ 1267 License: current.License{ 1268 Accept: true, 1269 }, 1270 OrdererType: "etcdraft", 1271 SystemChannelName: "testchainid", 1272 UseChannelLess: pointer.Bool(true), 1273 OrgName: "orderermsp", 1274 MSPID: "orderermsp", 1275 ImagePullSecrets: []string{"regcred"}, 1276 GenesisProfile: "Initial", 1277 Domain: integration.TestAutomation1IngressDomain, 1278 Images: ¤t.OrdererImages{ 1279 GRPCWebImage: integration.GrpcwebImage, 1280 GRPCWebTag: integration.GrpcwebTag, 1281 OrdererImage: integration.OrdererImage, 1282 OrdererTag: integration.Orderer24Tag, 1283 OrdererInitImage: integration.InitImage, 1284 OrdererInitTag: integration.InitTag, 1285 }, 1286 ClusterSecret: []*current.SecretSpec{ 1287 ¤t.SecretSpec{ 1288 MSP: testMSPSpec, 1289 }, 1290 }, 1291 Resources: ¤t.OrdererResources{ 1292 Orderer: &corev1.ResourceRequirements{ 1293 Requests: defaultRequestsOrderer, 1294 Limits: defaultLimitsOrderer, 1295 }, 1296 GRPCProxy: &corev1.ResourceRequirements{ 1297 Requests: defaultRequestsProxy, 1298 Limits: defaultLimitsProxy, 1299 }, 1300 }, 1301 DisableNodeOU: pointer.Bool(true), 1302 FabricVersion: integration.FabricVersion24 + "-1", 1303 }, 1304 } 1305 cr.Name = name 1306 1307 nodes := []Orderer{ 1308 Orderer{ 1309 Name: name + "node1", 1310 CR: cr.DeepCopy(), 1311 NodeName: fmt.Sprintf("%s%s%d", name, baseorderer.NODE, 1), 1312 NativeResourcePoller: integration.NativeResourcePoller{ 1313 Name: name + "node1", 1314 Namespace: namespace, 1315 Client: kclient, 1316 }, 1317 }, 1318 } 1319 1320 nodes[0].CR.ObjectMeta.Name = name + "node1" 1321 1322 return &Orderer{ 1323 Name: name, 1324 CR: cr, 1325 NodeName: fmt.Sprintf("%s-%s%d", name, baseorderer.NODE, 1), 1326 NativeResourcePoller: integration.NativeResourcePoller{ 1327 Name: name, 1328 Namespace: namespace, 1329 Client: kclient, 1330 }, 1331 }, nodes 1332 } 1333 1334 type Orderer struct { 1335 Name string 1336 CR *current.IBPOrderer 1337 NodeName string 1338 integration.NativeResourcePoller 1339 } 1340 1341 func (orderer *Orderer) pollForCRStatus() current.IBPCRStatusType { 1342 crStatus := ¤t.IBPOrderer{} 1343 1344 result := ibpCRClient.Get().Namespace(namespace).Resource("ibporderers").Name(orderer.Name).Do(context.TODO()) 1345 result.Into(crStatus) 1346 1347 return crStatus.Status.Type 1348 } 1349 1350 func (orderer *Orderer) allInitSecretsExist() bool { 1351 prefix := "ecert-" + orderer.NodeName 1352 name := prefix + "-admincerts" 1353 _, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 1354 if err != nil { 1355 return false 1356 } 1357 1358 name = prefix + "-cacerts" 1359 _, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 1360 if err != nil { 1361 return false 1362 } 1363 1364 name = prefix + "-signcert" 1365 _, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 1366 if err != nil { 1367 return false 1368 } 1369 1370 name = prefix + "-keystore" 1371 _, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 1372 if err != nil { 1373 return false 1374 } 1375 1376 prefix = "tls-" + orderer.NodeName 1377 name = prefix + "-cacerts" 1378 _, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 1379 if err != nil { 1380 return false 1381 } 1382 1383 name = prefix + "-signcert" 1384 _, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 1385 if err != nil { 1386 return false 1387 } 1388 1389 name = prefix + "-keystore" 1390 _, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{}) 1391 if err != nil { 1392 return false 1393 } 1394 1395 return true 1396 } 1397 1398 func (o *Orderer) DeploymentExists() bool { 1399 dep, err := kclient.AppsV1().Deployments(namespace).Get(context.TODO(), o.NodeName, metav1.GetOptions{}) 1400 if err == nil && dep != nil { 1401 return true 1402 } 1403 1404 return false 1405 }