Esempio n. 1
0
    def read_ldap_credentials(self):
        """Read ldap credentials (rootdn, sgiam) from the openldap_config file."""
        try:
            # Load the openldap config file
            index_id = 'openldap_config_file_read_index'
            Conf.load(index_id, f'yaml://{self.openldap_config_file}')

            # Read the cluster id from openldap_config file
            self.cluster_id = Conf.get(index_id, f'{self.cluster_id_key}')

            cipher_key = Cipher.generate_key(
                self.cluster_id,
                self.get_confkey('CONFSTORE_OPENLDAP_CONST_KEY'))

            # rootdn username/password
            self.ldap_root_user = Conf.get(index_id, f'{self.rootdn_user_key}')
            encrypted_rootdn_pass = Conf.get(index_id,
                                             f'{self.rootdn_pass_key}')
            if encrypted_rootdn_pass != None:
                self.rootdn_passwd = Cipher.decrypt(
                    cipher_key, bytes(str(encrypted_rootdn_pass), 'utf-8'))

        except Exception as e:
            Log.error(f'read ldap credentials failed, error: {e}')
            raise e
Esempio n. 2
0
def decrypt(key, text, caller=None):
    '''Decrypt the <text>'''
    decrypt_text = text
    try:
        decrypt_text = Cipher.decrypt(key, text.encode("utf-8"))
    except CipherInvalidToken as e:
        logger.error("{0}:Password decryption failed requested by {1}.".format(e, caller))
    return decrypt_text.decode("utf-8")
 def test_stonith_ok(self):
     """Check Stonith configuration."""
     for node in self.node_list:
         bmc_ip = self.bmc_data[node]['ip']
         bmc_user = self.bmc_data[node]['user']
         secret = self.bmc_data[node]['secret']
         key = Cipher.generate_key(self.cluster_id, 'cluster')
         bmc_passwd = Cipher.decrypt(key, secret.encode('ascii')).decode()
         BmcV().validate('stonith', [node, bmc_ip, bmc_user, bmc_passwd])
def decrypt(key, text):
    '''Decrypt the <text>'''
    decrypt_text = text
    try:
        decrypt_text = Cipher.decrypt(key, text).decode()
        return decrypt_text
    except CipherInvalidToken as e:
        print("Password decryption failed requested by %s" % SECTION)
        return decrypt_text.decode()
 def test_accessibility_ok(self):
     """Check BMC accessibility for nodes in cluster."""
     for node in self.node_list:
         bmc_ip = self.bmc_data[node]['ip']
         bmc_user = self.bmc_data[node]['user']
         secret = self.bmc_data[node]['secret']
         key = Cipher.generate_key(self.cluster_id, 'cluster')
         bmc_passwd = Cipher.decrypt(key, secret.encode('ascii')).decode()
         BmcV().validate('accessible', [node, bmc_ip, bmc_user, bmc_passwd])
 def test_accessibility_error_on_invalid_bmc_ip(self):
     """Check 'accessible' validation type for fake bmc_ip argument."""
     node = self.node_list[0]
     bmc_ip = "10.256.256.10"
     user = self.bmc_data[node]['user']
     secret = self.bmc_data[node]['secret']
     key = Cipher.generate_key(self.cluster_id, 'cluster')
     passwd = Cipher.decrypt(key, secret.encode('ascii')).decode()
     self.assertRaises(VError,
                       BmcV().validate, 'accessible',
                       [node, bmc_ip, user, passwd])
Esempio n. 7
0
    async def get(self, name: str) -> bytes:
        """
        Gets bytes from the encrypted storage.

        Acquires the data from the storage and decrypts it with the default CORTX cipher
        Raises CipherInvalidToken if decryption fails.
        """
        neb = await self._get_item(name)
        if neb is None:
            return None

        decrypted_bytes = Cipher.decrypt(self._key, neb.data.encode('ascii'))
        return decrypted_bytes
Esempio n. 8
0
def decrypt(component, secret):
    """ Decrypt secret.

    Args:
      secret: Secret to be decrypted.
    """
    retval = None
    cluster_id = __grains__['cluster_id']
    cipher_key = Cipher.generate_key(cluster_id, component)

    if secret:
        retval = (Cipher.decrypt(cipher_key,
                                 secret.encode("utf-8"))).decode("utf-8")

    return retval
