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 = &current.MSPSpec{
    95  		Component: &current.MSP{
    96  			KeyStore:   "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR0hBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJHMHdhd0lCQVFRZ2FYb2MwNkxoWmliYjFsSEUKU0ZaY2NSeThmcWUySjROQW1rdEtXZEpFZVBxaFJBTkNBQVJ4UGVOKy94WHRLeTdXNGlZajUxQ29LQ2NmZ2Y4NApnMDBkamEzSStNeHNLSDZncVNQUGpXbThvUi9sYnZhbW9jay84bURoRi9yZTd3SU5qWkpGeG80aAotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==",
    97  			SignCerts:  "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNUVENDQWZPZ0F3SUJBZ0lVTUw4NVhXVVJLZURqV1ZjelNWZ0ZoWDdtWlFjd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVGN3TUZvWERUSTFNVEV5T1RJd01qSXdNRm93WFRFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdZMnhwWlc1ME1RNHdEQVlEVlFRREV3VmhaRzFwYmpCWk1CTUdCeXFHClNNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJIRTk0MzcvRmUwckx0YmlKaVBuVUtnb0p4K0IvemlEVFIyTnJjajQKekd3b2ZxQ3BJOCtOYWJ5aEgrVnU5cWFoeVQveVlPRVgrdDd2QWcyTmtrWEdqaUdqZ1lVd2dZSXdEZ1lEVlIwUApBUUgvQkFRREFnZUFNQXdHQTFVZEV3RUIvd1FDTUFBd0hRWURWUjBPQkJZRUZNSGxPTGthZTFSbFRaZ1BNQ0ZQCkxKai80MHBzTUI4R0ExVWRJd1FZTUJhQUZNeTZicUR5Q1p1UThEeTBQWkhtVUNJTDRzNmlNQ0lHQTFVZEVRUWIKTUJtQ0YxTmhZV1J6TFUxaFkwSnZiMnN0VUhKdkxteHZZMkZzTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFERAowY1Z6aEJFcGo1aFhYVXQzQSsxQVZOc2IyZDgxNVpZSVVVTG0xQXZ5T1FJZ1d1eldoVzQ5QUNWSG8zWkhNRE1vCmU5d3FRbUpTNDB2UGJtMEtOVUVkdURjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==",
    98  			CACerts:    []string{"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNGakNDQWIyZ0F3SUJBZ0lVS2dNc2pwYlFSNlRHUUs3QVBhMEZmUVZxT1pvd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVFV3TUZvWERUTTFNVEV5TnpJd01UVXdNRm93YURFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdSbUZpY21sak1Sa3dGd1lEVlFRREV4Qm1ZV0p5YVdNdFkyRXRjMlZ5CmRtVnlNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUrb2lXeWdGNWpLY081cWtzaG8zN3lzRSsKdXYxMEF5WWZrUGxVWXlBVkJOeGtlSGN1RUlWSmY5LzZRL2x2S2NvUyt6cFp2dlFiSTEzT1pSTDNMK25IZXFORgpNRU13RGdZRFZSMFBBUUgvQkFRREFnRUdNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUV3SFFZRFZSME9CQllFCkZNeTZicUR5Q1p1UThEeTBQWkhtVUNJTDRzNmlNQW9HQ0NxR1NNNDlCQU1DQTBjQU1FUUNJQmdSTXNqN3Azc1YKMHNieEQxa2t0amloVEpHVFJBWlZRQXVyY0hhRVVENFVBaUFoN0o4U2ZPQTc5VjN4RDdvaExFcmVpZHVnZnhIbAozWWxZS0g3MG9qQXhRZz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"},
    99  			AdminCerts: []string{"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNUVENDQWZPZ0F3SUJBZ0lVTUw4NVhXVVJLZURqV1ZjelNWZ0ZoWDdtWlFjd0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEl3TVRFek1ESXdNVGN3TUZvWERUSTFNVEV5T1RJd01qSXdNRm93WFRFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdZMnhwWlc1ME1RNHdEQVlEVlFRREV3VmhaRzFwYmpCWk1CTUdCeXFHClNNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJIRTk0MzcvRmUwckx0YmlKaVBuVUtnb0p4K0IvemlEVFIyTnJjajQKekd3b2ZxQ3BJOCtOYWJ5aEgrVnU5cWFoeVQveVlPRVgrdDd2QWcyTmtrWEdqaUdqZ1lVd2dZSXdEZ1lEVlIwUApBUUgvQkFRREFnZUFNQXdHQTFVZEV3RUIvd1FDTUFBd0hRWURWUjBPQkJZRUZNSGxPTGthZTFSbFRaZ1BNQ0ZQCkxKai80MHBzTUI4R0ExVWRJd1FZTUJhQUZNeTZicUR5Q1p1UThEeTBQWkhtVUNJTDRzNmlNQ0lHQTFVZEVRUWIKTUJtQ0YxTmhZV1J6TFUxaFkwSnZiMnN0VUhKdkxteHZZMkZzTUFvR0NDcUdTTTQ5QkFNQ0EwZ0FNRVVDSVFERAowY1Z6aEJFcGo1aFhYVXQzQSsxQVZOc2IyZDgxNVpZSVVVTG0xQXZ5T1FJZ1d1eldoVzQ5QUNWSG8zWkhNRE1vCmU5d3FRbUpTNDB2UGJtMEtOVUVkdURjPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="},
   100  		},
   101  		TLS: &current.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 := &current.IBPOrderer{}
   304  						result := ibpCRClient.Get().Namespace(namespace).Resource("ibporderers").Name(node.Name).Do(context.TODO())
   305  						result.Into(updatenode)
   306  
   307  						updatenode.Spec.Resources = &current.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 := &current.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 := &current.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 := &current.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 := &current.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: &current.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  				&current.SecretSpec{
   929  					MSP: testMSPSpec,
   930  				},
   931  			},
   932  			Resources: &current.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 := &current.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: &current.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  				&current.SecretSpec{
  1005  					MSP: testMSPSpec,
  1006  				},
  1007  				&current.SecretSpec{
  1008  					MSP: testMSPSpec,
  1009  				},
  1010  				&current.SecretSpec{
  1011  					MSP: testMSPSpec,
  1012  				},
  1013  			},
  1014  			Zone:   "select",
  1015  			Region: "select",
  1016  			Resources: &current.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 := &current.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: &current.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: &current.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 := &current.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: &current.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  				&current.SecretSpec{
  1183  					MSP: testMSPSpec,
  1184  				},
  1185  				&current.SecretSpec{
  1186  					MSP: testMSPSpec,
  1187  				},
  1188  				&current.SecretSpec{
  1189  					MSP: testMSPSpec,
  1190  				},
  1191  			},
  1192  			Zone:   "select",
  1193  			Region: "select",
  1194  			Resources: &current.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 := &current.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: &current.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  				&current.SecretSpec{
  1288  					MSP: testMSPSpec,
  1289  				},
  1290  			},
  1291  			Resources: &current.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 := &current.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  }