github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/offering/openshift/ca/ca_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 openshiftca_test
    20  
    21  import (
    22  	"encoding/json"
    23  	"path/filepath"
    24  
    25  	. "github.com/onsi/ginkgo/v2"
    26  	. "github.com/onsi/gomega"
    27  	"k8s.io/apimachinery/pkg/types"
    28  	"sigs.k8s.io/controller-runtime/pkg/client"
    29  
    30  	"context"
    31  
    32  	corev1 "k8s.io/api/core/v1"
    33  
    34  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    35  	"github.com/IBM-Blockchain/fabric-operator/controllers/mocks"
    36  	config "github.com/IBM-Blockchain/fabric-operator/operatorconfig"
    37  	v1 "github.com/IBM-Blockchain/fabric-operator/pkg/apis/ca/v1"
    38  	"github.com/IBM-Blockchain/fabric-operator/pkg/apis/deployer"
    39  	initializer "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/ca"
    40  	managermocks "github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/mocks"
    41  	baseca "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/ca"
    42  	basecamocks "github.com/IBM-Blockchain/fabric-operator/pkg/offering/base/ca/mocks"
    43  	openshiftca "github.com/IBM-Blockchain/fabric-operator/pkg/offering/openshift/ca"
    44  	"github.com/IBM-Blockchain/fabric-operator/pkg/offering/openshift/ca/override"
    45  	"github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors"
    46  	"github.com/IBM-Blockchain/fabric-operator/version"
    47  	"github.com/pkg/errors"
    48  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    49  	"k8s.io/apimachinery/pkg/runtime"
    50  )
    51  
    52  var _ = Describe("Openshift CA", func() {
    53  	const (
    54  		defaultConfigs = "../../../../defaultconfig/ca"
    55  		testdataDir    = "../../../../testdata"
    56  
    57  		testCert = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNwVENDQWtxZ0F3SUJBZ0lSQU1FeVZVcDRMdlYydEFUREhlWklldDh3Q2dZSUtvWkl6ajBFQXdJd2daVXgKQ3pBSkJnTlZCQVlUQWxWVE1SY3dGUVlEVlFRSUV3NU9iM0owYUNCRFlYSnZiR2x1WVRFUE1BMEdBMVVFQnhNRwpSSFZ5YUdGdE1Rd3dDZ1lEVlFRS0V3TkpRazB4RXpBUkJnTlZCQXNUQ2tKc2IyTnJZMmhoYVc0eE9UQTNCZ05WCkJBTVRNR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzFqWVM1aGNIQnpMbkIxYldGekxtOXpMbVo1Y21VdWFXSnQKTG1OdmJUQWVGdzB5TURBeE1qSXhPREExTURCYUZ3MHpNREF4TVRreE9EQTFNREJhTUlHVk1Rc3dDUVlEVlFRRwpFd0pWVXpFWE1CVUdBMVVFQ0JNT1RtOXlkR2dnUTJGeWIyeHBibUV4RHpBTkJnTlZCQWNUQmtSMWNtaGhiVEVNCk1Bb0dBMVVFQ2hNRFNVSk5NUk13RVFZRFZRUUxFd3BDYkc5amEyTm9ZV2x1TVRrd053WURWUVFERXpCcVlXNHkKTWkxdmNtUmxjbVZ5YjNKblkyRXRZMkV1WVhCd2N5NXdkVzFoY3k1dmN5NW1lWEpsTG1saWJTNWpiMjB3V1RBVApCZ2NxaGtqT1BRSUJCZ2dxaGtqT1BRTUJCd05DQUFTR0lHUFkvZC9tQVhMejM4SlROR3F5bldpOTJXUVB6cnN0Cm5vdEFWZlh0dHZ5QWJXdTRNbWNUMEh6UnBTWjNDcGdxYUNXcTg1MUwyV09LcnZ6L0JPREpvM2t3ZHpCMUJnTlYKSFJFRWJqQnNnakJxWVc0eU1pMXZjbVJsY21WeWIzSm5ZMkV0WTJFdVlYQndjeTV3ZFcxaGN5NXZjeTVtZVhKbApMbWxpYlM1amIyMkNPR3BoYmpJeUxXOXlaR1Z5WlhKdmNtZGpZUzF2Y0dWeVlYUnBiMjV6TG1Gd2NITXVjSFZ0CllYTXViM011Wm5seVpTNXBZbTB1WTI5dE1Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQ0lRQzM3Y1pkNFY2RThPQ1IKaDloQXEyK0dyR21FVTFQU0I1eHo5RkdEWThkODZRSWhBT1crM3Urb2d4bFNWNUoyR3ZYbHRaQmpXRkpvYnJxeApwVVQ4cW4yMDA1b0wKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo"
    58  	)
    59  
    60  	var (
    61  		ca             *openshiftca.CA
    62  		instance       *current.IBPCA
    63  		mockKubeClient *mocks.Client
    64  
    65  		deploymentMgr          *managermocks.ResourceManager
    66  		serviceMgr             *managermocks.ResourceManager
    67  		pvcMgr                 *managermocks.ResourceManager
    68  		roleMgr                *managermocks.ResourceManager
    69  		roleBindingMgr         *managermocks.ResourceManager
    70  		serviceAccountMgr      *managermocks.ResourceManager
    71  		caRouteManager         *managermocks.ResourceManager
    72  		operationsRouteManager *managermocks.ResourceManager
    73  
    74  		initMock *basecamocks.InitializeIBPCA
    75  		update   *basecamocks.Update
    76  		certMgr  *basecamocks.CertificateManager
    77  	)
    78  
    79  	Context("Reconciles", func() {
    80  		BeforeEach(func() {
    81  			mockKubeClient = &mocks.Client{}
    82  			update = &basecamocks.Update{}
    83  
    84  			replicas := int32(1)
    85  			instance = &current.IBPCA{
    86  				TypeMeta: metav1.TypeMeta{
    87  					Kind: "IBPCA",
    88  				},
    89  				ObjectMeta: metav1.ObjectMeta{
    90  					Name:      "ca1",
    91  					Namespace: "test",
    92  				},
    93  				Spec: current.IBPCASpec{
    94  					Domain:        "domain",
    95  					Images:        &current.CAImages{},
    96  					Replicas:      &replicas,
    97  					FabricVersion: "1.4.9-0",
    98  				},
    99  				Status: current.IBPCAStatus{
   100  					CRStatus: current.CRStatus{
   101  						Version: version.Operator,
   102  					},
   103  				},
   104  			}
   105  
   106  			mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error {
   107  				switch obj.(type) {
   108  				case *corev1.Secret:
   109  					o := obj.(*corev1.Secret)
   110  					switch types.Name {
   111  					case instance.Name + "-ca-crypto":
   112  						o.Name = instance.Name + "-ca-crypto"
   113  						o.Namespace = instance.Namespace
   114  						o.Data = map[string][]byte{"tls-cert.pem": []byte(testCert)}
   115  					case instance.Name + "-tlsca-crypto":
   116  						o.Name = instance.Name + "-tlsca-crypto"
   117  						o.Namespace = instance.Namespace
   118  						o.Data = map[string][]byte{"cert.pem": []byte(testCert)}
   119  					}
   120  				}
   121  				return nil
   122  			}
   123  			deploymentMgr = &managermocks.ResourceManager{}
   124  			serviceMgr = &managermocks.ResourceManager{}
   125  			pvcMgr = &managermocks.ResourceManager{}
   126  			roleMgr = &managermocks.ResourceManager{}
   127  			roleBindingMgr = &managermocks.ResourceManager{}
   128  			serviceAccountMgr = &managermocks.ResourceManager{}
   129  			caRouteManager = &managermocks.ResourceManager{}
   130  			operationsRouteManager = &managermocks.ResourceManager{}
   131  			initMock = &basecamocks.InitializeIBPCA{}
   132  			restartMgr := &basecamocks.RestartManager{}
   133  			certMgr = &basecamocks.CertificateManager{}
   134  
   135  			cfg := &config.Config{
   136  				CAInitConfig: &initializer.Config{
   137  					CADefaultConfigPath:     filepath.Join(defaultConfigs, "/ca.yaml"),
   138  					CAOverrideConfigPath:    filepath.Join(testdataDir, "init/override.yaml"),
   139  					TLSCADefaultConfigPath:  filepath.Join(defaultConfigs, "tlsca.yaml"),
   140  					TLSCAOverrideConfigPath: filepath.Join(testdataDir, "init/override.yaml"),
   141  					SharedPath:              "shared",
   142  				},
   143  				Operator: config.Operator{
   144  					Versions: &deployer.Versions{
   145  						CA: map[string]deployer.VersionCA{
   146  							"1.4.9-0": {},
   147  						},
   148  					},
   149  				},
   150  			}
   151  
   152  			certMgr.GetSecretReturns(&corev1.Secret{}, nil)
   153  			deploymentMgr.ExistsReturns(true)
   154  			ca = &openshiftca.CA{
   155  				CA: &baseca.CA{
   156  					Client:                mockKubeClient,
   157  					Scheme:                &runtime.Scheme{},
   158  					DeploymentManager:     deploymentMgr,
   159  					ServiceManager:        serviceMgr,
   160  					PVCManager:            pvcMgr,
   161  					RoleManager:           roleMgr,
   162  					RoleBindingManager:    roleBindingMgr,
   163  					ServiceAccountManager: serviceAccountMgr,
   164  					Override:              &override.Override{},
   165  					Config:                cfg,
   166  					Initializer:           initMock,
   167  					Restart:               restartMgr,
   168  					CertificateManager:    certMgr,
   169  				},
   170  				CARouteManager:         caRouteManager,
   171  				OperationsRouteManager: operationsRouteManager,
   172  				Override:               &override.Override{},
   173  			}
   174  		})
   175  
   176  		It("returns a breaking error if initialization fails", func() {
   177  			initMock.HandleEnrollmentCAInitReturns(nil, errors.New("failed to init"))
   178  			_, err := ca.Reconcile(instance, update)
   179  			Expect(err).To(HaveOccurred())
   180  			Expect(err.Error()).To(ContainSubstring("Code: 20 - failed to initialize ca: failed to init"))
   181  			Expect(operatorerrors.IsBreakingError(err, "msg", nil)).NotTo(HaveOccurred())
   182  		})
   183  
   184  		It("returns an error if pvc manager fails to reconcile", func() {
   185  			pvcMgr.ReconcileReturns(errors.New("failed to reconcile pvc"))
   186  			_, err := ca.Reconcile(instance, update)
   187  			Expect(err).To(HaveOccurred())
   188  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed PVC reconciliation: failed to reconcile pvc"))
   189  		})
   190  
   191  		It("returns an error if service manager fails to reconcile", func() {
   192  			serviceMgr.ReconcileReturns(errors.New("failed to reconcile service"))
   193  			_, err := ca.Reconcile(instance, update)
   194  			Expect(err).To(HaveOccurred())
   195  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Service reconciliation: failed to reconcile service"))
   196  		})
   197  
   198  		It("returns an error if role manager fails to reconcile", func() {
   199  			roleMgr.ReconcileReturns(errors.New("failed to reconcile role"))
   200  			_, err := ca.Reconcile(instance, update)
   201  			Expect(err).To(HaveOccurred())
   202  			Expect(err.Error()).To(ContainSubstring("failed to reconcile role"))
   203  		})
   204  
   205  		It("returns an error if role binding manager fails to reconcile", func() {
   206  			roleBindingMgr.ReconcileReturns(errors.New("failed to reconcile role binding"))
   207  			_, err := ca.Reconcile(instance, update)
   208  			Expect(err).To(HaveOccurred())
   209  			Expect(err.Error()).To(ContainSubstring("failed to reconcile role binding"))
   210  		})
   211  
   212  		It("returns an error if service account manager fails to reconcile", func() {
   213  			serviceAccountMgr.ReconcileReturns(errors.New("failed to reconcile service account"))
   214  			_, err := ca.Reconcile(instance, update)
   215  			Expect(err).To(HaveOccurred())
   216  			Expect(err.Error()).To(ContainSubstring("failed to reconcile service account"))
   217  		})
   218  
   219  		It("returns an error if deployment manager fails to reconcile", func() {
   220  			deploymentMgr.ReconcileReturns(errors.New("failed to reconcile deployment"))
   221  			_, err := ca.Reconcile(instance, update)
   222  			Expect(err).To(HaveOccurred())
   223  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Deployment reconciliation: failed to reconcile deployment"))
   224  		})
   225  
   226  		It("returns an error if ca route manager fails to reconcile", func() {
   227  			caRouteManager.ReconcileReturns(errors.New("failed to reconcile ca route"))
   228  			_, err := ca.Reconcile(instance, update)
   229  			Expect(err).To(HaveOccurred())
   230  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed CA Route reconciliation: failed to reconcile ca route"))
   231  		})
   232  
   233  		It("returns an error if operations route manager fails to reconcile", func() {
   234  			operationsRouteManager.ReconcileReturns(errors.New("failed to reconcile operations route"))
   235  			_, err := ca.Reconcile(instance, update)
   236  			Expect(err).To(HaveOccurred())
   237  			Expect(err.Error()).To(Equal("failed to reconcile managers: failed Operations Route reconciliation: failed to reconcile operations route"))
   238  		})
   239  
   240  		It("returns an error if restart fails", func() {
   241  			update.RestartNeededReturns(true)
   242  			mockKubeClient.PatchReturns(errors.New("patch failed"))
   243  			_, err := ca.Reconcile(instance, update)
   244  			Expect(err).Should(MatchError(ContainSubstring("patch failed")))
   245  		})
   246  
   247  		It("reconciles IBPCA", func() {
   248  			_, err := ca.Reconcile(instance, update)
   249  			Expect(err).NotTo(HaveOccurred())
   250  		})
   251  	})
   252  
   253  	Context("AddTLSCryptoIfMissing", func() {
   254  		It("adds tls crypto", func() {
   255  			mockKubeClient.GetReturns(errors.New("fake error"))
   256  			err := ca.AddTLSCryptoIfMissing(instance, &current.CAEndpoints{})
   257  			Expect(err).NotTo(HaveOccurred())
   258  
   259  			caOverrides := &v1.ServerConfig{}
   260  			err = json.Unmarshal(instance.Spec.ConfigOverride.CA.Raw, caOverrides)
   261  			Expect(err).NotTo(HaveOccurred())
   262  
   263  			Expect(caOverrides.TLS.CertFile).NotTo(Equal(""))
   264  			Expect(caOverrides.TLS.KeyFile).NotTo(Equal(""))
   265  		})
   266  	})
   267  })