Esempio n. 9
0
    def decrypt_passwd(self, encr_pass):
        """Returns decrypted password"""

        _component = "storage"
        try:
            cipher_key = Cipher.generate_key(enc_id_on_node, _component)
            return (
                Cipher.decrypt(
                    cipher_key, encr_pass.encode("utf-8")
                )
            ).decode("utf-8")
        except Exception as exc:
            self.logger.error(
                "Could not decrypt the password stored in the configuration\n"
            )
            raise exc
Esempio n. 10
0
def decrypt(component, secret):
    """ Decrypt secret.

    Args:
      secret: Secret to be decrypted.
    """
    from cortx.utils.security.cipher import Cipher, CipherInvalidToken
    
    retval = None
    cluster_id = __grains__['cluster_id']
    cipher_key = Cipher.generate_key(cluster_id, component)

    if secret:
        retval = (Cipher.decrypt(cipher_key, secret.encode("utf-8"))).decode("utf-8")
      
    return retval
def test_bmc_config(args):
    """Check if BMC configuration are valid.

    Testing BMC config with ipmitool is possible only when ipmi over lan
    is configured(out-band setup). It is taken care by test_bmc_is_accessible.
    So, validation on bmc onfiguration with bmc ip, user and secret value
    through ssh is fine at this time.
    """
    bmc_ip = Conf.get(GLOBAL_CONF, BMC_IP_KEY)
    bmc_user = Conf.get(GLOBAL_CONF, BMC_USER_KEY)
    bmc_secret = Conf.get(GLOBAL_CONF, BMC_SECRET_KEY)
    bmc_key = Cipher.generate_key(MACHINE_ID, "server_node")
    bmc_passwd = Cipher.decrypt(bmc_key,
                                bmc_secret.encode("utf-8")).decode("utf-8")
    # check BMC ip, user, password are valid
    session = SSHChannel(bmc_ip, bmc_user, bmc_passwd)
    session.disconnect()
Esempio n. 12
0
def decrypt(component, secret):
    """Decrypt secret.

    Args:
      secret: Secret to be decrypted.
    """
    from cortx.utils.security.cipher import Cipher

    retval = None
    cluster_id = getattr(sys.modules[__name__], '__grains__')['cluster_id']
    cipher_key = Cipher.generate_key(cluster_id, component)

    if secret:
        retval = (Cipher.decrypt(cipher_key,
                                 secret.encode("utf-8"))).decode("utf-8")

    return retval
def test_bmc_is_accessible(args):
    """Check if BMC is accessible through KCS or LAN."""
    channel_interface = Conf.get(SSPL_CONF, "BMC_INTERFACE>default", 'system')

    if channel_interface == "system":
        # Check BMC is accessible through KCS
        cmd = "sudo ipmitool channel info"
        expected_channel = "KCS"
        channel_found = None
        res_op, res_err, res_rc = SimpleProcess(cmd).run()
        if res_rc == 0:
            res_op = res_op.decode()
            search_res = re.search(
                r"%s[\s]+:[\s]+(\w+)(.*)" % CHANNEL_PROTOCOL, res_op)
            if search_res:
                channel_found = search_res.groups()[0]
            if expected_channel != channel_found:
                print("UNEXPECTED BMC CHANNEL TYPE FOUND.")
                print("Expected: %s" % expected_channel)
                print("Found: %s" % channel_found)
        else:
            res_err = res_err.decode()
            kcs_errors = ("could not find inband device", "driver timeout")
            if not any(err for err in kcs_errors if err in res_err):
                raise Exception(
                    "BMC is NOT accessible through KCS - ERROR: %s" % res_err)
    elif channel_interface == "lan":
        # Check BMC is accessible through LAN
        subcommand = "channel info"
        bmc_ip = Conf.get(GLOBAL_CONF, BMC_IP_KEY)
        bmc_user = Conf.get(GLOBAL_CONF, BMC_USER_KEY)
        bmc_secret = Conf.get(GLOBAL_CONF, BMC_SECRET_KEY)
        bmc_key = Cipher.generate_key(MACHINE_ID, "server_node")
        bmc_passwd = Cipher.decrypt(bmc_key,
                                    bmc_secret.encode("utf-8")).decode("utf-8")
        cmd = "sudo ipmitool -H %s -U %s -P %s -I lan %s" % (
            bmc_ip, bmc_user, bmc_passwd, subcommand)
        res_op, res_err, res_rc = SimpleProcess(cmd).run()
        if res_rc != 0:
            raise Exception("BMC is NOT accessible over lan - ERROR: %s" %
                            res_err.decode())
