Esempio n. 1
0
    def get_from_dir(cls, directory=None, store=True):
        directory = directory or Config.path_expand("~/.ssh")
        files = [file for file in os.listdir(expanduser(Config.path_expand(directory)))
                 if file.lower().endswith(".pub")]
        d = []
        for file in files:
            location = Config.path_expand("{:}/{:}".format(directory, file))

            sshkey = SSHkey(location).get()

            i = sshkey["comment"]
            if i is not None:
                i = i.replace("@", "_")
                i = i.replace("-", "_")
                i = i.replace(" ", "_")
                i = i.replace(".", "_")
            else:
                # use base name
                i = file.replace(".pub", "")
            sshkey["kind"] = "key"
            sshkey["source"] = 'file'

            if store:
                cls._add_from_sshkey(
                    dict(sshkey),
                    keyname=sshkey["name"],
                    source=sshkey["source"],
                    uri=sshkey["uri"])
            else:
                d.append(dict(sshkey))
        if not store:
            return d
Esempio n. 2
0
    def get_from_yaml(cls, filename=None, load_order=None, store=True):
        """
        :param filename: name of the yaml file
        :return: a SSHKeyManager (dict of keys)
        """
        config = None
        if filename is None:
            # default = Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.yaml"))
            # config = ConfigDict("cloudmesh.yaml")
            filename = "cloudmesh.yaml"
            config = ConfigDict(filename)
        elif load_order:
            config = ConfigDict(filename, load_order)
        else:
            Console.error("Wrong arguments")
            return
        config_keys = config["cloudmesh"]["keys"]
        default = config_keys["default"]
        keylist = config_keys["keylist"]

        uri = Config.path_expand(os.path.join("~", ".cloudmesh", filename))

        d = []
        for key in list(keylist.keys()):
            keyname = key
            value = keylist[key]
            if os.path.isfile(Config.path_expand(value)):
                path = Config.path_expand(value)
                if store:
                    Key.add_from_path(path, keyname)
                else:
                    d.append(Key.add_from_path(path, keyname, store=False))
            else:

                keytype, string, comment = SSHkey._parse(value)
                thekey = {
                    'uri': 'yaml://{}'.format(uri),
                    'string': value,
                    'fingerprint': SSHkey._fingerprint(value),
                    'name': keyname,
                    'comment': comment,
                    'source': 'git',
                    'kind': 'key'
                }

                thekey["type"], thekey["key"], thekey[
                    "comment"] = SSHkey._parse(value)

                if thekey["comment"] is None:
                    thekey["comment"] = keyname
                if store:
                    try:
                        cls.cm.add(thekey)
                    except:
                        Console.error("Key already in db", traceflag=False)
                else:
                    d.append(thekey)
        if not store:
            return d
        """
Esempio n. 3
0
    def get_from_dir(cls, directory=None, store=True):
        directory = directory or Config.path_expand("~/.ssh")
        files = [
            file
            for file in os.listdir(expanduser(Config.path_expand(directory)))
            if file.lower().endswith(".pub")
        ]
        d = []
        for file in files:
            location = Config.path_expand("{:}/{:}".format(directory, file))

            sshkey = SSHkey(location).get()

            i = sshkey["comment"]
            if i is not None:
                i = i.replace("@", "_")
                i = i.replace("-", "_")
                i = i.replace(" ", "_")
                i = i.replace(".", "_")
            else:
                # use base name
                i = file.replace(".pub", "")
            sshkey["kind"] = "key"
            sshkey["source"] = 'file'

            if store:
                cls._add_from_sshkey(dict(sshkey),
                                     keyname=sshkey["name"],
                                     source=sshkey["source"],
                                     uri=sshkey["uri"])
            else:
                d.append(dict(sshkey))
        if not store:
            return d
Esempio n. 4
0
    def get_from_dir(self, directory=None):
        directory = directory or Config.path_expand("~/.ssh")
        files = [file for file in os.listdir(expanduser(Config.path_expand(directory)))
                 if file.lower().endswith(".pub")]
        for file in files:
            location = Config.path_expand("{:}/{:}".format(directory, file))

            sshkey = SSHkey(location)
            i = sshkey.comment
            self.__keys__[i] = sshkey.__key__
Esempio n. 5
0
    def add_from_path(cls,
                      path,
                      keyname=None,
                      user=None,
                      source=None,
                      uri=None,
                      store=True):
        """
        Adds the key to the database based on the path

        :param keyname: name of the key or path to the key
        :return:
        """

        user = user or cls.cm.user

        sshkey = SSHkey(Config.path_expand(path))

        if store:
            cls._add_from_sshkey(sshkey.__key__,
                             keyname,
                             user,
                             source=source,
                             uri=uri)
        else:
            return sshkey.__key__
Esempio n. 6
0
    def get_hostname(cls, host):
        """
        Method to return hostname
        for a host in ssh config
        :param host:
        :return:
        """
        filename = Config.path_expand("~/.ssh/config")
        with open(filename, 'r') as f:
            lines = f.read().split("\n")

        found = False
        for line in lines:
            # search for host
            if "Host " in line:
                _host = line.strip().replace("Host ", "", 1).replace(" ", "")
                # if host found in ssh config
                if _host == host:
                    found = True
                    pass

            # search for hostname
            if "Hostname " in line and found is True:
                # return corresponding hostname
                hostname = line.strip().replace("Hostname ", "",
                                                1).replace(" ", "")
                return hostname
Esempio n. 7
0
    def read(self, file_path, keyname=None):
        self.__key__ = {}
        if file_path is not None:
            file_path = Config.path_expand(file_path)
            uri = 'file://{}'.format(file_path)
            self.__key__ = {
                'uri': uri,
                'string': open(file_path, "r").read().rstrip()
            }

            (self.__key__['type'],
             self.__key__['key'],
             self.__key__['comment']) = self._parse(self.__key__['string'])
            self.__key__['fingerprint'] = self._fingerprint(self.__key__['string'])

            # Workaround for multiple file entries in cloudmesh.yaml getting same name derived from file name (like id_rsa).
            # This caused the dict to have just 1 entry as the name is the key.
            # Change tracked in git issue #8
            if keyname is None:
                name = basename(file_path).replace(".pub", "").replace("id_", "")
            else:
                name = keyname

            self.__key__['name'] = name
            self.__key__['comment'] = self.__key__['comment']
            self.__key__['source'] = 'ssh'
        return self.__key__
Esempio n. 8
0
    def get_hostuser(cls, host):
        """
        Method to return user login
        for a host in ssh config
        :param host:
        :return:
        """
        filename = Config.path_expand("~/.ssh/config")
        with open(filename, 'r') as f:
            lines = f.read().split("\n")

        found = False
        for line in lines:
            # search for host
            if "Host " in line:
                _host = line.strip().replace("Host ", "", 1).replace(" ", "")
                # if host found in ssh config
                if _host == host:
                    found = True
                    pass

            # search for user
            if "User " in line and found is True:
                # return corresponding user
                username = line.strip().replace("User ", "", 1).replace(" ", "")
                return username
Esempio n. 9
0
    def add_from_path(cls,
                      path,
                      keyname=None,
                      user=None,
                      source=None,
                      uri=None,
                      store=True):
        """
        Adds the key to the database based on the path

        :param keyname: name of the key or path to the key
        :return:
        """

        user = user or cls.cm.user

        sshkey = SSHkey(Config.path_expand(path))

        if store:
            cls._add_from_sshkey(sshkey.__key__,
                                 keyname,
                                 user,
                                 source=source,
                                 uri=uri)
        else:
            return sshkey.__key__
Esempio n. 10
0
    def read(self, file_path, keyname=None):
        self.__key__ = {}
        if file_path is not None:
            orig_path = file_path
            file_path = Config.path_expand(file_path)
            uri = 'file://{}'.format(file_path)
            self.__key__ = {
                'uri': uri,
                'path': orig_path,
                'string': open(file_path, "r").read().rstrip()
            }

            (self.__key__['type'], self.__key__['key'],
             self.__key__['comment']) = self._parse(self.__key__['string'])
            self.__key__['fingerprint'] = self._fingerprint(
                self.__key__['string'])

            # Workaround for multiple file entries in cloudmesh.yaml getting same name derived from file name (like id_rsa).
            # This caused the dict to have just 1 entry as the name is the key.
            # Change tracked in git issue #8
            if keyname is None:
                name = basename(file_path).replace(".pub",
                                                   "").replace("id_", "")
            else:
                name = keyname

            self.__key__['name'] = name
            self.__key__['comment'] = self.__key__['comment']
            self.__key__['source'] = 'ssh'
        return self.__key__
Esempio n. 11
0
    def remote(cls, host, force=False):
        """

        TODO: there is a bug in the instalation of kilo the openrc file on
        the remote machine is not called openrc.sh but contains username and
        project number.

        :param host: the remote host
        :param force:
        :return:
        """

        config = ConfigDict("cloudmesh.yaml")

        host_spec = config["cloudmesh.clouds." + host]
        host_credentials = host_spec["credentials"]

        if 'cm_openrc' in host_spec:
            Console.ok("looking for openrc")
        else:
            Console.error("no cm_openrc specified in the host")
            return

        hostname = config["cloudmesh.clouds." + host + ".cm_host"]
        Console.ok("fetching information from {:}  ...".format(host))

        openrc = host_spec["cm_openrc"]

        directory = os.path.dirname(openrc)
        base = os.path.basename(openrc)

        _from_dir = "{:}:{:}".format(hostname, directory).replace("~/", "")
        _to_dir = os.path.dirname(Config.path_expand(directory))
        openrc_file = Config.path_expand(openrc)
        print("From:  ", _from_dir)
        print("To:    ", _to_dir)
        print("Openrc:", openrc_file)

        cls.make_dir(_to_dir)
        r = ""
        Console.ok("Reading rc file from {}".format(host))
        try:
            r = Shell.scp('-r', _from_dir, _to_dir)
        except Exception, e:
            print(e)
            return
    def initialize(self, cloudname, user=None):

        d = ConfigDict("cloudmesh.yaml")
        self.cloud_details = d["cloudmesh"]["clouds"][cloudname]

        # pprint(self.cloud_details)

        self.cloud = cloudname
        self.default_flavor = self.cloud_details["default"]["flavor"]
        self.default_image = self.cloud_details["default"]["image"]
        self.tenant = self.cloud_details['credentials']['OS_TENANT_NAME']
        version = 2
        credentials = self.cloud_details["credentials"]
        cert = False
        if "OS_CACERT" in credentials:
            if credentials["OS_CACERT"] is not False:
                cert = Config.path_expand(credentials["OS_CACERT"])
        auth_url = credentials["OS_AUTH_URL"]
        ksversion = auth_url.split("/")[-1]

        """
        # GitHub issue 101
        # mechanism to interactively ask for password
        # when OS_PASSWORD set as "readline",
        # or read os.environ if set as "env".
        """
        os_password = credentials["OS_PASSWORD"]
        prompt = "Password for cloud - {}:".format(cloudname)
        if os_password.lower() in ["readline", "read", "tbd"]:
            if cloudname in CloudProviderOpenstackAPI.cloud_pwd and \
                        'pwd' in CloudProviderOpenstackAPI.cloud_pwd[cloudname]:
                os_password = CloudProviderOpenstackAPI.cloud_pwd[cloudname]["pwd"]
            else:
                os_password = getpass.getpass(prompt=prompt)
        elif os_password.lower() == "env":
            if cloudname in CloudProviderOpenstackAPI.cloud_pwd and \
                        'pwd' in CloudProviderOpenstackAPI.cloud_pwd[cloudname]:
                os_password = CloudProviderOpenstackAPI.cloud_pwd[cloudname]["pwd"]
            else:
                os_password = os.environ.get("OS_PASSWORD", getpass.getpass(prompt=prompt))

        # store the password for this session
        CloudProviderOpenstackAPI.cloud_pwd[cloudname] = {}
        CloudProviderOpenstackAPI.cloud_pwd[cloudname]["pwd"] = os_password
        CloudProviderOpenstackAPI.cloud_pwd[cloudname]["status"] = "Active"

        if "v2.0" == ksversion:
            self.provider = client.Client(
                version,
                credentials["OS_USERNAME"],
                os_password,
                credentials["OS_TENANT_NAME"],
                credentials["OS_AUTH_URL"],
                cert)
        elif "v3" == ksversion:
            sess = session.Session(auth=self._ksv3_auth(credentials),
                                   verify=cert)
            self.provider = client.Client(2, session=sess)
    def __init__(self):
        self.__dict__ = self.__shared_state

        if self.initialized is None:
            self.filename = Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.db"))
            self.create()
            self.create_tables()
            self.start()
            self.user = ConfigDict(filename="cloudmesh.yaml")["cloudmesh.profile.user"]
Esempio n. 14
0
    def __init__(self):
        self.__dict__ = self.__shared_state

        if self.initialized is None:
            self.filename = Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.db"))
            self.create()
            self.create_tables()
            self.start()
            self.user = ConfigDict(filename="cloudmesh.yaml")["cloudmesh.profile.user"]
Esempio n. 15
0
    def sync(cls, cloudname, localdir, remotedir, operation=None):
        """
        Syncs a local directory with a remote directory.
        Either from local to remote OR vice-versa
        :param cloudname:
        :param localdir:
        :param remotedir:
        :param operation: get/put
        :return:
        """
        # Get the operating system
        os_type = cls.operating_system()

        # fix the local dir path
        localdirpath = Config.path_expand(localdir)

        # check if local directory exists
        if not os.path.exists(localdirpath):
            if operation == "put":
                Console.error("The local directory [{}] does not exist."
                              .format(localdirpath))
                return None
            elif operation == "get":
                # for receiving, create local dir
                os.mkdir(localdirpath)
                Console.msg("Created local directory [{}] for sync."
                            .format(localdirpath))

        """
            rsync now works on windows machines as well.
            we install rsync (v5.4.1.20150827) on windows via chocolatey
            $ choco install rsync
        """

        host = cls.get_host(cloudname)
        if host is None:
            Console.error("Cloud [{}] not found in cloudmesh.yaml file."
                          .format(cloudname))
            return None
        else:
            args = None
            if operation == "put":
                args = [
                    "-r",
                    localdir,
                    host + ":" + remotedir
                ]
            elif operation == "get":
                args = [
                    "-r",
                    host + ":" + remotedir,
                    localdir
                ]
            # call rsync
            return Shell.rsync(*args)
Esempio n. 16
0
 def set_os_environment(cls, cloudname):
     try:
         d = ConfigDict("cloudmesh.yaml")
         credentials = d["cloudmesh"]["clouds"][cloudname]["credentials"]
         for key in credentials.keys():
             if key == "OS_CACERT":
                 os.environ[key] = Config.path_expand(credentials[key])
             else:
                 os.environ[key] = credentials[key]
     except Exception, e:
         print(e)
Esempio n. 17
0
 def get_from_yaml(self, filename=None, load_order=None):
     """
     :param filename: name of the yaml file
     :return: a SSHKeyManager (dict of keys)
     """
     config = None
     if filename is None:
         # default = Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.yaml"))
         # config = ConfigDict("cloudmesh.yaml")
         filename = "cloudmesh.yaml"
         config = ConfigDict(filename)
     elif load_order:
         config = ConfigDict(filename, load_order)
     else:
         Console.error("Wrong arguments")
         return
     config_keys = config["cloudmesh"]["keys"]
     default = config_keys["default"]
     keylist = config_keys["keylist"]
     sshmanager = SSHKeyManager()
     for key in list(keylist.keys()):
         keyname = key
         value = keylist[key]
         if os.path.isfile(Config.path_expand(value)):
             path = Config.path_expand(value)
             sshmanager.add_from_file(path, keyname)
         else:
             sshkey = SSHkey()
             uri = Config.path_expand(os.path.join("~", ".cloudmesh", filename))
             sshkey.__key__['uri'] = 'yaml://{}'.format(uri)
             sshkey.__key__['string'] = value
             (sshkey.__key__['type'],
              sshkey.__key__['key'],
              sshkey.__key__['comment']) = sshkey._parse(sshkey.__key__['string'])
             sshkey.__key__['fingerprint'] = sshkey._fingerprint(sshkey.__key__['string'])
             sshkey.__key__['name'] = keyname
             sshkey.__key__['filename'] = filename
             sshmanager.add_from_object(sshkey)
     return sshmanager
     """
