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

     1  //go:build !pkcs11
     2  // +build !pkcs11
     3  
     4  /*
     5   * Copyright contributors to the Hyperledger Fabric Operator project
     6   *
     7   * SPDX-License-Identifier: Apache-2.0
     8   *
     9   * Licensed under the Apache License, Version 2.0 (the "License");
    10   * you may not use this file except in compliance with the License.
    11   * You may obtain a copy of the License at:
    12   *
    13   * 	  http://www.apache.org/licenses/LICENSE-2.0
    14   *
    15   * Unless required by applicable law or agreed to in writing, software
    16   * distributed under the License is distributed on an "AS IS" BASIS,
    17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    18   * See the License for the specific language governing permissions and
    19   * limitations under the License.
    20   */
    21  
    22  package ca_test
    23  
    24  import (
    25  	"context"
    26  	"encoding/json"
    27  	"fmt"
    28  	"time"
    29  
    30  	current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1"
    31  	"github.com/IBM-Blockchain/fabric-operator/integration"
    32  	"github.com/IBM-Blockchain/fabric-operator/integration/helper"
    33  	v1 "github.com/IBM-Blockchain/fabric-operator/pkg/apis/ca/v1"
    34  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    35  	"github.com/IBM-Blockchain/fabric-operator/pkg/util/pointer"
    36  	. "github.com/onsi/ginkgo/v2"
    37  	. "github.com/onsi/gomega"
    38  	appsv1 "k8s.io/api/apps/v1"
    39  	corev1 "k8s.io/api/core/v1"
    40  	"k8s.io/apimachinery/pkg/api/resource"
    41  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    42  	"k8s.io/apimachinery/pkg/runtime"
    43  	"k8s.io/apimachinery/pkg/types"
    44  	"k8s.io/apimachinery/pkg/util/wait"
    45  	"sigs.k8s.io/yaml"
    46  )
    47  
    48  var _ = Describe("Interaction between IBP-Operator and Kubernetes cluster", func() {
    49  	var (
    50  		err error
    51  		ca  *CA
    52  		ca2 *CA
    53  		ca3 *CA
    54  	)
    55  
    56  	BeforeEach(func() {
    57  		ca = GetCA1()
    58  		err = helper.CreateCA(ibpCRClient, ca.CR)
    59  		Expect(err).NotTo(HaveOccurred())
    60  
    61  		ca2 = GetCA2()
    62  		err = helper.CreateCA(ibpCRClient, ca2.CR)
    63  		Expect(err).NotTo(HaveOccurred())
    64  
    65  		ca3 = GetCA3()
    66  		err = helper.CreateCA(ibpCRClient, ca3.CR)
    67  		Expect(err).NotTo(HaveOccurred())
    68  
    69  		integration.ClearOperatorConfig(kclient, namespace)
    70  	})
    71  
    72  	AfterEach(func() {
    73  		// Set flag if a test falls
    74  		if CurrentGinkgoTestDescription().Failed {
    75  			testFailed = true
    76  		}
    77  	})
    78  
    79  	Context("IBPCA controller", func() {
    80  		Context("applying the first instance of IBPCA CR", func() {
    81  			var (
    82  				err error
    83  				dep *appsv1.Deployment
    84  			)
    85  
    86  			It("creates a IBPCA custom resource", func() {
    87  				By("setting the CR status to deploying", func() {
    88  					Eventually(ca.PollForCRStatus).Should((Equal(current.Deploying)))
    89  				})
    90  
    91  				By("creating a service", func() {
    92  					Eventually(ca.ServiceExists).Should((Equal(true)))
    93  				})
    94  
    95  				By("creating a configmap", func() {
    96  					Eventually(ca.ConfigMapExists).Should((Equal(true)))
    97  				})
    98  
    99  				By("starting a ingress", func() {
   100  					Eventually(ca.IngressExists).Should((Equal(true)))
   101  				})
   102  
   103  				By("creating a deployment", func() {
   104  					Eventually(ca.DeploymentExists).Should((Equal(true)))
   105  				})
   106  
   107  				By("starting a pod", func() {
   108  					Eventually(ca.PodIsRunning).Should((Equal(true)))
   109  				})
   110  
   111  				By("creating config map that contains spec", func() {
   112  					Eventually(func() bool {
   113  						_, err := kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), ca.Name+"-spec", metav1.GetOptions{})
   114  						if err != nil {
   115  							return false
   116  						}
   117  						return true
   118  					}).Should(Equal(true))
   119  				})
   120  
   121  				By("creating secret with crypto for CA", func() {
   122  					secret, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), ca.Name+"-ca-crypto", metav1.GetOptions{})
   123  					Expect(err).NotTo(HaveOccurred())
   124  					Expect(secret).NotTo(BeNil())
   125  					Expect(len(secret.Data)).To(Equal(6))
   126  				})
   127  
   128  				By("creating secret with crypto for TLS CA", func() {
   129  					secret, err := kclient.CoreV1().Secrets(namespace).Get(context.TODO(), ca.Name+"-tlsca-crypto", metav1.GetOptions{})
   130  					Expect(err).NotTo(HaveOccurred())
   131  					Expect(secret).NotTo(BeNil())
   132  					Expect(len(secret.Data)).To(Equal(2))
   133  				})
   134  
   135  				By("setting the CR status to deployed when pod is running", func() {
   136  					Eventually(ca.PollForCRStatus).Should((Equal(current.Deployed)))
   137  				})
   138  			})
   139  
   140  			It("should not find zone and region", func() {
   141  				// Wait for new deployment before querying deployment for updates
   142  				err = wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
   143  					dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   144  					if dep != nil {
   145  						if dep.Status.UpdatedReplicas == 1 && dep.Status.Conditions[0].Type == appsv1.DeploymentAvailable {
   146  							return true, nil
   147  						}
   148  					}
   149  					return false, nil
   150  				})
   151  				Expect(err).NotTo(HaveOccurred())
   152  				dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   153  				Expect(err).NotTo(HaveOccurred())
   154  
   155  				// TODO :: only run these when using MZ clusters
   156  				// By("checking zone", func() {
   157  				// 	Expect(ca.TestAffinityZone(dep)).To((Equal(false)))
   158  				// })
   159  
   160  				// By("checking region", func() {
   161  				// 	Expect(ca.TestAffinityRegion(dep)).To((Equal(false)))
   162  				// })
   163  			})
   164  
   165  			When("the custom resource is updated", func() {
   166  				var (
   167  					err                 error
   168  					dep                 *appsv1.Deployment
   169  					newResourceRequests corev1.ResourceList
   170  					newResourceLimits   corev1.ResourceList
   171  				)
   172  
   173  				BeforeEach(func() {
   174  					newResourceRequests = map[corev1.ResourceName]resource.Quantity{
   175  						corev1.ResourceCPU:    resource.MustParse("55m"),
   176  						corev1.ResourceMemory: resource.MustParse("110M"),
   177  					}
   178  					newResourceLimits = map[corev1.ResourceName]resource.Quantity{
   179  						corev1.ResourceCPU:    resource.MustParse("55m"),
   180  						corev1.ResourceMemory: resource.MustParse("110M"),
   181  					}
   182  					ca.expectedRequests = newResourceRequests
   183  					ca.expectedLimits = newResourceLimits
   184  
   185  					Eventually(ca.DeploymentExists).Should((Equal(true)))
   186  					dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   187  					Expect(err).NotTo(HaveOccurred())
   188  
   189  				})
   190  
   191  				It("updates the instance of IBPCA if resources are updated in CR", func() {
   192  					currentResources := dep.Spec.Template.Spec.Containers[0].Resources
   193  					Expect(currentResources.Requests).To(Equal(defaultRequests))
   194  					Expect(currentResources.Limits).To(Equal(defaultLimits))
   195  
   196  					ca.CR.Spec.Resources = &current.CAResources{
   197  						CA: &corev1.ResourceRequirements{
   198  							Requests: newResourceRequests,
   199  							Limits:   newResourceLimits,
   200  						},
   201  					}
   202  
   203  					caOverrides := &v1.ServerConfig{}
   204  					err := json.Unmarshal(ca.CR.Spec.ConfigOverride.CA.Raw, caOverrides)
   205  					Expect(err).NotTo(HaveOccurred())
   206  					caOverrides.CAConfig.CA = v1.CAInfo{
   207  						Name: "new-ca",
   208  					}
   209  
   210  					caJson, err := util.ConvertToJsonMessage(caOverrides)
   211  					Expect(err).NotTo(HaveOccurred())
   212  					ca.CR.Spec.ConfigOverride.CA = &runtime.RawExtension{Raw: *caJson}
   213  
   214  					tlscaOverrides := &v1.ServerConfig{}
   215  					err = json.Unmarshal(ca.CR.Spec.ConfigOverride.TLSCA.Raw, tlscaOverrides)
   216  					Expect(err).NotTo(HaveOccurred())
   217  					tlscaOverrides.CAConfig.CA = v1.CAInfo{
   218  						Name: "new-tlsca",
   219  					}
   220  
   221  					tlscaJson, err := util.ConvertToJsonMessage(tlscaOverrides)
   222  					Expect(err).NotTo(HaveOccurred())
   223  					ca.CR.Spec.ConfigOverride.TLSCA = &runtime.RawExtension{Raw: *tlscaJson}
   224  
   225  					bytes, err := json.Marshal(ca.CR)
   226  					Expect(err).NotTo(HaveOccurred())
   227  
   228  					result := ibpCRClient.Patch(types.MergePatchType).Namespace(namespace).Resource("ibpcas").Name(ca.Name).Body(bytes).Do(context.TODO())
   229  					Expect(result.Error()).NotTo(HaveOccurred())
   230  
   231  					// Wait for new deployment before querying deployment for updates
   232  					err = wait.Poll(500*time.Millisecond, 120*time.Second, func() (bool, error) {
   233  						dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   234  						if dep != nil {
   235  							if dep.Status.UpdatedReplicas == 1 && dep.Status.Conditions[0].Type == appsv1.DeploymentAvailable {
   236  								if dep.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().MilliValue() == newResourceRequests.Cpu().MilliValue() {
   237  									return true, nil
   238  								}
   239  							}
   240  						}
   241  						return false, nil
   242  					})
   243  					Expect(err).NotTo(HaveOccurred())
   244  
   245  					Eventually(ca.resourcesRequestsUpdated).Should(Equal(true))
   246  					Eventually(ca.resourcesLimitsUpdated).Should(Equal(true))
   247  
   248  					By("updating the config map with new values from override for ecert and tls ca", func() {
   249  						cm, err := kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), fmt.Sprintf("%s-ca-config", ca.Name), metav1.GetOptions{})
   250  						Expect(err).NotTo(HaveOccurred())
   251  
   252  						serverconfig := &v1.ServerConfig{}
   253  						err = yaml.Unmarshal(cm.BinaryData["fabric-ca-server-config.yaml"], serverconfig)
   254  						Expect(err).NotTo(HaveOccurred())
   255  
   256  						Expect(serverconfig.CAConfig.CA.Name).To(Equal("new-ca"))
   257  
   258  						cm, err = kclient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), fmt.Sprintf("%s-tlsca-config", ca.Name), metav1.GetOptions{})
   259  						Expect(err).NotTo(HaveOccurred())
   260  
   261  						serverconfig = &v1.ServerConfig{}
   262  						err = yaml.Unmarshal(cm.BinaryData["fabric-ca-server-config.yaml"], serverconfig)
   263  						Expect(err).NotTo(HaveOccurred())
   264  
   265  						Expect(serverconfig.CAConfig.CA.Name).To(Equal("new-tlsca"))
   266  
   267  						By("restarting deployment for ecert ca", func() {
   268  							// Pod should first go away, and deployment is restarted
   269  							// Eventually(ca.PodIsRunning).Should((Equal(false))) // FLAKY TEST
   270  							// Pod should eventually then go into running state
   271  							Eventually(ca.PodIsRunning).Should((Equal(true)))
   272  						})
   273  
   274  					})
   275  
   276  				})
   277  			})
   278  
   279  			When("a deployment managed by operator is manually edited", func() {
   280  				var (
   281  					err error
   282  					dep *appsv1.Deployment
   283  				)
   284  
   285  				BeforeEach(func() {
   286  					Eventually(ca.DeploymentExists).Should((Equal(true)))
   287  					dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   288  					Expect(err).NotTo(HaveOccurred())
   289  				})
   290  
   291  				It("restores states", func() {
   292  
   293  					// Reduce the deployment resource requests
   294  					origRequests := dep.Spec.Template.Spec.Containers[0].Resources.Requests
   295  					newResourceRequests := corev1.ResourceList{
   296  						corev1.ResourceCPU:    resource.MustParse("20m"),
   297  						corev1.ResourceMemory: resource.MustParse("50M"),
   298  					}
   299  					Expect(newResourceRequests).ToNot(Equal(origRequests))
   300  
   301  					dep.Spec.Template.Spec.Containers[0].Resources.Requests = newResourceRequests
   302  					depBytes, err := json.Marshal(dep)
   303  					Expect(err).NotTo(HaveOccurred())
   304  
   305  					// After patching, the resource limits should have been reduced to the lower values
   306  					dep, err = kclient.AppsV1().Deployments(namespace).Patch(context.TODO(), ca.Name, types.MergePatchType, depBytes, metav1.PatchOptions{})
   307  					Expect(err).NotTo(HaveOccurred())
   308  					Expect(dep.Spec.Template.Spec.Containers[0].Resources.Requests).To(Equal(newResourceRequests))
   309  
   310  					// And with get resource, not just the deployment returned by patch
   311  					dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   312  					Expect(err).NotTo(HaveOccurred())
   313  					Expect(dep.Spec.Template.Spec.Containers[0].Resources.Requests).To(Equal(newResourceRequests))
   314  
   315  					// But the operator prevails:  resource limits will be reset to the original amount specified in the CRD
   316  					err = wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
   317  						dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   318  						if dep != nil {
   319  							if dep.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().MilliValue() == origRequests.Cpu().MilliValue() {
   320  								return true, nil
   321  							}
   322  						}
   323  						return false, nil
   324  					})
   325  					Expect(err).NotTo(HaveOccurred())
   326  
   327  					dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca.Name, metav1.GetOptions{})
   328  					Expect(err).NotTo(HaveOccurred())
   329  					Expect(dep.Spec.Template.Spec.Containers[0].Resources.Requests).To(Equal(origRequests))
   330  				})
   331  			})
   332  		})
   333  
   334  		Context("applying the second instance of IBPCA CR", func() {
   335  			var (
   336  				err error
   337  				dep *appsv1.Deployment
   338  			)
   339  
   340  			BeforeEach(func() {
   341  				Eventually(ca2.PodIsRunning).Should((Equal(true)))
   342  			})
   343  
   344  			It("should find zone and region", func() {
   345  				// Wait for new deployment before querying deployment for updates
   346  				err = wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
   347  					dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca2.Name, metav1.GetOptions{})
   348  					if dep != nil {
   349  						if dep.Status.UpdatedReplicas == 1 && dep.Status.Conditions[0].Type == appsv1.DeploymentAvailable {
   350  							return true, nil
   351  						}
   352  					}
   353  					return false, nil
   354  				})
   355  				Expect(err).NotTo(HaveOccurred())
   356  				dep, err = kclient.AppsV1().Deployments(namespace).Get(context.TODO(), ca2.Name, metav1.GetOptions{})
   357  				Expect(err).NotTo(HaveOccurred())
   358  
   359  				// TODO :: only run these when using MZ clusters
   360  				// By("checking zone", func() {
   361  				// 	Expect(ca2.TestAffinityZone(dep)).To((Equal(true)))
   362  				// })
   363  
   364  				// By("checking region", func() {
   365  				// 	Expect(ca2.TestAffinityRegion(dep)).To((Equal(true)))
   366  				// })
   367  			})
   368  
   369  			When("fabric version is updated", func() {
   370  				BeforeEach(func() {
   371  					ibpca := &current.IBPCA{}
   372  					result := ibpCRClient.Get().Namespace(namespace).Resource("ibpcas").Name(ca2.Name).Do(context.TODO())
   373  					result.Into(ibpca)
   374  
   375  					ibpca.Spec.FabricVersion = integration.FabricCAVersion + "-1"
   376  					bytes, err := json.Marshal(ibpca)
   377  					Expect(err).NotTo(HaveOccurred())
   378  
   379  					result = ibpCRClient.Patch(types.MergePatchType).Namespace(namespace).Resource("ibpcas").Name(ca2.Name).Body(bytes).Do(context.TODO())
   380  					Expect(result.Error()).NotTo(HaveOccurred())
   381  				})
   382  
   383  				It("sets images mapped to version", func() {
   384  					Eventually(func() current.CAImages {
   385  						ibpca := &current.IBPCA{}
   386  						result := ibpCRClient.Get().Namespace(namespace).Resource("ibpcas").Name(ca2.Name).Do(context.TODO())
   387  						result.Into(ibpca)
   388  						fmt.Println("ca images ")
   389  						fmt.Printf("%+v", *ibpca.Spec.Images)
   390  						return *ibpca.Spec.Images
   391  					}).Should(Equal(current.CAImages{
   392  						CAInitImage: integration.InitImage,
   393  						CAInitTag:   integration.InitTag,
   394  						CAImage:     integration.CaImage,
   395  						CATag:       integration.CaTag,
   396  					}))
   397  				})
   398  			})
   399  		})
   400  
   401  		Context("applying incorrectly configured third instance of IBPCA CR", func() {
   402  			It("should set the CR status to error", func() {
   403  				Eventually(ca3.PollForCRStatus).Should((Equal(current.Error)))
   404  
   405  				crStatus := &current.IBPCA{}
   406  				result := ibpCRClient.Get().Namespace(namespace).Resource("ibpcas").Name(ca3.Name).Do(context.TODO())
   407  				result.Into(crStatus)
   408  
   409  				Expect(crStatus.Status.Message).To(ContainSubstring("Failed to provide database configuration for TLSCA to support greater than 1 replicas"))
   410  			})
   411  		})
   412  
   413  		Context("pod restart", func() {
   414  			var (
   415  				oldPodName string
   416  			)
   417  			Context("should not trigger deployment restart if config overrides not updated", func() {
   418  				BeforeEach(func() {
   419  					Eventually(ca.PodIsRunning).Should((Equal(true)))
   420  
   421  					Eventually(func() int {
   422  						return len(ca.GetPods())
   423  					}).Should(Equal(1))
   424  
   425  					pods := ca.GetPods()
   426  					oldPodName = pods[0].Name
   427  				})
   428  
   429  				It("does not restart the ca pod", func() {
   430  					Eventually(ca.PodIsRunning).Should((Equal(true)))
   431  
   432  					Eventually(func() bool {
   433  						pods := ca.GetPods()
   434  						if len(pods) != 1 {
   435  							return false
   436  						}
   437  
   438  						newPodName := pods[0].Name
   439  						if newPodName == oldPodName {
   440  							return true
   441  						}
   442  
   443  						return false
   444  					}).Should(Equal(true))
   445  				})
   446  			})
   447  
   448  			Context("should trigger deployment restart if config overrides updated", func() {
   449  				BeforeEach(func() {
   450  					Eventually(ca.PodIsRunning).Should((Equal(true)))
   451  
   452  					Eventually(func() int {
   453  						return len(ca.GetPods())
   454  					}).Should(Equal(1))
   455  
   456  					pods := ca.GetPods()
   457  					oldPodName = pods[0].Name
   458  
   459  					caOverrides := &v1.ServerConfig{}
   460  					err = json.Unmarshal(ca.CR.Spec.ConfigOverride.CA.Raw, caOverrides)
   461  					Expect(err).NotTo(HaveOccurred())
   462  					caOverrides.CAConfig.CA = v1.CAInfo{
   463  						Name: "new-ca",
   464  					}
   465  
   466  					caJson, err := util.ConvertToJsonMessage(caOverrides)
   467  					Expect(err).NotTo(HaveOccurred())
   468  					ca.CR.Spec.ConfigOverride.CA = &runtime.RawExtension{Raw: *caJson}
   469  
   470  					bytes, err := json.Marshal(ca.CR)
   471  					Expect(err).NotTo(HaveOccurred())
   472  
   473  					result := ibpCRClient.Patch(types.MergePatchType).Namespace(namespace).Resource("ibpcas").Name(ca.Name).Body(bytes).Do(context.TODO())
   474  					Expect(result.Error()).NotTo(HaveOccurred())
   475  				})
   476  
   477  				It("restarts the ca pod", func() {
   478  
   479  					// FLAKY TEST: Checking for pod not running before pod is running causes test to be flaky
   480  					// due to the rolling restart nature of our component restarts. Sometimes, a new pod
   481  					// comes up quicker than this test can check for a non-running pod, so it will never
   482  					// detect that the pod was being terminated before a new one come up.
   483  					// Eventually(ca.PodIsRunning, 240*time.Second, 500*time.Millisecond).Should((Equal(false)))
   484  					Eventually(ca.PodIsRunning).Should((Equal(true)))
   485  
   486  					Eventually(func() bool {
   487  						pods := ca.GetPods()
   488  						if len(pods) != 1 {
   489  							return false
   490  						}
   491  
   492  						newPodName := pods[0].Name
   493  						if newPodName == oldPodName {
   494  							return false
   495  						}
   496  
   497  						return true
   498  					}).Should(Equal(true))
   499  				})
   500  			})
   501  		})
   502  
   503  		Context("enroll intermediate ca", func() {
   504  			BeforeEach(func() {
   505  				Eventually(ca.PodIsRunning).Should((Equal(true)))
   506  			})
   507  
   508  			It("enrolls with root ca", func() {
   509  				ica := GetIntermediateCA()
   510  				helper.CreateCA(ibpCRClient, ica.CR)
   511  
   512  				Eventually(ica.PodIsRunning).Should((Equal(true)))
   513  			})
   514  		})
   515  
   516  		Context("delete crs", func() {
   517  			It("should delete IBPCA CR", func() {
   518  				By("deleting the first instance of IBPCA CR", func() {
   519  					result := ibpCRClient.Delete().Namespace(namespace).Resource("ibpcas").Name(ca.Name).Do(context.TODO())
   520  					Expect(result.Error()).NotTo(HaveOccurred())
   521  				})
   522  
   523  				By("deleting the second instance of IBPCA CR", func() {
   524  					result := ibpCRClient.Delete().Namespace(namespace).Resource("ibpcas").Name(ca2.Name).Do(context.TODO())
   525  					Expect(result.Error()).NotTo(HaveOccurred())
   526  				})
   527  
   528  				By("deleting the third instance of IBPCA CR", func() {
   529  					result := ibpCRClient.Delete().Namespace(namespace).Resource("ibpcas").Name(ca3.Name).Do(context.TODO())
   530  					Expect(result.Error()).NotTo(HaveOccurred())
   531  				})
   532  			})
   533  		})
   534  	})
   535  })
   536  
   537  func GetCA1() *CA {
   538  	caOverrides := &v1.ServerConfig{
   539  		Debug: pointer.True(),
   540  		TLS: v1.ServerTLSConfig{
   541  			CertFile: tlsCert,
   542  			KeyFile:  tlsKey,
   543  		},
   544  		CAConfig: v1.CAConfig{
   545  			CA: v1.CAInfo{
   546  				Name:     "ca",
   547  				Certfile: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVakNDQWZpZ0F3SUJBZ0lSQUtSTFhRQm02WUo5ODlhRGQxVmRxM2d3Q2dZSUtvWkl6ajBFQXdJd2N6RUwKTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFnVENrTmhiR2xtYjNKdWFXRXhGakFVQmdOVkJBY1REVk5oYmlCRwpjbUZ1WTJselkyOHhHVEFYQmdOVkJBb1RFRzl5WnpFdVpYaGhiWEJzWlM1amIyMHhIREFhQmdOVkJBTVRFMk5oCkxtOXlaekV1WlhoaGJYQnNaUzVqYjIwd0hoY05NakF3TkRBNU1EQTBOekF3V2hjTk16QXdOREEzTURBME56QXcKV2pCek1Rc3dDUVlEVlFRR0V3SlZVekVUTUJFR0ExVUVDQk1LUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnhNTgpVMkZ1SUVaeVlXNWphWE5qYnpFWk1CY0dBMVVFQ2hNUWIzSm5NUzVsZUdGdGNHeGxMbU52YlRFY01Cb0dBMVVFCkF4TVRZMkV1YjNKbk1TNWxlR0Z0Y0d4bExtTnZiVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUEKQkxJMENnNlFMTDZqOWdZQkZsQ3k1RTVWSC8vUHJoSUhwZ0ZNQ3VRUXJ4WUM2Y3dBbGdhS1g3Tmd4QzQrenE2dApUaU54OGtSd3h3NTRrQ2N0ZnZQdU1DMmpiVEJyTUE0R0ExVWREd0VCL3dRRUF3SUJwakFkQmdOVkhTVUVGakFVCkJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXdEd1lEVlIwVEFRSC9CQVV3QXdFQi96QXBCZ05WSFE0RUlnUWcKRlhXeWVGYlpMaFRHTko5MzVKQm85bFMyM284cm13SjJSQnZXaDlDMldJa3dDZ1lJS29aSXpqMEVBd0lEU0FBdwpSUUloQUxVcUU5a2F2U0NmbEV6U25ERUhIdVh1ZjR4MEhUbnU3eGtNOXArNW5PcnBBaUF1aE5NWXhxbjU5MUpLCjdWRGFPK0k0eVVWZEViNGxiRlFBZUJiR1FTdkxDdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0==",
   548  				Keyfile:  "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JR0hBZ0VBTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEJHMHdhd0lCQVFRZ1FNWnEwdFY4Mjl0UUZQcS8KcSswZnNES0p6MDdnd0dpS0FUNEMwTG9qSnpDaFJBTkNBQVN5TkFvT2tDeStvL1lHQVJaUXN1Uk9WUi8vejY0UwpCNllCVEFya0VLOFdBdW5NQUpZR2lsK3pZTVF1UHM2dXJVNGpjZkpFY01jT2VKQW5MWDd6N2pBdAotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0t",
   549  			},
   550  		},
   551  	}
   552  	caJson, err := util.ConvertToJsonMessage(caOverrides)
   553  	Expect(err).NotTo(HaveOccurred())
   554  
   555  	tlscaOverrides := v1.ServerConfig{
   556  		CAConfig: v1.CAConfig{
   557  			CA: v1.CAInfo{
   558  				Name: "tlsca-ca1",
   559  			},
   560  		},
   561  	}
   562  	tlscaJson, err := util.ConvertToJsonMessage(tlscaOverrides)
   563  	Expect(err).NotTo(HaveOccurred())
   564  
   565  	name := "ibpca1"
   566  	cr := &current.IBPCA{
   567  		ObjectMeta: metav1.ObjectMeta{
   568  			Name:      name,
   569  			Namespace: namespace,
   570  		},
   571  		Spec: current.IBPCASpec{
   572  			License: current.License{
   573  				Accept: true,
   574  			},
   575  			ImagePullSecrets: []string{"regcred"},
   576  			// TODO:OSS
   577  			Domain: domain,
   578  			Images: &current.CAImages{
   579  				CAImage:     integration.CaImage,
   580  				CATag:       integration.CaTag,
   581  				CAInitImage: integration.InitImage,
   582  				CAInitTag:   integration.InitTag,
   583  			},
   584  			RegistryURL: "no-registry-url",
   585  			Resources: &current.CAResources{
   586  				CA: &corev1.ResourceRequirements{
   587  					Requests: defaultRequests,
   588  					Limits:   defaultLimits,
   589  				},
   590  			},
   591  			ConfigOverride: &current.ConfigOverride{
   592  				CA:    &runtime.RawExtension{Raw: *caJson},
   593  				TLSCA: &runtime.RawExtension{Raw: *tlscaJson},
   594  			},
   595  			FabricVersion: integration.FabricCAVersion,
   596  		},
   597  	}
   598  
   599  	return &CA{
   600  		CA: helper.CA{
   601  			Name:      name,
   602  			Namespace: namespace,
   603  			CR:        cr,
   604  			CRClient:  ibpCRClient,
   605  			KClient:   kclient,
   606  			NativeResourcePoller: integration.NativeResourcePoller{
   607  				Name:      name,
   608  				Namespace: namespace,
   609  				Client:    kclient,
   610  			},
   611  		},
   612  	}
   613  }
   614  
   615  func GetCA2() *CA {
   616  	caOverrides := &v1.ServerConfig{
   617  		Debug: pointer.True(),
   618  		TLS: v1.ServerTLSConfig{
   619  			CertFile: tlsCert,
   620  			KeyFile:  tlsKey,
   621  		},
   622  	}
   623  	caJson, err := util.ConvertToJsonMessage(caOverrides)
   624  	Expect(err).NotTo(HaveOccurred())
   625  
   626  	name := "ibpca2"
   627  	cr := &current.IBPCA{
   628  		ObjectMeta: metav1.ObjectMeta{
   629  			Name:      name,
   630  			Namespace: namespace,
   631  		},
   632  		Spec: current.IBPCASpec{
   633  			License: current.License{
   634  				Accept: true,
   635  			},
   636  			ImagePullSecrets: []string{"regcred"},
   637  			Images: &current.CAImages{
   638  				CAImage:     integration.CaImage,
   639  				CATag:       integration.CaTag,
   640  				CAInitImage: integration.InitImage,
   641  				CAInitTag:   integration.InitTag,
   642  			},
   643  			RegistryURL:   "no-registry-url",
   644  			FabricVersion: integration.FabricCAVersion,
   645  			Resources: &current.CAResources{
   646  				CA: &corev1.ResourceRequirements{
   647  					Requests: defaultRequests,
   648  					Limits:   defaultLimits,
   649  				},
   650  			},
   651  			ConfigOverride: &current.ConfigOverride{
   652  				CA: &runtime.RawExtension{Raw: *caJson},
   653  			},
   654  			Zone:   "select",
   655  			Region: "select",
   656  			Domain: domain,
   657  			CustomNames: current.CACustomNames{
   658  				Sqlite: "/data/fabric-ca-server.db",
   659  			},
   660  		},
   661  	}
   662  	cr.Name = name
   663  
   664  	return &CA{
   665  		CA: helper.CA{
   666  			Name:      name,
   667  			Namespace: namespace,
   668  			CR:        cr,
   669  			CRClient:  ibpCRClient,
   670  			KClient:   kclient,
   671  			NativeResourcePoller: integration.NativeResourcePoller{
   672  				Name:      name,
   673  				Namespace: namespace,
   674  				Client:    kclient,
   675  			},
   676  		},
   677  	}
   678  }
   679  
   680  func GetCA3() *CA {
   681  	caOverrides := &v1.ServerConfig{
   682  		Debug: pointer.True(),
   683  		TLS: v1.ServerTLSConfig{
   684  			CertFile: tlsCert,
   685  			KeyFile:  tlsKey,
   686  		},
   687  	}
   688  
   689  	caJson, err := util.ConvertToJsonMessage(caOverrides)
   690  	Expect(err).NotTo(HaveOccurred())
   691  	var replicas int32
   692  	replicas = 3
   693  	name := "ibpca3"
   694  	cr := &current.IBPCA{
   695  		ObjectMeta: metav1.ObjectMeta{
   696  			Name:      name,
   697  			Namespace: namespace,
   698  		},
   699  		Spec: current.IBPCASpec{
   700  			Domain: domain,
   701  			ConfigOverride: &current.ConfigOverride{
   702  				CA: &runtime.RawExtension{Raw: *caJson},
   703  			},
   704  			FabricVersion: integration.FabricCAVersion,
   705  			License: current.License{
   706  				Accept: true,
   707  			},
   708  			Replicas: &replicas,
   709  		},
   710  	}
   711  
   712  	return &CA{
   713  		CA: helper.CA{
   714  			Name:      name,
   715  			Namespace: namespace,
   716  			CR:        cr,
   717  			CRClient:  ibpCRClient,
   718  			KClient:   kclient,
   719  			NativeResourcePoller: integration.NativeResourcePoller{
   720  				Name:      name,
   721  				Namespace: namespace,
   722  				Client:    kclient,
   723  			},
   724  		},
   725  	}
   726  }
   727  
   728  func GetIntermediateCA() *CA {
   729  	caOverrides := &v1.ServerConfig{
   730  		Debug: pointer.True(),
   731  		TLS: v1.ServerTLSConfig{
   732  			CertFile: tlsCert,
   733  			KeyFile:  tlsKey,
   734  		},
   735  		CAConfig: v1.CAConfig{
   736  			Intermediate: v1.IntermediateCA{
   737  				ParentServer: v1.ParentServer{
   738  					URL: fmt.Sprintf("https://admin:adminpw@%s-ibpca1-ca.%s", namespace, domain),
   739  				},
   740  				TLS: v1.ClientTLSConfig{
   741  					Enabled:   pointer.True(),
   742  					CertFiles: []string{trustedRootTLSCert},
   743  				},
   744  			},
   745  		},
   746  	}
   747  
   748  	caJson, err := util.ConvertToJsonMessage(caOverrides)
   749  	Expect(err).NotTo(HaveOccurred())
   750  
   751  	name := "interca"
   752  	cr := &current.IBPCA{
   753  		ObjectMeta: metav1.ObjectMeta{
   754  			Name:      name,
   755  			Namespace: namespace,
   756  		},
   757  		Spec: current.IBPCASpec{
   758  			License: current.License{
   759  				Accept: true,
   760  			},
   761  			ImagePullSecrets: []string{"regcred"},
   762  			Domain:           domain,
   763  			Images: &current.CAImages{
   764  				CAImage:     integration.CaImage,
   765  				CATag:       integration.CaTag,
   766  				CAInitImage: integration.InitImage,
   767  				CAInitTag:   integration.InitTag,
   768  			},
   769  			ConfigOverride: &current.ConfigOverride{
   770  				CA: &runtime.RawExtension{Raw: *caJson},
   771  			},
   772  			FabricVersion: integration.FabricCAVersion,
   773  		},
   774  	}
   775  
   776  	return &CA{
   777  		CA: helper.CA{
   778  			Name:      name,
   779  			Namespace: namespace,
   780  			CR:        cr,
   781  			NativeResourcePoller: integration.NativeResourcePoller{
   782  				Name:      name,
   783  				Namespace: namespace,
   784  				Client:    kclient,
   785  			},
   786  		},
   787  	}
   788  }