Esempio n. 14
0
    def validate(self):
        """Check below requirements.

        1. Validate input configs
        2. Validate BMC connectivity
        3. Validate storage controller connectivity
        4. Validate network interface availability
        """
        machine_id = Utility.get_machine_id()
        mgmt_interfaces = []
        data_private_interfaces = []
        data_public_interfaces = []

        # Validate input/provisioner configs
        node_type = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX, "server_node>%s>type" % machine_id)
        cluster_id = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX, "server_node>%s>cluster_id" % machine_id)
        if node_type.lower() not in ["virtual", "vm"]:
            bmc_ip = Utility.get_config_value(
                PRVSNR_CONFIG_INDEX, "server_node>%s>bmc>ip" % machine_id)
            bmc_user = Utility.get_config_value(
                PRVSNR_CONFIG_INDEX, "server_node>%s>bmc>user" % machine_id)
            bmc_secret = Utility.get_config_value(
                PRVSNR_CONFIG_INDEX, "server_node>%s>bmc>secret" % machine_id)
            bmc_key = Cipher.generate_key(machine_id,
                                          ServiceTypes.SERVER_NODE.value)
            bmc_passwd = Cipher.decrypt(
                bmc_key, bmc_secret.encode("utf-8")).decode("utf-8")
            data_private_interfaces = Utility.get_config_value(
                PRVSNR_CONFIG_INDEX,
                "server_node>%s>network>data>private_interfaces" % machine_id)
            data_public_interfaces = Utility.get_config_value(
                PRVSNR_CONFIG_INDEX,
                "server_node>%s>network>data>public_interfaces" % machine_id)
        mgmt_public_fqdn = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "server_node>%s>network>management>public_fqdn" % machine_id)
        mgmt_interfaces = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "server_node>%s>network>management>interfaces" % machine_id)
        data_private_fqdn = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "server_node>%s>network>data>private_fqdn" % machine_id)
        data_public_fqdn = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "server_node>%s>network>data>public_fqdn" % machine_id)
        enclosure_id = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "server_node>%s>storage>enclosure_id" % machine_id)
        primary_ip = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "storage_enclosure>%s>controller>primary>ip" % enclosure_id)
        secondary_ip = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "storage_enclosure>%s>controller>secondary>ip" % enclosure_id)
        cntrlr_user = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "storage_enclosure>%s>controller>user" % enclosure_id)
        cntrlr_secret = Utility.get_config_value(
            PRVSNR_CONFIG_INDEX,
            "storage_enclosure>%s>controller>secret" % enclosure_id)
        cntrlr_key = Cipher.generate_key(enclosure_id,
                                         ServiceTypes.STORAGE_ENCLOSURE.value)
        cntrlr_passwd = Cipher.decrypt(
            cntrlr_key, cntrlr_secret.encode("utf-8")).decode("utf-8")

        # Validate BMC connectivity & storage controller accessibility
        if node_type.lower() not in ["virtual", "vm"]:
            NetworkV().validate("connectivity",
                                [bmc_ip, primary_ip, secondary_ip])
            BmcV().validate("accessible",
                            [socket.getfqdn(), bmc_ip, bmc_user, bmc_passwd])
            c_validator = ControllerV()
            c_validator.validate("accessible",
                                 [primary_ip, cntrlr_user, cntrlr_passwd])
            c_validator.validate("accessible",
                                 [secondary_ip, cntrlr_user, cntrlr_passwd])

        # Validate network fqdn reachability
        NetworkV().validate(
            "connectivity",
            [mgmt_public_fqdn, data_private_fqdn, data_public_fqdn])

        # Validate network interface availability
        for i_list in [
                mgmt_interfaces, data_private_interfaces,
                data_public_interfaces
        ]:
            self.validate_nw_cable_connection(i_list)
            self.validate_nw_interfaces(i_list)