Esempio n. 18
0
    def set_os_environ(cls, cloudname):
        """Set os environment variables on a given cloudname"""
        try:
            d = ConfigDict("cloudmesh.yaml")
            credentials = d["cloudmesh"]["clouds"][cloudname]["credentials"]
            for key, value in credentials.iteritems():
                if key == "OS_CACERT":
                    os.environ[key] = Config.path_expand(value)
                else:
                    os.environ[key] = value

                print("Key: " + key + ", Value: " + os.environ[key])

            nova = client.Client("2",
                                 credentials["OS_USERNAME"],
                                 credentials["OS_PASSWORD"],
                                 credentials["OS_TENANT_NAME"],
                                 credentials["OS_AUTH_URL"],
                                 Config.path_expand(credentials["OS_CACERT"]))
            return nova
        except Exception, e:
            print(e)
Esempio n. 19
0
    def activate(self):
        """activates the shared variables"""

        # engine = create_engine('sqlite:////tmp/test.db', echo=debug)

        self.filename = Config.path_expand(
            os.path.join("~", ".cloudmesh", "cloudmesh.db"))
        self.endpoint = 'sqlite:///{:}'.format(self.filename)
        self.engine = create_engine(self.endpoint)
        self.Base = declarative_base(bind=self.engine)

        self.meta = MetaData()
        self.meta.reflect(bind=self.engine)
Esempio n. 20
0
    def activate(self):
        """activates the shared variables"""
        self.debug = False

        # engine = create_engine('sqlite:////tmp/test.db', echo=debug)

        self.filename = Config.path_expand("~/.cloudmesh/cloudmesh.db")
        self.endpoint = 'sqlite:///{:}'.format(self.filename)
        self.engine = create_engine(self.endpoint)
        self.Base = declarative_base(bind=self.engine)

        self.meta = MetaData()
        self.meta.reflect(bind=self.engine)
Esempio n. 21
0
def set_os_environ(cloudname):
    """Set os environment variables on a given cloudname"""
    # TODO: this has a severe bug as it is not unsetting variables
    # Also this coded duplicates in part from register
    try:
        d = ConfigDict("cloudmesh.yaml")
        credentials = d["cloudmesh"]["clouds"][cloudname]["credentials"]
        for key, value in list(credentials.items()):
            if key == "OS_CACERT":
                os.environ[key] = Config.path_expand(value)
            else:
                os.environ[key] = value
    except Exception as e:
        print(e)
def set_os_environ(cloudname):
    """Set os environment variables on a given cloudname"""
    # TODO: this has a severe bug as it is not unsetting variables
    # Also this coded duplicates in part from register
    try:
        d = ConfigDict("cloudmesh.yaml")
        credentials = d["cloudmesh"]["clouds"][cloudname]["credentials"]
        for key, value in credentials.iteritems():
            if key == "OS_CACERT":
                os.environ[key] = Config.path_expand(value)
            else:
                os.environ[key] = value
    except Exception as e:
        print(e)
Esempio n. 23
0
    def add(self, key_path, keyname=None, user=None, source=None, uri=None):
        """
        Adds the key to the database based on the path

        :param keyname: name of the key or path to the key
        :return:
        """

        sshkey = SSHkey(Config.path_expand(key_path))

        self.add_from_sshkey(sshkey.__key__,
                             keyname, user,
                             source=source,
                             uri=uri)
Esempio n. 24
0
    def add(self, key_path, keyname=None, user=None, source=None, uri=None):
        """
        Adds the key to the database based on the path

        :param keyname: name of the key or path to the key
        :return:
        """

        sshkey = SSHkey(Config.path_expand(key_path))

        self.add_from_sshkey(sshkey.__key__,
                             keyname,
                             user,
                             source=source,
                             uri=uri)
Esempio n. 25
0
    def sync(cls, cloudname, localdir, remotedir, operation=None):
        """
        Syncs a local directory with a remote directory.
        Either from local to remote OR vice-versa
        :param cloudname:
        :param localdir:
        :param remotedir:
        :param operation: get/put
        :return:
        """
        # Get the operating system
        os_type = cls.operating_system()

        # fix the local dir path
        localdirpath = Config.path_expand(localdir)

        # check if local directory exists
        if not os.path.exists(localdirpath):
            if operation == "put":
                Console.error(
                    "The local directory [{}] does not exist.".format(
                        localdirpath))
                return None
            elif operation == "get":
                # for receiving, create local dir
                os.mkdir(localdirpath)
                Console.msg("Created local directory [{}] for sync.".format(
                    localdirpath))
        """
            rsync now works on windows machines as well.
            we install rsync (v5.4.1.20150827) on windows via chocolatey
            $ choco install rsync
        """

        host = cls.get_host(cloudname)
        if host is None:
            Console.error(
                "Cloud [{}] not found in cloudmesh.yaml file.".format(
                    cloudname))
            return None
        else:
            args = None
            if operation == "put":
                args = ["-r", localdir, host + ":" + remotedir]
            elif operation == "get":
                args = ["-r", host + ":" + remotedir, localdir]
            # call rsync
            return Shell.rsync(*args)
Esempio n. 26
0
    def list_ssh(cls):
        """
        lists hosts from ~/.ssh/config

        :return:
        """
        filename = Config.path_expand("~/.ssh/config")
        with open(filename, 'r') as f:
            lines = f.read().split("\n")
        hosts = []
        for line in lines:
            if "Host " in line:
                host = line.strip().replace("Host ", "", 1).replace(" ", "")
                hosts.append(host)

        return hosts
Esempio n. 27
0
    def list_ssh(cls):
        """
        lists hosts from ~/.ssh/config

        :return:
        """
        filename = Config.path_expand("~/.ssh/config")
        with open(filename, 'r') as f:
            lines = f.read().split("\n")
        hosts = []
        for line in lines:
            if "Host " in line:
                host = line.strip().replace("Host ", "", 1).replace(" ", "")
                dhost = {"host": host}
                hosts.append(dhost)
        return hosts
    def initialize(self, cloudname, user=None):

        d = ConfigDict("cloudmesh.yaml")
        self.cloud_details = d["cloudmesh"]["clouds"][cloudname]

        # pprint(self.cloud_details)

        self.cloud = cloudname
        self.default_flavor = self.cloud_details["default"]["flavor"]
        self.default_image = self.cloud_details["default"]["image"]
        self.tenant = self.cloud_details['credentials']['OS_TENANT_NAME']
        version = 2
        credentials = self.cloud_details["credentials"]
        cert = False
        if "OS_CACERT" in credentials:
            if credentials["OS_CACERT"] is not False:
                cert = Config.path_expand(credentials["OS_CACERT"])
        auth_url = credentials["OS_AUTH_URL"]
        ksversion = auth_url.split("/")[-1]

        """
        # GitHub issue 101
        # mechanism to interactively ask for password
        # when OS_PASSWORD set as "readline",
        # or read os.environ if set as "env".
        """
        os_password = credentials["OS_PASSWORD"]
        if os_password.lower() == "readline":
            os_password = getpass.getpass()
        elif os_password.lower() == "env":
            os_password = os.environ.get("OS_PASSWORD", getpass.getpass())

        if "v2.0" == ksversion:
            self.provider = client.Client(
                version,
                credentials["OS_USERNAME"],
                os_password,
                credentials["OS_TENANT_NAME"],
                credentials["OS_AUTH_URL"],
                cert)
        elif "v3" == ksversion:
            sess = session.Session(auth=self._ksv3_auth(credentials),
                                   verify=cert)
            self.provider = client.Client(2, session=sess)
Esempio n. 29
0
    def initialize(self, cloudname, user=None):

        d = ConfigDict("cloudmesh.yaml")
        self.cloud_details = d["cloudmesh"]["clouds"][cloudname]

        # pprint(self.cloud_details)

        self.cloud = cloudname
        self.default_flavor = self.cloud_details["default"]["flavor"]
        self.default_image = self.cloud_details["default"]["image"]
        self.tenant = self.cloud_details['credentials']['OS_TENANT_NAME']
        version = 2
        credentials = self.cloud_details["credentials"]
        cert = False
        if "OS_CACERT" in credentials:
            if credentials["OS_CACERT"] is not False:
                cert = Config.path_expand(credentials["OS_CACERT"])
        auth_url = credentials["OS_AUTH_URL"]
        ksversion = auth_url.split("/")[-1]
        """
        # GitHub issue 101
        # mechanism to interactively ask for password
        # when OS_PASSWORD set as "readline",
        # or read os.environ if set as "env".
        """
        os_password = credentials["OS_PASSWORD"]
        if os_password.lower() == "readline":
            os_password = getpass.getpass()
        elif os_password.lower() == "env":
            os_password = os.environ.get("OS_PASSWORD", getpass.getpass())

        if "v2.0" == ksversion:
            self.provider = client.Client(version, credentials["OS_USERNAME"],
                                          os_password,
                                          credentials["OS_TENANT_NAME"],
                                          credentials["OS_AUTH_URL"], cert)
        elif "v3" == ksversion:
            sess = session.Session(auth=self._ksv3_auth(credentials),
                                   verify=cert)
            self.provider = client.Client(2, session=sess)
Esempio n. 30
0
    def read_rc_file(cls, host, openrc, force=False):
        """

        :param host: the host name
        :type host: string
        :param openrc: the file name
        :type openrc: string
        :return:
        """

        openrc = Config.path_expand(openrc)

        # check if file exists
        if not os.path.isfile(openrc):
            Console.error("File not found.")
            return

        with open(openrc, 'r') as f:
            lines = f.read().split("\n")

        config = ConfigDict("cloudmesh.yaml")
        credentials = {}
        for line in lines:
            if line.strip().startswith("export "):
                line = line.replace("export ", "")
                key, value = line.split("=", 1)
                credentials[key] = value

        if host not in config["cloudmesh.clouds"] or force:
            config["cloudmesh"]["clouds"][host] = {
                "credentials": credentials,
                "cm_heading": "TBD",
                "cm_host": "TBD",
                "cm_label": "TBD",
                "cm_type": "TBD",
                "cm_type_version": "TBD"
            }

        config.save()
        return config["cloudmesh"]["clouds"][host]["credentials"]
Esempio n. 31
0
    def read_rc_file(cls, host, openrc, force=False):
        """

        :param host: the host name
        :type host: string
        :param openrc: the file name
        :type openrc: string
        :return:
        """

        openrc = Config.path_expand(openrc)

        # check if file exists
        if not os.path.isfile(openrc):
            Console.error("File not found.")
            return

        with open(openrc, 'r') as f:
            lines = f.read().split("\n")

        config = ConfigDict("cloudmesh.yaml")
        credentials = {}
        for line in lines:
            if line.strip().startswith("export "):
                line = line.replace("export ", "")
                key, value = line.split("=", 1)
                credentials[key] = value

        if host not in config["cloudmesh.clouds"] or force:
            config["cloudmesh"]["clouds"][host] = {
                "credentials": credentials,
                "cm_heading": "TBD",
                "cm_host": "TBD",
                "cm_label": "TBD",
                "cm_type": "TBD",
                "cm_type_version": "TBD"}

        config.save()
        return config["cloudmesh"]["clouds"][host]["credentials"]
Esempio n. 32
0
    def do_server(self, args, arguments):
        """
        Usage:
            server

        Options:
          -h --help
          -v       verbose mode

        Description:
          Starts up a REST service and a WEB GUI so one can browse the data in an
          existing cloudmesh database.

          The location of the database is supposed to be in

            ~/.cloud,esh/cloudmesh.db

        """

        # import warnings
        # with warnings.catch_warnings():
        #    warnings.filter("ignore")
        # ignore "SQLALCHEMY_TRACK_MODIFICATIONS")

        from sandman import app
        from sandman.model import activate

        filename = "sqlite:///{}".format(
            Config.path_expand(os.path.join("~", ".cloudmesh",
                                            "cloudmesh.db")))

        print("database: {}".format(filename))

        app.config['SQLALCHEMY_DATABASE_URI'] = filename
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

        activate()

        app.run()
Esempio n. 33
0
    def do_server(self, args, arguments):
        """
        Usage:
            server

        Options:
          -h --help
          -v       verbose mode

        Description:
          Starts up a REST service and a WEB GUI so one can browse the data in an
          existing cloudmesh database.

          The location of the database is supposed to be in

            ~/.cloud,esh/cloudmesh.db

        """

        # import warnings
        # with warnings.catch_warnings():
        #    warnings.filter("ignore")
        # ignore "SQLALCHEMY_TRACK_MODIFICATIONS")

        from sandman import app
        from sandman.model import activate

        filename = "sqlite:///{}".format(Config.path_expand(
            os.path.join("~", ".cloudmesh", "cloudmesh.db")))

        print("database: {}".format(filename))

        app.config['SQLALCHEMY_DATABASE_URI'] = filename
        app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

        activate()

        app.run()
Esempio n. 34
0
    def __init__(self, cloudname, cm_user=None):
        self.nodes = None
        self.flavors = None
        self.data = None
        self.images = None
        self.cloudname = cloudname
        self.user = cm_user

        OpenStack = get_driver(Provider.OPENSTACK)
        self.credential = \
            ConfigDict("cloudmesh.yaml")['cloudmesh']['clouds'][cloudname]['credentials']

        libcloud.security.CA_CERTS_PATH = [Config.path_expand(self.credential['OS_CACERT'])]
        libcloud.security.VERIFY_SSL_CERT = True

        auth_url = "%s/tokens/" % self.credential['OS_AUTH_URL']

        self.driver = OpenStack(
            self.credential['OS_USERNAME'],
            self.credential['OS_PASSWORD'],
            ex_force_auth_url=auth_url,
            ex_tenant_name=self.credential['OS_TENANT_NAME'],
            ex_force_auth_version='2.0_password',
            ex_force_service_region='regionOne')
