github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/base/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 basepeer_test
    20  
    21  import (
    22  	"context"
    23  	"crypto/ecdsa"
    24  	"crypto/elliptic"
    25  	"crypto/rand"
    26  	"crypto/x509"
    27  	"encoding/pem"
    28  	"fmt"
    29  	"math/big"
    30  	"time"
    31  
    32  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    33  
    34  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    35  	cmocks "github.com/IBM-Blockchain/fabric-operator/controllers/mocks"
    36  	config "github.com/IBM-Blockchain/fabric-operator/operatorconfig"
    37  	commonapi "github.com/IBM-Blockchain/fabric-operator/pkg/apis/common"
    38  	"github.com/IBM-Blockchain/fabric-operator/pkg/apis/deployer"
    39  	v1 "github.com/IBM-Blockchain/fabric-operator/pkg/apis/peer/v1"
    40  	"github.com/IBM-Blockchain/fabric-operator/pkg/certificate"
    41  	commonconfig "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common/config"
    42  	"github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common/enroller"
    43  	"github.com/IBM-Blockchain/fabric-operator/pkg/initializer/common/mspparser"
    44  	peerinit "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/peer"
    45  	pconfig "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/peer/config/v1"
    46  	managermocks "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/mocks"
    47  	basepeer "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer"
    48  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer/mocks"
    49  	peermocks "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/peer/mocks"
    50  	"github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors"
    51  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    52  	"github.com/IBM-Blockchain/fabric-operator/version"
    53  	. "github.com/onsi/ginkgo/v2"
    54  	. "github.com/onsi/gomega"
    55  	"github.com/pkg/errors"
    56  	corev1 "k8s.io/api/core/v1"
    57  	k8serror "k8s.io/apimachinery/pkg/api/errors"
    58  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    59  	"k8s.io/apimachinery/pkg/runtime"
    60  	"k8s.io/apimachinery/pkg/runtime/schema"
    61  	"k8s.io/apimachinery/pkg/types"
    62  	"k8s.io/apimachinery/pkg/util/intstr"
    63  	"sigs.k8s.io/controller-runtime/pkg/client"
    64  	"sigs.k8s.io/yaml"
    65  )
    66  
    67  var _ = Describe("Base Peer", func() {
    68  	var (
    69  		peer           *basepeer.Peer
    70  		instance       *current.IBPPeer
    71  		mockKubeClient *cmocks.Client
    72  		cfg            *config.Config
    73  
    74  		deploymentMgr     *peermocks.DeploymentManager
    75  		serviceMgr        *managermocks.ResourceManager
    76  		pvcMgr            *managermocks.ResourceManager
    77  		couchPvcMgr       *managermocks.ResourceManager
    78  		configMapMgr      *managermocks.ResourceManager
    79  		roleMgr           *managermocks.ResourceManager
    80  		roleBindingMgr    *managermocks.ResourceManager
    81  		serviceAccountMgr *managermocks.ResourceManager
    82  
    83  		certificateMgr *peermocks.CertificateManager
    84  		initializer    *peermocks.InitializeIBPPeer
    85  		update         *mocks.Update
    86  	)
    87  
    88  	BeforeEach(func() {
    89  		mockKubeClient = &cmocks.Client{}
    90  		update = &mocks.Update{}
    91  
    92  		replicas := int32(1)
    93  		instance = &current.IBPPeer{
    94  			Spec: current.IBPPeerSpec{
    95  				PeerExternalEndpoint: "address",
    96  				Domain:               "domain",
    97  				HSM: &current.HSM{
    98  					PKCS11Endpoint: "tcp://0.0.0.0:2347",
    99  				},
   100  				StateDb: "couchdb",
   101  				Images: &current.PeerImages{
   102  					PeerTag: "1.4.7-20200611",
   103  				},
   104  				Replicas:      &replicas,
   105  				FabricVersion: "1.4.9",
   106  			},
   107  		}
   108  		instance.Kind = "IBPPeer"
   109  		instance.Name = "peer1"
   110  		instance.Namespace = "random"
   111  
   112  		mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
   113  			switch obj.(type) {
   114  			case *current.IBPPeer:
   115  				o := obj.(*current.IBPPeer)
   116  				o.Kind = "IBPPeer"
   117  				instance = o
   118  			case *corev1.Service:
   119  				o := obj.(*corev1.Service)
   120  				o.Spec.Type = corev1.ServiceTypeNodePort
   121  				o.Spec.Ports = append(o.Spec.Ports, corev1.ServicePort{
   122  					Name: "peer-api",
   123  					TargetPort: intstr.IntOrString{
   124  						IntVal: 7051,
   125  					},
   126  					NodePort: int32(7051),
   127  				})
   128  			case *corev1.Secret:
   129  				o := obj.(*corev1.Secret)
   130  				switch types.Name {
   131  				case "tls-" + instance.Name + "-signcert":
   132  					o.Name = "tls-" + instance.Name + "-signcert"
   133  					o.Namespace = instance.Namespace
   134  					o.Data = map[string][]byte{"cert.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   135  				case "tls-" + instance.Name + "-keystore":
   136  					o.Name = "tls-" + instance.Name + "-keystore"
   137  					o.Namespace = instance.Namespace
   138  					o.Data = map[string][]byte{"key.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   139  				case "tls-" + instance.Name + "-cacerts":
   140  					o.Name = "tls-" + instance.Name + "-cacerts"
   141  					o.Namespace = instance.Namespace
   142  					o.Data = map[string][]byte{"key.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   143  				case "ecert-" + instance.Name + "-signcert":
   144  					o.Name = "ecert-" + instance.Name + "-signcert"
   145  					o.Namespace = instance.Namespace
   146  					o.Data = map[string][]byte{"cert.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   147  				case "ecert-" + instance.Name + "-cacerts":
   148  					o.Name = "ecert-" + instance.Name + "-cacerts"
   149  					o.Namespace = instance.Namespace
   150  					o.Data = map[string][]byte{"cacert-0.pem": []byte("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo")}
   151  				}
   152  			}
   153  			return nil
   154  		}
   155  		instance.Status.Version = version.Operator
   156  
   157  		deploymentMgr = &peermocks.DeploymentManager{}
   158  		serviceMgr = &managermocks.ResourceManager{}
   159  		pvcMgr = &managermocks.ResourceManager{}
   160  		couchPvcMgr = &managermocks.ResourceManager{}
   161  		configMapMgr = &managermocks.ResourceManager{}
   162  		roleMgr = &managermocks.ResourceManager{}
   163  		roleBindingMgr = &managermocks.ResourceManager{}
   164  		serviceAccountMgr = &managermocks.ResourceManager{}
   165  
   166  		scheme := &runtime.Scheme{}
   167  		cfg = &config.Config{
   168  			PeerInitConfig: &peerinit.Config{
   169  				OUFile:       "../../../../defaultconfig/peer/ouconfig.yaml",
   170  				CorePeerFile: "../../../../defaultconfig/peer/core.yaml",
   171  			},
   172  			Operator: config.Operator{
   173  				Versions: &deployer.Versions{
   174  					Peer: map[string]deployer.VersionPeer{
   175  						"1.4.9-0": {
   176  							Default: true,
   177  							Image: deployer.PeerImages{
   178  								PeerImage:     "peerimage",
   179  								PeerTag:       "1.4.9",
   180  								PeerInitImage: "peerinitimage",
   181  								PeerInitTag:   "1.4.9",
   182  							},
   183  						},
   184  					},
   185  				},
   186  			},
   187  		}
   188  		initializer = &peermocks.InitializeIBPPeer{}
   189  		initializer.GetInitPeerReturns(&peerinit.Peer{}, nil)
   190  
   191  		certificateMgr = &peermocks.CertificateManager{}
   192  		restartMgr := &peermocks.RestartManager{}
   193  		peer = &basepeer.Peer{
   194  			Client: mockKubeClient,
   195  			Scheme: scheme,
   196  			Config: cfg,
   197  
   198  			DeploymentManager:       deploymentMgr,
   199  			ServiceManager:          serviceMgr,
   200  			PVCManager:              pvcMgr,
   201  			StateDBPVCManager:       couchPvcMgr,
   202  			FluentDConfigMapManager: configMapMgr,
   203  			RoleManager:             roleMgr,
   204  			RoleBindingManager:      roleBindingMgr,
   205  			ServiceAccountManager:   serviceAccountMgr,
   206  			Initializer:             initializer,
   207  
   208  			CertificateManager: certificateMgr,
   209  			RenewCertTimers:    make(map[string]*time.Timer),
   210  
   211  			Restart: restartMgr,
   212  		}
   213  	})
   214  
   215  	Context("pre reconcile checks", func() {
   216  		Context("version and images", func() {
   217  			Context("create CR", func() {
   218  				It("returns an error if fabric version is not set in spec", func() {
   219  					instance.Spec.FabricVersion = ""
   220  					_, err := peer.PreReconcileChecks(instance, update)
   221  					Expect(err).To(MatchError(ContainSubstring("fabric version is not set")))
   222  				})
   223  
   224  				Context("images section blank", func() {
   225  					BeforeEach(func() {
   226  						instance.Spec.Images = nil
   227  					})
   228  
   229  					It("normalizes fabric version and requests a requeue", func() {
   230  						instance.Spec.FabricVersion = "1.4.9"
   231  						requeue, err := peer.PreReconcileChecks(instance, update)
   232  						Expect(err).NotTo(HaveOccurred())
   233  						Expect(requeue).To(Equal(true))
   234  						Expect(instance.Spec.FabricVersion).To(Equal("1.4.9-0"))
   235  					})
   236  
   237  					It("returns an error if fabric version not supported", func() {
   238  						instance.Spec.FabricVersion = "0.0.1"
   239  						_, err := peer.PreReconcileChecks(instance, update)
   240  						Expect(err).To(MatchError(ContainSubstring("fabric version '0.0.1' is not supported")))
   241  					})
   242  
   243  					When("version is passed without hyphen", func() {
   244  						BeforeEach(func() {
   245  							instance.Spec.FabricVersion = "1.4.9"
   246  						})
   247  
   248  						It("finds default version for release and updates images section", func() {
   249  							requeue, err := peer.PreReconcileChecks(instance, update)
   250  							Expect(err).NotTo(HaveOccurred())
   251  							Expect(requeue).To(Equal(true))
   252  							Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   253  								PeerImage:     "peerimage",
   254  								PeerTag:       "1.4.9",
   255  								PeerInitImage: "peerinitimage",
   256  								PeerInitTag:   "1.4.9",
   257  							}))
   258  						})
   259  					})
   260  
   261  					When("version is passed with hyphen", func() {
   262  						BeforeEach(func() {
   263  							instance.Spec.FabricVersion = "1.4.9-0"
   264  						})
   265  
   266  						It("looks images and updates images section", func() {
   267  							requeue, err := peer.PreReconcileChecks(instance, update)
   268  							Expect(err).NotTo(HaveOccurred())
   269  							Expect(requeue).To(Equal(true))
   270  							Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   271  								PeerImage:     "peerimage",
   272  								PeerTag:       "1.4.9",
   273  								PeerInitImage: "peerinitimage",
   274  								PeerInitTag:   "1.4.9",
   275  							}))
   276  						})
   277  					})
   278  				})
   279  
   280  				Context("images section passed", func() {
   281  					BeforeEach(func() {
   282  						instance.Spec.Images = &current.PeerImages{
   283  							PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
   284  							PeerTag:       "2.0.0",
   285  							PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
   286  							PeerInitTag:   "2.0.0",
   287  						}
   288  					})
   289  
   290  					When("version is not passed", func() {
   291  						BeforeEach(func() {
   292  							instance.Spec.FabricVersion = ""
   293  						})
   294  
   295  						It("returns an error", func() {
   296  							_, err := peer.PreReconcileChecks(instance, update)
   297  							Expect(err).To(MatchError(ContainSubstring("fabric version is not set")))
   298  						})
   299  					})
   300  
   301  					When("version is passed", func() {
   302  						BeforeEach(func() {
   303  							instance.Spec.FabricVersion = "2.0.0-8"
   304  						})
   305  
   306  						It("persists current spec configuration", func() {
   307  							requeue, err := peer.PreReconcileChecks(instance, update)
   308  							Expect(err).NotTo(HaveOccurred())
   309  							Expect(requeue).To(Equal(false))
   310  							Expect(instance.Spec.FabricVersion).To(Equal("2.0.0-8"))
   311  							Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   312  								PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
   313  								PeerTag:       "2.0.0",
   314  								PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
   315  								PeerInitTag:   "2.0.0",
   316  							}))
   317  						})
   318  					})
   319  				})
   320  			})
   321  
   322  			Context("update CR", func() {
   323  				BeforeEach(func() {
   324  					instance.Spec.FabricVersion = "2.0.1-0"
   325  					instance.Spec.Images = &current.PeerImages{
   326  						PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
   327  						PeerTag:       "2.0.1",
   328  						PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
   329  						PeerInitTag:   "2.0.1",
   330  					}
   331  				})
   332  
   333  				When("images updated", func() {
   334  					BeforeEach(func() {
   335  						update.ImagesUpdatedReturns(true)
   336  						instance.Spec.Images = &current.PeerImages{
   337  							PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
   338  							PeerTag:       "2.0.8",
   339  							PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
   340  							PeerInitTag:   "2.0.8",
   341  						}
   342  					})
   343  
   344  					Context("and version updated", func() {
   345  						BeforeEach(func() {
   346  							update.FabricVersionUpdatedReturns(true)
   347  							instance.Spec.FabricVersion = "2.0.1-8"
   348  						})
   349  
   350  						It("persists current spec configuration", func() {
   351  							requeue, err := peer.PreReconcileChecks(instance, update)
   352  							Expect(err).NotTo(HaveOccurred())
   353  							Expect(requeue).To(Equal(false))
   354  							Expect(instance.Spec.FabricVersion).To(Equal("2.0.1-8"))
   355  							Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   356  								PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
   357  								PeerTag:       "2.0.8",
   358  								PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
   359  								PeerInitTag:   "2.0.8",
   360  							}))
   361  						})
   362  					})
   363  
   364  					Context("and version not updated", func() {
   365  						It("persists current spec configuration", func() {
   366  							requeue, err := peer.PreReconcileChecks(instance, update)
   367  							Expect(err).NotTo(HaveOccurred())
   368  							Expect(requeue).To(Equal(false))
   369  							Expect(instance.Spec.FabricVersion).To(Equal("2.0.1-0"))
   370  							Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   371  								PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
   372  								PeerTag:       "2.0.8",
   373  								PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
   374  								PeerInitTag:   "2.0.8",
   375  							}))
   376  						})
   377  					})
   378  				})
   379  
   380  				When("images not updated", func() {
   381  					Context("and version updated during operator migration", func() {
   382  						BeforeEach(func() {
   383  							update.FabricVersionUpdatedReturns(true)
   384  							instance.Spec.FabricVersion = "unsupported"
   385  						})
   386  
   387  						It("persists current spec configuration", func() {
   388  							requeue, err := peer.PreReconcileChecks(instance, update)
   389  							Expect(err).NotTo(HaveOccurred())
   390  							Expect(requeue).To(Equal(false))
   391  							Expect(instance.Spec.FabricVersion).To(Equal("unsupported"))
   392  							Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   393  								PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
   394  								PeerTag:       "2.0.1",
   395  								PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
   396  								PeerInitTag:   "2.0.1",
   397  							}))
   398  						})
   399  					})
   400  
   401  					Context("and version updated (not during operator migration)", func() {
   402  						BeforeEach(func() {
   403  							update.FabricVersionUpdatedReturns(true)
   404  						})
   405  
   406  						When("using non-hyphenated version", func() {
   407  							BeforeEach(func() {
   408  								instance.Spec.FabricVersion = "1.4.9"
   409  							})
   410  
   411  							It("looks images and updates images section", func() {
   412  								requeue, err := peer.PreReconcileChecks(instance, update)
   413  								Expect(err).NotTo(HaveOccurred())
   414  								Expect(requeue).To(Equal(true))
   415  								Expect(instance.Spec.FabricVersion).To(Equal("1.4.9-0"))
   416  								Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   417  									PeerImage:     "peerimage",
   418  									PeerTag:       "1.4.9",
   419  									PeerInitImage: "peerinitimage",
   420  									PeerInitTag:   "1.4.9",
   421  								}))
   422  							})
   423  						})
   424  
   425  						When("using hyphenated version", func() {
   426  							BeforeEach(func() {
   427  								instance.Spec.FabricVersion = "1.4.9-0"
   428  							})
   429  
   430  							It("looks images and updates images section", func() {
   431  								instance.Spec.RegistryURL = "test.cr"
   432  								requeue, err := peer.PreReconcileChecks(instance, update)
   433  								Expect(err).NotTo(HaveOccurred())
   434  								Expect(requeue).To(Equal(true))
   435  								Expect(instance.Spec.FabricVersion).To(Equal("1.4.9-0"))
   436  								Expect(*instance.Spec.Images).To(Equal(current.PeerImages{
   437  									PeerImage:     "test.cr/peerimage",
   438  									PeerTag:       "1.4.9",
   439  									PeerInitImage: "test.cr/peerinitimage",
   440  									PeerInitTag:   "1.4.9",
   441  								}))
   442  							})
   443  						})
   444  					})
   445  				})
   446  			})
   447  		})
   448  	})
   449  
   450  	Context("Reconciles", func() {
   451  		It("returns nil and requeues request if instance version updated", func() {
   452  			instance.Status.Version = ""
   453  			_, err := peer.Reconcile(instance, update)
   454  			Expect(err).NotTo(HaveOccurred())
   455  			Expect(mockKubeClient.PatchStatusCallCount()).To(Equal(1))
   456  		})
   457  		It("returns a breaking error if initialization fails", func() {
   458  			cfg.PeerInitConfig.CorePeerFile = "../../../../../defaultconfig/peer/badfile.yaml"
   459  			peer.Initializer = peerinit.New(cfg.PeerInitConfig, nil, nil, nil, nil, enroller.HSMEnrollJobTimeouts{})
   460  			_, err := peer.Reconcile(instance, update)
   461  			Expect(err).To(HaveOccurred())
   462  			Expect(err.Error()).To(ContainSubstring("Code: 22 - failed to initialize peer: open"))
   463  			Expect(operatorerrors.IsBreakingError(err, "msg", nil)).NotTo(HaveOccurred())
   464  		})
   465  
   466  		It("returns an error for invalid HSM endpoint", func() {
   467  			instance.Spec.HSM.PKCS11Endpoint = "tcp://:2347"
   468  			_, err := peer.Reconcile(instance, update)
   469  			Expect(err).To(HaveOccurred())
   470  			Expect(err.Error()).To(Equal(fmt.Sprintf("failed pre reconcile checks: invalid HSM endpoint for peer instance '%s': missing IP address", instance.Name)))
   471  		})
   472  
   473  		It("returns an error domain is not set", func() {
   474  			instance.Spec.Domain = ""
   475  			_, err := peer.Reconcile(instance, update)
   476  			Expect(err).To(HaveOccurred())
   477  			Expect(err.Error()).To(Equal(fmt.Sprintf("failed pre reconcile checks: domain not set for peer instance '%s'", instance.Name)))
   478  		})
   479  
   480  		It("returns an error if both enroll and reenroll action for ecert set to true", func() {
   481  			instance.Spec.Action.Enroll.Ecert = true
   482  			instance.Spec.Action.Reenroll.Ecert = true
   483  			_, err := peer.Reconcile(instance, update)
   484  			Expect(err).To(HaveOccurred())
   485  			Expect(err.Error()).To(Equal("failed pre reconcile checks: both enroll and renenroll action requested for ecert, must only select one"))
   486  		})
   487  
   488  		It("returns an error if both enroll and reenroll action for TLS cert set to true", func() {
   489  			instance.Spec.Action.Enroll.TLSCert = true
   490  			instance.Spec.Action.Reenroll.TLSCert = true
   491  			_, err := peer.Reconcile(instance, update)
   492  			Expect(err).To(HaveOccurred())
   493  			Expect(err.Error()).To(Equal("failed pre reconcile checks: both enroll and renenroll action requested for TLS cert, must only select one"))
   494  		})
   495  
   496  		It("returns an error if pvc manager fails to reconcile", func() {
   497  			pvcMgr.ReconcileReturns(errors.New("failed to reconcile pvc"))
   498  			_, err := peer.Reconcile(instance, update)
   499  			Expect(err).To(HaveOccurred())
   500  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed PVC reconciliation: failed to reconcile pvc"))
   501  		})
   502  
   503  		It("returns an error if couch pvc manager fails to reconcile", func() {
   504  			couchPvcMgr.ReconcileReturns(errors.New("failed to reconcile couch pvc"))
   505  			_, err := peer.Reconcile(instance, update)
   506  			Expect(err).To(HaveOccurred())
   507  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed CouchDB PVC reconciliation: failed to reconcile couch pvc"))
   508  		})
   509  
   510  		It("returns an error if service manager fails to reconcile", func() {
   511  			serviceMgr.ReconcileReturns(errors.New("failed to reconcile service"))
   512  			_, err := peer.Reconcile(instance, update)
   513  			Expect(err).To(HaveOccurred())
   514  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Service reconciliation: failed to reconcile service"))
   515  		})
   516  
   517  		It("returns an error if deployment manager fails to reconcile", func() {
   518  			deploymentMgr.ReconcileReturns(errors.New("failed to reconcile deployment"))
   519  			_, err := peer.Reconcile(instance, update)
   520  			Expect(err).To(HaveOccurred())
   521  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Deployment reconciliation: failed to reconcile deployment"))
   522  		})
   523  
   524  		It("returns an error if role manager fails to reconcile", func() {
   525  			roleMgr.ReconcileReturns(errors.New("failed to reconcile role"))
   526  			_, err := peer.Reconcile(instance, update)
   527  			Expect(err).To(HaveOccurred())
   528  			Expect(err.Error()).To(ContainSubstring("failed to reconcile role"))
   529  		})
   530  
   531  		It("returns an error if role binding manager fails to reconcile", func() {
   532  			roleBindingMgr.ReconcileReturns(errors.New("failed to reconcile role binding"))
   533  			_, err := peer.Reconcile(instance, update)
   534  			Expect(err).To(HaveOccurred())
   535  			Expect(err.Error()).To(ContainSubstring("failed to reconcile role binding"))
   536  		})
   537  
   538  		It("returns an error if service account binding manager fails to reconcile", func() {
   539  			serviceAccountMgr.ReconcileReturns(errors.New("failed to reconcile service account"))
   540  			_, err := peer.Reconcile(instance, update)
   541  			Expect(err).To(HaveOccurred())
   542  			Expect(err.Error()).To(ContainSubstring("failed to reconcile service account"))
   543  		})
   544  
   545  		It("returns an error if config map manager fails to reconcile", func() {
   546  			configMapMgr.ReconcileReturns(errors.New("failed to reconcile config map"))
   547  			_, err := peer.Reconcile(instance, update)
   548  			Expect(err).To(HaveOccurred())
   549  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed FluentD ConfigMap reconciliation: failed to reconcile config map"))
   550  		})
   551  
   552  		It("does not return an error on a successful reconcile", func() {
   553  			_, err := peer.Reconcile(instance, update)
   554  			Expect(err).NotTo(HaveOccurred())
   555  		})
   556  	})
   557  
   558  	Context("secret", func() {
   559  		It("does not try to create secret if the get request returns an error other than 'not found'", func() {
   560  			errMsg := "connection refused"
   561  			mockKubeClient.GetReturns(errors.New(errMsg))
   562  			err := peer.ReconcileSecret(instance)
   563  			Expect(err).To(HaveOccurred())
   564  			Expect(err.Error()).To(Equal(errMsg))
   565  		})
   566  
   567  		When("secret does not exist", func() {
   568  			BeforeEach(func() {
   569  				notFoundErr := &k8serror.StatusError{
   570  					ErrStatus: metav1.Status{
   571  						Reason: metav1.StatusReasonNotFound,
   572  					},
   573  				}
   574  				mockKubeClient.GetReturns(notFoundErr)
   575  			})
   576  
   577  			It("returns an error if the creation of the Secret fails", func() {
   578  				errMsg := "unable to create secret"
   579  				mockKubeClient.CreateReturns(errors.New(errMsg))
   580  				err := peer.ReconcileSecret(instance)
   581  				Expect(err).To(HaveOccurred())
   582  				Expect(err.Error()).To(Equal(errMsg))
   583  			})
   584  
   585  			It("does not return an error on a successfull secret creation", func() {
   586  				err := peer.ReconcileSecret(instance)
   587  				Expect(err).NotTo(HaveOccurred())
   588  			})
   589  		})
   590  	})
   591  
   592  	Context("check csr hosts", func() {
   593  		It("adds csr hosts if not present", func() {
   594  			instance = &current.IBPPeer{
   595  				Spec: current.IBPPeerSpec{
   596  					Secret: &current.SecretSpec{
   597  						Enrollment: &current.EnrollmentSpec{},
   598  					},
   599  				},
   600  			}
   601  			hosts := []string{"test.com", "127.0.0.1"}
   602  			peer.CheckCSRHosts(instance, hosts)
   603  			Expect(instance.Spec.Secret.Enrollment.TLS).NotTo(BeNil())
   604  			Expect(instance.Spec.Secret.Enrollment.TLS.CSR).NotTo(BeNil())
   605  			Expect(instance.Spec.Secret.Enrollment.TLS.CSR.Hosts).To(Equal(hosts))
   606  		})
   607  
   608  		It("appends csr hosts if passed", func() {
   609  			hostsCustom := []string{"custom.domain.com"}
   610  			hosts := []string{"test.com", "127.0.0.1"}
   611  			instance = &current.IBPPeer{
   612  				Spec: current.IBPPeerSpec{
   613  					Secret: &current.SecretSpec{
   614  						Enrollment: &current.EnrollmentSpec{
   615  							TLS: &current.Enrollment{
   616  								CSR: &current.CSR{
   617  									Hosts: hostsCustom,
   618  								},
   619  							},
   620  						},
   621  					},
   622  				},
   623  			}
   624  			peer.CheckCSRHosts(instance, hosts)
   625  			Expect(instance.Spec.Secret.Enrollment.TLS).NotTo(BeNil())
   626  			Expect(instance.Spec.Secret.Enrollment.TLS.CSR).NotTo(BeNil())
   627  			Expect(instance.Spec.Secret.Enrollment.TLS.CSR.Hosts).To(ContainElement(hostsCustom[0]))
   628  			Expect(instance.Spec.Secret.Enrollment.TLS.CSR.Hosts).To(ContainElement(hosts[0]))
   629  			Expect(instance.Spec.Secret.Enrollment.TLS.CSR.Hosts).To(ContainElement(hosts[1]))
   630  		})
   631  	})
   632  	Context("check certificates", func() {
   633  		It("returns error if fails to get certificate expiry info", func() {
   634  			certificateMgr.CheckCertificatesForExpireReturns("", "", errors.New("cert expiry error"))
   635  			_, err := peer.CheckCertificates(instance)
   636  			Expect(err).To(HaveOccurred())
   637  		})
   638  
   639  		It("sets cr status with certificate expiry info", func() {
   640  			certificateMgr.CheckCertificatesForExpireReturns(current.Warning, "message", nil)
   641  			status, err := peer.CheckCertificates(instance)
   642  			Expect(err).NotTo(HaveOccurred())
   643  			Expect(status.Type).To(Equal(current.Warning))
   644  			Expect(status.Message).To(Equal("message"))
   645  			Expect(status.Reason).To(Equal("certRenewalRequired"))
   646  		})
   647  	})
   648  
   649  	Context("set certificate timer", func() {
   650  		BeforeEach(func() {
   651  			instance.Spec.Secret = &current.SecretSpec{
   652  				Enrollment: &current.EnrollmentSpec{
   653  					TLS: &current.Enrollment{
   654  						EnrollID: "enrollID",
   655  					},
   656  				},
   657  			}
   658  			mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
   659  				switch obj.(type) {
   660  				case *current.IBPPeer:
   661  					o := obj.(*current.IBPPeer)
   662  					o.Kind = "IBPPeer"
   663  					o.Name = "peer1"
   664  					o.Namespace = "random"
   665  					o.Spec.Secret = &current.SecretSpec{
   666  						Enrollment: &current.EnrollmentSpec{
   667  							TLS: &current.Enrollment{
   668  								EnrollID: "enrollID",
   669  							},
   670  						},
   671  					}
   672  				case *corev1.Secret:
   673  					o := obj.(*corev1.Secret)
   674  					switch types.Name {
   675  					case "tls-" + instance.Name + "-signcert":
   676  						o.Name = "tls-" + instance.Name + "-signcert"
   677  						o.Namespace = instance.Namespace
   678  						o.Data = map[string][]byte{"cert.pem": generateCertPemBytes(29)}
   679  					case "tls-" + instance.Name + "-keystore":
   680  						o.Name = "tls-" + instance.Name + "-keystore"
   681  						o.Namespace = instance.Namespace
   682  						o.Data = map[string][]byte{"key.pem": []byte("")}
   683  					case instance.Name + "-crypto-backup":
   684  						return k8serrors.NewNotFound(schema.GroupResource{}, "not found")
   685  					}
   686  				}
   687  				return nil
   688  			}
   689  		})
   690  
   691  		It("returns error if unable to get duration to next renewal", func() {
   692  			certificateMgr.GetDurationToNextRenewalReturns(time.Duration(0), errors.New("failed to get duration"))
   693  			err := peer.SetCertificateTimer(instance, "tls")
   694  			Expect(err).To(HaveOccurred())
   695  			Expect(err.Error()).To(Equal("failed to get duration"))
   696  		})
   697  
   698  		Context("sets timer to renew TLS certificate", func() {
   699  			BeforeEach(func() {
   700  				certificateMgr.GetDurationToNextRenewalReturns(time.Duration(3*time.Second), nil)
   701  				mockKubeClient.UpdateStatusReturns(nil)
   702  				certificateMgr.RenewCertReturns(nil)
   703  			})
   704  
   705  			It("does not return error, but certificate fails to renew after timer", func() {
   706  				certificateMgr.RenewCertReturns(errors.New("failed to renew cert"))
   707  				err := peer.SetCertificateTimer(instance, "tls")
   708  				Expect(err).NotTo(HaveOccurred())
   709  				Expect(peer.RenewCertTimers["tls-peer1-signcert"]).NotTo(BeNil())
   710  
   711  				By("certificate fails to be renewed", func() {
   712  					Eventually(func() bool {
   713  						return mockKubeClient.UpdateStatusCallCount() == 1 &&
   714  							certificateMgr.RenewCertCallCount() == 1
   715  					}, time.Duration(5*time.Second)).Should(Equal(true))
   716  				})
   717  
   718  				// timer.Stop() == false means that it already fired
   719  				Expect(peer.RenewCertTimers["tls-peer1-signcert"].Stop()).To(Equal(false))
   720  			})
   721  
   722  			It("does not return error, and certificate is successfully renewed after timer", func() {
   723  				err := peer.SetCertificateTimer(instance, "tls")
   724  				Expect(err).NotTo(HaveOccurred())
   725  				Expect(peer.RenewCertTimers["tls-peer1-signcert"]).NotTo(BeNil())
   726  
   727  				By("certificate successfully renewed", func() {
   728  					Eventually(func() bool {
   729  						return mockKubeClient.UpdateStatusCallCount() == 1 &&
   730  							certificateMgr.RenewCertCallCount() == 1
   731  					}, time.Duration(5*time.Second)).Should(Equal(true))
   732  				})
   733  
   734  				// timer.Stop() == false means that it already fired
   735  				Expect(peer.RenewCertTimers["tls-peer1-signcert"].Stop()).To(Equal(false))
   736  			})
   737  
   738  			It("does not return error, and timer is set to renew certificate at a later time", func() {
   739  				// Set expiration date of certificate to be > 30 days from now
   740  				certificateMgr.GetDurationToNextRenewalReturns(time.Duration(35*24*time.Hour), nil)
   741  
   742  				err := peer.SetCertificateTimer(instance, "tls")
   743  				Expect(err).NotTo(HaveOccurred())
   744  				Expect(peer.RenewCertTimers["tls-peer1-signcert"]).NotTo(BeNil())
   745  
   746  				// timer.Stop() == true means that it has not fired but is now stopped
   747  				Expect(peer.RenewCertTimers["tls-peer1-signcert"].Stop()).To(Equal(true))
   748  			})
   749  		})
   750  
   751  		Context("read certificate expiration date to set timer correctly", func() {
   752  			BeforeEach(func() {
   753  				peer.CertificateManager = &certificate.CertificateManager{
   754  					Client: mockKubeClient,
   755  					Scheme: &runtime.Scheme{},
   756  				}
   757  
   758  				// set to 30 days
   759  				instance.Spec.NumSecondsWarningPeriod = 30 * basepeer.DaysToSecondsConversion
   760  			})
   761  
   762  			It("doesn't return error if timer is set correctly, but error in renewing certificate when timer goes off", func() {
   763  				// Set tls signcert expiration date to be 29 days from now, cert is renewed if expires within 30 days
   764  				mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
   765  					switch obj.(type) {
   766  					case *current.IBPPeer:
   767  						o := obj.(*current.IBPPeer)
   768  						o.Kind = "IBPPeer"
   769  						instance = o
   770  
   771  					case *corev1.Secret:
   772  						o := obj.(*corev1.Secret)
   773  						switch types.Name {
   774  						case "tls-" + instance.Name + "-signcert":
   775  							o.Name = "tls-" + instance.Name + "-signcert"
   776  							o.Namespace = instance.Namespace
   777  							o.Data = map[string][]byte{"cert.pem": generateCertPemBytes(29)}
   778  						case "tls-" + instance.Name + "-keystore":
   779  							o.Name = "tls-" + instance.Name + "-keystore"
   780  							o.Namespace = instance.Namespace
   781  							o.Data = map[string][]byte{"key.pem": []byte("")}
   782  						case instance.Name + "-crypto-backup":
   783  							return k8serrors.NewNotFound(schema.GroupResource{}, "not found")
   784  						}
   785  					}
   786  					return nil
   787  				}
   788  
   789  				err := peer.SetCertificateTimer(instance, "tls")
   790  				Expect(err).NotTo(HaveOccurred())
   791  				Expect(peer.RenewCertTimers["tls-peer1-signcert"]).NotTo(BeNil())
   792  
   793  				// Wait for timer to go off
   794  				time.Sleep(5 * time.Second)
   795  
   796  				// timer.Stop() == false means that it already fired
   797  				Expect(peer.RenewCertTimers["tls-peer1-signcert"].Stop()).To(Equal(false))
   798  			})
   799  
   800  			It("doesn't return error if timer is set correctly, timer doesn't go off certificate isn't ready for renewal", func() {
   801  				// Set tls signcert expiration date to be 50 days from now, cert is renewed if expires within 30 days
   802  				mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
   803  					switch obj.(type) {
   804  					case *current.IBPPeer:
   805  						o := obj.(*current.IBPPeer)
   806  						o.Kind = "IBPPeer"
   807  						instance = o
   808  
   809  					case *corev1.Secret:
   810  						o := obj.(*corev1.Secret)
   811  						switch types.Name {
   812  						case "tls-" + instance.Name + "-signcert":
   813  							o.Name = "tls-" + instance.Name + "-signcert"
   814  							o.Namespace = instance.Namespace
   815  							o.Data = map[string][]byte{"cert.pem": generateCertPemBytes(50)}
   816  						case "tls-" + instance.Name + "-keystore":
   817  							o.Name = "tls-" + instance.Name + "-keystore"
   818  							o.Namespace = instance.Namespace
   819  							o.Data = map[string][]byte{"key.pem": []byte("")}
   820  						case instance.Name + "-crypto-backup":
   821  							return k8serrors.NewNotFound(schema.GroupResource{}, "not found")
   822  						}
   823  					}
   824  					return nil
   825  				}
   826  
   827  				err := peer.SetCertificateTimer(instance, "tls")
   828  				Expect(err).NotTo(HaveOccurred())
   829  
   830  				// Timer shouldn't go off
   831  				time.Sleep(5 * time.Second)
   832  
   833  				Expect(peer.RenewCertTimers["tls-peer1-signcert"]).NotTo(BeNil())
   834  				// timer.Stop() == true means that it has not fired but is now stopped
   835  				Expect(peer.RenewCertTimers["tls-peer1-signcert"].Stop()).To(Equal(true))
   836  			})
   837  		})
   838  	})
   839  
   840  	Context("renew cert", func() {
   841  		BeforeEach(func() {
   842  			instance.Spec.Secret = &current.SecretSpec{
   843  				Enrollment: &current.EnrollmentSpec{
   844  					TLS: &current.Enrollment{},
   845  				},
   846  			}
   847  
   848  			certificateMgr.RenewCertReturns(nil)
   849  		})
   850  
   851  		It("returns error if secret spec is missing", func() {
   852  			instance.Spec.Secret = nil
   853  			err := peer.RenewCert("tls", instance, true)
   854  			Expect(err).To(HaveOccurred())
   855  			Expect(err.Error()).To(Equal("missing secret spec for instance 'peer1'"))
   856  		})
   857  
   858  		It("returns error if certificate generated by MSP", func() {
   859  			instance.Spec.Secret = &current.SecretSpec{
   860  				MSP: &current.MSPSpec{},
   861  			}
   862  			err := peer.RenewCert("tls", instance, true)
   863  			Expect(err).To(HaveOccurred())
   864  			Expect(err.Error()).To(Equal("cannot auto-renew certificate created by MSP, force renewal required"))
   865  		})
   866  
   867  		It("returns error if certificate manager fails to renew certificate", func() {
   868  			certificateMgr.RenewCertReturns(errors.New("failed to renew cert"))
   869  			err := peer.RenewCert("tls", instance, true)
   870  			Expect(err).To(HaveOccurred())
   871  			Expect(err.Error()).To(Equal("failed to renew cert"))
   872  		})
   873  
   874  		It("does not return error if certificate manager successfully renews cert", func() {
   875  			err := peer.RenewCert("tls", instance, true)
   876  			Expect(err).NotTo(HaveOccurred())
   877  		})
   878  	})
   879  
   880  	Context("set cr status", func() {
   881  		It("returns error if fails to get current instance", func() {
   882  			mockKubeClient.GetReturns(errors.New("get error"))
   883  			err := peer.UpdateCRStatus(instance)
   884  			Expect(err).To(HaveOccurred())
   885  			Expect(err.Error()).To(Equal("failed to get new instance: get error"))
   886  		})
   887  
   888  		It("returns error if fails to update instance status", func() {
   889  			mockKubeClient.UpdateStatusReturns(errors.New("update status error"))
   890  			certificateMgr.CheckCertificatesForExpireReturns(current.Warning, "cert renewal required", nil)
   891  			err := peer.UpdateCRStatus(instance)
   892  			Expect(err).To(HaveOccurred())
   893  			Expect(err.Error()).To(Equal("failed to update status to Warning phase: update status error"))
   894  		})
   895  
   896  		It("sets instance CR status to Warning", func() {
   897  			certificateMgr.CheckCertificatesForExpireReturns(current.Warning, "message", nil)
   898  			err := peer.UpdateCRStatus(instance)
   899  			Expect(err).NotTo(HaveOccurred())
   900  			Expect(instance.Status.Type).To(Equal(current.Warning))
   901  			Expect(instance.Status.Reason).To(Equal("certRenewalRequired"))
   902  			Expect(instance.Status.Message).To(Equal("message"))
   903  		})
   904  	})
   905  
   906  	Context("fabric peer migration", func() {
   907  		BeforeEach(func() {
   908  			overrides := &pconfig.Core{
   909  				Core: v1.Core{
   910  					Peer: v1.Peer{
   911  						BCCSP: &commonapi.BCCSP{
   912  							ProviderName: "pkcs11",
   913  							PKCS11: &commonapi.PKCS11Opts{
   914  								FileKeyStore: &commonapi.FileKeyStoreOpts{
   915  									KeyStorePath: "msp/keystore",
   916  								},
   917  							},
   918  						},
   919  					},
   920  				},
   921  			}
   922  			jmRaw, err := util.ConvertToJsonMessage(overrides)
   923  			Expect(err).NotTo(HaveOccurred())
   924  
   925  			instance.Spec.ConfigOverride = &runtime.RawExtension{Raw: *jmRaw}
   926  
   927  			coreBytes, err := yaml.Marshal(overrides)
   928  			Expect(err).NotTo(HaveOccurred())
   929  
   930  			cm := &corev1.ConfigMap{
   931  				BinaryData: map[string][]byte{
   932  					"core.yaml": coreBytes,
   933  				},
   934  			}
   935  
   936  			mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
   937  				switch obj.(type) {
   938  				case *corev1.ConfigMap:
   939  					o := obj.(*corev1.ConfigMap)
   940  					o.Name = "core-config"
   941  					o.BinaryData = cm.BinaryData
   942  				}
   943  				return nil
   944  			}
   945  		})
   946  
   947  		It("removes keystore path value", func() {
   948  			peerConfig, err := peer.FabricPeerMigrationV1_4(instance)
   949  			Expect(err).NotTo(HaveOccurred())
   950  			Expect(peerConfig.Peer.BCCSP.PKCS11.FileKeyStore).To(BeNil())
   951  		})
   952  
   953  		When("fabric peer tag is less than 1.4.7", func() {
   954  			BeforeEach(func() {
   955  				instance.Spec.Images.PeerTag = "1.4.6-20200611"
   956  			})
   957  
   958  			It("returns without updating config", func() {
   959  				peerConfig, err := peer.FabricPeerMigrationV1_4(instance)
   960  				Expect(err).NotTo(HaveOccurred())
   961  				Expect(peerConfig).To(BeNil())
   962  			})
   963  		})
   964  
   965  		When("hsm is not enabled", func() {
   966  			BeforeEach(func() {
   967  				overrides := &pconfig.Core{
   968  					Core: v1.Core{
   969  						Peer: v1.Peer{
   970  							BCCSP: &commonapi.BCCSP{
   971  								ProviderName: "sw",
   972  								SW: &commonapi.SwOpts{
   973  									FileKeyStore: commonapi.FileKeyStoreOpts{
   974  										KeyStorePath: "msp/keystore",
   975  									},
   976  								},
   977  							},
   978  						},
   979  					},
   980  				}
   981  				jmRaw, err := util.ConvertToJsonMessage(overrides)
   982  				Expect(err).NotTo(HaveOccurred())
   983  
   984  				instance.Spec.ConfigOverride = &runtime.RawExtension{Raw: *jmRaw}
   985  			})
   986  
   987  			It("returns without updating config", func() {
   988  				peerConfig, err := peer.FabricPeerMigrationV1_4(instance)
   989  				Expect(err).NotTo(HaveOccurred())
   990  				Expect(peerConfig).To(BeNil())
   991  			})
   992  		})
   993  	})
   994  
   995  	Context("images override", func() {
   996  		var images *current.PeerImages
   997  
   998  		Context("using registry url", func() {
   999  			BeforeEach(func() {
  1000  				images = &current.PeerImages{
  1001  					PeerInitImage: "peerinitimage",
  1002  					PeerInitTag:   "2.0.0",
  1003  					PeerImage:     "peerimage",
  1004  					PeerTag:       "2.0.0",
  1005  					DindImage:     "dindimage",
  1006  					DindTag:       "2.0.0",
  1007  					CouchDBImage:  "couchimage",
  1008  					CouchDBTag:    "2.0.0",
  1009  					GRPCWebImage:  "grpcimage",
  1010  					GRPCWebTag:    "2.0.0",
  1011  					FluentdImage:  "fluentdimage",
  1012  					FluentdTag:    "2.0.0",
  1013  				}
  1014  			})
  1015  
  1016  			It("overrides images based with registry url and does not append more value on each call", func() {
  1017  				images.Override(images, "ghcr.io/ibm-blockchain/", "amd64")
  1018  				Expect(images.PeerInitImage).To(Equal("ghcr.io/ibm-blockchain/peerinitimage"))
  1019  				Expect(images.PeerInitTag).To(Equal("2.0.0"))
  1020  				Expect(images.PeerImage).To(Equal("ghcr.io/ibm-blockchain/peerimage"))
  1021  				Expect(images.PeerTag).To(Equal("2.0.0"))
  1022  				Expect(images.DindImage).To(Equal("ghcr.io/ibm-blockchain/dindimage"))
  1023  				Expect(images.DindTag).To(Equal("2.0.0"))
  1024  				Expect(images.CouchDBImage).To(Equal("ghcr.io/ibm-blockchain/couchimage"))
  1025  				Expect(images.CouchDBTag).To(Equal("2.0.0"))
  1026  				Expect(images.GRPCWebImage).To(Equal("ghcr.io/ibm-blockchain/grpcimage"))
  1027  				Expect(images.GRPCWebTag).To(Equal("2.0.0"))
  1028  				Expect(images.FluentdImage).To(Equal("ghcr.io/ibm-blockchain/fluentdimage"))
  1029  				Expect(images.FluentdTag).To(Equal("2.0.0"))
  1030  			})
  1031  
  1032  			It("overrides images based with registry url and does not append more value on each call", func() {
  1033  				images.Override(images, "ghcr.io/ibm-blockchain/images/", "s390")
  1034  				Expect(images.PeerInitImage).To(Equal("ghcr.io/ibm-blockchain/images/peerinitimage"))
  1035  				Expect(images.PeerInitTag).To(Equal("2.0.0"))
  1036  				Expect(images.PeerImage).To(Equal("ghcr.io/ibm-blockchain/images/peerimage"))
  1037  				Expect(images.PeerTag).To(Equal("2.0.0"))
  1038  				Expect(images.DindImage).To(Equal("ghcr.io/ibm-blockchain/images/dindimage"))
  1039  				Expect(images.DindTag).To(Equal("2.0.0"))
  1040  				Expect(images.CouchDBImage).To(Equal("ghcr.io/ibm-blockchain/images/couchimage"))
  1041  				Expect(images.CouchDBTag).To(Equal("2.0.0"))
  1042  				Expect(images.GRPCWebImage).To(Equal("ghcr.io/ibm-blockchain/images/grpcimage"))
  1043  				Expect(images.GRPCWebTag).To(Equal("2.0.0"))
  1044  				Expect(images.FluentdImage).To(Equal("ghcr.io/ibm-blockchain/images/fluentdimage"))
  1045  				Expect(images.FluentdTag).To(Equal("2.0.0"))
  1046  			})
  1047  		})
  1048  
  1049  		Context("using fully qualified path", func() {
  1050  			BeforeEach(func() {
  1051  				images = &current.PeerImages{
  1052  					PeerInitImage: "ghcr.io/ibm-blockchain/peerinitimage",
  1053  					PeerInitTag:   "2.0.0",
  1054  					PeerImage:     "ghcr.io/ibm-blockchain/peerimage",
  1055  					PeerTag:       "2.0.0",
  1056  					DindImage:     "ghcr.io/ibm-blockchain/dindimage",
  1057  					DindTag:       "2.0.0",
  1058  					CouchDBImage:  "ghcr.io/ibm-blockchain/couchimage",
  1059  					CouchDBTag:    "2.0.0",
  1060  					GRPCWebImage:  "ghcr.io/ibm-blockchain/grpcimage",
  1061  					GRPCWebTag:    "2.0.0",
  1062  					FluentdImage:  "ghcr.io/ibm-blockchain/fluentdimage",
  1063  					FluentdTag:    "2.0.0",
  1064  				}
  1065  			})
  1066  
  1067  			It("keeps images and adds arch to tag", func() {
  1068  				images.Override(images, "", "amd64")
  1069  				Expect(images.PeerInitImage).To(Equal("ghcr.io/ibm-blockchain/peerinitimage"))
  1070  				Expect(images.PeerInitTag).To(Equal("2.0.0"))
  1071  				Expect(images.PeerImage).To(Equal("ghcr.io/ibm-blockchain/peerimage"))
  1072  				Expect(images.PeerTag).To(Equal("2.0.0"))
  1073  				Expect(images.DindImage).To(Equal("ghcr.io/ibm-blockchain/dindimage"))
  1074  				Expect(images.DindTag).To(Equal("2.0.0"))
  1075  				Expect(images.CouchDBImage).To(Equal("ghcr.io/ibm-blockchain/couchimage"))
  1076  				Expect(images.CouchDBTag).To(Equal("2.0.0"))
  1077  				Expect(images.GRPCWebImage).To(Equal("ghcr.io/ibm-blockchain/grpcimage"))
  1078  				Expect(images.GRPCWebTag).To(Equal("2.0.0"))
  1079  				Expect(images.FluentdImage).To(Equal("ghcr.io/ibm-blockchain/fluentdimage"))
  1080  				Expect(images.FluentdTag).To(Equal("2.0.0"))
  1081  			})
  1082  		})
  1083  	})
  1084  
  1085  	Context("update connection profile", func() {
  1086  		It("returns error if fails to get cert", func() {
  1087  			mockKubeClient.GetReturns(errors.New("get error"))
  1088  			err := peer.UpdateConnectionProfile(instance)
  1089  			Expect(err).To(HaveOccurred())
  1090  			Expect(err.Error()).To(ContainSubstring("get error"))
  1091  		})
  1092  
  1093  		It("updates connection profile cm", func() {
  1094  			err := peer.UpdateConnectionProfile(instance)
  1095  			Expect(err).NotTo(HaveOccurred())
  1096  			Expect(mockKubeClient.GetCallCount()).To(Equal(7))
  1097  		})
  1098  	})
  1099  
  1100  	Context("update msp certificates", func() {
  1101  		const testcert = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNpVENDQWkrZ0F3SUJBZ0lVRkd3N0RjK0QvZUoyY08wOHd6d2tialIzK1M4d0NnWUlLb1pJemowRUF3SXcKYURFTE1Ba0dBMVVFQmhNQ1ZWTXhGekFWQmdOVkJBZ1REazV2Y25Sb0lFTmhjbTlzYVc1aE1SUXdFZ1lEVlFRSwpFd3RJZVhCbGNteGxaR2RsY2pFUE1BMEdBMVVFQ3hNR1JtRmljbWxqTVJrd0Z3WURWUVFERXhCbVlXSnlhV010ClkyRXRjMlZ5ZG1WeU1CNFhEVEU1TVRBd09URTBNakF3TUZvWERUSXdNVEF3T0RFME1qQXdNRm93YnpFTE1Ba0cKQTFVRUJoTUNWVk14RnpBVkJnTlZCQWdURGs1dmNuUm9JRU5oY205c2FXNWhNUlF3RWdZRFZRUUtFd3RJZVhCbApjbXhsWkdkbGNqRVBNQTBHQTFVRUN4TUdSbUZpY21sak1TQXdIZ1lEVlFRREV4ZFRZV0ZrY3kxTllXTkNiMjlyCkxWQnlieTVzYjJOaGJEQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJBK0JBRzhZakJvTllabGgKRjFrVHNUbHd6VERDQTJocDhZTXI5Ky8vbEd0NURoSGZVT1c3bkhuSW1USHlPRjJQVjFPcVRuUWhUbWpLYTdaQwpqeU9BUWxLamdhOHdnYXd3RGdZRFZSMFBBUUgvQkFRREFnT29NQjBHQTFVZEpRUVdNQlFHQ0NzR0FRVUZCd01CCkJnZ3JCZ0VGQlFjREFqQU1CZ05WSFJNQkFmOEVBakFBTUIwR0ExVWREZ1FXQkJTbHJjL0lNQkxvMzR0UktvWnEKNTQreDIyYWEyREFmQmdOVkhTTUVHREFXZ0JSWmpxT3RQZWJzSFI2UjBNQUhrNnd4ei85UFZqQXRCZ05WSFJFRQpKakFrZ2hkVFlXRmtjeTFOWVdOQ2IyOXJMVkJ5Ynk1c2IyTmhiSUlKYkc5allXeG9iM04wTUFvR0NDcUdTTTQ5CkJBTUNBMGdBTUVVQ0lRRGR0Y1QwUE9FQXJZKzgwdEhmWUwvcXBiWWoxMGU2eWlPWlpUQ29wY25mUVFJZ1FNQUQKaFc3T0NSUERNd3lqKzNhb015d2hFenFHYy9jRDJSU2V5ekRiRjFFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
  1102  
  1103  		BeforeEach(func() {
  1104  			msp := &current.MSP{
  1105  				SignCerts: testcert,
  1106  				CACerts:   []string{testcert},
  1107  				KeyStore:  "keystore",
  1108  			}
  1109  
  1110  			initializer.GetUpdatedPeerReturns(&peerinit.Peer{
  1111  				Cryptos: &commonconfig.Cryptos{
  1112  					TLS: &mspparser.MSPParser{
  1113  						Config: msp,
  1114  					},
  1115  				},
  1116  			}, nil)
  1117  
  1118  		})
  1119  
  1120  		It("returns error if fails to get update msp parsers", func() {
  1121  			initializer.GetUpdatedPeerReturns(nil, errors.New("get error"))
  1122  			err := peer.UpdateMSPCertificates(instance)
  1123  			Expect(err).To(HaveOccurred())
  1124  			Expect(err.Error()).To(ContainSubstring("get error"))
  1125  		})
  1126  
  1127  		It("returns error if fails to generate crypto", func() {
  1128  			initializer.GetUpdatedPeerReturns(&peerinit.Peer{
  1129  				Cryptos: &commonconfig.Cryptos{
  1130  					TLS: &mspparser.MSPParser{
  1131  						Config: &current.MSP{
  1132  							SignCerts: "invalid",
  1133  						},
  1134  					},
  1135  				},
  1136  			}, nil)
  1137  			err := peer.UpdateMSPCertificates(instance)
  1138  			Expect(err).To(HaveOccurred())
  1139  		})
  1140  
  1141  		It("returns error if fails to update secrets", func() {
  1142  			initializer.UpdateSecretsFromResponseReturns(errors.New("update error"))
  1143  			err := peer.UpdateMSPCertificates(instance)
  1144  			Expect(err).To(HaveOccurred())
  1145  			Expect(err.Error()).To(Equal("update error"))
  1146  		})
  1147  
  1148  		It("updates secrets of certificates passed through MSP spec", func() {
  1149  			err := peer.UpdateMSPCertificates(instance)
  1150  			Expect(err).NotTo(HaveOccurred())
  1151  			Expect(initializer.UpdateSecretsFromResponseCallCount()).To(Equal(1))
  1152  		})
  1153  	})
  1154  
  1155  	Context("enroll for ecert", func() {
  1156  		It("returns error if no enrollment information provided", func() {
  1157  			err := peer.EnrollForEcert(instance)
  1158  			Expect(err).To(HaveOccurred())
  1159  			Expect(err).To(MatchError(ContainSubstring("unable to enroll, no ecert enrollment information provided")))
  1160  		})
  1161  
  1162  		It("returns error if enrollment with ca fails", func() {
  1163  			instance.Spec.Secret = &current.SecretSpec{
  1164  				Enrollment: &current.EnrollmentSpec{
  1165  					Component: &current.Enrollment{},
  1166  				},
  1167  			}
  1168  			err := peer.EnrollForEcert(instance)
  1169  			Expect(err).To(HaveOccurred())
  1170  			Expect(err).To(MatchError(ContainSubstring("failed to enroll for ecert")))
  1171  		})
  1172  	})
  1173  
  1174  	Context("enroll for TLS cert", func() {
  1175  		It("returns error if no enrollment information provided", func() {
  1176  			err := peer.EnrollForTLSCert(instance)
  1177  			Expect(err).To(HaveOccurred())
  1178  			Expect(err).To(MatchError(ContainSubstring("unable to enroll, no TLS enrollment information provided")))
  1179  		})
  1180  
  1181  		It("returns error if enrollment with ca fails", func() {
  1182  			instance.Spec.Secret = &current.SecretSpec{
  1183  				Enrollment: &current.EnrollmentSpec{
  1184  					TLS: &current.Enrollment{},
  1185  				},
  1186  			}
  1187  			err := peer.EnrollForTLSCert(instance)
  1188  			Expect(err).To(HaveOccurred())
  1189  			Expect(err).To(MatchError(ContainSubstring("failed to enroll for TLS cert")))
  1190  		})
  1191  	})
  1192  })
  1193  
  1194  func generateCertPemBytes(daysUntilExpired int) []byte {
  1195  	certtemplate := x509.Certificate{
  1196  		SerialNumber: big.NewInt(1),
  1197  		NotBefore:    time.Now(),
  1198  		NotAfter:     time.Now().Add(time.Duration(daysUntilExpired) * time.Hour * 24),
  1199  	}
  1200  
  1201  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  1202  	Expect(err).NotTo(HaveOccurred())
  1203  
  1204  	cert, err := x509.CreateCertificate(rand.Reader, &certtemplate, &certtemplate, &priv.PublicKey, priv)
  1205  	Expect(err).NotTo(HaveOccurred())
  1206  
  1207  	block := &pem.Block{
  1208  		Type:  "CERTIFICATE",
  1209  		Bytes: cert,
  1210  	}
  1211  
  1212  	return pem.EncodeToMemory(block)
  1213  }