Esempio n. 15
0
def decrypt(key, text, caller=None):
    """Decrypt the <text>."""
    decrypt_text = Cipher.decrypt(key, text.encode("utf-8")).decode("utf-8")
    return decrypt_text
Esempio n. 16
0
 def decrypt(key: str, data: str):
     ddata = Cipher.decrypt(bytes(key, 'utf-8'), bytes(data, 'utf-8'))
     return ddata.decode("utf-8")
Esempio n. 17
0
    def process(self):
        """
        Process config command.
        """
        Log.info("Processing config command")
        # Read machine-id and using machine-id read minion name from confstore
        # This minion name will be used for adding the node to the cluster.
        nodelist = []
        command = "cat /etc/machine-id"
        machine_id, err, rc = self._execute.run_cmd(command, check_error=True)
        Log.info(f"Read machine-id. Output: {machine_id}, Err: {err}, RC: {rc}")
        minion_name = Conf.get(self._index, f"cluster.server_nodes.{machine_id.strip()}")
        nodelist.append(minion_name)
        # The config step will be called from primary node alwasys,
        # see how to get and use the node name then.

        # Read cluster name and cluster user
        cluster_name = Conf.get(self._index, 'corosync-pacemaker.cluster_name')
        cluster_user = Conf.get(self._index, 'corosync-pacemaker.user')

        # Read cluster user password and decrypt the same
        cluster_id = Conf.get(self._index, 'cluster.cluster_id')
        cluster_secret = Conf.get(self._index, 'corosync-pacemaker.secret')
        key = Cipher.generate_key(cluster_id, 'corosync-pacemaker')
        cluster_secret = Cipher.decrypt(key, cluster_secret.encode('ascii')).decode()

        # Get s3 instance count
        try:
            s3_instances = Conf.get(self._index, f"cluster.{minion_name}.s3_instances")
            if int(s3_instances) < 1:
                raise HaConfigException(f"Found {s3_instances} which is invalid s3 instance count.")
        except Exception as e:
            Log.error(f"Found {s3_instances} which is invalid s3 instance count. Error: {e}")
            raise HaConfigException(f"Found {s3_instances} which is invalid s3 instance count.")

        # Check if the cluster exists already, if yes skip creating the cluster.
        output, err, rc = self._execute.run_cmd(const.PCS_CLUSTER_STATUS, check_error=False)
        Log.info(f"Cluster status. Output: {output}, Err: {err}, RC: {rc}")
        if rc != 0:
            if(err.find("No such file or directory: 'pcs'") != -1):
                Log.error("Cluster config failed; pcs not installed")
                raise HaConfigException("Cluster config failed; pcs not installed")
            # If cluster is not created; create a cluster.
            elif(err.find("cluster is not currently running on this node") != -1):
                try:
                    Log.info(f"Creating cluster: {cluster_name} with node: {minion_name}")
                    cluster_auth(cluster_user, cluster_secret, nodelist)
                    cluster_create(cluster_name, nodelist)
                    Log.info(f"Created cluster: {cluster_name} successfully")
                    Log.info("Creating pacemaker resources")
                    create_all_resources(s3_instances=s3_instances)
                    Log.info("Created pacemaker resources successfully")
                except Exception as e:
                    Log.error(f"Cluster creation failed; destroying the cluster. Error: {e}")
                    output = self._execute.run_cmd(const.PCS_CLUSTER_DESTROY, check_error=True)
                    Log.info(f"Cluster destroyed. Output: {output}")
                    raise HaConfigException("Cluster creation failed")
            else:
                pass # Nothing to do
        else:
            # Cluster exists already, check if it is a new node and add it to the existing cluster.
             Log.info("The cluster exists already, check and add new node")
        Log.info("config command is successful")
