github.com/IBM-Blockchain/fabric-operator@v1.0.4/integration/migration/migration_test.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package migration_test
    20  
    21  import (
    22  	"context"
    23  	"encoding/json"
    24  	"errors"
    25  	"fmt"
    26  	"io/ioutil"
    27  	"math/rand"
    28  	"path/filepath"
    29  	"strings"
    30  	"time"
    31  
    32  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    33  	"github.com/IBM-Blockchain/fabric-operator/integration"
    34  	config "github.com/IBM-Blockchain/fabric-operator/operatorconfig"
    35  	cainit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/ca"
    36  	"github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common/mocks"
    37  	ordererinit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/orderer"
    38  	peerinit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/peer"
    39  	allmigrator "github.com/IBM-Blockchain/fabric-operator/pkg/migrator"
    40  	"github.com/IBM-Blockchain/fabric-operator/pkg/migrator/initsecret"
    41  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering"
    42  	"github.com/IBM-Blockchain/fabric-operator/version"
    43  	. "github.com/onsi/ginkgo/v2"
    44  	. "github.com/onsi/gomega"
    45  	corev1 "k8s.io/api/core/v1"
    46  	networkingv1 "k8s.io/api/networking/v1"
    47  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    48  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    49  	"k8s.io/apimachinery/pkg/types"
    50  	"k8s.io/apimachinery/pkg/util/wait"
    51  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    52  	"sigs.k8s.io/controller-runtime/pkg/log/zap"
    53  )
    54  
    55  func GetLabels(instance v1.Object) map[string]string {
    56  	return map[string]string{
    57  		"app": "peermigraton",
    58  	}
    59  }
    60  
    61  func RandomNodePort() int32 {
    62  	rand.Seed(time.Now().UnixNano())
    63  	min := 30000
    64  	max := 32767
    65  	return int32(rand.Intn(max-min+1) + min)
    66  }
    67  
    68  // TODO api versioning/migration logic will be updated
    69  var _ = PDescribe("migrating", func() {
    70  	Context("ca", func() {
    71  		var (
    72  			migrator          *allmigrator.Migrator
    73  			instance          *current.IBPCA
    74  			httpNodePort      int32
    75  			operationNodePort int32
    76  		)
    77  
    78  		BeforeEach(func() {
    79  			logf.SetLogger(zap.New())
    80  
    81  			defaultConfigs := "../../defaultconfig"
    82  			of, err := offering.GetType("K8S")
    83  			Expect(err).To(BeNil())
    84  
    85  			operatorCfg := &config.Config{
    86  				CAInitConfig: &cainit.Config{
    87  					CADefaultConfigPath:    filepath.Join(defaultConfigs, "ca/ca.yaml"),
    88  					TLSCADefaultConfigPath: filepath.Join(defaultConfigs, "ca/tlsca.yaml"),
    89  					SharedPath:             "/shared",
    90  				},
    91  				PeerInitConfig: &peerinit.Config{
    92  					OUFile: filepath.Join(defaultConfigs, "peer/ouconfig.yaml"),
    93  				},
    94  				OrdererInitConfig: &ordererinit.Config{
    95  					OrdererFile:  filepath.Join(defaultConfigs, "orderer/orderer.yaml"),
    96  					ConfigTxFile: filepath.Join(defaultConfigs, "orderer/configtx.yaml"),
    97  					OUFile:       filepath.Join(defaultConfigs, "orderer/ouconfig.yaml"),
    98  				},
    99  				Offering: of,
   100  			}
   101  
   102  			migrator = allmigrator.New(mgr, operatorCfg, namespace)
   103  
   104  			consoleinstance := &current.IBPConsole{
   105  				ObjectMeta: metav1.ObjectMeta{
   106  					Name:      "consolemigration0",
   107  					Namespace: namespace,
   108  				},
   109  				Spec: current.IBPConsoleSpec{
   110  					NetworkInfo: &current.NetworkInfo{
   111  						Domain: "domain",
   112  					},
   113  				},
   114  				Status: current.IBPConsoleStatus{
   115  					CRStatus: current.CRStatus{
   116  						Status:  current.True,
   117  						Version: version.V213,
   118  					},
   119  				},
   120  			}
   121  			err = client.Create(context.TODO(), consoleinstance)
   122  			Expect(err).NotTo(HaveOccurred())
   123  
   124  			err = client.UpdateStatus(context.TODO(), consoleinstance)
   125  			Expect(err).NotTo(HaveOccurred())
   126  
   127  			instance = &current.IBPCA{
   128  				ObjectMeta: metav1.ObjectMeta{
   129  					Name:      "camigration",
   130  					Namespace: namespace,
   131  				},
   132  				Spec: current.IBPCASpec{
   133  					FabricVersion: integration.FabricCAVersion,
   134  				},
   135  				Status: current.IBPCAStatus{
   136  					CRStatus: current.CRStatus{
   137  						Status: current.True,
   138  					},
   139  				},
   140  			}
   141  			err = client.Create(context.TODO(), instance)
   142  			Expect(err).NotTo(HaveOccurred())
   143  			err = client.UpdateStatus(context.TODO(), instance)
   144  			Expect(err).NotTo(HaveOccurred())
   145  
   146  			operationNodePort = RandomNodePort()
   147  			httpNodePort = RandomNodePort()
   148  			service := &corev1.Service{
   149  				Spec: corev1.ServiceSpec{
   150  					Type: corev1.ServiceTypeNodePort,
   151  					Ports: []corev1.ServicePort{
   152  						corev1.ServicePort{
   153  							Name:     "http",
   154  							Port:     int32(7054),
   155  							NodePort: httpNodePort,
   156  						},
   157  						corev1.ServicePort{
   158  							Name:     "operations",
   159  							Port:     int32(9443),
   160  							NodePort: operationNodePort,
   161  						},
   162  					},
   163  				},
   164  			}
   165  			service.Name = "camigration-service"
   166  			service.Namespace = namespace
   167  
   168  			httpNodePort, operationNodePort = CreateServiceWithRetry(service, 3)
   169  			pathType := networkingv1.PathTypeImplementationSpecific
   170  			ingress := &networkingv1.Ingress{
   171  				Spec: networkingv1.IngressSpec{
   172  					Rules: []networkingv1.IngressRule{
   173  						networkingv1.IngressRule{
   174  							IngressRuleValue: networkingv1.IngressRuleValue{
   175  								HTTP: &networkingv1.HTTPIngressRuleValue{
   176  									Paths: []networkingv1.HTTPIngressPath{
   177  										networkingv1.HTTPIngressPath{
   178  											Backend: networkingv1.IngressBackend{
   179  												Service: &networkingv1.IngressServiceBackend{
   180  													Name: "camigration-service",
   181  													Port: networkingv1.ServiceBackendPort{
   182  														Number: 443,
   183  													},
   184  												},
   185  											},
   186  											Path:     "/",
   187  											PathType: &pathType,
   188  										},
   189  									},
   190  								},
   191  							},
   192  						},
   193  					},
   194  				},
   195  			}
   196  			ingress.Name = "camigration"
   197  			ingress.Namespace = namespace
   198  
   199  			err = client.Create(context.TODO(), ingress)
   200  			Expect(err).NotTo(HaveOccurred())
   201  
   202  			cm := &corev1.ConfigMap{
   203  				ObjectMeta: metav1.ObjectMeta{
   204  					Name:      fmt.Sprintf("%s-ca", instance.Name),
   205  					Namespace: instance.Namespace,
   206  				},
   207  			}
   208  			err = client.Create(context.TODO(), cm)
   209  			Expect(err).NotTo(HaveOccurred())
   210  
   211  			cm = &corev1.ConfigMap{
   212  				ObjectMeta: metav1.ObjectMeta{
   213  					Name:      fmt.Sprintf("%s-overrides", instance.Name),
   214  					Namespace: instance.Namespace,
   215  				},
   216  			}
   217  			err = client.Create(context.TODO(), cm)
   218  			Expect(err).NotTo(HaveOccurred())
   219  
   220  			secret := &corev1.Secret{
   221  				ObjectMeta: metav1.ObjectMeta{
   222  					Name:      fmt.Sprintf("%s-ca", instance.Name),
   223  					Namespace: instance.Namespace,
   224  				},
   225  			}
   226  			err = client.Create(context.TODO(), secret)
   227  			Expect(err).NotTo(HaveOccurred())
   228  
   229  			secret = &corev1.Secret{
   230  				ObjectMeta: metav1.ObjectMeta{
   231  					Name:      fmt.Sprintf("%s-tlsca", instance.Name),
   232  					Namespace: instance.Namespace,
   233  				},
   234  			}
   235  			err = client.Create(context.TODO(), secret)
   236  			Expect(err).NotTo(HaveOccurred())
   237  		})
   238  
   239  		It("migrates ca resources", func() {
   240  			err := migrator.Migrate()
   241  			Expect(err).NotTo(HaveOccurred())
   242  
   243  			By("creating a secret with state of current resources before migration", func() {
   244  				var secret *corev1.Secret
   245  				var err error
   246  
   247  				Eventually(func() bool {
   248  					secret, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "camigration-oldstate", metav1.GetOptions{})
   249  					if err != nil {
   250  						return false
   251  					}
   252  					return true
   253  				}).Should(Equal(true))
   254  
   255  				Expect(secret.Data["camigration-service"]).NotTo(Equal(""))
   256  				Expect(secret.Data["camigration-cm-ca"]).NotTo(Equal(""))
   257  				Expect(secret.Data["camigration-cm-overrides"]).NotTo(Equal(""))
   258  				Expect(secret.Data["camigration-secret-ca"]).NotTo(Equal(""))
   259  				Expect(secret.Data["camigration-secret-tlsca"]).NotTo(Equal(""))
   260  			})
   261  
   262  			By("creating a new service with no 'service' in name and same nodeport", func() {
   263  				var service *corev1.Service
   264  				var err error
   265  
   266  				Eventually(func() bool {
   267  					service, err = kclient.CoreV1().Services(namespace).Get(context.TODO(), "camigration", metav1.GetOptions{})
   268  					if err != nil {
   269  						return false
   270  					}
   271  					return true
   272  				}).Should(Equal(true))
   273  
   274  				Expect(service.Spec.Ports[0].NodePort).To(Equal(httpNodePort))
   275  				Expect(service.Spec.Ports[1].NodePort).To(Equal(operationNodePort))
   276  
   277  				_, err = kclient.CoreV1().Services(namespace).Get(context.TODO(), "camigration-service", metav1.GetOptions{})
   278  				Expect(err).To(HaveOccurred())
   279  			})
   280  
   281  			By("creating a new ingress with no dashes and same servicename", func() {
   282  				var ingress *networkingv1.Ingress
   283  				var err error
   284  
   285  				Eventually(func() bool {
   286  					ingress, err = kclient.NetworkingV1().Ingresses(namespace).Get(context.TODO(), "camigration", metav1.GetOptions{})
   287  					if err != nil {
   288  						return false
   289  					}
   290  					return true
   291  				}).Should(Equal(true))
   292  
   293  				Expect(ingress.Spec.Rules[0].HTTP.Paths[0].Backend.Service.Name).To(Equal("camigration"))
   294  			})
   295  		})
   296  	})
   297  
   298  	Context("console", func() {
   299  		var (
   300  			migrator          *allmigrator.Migrator
   301  			instance          *current.IBPConsole
   302  			httpNodePort      int32
   303  			operationNodePort int32
   304  		)
   305  
   306  		BeforeEach(func() {
   307  			logf.SetLogger(zap.New())
   308  
   309  			defaultConfigs := "../../defaultconfig"
   310  			of, err := offering.GetType("K8S")
   311  
   312  			operatorCfg := &config.Config{
   313  				CAInitConfig: &cainit.Config{
   314  					CADefaultConfigPath:    filepath.Join(defaultConfigs, "ca/ca.yaml"),
   315  					TLSCADefaultConfigPath: filepath.Join(defaultConfigs, "ca/tlsca.yaml"),
   316  					SharedPath:             "/shared",
   317  				},
   318  				PeerInitConfig: &peerinit.Config{
   319  					OUFile: filepath.Join(defaultConfigs, "peer/ouconfig.yaml"),
   320  				},
   321  				OrdererInitConfig: &ordererinit.Config{
   322  					OrdererFile:  filepath.Join(defaultConfigs, "orderer/orderer.yaml"),
   323  					ConfigTxFile: filepath.Join(defaultConfigs, "orderer/configtx.yaml"),
   324  					OUFile:       filepath.Join(defaultConfigs, "orderer/ouconfig.yaml"),
   325  				},
   326  				Offering: of,
   327  			}
   328  
   329  			migrator = allmigrator.New(mgr, operatorCfg, namespace)
   330  
   331  			instance = &current.IBPConsole{
   332  				ObjectMeta: metav1.ObjectMeta{
   333  					Name:      "consolemigration",
   334  					Namespace: namespace,
   335  				},
   336  				Spec: current.IBPConsoleSpec{
   337  					NetworkInfo: &current.NetworkInfo{},
   338  				},
   339  				Status: current.IBPConsoleStatus{
   340  					CRStatus: current.CRStatus{
   341  						Status: current.True,
   342  					},
   343  				},
   344  			}
   345  			err = client.Create(context.TODO(), instance)
   346  			Expect(err).NotTo(HaveOccurred())
   347  			err = client.UpdateStatus(context.TODO(), instance)
   348  			Expect(err).NotTo(HaveOccurred())
   349  
   350  			operationNodePort = RandomNodePort()
   351  			httpNodePort = RandomNodePort()
   352  			service := &corev1.Service{
   353  				Spec: corev1.ServiceSpec{
   354  					Type: corev1.ServiceTypeNodePort,
   355  					Ports: []corev1.ServicePort{
   356  						corev1.ServicePort{
   357  							Name:     "http",
   358  							Port:     int32(7054),
   359  							NodePort: httpNodePort,
   360  						},
   361  						corev1.ServicePort{
   362  							Name:     "operations",
   363  							Port:     int32(9443),
   364  							NodePort: operationNodePort,
   365  						},
   366  					},
   367  				},
   368  			}
   369  			service.Name = "consolemigration-service"
   370  			service.Namespace = namespace
   371  
   372  			httpNodePort, operationNodePort = CreateServiceWithRetry(service, 3)
   373  
   374  			ingress := &networkingv1.Ingress{
   375  				Spec: networkingv1.IngressSpec{
   376  					Rules: []networkingv1.IngressRule{
   377  						networkingv1.IngressRule{
   378  							IngressRuleValue: networkingv1.IngressRuleValue{
   379  								HTTP: &networkingv1.HTTPIngressRuleValue{
   380  									Paths: []networkingv1.HTTPIngressPath{
   381  										networkingv1.HTTPIngressPath{
   382  											Backend: networkingv1.IngressBackend{
   383  												Service: &networkingv1.IngressServiceBackend{
   384  													Name: "consolemigration-service",
   385  													Port: networkingv1.ServiceBackendPort{
   386  														Number: 443,
   387  													},
   388  												},
   389  											},
   390  										},
   391  									},
   392  								},
   393  							},
   394  						},
   395  					},
   396  				},
   397  			}
   398  			ingress.Name = "consolemigration"
   399  			ingress.Namespace = namespace
   400  
   401  			err = client.Create(context.TODO(), ingress)
   402  			Expect(err).NotTo(HaveOccurred())
   403  
   404  			secret := &corev1.Secret{
   405  				ObjectMeta: metav1.ObjectMeta{
   406  					Name:      fmt.Sprintf("%s-console-pw", instance.Name),
   407  					Namespace: instance.Namespace,
   408  				},
   409  			}
   410  			err = client.Create(context.TODO(), secret)
   411  			Expect(err).NotTo(HaveOccurred())
   412  
   413  			cm := &corev1.ConfigMap{
   414  				ObjectMeta: metav1.ObjectMeta{
   415  					Name:      fmt.Sprintf("%s-configmap", instance.Name),
   416  					Namespace: instance.Namespace,
   417  				},
   418  			}
   419  			err = client.Create(context.TODO(), cm)
   420  			Expect(err).NotTo(HaveOccurred())
   421  
   422  			cm = &corev1.ConfigMap{
   423  				ObjectMeta: metav1.ObjectMeta{
   424  					Name:      fmt.Sprintf("%s-deployer-template", instance.Name),
   425  					Namespace: instance.Namespace,
   426  				},
   427  			}
   428  			err = client.Create(context.TODO(), cm)
   429  			Expect(err).NotTo(HaveOccurred())
   430  
   431  			cm = &corev1.ConfigMap{
   432  				ObjectMeta: metav1.ObjectMeta{
   433  					Name:      fmt.Sprintf("%s-template-configmap", instance.Name),
   434  					Namespace: instance.Namespace,
   435  				},
   436  			}
   437  			err = client.Create(context.TODO(), cm)
   438  			Expect(err).NotTo(HaveOccurred())
   439  
   440  			n := types.NamespacedName{
   441  				Name:      cm.GetName(),
   442  				Namespace: cm.GetNamespace(),
   443  			}
   444  
   445  			err = wait.Poll(500*time.Millisecond, 30*time.Second, func() (bool, error) {
   446  				err := client.Get(context.TODO(), n, cm)
   447  				if err == nil {
   448  					return true, nil
   449  				}
   450  				return false, nil
   451  			})
   452  			Expect(err).NotTo(HaveOccurred())
   453  
   454  		})
   455  
   456  		It("migrates console resources", func() {
   457  			err := migrator.Migrate()
   458  			Expect(err).NotTo(HaveOccurred())
   459  
   460  			Eventually(func() bool {
   461  				_, err := kclient.CoreV1().Services(namespace).Get(context.TODO(), "consolemigration-service", metav1.GetOptions{})
   462  				if err != nil {
   463  					return false
   464  				}
   465  				return true
   466  			}).Should(Equal(false))
   467  
   468  			By("creating a secret with state of current resources before migration", func() {
   469  				var secret *corev1.Secret
   470  				var err error
   471  
   472  				Eventually(func() bool {
   473  					secret, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "consolemigration-oldstate", metav1.GetOptions{})
   474  					if err != nil {
   475  						return false
   476  					}
   477  					return true
   478  				}).Should(Equal(true))
   479  
   480  				Expect(secret.Data["consolemigration-service"]).NotTo(Equal(""))
   481  				Expect(secret.Data["consolemigration-cm"]).NotTo(Equal(""))
   482  				Expect(secret.Data["consolemigration-cm-deployer"]).NotTo(Equal(""))
   483  				Expect(secret.Data["consolemigration-cm-template"]).NotTo(Equal(""))
   484  				Expect(secret.Data["consolemigration-secret-pw"]).NotTo(Equal(""))
   485  			})
   486  
   487  			By("creating a new service with 'service' and same nodeport", func() {
   488  				var service *corev1.Service
   489  				var err error
   490  
   491  				Eventually(func() bool {
   492  					service, err = kclient.CoreV1().Services(namespace).Get(context.TODO(), "consolemigration", metav1.GetOptions{})
   493  					if err != nil {
   494  						return false
   495  					}
   496  					return true
   497  				}).Should(Equal(true))
   498  
   499  				Expect(service.Spec.Ports[0].NodePort).To(Equal(httpNodePort))
   500  				Expect(service.Spec.Ports[1].NodePort).To(Equal(operationNodePort))
   501  			})
   502  
   503  			By("creating a new ingress with no dashes and same servicename", func() {
   504  				var ingress *networkingv1.Ingress
   505  				var err error
   506  
   507  				Eventually(func() bool {
   508  					ingress, err = kclient.NetworkingV1().Ingresses(namespace).Get(context.TODO(), "consolemigration", metav1.GetOptions{})
   509  					if err != nil {
   510  						return false
   511  					}
   512  					return true
   513  				}).Should(Equal(true))
   514  
   515  				Expect(ingress.Spec.Rules[0].HTTP.Paths[0].Backend.Service.Name).To(Equal("consolemigration"))
   516  			})
   517  		})
   518  	})
   519  
   520  	Context("peer", func() {
   521  		var (
   522  			migrator             *allmigrator.Migrator
   523  			instance             *current.IBPPeer
   524  			mspSecret            *initsecret.Secret
   525  			peerApiNodePort      int32
   526  			operationNodePort    int32
   527  			grpcwebDebugNodePort int32
   528  			grpcwebNodePort      int32
   529  		)
   530  
   531  		BeforeEach(func() {
   532  			logf.SetLogger(zap.New())
   533  			mockValidator := &mocks.CryptoValidator{}
   534  			mockValidator.CheckEcertCryptoReturns(errors.New("not found"))
   535  
   536  			defaultConfigs := "../../defaultconfig"
   537  			of, err := offering.GetType("K8S")
   538  
   539  			operatorCfg := &config.Config{
   540  				CAInitConfig: &cainit.Config{
   541  					CADefaultConfigPath:    filepath.Join(defaultConfigs, "ca/ca.yaml"),
   542  					TLSCADefaultConfigPath: filepath.Join(defaultConfigs, "ca/tlsca.yaml"),
   543  					SharedPath:             "/shared",
   544  				},
   545  				PeerInitConfig: &peerinit.Config{
   546  					CorePeerFile: filepath.Join(defaultConfigs, "peer/core.yaml"),
   547  					OUFile:       filepath.Join(defaultConfigs, "peer/ouconfig.yaml"),
   548  				},
   549  				OrdererInitConfig: &ordererinit.Config{
   550  					OrdererFile:  filepath.Join(defaultConfigs, "orderer/orderer.yaml"),
   551  					ConfigTxFile: filepath.Join(defaultConfigs, "orderer/configtx.yaml"),
   552  					OUFile:       filepath.Join(defaultConfigs, "orderer/ouconfig.yaml"),
   553  				},
   554  				Offering: of,
   555  			}
   556  
   557  			migrator = allmigrator.New(mgr, operatorCfg, namespace)
   558  
   559  			instance = &current.IBPPeer{
   560  				ObjectMeta: metav1.ObjectMeta{
   561  					Name:      "peermigration",
   562  					Namespace: namespace,
   563  				},
   564  				Spec: current.IBPPeerSpec{
   565  					Domain:           "127.0.0.1",
   566  					ImagePullSecrets: []string{"pullSecret"},
   567  					Images: &current.PeerImages{
   568  						CouchDBImage: integration.CouchdbImage,
   569  						CouchDBTag:   integration.CouchdbTag,
   570  					},
   571  				},
   572  				Status: current.IBPPeerStatus{
   573  					CRStatus: current.CRStatus{
   574  						Status: current.True,
   575  					},
   576  				},
   577  			}
   578  			err = client.Create(context.TODO(), instance)
   579  			Expect(err).NotTo(HaveOccurred())
   580  			err = client.UpdateStatus(context.TODO(), instance)
   581  			Expect(err).NotTo(HaveOccurred())
   582  
   583  			peerApiNodePort = RandomNodePort()
   584  			operationNodePort = RandomNodePort()
   585  			grpcwebDebugNodePort = RandomNodePort()
   586  			grpcwebNodePort = RandomNodePort()
   587  			service := &corev1.Service{
   588  				Spec: corev1.ServiceSpec{
   589  					Type: corev1.ServiceTypeNodePort,
   590  					Ports: []corev1.ServicePort{
   591  						corev1.ServicePort{
   592  							Name:     "peer-api",
   593  							Port:     int32(7051),
   594  							NodePort: peerApiNodePort,
   595  						},
   596  						corev1.ServicePort{
   597  							Name:     "operations",
   598  							Port:     int32(9443),
   599  							NodePort: operationNodePort,
   600  						},
   601  						corev1.ServicePort{
   602  							Name:     "grpcweb-debug",
   603  							Port:     int32(8080),
   604  							NodePort: grpcwebDebugNodePort,
   605  						},
   606  						corev1.ServicePort{
   607  							Name:     "grpcweb",
   608  							Port:     int32(7443),
   609  							NodePort: grpcwebNodePort,
   610  						},
   611  					},
   612  				},
   613  			}
   614  			service.Name = "peermigration-service"
   615  			service.Namespace = namespace
   616  
   617  			peerApiNodePort, operationNodePort, grpcwebDebugNodePort, grpcwebNodePort = CreatePeerServiceWithRetry(service, 3)
   618  
   619  			ingress := &networkingv1.Ingress{
   620  				Spec: networkingv1.IngressSpec{
   621  					Rules: []networkingv1.IngressRule{
   622  						networkingv1.IngressRule{
   623  							IngressRuleValue: networkingv1.IngressRuleValue{
   624  								HTTP: &networkingv1.HTTPIngressRuleValue{
   625  									Paths: []networkingv1.HTTPIngressPath{
   626  										networkingv1.HTTPIngressPath{
   627  											Backend: networkingv1.IngressBackend{
   628  												Service: &networkingv1.IngressServiceBackend{
   629  													Name: "peermigration-service",
   630  													Port: networkingv1.ServiceBackendPort{
   631  														Number: 443,
   632  													},
   633  												},
   634  											},
   635  										},
   636  									},
   637  								},
   638  							},
   639  						},
   640  					},
   641  				},
   642  			}
   643  			ingress.Name = "peermigration"
   644  			ingress.Namespace = namespace
   645  
   646  			err = client.Create(context.TODO(), ingress)
   647  			Expect(err).NotTo(HaveOccurred())
   648  
   649  			cm := &corev1.ConfigMap{
   650  				ObjectMeta: metav1.ObjectMeta{
   651  					Name:      fmt.Sprintf("%s-fluentd-configmap", instance.Name),
   652  					Namespace: instance.Namespace,
   653  				},
   654  			}
   655  			err = client.Create(context.TODO(), cm)
   656  			Expect(err).NotTo(HaveOccurred())
   657  
   658  			secretBytes, err := ioutil.ReadFile("../../testdata/migration/secret.json")
   659  			Expect(err).NotTo(HaveOccurred())
   660  
   661  			secret := &corev1.Secret{
   662  				Data: map[string][]byte{"secret.json": secretBytes},
   663  			}
   664  			secret.Name = "peermigration-msp-secret"
   665  			secret.Namespace = namespace
   666  
   667  			err = client.Create(context.TODO(), secret)
   668  			Expect(err).NotTo(HaveOccurred())
   669  
   670  			Eventually(func() bool {
   671  				namespacedName := types.NamespacedName{
   672  					Name:      secret.Name,
   673  					Namespace: namespace,
   674  				}
   675  
   676  				secret := &corev1.Secret{}
   677  				err := client.Get(context.TODO(), namespacedName, secret)
   678  				if err != nil {
   679  					return false
   680  				}
   681  				return true
   682  			}).Should(Equal(true))
   683  
   684  			mspSecret = &initsecret.Secret{}
   685  			err = json.Unmarshal(secretBytes, mspSecret)
   686  			Expect(err).NotTo(HaveOccurred())
   687  		})
   688  
   689  		It("migrates old MSP secret to new secrets", func() {
   690  			err := migrator.Migrate()
   691  			Expect(err).NotTo(HaveOccurred())
   692  
   693  			By("creating a secret with state of current resources before migration", func() {
   694  				var secret *corev1.Secret
   695  				var err error
   696  
   697  				Eventually(func() bool {
   698  					secret, err = kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "peermigration-oldstate", metav1.GetOptions{})
   699  					if err != nil {
   700  						return false
   701  					}
   702  					return true
   703  				}).Should(Equal(true))
   704  
   705  				Expect(secret.Data["peermigration-service"]).NotTo(Equal(""))
   706  				Expect(secret.Data["peermigration-cm-fluentd"]).NotTo(Equal(""))
   707  			})
   708  
   709  			By("creating ecert ca certs secret", func() {
   710  				Eventually(func() bool {
   711  					_, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "ecert-peermigration-cacerts", metav1.GetOptions{})
   712  					if err != nil {
   713  						return false
   714  					}
   715  					return true
   716  				}).Should(Equal(true))
   717  			})
   718  
   719  			By("creating ecert keystore secret", func() {
   720  				Eventually(func() bool {
   721  					_, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "ecert-peermigration-keystore", metav1.GetOptions{})
   722  					if err != nil {
   723  						return false
   724  					}
   725  					return true
   726  				}).Should(Equal(true))
   727  			})
   728  
   729  			By("creating ecert signcert secret", func() {
   730  				Eventually(func() bool {
   731  					_, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "ecert-peermigration-signcert", metav1.GetOptions{})
   732  					if err != nil {
   733  						return false
   734  					}
   735  					return true
   736  				}).Should(Equal(true))
   737  			})
   738  
   739  			By("creating ecert admin cert secret", func() {
   740  				Eventually(func() bool {
   741  					_, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "ecert-peermigration-admincerts", metav1.GetOptions{})
   742  					if err != nil {
   743  						return false
   744  					}
   745  					return true
   746  				}).Should(Equal(true))
   747  			})
   748  
   749  			By("creating tls ca certs secret", func() {
   750  				Eventually(func() bool {
   751  					_, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "tls-peermigration-cacerts", metav1.GetOptions{})
   752  					if err != nil {
   753  						return false
   754  					}
   755  					return true
   756  				}).Should(Equal(true))
   757  			})
   758  
   759  			By("creating tls keystore certs secret", func() {
   760  				Eventually(func() bool {
   761  					_, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "tls-peermigration-keystore", metav1.GetOptions{})
   762  					if err != nil {
   763  						return false
   764  					}
   765  					return true
   766  				}).Should(Equal(true))
   767  			})
   768  
   769  			By("creating tls signcert secret", func() {
   770  				Eventually(func() bool {
   771  					_, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), "tls-peermigration-signcert", metav1.GetOptions{})
   772  					if err != nil {
   773  						return false
   774  					}
   775  					return true
   776  				}).Should(Equal(true))
   777  			})
   778  
   779  			By("creating a new service with no 'service' and same nodeport", func() {
   780  				var service *corev1.Service
   781  				var err error
   782  
   783  				Eventually(func() bool {
   784  					service, err = kclient.CoreV1().Services(namespace).Get(context.TODO(), "peermigration", metav1.GetOptions{})
   785  					if err != nil {
   786  						return false
   787  					}
   788  					return true
   789  				}).Should(Equal(true))
   790  
   791  				Expect(service.Spec.Ports[0].NodePort).To(Equal(peerApiNodePort))
   792  				Expect(service.Spec.Ports[1].NodePort).To(Equal(operationNodePort))
   793  				Expect(service.Spec.Ports[2].NodePort).To(Equal(grpcwebDebugNodePort))
   794  				Expect(service.Spec.Ports[3].NodePort).To(Equal(grpcwebNodePort))
   795  
   796  				_, err = kclient.CoreV1().Services(namespace).Get(context.TODO(), "peermigration-service", metav1.GetOptions{})
   797  				Expect(err).To(HaveOccurred())
   798  			})
   799  
   800  			By("creating a new ingress with no dashes and same servicename", func() {
   801  				var ingress *networkingv1.Ingress
   802  				var err error
   803  
   804  				Eventually(func() bool {
   805  					ingress, err = kclient.NetworkingV1().Ingresses(namespace).Get(context.TODO(), "peermigration", metav1.GetOptions{})
   806  					if err != nil {
   807  						return false
   808  					}
   809  					return true
   810  				}).Should(Equal(true))
   811  
   812  				Expect(ingress.Spec.Rules[0].HTTP.Paths[0].Backend.Service.Name).To(Equal("peermigration"))
   813  			})
   814  		})
   815  	})
   816  
   817  	Context("orderer", func() {
   818  		var (
   819  			migrator  *allmigrator.Migrator
   820  			instance  *current.IBPOrderer
   821  			mspSecret *initsecret.Secret
   822  		)
   823  
   824  		BeforeEach(func() {
   825  			logf.SetLogger(zap.New())
   826  
   827  			defaultConfigs := "../../defaultconfig"
   828  			of, err := offering.GetType("K8S")
   829  
   830  			operatorCfg := &config.Config{
   831  				CAInitConfig: &cainit.Config{
   832  					CADefaultConfigPath:    filepath.Join(defaultConfigs, "ca/ca.yaml"),
   833  					TLSCADefaultConfigPath: filepath.Join(defaultConfigs, "ca/tlsca.yaml"),
   834  					SharedPath:             "/shared",
   835  				},
   836  				PeerInitConfig: &peerinit.Config{
   837  					OUFile: filepath.Join(defaultConfigs, "peer/ouconfig.yaml"),
   838  				},
   839  				OrdererInitConfig: &ordererinit.Config{
   840  					OrdererFile:  filepath.Join(defaultConfigs, "orderer/orderer.yaml"),
   841  					ConfigTxFile: filepath.Join(defaultConfigs, "orderer/configtx.yaml"),
   842  					OUFile:       filepath.Join(defaultConfigs, "orderer/ouconfig.yaml"),
   843  				},
   844  				Offering: of,
   845  			}
   846  
   847  			mockValidator := &mocks.CryptoValidator{}
   848  			mockValidator.CheckEcertCryptoReturns(errors.New("not found"))
   849  
   850  			migrator = allmigrator.New(mgr, operatorCfg, namespace)
   851  
   852  			instance = &current.IBPOrderer{
   853  				ObjectMeta: metav1.ObjectMeta{
   854  					Name:      "orderer-migration",
   855  					Namespace: namespace,
   856  				},
   857  				Spec: current.IBPOrdererSpec{
   858  					Domain: "orderer.url",
   859  				},
   860  				Status: current.IBPOrdererStatus{
   861  					CRStatus: current.CRStatus{
   862  						Status: current.True,
   863  					},
   864  				},
   865  			}
   866  			err = client.Create(context.TODO(), instance)
   867  			Expect(err).NotTo(HaveOccurred())
   868  			err = client.UpdateStatus(context.TODO(), instance)
   869  			Expect(err).NotTo(HaveOccurred())
   870  
   871  			secretBytes, err := ioutil.ReadFile("../../testdata/migration/secret.json")
   872  			Expect(err).NotTo(HaveOccurred())
   873  
   874  			secret := &corev1.Secret{
   875  				Data: map[string][]byte{"secret.json": secretBytes},
   876  			}
   877  			secret.Name = "orderer-migration-secret"
   878  			secret.Namespace = namespace
   879  
   880  			err = client.Create(context.TODO(), secret)
   881  			Expect(err).NotTo(HaveOccurred())
   882  
   883  			Eventually(func() bool {
   884  				namespacedName := types.NamespacedName{
   885  					Name:      secret.Name,
   886  					Namespace: namespace,
   887  				}
   888  
   889  				secret := &corev1.Secret{}
   890  				err := client.Get(context.TODO(), namespacedName, secret)
   891  				if err != nil {
   892  					return false
   893  				}
   894  				return true
   895  			}).Should(Equal(true))
   896  
   897  			mspSecret = &initsecret.Secret{}
   898  			err = json.Unmarshal(secretBytes, mspSecret)
   899  			Expect(err).NotTo(HaveOccurred())
   900  
   901  			configmap := &corev1.ConfigMap{}
   902  			configmap.Name = fmt.Sprintf("%s-env-configmap", instance.GetName())
   903  			configmap.Namespace = namespace
   904  
   905  			err = client.Create(context.TODO(), configmap)
   906  			Expect(err).NotTo(HaveOccurred())
   907  
   908  			ingress := &networkingv1.Ingress{
   909  				Spec: networkingv1.IngressSpec{
   910  					Rules: []networkingv1.IngressRule{
   911  						networkingv1.IngressRule{
   912  							IngressRuleValue: networkingv1.IngressRuleValue{
   913  								HTTP: &networkingv1.HTTPIngressRuleValue{
   914  									Paths: []networkingv1.HTTPIngressPath{
   915  										networkingv1.HTTPIngressPath{
   916  											Backend: networkingv1.IngressBackend{
   917  												Service: &networkingv1.IngressServiceBackend{
   918  													Name: "camigration-service",
   919  													Port: networkingv1.ServiceBackendPort{
   920  														Number: 443,
   921  													},
   922  												},
   923  											},
   924  										},
   925  									},
   926  								},
   927  							},
   928  						},
   929  					},
   930  				},
   931  			}
   932  			ingress.Name = "orderer-migration"
   933  			ingress.Namespace = namespace
   934  
   935  			err = client.Create(context.TODO(), ingress)
   936  			Expect(err).NotTo(HaveOccurred())
   937  
   938  			n := types.NamespacedName{
   939  				Name:      ingress.GetName(),
   940  				Namespace: ingress.GetNamespace(),
   941  			}
   942  
   943  			err = wait.Poll(500*time.Millisecond, 30*time.Second, func() (bool, error) {
   944  				err := client.Get(context.TODO(), n, ingress)
   945  				if err == nil {
   946  					return true, nil
   947  				}
   948  				return false, nil
   949  			})
   950  			Expect(err).NotTo(HaveOccurred())
   951  
   952  		})
   953  
   954  		It("generates the configmap", func() {
   955  			err := migrator.Migrate()
   956  			Expect(err).NotTo(HaveOccurred())
   957  
   958  			Eventually(func() bool {
   959  				_, err := kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), "orderer-migrationnode1-config", metav1.GetOptions{})
   960  				if err != nil {
   961  					return true
   962  				}
   963  				return false
   964  			}).Should(Equal(true))
   965  		})
   966  	})
   967  })
   968  
   969  func CreateServiceWithRetry(service *corev1.Service, retryNumber int) (int32, int32) {
   970  	err := client.Create(context.TODO(), service)
   971  	if err != nil {
   972  		if retryNumber == 0 {
   973  			Expect(err).NotTo(HaveOccurred())
   974  		}
   975  		if strings.Contains(err.Error(), "provided port is already allocated") {
   976  			fmt.Fprintf(GinkgoWriter, "encountered port error: %s, trying again\n", err)
   977  			for i, _ := range service.Spec.Ports {
   978  				service.Spec.Ports[i].NodePort = RandomNodePort()
   979  			}
   980  			CreateServiceWithRetry(service, retryNumber-1)
   981  		}
   982  	}
   983  
   984  	return service.Spec.Ports[0].NodePort, service.Spec.Ports[1].NodePort
   985  }
   986  
   987  func CreatePeerServiceWithRetry(service *corev1.Service, retryNumber int) (int32, int32, int32, int32) {
   988  	err := client.Create(context.TODO(), service)
   989  	if err != nil {
   990  		if retryNumber == 0 {
   991  			Expect(err).NotTo(HaveOccurred())
   992  		}
   993  		if strings.Contains(err.Error(), "provided port is already allocated") {
   994  			fmt.Fprintf(GinkgoWriter, "encountered port error: %s, trying again\n", err)
   995  			for i, _ := range service.Spec.Ports {
   996  				service.Spec.Ports[i].NodePort = RandomNodePort()
   997  			}
   998  			CreatePeerServiceWithRetry(service, retryNumber-1)
   999  		}
  1000  	}
  1001  
  1002  	return service.Spec.Ports[0].NodePort, service.Spec.Ports[1].NodePort, service.Spec.Ports[2].NodePort, service.Spec.Ports[3].NodePort
  1003  }