def test_setup_certs(tmpdir): ca_cert_file = Path(tmpdir) / './ca.crt' ca_key_file = Path(tmpdir) / './ca.key' cert_file = Path(tmpdir) / './chain.pem' key_file = Path(tmpdir) / './pkey.key' setup_crts(ca_common_name="test", cert_common_name="test", san_list="test", ca_cert_file=ca_cert_file, ca_key_file=ca_key_file, cert_file=cert_file, key_file=key_file) assert True
def test_setup_log(caplog, tmpdir): ca_cert_file = Path(tmpdir) / './ca.crt' ca_key_file = Path(tmpdir) / './ca.key' cert_file = Path(tmpdir) / './chain.pem' key_file = Path(tmpdir) / './pkey.key' setup_crts(ca_common_name="test", cert_common_name="test", san_list="test", ca_cert_file=ca_cert_file, ca_key_file=ca_key_file, cert_file=cert_file, key_file=key_file) with caplog.at_level(logging.INFO): assert "" in caplog.text
def install(self): """ Installs Couchbase """ self.kubernetes.create_namespace( name=self.settings.get("CN_NAMESPACE")) if self.settings.get("COUCHBASE_CLUSTER_FILE_OVERRIDE") == "N": self.analyze_couchbase_cluster_yaml() cb_namespace = self.settings.get("COUCHBASE_NAMESPACE") storage_class_file_parser = Parser(self.storage_class_file, "StorageClass") if self.settings.get('DEPLOYMENT_ARCH') == "gke" or \ self.settings.get('DEPLOYMENT_ARCH') == "aks" or \ self.settings.get('DEPLOYMENT_ARCH') == "do": try: del storage_class_file_parser["parameters"]["encrypted"] except KeyError: logger.info("Key not found") storage_class_file_parser["parameters"][ "type"] = self.settings.get("COUCHBASE_VOLUME_TYPE") if self.settings.get('DEPLOYMENT_ARCH') == "gke": storage_class_file_parser["provisioner"] = "kubernetes.io/gce-pd" elif self.settings.get('DEPLOYMENT_ARCH') == "aks": storage_class_file_parser[ "provisioner"] = "kubernetes.io/azure-disk" elif self.settings.get('DEPLOYMENT_ARCH') == "do": storage_class_file_parser[ "provisioner"] = "dobs.csi.digitalocean.com" elif self.settings.get('DEPLOYMENT_ARCH') == "microk8s": storage_class_file_parser["provisioner"] = "microk8s.io/hostpath" try: del storage_class_file_parser["allowVolumeExpansion"] del storage_class_file_parser["parameters"] except KeyError: logger.info("Key not found") storage_class_file_parser.dump_it() elif self.settings.get('DEPLOYMENT_ARCH') == "minikube": storage_class_file_parser[ "provisioner"] = "k8s.io/minikube-hostpath" try: del storage_class_file_parser["allowVolumeExpansion"] del storage_class_file_parser["parameters"] except KeyError: logger.info("Key not found") storage_class_file_parser.dump_it() else: try: storage_class_file_parser["parameters"][ "type"] = self.settings.get("COUCHBASE_VOLUME_TYPE") except KeyError: logger.info("Key not found") storage_class_file_parser.dump_it() logger.info("Installing Couchbase...") couchbase_crts_keys = Path("couchbase_crts_keys") if not couchbase_crts_keys.exists(): os.mkdir(couchbase_crts_keys) custom_cb_ca_crt = Path("./couchbase_crts_keys/ca.crt") custom_cb_crt = Path("./couchbase_crts_keys/chain.pem") custom_cb_key = Path("./couchbase_crts_keys/pkey.key") if not custom_cb_ca_crt.exists() and not custom_cb_crt.exists( ) and not custom_cb_key.exists(): setup_crts( ca_common_name=self.settings.get("COUCHBASE_CN"), cert_common_name="couchbase-server", san_list=self.settings.get("COUCHBASE_SUBJECT_ALT_NAME"), ca_cert_file="./couchbase_crts_keys/ca.crt", ca_key_file="./couchbase_crts_keys/ca.key", cert_file="./couchbase_crts_keys/chain.pem", key_file="./couchbase_crts_keys/pkey.key") self.kubernetes.create_namespace(name=cb_namespace) chain_pem_filepath = Path("./couchbase_crts_keys/chain.pem") pkey_filepath = Path("./couchbase_crts_keys/pkey.key") tls_cert_filepath = Path("./couchbase_crts_keys/tls-cert-file") tls_private_key_filepath = Path( "./couchbase_crts_keys/tls-private-key-file") ca_cert_filepath = Path("./couchbase_crts_keys/ca.crt") shutil.copyfile(ca_cert_filepath, Path("./couchbase_crts_keys/couchbase.crt")) shutil.copyfile(chain_pem_filepath, tls_cert_filepath) shutil.copyfile(pkey_filepath, tls_private_key_filepath) encoded_ca_crt_string = self.settings.get("COUCHBASE_CRT") if not encoded_ca_crt_string: with open(ca_cert_filepath) as content_file: ca_crt_content = content_file.read() encoded_ca_crt_bytes = base64.b64encode( ca_crt_content.encode("utf-8")) encoded_ca_crt_string = str(encoded_ca_crt_bytes, "utf-8") self.settings.set("COUCHBASE_CRT", encoded_ca_crt_string) with open(chain_pem_filepath) as content_file: chain_pem_content = content_file.read() encoded_chain_bytes = base64.b64encode( chain_pem_content.encode("utf-8")) encoded_chain_string = str(encoded_chain_bytes, "utf-8") with open(pkey_filepath) as content_file: pkey_content = content_file.read() encoded_pkey_bytes = base64.b64encode(pkey_content.encode("utf-8")) encoded_pkey_string = str(encoded_pkey_bytes, "utf-8") self.kubernetes.patch_or_create_namespaced_secret( name="couchbase-server-tls", namespace=cb_namespace, literal=chain_pem_filepath.name, value_of_literal=encoded_chain_string, second_literal=pkey_filepath.name, value_of_second_literal=encoded_pkey_string) self.kubernetes.patch_or_create_namespaced_secret( name="couchbase-operator-tls", namespace=cb_namespace, literal=ca_cert_filepath.name, value_of_literal=encoded_ca_crt_string) encoded_cb_super_user_bytes = base64.b64encode( self.settings.get("COUCHBASE_SUPERUSER").encode("utf-8")) encoded_cb_super_user_string = str(encoded_cb_super_user_bytes, "utf-8") encoded_cb_pass_bytes = base64.b64encode( self.settings.get("COUCHBASE_PASSWORD").encode("utf-8")) encoded_cb_pass_string = str(encoded_cb_pass_bytes, "utf-8") encoded_cb_super_pass_bytes = base64.b64encode( self.settings.get("COUCHBASE_SUPERUSER_PASSWORD").encode("utf-8")) encoded_cb_super_pass_string = str(encoded_cb_super_pass_bytes, "utf-8") self.create_couchbase_gluu_cert_pass_secrets( encoded_ca_crt_string, encoded_cb_pass_string, encoded_cb_super_pass_string) self.kubernetes.patch_or_create_namespaced_secret( name="gluu-couchbase-user-password", namespace=self.settings.get("COUCHBASE_NAMESPACE"), literal="password", value_of_literal=encoded_cb_pass_string) command = "./{}/bin/cbopcfg -backup=true -namespace={}".format( self.couchbase_source_file, self.settings.get("COUCHBASE_NAMESPACE")) exec_cmd(command, output_file=self.couchbase_operator_dac_file) couchbase_cluster_parser = Parser(self.couchbase_cluster_file, "CouchbaseCluster") couchbase_cluster_parser["spec"]["networking"]["tls"]["static"][ "serverSecret"] = "couchbase-server-tls" couchbase_cluster_parser["spec"]["networking"]["tls"]["static"][ "operatorSecret"] = "couchbase-operator-tls" try: couchbase_cluster_parser["spec"]["security"]["rbac"]["selector"]["matchLabels"]["cluster"] = \ self.settings.get("COUCHBASE_CLUSTER_NAME") couchbase_cluster_parser["spec"]["security"]["rbac"][ "managed"] = True except KeyError: logger.error( "rbac section is missing or incorrect in couchbase-cluster.yaml." " Please set spec --> security --> rbac --> managed : true" " and set spec --> security --> rbac --> selector --> matchLabels --> " "cluster --> to your cluster name") logger.info( "As a result of the above the installation will exit " "as the gluu user will not be created causing the communication between " "Gluu server and Couchbase to fail.") sys.exit() if self.settings.get("DEPLOYMENT_ARCH") == "local": volume_claims = couchbase_cluster_parser["spec"][ "volumeClaimTemplates"] for i, volume_claim in enumerate(volume_claims): couchbase_cluster_parser["spec"]["volumeClaimTemplates"][i]["spec"]["storageClassName"] = \ "openebs-hostpath" couchbase_cluster_parser.dump_it() self.kubernetes.create_objects_from_dict( self.couchbase_custom_resource_definition_file, namespace=cb_namespace) self.kubernetes.create_objects_from_dict( self.couchbase_operator_dac_file, namespace=cb_namespace) self.kubernetes.check_pods_statuses(cb_namespace, "app=couchbase-operator", 700) self.kubernetes.patch_or_create_namespaced_secret( name="cb-auth", namespace=cb_namespace, literal="username", value_of_literal=encoded_cb_super_user_string, second_literal="password", value_of_second_literal=encoded_cb_super_pass_string) self.kubernetes.create_objects_from_dict(self.storage_class_file, namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_cluster_file, group="couchbase.com", version="v2", plural="couchbaseclusters", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_buckets_file, group="couchbase.com", version="v2", plural="couchbasebuckets", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_ephemeral_buckets_file, group="couchbase.com", version="v2", plural="couchbaseephemeralbuckets", namespace=cb_namespace) coucbase_group_parser = Parser(self.couchbase_group_file, "CouchbaseGroup") coucbase_group_parser["metadata"]["labels"]["cluster"] = \ self.settings.get("COUCHBASE_CLUSTER_NAME") coucbase_group_parser.dump_it() coucbase_user_parser = Parser(self.couchbase_user_file, "CouchbaseUser") coucbase_user_parser["metadata"]["labels"]["cluster"] = \ self.settings.get("COUCHBASE_CLUSTER_NAME") coucbase_user_parser.dump_it() self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_group_file, group="couchbase.com", version="v2", plural="couchbasegroups", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_user_file, group="couchbase.com", version="v2", plural="couchbaseusers", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_rolebinding_file, group="couchbase.com", version="v2", plural="couchbaserolebindings", namespace=cb_namespace) self.kubernetes.check_pods_statuses( cb_namespace, "couchbase_service_analytics=enabled", 700) self.kubernetes.check_pods_statuses(cb_namespace, "couchbase_service_data=enabled", 700) self.kubernetes.check_pods_statuses( cb_namespace, "couchbase_service_eventing=enabled", 700) self.kubernetes.check_pods_statuses(cb_namespace, "couchbase_service_index=enabled", 700) self.kubernetes.check_pods_statuses(cb_namespace, "couchbase_service_query=enabled", 700) self.kubernetes.check_pods_statuses( cb_namespace, "couchbase_service_search=enabled", 700) # Setup couchbase backups if self.settings.get("DEPLOYMENT_ARCH") not in ("microk8s", "minikube"): self.setup_backup_couchbase() shutil.rmtree(self.couchbase_source_folder_pattern, ignore_errors=True) if self.settings.get("DEPLOY_MULTI_CLUSTER") == "Y": logger.info( "Setup XDCR between the running Gluu couchbase cluster and this one" )
def install(self): """ Installs Couchbase """ self.kubernetes.create_namespace( name=self.settings.get("installer-settings.namespace")) if not self.settings.get( "installer-settings.couchbase.customFileOverride"): try: self.analyze_couchbase_cluster_yaml() except Exception: # TODO remove this exception logger.error( "Looks like some of the couchbase files were misconfigured. " "If you wish to override the couchbase files please set " " installer-settings.couchbase.customFileOverride to true`" ) sys.exit() cb_namespace = self.settings.get( "installer-settings.couchbase.namespace") storage_class_file_parser = Parser(self.storage_class_file, "StorageClass") if self.settings.get('global.storageClass.provisioner') in ( "kubernetes.io/gce-pd", "dobs.csi.digitalocean.com", "kubernetes.io/azure-disk"): try: del storage_class_file_parser["parameters"]["encrypted"] except KeyError: logger.info("Key not found") storage_class_file_parser["parameters"]["type"] = \ self.settings.get("installer-settings.couchbase.volumeType") storage_class_file_parser["provisioner"] = self.settings.get( 'global.storageClass.provisioner') if self.settings.get( 'global.storageClass.provisioner') == "microk8s.io/hostpath": try: del storage_class_file_parser["allowVolumeExpansion"] del storage_class_file_parser["parameters"] except KeyError: logger.info("Key not found") storage_class_file_parser.dump_it() elif self.settings.get('global.storageClass.provisioner' ) == "k8s.io/minikube-hostpath": try: del storage_class_file_parser["allowVolumeExpansion"] del storage_class_file_parser["parameters"] except KeyError: logger.info("Key not found") storage_class_file_parser.dump_it() else: try: storage_class_file_parser["parameters"]["type"] = \ self.settings.get("installer-settings.couchbase.volumeType") except KeyError: logger.info("Key not found") storage_class_file_parser.dump_it() logger.info("Installing Couchbase...") couchbase_crts_keys = Path("couchbase_crts_keys") if not couchbase_crts_keys.exists(): os.mkdir(couchbase_crts_keys) custom_cb_ca_crt = Path("./couchbase_crts_keys/ca.crt") custom_cb_crt = Path("./couchbase_crts_keys/chain.pem") custom_cb_key = Path("./couchbase_crts_keys/pkey.key") if not custom_cb_ca_crt.exists() and not custom_cb_crt.exists( ) and not custom_cb_key.exists(): setup_crts( ca_common_name=self.settings.get( "installer-settings.couchbase.commonName"), cert_common_name="couchbase-server", san_list=self.settings.get( "installer-settings.couchbase.subjectAlternativeName"), ca_cert_file="./couchbase_crts_keys/ca.crt", ca_key_file="./couchbase_crts_keys/ca.key", cert_file="./couchbase_crts_keys/chain.pem", key_file="./couchbase_crts_keys/pkey.key") labels = {"app": "gluu-couchbase"} if self.settings.get("global.istio.enabled"): labels = {"app": "couchbase", "istio-injection": "enabled"} self.kubernetes.create_namespace(name=cb_namespace, labels=labels) chain_pem_filepath = Path("./couchbase_crts_keys/chain.pem") pkey_filepath = Path("./couchbase_crts_keys/pkey.key") tls_cert_filepath = Path("./couchbase_crts_keys/tls-cert-file") tls_private_key_filepath = Path( "./couchbase_crts_keys/tls-private-key-file") ca_cert_filepath = Path("./couchbase_crts_keys/ca.crt") shutil.copyfile(ca_cert_filepath, Path("./couchbase_crts_keys/couchbase.crt")) shutil.copyfile(chain_pem_filepath, tls_cert_filepath) shutil.copyfile(pkey_filepath, tls_private_key_filepath) encoded_ca_crt_string = self.settings.get( "config.configmap.cnCouchbaseCrt") if encoded_ca_crt_string in (None, ''): with open(ca_cert_filepath) as content_file: ca_crt_content = content_file.read() encoded_ca_crt_bytes = base64.b64encode( ca_crt_content.encode("utf-8")) encoded_ca_crt_string = str(encoded_ca_crt_bytes, "utf-8") self.settings.set("config.configmap.cnCouchbaseCrt", encoded_ca_crt_string) with open(chain_pem_filepath) as content_file: chain_pem_content = content_file.read() encoded_chain_bytes = base64.b64encode( chain_pem_content.encode("utf-8")) encoded_chain_string = str(encoded_chain_bytes, "utf-8") with open(pkey_filepath) as content_file: pkey_content = content_file.read() encoded_pkey_bytes = base64.b64encode(pkey_content.encode("utf-8")) encoded_pkey_string = str(encoded_pkey_bytes, "utf-8") self.kubernetes.patch_or_create_namespaced_secret( name="couchbase-server-tls", namespace=cb_namespace, literal=chain_pem_filepath.name, value_of_literal=encoded_chain_string, second_literal=pkey_filepath.name, value_of_second_literal=encoded_pkey_string) self.kubernetes.patch_or_create_namespaced_secret( name="couchbase-operator-tls", namespace=cb_namespace, literal=ca_cert_filepath.name, value_of_literal=encoded_ca_crt_string) encoded_cb_super_user_bytes = base64.b64encode( self.settings.get("config.configmap.cnCouchbaseSuperUser").encode( "utf-8")) encoded_cb_super_user_string = str(encoded_cb_super_user_bytes, "utf-8") encoded_cb_pass_bytes = base64.b64encode( self.settings.get("config.configmap.cnCouchbasePassword").encode( "utf-8")) encoded_cb_pass_string = str(encoded_cb_pass_bytes, "utf-8") encoded_cb_super_pass_bytes = base64.b64encode( self.settings.get("config.configmap.cnCouchbaseSuperUserPassword"). encode("utf-8")) encoded_cb_super_pass_string = str(encoded_cb_super_pass_bytes, "utf-8") self.create_couchbase_gluu_cert_pass_secrets( encoded_ca_crt_string, encoded_cb_pass_string, encoded_cb_super_pass_string) self.kubernetes.patch_or_create_namespaced_secret( name="gluu-couchbase-user-password", namespace=self.settings.get( "installer-settings.couchbase.namespace"), literal="password", value_of_literal=encoded_cb_pass_string) admission_command = "./{}/bin/cbopcfg generate admission --namespace {}".format( self.couchbase_source_file, self.settings.get("installer-settings.couchbase.namespace")) operator_command = "./{}/bin/cbopcfg generate operator --namespace {}".format( self.couchbase_source_file, self.settings.get("installer-settings.couchbase.namespace")) backup_command = "./{}/bin/cbopcfg generate backup --namespace {}".format( self.couchbase_source_file, self.settings.get("installer-settings.couchbase.namespace")) # @TODO: Remove condition and operator_command override after depreciation of couchbase operator 2.0 if self.old_couchbase: operator_command = "./{}/bin/cbopcfg -backup=true -namespace={}".format( self.couchbase_source_file, self.settings.get("installer-settings.couchbase.namespace")) exec_cmd(operator_command, output_file=self.couchbase_operator_dac_file) # @TODO: Remove only the condition after depreciation of couchbase operator 2.0 if not self.old_couchbase: exec_cmd(backup_command, output_file=self.couchbase_operator_backup_file) exec_cmd(admission_command, output_file=self.couchbase_admission_file) couchbase_cluster_parser = Parser(self.couchbase_cluster_file, "CouchbaseCluster") couchbase_cluster_parser["spec"]["networking"]["tls"]["static"][ "serverSecret"] = "couchbase-server-tls" couchbase_cluster_parser["spec"]["networking"]["tls"]["static"][ "operatorSecret"] = "couchbase-operator-tls" if self.settings.get("global.istio.enabled"): couchbase_cluster_parser["spec"]["networking"][ "networkPlatform"] = "Istio" try: couchbase_cluster_parser["spec"]["security"]["rbac"]["selector"]["matchLabels"]["cluster"] = \ self.settings.get("installer-settings.couchbase.clusterName") couchbase_cluster_parser["spec"]["security"]["rbac"][ "managed"] = True except KeyError: logger.error( "rbac section is missing or incorrect in couchbase-cluster.yaml." " Please set spec --> security --> rbac --> managed : true" " and set spec --> security --> rbac --> selector --> matchLabels --> " "cluster --> to your cluster name") logger.info( "As a result of the above the installation will exit " "as the gluu user will not be created causing the communication between " "Gluu server and Couchbase to fail.") sys.exit() if "localOpenEbsHostPathDynamic" in self.settings.get( "installer-settings.volumeProvisionStrategy"): volume_claims = couchbase_cluster_parser["spec"][ "volumeClaimTemplates"] for i, volume_claim in enumerate(volume_claims): couchbase_cluster_parser["spec"]["volumeClaimTemplates"][i]["spec"]["storageClassName"] = \ "openebs-hostpath" couchbase_cluster_parser.dump_it() self.kubernetes.create_objects_from_dict( self.couchbase_custom_resource_definition_file, namespace=cb_namespace) self.kubernetes.create_objects_from_dict( self.couchbase_operator_dac_file, namespace=cb_namespace) # @TODO: Remove only the condition after depreciation of couchbase operator 2.0 if not self.old_couchbase: self.kubernetes.create_objects_from_dict( self.couchbase_admission_file, namespace=cb_namespace) self.kubernetes.create_objects_from_dict( self.couchbase_operator_backup_file, namespace=cb_namespace) self.kubernetes.check_pods_statuses(cb_namespace, "app=couchbase-operator", 700) self.kubernetes.patch_or_create_namespaced_secret( name="cb-auth", namespace=cb_namespace, literal="username", value_of_literal=encoded_cb_super_user_string, second_literal="password", value_of_second_literal=encoded_cb_super_pass_string) self.kubernetes.create_objects_from_dict(self.storage_class_file, namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_cluster_file, group="couchbase.com", version="v2", plural="couchbaseclusters", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_buckets_file, group="couchbase.com", version="v2", plural="couchbasebuckets", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_ephemeral_buckets_file, group="couchbase.com", version="v2", plural="couchbaseephemeralbuckets", namespace=cb_namespace) coucbase_group_parser = Parser(self.couchbase_group_file, "CouchbaseGroup") coucbase_group_parser["metadata"]["labels"]["cluster"] = \ self.settings.get("installer-settings.couchbase.clusterName") permissions = [ "query_select", "query_update", "query_insert", "query_delete" ] allbuckets = ["", "site", "user", "cache", "token", "session"] roles = [] for permission in permissions: for bucket in allbuckets: bucket_name = self.settings.get( "config.configmap.cnCouchbaseBucketPrefix") if bucket: bucket_name = bucket_name + "_" + bucket roles.append({"name": permission, "bucket": bucket_name}) coucbase_group_parser["spec"]["roles"] = roles coucbase_group_parser.dump_it() coucbase_user_parser = Parser(self.couchbase_user_file, "CouchbaseUser") coucbase_user_parser["metadata"]["labels"]["cluster"] = \ self.settings.get("installer-settings.couchbase.clusterName") coucbase_user_parser.dump_it() self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_group_file, group="couchbase.com", version="v2", plural="couchbasegroups", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_user_file, group="couchbase.com", version="v2", plural="couchbaseusers", namespace=cb_namespace) self.kubernetes.create_namespaced_custom_object( filepath=self.couchbase_rolebinding_file, group="couchbase.com", version="v2", plural="couchbaserolebindings", namespace=cb_namespace) self.kubernetes.check_pods_statuses( cb_namespace, "couchbase_service_analytics=enabled", 700) self.kubernetes.check_pods_statuses(cb_namespace, "couchbase_service_data=enabled", 700) self.kubernetes.check_pods_statuses( cb_namespace, "couchbase_service_eventing=enabled", 700) self.kubernetes.check_pods_statuses(cb_namespace, "couchbase_service_index=enabled", 700) self.kubernetes.check_pods_statuses(cb_namespace, "couchbase_service_query=enabled", 700) self.kubernetes.check_pods_statuses( cb_namespace, "couchbase_service_search=enabled", 700) # Setup couchbase backups if self.settings.get("global.storageClass.provisioner") not in ( "microk8s.io/hostpath", "k8s.io/minikube-hostpath"): self.setup_backup_couchbase() shutil.rmtree(self.couchbase_source_folder_pattern, ignore_errors=True)