github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/openshift/peer/peer_test.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package openshiftpeer_test
    20  
    21  import (
    22  	"context"
    23  
    24  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    25  	cmocks "github.com/IBM-Blockchain/fabric-operator/controllers/mocks"
    26  	config "github.com/IBM-Blockchain/fabric-operator/operatorconfig"
    27  	"github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common/enroller"
    28  	peerinit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/peer"
    29  	managermocks "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/mocks"
    30  	basepeer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer"
    31  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer/mocks"
    32  	peermocks "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer/mocks"
    33  	openshiftpeer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/openshift/peer"
    34  	"github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors"
    35  	"github.com/IBM-Blockchain/fabric-operator/version"
    36  	. "github.com/onsi/ginkgo/v2"
    37  	. "github.com/onsi/gomega"
    38  	"github.com/pkg/errors"
    39  	corev1 "k8s.io/api/core/v1"
    40  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    41  	"k8s.io/apimachinery/pkg/runtime"
    42  	"k8s.io/apimachinery/pkg/types"
    43  	"sigs.k8s.io/controller-runtime/pkg/client"
    44  )
    45  
    46  var _ = Describe("Openshift Peer", func() {
    47  	var (
    48  		peer           *openshiftpeer.Peer
    49  		instance       *current.IBPPeer
    50  		mockKubeClient *cmocks.Client
    51  		cfg            *config.Config
    52  
    53  		deploymentMgr          *peermocks.DeploymentManager
    54  		peerRouteManager       *managermocks.ResourceManager
    55  		operationsRouteManager *managermocks.ResourceManager
    56  		grpcRouteManager       *managermocks.ResourceManager
    57  		update                 *mocks.Update
    58  	)
    59  
    60  	Context("Reconciles", func() {
    61  		BeforeEach(func() {
    62  			mockKubeClient = &cmocks.Client{}
    63  			update = &mocks.Update{}
    64  
    65  			replicas := int32(1)
    66  			instance = &current.IBPPeer{
    67  				TypeMeta: metav1.TypeMeta{
    68  					Kind: "IBPPeer",
    69  				},
    70  				ObjectMeta: metav1.ObjectMeta{
    71  					Name:      "peer1",
    72  					Namespace: "random",
    73  				},
    74  				Spec: current.IBPPeerSpec{
    75  					PeerExternalEndpoint: "address",
    76  					Domain:               "domain",
    77  					DindArgs:             []string{"fake", "args"},
    78  					StateDb:              "couchdb",
    79  					Replicas:             &replicas,
    80  					Images:               &current.PeerImages{},
    81  					FabricVersion:        "1.4.9",
    82  				},
    83  				Status: current.IBPPeerStatus{
    84  					CRStatus: current.CRStatus{
    85  						Version: version.Operator,
    86  					},
    87  				},
    88  			}
    89  
    90  			mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
    91  				switch obj.(type) {
    92  				case *corev1.Secret:
    93  					o := obj.(*corev1.Secret)
    94  					switch types.Name {
    95  					case "tls-" + instance.Name + "-signcert":
    96  						o.Name = "tls-" + instance.Name + "-signcert"
    97  						o.Namespace = instance.Namespace
    98  						o.Data = map[string][]byte{"cert.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
    99  					case "tls-" + instance.Name + "-cacerts":
   100  						o.Name = "tls-" + instance.Name + "-cacerts"
   101  						o.Namespace = instance.Namespace
   102  						o.Data = map[string][]byte{"cert.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   103  					case "ecert-" + instance.Name + "-signcert":
   104  						o.Name = "ecert-" + instance.Name + "-signcert"
   105  						o.Namespace = instance.Namespace
   106  						o.Data = map[string][]byte{"cert.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   107  					case "ecert-" + instance.Name + "-cacerts":
   108  						o.Name = "ecert-" + instance.Name + "-cacerts"
   109  						o.Namespace = instance.Namespace
   110  						o.Data = map[string][]byte{"cacert-0.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   111  					}
   112  				}
   113  				return nil
   114  			}
   115  
   116  			deploymentMgr = &peermocks.DeploymentManager{}
   117  			serviceMgr := &managermocks.ResourceManager{}
   118  			pvcMgr := &managermocks.ResourceManager{}
   119  			couchPvcMgr := &managermocks.ResourceManager{}
   120  			configMapMgr := &managermocks.ResourceManager{}
   121  			roleMgr := &managermocks.ResourceManager{}
   122  			roleBindingMgr := &managermocks.ResourceManager{}
   123  			serviceAccountMgr := &managermocks.ResourceManager{}
   124  			certificateMgr := &peermocks.CertificateManager{}
   125  			restartMgr := &peermocks.RestartManager{}
   126  
   127  			peerRouteManager = &managermocks.ResourceManager{}
   128  			operationsRouteManager = &managermocks.ResourceManager{}
   129  			grpcRouteManager = &managermocks.ResourceManager{}
   130  
   131  			scheme := &runtime.Scheme{}
   132  			cfg = &config.Config{
   133  				PeerInitConfig: &peerinit.Config{
   134  					OUFile:       "../../../../defaultconfig/peer/ouconfig.yaml",
   135  					CorePeerFile: "../../../../defaultconfig/peer/core.yaml",
   136  				},
   137  			}
   138  			initializer := &peermocks.InitializeIBPPeer{}
   139  			initializer.GetInitPeerReturns(&peerinit.Peer{}, nil)
   140  			peer = &openshiftpeer.Peer{
   141  				Peer: &basepeer.Peer{
   142  					Config:                  cfg,
   143  					Client:                  mockKubeClient,
   144  					Scheme:                  scheme,
   145  					DeploymentManager:       deploymentMgr,
   146  					ServiceManager:          serviceMgr,
   147  					PVCManager:              pvcMgr,
   148  					StateDBPVCManager:       couchPvcMgr,
   149  					FluentDConfigMapManager: configMapMgr,
   150  					RoleManager:             roleMgr,
   151  					RoleBindingManager:      roleBindingMgr,
   152  					ServiceAccountManager:   serviceAccountMgr,
   153  					Initializer:             initializer,
   154  					CertificateManager:      certificateMgr,
   155  					Restart:                 restartMgr,
   156  				},
   157  				RouteManager:           peerRouteManager,
   158  				OperationsRouteManager: operationsRouteManager,
   159  				GRPCRouteManager:       grpcRouteManager,
   160  			}
   161  		})
   162  
   163  		It("returns an error if peer route manager fails to reconcile", func() {
   164  			peerRouteManager.ReconcileReturns(errors.New("failed to reconcile peer route"))
   165  			_, err := peer.Reconcile(instance, update)
   166  			Expect(err).To(HaveOccurred())
   167  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Peer Route reconciliation: failed to reconcile peer route"))
   168  		})
   169  
   170  		It("returns an error if operations route manager fails to reconcile", func() {
   171  			operationsRouteManager.ReconcileReturns(errors.New("failed to reconcile operations route"))
   172  			_, err := peer.Reconcile(instance, update)
   173  			Expect(err).To(HaveOccurred())
   174  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Operations Route reconciliation: failed to reconcile operations route"))
   175  		})
   176  
   177  		It("returns an error if grpc web route manager fails to reconcile", func() {
   178  			grpcRouteManager.ReconcileReturns(errors.New("failed to reconcile grpc web route"))
   179  			_, err := peer.Reconcile(instance, update)
   180  			Expect(err).To(HaveOccurred())
   181  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Peer GRPC Route reconciliation: failed to reconcile grpc web route"))
   182  		})
   183  
   184  		// Disabling this test because the function uses rest client which cannot be mocked
   185  		// It("adds dind args in CR if not passed", func() {
   186  		// 	mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
   187  		// 		switch obj.(type) {
   188  		// 		case *openshiftv1.ClusterVersion:
   189  		// 			cv := &openshiftv1.ClusterVersion{
   190  		// 				Spec: openshiftv1.ClusterVersionSpec{
   191  		// 					Channel: "stable-4.2",
   192  		// 				},
   193  		// 			}
   194  
   195  		// 			obj = cv.DeepCopy()
   196  		// 		}
   197  
   198  		// 		return nil
   199  
   200  		// 	}
   201  		// 	_, err := peer.SelectDinDArgs(instance)
   202  		// 	Expect(err).NotTo(HaveOccurred())
   203  
   204  		// 	Expect(len(instance.Spec.DindArgs)).NotTo(Equal(0))
   205  		// })
   206  
   207  		It("returns a breaking error if initialization fails", func() {
   208  			cfg.PeerInitConfig.CorePeerFile = "../../../../defaultconfig/peer/badfile.yaml"
   209  			peer.Initializer = peerinit.New(cfg.PeerInitConfig, nil, nil, nil, nil, enroller.HSMEnrollJobTimeouts{})
   210  			_, err := peer.Reconcile(instance, update)
   211  			Expect(err).To(HaveOccurred())
   212  			Expect(err.Error()).To(ContainSubstring("Code: 22 - failed to initialize peer: open"))
   213  			Expect(operatorerrors.IsBreakingError(err, "msg", nil)).NotTo(HaveOccurred())
   214  		})
   215  
   216  		It("reconciles openshift peer", func() {
   217  			_, err := peer.Reconcile(instance, update)
   218  			Expect(err).NotTo(HaveOccurred())
   219  		})
   220  	})
   221  })