Esempio n. 18
0
    def process(self):
        """
        Process config command.
        """
        Log.info("Processing config command")
        # Read machine-id and using machine-id read minion name from confstore
        # This minion name will be used for adding the node to the cluster.
        node_name: str = self.get_node_name()
        nodelist: list = self.get_nodelist(fetch_from=ConfigCmd.PROV_CONFSTORE)

        # Read cluster name and cluster user
        machine_id = self.get_machine_id()
        cluster_id = Conf.get(self._index,
                              f"server_node.{machine_id}.cluster_id")
        cluster_name = Conf.get(self._index, f"cluster.{cluster_id}.name")
        cluster_user = Conf.get(
            self._index, f"cortx.software.{const.HA_CLUSTER_SOFTWARE}.user")
        node_type = Conf.get(self._index,
                             f"server_node.{machine_id}.type").strip()

        # Read cluster user password and decrypt the same
        cluster_secret = Conf.get(
            self._index, f"cortx.software.{const.HA_CLUSTER_SOFTWARE}.secret")
        key = Cipher.generate_key(cluster_id, const.HACLUSTER_KEY)
        cluster_secret = Cipher.decrypt(
            key, cluster_secret.encode('ascii')).decode()
        mgmt_info: dict = self._get_mgmt_vip(machine_id, cluster_id)
        s3_instances = ConfigCmd.get_s3_instance(machine_id)

        self._update_env(node_name, node_type, const.HA_CLUSTER_SOFTWARE)
        self._fetch_fids()
        self._update_cluster_manager_config()

        # Update cluster and resources
        self._cluster_manager = CortxClusterManager(default_log_enable=False)
        Log.info("Checking if cluster exists already")
        cluster_exists = bool(
            json.loads(
                self._cluster_manager.cluster_controller.cluster_exists()).get(
                    "msg"))
        Log.info(f"Cluster exists? {cluster_exists}")

        if not cluster_exists:
            node_count: int = len(
                self.get_nodelist(fetch_from=ConfigCmd.HA_CONFSTORE))
            if node_count == 0:
                Log.info(
                    f"Creating cluster: {cluster_name} with node: {node_name}")
                # Create cluster
                try:
                    self._create_cluster(cluster_name, cluster_user,
                                         cluster_secret, node_name)
                    self._create_resource(s3_instances=s3_instances,
                                          mgmt_info=mgmt_info)
                    self._confstore.set(
                        f"{const.CLUSTER_CONFSTORE_NODES_KEY}/{node_name}")
                except Exception as e:
                    Log.error(
                        f"Cluster creation failed; destroying the cluster. Error: {e}"
                    )
                    output = self._execute.run_cmd(const.PCS_CLUSTER_DESTROY)
                    Log.error(f"Cluster destroyed. Output: {output}")
                    # Delete the node from nodelist if it was added in the store
                    if self._confstore.key_exists(
                            f"{const.CLUSTER_CONFSTORE_NODES_KEY}/{node_name}"
                    ):
                        self._confstore.delete(
                            f"{const.CLUSTER_CONFSTORE_NODES_KEY}/{node_name}")
                    raise HaConfigException("Cluster creation failed")
                # Add Other Node
                for node in nodelist:
                    if node != node_name:
                        Log.info(
                            f"Adding node {node} to Cluster {cluster_name}")
                        self._add_node(node, cluster_user, cluster_secret)
            else:
                # Add node with SSH
                self._add_node_remotely(node_name, cluster_user,
                                        cluster_secret)
        else:
            for node in nodelist:
                if node != node_name:
                    Log.info(f"Adding node {node} to Cluster {cluster_name}")
                    self._add_node(node, cluster_user, cluster_secret)
        self._execute.run_cmd(const.PCS_CLEANUP)
        Log.info("config command is successful")
def decrypt(key, text):
    ''' Decrypt the <text> '''
    return Cipher.decrypt(key, text.encode("utf-8")).decode("utf-8")
def decrypt(key, text):
    ''' Decrypt the <text> '''
    return Cipher.decrypt(key, text).decode()
Esempio n. 21
0
def decrypt(key, text, caller=None):
    """Decrypt the <text>."""
    decrypt_text = Cipher.decrypt(key, text).decode()
    return decrypt_text