Esempio n. 35
0
    def run(cls, cluster, group, cmd, **kwargs):

        # determine the script name..

        #
        # TODO: script count is variable in data base, we test if fil exists and if it
        # does increase counter till we find one that does not, that will be new counter.
        # new counter will than be placed in db.
        #
        # define get_script_name(directory, prefix, counter)
        # there maybe s a similar thing already in the old cloudmesh
        #

        # if not kwargs['-name']:
        #
        #    old_count = Shell.ssh(cluster,
        #                          "ls {}*.sh | wc -l | sed 's/$/ count/'".
        #                          format(username))
        #    c = [f for f in old_count.splitlines() if 'count' in f]
        #    script_count = c[0].split()[0]
        # else:
        #    script_count = kwargs['-name']

        config = cls.read_config(cluster)
        if config["credentials"]["username"] == 'TBD':
            return "Please enter username in cloudmesh.yaml for cluster {}".format(cluster)

        cls.incr()
        data = {
            "cluster": cluster,
            "count": cls.counter(),
            "username": config["credentials"]["username"],
            "remote_experiment_dir": config["default"]["experiment_dir"],
            "queue": config["default"]["queue"],
            "id": None,
            "nodes": 1,
            "tasks_per_node": 1,
        }
        data["script_base_name"] = "{username}-{count}".format(**data)
        data["script_name"] = "{username}-{count}.sh".format(**data)
        data["script_output"] = "{username}-{count}.out".format(**data)
        data["script_error"] = "{username}-{count}.err".format(**data)
        data["remote_experiment_dir"] = \
            "{remote_experiment_dir}/{count}".format(**data).format(**data)
        data["group"] = group

        # overwrite defaults
        option_mapping = {'-t': '{tasks_per_node}'.format(**data),
                          '-N': '{nodes}'.format(**data),
                          '-p': '{queue}'.format(**data),
                          '-o': '{script_output}'.format(**data),
                          '-D': '{remote_experiment_dir}'.format(**data),
                          '-e': '{script_error}'.format(**data)}

        # map(lambda k, v:
        #    option_mapping.__setitem__(k, kwargs.get(k) or v),
        #    option_mapping.items())
        #
        # rewrite for better readability
        for (k, v) in iteritems(option_mapping):
            option_mapping[k] = kwargs.get(k) or v

        config = cls.read_config(cluster)
        project = None
        try:
            project = config["credentials"]["project"]
            if project.lower() not in ["tbd", "none"]:
                option_mapping["-A"] = project
        except:
            pass

        for key in option_mapping:
            data[key] = option_mapping[key]

        # create the options for the script
        options = ""
        for key, value in option_mapping.items():
            options += '#SBATCH {} {}\n'.format(key, value)

        cls.create_remote_dir(cluster, data["remote_experiment_dir"])

        # if the command is a script, copy the script
        if os.path.isfile(Config.path_expand(cmd)):
            _from = Config.path_expand(cmd)
            _to = '{cluster}:{remote_experiment_dir}'.format(**data)

            local_file_name = cmd.split('/')[-1]
            Shell.execute("rsync", [_from, _to])
            data["command"] = '{remote_experiment_dir}/{local_file_name}'.format(local_file_name=local_file_name,
                                                                                 **data)
        else:
            data["command"] = cmd

        data["options"] = options

        script = textwrap.dedent(
            """
            #! /bin/sh
            {options}

            echo '#CLOUDMESH: BATCH ENVIRONMENT'
            echo 'BASIL_RESERVATION_ID:' $BASIL_RESERVATION_ID
            echo 'SLURM_CPU_BIND:' $SLURM_CPU_BIND
            echo 'SLURM_JOB_ID:' $SLURM_JOB_ID
            echo 'SLURM_JOB_CPUS_PER_NODE:' $SLURM_JOB_CPUS_PER_NODE
            echo 'SLURM_JOB_DEPENDENCY:' $SLURM_JOB_DEPENDENCY
            echo 'SLURM_JOB_NAME:' $SLURM_JOB_NAME
            echo 'SLURM_JOB_NODELIST:' $SLURM_JOB_NODELIST
            echo 'SLURM_JOB_NUM_NODES:' $SLURM_JOB_NUM_NODES
            echo 'SLURM_MEM_BIND:' $SLURM_MEM_BIND
            echo 'SLURM_TASKS_PER_NODE:' $SLURM_TASKS_PER_NODE
            echo 'MPIRUN_NOALLOCATE:' $MPIRUN_NOALLOCATE
            echo 'MPIRUN_NOFREE:' $MPIRUN_NOFREE
            echo 'SLURM_NTASKS_PER_CORE:' $SLURM_NTASKS_PER_CORE
            echo 'SLURM_NTASKS_PER_NODE:' $SLURM_NTASKS_PER_NODE
            echo 'SLURM_NTASKS_PER_SOCKET:' $SLURM_NTASKS_PER_SOCKET
            echo 'SLURM_RESTART_COUNT:' $SLURM_RESTART_COUNT
            echo 'SLURM_SUBMIT_DIR:' $SLURM_SUBMIT_DIR
            echo 'MPIRUN_PARTITION:' $MPIRUN_PARTITION
            d=$(date)
            echo \"#CLOUDMESH: status, start, $d\"
            srun -l echo \"#CLOUDMESH: status, start, $d\"
            srun -l {command}
            d=$(date)
            srun -l echo \"#CLOUDMESH: status, finished, $d\"
            d=$(date)
            echo \"#CLOUDMESH: status, finished, $d\"
            """
        ).format(**data).replace("\r\n", "\n").strip()

        _from = Config.path_expand('~/.cloudmesh/{script_name}'.format(**data))
        _to = '{cluster}:{remote_experiment_dir}'.format(**data)
        data["from"] = _from
        data["to"] = _to
        data["script"] = script
        # write the script to local

        # print(_from)
        # print(_to)

        with open(_from, 'w') as local_file:
            local_file.write(script)

        # copy to remote host
        Shell.scp(_from, _to)

        # delete local file
        # Shell.execute('rm', _from)
        # import sys; sys.exit()

        # run the sbatch command

        cmd = 'sbatch {remote_experiment_dir}/{script_name}'.format(**data)
        data["cmd"] = cmd

        # print ("CMD>", cmd)
        result = Shell.ssh(cluster, cmd)

        data["output"] = result

        # find id
        for line in result.split("\n"):
            # print ("LLL>", line)
            if "Submitted batch job" in line:
                data["job_id"] = int(line.replace("Submitted batch job ", "").strip())
                break

        #
        # HACK, should not depend on Model.py
        #

        # from cloudmesh_client.db.model import BATCHJOB
        # name = ""
        # BATCHJOB(name,
        #         cluster=data["cluster"],
        #         id=data["id"],
        #         script=data["script"]) # has user and username which seems wrong

        # here what we have in data and want to store the - options are obviously wrong
        # and need to be full names
        # noinspection PyPep8,PyPep8
        """
                {'-D': '/N/u/gvonlasz/experiment/3',
                 '-N': '1',
                 '-o': 'gvonlasz-3.out',
                 '-p': 'delta',
                 '-t': '1',
                 'cluster': 'india',
                 'cmd': 'sbatch /N/u/gvonlasz/experiment/3/gvonlasz-3.sh',
                 'command': 'uname',
                 'count': 3,
                 'from': '/Users/big/.cloudmesh/gvonlasz-3.sh',
                 'id': 1346,
                 'options': '#SBATCH -t 1\n#SBATCH -o gvonlasz-3.out\n#SBATCH -N 1\n#SBATCH -p delta\n#SBATCH -D /N/u/gvonlasz/experiment/3\n',
                 'output': 'Submitted batch job 1346',
                 'queue': 'delta',
                 'remote_experiment_dir': '/N/u/gvonlasz/experiment/3',
                 'script': "#! /bin/sh\n#SBATCH -t 1\n#SBATCH -o gvonlasz-3.out\n#SBATCH -N 1\n#SBATCH -p delta\n#SBATCH -D /N/u/gvonlasz/experiment/3\n\nsrun -l echo '#CLOUDMESH: Starting'\nsrun -l uname\nsrun -l echo '#CLOUDMESH: Test ok'",
                 'script_base_name': 'gvonlasz-3',
                 'script_name': 'gvonlasz-3.sh',
                 'script_output': 'gvonlasz-3.out',
                 'to': 'india:/N/u/gvonlasz/experiment/3',
                 'username': '******'}
                """

        """
        we also want to store what part of the .out file,

        BASIL_RESERVATION_ID:
        SLURM_CPU_BIND:
        SLURM_JOB_ID: 1351
        SLURM_JOB_CPUS_PER_NODE: 12
        SLURM_JOB_DEPENDENCY:
        SLURM_JOB_NAME: gvonlasz-8.sh
        SLURM_JOB_NODELIST: d001
        SLURM_JOB_NUM_NODES: 1
        SLURM_MEM_BIND:
        SLURM_TASKS_PER_NODE: 12
        MPIRUN_NOALLOCATE:
        MPIRUN_NOFREE:
        SLURM_NTASKS_PER_CORE:
        SLURM_NTASKS_PER_NODE:
        SLURM_NTASKS_PER_SOCKET:
        SLURM_RESTART_COUNT:
        SLURM_SUBMIT_DIR: /N/u/gvonlasz
        MPIRUN_PARTITION:

        so maybe we want to use some of the names here as they reflect the env vars
        """

        #
        # add data to database
        #
        # remove the - options

        for key in ['-t', '-N', '-p', '-o', '-D', '-e']:
            if key in data:
                print(key, data[key])
                del data[key]
        data['status'] = 'started'
        cls.add_db(**data)

        return data
Esempio n. 36
0
    def delete(cls, name, group, cloud, force=False):
        """
       deletes a VM or a set of VM

       :param name: name or id of the vm to be deleted
       :type name: list of strings
       :param group: the group name of server
       :type group: string
       :param cloud: the cloud name
       :type cloud: string
       :param force: forces the delete process
       :type force: bool

       :return:
       """
        # TODO: delete by group. set default cloud

        # default cloud. fix this
        if cloud is None:
            cloud = "india"

        if cloud == "india":
            OpenStack = get_driver(Provider.OPENSTACK)
            try:
                # get cloud credential from yaml file
                confd = ConfigDict("cloudmesh.yaml")
                cloudcred = confd['cloudmesh']['clouds']['india'][
                    'credentials']
            except Exception as e:
                Console.error(e.message)
                return

            # set path to cacert and enable ssl connection
            libcloud.security.CA_CERTS_PATH = [
                Config.path_expand(cloudcred['OS_CACERT'])
            ]
            libcloud.security.VERIFY_SSL_CERT = True

            auth_url = "%s/tokens/" % cloudcred['OS_AUTH_URL']

            driver = OpenStack(cloudcred['OS_USERNAME'],
                               cloudcred['OS_PASSWORD'],
                               ex_force_auth_url=auth_url,
                               ex_tenant_name=cloudcred['OS_TENANT_NAME'],
                               ex_force_auth_version='2.0_password',
                               ex_force_service_region='regionOne')

            # gets all the VMs
            nodes = driver.list_nodes()

            def __destroy_node(node):
                """
                    deletes a Virtual Machine

                :param node: node to be deleted
                :type node: Node
                :return:
                """
                try:
                    while True:
                        answer = ""
                        if not force:
                            answer = raw_input(
                                "Would you like to delete {:}? y/n".format(
                                    node.name))
                        if answer.lower() == 'y' or answer.lower(
                        ) == 'yes' or force:
                            break
                        elif answer.lower() != 'n' and answer.lower() != 'no':
                            Console.ok("Invalid option")
                        else:
                            Console.ok("Operation aborted")
                            return

                    driver.destroy_node(node)
                    Console.ok("Virtual Machine {:} deleted".format(node.name))

                except Exception as e:
                    Console.error(
                        "Could not delete Virtual Machine {:}. {:}".format(
                            node.name, e.message))

            def __deleteNode(*args):
                """
                    finds a node to be deleted

                    :param *args: [name], [prefix], [start], [end]
                    :param name: full name of the vm
                    :type name: string
                    :param prefix: fist part of the vm name. Example: full name: sample-[5-12], prefix: 'sample'
                    :type prefix: string
                    :param start: first virtual machine. Example: full name: sample-[5-12], start: '5'
                    :type start: string
                    :param end: last virtual machine. Example: full name: sample-[12-99], end: 99
                    :type end: string

                """
                if len(args) == 1:  # only one vm
                    name = args[0]
                    for i in nodes:
                        if i.name == name:
                            __destroy_node(i)
                            return
                    Console.error("Virtual Machine {:} not found".format(name))
                else:  # interval of vms like sample-[1-10]
                    prefix = args[0]
                    start = args[1].zfill(3)
                    end = args[2].zfill(3)

                    for i in range(int(start), int(end) + 1):
                        name = prefix + "-" + str(i).zfill(
                            3)  # name of the vms to be deleted
                        flag = False
                        for j in nodes:
                            if name == j.name:
                                __destroy_node(j)
                                flag = True
                                break
                        if not flag:
                            Console.error(
                                "Virtual Machine {:} not found".format(name))

                            # name is a list of strings. A string is one of:
                            # sample_[100-9999]. Deletes vm starting at 100 until 9999
                            # sample. Deletes vm named sample

            for i in name:
                name = i.strip()
                if name[-1] == ']':  # vm name like sample-[1-10]
                    a = (name.split('[')[1]).split(']')[0].split('-')
                    prefix = name.split(
                        '-'
                    )[0]  # example: prefix is the sting 'sample' from sample-[10-12]
                    start = a[0]  # type: str
                    end = a[1]  # type: str
                    __deleteNode(prefix, start, end)
                else:  # vm name like sample-daniel
                    __deleteNode(name)
Esempio n. 37
0
    def start(cls, name, count, cloud, image, flavor, group):
        """
        TODO: group has not been used yet. fix that

        starts a virtual Machine (VM) or a set of VMs

        :param name: name of the virtual machine
        :type name: string, None
        :param count: give the number of servers to start
        :type count: integer, None
        :param cloud: give a cloud to work on, if not given, selected or default cloud will be used
        :type cloud: integer, None
        :param image: image name
        :type image: string, None
        :param flavor:flavor name. m1.medium, for example
        :type flavor: string, None
        :param group: the group name of server
        :type group: string, None
        :return:
        """

        # TODO: vm start (without arguments) use default cloud, image, flavor, group.
        if cloud is None:  # use default values for cloud, image and flavor
            pass

        config = CloudRegister.get(cloud)
        if 'cm_type' in ["openstack"]:
            provider = Provider.OPENSTACK
            OpenStack = get_driver(provider)
            try:
                cloud_credentials = config['credentials']
            except Exception as e:
                Console.error(e.message)
                return

            # TODO: THIS MAY BE JUST TRUE IF THE CERT PATH EXISTS IN CREDENTIAL

            # set path to cacert and enable ssl connection
            libcloud.security.CA_CERTS_PATH = [
                Config.path_expand(cloud_credentials['OS_CACERT'])
            ]
            libcloud.security.VERIFY_SSL_CERT = True

            auth_url = "%s/tokens/" % cloud_credentials['OS_AUTH_URL']

            driver = OpenStack(
                cloud_credentials['OS_USERNAME'],
                cloud_credentials['OS_PASSWORD'],
                ex_force_auth_url=auth_url,
                ex_tenant_name=cloud_credentials['OS_TENANT_NAME'],
                ex_force_auth_version='2.0_password',
                ex_force_service_region='regionOne')

            # obtain available images
            # type of images: <class 'libcloud.compute.base.NodeImage'>
            images = driver.list()
            if not [i for i in images if i.name == image]:
                Console.error("Image {:} not found".format(image))
                return
            image = [i for i in images if i.name == image][0]

            # sizes/flavors
            sizes = driver.list_sizes()
            if not [i for i in sizes if i.name == flavor]:
                Console.error("Flavor {:} not found".format(flavor))
                return
            size = [i for i in sizes if i.name == flavor][0]

            if count is None:
                count = 1
            count = int(count)

            def __findsufix():
                # TODO: THIS IS A BIG BUG AS THE NEXT VM NAME IS NOT MANAGED BY SUFFIX
                """
                    Virtual machine name (VM) format:
                      string-001, string-002, ..., string-n
                    returns the max sufix from the VM list. It will be used in the new vm name in order to avoid
                    VMs with the same name.

                    :return: max sufix
                    :return type: string
                """
                nodes = driver.list_nodes()
                sufix = 1
                for i in nodes:
                    n = 0
                    try:
                        n = int(
                            i.name.split('-', 1)[1]
                        )  # not always is int(i.name.split('-', 1)[1] a digit
                    except:
                        pass
                    if sufix <= n:
                        sufix = n + 1
                sufix = str(sufix).zfill(3)
                return sufix

            # set vm name
            sufix = __findsufix()
            global cm
            if name is None:
                cm.name(cloud_credentials['OS_USERNAME'] + "-" + sufix)
            else:
                cm.name(name + "-" + sufix)

            # launch a new VM
            Console.ok("Booting Virtual Machine...")
            for i in range(0, count):
                name = cm.get_name()
                try:
                    node = driver.create_node(name=name,
                                              image=image,
                                              size=size)
                except Exception as e:
                    Console.error(
                        "{:} virtual machines have not been created. {:}".
                        format(count - i, e.message))
                    return
                cm.name(cm.next_name())

            # wait the node to be ready before assigning public IP
            sleep(10)
            Console.ok("Virtual Machine created")
        else:
            Console.error('cloud {:} not found'.format(cloud))
