예제 #1
0
class Crypto(object):
    def __init__(self):
        self.db = Database(config.mongodb_uri, config.database_name)
        self.db.set_collection("Cryptography")
        self.secret = self.__get_secret()

    def __del__(self):
        try:
            self.db.client.close()
        except Exception:
            pass

    def __find_secret_from_db(self):
        query = {"secret_key": {"$exists": 1}}
        secrets = self.db.find(query)
        temp = []
        for secret in secrets:
            if len(secret) == 2:
                temp.append(secret)

        if len(temp) > 1:
            raise RuntimeError("There is more than one secret in the DB")
        elif len(temp) == 1:
            return temp[0]["secret_key"]
        else:
            return None

    def __gen_secret(self):
        existing_secret = self.__find_secret_from_db()
        if existing_secret is not None:
            return existing_secret

        secret = Fernet.generate_key()
        self.db.insert({"secret_key": secret})
        return secret

    def __get_secret(self):
        existing_secret = self.__find_secret_from_db()
        if existing_secret is not None:
            return existing_secret

        return self.__gen_secret()

    def encrypt(self, data: str):
        fernet = Fernet(self.secret)
        return fernet.encrypt(data.encode())

    def decrypt(self, data: str):
        fernet = Fernet(self.secret)
        return fernet.decrypt(data).decode()
예제 #2
0
class Credential(object):
    def __init__(self):
        self.db = Database(config.mongodb_uri, config.database_name)
        self.db.set_collection("credential")

    def __del__(self):
        try:
            self.db.client.close()
        except Exception:
            pass

    def get_all_credentials(self) -> dict:
        credentials = self.db.find_all({"_id": 1, "name": 1, "username": 1})
        for cred in credentials:
            # convert ObjectId to string
            cred["_id"] = str(cred["_id"])
        credentials = {"credentials": credentials}
        return credentials

    def create_credential(self, data: dict) -> bool:
        # check if i have all the data i need
        required_key = ["name", "username", "password"]
        for key in required_key:
            if key not in data:
                raise ValueError("credential need name, username and password")

        # check if name exist in db
        exist_data = self.db.find({"name": data["name"]})
        if len(exist_data) > 0:
            raise ValueError("Same name for credential already exist in DB")

        # encrypt the password
        crypto_tool = Crypto()
        data["password"] = crypto_tool.encrypt(data["password"])
        return self.db.insert(data)

    def get_one_credential_with_password(self, id) -> dict:
        crypto_tool = Crypto()
        credential = self.db.find_by_id(id)
        if credential is None:
            raise ValueError("not able to find credential from db")
        credential["password"] = crypto_tool.decrypt(credential["password"])
        return credential
예제 #3
0
class Resource(object):
    def __init__(self):
        self.db = Database(config.mongodb_uri, config.database_name)
        self.db.set_collection("resource")

    def __del__(self):
        try:
            self.db.client.close()
        except Exception:
            pass

    def discover_new_node(self, node: dict) -> bool:
        # check if i have all the data i need
        required_key = ["address", "cred_id"]
        for key in required_key:
            if key not in node:
                raise ValueError("discover new node require address and credential id")
        
        # get credential detail from DB
        cred_tool = Credential()
        cred = cred_tool.get_one_credential_with_password(node["cred_id"])

        # initiate ssh connection
        ssh = SSHClient(node["address"], cred["username"], cred["password"])

        # check if user have sudo privilege
        if not ssh.check_sudo_privilege():
            raise RuntimeError("User don't have sudo previlege")

        # check Linux distro
        distro = ssh.command("cat /etc/os-release")
        distro = util.convert_to_dict.config_to_dict(distro)
        try:
            if distro["ID"] != "centos":
                raise RuntimeError("Only support CentOS 7")
            if int(distro["VERSION_ID"]) != 7:
                raise RuntimeError("Only support CentOS 7")
        except KeyError as err:
            logging.exception("cannot verify the linux distro : {}".format(distro))
            raise RuntimeError("Only support CentOS 7")

        # get disk list in dict
        disk_list = util.inventory.get_disk_list(ssh)

        # check if address exist in db
        exist_data = self.db.find({"address": node["address"]})
        if len(exist_data) > 0:
            raise ValueError("node is already discovered")

        # write node infomation to DB
        return self.db.insert({
            "address" : node["address"],
            "cred_id" : node["cred_id"],
            "distro" : distro["ID"],
            "version" : int(distro["VERSION_ID"]),
            "name" : distro["PRETTY_NAME"] if "PRETTY_NAME" in distro else distro["ID"] + " " + distro["VERSION_ID"],
            "disks": disk_list
        })
    
    def get_all_nodes(self):
        nodes = self.db.find_all()
        for node in nodes:
            # convert ObjectId to string
            node["_id"] = str(node["_id"])
        nodes = {"nodes" : nodes}
        return nodes

    def delete_one_node(self, node_id):
        # check if i have all the data i need
        required_key = ["id"]
        for key in required_key:
            if key not in node_id:
                raise ValueError("delete node requires id")

        #TODO
        # Need to add check if node is in use for cluster. if yes do not delete
        
        self.db.delete(node_id["id"])