def remove_xcluster_root_cert(self, ssh_options, replication_config_name, producer_certs_dir): def check_rm_result(rm_result): if rm_result.exited and rm_result.stderr.find( "No such file or directory") == -1: raise YBOpsRuntimeError( "Remote shell command 'rm' failed with " "return code '{}' and error '{}'".format( rm_result.stderr.encode('utf-8'), rm_result.exited)) if producer_certs_dir is None: producer_certs_dir = self.PRODUCER_CERTS_DIR_NAME remote_shell = RemoteShell(ssh_options) node_ip = ssh_options["ssh_host"] src_root_cert_dir_path = os.path.join(producer_certs_dir, replication_config_name) src_root_cert_path = os.path.join(src_root_cert_dir_path, self.ROOT_CERT_NAME) logging.info( "Removing server cert located at {} from server {}.".format( src_root_cert_dir_path, node_ip)) remote_shell.run_command( 'chmod -f 666 {}/* || true'.format(src_root_cert_dir_path)) result = remote_shell.run_command_raw('rm ' + src_root_cert_path) check_rm_result(result) # Remove the directory only if it is empty. result = remote_shell.run_command_raw('rm -d ' + src_root_cert_dir_path) check_rm_result(result) # No need to check the result of this command. remote_shell.run_command_raw('rm -d ' + producer_certs_dir)
def verify_certs(self, root_crt_path, node_crt_path, ssh_options, verify_hostname=False): remote_shell = RemoteShell(ssh_options) try: remote_shell.run_command('which openssl') except YBOpsRuntimeError: logging.debug( "Openssl not found, skipping certificate verification.") return # Verify if the node cert is not expired validity_verify = remote_shell.run_command_raw( "openssl x509 -noout -checkend 86400 -in {}".format(node_crt_path)) if validity_verify.exited == 1: raise YBOpsRuntimeError( "Node cert: {} is expired or will expire in one day.".format( node_crt_path)) # Verify if node cert has valid signature signature_verify = remote_shell.run_command_raw( "openssl verify -CAfile {} {} | egrep error".format( root_crt_path, node_crt_path)) if signature_verify.exited != 1: raise YBOpsRuntimeError( "Node cert: {} is not signed by the provided root cert: {}.". format(node_crt_path, root_crt_path)) if verify_hostname: self.__verify_certs_hostname(node_crt_path, ssh_options)
def compare_root_certs(self, extra_vars, ssh_options): has_openssl = True root_cert_path = extra_vars["root_cert_path"] certs_node_dir = extra_vars["certs_node_dir"] yb_root_cert_path = os.path.join(certs_node_dir, self.ROOT_CERT_NAME) remote_shell = RemoteShell(ssh_options) try: remote_shell.run_command('which openssl') except YBOpsRuntimeError as e: # No openssl, just compare files. has_openssl = False # Check if files exist. If not, let it error out (since the root files should be there.) remote_shell.run_command('test -f {}'.format(root_cert_path)) remote_shell.run_command('test -f {}'.format(yb_root_cert_path)) # Compare the openssl hash if openssl is present. if has_openssl: md5_cmd = "openssl x509 -noout -modulus -in '{}' | openssl md5" curr_root = remote_shell.run_command(md5_cmd.format(yb_root_cert_path)) new_root = remote_shell.run_command(md5_cmd.format(root_cert_path)) if curr_root.stdout != new_root.stdout: raise YBOpsRuntimeError("Root certs are different.") # Openssl not present, just compare the files after removing whitespace. else: # If there is an error code, that means the files are different. Should fail. remote_shell.run_command('diff -Z {} {}'.format(root_cert_path, yb_root_cert_path))
def expand_file_system(self, args, ssh_options): remote_shell = RemoteShell(ssh_options) mount_points = self.get_mount_points_csv(args).split(',') for mount_point in mount_points: logging.info("Expanding file system with mount point: {}".format( mount_point)) remote_shell.run_command('sudo xfs_growfs {}'.format(mount_point))
def create_encryption_at_rest_file(self, extra_vars, ssh_options): node_ip = ssh_options["ssh_host"] encryption_key_path = extra_vars["encryption_key_file"] # Source file path key_node_dir = extra_vars["encryption_key_dir"] # Target file path with open(encryption_key_path, "r") as f: encryption_key = f.read() key_file = os.path.basename(encryption_key_path) common_path = os.path.join(self.CERTS_TEMP_DIR, node_ip) try: os.makedirs(common_path) except OSError as exc: # Guard against race condition if exc.errno != errno.EEXIST: raise YBOpsRuntimeError(common_path + " could not be be created") # Write encryption-at-rest key to file with open(os.path.join(common_path, key_file), 'wb') as key_out: key_out.write(encryption_key) # Copy files over to node remote_shell = RemoteShell(ssh_options) remote_shell.run_command('mkdir -p ' + key_node_dir) remote_shell.put_file(os.path.join(common_path, key_file), os.path.join(key_node_dir, key_file)) try: shutil.rmtree(common_path) except OSError as e: raise YBOpsRuntimeError("Error: %s - %s." % (e.filename, e.strerror))
def initYSQL(self, master_addresses, ssh_options): remote_shell = RemoteShell(ssh_options) init_db_path = os.path.join(YB_HOME_DIR, "tserver/postgres/bin/initdb") remote_shell.run_command( "bash -c \"YB_ENABLED_IN_POSTGRES=1 FLAGS_pggate_master_addresses={} " "{} -D /tmp/yb_pg_initdb_tmp_data_dir " "-U postgres\"".format(master_addresses, init_db_path))
def verify_certs(self, root_crt_path, node_crt_path, ssh_options, verify_hostname=False): remote_shell = RemoteShell(ssh_options) # Verify that both cert are present in FS and have read rights root_file_verify = remote_shell.run_command_raw( "test -r {}".format(root_crt_path)) if root_file_verify.exited == 1: raise YBOpsRuntimeError( "Root cert: {} is absent or is not readable.".format( root_crt_path)) node_file_verify = remote_shell.run_command_raw( "test -r {}".format(node_crt_path)) if node_file_verify.exited == 1: raise YBOpsRuntimeError( "Node cert: {} is absent or is not readable.".format( node_crt_path)) try: remote_shell.run_command('which openssl') except YBOpsRuntimeError: logging.debug( "Openssl not found, skipping certificate verification.") return # Verify if root and node certs are valid cert_verify = remote_shell.run_command_raw( ("openssl crl2pkcs7 -nocrl -certfile {} -certfile {} " "| openssl pkcs7 -print_certs -text -noout").format( root_crt_path, node_crt_path)) if cert_verify.exited == 1: raise YBOpsRuntimeError( "Provided certs ({}, {}) are not valid.".format( root_crt_path, node_crt_path)) # Verify if the node cert is not expired validity_verify = remote_shell.run_command_raw( "openssl x509 -noout -checkend 86400 -in {}".format(node_crt_path)) if validity_verify.exited == 1: raise YBOpsRuntimeError( "Node cert: {} is expired or will expire in one day.".format( node_crt_path)) # Verify if node cert has valid signature signature_verify = remote_shell.run_command_raw( "openssl verify -CAfile {} {} | egrep error".format( root_crt_path, node_crt_path)) if signature_verify.exited != 1: raise YBOpsRuntimeError( "Node cert: {} is not signed by the provided root cert: {}.". format(node_crt_path, root_crt_path)) if verify_hostname: self.__verify_certs_hostname(node_crt_path, ssh_options)
def run_control_script(self, process, command, args, extra_vars, host_info): updated_vars = {"process": process, "command": command} updated_vars.update(extra_vars) updated_vars.update(get_ssh_host_port(host_info, args.custom_ssh_port)) if os.environ.get("YB_USE_FABRIC", False): remote_shell = RemoteShell(updated_vars) file_path = os.path.join(YB_HOME_DIR, "bin/yb-server-ctl.sh") remote_shell.run_command("{} {} {}".format(file_path, process, command)) else: self.setup_ansible(args).run("yb-server-ctl.yml", updated_vars, host_info)
def run_control_script(self, process, command, args, extra_vars, host_info): updated_vars = {"process": process, "command": command} updated_vars.update(extra_vars) updated_vars.update(get_ssh_host_port(host_info, args.custom_ssh_port)) remote_shell = RemoteShell(updated_vars) if process == "thirdparty" or process == "platform-services": self.setup_ansible(args).run("yb-server-ctl.yml", updated_vars, host_info) return if args.systemd_services: if command == "start": remote_shell.run_command( "sudo systemctl enable yb-{}".format(process)) remote_shell.run_command("sudo systemctl {} yb-{}".format( command, process)) if command == "stop": remote_shell.run_command( "sudo systemctl disable yb-{}".format(process)) return if os.environ.get("YB_USE_FABRIC", False): file_path = os.path.join(YB_HOME_DIR, "bin/yb-server-ctl.sh") remote_shell.run_command("{} {} {}".format(file_path, process, command)) else: self.setup_ansible(args).run("yb-server-ctl.yml", updated_vars, host_info)
def run_control_script(self, process, command, args, extra_vars, host_info): updated_vars = {"process": process, "command": command} updated_vars.update(extra_vars) updated_vars.update(get_ssh_host_port(host_info)) if os.environ.get("YB_USE_FABRIC", False): remote_shell = RemoteShell(updated_vars) ssh_user = updated_vars.get("ssh_user") # TODO: change the home directory from being hard coded into a param passed in. remote_shell.run_command( "/home/yugabyte/bin/yb-server-ctl.sh {} {}".format( process, command)) else: self.setup_ansible(args).run("yb-server-ctl.yml", updated_vars, host_info)
def create_encryption_at_rest_file(self, extra_vars, ssh_options): encryption_key_path = extra_vars["encryption_key_file"] # Source file path key_node_dir = extra_vars["encryption_key_dir"] # Target file path with open(encryption_key_path, "r") as f: encryption_key = f.read() key_file = os.path.basename(encryption_key_path) with tempfile.TemporaryDirectory() as common_path: # Write encryption-at-rest key to file with open(os.path.join(common_path, key_file), 'wb') as key_out: key_out.write(encryption_key) # Copy files over to node remote_shell = RemoteShell(ssh_options) remote_shell.run_command('mkdir -p ' + key_node_dir) remote_shell.put_file(os.path.join(common_path, key_file), os.path.join(key_node_dir, key_file))
def copy_certs(self, extra_vars, ssh_options): remote_shell = RemoteShell(ssh_options) if "root_cert_path" in extra_vars: root_cert_path = extra_vars["root_cert_path"] node_cert_path = extra_vars["node_cert_path"] node_key_path = extra_vars["node_key_path"] certs_node_dir = extra_vars["certs_node_dir"] self.verify_certs(root_cert_path, node_cert_path, ssh_options, verify_hostname=True) self.__copy_certs(ssh_options, remote_shell, root_cert_path, node_cert_path, node_key_path, certs_node_dir) if "client_root_cert_path" in extra_vars: root_cert_path = extra_vars["client_root_cert_path"] node_cert_path = extra_vars["client_node_cert_path"] node_key_path = extra_vars["client_node_key_path"] certs_client_dir = extra_vars["certs_client_dir"] self.verify_certs(root_cert_path, node_cert_path, ssh_options, verify_hostname=False) self.__copy_certs(ssh_options, remote_shell, root_cert_path, node_cert_path, node_key_path, certs_client_dir) if "client_cert_path" in extra_vars: client_cert_path = extra_vars["client_cert_path"] client_key_path = extra_vars["client_key_path"] logging.info("Moving client certs located at {}, {}.".format( client_cert_path, client_key_path)) remote_shell.run_command('mkdir -p ' + self.YSQLSH_CERT_DIR) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format( self.YSQLSH_CERT_DIR)) remote_shell.run_command('cp {} {}'.format( client_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME))) remote_shell.run_command('cp {} {}'.format( client_key_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME))) remote_shell.run_command('chmod 400 {}/*'.format( self.YSQLSH_CERT_DIR))
def get_mount_roots(ssh_options, paths): remote_shell = RemoteShell(ssh_options) remote_cmd = 'df --output=target {}'.format(" ".join(paths.split(","))) # Example output of the df cmd # $ df --output=target /bar/foo/rnd /storage/abc # Mounted on # /bar # /storage mount_roots = remote_shell.run_command(remote_cmd).stdout.split('\n')[1:] return ",".join([mroot.strip() for mroot in mount_roots if mroot.strip()])
def run_control_script(self, process, command, args, extra_vars, host_info): updated_vars = { "process": process, "command": command } updated_vars.update(extra_vars) updated_vars.update(get_ssh_host_port(host_info, args.custom_ssh_port)) remote_shell = RemoteShell(updated_vars) if args.num_volumes: volume_cnt = remote_shell.run_command( "df | awk '{{print $6}}' | egrep '^{}[0-9]+' | wc -l".format( AbstractCloud.MOUNT_PATH_PREFIX ) ) if int(volume_cnt.stdout) < int(args.num_volumes): raise YBOpsRuntimeError( "Not all data volumes attached: needed {} found {}".format( args.num_volumes, volume_cnt.stdout ) ) if process == "thirdparty" or process == "platform-services": self.setup_ansible(args).run("yb-server-ctl.yml", updated_vars, host_info) return if args.systemd_services: if command == "start": remote_shell.run_command( "sudo systemctl enable yb-{}".format(process) ) remote_shell.run_command( "sudo systemctl {} yb-{}".format(command, process) ) if command == "stop": remote_shell.run_command( "sudo systemctl disable yb-{}".format(process) ) return if os.environ.get("YB_USE_FABRIC", False): file_path = os.path.join(YB_HOME_DIR, "bin/yb-server-ctl.sh") remote_shell.run_command( "{} {} {}".format(file_path, process, command) ) else: self.setup_ansible(args).run("yb-server-ctl.yml", updated_vars, host_info)
def __verify_certs_hostname(self, node_crt_path, ssh_options): host = ssh_options["ssh_host"] remote_shell = RemoteShell(ssh_options) logging.info("Verifying Subject for certs {}".format(node_crt_path)) # Get readable text version of cert cert_text = remote_shell.run_command( "openssl x509 -noout -text -in {}".format(node_crt_path)) if "Certificate:" not in cert_text.stdout: raise YBOpsRuntimeError( "Unable to decode the node cert: {}.".format(node_crt_path)) # Extract commonName and subjectAltName from the cert text output regex_out = re.findall( " Subject:.*CN=([\\S]*)$| (DNS|IP Address):([\\S]*?)(,|$)", cert_text.stdout, re.M) # Hostname will be present in group 0 for CN and in group 1 and 2 for SAN cn_entry = [x[0] for x in regex_out if x[0] != ''] san_entry = {(x[1], x[2]) for x in regex_out if x[0] == ''} # Create cert object following the below dictionary format # https://docs.python.org/3/library/ssl.html#ssl.SSLSocket.getpeercert cert_cn = { 'subject': ((('commonName', cn_entry[0] if len(cn_entry) > 0 else ''), ), ) } cert_san = {'subjectAltName': tuple(san_entry)} # Check if the provided hostname matches with either CN or SAN cn_matched = False san_matched = False try: ssl.match_hostname(cert_cn, host) cn_matched = True except ssl.CertificateError: pass try: ssl.match_hostname(cert_san, host) san_matched = True except ssl.CertificateError: pass if not cn_matched and not san_matched: raise YBOpsRuntimeError( "'{}' does not match with any entry in CN or SAN of the node cert: {}, " "cert_cn: {}, cert_san: {}".format(host, node_crt_path, cert_cn, cert_san))
def append_new_root_cert(self, ssh_options, root_cert_path, certs_location, certs_dir): remote_shell = RemoteShell(ssh_options) yb_root_cert_path = os.path.join(certs_dir, self.ROOT_CERT_NAME) yb_root_cert_new_path = os.path.join(certs_dir, self.ROOT_CERT_NEW_NAME) # Give write permissions to cert directory remote_shell.run_command('chmod -f 666 {}/* || true'.format(certs_dir)) # Copy the new root cert to ca_new.crt if certs_location == self.CERT_LOCATION_NODE: remote_shell.run_command("cp '{}' '{}'".format(root_cert_path, yb_root_cert_new_path)) if certs_location == self.CERT_LOCATION_PLATFORM: remote_shell.put_file(root_cert_path, yb_root_cert_new_path) # Append new cert content to ca.crt remote_shell.run_command( "cat '{}' >> '{}'".format(yb_root_cert_new_path, yb_root_cert_path)) # Reset the write permissions remote_shell.run_command('chmod 400 {}/*'.format(certs_dir))
def remove_old_root_cert(self, ssh_options, certs_dir): remote_shell = RemoteShell(ssh_options) yb_root_cert_path = os.path.join(certs_dir, self.ROOT_CERT_NAME) yb_root_cert_new_path = os.path.join(certs_dir, self.ROOT_CERT_NEW_NAME) # Check if ca_new.crt is present, it will be present if # APPEND_NEW_ROOT_CERT action was performed before file_verify = remote_shell.run_command_raw( "test -f '{}'".format(yb_root_cert_new_path)) # No action needed if ca_new.crt is not present if not file_verify.exited: # Give write permissions to cert directory remote_shell.run_command( 'chmod -f 666 {}/* || true'.format(certs_dir)) # Remove ca.crt and rename ca_new.crt to ca.crt remote_shell.run_command("mv '{}' '{}'".format( yb_root_cert_new_path, yb_root_cert_path)) # Reset the write permissions remote_shell.run_command('chmod 400 {}/*'.format(certs_dir))
def cleanup_client_certs(self, ssh_options): remote_shell = RemoteShell(ssh_options) yb_root_cert_path = os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_ROOT_NAME) yb_client_cert_path = os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME) yb_client_key_path = os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME) logging.info("Removing client certs located at {}, {}, {}.".format( yb_root_cert_path, yb_client_cert_path, yb_client_key_path)) # Give write permissions. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format( self.YSQLSH_CERT_DIR)) # Remove client certs remote_shell.run_command("rm '{}' '{}' '{}' || true".format( yb_root_cert_path, yb_client_cert_path, yb_client_key_path)) # Reset the write permission as a sanity check. remote_shell.run_command('chmod 400 {}/* || true'.format( self.YSQLSH_CERT_DIR))
def generate_client_cert(self, extra_vars, ssh_options): remote_shell = RemoteShell(ssh_options) if "rootCA_cert" in extra_vars: root_cert_path = extra_vars["rootCA_cert"] root_key_path = extra_vars["rootCA_key"] certs_node_dir = extra_vars["certs_node_dir"] self.__generate_client_cert(extra_vars, ssh_options, root_cert_path, root_key_path, certs_node_dir, remote_shell) if "clientRootCA_cert" in extra_vars: root_cert_path = extra_vars["clientRootCA_cert"] root_key_path = extra_vars["clientRootCA_key"] certs_client_dir = extra_vars["certs_client_dir"] self.__generate_client_cert(extra_vars, ssh_options, root_cert_path, root_key_path, certs_client_dir, remote_shell) if "client_cert" in extra_vars: if "rootCA_cert" in extra_vars: root_cert_path = extra_vars["rootCA_cert"] else: root_cert_path = extra_vars["clientRootCA_cert"] client_cert_path = extra_vars["client_cert"] client_key_path = extra_vars["client_key"] remote_shell.run_command('mkdir -p ' + self.YSQLSH_CERT_DIR) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format( self.YSQLSH_CERT_DIR)) remote_shell.put_file( root_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_ROOT_NAME)) remote_shell.put_file( client_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME)) remote_shell.put_file( client_key_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME)) remote_shell.run_command('chmod 400 {}/*'.format( self.YSQLSH_CERT_DIR))
def copy_xcluster_root_cert(self, ssh_options, root_cert_path, replication_config_name, producer_certs_dir): if producer_certs_dir is None: producer_certs_dir = self.PRODUCER_CERTS_DIR_NAME remote_shell = RemoteShell(ssh_options) node_ip = ssh_options["ssh_host"] src_root_cert_dir_path = os.path.join(producer_certs_dir, replication_config_name) src_root_cert_path = os.path.join(src_root_cert_dir_path, self.ROOT_CERT_NAME) logging.info("Moving server cert located at {} to {}:{}.".format( root_cert_path, node_ip, src_root_cert_dir_path)) remote_shell.run_command('mkdir -p ' + src_root_cert_dir_path) # Give write permissions. If the command fails, ignore. remote_shell.run_command( 'chmod -f 666 {}/* || true'.format(src_root_cert_dir_path)) remote_shell.put_file(root_cert_path, src_root_cert_path) # Reset the write permission as a sanity check. remote_shell.run_command( 'chmod 400 {}/*'.format(src_root_cert_dir_path))
def copy_server_certs(self, extra_vars, ssh_options): remote_shell = RemoteShell(ssh_options) root_cert_path = extra_vars["server_root_cert"] node_cert_path = extra_vars["server_node_cert"] node_key_path = extra_vars["server_node_key"] certs_dir = extra_vars["certs_client_dir"] node_ip = ssh_options["ssh_host"] logging.info("Copying server certs located at {}, {}, {}.".format( root_cert_path, node_cert_path, node_key_path)) key_file = 'node.{}.key'.format(node_ip) cert_file = 'node.{}.crt'.format(node_ip) remote_shell.run_command('mkdir -p ' + certs_dir) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format(certs_dir)) remote_shell.put_file(root_cert_path, os.path.join(certs_dir, self.ROOT_CERT_NAME)) remote_shell.put_file(node_cert_path, os.path.join(certs_dir, cert_file)) remote_shell.put_file(node_key_path, os.path.join(certs_dir, key_file)) remote_shell.run_command('chmod 400 {}/*'.format(certs_dir))
def generate_client_cert(self, extra_vars, ssh_options): node_ip = ssh_options["ssh_host"] root_cert_path = extra_vars["rootCA_cert"] root_key_path = extra_vars["rootCA_key"] certs_node_dir = extra_vars["certs_node_dir"] with open(root_cert_path, 'r') as cert_in: certlines = cert_in.read() root_cert = x509.load_pem_x509_certificate(certlines, default_backend()) with open(root_key_path, 'r') as key_in: keylines = key_in.read() root_key = load_pem_private_key(keylines, None, default_backend()) private_key = rsa.generate_private_key( public_exponent=self.PUBLIC_EXPONENT, key_size=self.KEY_SIZE, backend=default_backend() ) public_key = private_key.public_key() builder = x509.CertificateBuilder() builder = builder.subject_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, six.text_type(node_ip)), x509.NameAttribute(NameOID.ORGANIZATION_NAME, six.text_type(extra_vars["org_name"])) ])) builder = builder.issuer_name(root_cert.subject) builder = builder.not_valid_before(datetime.datetime.utcnow()) builder = builder.not_valid_after(datetime.datetime.utcnow() + datetime.timedelta( extra_vars["cert_valid_duration"])) builder = builder.serial_number(x509.random_serial_number()) builder = builder.public_key(public_key) builder = builder.add_extension(x509.BasicConstraints(ca=False, path_length=None), critical=True) certificate = builder.sign(private_key=root_key, algorithm=hashes.SHA256(), backend=default_backend()) # Write private key to file pem = private_key.private_bytes( encoding=Encoding.PEM, format=PrivateFormat.TraditionalOpenSSL, encryption_algorithm=NoEncryption() ) key_file = 'node.{}.key'.format(node_ip) cert_file = 'node.{}.crt'.format(node_ip) common_path = '{}/{}'.format(self.CERTS_TEMP_DIR, node_ip) try: os.makedirs(common_path) except OSError as exc: # Guard against race condition if exc.errno != errno.EEXIST: raise YBOpsRuntimeError(common_path + " could not be be created") with open(os.path.join(common_path, key_file), 'wb') as pem_out: pem_out.write(pem) # Write certificate to file pem = certificate.public_bytes(encoding=Encoding.PEM) with open(os.path.join(common_path, cert_file), 'wb') as pem_out: pem_out.write(pem) # Copy files over to node remote_shell = RemoteShell(ssh_options) remote_shell.run_command('mkdir -p ' + certs_node_dir) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format(certs_node_dir)) remote_shell.put_file(os.path.join(common_path, key_file), os.path.join(certs_node_dir, key_file)) remote_shell.put_file(os.path.join(common_path, cert_file), os.path.join(certs_node_dir, cert_file)) remote_shell.put_file(root_cert_path, os.path.join(certs_node_dir, self.ROOT_CERT_NAME)) remote_shell.run_command('chmod 400 {}/*'.format(certs_node_dir)) if "client_cert" in extra_vars: client_cert_path = extra_vars["client_cert"] client_key_path = extra_vars["client_key"] remote_shell.run_command('mkdir -p ' + self.YSQLSH_CERT_DIR) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format(self.YSQLSH_CERT_DIR)) remote_shell.put_file(root_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_ROOT_NAME)) remote_shell.put_file(client_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME)) remote_shell.put_file(client_key_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME)) remote_shell.run_command('chmod 400 {}/*'.format(self.YSQLSH_CERT_DIR)) try: shutil.rmtree(common_path) except OSError as e: raise YBOpsRuntimeError("Error: %s - %s." % (e.filename, e.strerror))
def copy_certs(self, extra_vars, ssh_options): node_ip = ssh_options["ssh_host"] root_cert_path = extra_vars["root_cert_path"] node_cert_path = extra_vars["node_cert_path"] node_key_path = extra_vars["node_key_path"] certs_node_dir = extra_vars["certs_node_dir"] logging.info("Moving certs located at {}, {}, {}.".format(root_cert_path, node_cert_path, node_key_path)) key_file = 'node.{}.key'.format(node_ip) cert_file = 'node.{}.crt'.format(node_ip) remote_shell = RemoteShell(ssh_options) remote_shell.run_command('mkdir -p ' + certs_node_dir) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format(certs_node_dir)) remote_shell.run_command('cp {} {}'.format(root_cert_path, os.path.join(certs_node_dir, self.ROOT_CERT_NAME))) remote_shell.run_command('cp {} {}'.format(node_cert_path, os.path.join(certs_node_dir, cert_file))) remote_shell.run_command('cp {} {}'.format(node_key_path, os.path.join(certs_node_dir, key_file))) remote_shell.run_command('chmod 400 {}/*'.format(certs_node_dir)) if "client_cert_path" in extra_vars: client_cert_path = extra_vars["client_cert_path"] client_key_path = extra_vars["client_key_path"] logging.info("Moving client certs located at {}, {}.".format(client_cert_path, client_key_path)) remote_shell.run_command('mkdir -p ' + self.YSQLSH_CERT_DIR) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format(self.YSQLSH_CERT_DIR)) remote_shell.run_command('cp {} {}'.format(client_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME))) remote_shell.run_command('cp {} {}'.format(client_key_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME))) remote_shell.run_command('chmod 400 {}/*'.format(self.YSQLSH_CERT_DIR))
def initYSQL(self, master_addresses, ssh_options): remote_shell = RemoteShell(ssh_options) remote_shell.run_command( "bash -c \"YB_ENABLED_IN_POSTGRES=1 FLAGS_pggate_master_addresses={} " "/home/yugabyte/tserver/postgres/bin/initdb -D /tmp/yb_pg_initdb_tmp_data_dir " "-U postgres\"".format(master_addresses))
def copy_server_certs(self, ssh_options, root_cert_path, server_cert_path, server_key_path, certs_location, certs_dir): remote_shell = RemoteShell(ssh_options) node_ip = ssh_options["ssh_host"] logging.info("Moving server certs located at {}, {}, {}.".format( root_cert_path, server_cert_path, server_key_path)) cert_file = 'node.{}.crt'.format(node_ip) key_file = 'node.{}.key'.format(node_ip) remote_shell.run_command('mkdir -p ' + certs_dir) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format(certs_dir)) if certs_location == self.CERT_LOCATION_NODE: self.verify_certs(root_cert_path, server_cert_path, ssh_options, verify_hostname=True) remote_shell.run_command('cp {} {}'.format( root_cert_path, os.path.join(certs_dir, self.ROOT_CERT_NAME))) remote_shell.run_command('cp {} {}'.format( server_cert_path, os.path.join(certs_dir, cert_file))) remote_shell.run_command('cp {} {}'.format( server_key_path, os.path.join(certs_dir, key_file))) if certs_location == self.CERT_LOCATION_PLATFORM: remote_shell.put_file(root_cert_path, os.path.join(certs_dir, self.ROOT_CERT_NAME)) remote_shell.put_file(server_cert_path, os.path.join(certs_dir, cert_file)) remote_shell.put_file(server_key_path, os.path.join(certs_dir, key_file)) # Reset the write permission as a sanity check. remote_shell.run_command('chmod 400 {}/*'.format(certs_dir))
def copy_client_certs(self, ssh_options, root_cert_path, client_cert_path, client_key_path, certs_location): remote_shell = RemoteShell(ssh_options) yb_root_cert_path = os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_ROOT_NAME) yb_client_cert_path = os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME) yb_client_key_path = os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME) logging.info("Moving client certs located at {}, {}, {}.".format( root_cert_path, client_cert_path, client_key_path)) remote_shell.run_command('mkdir -p ' + self.YSQLSH_CERT_DIR) # Give write permissions. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format( self.YSQLSH_CERT_DIR)) if certs_location == self.CERT_LOCATION_NODE: remote_shell.run_command("cp '{}' '{}'".format( root_cert_path, yb_root_cert_path)) remote_shell.run_command("cp '{}' '{}'".format( client_cert_path, yb_client_cert_path)) remote_shell.run_command("cp '{}' '{}'".format( client_key_path, yb_client_key_path)) if certs_location == self.CERT_LOCATION_PLATFORM: remote_shell.put_file(root_cert_path, yb_root_cert_path) remote_shell.put_file(client_cert_path, yb_client_cert_path) remote_shell.put_file(client_key_path, yb_client_key_path) # Reset the write permission as a sanity check. remote_shell.run_command('chmod 400 {}/*'.format(self.YSQLSH_CERT_DIR))
def copy_client_certs(self, ssh_options, root_cert_path, client_cert_path, client_key_path, certs_location): remote_shell = RemoteShell(ssh_options) node_ip = ssh_options["ssh_host"] logging.info("Moving client certs located at {}, {}, {}.".format( root_cert_path, client_cert_path, client_key_path)) cert_file = 'node.{}.crt'.format(node_ip) key_file = 'node.{}.key'.format(node_ip) remote_shell.run_command('mkdir -p ' + self.YSQLSH_CERT_DIR) # Give write permission in case file exists. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format( self.YSQLSH_CERT_DIR)) if certs_location == self.CERT_LOCATION_NODE: remote_shell.run_command('cp {} {}'.format( root_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.ROOT_CERT_NAME))) remote_shell.run_command('cp {} {}'.format( client_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME))) remote_shell.run_command('cp {} {}'.format( client_key_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME))) if certs_location == self.CERT_LOCATION_PLATFORM: remote_shell.put_file( root_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_ROOT_NAME)) remote_shell.put_file( client_cert_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_CERT_NAME)) remote_shell.put_file( client_key_path, os.path.join(self.YSQLSH_CERT_DIR, self.CLIENT_KEY_NAME)) remote_shell.run_command('chmod 400 {}/*'.format(self.YSQLSH_CERT_DIR))
def copy_server_certs(self, ssh_options, root_cert_path, server_cert_path, server_key_path, certs_location, certs_dir, rotate_certs, skip_cert_validation): remote_shell = RemoteShell(ssh_options) node_ip = ssh_options["ssh_host"] cert_file = 'node.{}.crt'.format(node_ip) key_file = 'node.{}.key'.format(node_ip) yb_root_cert_path = os.path.join(certs_dir, self.ROOT_CERT_NAME) yb_server_cert_path = os.path.join(certs_dir, cert_file) yb_server_key_path = os.path.join(certs_dir, key_file) copy_root = True if rotate_certs: root_cert_command = remote_shell.run_command_raw( "cat '{}'".format(yb_root_cert_path)) # In case of tls toggle root cert might not be present if not root_cert_command.exited: root_cert = root_cert_command.stdout root_cert_new = None if certs_location == self.CERT_LOCATION_NODE: root_cert_new = remote_shell.run_command( "cat '{}'".format(root_cert_path)).stdout if certs_location == self.CERT_LOCATION_PLATFORM: with open(root_cert_path) as file: root_cert_new = file.read() if root_cert is not None and root_cert_new is not None: compare_result = self.compare_certs( root_cert_new, root_cert) if compare_result == 0 or compare_result == 1: # Don't copy root certs if the new root cert is # same or subset of the existing root cert copy_root = False else: raise YBOpsRuntimeError( "Unable to fetch the certificate {}".format( root_cert_path)) logging.info("Moving server certs located at {}, {}, {}.".format( root_cert_path, server_cert_path, server_key_path)) remote_shell.run_command('mkdir -p ' + certs_dir) # Give write permissions. If the command fails, ignore. remote_shell.run_command('chmod -f 666 {}/* || true'.format(certs_dir)) if certs_location == self.CERT_LOCATION_NODE: if skip_cert_validation == 'ALL': logging.info( "Skipping all validations for certs for node {}".format( node_ip)) else: verify_hostname = True if skip_cert_validation == 'HOSTNAME': logging.info( "Skipping host name validation for certs for node {}". format(node_ip)) verify_hostname = False self.verify_certs(root_cert_path, server_cert_path, ssh_options, verify_hostname) if copy_root: remote_shell.run_command("cp '{}' '{}'".format( root_cert_path, yb_root_cert_path)) remote_shell.run_command("cp '{}' '{}'".format( server_cert_path, yb_server_cert_path)) remote_shell.run_command("cp '{}' '{}'".format( server_key_path, yb_server_key_path)) if certs_location == self.CERT_LOCATION_PLATFORM: if copy_root: remote_shell.put_file(root_cert_path, yb_root_cert_path) remote_shell.put_file(server_cert_path, yb_server_cert_path) remote_shell.put_file(server_key_path, yb_server_key_path) # Reset the write permission as a sanity check. remote_shell.run_command('chmod 400 {}/*'.format(certs_dir))