Esempio n. 38
0
                d[gitkeyname]['keyname'] = keyname
                d[gitkeyname]['user'] = None
                d[gitkeyname]['source'] = 'git'
                # sshdb.add_from_dict(d[gitkeyname])
            except Exception, e:
                import traceback
                print(traceback.format_exc())
                print (e)
                Console.error("The key may already there")

        elif arguments['add'] and arguments["--ssh"]:

            # print('ssh add')
            sshdb = SSHKeyDBManager()
            keyname = arguments['--name']
            filename = Config.path_expand("~/.ssh/id_rsa.pub")
            try:
                sshdb.add(filename, keyname, source="ssh", uri="file://" + filename)
                print("Key {:} successfully added to the database".format(keyname or ""))
                msg = "info. OK."
                Console.ok(msg)
            except Exception, e:
                import traceback
                print(traceback.format_exc())
                print (e)
                print (keyname)
                print (filename)
                Console.error("Problem adding the key `{}` from file `{}`".format(keyname, filename))

        elif arguments['add'] and not arguments["--git"]:
from cloudmesh_client.common.ConfigDict import ConfigDict
from cloudmesh_client.common.ConfigDict import Config
from time import sleep
from pprint import pprint
from __future__ import print_function

OpenStack = get_driver(Provider.OPENSTACK)

# get cloud credential from yaml file
confd = ConfigDict("cloudmesh.yaml")
cloudcred = confd['cloudmesh']['clouds']['india']['credentials']

pprint(cloudcred)

# set path to cacert and enable ssl connection
libcloud.security.CA_CERTS_PATH = [Config.path_expand(cloudcred['OS_CACERT'])]
libcloud.security.VERIFY_SSL_CERT = True

auth_url = "%s/tokens/" % cloudcred['OS_AUTH_URL']

driver = OpenStack(cloudcred['OS_USERNAME'],
                   cloudcred['OS_PASSWORD'],
                   ex_force_auth_url=auth_url,
                   ex_tenant_name=cloudcred['OS_TENANT_NAME'],
                   ex_force_auth_version='2.0_password',
                   ex_force_service_region='regionOne')

# list VMs
nodes = driver.list_nodes()
print(nodes)
Esempio n. 40
0
 def _get_config_yaml_file(arguments):
     filename = arguments["--yaml"] or "cloudmesh.yaml"
     filename = Config.find_file(filename)
     return filename
Esempio n. 41
0
import os

from cloudmesh_client.common.ConfigDict import Config

dot_cloudmesh = os.path.join(Config.path_expand("~"), ".cloudmesh")
cloudmesh_yaml = os.path.join(Config.path_expand("~"), ".cloudmesh",
                              "cloudmesh.yaml")
cloudmesh_db = os.path.join(Config.path_expand("~"), ".cloudmesh",
                            "cloudmesh.db")
Esempio n. 42
0
from __future__ import print_function

from cloudmesh_client.common.ConfigDict import ConfigDict
from cloudmesh_client.common.ConfigDict import Config
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import cloudmesh_client.common.tables as tables
from cloudmesh_client.db.models import VM, FLAVOR, DEFAULT, IMAGE
import cloudmesh_client.db.models
import cloudmesh_client.db.models as models

filename = Config.path_expand("~/test/db.db")
endpoint = 'sqlite:///{:}'.format(filename)
engine = create_engine(endpoint)
Base = declarative_base(bind=engine)

Session = sessionmaker(bind=engine)
session = Session()

r = session.query(VM).all()
for obj in r:
    print(obj.name)

result = dict()
for u in r:
    _id = u.id
    values = {}
    for key in u.__dict__.keys():
        if not key.startswith("_sa"):
            values[key] = u.__dict__[key]
Esempio n. 43
0
    def get_from_yaml(cls, filename=None, load_order=None, store=True):
        """
        :param filename: name of the yaml file
        :return: a SSHKeyManager (dict of keys)
        """
        config = None
        if filename is None:
            # default = Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.yaml"))
            # config = ConfigDict("cloudmesh.yaml")
            filename = "cloudmesh.yaml"
            config = ConfigDict(filename)
        elif load_order:
            config = ConfigDict(filename, load_order)
        else:
            Console.error("Wrong arguments")
            return
        config_keys = config["cloudmesh"]["keys"]
        default = config_keys["default"]
        keylist = config_keys["keylist"]

        uri = Config.path_expand(os.path.join("~", ".cloudmesh", filename))


        d = []
        for key in list(keylist.keys()):
            keyname = key
            value = keylist[key]
            if os.path.isfile(Config.path_expand(value)):
                path = Config.path_expand(value)
                if store:
                    Key.add_from_path(path, keyname)
                else:
                    d.append(Key.add_from_path(path, keyname, store=False))
            else:

                keytype, string, comment = SSHkey._parse(value)
                thekey = {
                    'uri': 'yaml://{}'.format(uri),
                    'string': value,
                    'fingerprint': SSHkey._fingerprint(value),
                    'name': keyname,
                    'comment': comment,
                    'source': 'git',
                    'kind': 'key'
                }

                thekey["type"], thekey["key"], thekey["comment"] = SSHkey._parse(value)

                if thekey["comment"] is None:
                    thekey["comment"] = keyname
                if store:
                    try:
                        cls.cm.add(thekey)
                    except:
                        Console.error("Key already in db", traceflag=False)
                else:
                    d.append(thekey)
        if not store:
            return d



        """
Esempio n. 44
0
    def do_key(self, args, arguments):
        """
        ::

           Usage:
             key  -h | --help
             key list --cloud=CLOUD
             key list --source=db [--format=FORMAT]
             key list --source=yaml [--format=FORMAT]
             key list --source=ssh [--dir=DIR] [--format=FORMAT]
             key list --source=git [--format=FORMAT] [--username=USERNAME]
             key list
             key load [--format=FORMAT]
             key add [NAME] [--source=FILENAME]
             key add [NAME] [--git]
             key add [NAME] [--ssh]
             key get NAME
             key default --select
             key delete (NAME | --select | --all)
             key delete NAME --cloud=CLOUD
             key upload [NAME] [--cloud=CLOUD]
             key upload [NAME] --active

           Manages the keys

           Arguments:

             CLOUD          The cloud
             NAME           The name of the key.
             SOURCE         db, ssh, all
             KEYNAME        The name of a key. For key upload it defaults to the default key name.
             FORMAT         The format of the output (table, json, yaml)
             FILENAME       The filename with full path in which the key
                            is located
             NAME_ON_CLOUD  Typically the name of the keypair on the cloud.

           Options:

              --dir=DIR                     the directory with keys [default: ~/.ssh]
              --format=FORMAT               the format of the output [default: table]
              --source=SOURCE               the source for the keys [default: db]
              --username=USERNAME           the source for the keys [default: none]
              --name=KEYNAME                The name of a key
              --all                         delete all keys
              --force                       delete the key form the cloud
              --name_on_cloud=NAME_ON_CLOUD Typically the name of the keypair on the cloud.

           Description:

           key list --source=git  [--username=USERNAME]

              lists all keys in git for the specified user. If the
              name is not specified it is read from cloudmesh.yaml

           key list --source=ssh  [--dir=DIR] [--format=FORMAT]

              lists all keys in the directory. If the directory is not
              specified the default will be ~/.ssh

           key list --source=yaml  [--dir=DIR] [--format=FORMAT]

              lists all keys in cloudmesh.yaml file in the specified directory.
               dir is by default ~/.cloudmesh

           key list [--format=FORMAT]

               list the keys in the giiven format: json, yaml,
               table. table is default

           key list

                Prints list of keys. NAME of the key can be specified

               
           key add [--name=keyname] FILENAME

               adds the key specifid by the filename to the key
               database

           key get NAME

               Retrieves the key indicated by the NAME parameter from database
               and prints its fingerprint.

           key default --select

                Select the default key interactively

           key delete NAME

                deletes a key. In yaml mode it can delete only key that
                are not saved in the database

           key rename NAME NEW

                renames the key from NAME to NEW.
                
        """
        # pprint(arguments)

        invalid_names = ['tbd', 'none', "", 'id_rsa']

        def _print_dict(d, header=None, format='table'):
            msg = Printer.write(
                d,
                order=["name", "comment", "uri", "fingerprint", "source"],
                output=format,
                sort_keys=True)
            if msg is None:
                Console.error("No keys found.", traceflag=False)
                return None
            else:
                return msg

        directory = Config.path_expand(arguments["--dir"])

        cloud = arguments["--cloud"] or Default.cloud

        if arguments['list']:
            _format = arguments['--format']
            _source = arguments['--source']
            _dir = arguments['--dir']

            if "--source" not in arguments and "--cloud" not in arguments:
                arguments["--source"] = 'db'

            if arguments['--cloud']:

                #
                # get key list from openstack cloud
                #
                #keys = Key.list(cloud, output=_format)

                keys = Key.list_on_cloud(cloud, live=True, format=_format)
                if keys is None:
                    Console.ok("The Key list is empty")
                else:
                    print(keys)
                return ""

            elif arguments['--source'] == 'ssh':

                try:
                    #sshm = SSHKeyManager()
                    d = Key.get_from_dir(directory, store=False)

                    #print("SSS", type(Key.__keys__))
                    #d = dict(Key.all())
                    #print(d)
                    print(
                        Printer.write(d,
                                      order=[
                                          "name", "comment", "uri",
                                          "fingerprint", "source"
                                      ],
                                      output="table"))

                    # d = dict(sshm.__keys__)

                    # print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                    return ""
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing keys from ssh")

            elif arguments['--source'] in ['cm', 'cloudmesh', 'yaml']:

                try:
                    #sshm = SSHKeyManager()
                    d = Key.get_from_yaml(load_order=directory, store=False)

                    print(
                        Printer.write(d,
                                      order=[
                                          "name", "comment", "uri",
                                          "fingerprint", "source"
                                      ],
                                      output=_format))
                    return ""
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing keys from `{:}`".format(
                        arguments['--source']))

            elif arguments['--source'] in ['git']:

                username = arguments["--username"]
                # print(username)
                if username == 'none':
                    conf = ConfigDict("cloudmesh.yaml")
                    username = conf["cloudmesh.github.username"]

                #sshm = SSHKeyManager()
                try:

                    d = Key.get_from_git(username, store=False)

                    print(
                        Printer.write(d,
                                      order=[
                                          "name", "comment", "uri",
                                          "fingerprint", "source"
                                      ],
                                      output=_format))

                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing git keys from database")
                    return ""

            elif arguments['--source'] == 'db':

                try:
                    #sshdb = SSHKeyDBManager()
                    d = Key.all(output='dict')

                    if d is not None or d != []:

                        print(
                            Printer.write(d,
                                          order=[
                                              "name", "comment", "uri",
                                              "fingerprint", "source"
                                          ],
                                          output=_format))

                        # print(_print_dict(d, output=arguments['--format']))
                        msg = "info. OK."
                        Console.ok(msg)
                    else:
                        Console.error("No keys in the database")
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing keys from database")

        elif arguments['get']:

            try:
                name = arguments['NAME']
                #sshdb = SSHKeyDBManager()
                d = Key.all(output="dict")

                for key in d:
                    if key["name"] == name:
                        print("{:}: {:}".format(key['name'],
                                                key['fingerprint']))
                        msg = "info. OK."
                        Console.ok(msg)
                        return ""
                    else:
                        pass
                Console.error("The key is not in the database")
            except Exception as e:
                Error.traceback(e)
                Console.error("The key is not in the database")

        # key add [NAME] [--source=FILENAME]
        #     key add [NAME] [--git]

        elif arguments['add'] and arguments["--git"]:

            # Console.error("This feature is not yet implemented", traceflag=False)
            # return ""

            print('git add')
            #sshdb = SSHKeyDBManager()

            data = dotdict(arguments)

            keyname = data.NAME

            #
            # get name
            #
            conf = ConfigDict("cloudmesh.yaml")
            data.username = conf["cloudmesh.github.username"]
            data.name = arguments['NAME'] or data.username

            #
            # get git username
            #
            data.username = ConfigDict(
                "cloudmesh.yaml")["cloudmesh.github.username"]

            if str(data.name).lower() in invalid_names:
                Console.error(
                    "The github user name is not set in the yaml file",
                    traceflag=False)
                return ""

            try:
                Console.msg(
                    "Retrieving github ssh keys for user {username}".format(
                        **data))
                #sshm = SSHKeyManager()
                Key.get_from_git(data.username)
                d = Key.all()
                # pprint(d)
            except Exception as e:
                Console.error(
                    "Problem adding keys to git for user: {username}".format(
                        **data))
                return ""

            for key in d:
                if key is not None:
                    key["name"] = key["name"].replace("-", "_")
                    key["source"] = "git"
                    key["user"] = data.name
                    try:
                        o = dict(key)
                        o['value'] = key["string"]
                        Key.add_from_dict(key)
                    except Exception as e:
                        Console.error(
                            "The key {name} with that finger print already exists"
                            .format(**key),
                            traceflag=False)

        elif arguments['add'] and not arguments["--git"]:

            #     key add [NAME] [--source=FILENAME]
            #     key add [NAME] [--git]

            #sshdb = SSHKeyDBManager()

            data = dotdict()

            #
            # get name
            #
            conf = ConfigDict("cloudmesh.yaml")
            data.username = conf["cloudmesh.profile.user"]
            data.name = arguments['NAME'] or data.username

            data.filename = arguments['--source']
            if data.filename == "db" or data.filename is None:
                data.filename = Config.path_expand("~/.ssh/id_rsa.pub")

            if str(data.name).lower() in invalid_names:
                msg = (
                    "Your choice of keyname {name} is insufficient. \n"
                    "You must be chosing a keyname that is distingct on all clouds. \n"
                    "Possible choices are your gmail name, your XSEDE name, or \n"
                    "some name that is uniqe. "
                    "Best is also to set this name in \n"
                    "cloudmesh.profile.user as "
                    "part of your \n~/cloudmesh/cloudmesh.yaml file.")
                Console.error(msg.format(**data), traceflag=False)
                return ""

            try:
                Key.add_from_path(data.filename,
                                  data.name,
                                  source="ssh",
                                  uri="file://" + data.filename)
                print("Key {name} successfully added to the database".format(
                    **data))
                msg = "info. OK."
                Console.ok(msg)

            except ValueError as e:
                Console.error(
                    "A key with this fingerprint already exists".format(
                        **data),
                    traceflag=False)
                Console.msg("Please use check with: key list")

            return ""

        elif arguments['default']:

            # print("default")

            if arguments['--select']:
                keyname = None
                try:
                    #sshdb = SSHKeyDBManager()
                    select = Key.select()
                    if select != 'q':
                        keyname = select.split(':')[0]
                        print("Setting key: {:} as default.".format(keyname))
                        Default.key = keyname
                        msg = "info. OK."
                        Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error(
                        "Setting default for selected key {:} failed.".format(
                            keyname))

            else:
                try:
                    #sshdb = SSHKeyDBManager()
                    d = Key.table_dict()

                    for i in d:
                        if d[i]["is_default"] == "True":
                            key = d[i]
                            print("{:}: {:}".format(key['name'],
                                                    key['fingerprint']))
                            msg = "info. OK."
                            Console.ok(msg)
                            return ""
                        else:
                            pass
                    Console.error("The key is not in the database")
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem retrieving default key.")

        elif arguments['delete'] and arguments["--cloud"]:

            key = dotdict({
                'cloud': arguments["--cloud"],
                'name': arguments["NAME"]
            })
            try:
                Key.delete(key.name, key.cloud)
                msg = "info. OK."
                Console.ok(msg)
            except:
                Console.error(
                    "Problem deleting the key {name} on the cloud {cloud}".
                    format(**key))

        elif arguments['delete']:

            # key delete (NAME | --select| --all)

            data = dotdict({
                'all': arguments['--all'] or False,
                'select': arguments['--select'] or False,
                'name': arguments['NAME'] or False,
            })

            pprint(data)
            # BUG delete all is not properly implemented

            if data.all:
                Console.TODO("Delete --all is not yet implemented.")
                # Key.delete()
            elif data.select:
                key = Key.select()
                print(key)

            else:  # name
                Key.delete(data.name)

            msg = "info. OK."
            Console.ok(msg)

        elif arguments['upload']:

            # pprint(arguments)

            try:
                #
                # get username
                #
                conf = ConfigDict("cloudmesh.yaml")
                username = conf["cloudmesh"]["profile"]["user"]
                if username in ['None', 'TBD']:
                    username = None

                #
                # get cloudnames
                #
                clouds = []

                if arguments["--active"]:
                    cloud = 'active'
                else:
                    cloud = arguments["--cloud"] or Default.cloud

                if cloud == "all":
                    config = ConfigDict("cloudmesh.yaml")
                    clouds = config["cloudmesh"]["clouds"]
                elif cloud == 'active':
                    config = ConfigDict("cloudmesh.yaml")
                    clouds = config["cloudmesh"]["active"]
                else:
                    clouds.append(cloud)

                #
                # get keyname
                #

                for cloud in clouds:
                    status = 0
                    #sshdb = SSHKeyDBManager()
                    #sshm = SSHKeyManager()
                    keys = Key.all()
                    for key in keys:

                        print("upload key {} -> {}".format(key["name"], cloud))

                        try:
                            status = Key.add_key_to_cloud(
                                username, key["name"], cloud)

                        except Exception as e:
                            Console.error("problem")
                            if "already exists" in str(e):
                                print(
                                    "key already exists. Skipping upload. OK.")
                        if status == 1:
                            print("Problem uploading key {} to {}. failed.".
                                  format(key["name"], cloud))

            except Exception as e:
                Console.error("Problem adding key to cloud")
Esempio n. 45
0
    def sync(cls, cloudname, localdir, remotedir, operation=None):
        """
        Syncs a local directory with a remote directory.
        Either from local to remote OR vice-versa
        :param cloudname:
        :param localdir:
        :param remotedir:
        :param operation: get/put
        :return:
        """
        # Get the operating system
        os_type = cls.operating_system()

        # fix the local dir path
        localdir = Config.path_expand(localdir)

        # check if local directory exists
        if not os.path.exists(localdir):
            if operation == "put":
                Console.error("The local directory [{}] does not exist."
                              .format(localdir))
                return None
            elif operation == "get":
                # for receiving, create local dir
                os.mkdir(localdir)
                Console.msg("Created local directory [{}] for sync."
                            .format(localdir))

        # sync entire local directory
        elif os.path.isdir(localdir):
            if operation == "put":
                localdir += "/*"
            elif operation == "get":
                localdir += "/"

        # for windows use pscp
        # rsync has issues with latest win10
        if 'windows' in os_type:
            ppk_file = ''
            while ppk_file == '':
                ppk_file = raw_input("Please enter putty private key(ppk) "
                                     "file path: ")
                # expand the path
                ppk_file = Config.path_expand(ppk_file)
                pass

            host = cls.get_host(cloudname)
            if host is None:
                Console.error("Cloud [{}] not found in cloudmesh.yaml file."
                              .format(cloudname))
                return None
            else:
                # Get the hostname and user of remote host
                hostname = cls.get_hostname(host)
                user = cls.get_hostuser(host)

                # Console.msg("Syncing local dir [{}] with remote host [{}]"
                #            .format(localdir, user + "@" + hostname))
                args = None
                if operation == "put":
                    # Construct the arguments
                    # local dir comes first (send)
                    args = [
                        "-i",
                        ppk_file,
                        localdir,
                        user + "@" + hostname + ":" + remotedir
                    ]
                elif operation == "get":
                    # Construct the arguments
                    # remote dir comes first (receive)
                    args = [
                        "-i",
                        ppk_file,
                        user + "@" + hostname + ":" + remotedir,
                        localdir
                    ]

                try:
                    # Convert command to string
                    cmd = " ".join(["pscp"] + args)
                    result = os.system(cmd)
                    if result != 0:
                        Console.error("Something went wrong. Please try again later.")
                        return None
                    else:
                        return "Success."
                except Exception as ex:
                    print(ex, ex.message)

        # for linux/mac machines use rsync
        else:
            host = cls.get_host(cloudname)
            if host is None:
                Console.error("Cloud [{}] not found in cloudmesh.yaml file."
                              .format(cloudname))
                return None
            else:
                args = None
                if operation == "put":
                    args = [
                        localdir,
                        host + ":" + remotedir
                    ]
                elif operation == "get":
                    args = [
                        host + ":" + remotedir,
                        localdir
                    ]
                # call rsync
                return Shell.rsync(*args)
Esempio n. 46
0
 def make_dir(cls, directory):
     if not os.path.exists(Config.path_expand(directory)):
         os.makedirs(Config.path_expand(directory))
from cloudmesh_client.common.ConfigDict import ConfigDict
from cloudmesh_client.common.ConfigDict import Config
from time import sleep
from pprint import pprint
from __future__ import print_function
OpenStack = get_driver(Provider.OPENSTACK)

# get cloud credential from yaml file
confd = ConfigDict("cloudmesh.yaml")
cloudcred = confd['cloudmesh']['clouds']['india']['credentials']

pprint(cloudcred)

# set path to cacert and enable ssl connection
libcloud.security.CA_CERTS_PATH = [Config.path_expand(cloudcred['OS_CACERT'])]
libcloud.security.VERIFY_SSL_CERT = True

auth_url = "%s/tokens/" % cloudcred['OS_AUTH_URL']

driver = OpenStack(cloudcred['OS_USERNAME'],
                   cloudcred['OS_PASSWORD'],
                   ex_force_auth_url=auth_url,
                   ex_tenant_name=cloudcred['OS_TENANT_NAME'],
                   ex_force_auth_version='2.0_password',
                   ex_force_service_region='regionOne')

# list VMs
nodes = driver.list_nodes()
print (nodes)
Esempio n. 48
0
class CloudmeshDatabase(object):
    '''

    def __init__(self, user=None):
        self.__dict__ = self.__shared_state

        if self.initialized is None:
            self.user = ConfigDict("cloudmesh.yaml")["cloudmesh.profile.user"]
            self.filename = Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.db"))
            self.engine = create_engine('sqlite:///{}'.format(self.filename), echo=False)
            self.data = {"filename": self.filename}

            if user is None:
                self.user = ConfigDict("cloudmesh.yaml")["cloudmesh.profile.user"]
            else:
                self.user = user
            CloudmeshDatabase.create()
            CloudmeshDatabase.create_tables()
            CloudmeshDatabase.start()

    #
    # MODEL
    #
    @classmethod
    def create(cls):
        # cls.clean()
        filename = Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.db"))
        if not os.path.isfile(filename):
            cls.create_model()


    '''
    __shared_state = {}
    data = {
        "filename":
        Config.path_expand(os.path.join("~", ".cloudmesh", "cloudmesh.db"))
    }
    initialized = None
    engine = create_engine('sqlite:///{filename}'.format(**data), echo=False)
    Base = declarative_base()
    session = None
    tables = None
    # user = "******"
    # user = ConfigDict("cloudmesh.yaml")["cloudmesh.profile.user"]
    user = None

    def __init__(self):
        self.__dict__ = self.__shared_state

        if self.initialized is None:
            self.filename = Config.path_expand(
                os.path.join("~", ".cloudmesh", "cloudmesh.db"))
            self.create()
            self.create_tables()
            self.start()
            self.user = ConfigDict(
                filename="cloudmesh.yaml")["cloudmesh.profile.user"]

    @classmethod
    def refresh_new(cls, kind, name, **kwargs):
        """
        This method refreshes the local database
        with the live cloud details
        :param kind:
        :param name:
        :param kwargs:
        :return:
        """

        try:
            # print(cloudname)
            # get the user
            # TODO: Confirm user

            # user = cls.user

            purge = kwargs.get("purge", True)

            if kind in ["flavor", "image", "vm"]:

                # get provider for specific cloud
                provider = CloudProvider(name).provider

                current_elements = cls.find_new(category=name,
                                                kind=kind,
                                                output='dict',
                                                key='name')

                #returns the following:
                #current_elements = {}
                #for element in elements:
                #    current_elements[element["name"]] = element

                # pprint(current_elements)

                if purge:
                    cls.clear(kind=kind, category=name)

                elements = provider.list(kind, name)
                #
                # image, flavor, username, group, ...
                #

                for element in list(elements.values()):
                    element["uuid"] = element['id']
                    element['type'] = 'string'
                    element["category"] = name

                    # element["user"] = user
                    element["kind"] = kind
                    element["provider"] = provider.cloud_type
                    if current_elements is not None:
                        for index in current_elements:
                            current = current_elements[index]
                            for attribute in [
                                    "username", "image", "flavor", "group"
                            ]:
                                if attribute in current and current[
                                        attribute] is not None:
                                    element[attribute] = current[attribute]
                    print("CCC", index, element["name"], element["flavor"])
                    cls.add(element)

                return True

            elif kind in ["batchjob"]:

                # provider = BatchProvider(name).provider
                # provider = BatchProvider(name)

                from cloudmesh_client.cloud.hpc.BatchProvider import BatchProvider
                provider = BatchProvider(name)

                vms = provider.list_job(name)
                for job in list(vms.values()):
                    job[u'uuid'] = job['id']
                    job[u'type'] = 'string'
                    job[u'category'] = name
                    # job[u'user'] = user

                    cls.add(job)
                    cls.save()
                return True

            elif kind not in ["secgroup"]:
                Console.error(
                    "refresh not supported for this kind: {}".format(kind))

        except Exception as ex:
            Console.error("Problem with secgroup")
            return False

    @classmethod
    def insert(cls, obj):
        """Insert a row into the database

        :param obj: the object model to insert
        :returns:
        :rtype:
        """

        # this method was written because I was having difficulty
        # getting others to work. Not ideal, but there is a deadline
        # and it is faster to write it myself than dig through the
        # rest of the code to figure out how it works and how to
        # deal with corner cases :(

        # since some models may not be defined in the module
        # db.general.model or db.openstack.model, etc, ensure that the
        # DB knows about the table
        if obj.__tablename__ not in cls.Base.metadata.tables.keys():
            cls.create_model()

        cls.session.add(obj)
        cls.session.commit()

    @classmethod
    def select(cls, table, **filter_args):
        """Return rows of the table matching filter args.

        This is a proxy for sqlalchemy's ``session.query(table).filter(**kwargs)``

        :param type table: the model class
        :returns: all rows in the table matching ``**filter_args``
        """

        return cls.session.query(table).filter_by(**filter_args)

    @classmethod
    def delete_(cls, table, **filter_args):
        """Delete rows in the table matching ``filter_args``

        :param type table: the model class
        """
        cls.session.query(table).filter_by(**filter_args).delete()
        cls.session.commit()

    @classmethod
    def update_(cls, table, where=None, values=None):
        """Updates a subset of rows in the table, filtered by ``where``,
        setting to ``values``.

        :param type table: the table class
        :param dict where: match rows where all these properties hold
        :param dict values: set the columns to these values
        """

        cls.session.query(table)\
            .filter_by(**where)\
            .update(values)
        cls.session.commit()

    def find_new(cls, **kwargs):
        """
        This method returns either
        a) an array of objects from the database in dict format, that match a particular kind.
           If the kind is not specified vm is used. one of the arguments must be scope="all"
        b) a single entry that matches the first occurance of the query specified by kwargs,
           such as name="vm_001"

        :param kwargs: the arguments to be matched, scope defines if all or just the first value
               is returned. first is default.
        :return: a list of objects, if scope is first a single object in dotdict format is returned
        """
        """

        parameters:
            output="dict"
            key="name"

        output:
            name1:    element["name"]
              attribute
              ...
            name2:
               ....

        parameters:
            output="dict"
            key="id"

        output:
            "0":  index in the list of elements
              attribute
              ...
            "1":
               ....

        parameters:
            output="list"
            key="id"

        output:
            [element0, element1, element2] each of which is a dot dict

        other things
            scope = "first" -> one elemnet only as dotdict  (not an list)
            scope = "all" -> any of the above but each element is a dotdict returns either list or dict


        find -> list

        to_dict(list, key="name")

        to_dict(find(...), key="name") - dict of dotdicts  <-- or None if we do not find

        ??? too complex to implement, find(...).dict(key="name") - dict of dotdicts


        Default.purge = True  -> when delete vm it deletes vm from db, if not keep the vm

        Vm.names -> list names of all vms in db

            if newvmname in Vm.names:
                error vm already exists

        cls.replace

        cls.add -> cls.upsert
             just keep add for now but introduce new upser that just calls current add?
             or do refactor on add and replaces with upsert

        """

        scope = kwargs.pop("scope", "all")
        output = kwargs.pop("output", "dict")

        table = kwargs.pop("table", None)

        result = []

        if table is not None:
            part = cls.session.query(table).filter_by(**kwargs)
            result.extend(cls.to_list(part))

        else:
            category = kwargs.get("category", None)
            provider = kwargs.get("provider", None)
            kind = kwargs.get("kind", None)

            if provider is not None and kind is not None:

                t = cls.table(provider, kind)
                part = cls.session.query(t).filter_by(**kwargs)
                if output == 'dict':
                    result.extend(cls.to_list(part))
                else:
                    result.extend(part)
            elif provider is None:
                for t in cls.tables:
                    # print ("CCCC", t.__kind__, t.__provider__, kwargs)
                    if (t.__kind__ == kind):
                        part = cls.session.query(t).filter_by(**kwargs)
                        if output == 'dict':
                            result.extend(cls.to_list(part))
                        else:
                            result.extend(part)
            else:
                Console.error("nothing searched {}".format(kwargs))

        objects = result

        if len(objects) == 0:
            return None
        elif scope == "first":
            if output == 'dict':
                objects = dotdict(result[0])
            else:
                objects = result[0]

        return objects

    @classmethod
    def add_new(cls, d, replace=True):
        """
        o dotdict

            if o is a dict an object of that type is created. It is checked if another object in the db already exists,
            if so the attributes of the object will be overwritten with the once in the database

            provider, kind, category, name must be set to identify the object


        o is in CloudmeshDatabase.Base

            this is an object of a table has been created and is to be added. It is checked if another object in the db
            already exists. If so the attributes of the existing object will be updated.


        """

        if d is None:
            return

        if type(d) in [dict, dotdict]:

            if "provider" in d:
                t = cls.table(kind=d["kind"], provider=d["provider"])
                provider = d["provider"]
            else:
                t = cls.table(kind=d["kind"])

                provider = t.__provider__
            d["provider"] = provider

            element = t(**d)

        else:
            element = d

        if replace:

            element.provider = element.__provider__

            current = cls.find(provider=element.provider,
                               kind=element.kind,
                               name=element.name,
                               category=element.category)

            if current is not None:
                for key in element.__dict__.keys():
                    current[0][key] = element.__dict__[key]
                    # current[0]['user'] = element.__dict__["user"]
            else:
                cls.session.add(element)
        else:
            cls.session.add(element)
        cls.save()

    #
    # MODEL
    #
    @classmethod
    def create(cls):
        # cls.clean()
        if not os.path.isfile("{filename}".format(**cls.data)):
            cls.create_model()

    @classmethod
    def create_model(cls):
        cls.Base.metadata.create_all(cls.engine)
        print("Model created")

    @classmethod
    def clean(cls):
        for table in cls.tables:
            cls.delete(kind=table.__kind__, provider=table.__provider__)

    @classmethod
    def create_tables(cls):
        """
        :return: the list of tables in model
        """
        cls.tables = [c for c in cls.Base.__subclasses__()]

    @classmethod
    def info(cls, kind=None):
        result = []

        for t in cls.tables:
            entry = dict()
            if kind is None or t.__kind__ in kind:
                entry = {
                    "count": cls.session.query(t).count(),
                    "tablename": t.__tablename__,
                    "provider": t.__provider__,
                    "kind": t.__kind__
                }
                result.append(entry)
        return result

    @classmethod
    def table(cls, provider=None, kind=None, name=None):
        """

        :param category:
        :param kind:
        :return: the table class based on a given table name.
                 In case the table does not exist an exception is thrown
        """

        t = None
        if name is not None:
            for t in cls.tables:
                if t.__tablename__ == name:
                    return t

        if provider is None and kind is not None:
            t = cls.get_table_from_kind(kind)
            return t

        if provider is None and kind is None:
            Console.error("No Kind specified")
            return None

        for t in cls.tables:
            if t.__kind__ == kind and t.__provider__ == provider:
                return t

        Console.error(
            "No table found for name={}, provider={}, kind={}".format(
                name, provider, kind))

    @classmethod
    def vm_table_from_provider(cls, provider):
        tablename = 'vm_{}'.format(provider)
        table = cls.table(name=tablename)
        return table

    @classmethod
    def get_table_from_kind(cls, kind):
        providers = set()
        for t in cls.tables:
            if t.__kind__ == kind:
                providers.add(t)
        providers = list(providers)
        if len(providers) == 1:
            return providers[0]
        elif len(providers) > 1:
            Console.error(
                "Providers for kind={} are not unique. Found={}".format(
                    kind, providers))
        else:
            Console.error("Providers for kind={} nor found".format(kind))
        return None

    #
    # SESSION
    #
    # noinspection PyPep8Naming
    @classmethod
    def start(cls):
        if cls.session is None:
            # print("start session")
            Session = sessionmaker(bind=cls.engine)
            cls.session = Session()

    @classmethod
    def all(cls, provider='general', category=None, kind=None, table=None):

        t = table
        data = {
            "provider": provider,
            "kind": kind,
        }

        if provider is not None and kind is not None:
            t = cls.table(provider=provider, kind=kind)

        elif provider is None and kind is not None:
            t = cls.table(kind=kind)
        else:
            Console.error(
                "find is improperly used provider={provider} kind={kind}".
                format(**data))
        result = cls.session.query(t).all()
        return cls.to_list(result)

    @classmethod
    def _find(cls,
              scope='all',
              provider=None,
              kind=None,
              output='dict',
              table=None,
              **kwargs):
        """
        find (category="openstack", kind="vm", name="vm_002")
        find (VM_OPENSTACK, kind="vm", name="vm_002") # do not use this one its only used internally

        :param category:
        :param kind:
        :param table:
        :param kwargs:
        :return:
        """
        t = table

        if table is None:

            if provider is None and kind is None:
                Console.error("No provider or kind specified in find")
            else:
                t = cls.table(provider=provider, kind=kind)

        elements = cls.session.query(t).filter_by(**kwargs)

        if scope == 'first':
            result = elements.first()
            if result is None:
                return None
            if output == 'dict':
                result = dotdict(cls.to_list([result])[0])
        elif output == 'dict':
            result = cls.to_list(elements)
        elif output == 'namedict':
            result = cls.to_dict(elements)
        return result

    @classmethod
    def find(cls, **kwargs):
        """
        This method returns either
        a) an array of objects from the database in dict format, that match a particular kind.
           If the kind is not specified vm is used. one of the arguments must be scope="all"
        b) a single entry that matches the first occurance of the query specified by kwargs,
           such as name="vm_001"

        To select a value from a specific table:
        1) identify the table of interest with :meth:`table`
           >>> t = db.table(name='default')
        2) specify the 'table' keywork:
           >>> db.find(table=t, cm_id=42)


        :param kwargs: the arguments to be matched, scope defines if all or just the first value
               is returned. first is default.
        :return: a list of objects, if scope is first a single object in dotdict format is returned
        """

        scope = kwargs.pop("scope", "all")
        output = kwargs.pop("output", "dict")

        table = kwargs.pop("table", None)

        result = []

        if table is not None:
            part = cls.session.query(table).filter_by(**kwargs)
            result.extend(cls.to_list(part))

        else:
            category = kwargs.get("category", None)
            provider = kwargs.get("provider", None)
            kind = kwargs.get("kind", None)

            if provider is not None and kind is not None:

                t = cls.table(provider, kind)
                part = cls.session.query(t).filter_by(**kwargs)
                if output == 'dict':
                    result.extend(cls.to_list(part))
                else:
                    result.extend(part)
            elif provider is None:
                for t in cls.tables:
                    # print ("CCCC", t.__kind__, t.__provider__, kwargs)
                    if (t.__kind__ == kind):
                        part = cls.session.query(t).filter_by(**kwargs)
                        if output == 'dict':
                            result.extend(cls.to_list(part))
                        else:
                            result.extend(part)
            else:
                Console.error("nothing searched {}".format(kwargs))

        objects = result
        '''
        if len(objects) == 0 and scope == "first":
            objects = None
        elif len(objects) != 0:
            if scope == "first":
                if output == 'dict':
                    objects = dotdict(result[0])
                else:
                    objects = result[0]
        '''

        if len(objects) == 0:
            return None
        elif scope == "first":
            if output == 'dict':
                objects = dotdict(result[0])
            else:
                objects = result[0]

        return objects

    @classmethod
    def add(cls, d, replace=True):
        """
        o dotdict

            if o is a dict an object of that type is created. It is checked if another object in the db already exists,
            if so the attributes of the object will be overwritten with the once in the database

            provider, kind, category, name must be set to identify the object


        o is in CloudmeshDatabase.Base

            this is an object of a table has been created and is to be added. It is checked if another object in the db
            already exists. If so the attributes of the existing object will be updated.


        """

        if d is None:
            return

        if type(d) in [dict, dotdict]:

            if "provider" in d:
                t = cls.table(kind=d["kind"], provider=d["provider"])
                provider = d["provider"]
            else:
                t = cls.table(kind=d["kind"])

                provider = t.__provider__
            d["provider"] = provider

            element = t(**d)

        else:
            element = d

        if replace:

            element.provider = element.__provider__

            current = cls.find(
                provider=element.provider,
                kind=element.kind,
                name=element.name,
                category=element.category,
                scope=
                "first"  # this ensures the returned result is object/dict, not list
            )
            if current is not None:
                for key in element.__dict__.keys():
                    # update based on the keys that exist in the db model
                    if key in current:
                        current[key] = element.__dict__[key]
                # current['user'] = element.__dict__["user"]

                # update on the db
                cls.update(provider=current["provider"],
                           kind=current["kind"],
                           filter={"name": current["name"]},
                           update=current)
            else:
                cls.session.add(element)
        else:
            cls.session.add(element)
        cls.save()

    @classmethod
    def add_obj(cls, objects):
        for obj in list(objects.values()):
            for key in list(obj.keys()):
                t = cls.table(kind=key)
                o = t(**obj[key])
                cls.add(o)

    @classmethod
    def filter_by(cls, **kwargs):
        """
        This method returns either
        a) an array of objects from the database in dict format, that match a particular kind.
           If the kind is not specified vm is used. one of the arguments must be scope="all"
        b) a single entry that matches the first occurance of the query specified by kwargs,
           such as name="vm_001"

        :param kwargs: the arguments to be matched, scope defines if all or just the first value
               is returned. first is default.
        :return: a list of objects, if scope is first a single object in dotdict format is returned
        """
        scope = kwargs.pop("scope", "all")

        result = []

        for t in cls.tables:
            part = cls.session.query(t).filter_by(**kwargs)
            result.extend(cls.to_list(part))

        objects = result
        if scope == "first" and objects is not None:
            objects = dotdict(result[0])

        return objects

    @classmethod
    def save(cls):
        cls.session.commit()
        cls.session.flush()

    @classmethod
    def to_list(cls, obj):
        """
        convert the object to dict

        :param obj:
        :return:
        """
        result = list()
        for u in obj:
            if u is not None:
                values = {}
                for key in list(u.__dict__.keys()):
                    if not key.startswith("_sa"):
                        values[key] = u.__dict__[key]
                result.append(values)
        return result

    @classmethod
    def to_dict(cls, obj, key="name"):
        """
        convert the object to dict

        :param obj:
        :return:
        """
        result = dict()
        for u in obj:
            if u is not None:
                values = {}
                for attribute in list(u.__dict__.keys()):
                    if not attribute.startswith("_sa"):
                        values[attribute] = u.__dict__[attribute]
                result[values[key]] = values
        return result

    #
    # DELETE
    #
    @classmethod
    def delete(cls, **kwargs):
        """
        :param kind:
        :return:
        """
        #
        # BUG does not look for user related data
        # user = self.user or Username()
        #
        result = False
        provider = kwargs.get("provider", None)
        kind = kwargs.get("kind")
        if provider is None:
            t = cls.get_table_from_kind(kind)

        if provider is None or kind is None:
            data = {
                "provider": provider,
                "kind": kind,
            }
            ValueError(
                "find is improperly used provider={provider} kind={kind}".
                format(**data))

        t = cls.table(provider=provider, kind=kind)

        if len(kwargs) == 0:
            result = cls.session.query(t).delete()
        else:
            result = cls.session.query(t).filter_by(**kwargs).delete()
        cls.save()

        return result != 0

    @classmethod
    def update(cls, **kwargs):
        """

        :param kind:
        :param kwargs:
        :return:
        """
        provider = kwargs.get("provider", None)
        kind = kwargs.get("kind", None)

        # bug: user = self.user or Username()
        if provider is not None and kind is not None:
            t = cls.table(provider=provider, kind=kind)
        else:
            data = {
                "provider": provider,
                "kind": kind,
            }
            ValueError(
                "find is improperly used provider={provider} kind={kind}".
                format(**data))
        filter = kwargs['filter']
        values = kwargs['update']

        # print (t, filter, values)

        cls.session.query(t).filter_by(**filter).update(values)
        cls.save()

    @classmethod
    def set(cls,
            name,
            attribute,
            value,
            provider=None,
            kind=None,
            scope="all"):

        if scope == "first" and provider is None:
            elements = cls.filter_by(name=name, kind=kind)[0]
            # pprint(elements)

            o = dotdict(elements)
            # print("PPPP", kind, name, attribute, value, o)

            if o[attribute] != value:
                cls.update(kind=o["kind"],
                           provider=o["provider"],
                           filter={'name': name},
                           update={attribute: value})
        elif scope == "first":
            o = dotdict(
                cls.filter_by(name=name, provider=provider, kind=kind)[0])
            # print("PPPP", provider, kind, name, attribute, value, o)

            if o[attribute] != value:
                cls.update(kind=o["kind"],
                           provider=o["provider"],
                           filter={'name': name},
                           update={attribute: value})
        elif provider is None or kind is None or scope == "all":
            o = cls.filter_by(name=name)
            cls.update(kind=o["kind"],
                       provider=o["provider"],
                       filter={'name': name},
                       update={attribute: value})
        else:
            Console.error("Problem setting attributes")

    @classmethod
    def clear(cls, kind, category, user=None):
        """
        This method deletes all 'kind' entries
        from the cloudmesh database
        :param category: the category name
        """
        # if user is None:
        #    user = cls.user

        try:
            elements = cls.find(kind=kind,
                                output='object',
                                scope="all",
                                category=category,
                                user=user)
            # pprint(elements)
            if elements is None:
                return
            for element in elements:
                # pprint(element)
                cls.session.delete(element)

        except Exception as ex:
            Console.error(ex.message)

    # ###################################
    # REFRESH
    # ###################################
    # noinspection PyUnusedLocal
    @classmethod
    def refresh(cls, kind, name, **kwargs):
        """
        This method refreshes the local database
        with the live cloud details
        :param kind:
        :param name:
        :param kwargs:
        :return:
        """

        try:
            # print(cloudname)
            # get the user
            # TODO: Confirm user

            # user = cls.user
            purge = kwargs.get("purge", True)

            if kind in ["flavor", "image", "vm"]:

                # get provider for specific cloud
                provider = CloudProvider(name).provider

                elements = cls.find(category=name, kind=kind, output='dict')

                current_elements = {}
                if elements:
                    for element in elements:
                        current_elements[element["name"]] = element

                    # pprint(current_elements)

                # if purge:
                #     cls.clear(kind=kind, category=name)

                elements = provider.list(kind, name)

                for element in list(elements.values()):
                    element["uuid"] = element['id']
                    element['type'] = 'string'
                    element["category"] = name

                    # element["user"] = user
                    element["kind"] = kind
                    element["provider"] = provider.cloud_type
                    if current_elements is not None:
                        for index in current_elements:
                            current = current_elements[index]
                            for attribute in [
                                    "username", "image", "flavor", "group"
                            ]:
                                if attribute in current and current[
                                        attribute] is not None:
                                    element[attribute] = current[attribute]
                    # print ("CCC", index, element["name"], element["flavor"])
                    cls.add(element)

                return True

            elif kind in ["batchjob"]:

                # provider = BatchProvider(name).provider
                # provider = BatchProvider(name)

                from cloudmesh_client.cloud.hpc.BatchProvider import BatchProvider
                provider = BatchProvider(name)

                vms = provider.list_job(name)
                for job in list(vms.values()):
                    job[u'uuid'] = job['id']
                    job[u'type'] = 'string'
                    job[u'category'] = name
                    # job[u'user'] = user

                    cls.add(job)
                    cls.save()
                return True

            elif kind not in ["secgroup"]:
                Console.error(
                    "refresh not supported for this kind: {}".format(kind))

        except Exception as ex:
            Console.error("Problem with secgroup")
            return False
    def initialize(self, cloudname, user=None):

        d = ConfigDict("cloudmesh.yaml")
        self.cloud_details = d["cloudmesh"]["clouds"][cloudname]

        # pprint(self.cloud_details)

        self.cloud = cloudname
        self.default_flavor = self.cloud_details["default"]["flavor"]
        self.default_image = self.cloud_details["default"]["image"]
        self.tenant = self.cloud_details['credentials']['OS_TENANT_NAME']
        version = 2
        credentials = self.cloud_details["credentials"]
        cert = False
        if "OS_CACERT" in credentials:
            if credentials["OS_CACERT"] is not False:
                cert = Config.path_expand(credentials["OS_CACERT"])
        auth_url = credentials["OS_AUTH_URL"]
        ksversion = auth_url.split("/")[-1]
        """
        # GitHub issue 101
        # mechanism to interactively ask for password
        # when OS_PASSWORD set as "readline",
        # or read os.environ if set as "env".
        """
        os_password = credentials["OS_PASSWORD"]
        prompt = "Password for cloud - {}:".format(cloudname)
        if os_password.lower() in ["readline", "read", "tbd"]:
            if cloudname in CloudProviderOpenstackAPI.cloud_pwd and \
                        'pwd' in CloudProviderOpenstackAPI.cloud_pwd[cloudname]:
                os_password = CloudProviderOpenstackAPI.cloud_pwd[cloudname][
                    "pwd"]
            else:
                os_password = getpass.getpass(prompt=prompt)
        elif os_password.lower() == "env":
            if cloudname in CloudProviderOpenstackAPI.cloud_pwd and \
                        'pwd' in CloudProviderOpenstackAPI.cloud_pwd[cloudname]:
                os_password = CloudProviderOpenstackAPI.cloud_pwd[cloudname][
                    "pwd"]
            else:
                os_password = os.environ.get("OS_PASSWORD",
                                             getpass.getpass(prompt=prompt))

        # store the password for this session
        CloudProviderOpenstackAPI.cloud_pwd[cloudname] = {}
        CloudProviderOpenstackAPI.cloud_pwd[cloudname]["pwd"] = os_password
        CloudProviderOpenstackAPI.cloud_pwd[cloudname]["status"] = "Active"

        if "v2.0" == ksversion:
            kws = dict(
                username=credentials['OS_USERNAME'],
                api_key=os_password,
                project_id=credentials['OS_TENANT_NAME'],
                auth_url=credentials['OS_AUTH_URL'],
            )
            if cert:
                kws['cacert'] = cert
                if not os.path.exists(cert):
                    Console.error(
                        'Certificate file `{}` not found'.format(cert))
            self.provider = client.Client(version, **kws)
        elif "v3" == ksversion:
            sess = session.Session(auth=self._ksv3_auth(credentials),
                                   verify=cert)
            self.provider = client.Client(2, session=sess)
Esempio n. 50
0
    def do_key(self, args, arguments):
        """
        ::

           Usage:
             key  -h | --help
             key list [--source=db] [--format=FORMAT]
             key list --source=cloudmesh [--format=FORMAT]
             key list --source=ssh [--dir=DIR] [--format=FORMAT]
             key list --source=git [--format=FORMAT] [--username=USERNAME]
             key add --git [--name=KEYNAME] FILENAME
             key add --ssh [--name=KEYNAME]
             key add [--name=KEYNAME] FILENAME
             key get NAME
             key default [KEYNAME | --select]
             key delete (KEYNAME | --select | --all) [-f]

           Manages the keys

           Arguments:

             SOURCE         db, ssh, all
             KEYNAME        The name of a key
             FORMAT         The format of the output (table, json, yaml)
             FILENAME       The filename with full path in which the key
                            is located

           Options:

              --dir=DIR            the directory with keys [default: ~/.ssh]
              --format=FORMAT      the format of the output [default: table]
              --source=SOURCE      the source for the keys [default: db]
              --username=USERNAME  the source for the keys [default: none]              
              --name=KEYNAME       The name of a key
              --all                delete all keys

           Description:

           key list --source=git  [--username=USERNAME]

              lists all keys in git for the specified user. If the
              name is not specified it is read from cloudmesh.yaml

           key list --source=ssh  [--dir=DIR] [--format=FORMAT]

              lists all keys in the directory. If the directory is not
              specified the default will be ~/.ssh

           key list --source=cloudmesh  [--dir=DIR] [--format=FORMAT]

              lists all keys in cloudmesh.yaml file in the specified directory.
               dir is by default ~/.cloudmesh

           key list [--format=FORMAT]

               list the keys in teh giiven format: json, yaml,
               table. table is default

           key list

                Prints list of keys. NAME of the key can be specified

               
           key add [--name=keyname] FILENAME

               adds the key specifid by the filename to the key
               database

           key get NAME

               Retrieves the key indicated by the NAME parameter from database
               and prints its fingerprint.

           key default [NAME]

                Used to set a key from the key-list as the default key
                if NAME is given. Otherwise print the current default
                key

           key delete NAME

                deletes a key. In yaml mode it can delete only key that
                are not saved in the database

           key rename NAME NEW

                renames the key from NAME to NEW.
                
        """
        # pprint(arguments)

        def _print_dict(d, header=None, format='table'):
            if format == "json":
                return json.dumps(d, indent=4)
            elif format == "yaml":
                return yaml.dump(d, default_flow_style=False)
            elif format == "table":
                return dict_printer(d,
                                    order=["name",
                                           "comment",
                                           "uri",
                                           "fingerprint",
                                           "source"],
                                    output="table",
                                    sort_keys=True)
            else:
                return d
                # return dict_printer(d,order=['cm_id, name, fingerprint'])

        directory = Config.path_expand(arguments["--dir"])

        if arguments['list']:
            _format = arguments['--format']
            _source = arguments['--source']
            _dir = arguments['--dir']

            if arguments['--source'] == 'ssh':

                try:
                    sshm = SSHKeyManager()
                    sshm.get_from_dir(directory)
                    d = dict(sshm.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception, e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem listing keys from ssh")

            elif arguments['--source'] in ['cm', 'cloudmesh']:

                try:
                    sshm = SSHKeyManager()
                    m = sshm.get_from_yaml(load_order=directory)
                    d = dict(m.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception, e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem listing keys from `{:}`".format(arguments['--source']))
Esempio n. 51
0
 def _get_config_yaml_file(arguments):
     filename = arguments["--yaml"] or "cloudmesh.yaml"
     filename = Config.find_file(filename)
     return filename
Esempio n. 52
0
    def do_key(self, args, arguments):
        """
        ::

           Usage:
             key  -h | --help
             key list [--source=db] [--format=FORMAT]
             key list --source=cloudmesh [--format=FORMAT]
             key list --source=ssh [--dir=DIR] [--format=FORMAT]
             key load [--format=FORMAT]
             key list --source=git [--format=FORMAT] [--username=USERNAME]
             key add --git [--name=KEYNAME] FILENAME
             key add --ssh [--name=KEYNAME]
             key add [--name=KEYNAME] FILENAME
             key get NAME
             key default [KEYNAME | --select]
             key delete (KEYNAME | --select | --all) [--force]
             key upload [KEYNAME] [--cloud=CLOUD]
             key map [--cloud=CLOUD]

           Manages the keys

           Arguments:

             SOURCE         db, ssh, all
             KEYNAME        The name of a key. For key upload it defaults to the default key name.
             FORMAT         The format of the output (table, json, yaml)
             FILENAME       The filename with full path in which the key
                            is located
             NAME_ON_CLOUD  Typically the name of the keypair on the cloud.

           Options:

              --dir=DIR                     the directory with keys [default: ~/.ssh]
              --format=FORMAT               the format of the output [default: table]
              --source=SOURCE               the source for the keys [default: db]
              --username=USERNAME           the source for the keys [default: none]
              --name=KEYNAME                The name of a key
              --all                         delete all keys
              --force                       delete the key form the cloud
              --name_on_cloud=NAME_ON_CLOUD Typically the name of the keypair on the cloud.

           Description:

           key list --source=git  [--username=USERNAME]

              lists all keys in git for the specified user. If the
              name is not specified it is read from cloudmesh.yaml

           key list --source=ssh  [--dir=DIR] [--format=FORMAT]

              lists all keys in the directory. If the directory is not
              specified the default will be ~/.ssh

           key list --source=cloudmesh  [--dir=DIR] [--format=FORMAT]

              lists all keys in cloudmesh.yaml file in the specified directory.
               dir is by default ~/.cloudmesh

           key list [--format=FORMAT]

               list the keys in teh giiven format: json, yaml,
               table. table is default

           key list

                Prints list of keys. NAME of the key can be specified

               
           key add [--name=keyname] FILENAME

               adds the key specifid by the filename to the key
               database

           key get NAME

               Retrieves the key indicated by the NAME parameter from database
               and prints its fingerprint.

           key default [NAME]

                Used to set a key from the key-list as the default key
                if NAME is given. Otherwise print the current default
                key

           key delete NAME

                deletes a key. In yaml mode it can delete only key that
                are not saved in the database

           key rename NAME NEW

                renames the key from NAME to NEW.
                
        """
        # pprint(arguments)

        def _print_dict(d, header=None, format='table'):
            if format == "json":
                return json.dumps(d, indent=4)
            elif format == "yaml":
                return yaml.dump(d, default_flow_style=False)
            elif format == "table":
                return dict_printer(d,
                                    order=["name",
                                           "comment",
                                           "uri",
                                           "fingerprint",
                                           "source"],
                                    output="table",
                                    sort_keys=True)
            else:
                return d
                # return dict_printer(d,order=['cm_id, name, fingerprint'])

        directory = Config.path_expand(arguments["--dir"])

        if arguments['list']:
            _format = arguments['--format']
            _source = arguments['--source']
            _dir = arguments['--dir']

            if arguments['--source'] == 'ssh':

                try:
                    sshm = SSHKeyManager()
                    sshm.get_from_dir(directory)
                    d = dict(sshm.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem listing keys from ssh")

            elif arguments['--source'] in ['cm', 'cloudmesh']:

                try:
                    sshm = SSHKeyManager()
                    m = sshm.get_from_yaml(load_order=directory)
                    d = dict(m.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem listing keys from `{:}`".format(arguments['--source']))

            elif arguments['--source'] in ['git']:

                username = arguments["--username"]
                # print(username)
                if username == 'none':
                    conf = ConfigDict("cloudmesh.yaml")
                    username = conf["cloudmesh.github.username"]

                sshm = SSHKeyManager()
                try:
                    sshm.get_from_git(username)
                    d = dict(sshm.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem listing git keys from database")
                    return ""

            elif arguments['--source'] == 'db':

                try:
                    sshdb = SSHKeyDBManager()
                    d = sshdb.table_dict()
                    if d != {}:
                        print(_print_dict(d, format=arguments['--format']))
                        msg = "info. OK."
                        Console.ok(msg)
                    else:
                        Console.error("No keys in the database")
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem listing keys from database")

        elif arguments['load']:
            _format = arguments['--format']
            _dir = arguments['--dir']

            try:
                sshm = SSHKeyManager()
                m = sshm.get_from_yaml(load_order=directory)
                d = dict(m.__keys__)

                sshdb = SSHKeyDBManager()

                for keyname in m.__keys__:
                    filename = m[keyname]["path"]
                    try:
                        sshdb.add(filename,
                                  keyname,
                                  source="yaml",
                                  uri="file://" + filename)
                    except Exception as e:
                        Console.error("problem adding key {}:{}".format(
                            keyname, filename))

                print(_print_dict(d, format=_format))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Console.error("Problem adding keys from yaml file")

        elif arguments['get']:

            try:
                name = arguments['NAME']
                sshdb = SSHKeyDBManager()
                d = sshdb.table_dict()

                for i in d:
                    if d[i]["name"] == name:
                        key = d[i]
                        print("{:}: {:}".format(key['name'], key['fingerprint']))
                        msg = "info. OK."
                        Console.ok(msg)
                        return ""
                    else:
                        pass
                Console.error("The key is not in the database")
            except Exception as e:
                import traceback
                print(traceback.format_exc())
                print (e)
                Console.error("The key is not in the database")

        # key add --git KEYNAME
        #      key add --ssh KEYNAME
        #      key add [--path=PATH]  KEYNAME

        elif arguments['add'] and arguments["--git"]:

            print('git add')
            sshdb = SSHKeyDBManager()
            keyname = arguments['--name']
            gitkeyname = arguments['NAME']
            filename = arguments['FILENAME']

            # Are we adding to the database as well?
            # sshdb.add(filename, keyname, source="ssh", uri="file://"+filename)

            username = arguments["--username"]

            if username == 'none':
                conf = ConfigDict("cloudmesh.yaml")
                username = conf["cloudmesh.github.username"]
            print(username)

            sshm = SSHKeyManager()
            try:
                sshm.get_from_git(username)
                d = dict(sshm.__keys__)
                print(d)
            except Exception as e:
                import traceback
                print(traceback.format_exc())
                print (e)
                Console.error("Problem adding keys to git for user: "******""

            try:
                # FIXME: correct code to add to git
                d[gitkeyname]['keyname'] = keyname
                d[gitkeyname]['user'] = None
                d[gitkeyname]['source'] = 'git'
                # sshdb.add_from_dict(d[gitkeyname])
            except Exception as e:
                Console.error("The key already exists")

        elif arguments['add'] and arguments["--ssh"]:

            # print('ssh add')
            sshdb = SSHKeyDBManager()
            keyname = arguments['--name']
            filename = Config.path_expand("~/.ssh/id_rsa.pub")
            try:
                sshdb.add(filename, keyname, source="ssh", uri="file://" + filename)
                print("Key {:} successfully added to the database".format(keyname or ""))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                """
                import traceback
                print(traceback.format_exc())
                print (e)
                print (keyname)
                print (filename)
                """
                Console.error("Problem adding the key `{}` from file `{}`".format(keyname, filename))

        elif arguments['add'] and not arguments["--git"]:

            # print('ssh add')
            sshdb = SSHKeyDBManager()
            keyname = arguments['--name']
            filename = arguments['FILENAME']
            try:
                sshdb.add(filename, keyname, source="ssh", uri="file://" + filename)
                print("Key {:} successfully added to the database".format(keyname or ""))
                msg = "info. OK."
                Console.ok(msg)

            except ValueError as e:
                Console.error("The key `{}` already exists".format(keyname), traceflag=False)
            """
            except Exception as e:
                import traceback
                print(traceback.format_exc())
                print (e)
                print (keyname)
                print (filename)
                Console.error("Problem adding the key `{}` from file `{}`".format(keyname, filename))
            """
            return ""

        elif arguments['default']:

            # print("default")

            if arguments['KEYNAME']:
                keyname = None
                try:
                    keyname = arguments['KEYNAME']
                    sshdb = SSHKeyDBManager()
                    sshdb.set_default(keyname)
                    Default.set_key(keyname)
                    print("Key {:} set as default".format(keyname))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Setting default for key {:} failed.".format(keyname))

            elif arguments['--select']:
                keyname = None
                try:
                    sshdb = SSHKeyDBManager()
                    select = sshdb.select()
                    if select != 'q':
                        keyname = select.split(':')[0]
                        print("Setting key: {:} as default.".format(keyname))
                        sshdb.set_default(keyname)
                        msg = "info. OK."
                        Console.ok(msg)
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Setting default for selected key {:} failed.".format(keyname))

            else:
                try:
                    sshdb = SSHKeyDBManager()
                    d = sshdb.table_dict()

                    for i in d:
                        if d[i]["is_default"] == "True":
                            key = d[i]
                            print("{:}: {:}".format(key['name'], key['fingerprint']))
                            msg = "info. OK."
                            Console.ok(msg)
                            return ""
                        else:
                            pass
                    Console.error("The key is not in the database")
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem retrieving default key.")

        elif arguments['delete']:

            delete_on_cloud = arguments["--force"] or False
            # print ("DDD", delete_on_cloud)
            if arguments['--all']:
                try:
                    sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud)
                    sshm.delete_all_keys()
                    print("All keys from the database deleted successfully.")
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem deleting keys")
            elif arguments['--select']:
                keyname = None
                sshdb = SSHKeyDBManager()
                select = sshdb.select()
                if select != 'q':
                    try:
                        keyname = select.split(':')[0]
                        print("Deleting key: {:}...".format(keyname))
                        sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud)
                        sshm.delete_key(keyname)
                        msg = "info. OK."
                        Console.ok(msg)
                    except Exception as e:
                        import traceback
                        print(traceback.format_exc())
                        print (e)
                        Console.error("Problem deleting the key `{:}`".format(keyname))
            else:
                keyname = None
                try:
                    keyname = arguments['KEYNAME']
                    sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud)
                    sshm.delete_key(keyname)
                    print("Key {:} deleted successfully from database.".format(keyname))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    import traceback
                    print(traceback.format_exc())
                    print (e)
                    Console.error("Problem deleting the key `{:}`".format(keyname))

        elif arguments['upload']:

            try:
                #
                # get username
                #
                conf = ConfigDict("cloudmesh.yaml")
                username = conf["cloudmesh"]["profile"]["username"]
                if username in ['None', 'TBD']:
                    username = None

                #
                # get cloudnames
                #
                clouds = []
                cloud = arguments["--cloud"] or Default.get_cloud()
                if cloud == "all":
                    config = ConfigDict("cloudmesh.yaml")
                    clouds = config["cloudmesh"]["clouds"]
                else:
                    clouds.append(cloud)

                #
                # get keyname
                #

                for cloud in clouds:
                    status = 0
                    sshdb = SSHKeyDBManager()
                    sshm = SSHKeyManager()
                    keys = sshdb.find_all()
                    for keyid in keys:
                        key = keys[keyid]

                        print ("upload key {} -> {}".format(key["name"],
                                                            cloud))

                        try:
                            status = sshm.add_key_to_cloud(
                                username,
                                key["name"],
                                cloud,
                                key["name"])

                        except Exception as e:
                            print (e)
                            if "already exists" in str(e):
                                print ("key already exists. Skipping "
                                       "upload. ok.")
                        if status == 1:
                            print("Problem uploading key. failed.")
                msg = "info. OK."
                Console.ok(msg)

            except Exception as e:
                import traceback
                print(traceback.format_exc())
                print (e)
                Console.error("Problem adding key to cloud")

        elif arguments['map']:
            try:
                cloud = arguments["--cloud"] or Default.get_cloud()
                sshm = SSHKeyManager()
                map_dict = sshm.get_key_cloud_maps(cloud)
                print(dict_printer(map_dict,
                                   order=["user", "key_name", "cloud_name", "key_name_on_cloud"]))

            except Exception as e:
                import traceback
                print(traceback.format_exc())
                print (e)
                Console.error("Problem adding key to cloud")
Esempio n. 53
0
    def do_key(self, args, arguments):
        """
        ::

           Usage:
             key  -h | --help
             key list [--source=db] [--format=FORMAT]
             key list --source=cloudmesh [--format=FORMAT]
             key list --source=ssh [--dir=DIR] [--format=FORMAT]
             key load [--format=FORMAT]
             key list --source=git [--format=FORMAT] [--username=USERNAME]
             key add --git [--name=KEYNAME] FILENAME
             key add --ssh [--name=KEYNAME]
             key add [--name=KEYNAME] FILENAME
             key get NAME
             key default [KEYNAME | --select]
             key delete (KEYNAME | --select | --all) [--force]
             key upload [KEYNAME] [--cloud=CLOUD]
             key map [--cloud=CLOUD]

           Manages the keys

           Arguments:

             SOURCE         db, ssh, all
             KEYNAME        The name of a key. For key upload it defaults to the default key name.
             FORMAT         The format of the output (table, json, yaml)
             FILENAME       The filename with full path in which the key
                            is located
             NAME_ON_CLOUD  Typically the name of the keypair on the cloud.

           Options:

              --dir=DIR                     the directory with keys [default: ~/.ssh]
              --format=FORMAT               the format of the output [default: table]
              --source=SOURCE               the source for the keys [default: db]
              --username=USERNAME           the source for the keys [default: none]
              --name=KEYNAME                The name of a key
              --all                         delete all keys
              --force                       delete the key form the cloud
              --name_on_cloud=NAME_ON_CLOUD Typically the name of the keypair on the cloud.

           Description:

           key list --source=git  [--username=USERNAME]

              lists all keys in git for the specified user. If the
              name is not specified it is read from cloudmesh.yaml

           key list --source=ssh  [--dir=DIR] [--format=FORMAT]

              lists all keys in the directory. If the directory is not
              specified the default will be ~/.ssh

           key list --source=cloudmesh  [--dir=DIR] [--format=FORMAT]

              lists all keys in cloudmesh.yaml file in the specified directory.
               dir is by default ~/.cloudmesh

           key list [--format=FORMAT]

               list the keys in teh giiven format: json, yaml,
               table. table is default

           key list

                Prints list of keys. NAME of the key can be specified

               
           key add [--name=keyname] FILENAME

               adds the key specifid by the filename to the key
               database

           key get NAME

               Retrieves the key indicated by the NAME parameter from database
               and prints its fingerprint.

           key default [NAME]

                Used to set a key from the key-list as the default key
                if NAME is given. Otherwise print the current default
                key

           key delete NAME

                deletes a key. In yaml mode it can delete only key that
                are not saved in the database

           key rename NAME NEW

                renames the key from NAME to NEW.
                
        """

        # pprint(arguments)

        def _print_dict(d, header=None, format='table'):
            if format == "json":
                return json.dumps(d, indent=4)
            elif format == "yaml":
                return yaml.dump(d, default_flow_style=False)
            elif format == "table":
                return dict_printer(
                    d,
                    order=["name", "comment", "uri", "fingerprint", "source"],
                    output="table",
                    sort_keys=True)
            else:
                return d
                # return dict_printer(d,order=['cm_id, name, fingerprint'])

        directory = Config.path_expand(arguments["--dir"])

        if arguments['list']:
            _format = arguments['--format']
            _source = arguments['--source']
            _dir = arguments['--dir']

            if arguments['--source'] == 'ssh':

                try:
                    sshm = SSHKeyManager()
                    sshm.get_from_dir(directory)
                    d = dict(sshm.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing keys from ssh")

            elif arguments['--source'] in ['cm', 'cloudmesh']:

                try:
                    sshm = SSHKeyManager()
                    m = sshm.get_from_yaml(load_order=directory)
                    d = dict(m.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing keys from `{:}`".format(
                        arguments['--source']))

            elif arguments['--source'] in ['git']:

                username = arguments["--username"]
                # print(username)
                if username == 'none':
                    conf = ConfigDict("cloudmesh.yaml")
                    username = conf["cloudmesh.github.username"]

                sshm = SSHKeyManager()
                try:
                    sshm.get_from_git(username)
                    d = dict(sshm.__keys__)
                    print(_print_dict(d, format=_format))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing git keys from database")
                    return ""

            elif arguments['--source'] == 'db':

                try:
                    sshdb = SSHKeyDBManager()
                    d = sshdb.table_dict()
                    if d != {}:
                        print(_print_dict(d, format=arguments['--format']))
                        msg = "info. OK."
                        Console.ok(msg)
                    else:
                        Console.error("No keys in the database")
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing keys from database")

        elif arguments['load']:
            _format = arguments['--format']
            _dir = arguments['--dir']

            try:
                sshm = SSHKeyManager()
                m = sshm.get_from_yaml(load_order=directory)
                d = dict(m.__keys__)

                sshdb = SSHKeyDBManager()

                for keyname in m.__keys__:
                    filename = m[keyname]["path"]
                    try:
                        sshdb.add(filename,
                                  keyname,
                                  source="yaml",
                                  uri="file://" + filename)
                    except Exception as e:
                        Console.error("problem adding key {}:{}".format(
                            keyname, filename))

                print(_print_dict(d, format=_format))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Console.error("Problem adding keys from yaml file")

        elif arguments['get']:

            try:
                name = arguments['NAME']
                sshdb = SSHKeyDBManager()
                d = sshdb.table_dict()

                for i in d:
                    if d[i]["name"] == name:
                        key = d[i]
                        print("{:}: {:}".format(key['name'],
                                                key['fingerprint']))
                        msg = "info. OK."
                        Console.ok(msg)
                        return ""
                    else:
                        pass
                Console.error("The key is not in the database")
            except Exception as e:
                Error.traceback(e)
                Console.error("The key is not in the database")

        # key add --git KEYNAME
        #      key add --ssh KEYNAME
        #      key add [--path=PATH]  KEYNAME

        elif arguments['add'] and arguments["--git"]:

            print('git add')
            sshdb = SSHKeyDBManager()
            keyname = arguments['--name']
            gitkeyname = arguments['NAME']
            filename = arguments['FILENAME']

            # Are we adding to the database as well?
            # sshdb.add(filename, keyname, source="ssh", uri="file://"+filename)

            username = arguments["--username"]

            if username == 'none':
                conf = ConfigDict("cloudmesh.yaml")
                username = conf["cloudmesh.github.username"]
            print(username)

            sshm = SSHKeyManager()
            try:
                sshm.get_from_git(username)
                d = dict(sshm.__keys__)
                print(d)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem adding keys to git for user: "******""

            try:
                # FIXME: correct code to add to git
                d[gitkeyname]['keyname'] = keyname
                d[gitkeyname]['user'] = None
                d[gitkeyname]['source'] = 'git'
                # sshdb.add_from_dict(d[gitkeyname])
            except Exception as e:
                Console.error("The key already exists")

        elif arguments['add'] and arguments["--ssh"]:

            # print('ssh add')
            sshdb = SSHKeyDBManager()
            keyname = arguments['--name']
            filename = Config.path_expand("~/.ssh/id_rsa.pub")
            try:
                sshdb.add(filename,
                          keyname,
                          source="ssh",
                          uri="file://" + filename)
                print("Key {:} successfully added to the database".format(
                    keyname or ""))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                """
                Error.traceback(e)
                print (keyname)
                print (filename)
                """
                Console.error(
                    "Problem adding the key `{}` from file `{}`".format(
                        keyname, filename))

        elif arguments['add'] and not arguments["--git"]:

            # print('ssh add')
            sshdb = SSHKeyDBManager()
            keyname = arguments['--name']
            filename = arguments['FILENAME']
            try:
                sshdb.add(filename,
                          keyname,
                          source="ssh",
                          uri="file://" + filename)
                print("Key {:} successfully added to the database".format(
                    keyname or ""))
                msg = "info. OK."
                Console.ok(msg)

            except ValueError as e:
                Console.error("The key `{}` already exists".format(keyname),
                              traceflag=False)
            """
            except Exception as e:
                Error.traceback(e)
                print (keyname)
                print (filename)
                Console.error("Problem adding the key `{}` from file `{}`".format(keyname, filename))
            """
            return ""

        elif arguments['default']:

            # print("default")

            if arguments['KEYNAME']:
                keyname = None
                try:
                    keyname = arguments['KEYNAME']
                    sshdb = SSHKeyDBManager()
                    sshdb.set_default(keyname)
                    Default.set_key(keyname)
                    print("Key {:} set as default".format(keyname))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error(
                        "Setting default for key {:} failed.".format(keyname))

            elif arguments['--select']:
                keyname = None
                try:
                    sshdb = SSHKeyDBManager()
                    select = sshdb.select()
                    if select != 'q':
                        keyname = select.split(':')[0]
                        print("Setting key: {:} as default.".format(keyname))
                        sshdb.set_default(keyname)
                        msg = "info. OK."
                        Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error(
                        "Setting default for selected key {:} failed.".format(
                            keyname))

            else:
                try:
                    sshdb = SSHKeyDBManager()
                    d = sshdb.table_dict()

                    for i in d:
                        if d[i]["is_default"] == "True":
                            key = d[i]
                            print("{:}: {:}".format(key['name'],
                                                    key['fingerprint']))
                            msg = "info. OK."
                            Console.ok(msg)
                            return ""
                        else:
                            pass
                    Console.error("The key is not in the database")
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem retrieving default key.")

        elif arguments['delete']:

            delete_on_cloud = arguments["--force"] or False
            # print ("DDD", delete_on_cloud)
            if arguments['--all']:
                try:
                    sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud)
                    sshm.delete_all_keys()
                    print("All keys from the database deleted successfully.")
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem deleting keys")
            elif arguments['--select']:
                keyname = None
                sshdb = SSHKeyDBManager()
                select = sshdb.select()
                if select != 'q':
                    try:
                        keyname = select.split(':')[0]
                        print("Deleting key: {:}...".format(keyname))
                        sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud)
                        sshm.delete_key(keyname)
                        msg = "info. OK."
                        Console.ok(msg)
                    except Exception as e:
                        Error.traceback(e)
                        Console.error(
                            "Problem deleting the key `{:}`".format(keyname))
            else:
                keyname = None
                try:
                    keyname = arguments['KEYNAME']
                    sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud)
                    sshm.delete_key(keyname)
                    print("Key {:} deleted successfully from database.".format(
                        keyname))
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error(
                        "Problem deleting the key `{:}`".format(keyname))

        elif arguments['upload']:

            try:
                #
                # get username
                #
                conf = ConfigDict("cloudmesh.yaml")
                username = conf["cloudmesh"]["profile"]["username"]
                if username in ['None', 'TBD']:
                    username = None

                #
                # get cloudnames
                #
                clouds = []
                cloud = arguments["--cloud"] or Default.get_cloud()
                if cloud == "all":
                    config = ConfigDict("cloudmesh.yaml")
                    clouds = config["cloudmesh"]["clouds"]
                else:
                    clouds.append(cloud)

                #
                # get keyname
                #

                for cloud in clouds:
                    status = 0
                    sshdb = SSHKeyDBManager()
                    sshm = SSHKeyManager()
                    keys = sshdb.find_all()
                    for keyid in keys:
                        key = keys[keyid]

                        print("upload key {} -> {}".format(key["name"], cloud))

                        try:
                            status = sshm.add_key_to_cloud(
                                username, key["name"], cloud, key["name"])

                        except Exception as e:
                            print(e)
                            if "already exists" in str(e):
                                print("key already exists. Skipping "
                                      "upload. ok.")
                        if status == 1:
                            print("Problem uploading key. failed.")
                msg = "info. OK."
                Console.ok(msg)

            except Exception as e:
                Error.traceback(e)
                Console.error("Problem adding key to cloud")

        elif arguments['map']:
            try:
                cloud = arguments["--cloud"] or Default.get_cloud()
                sshm = SSHKeyManager()
                map_dict = sshm.get_key_cloud_maps(cloud)
                print(
                    dict_printer(map_dict,
                                 order=[
                                     "user", "key_name", "cloud_name",
                                     "key_name_on_cloud"
                                 ]))

            except Exception as e:
                Error.traceback(e)
                Console.error("Problem adding key to cloud")
Esempio n. 54
0
 def make_dir(cls, directory):
     if not os.path.exists(Config.path_expand(directory)):
         os.makedirs(Config.path_expand(directory))