예제 #1
0
    def boot(self, cloud=None, image=None, flavor=None, key=None,  arguments=None):
        """
        Boots the image on a specified cloud

        :param image: The name of the image
        :type image: str
        :param flavor: The name of the flavor
        :type flavor: str
        :param key: The name of the key
        :type key: str
        :param cloud: The name of the cloud
        :type cloud: str
        :param arguments: An array of arguments
        :type arguments: list of str
        :return: the id of the vm
        :rtype: str
        """
        if cloud is None:
            cloud =  Default.get("cloud", "general")
            print("get default cloud: " + str(cloud))
        if image is None:
            image =  Default.get("image", cloud)
            print("get default image ", str(image))
        if flavor is None:
            flavor =  Default.get("flavor", cloud)
            print("get default flavor ", str(flavor))
        if key is None:
            key =  Default.get("key", str(cloud))
            print("get default key ", str(key))

        # command_key

        print("boot an image", image, flavor, key, cloud, arguments)
        pass
예제 #2
0
    def test_003(self):
        HEADING("set default image")
        name = self.data.image

        print(self.data)
        Default.set_image(name, self.data.cloud)

        print(Default.get(name=name, category=self.data.cloud))

        assert Default.get(name="image", category=self.data.cloud) == name
예제 #3
0
    def test_003(self):
        HEADING("set default image")
        name = self.data.image

        print(self.data)
        Default.set_image(name, self.data.cloud)

        print(Default.get(name=name, category=self.data.cloud))

        assert Default.get(name="image", category=self.data.cloud) == name
예제 #4
0
 def test_007(self):
     HEADING(" set default variable ")
     name = "myvar"
     value = "myvalue"
     cloud = self.data.cloud
     Default.set(name, value, cloud)
     assert Default.get(name=name, category=cloud) == value
예제 #5
0
    def get_info(cls, category="kilo", name=None, output="table"):
        """
        Method to get info about a group
        :param cloud:
        :param name:
        :param output:
        :return:
        """
        try:
            cloud = category or Default.get("cloud")
            args = {
                "name": name,
                "category": category
            }

            # group = cls.get(name=name, category=cloud)
            group = cls.cm.find("group", output="object", **args).first()

            if group is not None:
                d = cls.to_dict(group)
                # Transform the dict to show multiple rows per vm
                newdict = Group.transform_dict(d)
            else:
                return None

            return dict_printer(newdict,
                                order=cls.order,
                                output=output)
        except Exception as ex:
            Console.error(ex.message, ex)
예제 #6
0
    def test_004(self):
        print(Printer.write(self.cm.info()))

        m = Default.set_counter("index", 2)
        self.cm.add(m)

        o = Default.get_counter('index')
        print("OOO", o)

        Default.set_counter("index", 0)

        for i in range(0, 10):
            Default.incr_counter("index")

        print(Printer.write(self.cm.info()))

        c = self.cm.all(kind="default")

        print(Printer.write(c, order=['name', 'value', 'provider', 'type']))

        print(Default.get_counter(name="index"))

        i = Default.get(name="index")
        assert type(i) == int
        assert i == 10

        i = Default.index
        assert type(i) == int
        assert i == 10
예제 #7
0
 def test_007(self):
     HEADING(" set default variable ")
     name = "myvar"
     value = "myvalue"
     cloud = self.data.cloud
     Default.set(name, value, cloud)
     assert Default.get(name=name, category=cloud) == value
예제 #8
0
    def __init__(self, context):
        cmd.Cmd.__init__(self)
        self.command_topics = {}
        self.register_topics()
        self.context = context
        if self.context.debug:
            print("init CloudmeshConsole")

        self.prompt = 'ghost> '

        self.banner = textwrap.dedent("""
            +==========================================================+
            .                          _   .-')       ('-.   .-') _    .
            .                         ( '.( OO )_   _(  OO) (  OO) )   .
            .     .-----.  .-'),-----. ,--.   ,--.)(,------./     '._  .
            .    '  .--./ ( OO'  .-.  '|   `.'   |  |  .---'|'--...__) .
            .    |  |('-. /   |  | |  ||         |  |  |    '--.  .--' .
            .   /_) |OO  )\_) |  |\|  ||  |'.'|  | (|  '--.    |  |    .
            .   ||  |`-'|   \ |  | |  ||  |   |  |  |  .--'    |  |    .
            .  (_'  '--'\    `'  '-'  '|  |   |  |  |  `---.   |  |    .
            .     `-----'      `-----' `--'   `--'  `------'   `--'    .
            +==========================================================+
                                  Comet Ghost Shell
            """)
        # KeyCommands.__init__(self, context)

        #
        # set default cloud and default group if they do not exist
        # use the first cloud in cloudmesh.yaml as default
        #
        value = Default.get('cloud', 'general')
        if value is None:
            filename = path_expand("~/.cloudmesh/cloudmesh.yaml")
            clouds = ConfigDict(filename=filename)["cloudmesh"]["clouds"]
            cloud = clouds.keys()[0]
            Default.set('cloud', cloud, 'general')

        value = Default.get('default', 'general')
        if value is None:
            Default.set('default', 'default', 'general')

        for c in CloudmeshConsole.__bases__[1:]:
            # noinspection PyArgumentList
            c.__init__(self, context)
예제 #9
0
    def do_var(self, arg, arguments):
        """
        Usage:
            var list
            var delete NAMES
            var NAME=VALUE
            var NAME

        Arguments:
            NAME    Name of the variable
            NAMES   Names of the variable separated by spaces
            VALUE   VALUE to be assigned

        special vars date and time are defined
        """

        if arguments['list'] or arg == '' or arg is None:
            # self._list_variables()
            print(Var.list())
            return ""
        elif arguments['NAME=VALUE'] and "=" in arguments["NAME=VALUE"]:
            (variable, value) = arg.split('=', 1)
            if value == "time" or value == "now":
                value = datetime.datetime.now().strftime("%H:%M:%S")
            elif value == "date":
                value = datetime.datetime.now().strftime("%Y-%m-%d")
            elif value.startswith("default."):
                name = value.replace("default.", "")
                value = Default.get(name=name, category="general")
            elif "." in value:
                try:
                    config = ConfigDict("cloudmesh.yaml")
                    value = config[value]
                except Exception as e:
                    Console.error(
                        "can not find variable {} in cloudmesh.yaml".format(
                            value))
                    value = None
            # self._add_variable(variable, value)
            Var.set(variable, value)
            return ""
        elif arguments['NAME=VALUE'] and "=" not in arguments["NAME=VALUE"]:
            try:
                v = arguments['NAME=VALUE']
                # Console.ok(str(self.variables[v]))
                Console.ok(str(Var.get(v)))
            except:
                Console.error('variable {:} not defined'.format(
                    arguments['NAME=VALUE']))

        elif arg.startswith('delete'):
            variable = arg.split(' ')[1]
            Var.delete(variable)
            # self._delete_variable(variable)
            return ""
예제 #10
0
 def test_007(self):
     """
     set default variable
     :return:
     """
     HEADING()
     name = "myvar"
     value = "myvalue"
     cloud = "mycloud"
     Default.set(name, value, cloud)
     assert Default.get(name, cloud) == value
     self._check(value)
예제 #11
0
 def test_007(self):
     """
     set default variable
     :return:
     """
     HEADING()
     name = "myvar"
     value = "myvalue"
     cloud = "mycloud"
     Default.set(name, value, cloud)
     assert Default.get(name, cloud) == value
     self._check(value)
예제 #12
0
파일: cm.py 프로젝트: cloudmesh/client
    def do_var(self, arg, arguments):
        """
        Usage:
            var list
            var delete NAMES
            var NAME=VALUE
            var NAME

        Arguments:
            NAME    Name of the variable
            NAMES   Names of the variable separated by spaces
            VALUE   VALUE to be assigned

        special vars date and time are defined
        """

        if arguments['list'] or arg == '' or arg is None:
            # self._list_variables()
            print(Var.list())
            return ""
        elif arguments['NAME=VALUE'] and "=" in arguments["NAME=VALUE"]:
            (variable, value) = arg.split('=', 1)
            if value == "time" or value == "now":
                value = datetime.datetime.now().strftime("%H:%M:%S")
            elif value == "date":
                value = datetime.datetime.now().strftime("%Y-%m-%d")
            elif value.startswith("default."):
                name = value.replace("default.", "")
                value = Default.get(name=name, category="general")
            elif "." in value:
                try:
                    config = ConfigDict("cloudmesh.yaml")
                    value = config[value]
                except Exception as e:
                    Console.error("can not find variable {} in cloudmesh.yaml".format(value))
                    value = None
            # self._add_variable(variable, value)
            Var.set(variable, value)
            return ""
        elif arguments['NAME=VALUE'] and "=" not in arguments["NAME=VALUE"]:
            try:
                v = arguments['NAME=VALUE']
                # Console.ok(str(self.variables[v]))
                Console.ok(str(Var.get(v)))
            except:
                Console.error('variable {:} not defined'.format(arguments['NAME=VALUE']))

        elif arg.startswith('delete'):
            variable = arg.split(' ')[1]
            Var.delete(variable)
            # self._delete_variable(variable)
            return ""
예제 #13
0
    def boot(self,
             cloud=None,
             image=None,
             flavor=None,
             key=None,
             arguments=None):
        """
        Boots the image on a specified cloud

        :param image: The name of the image
        :type image: str
        :param flavor: The name of the flavor
        :type flavor: str
        :param key: The name of the key
        :type key: str
        :param cloud: The name of the cloud
        :type cloud: str
        :param arguments: An array of arguments
        :type arguments: list of str
        :return: the id of the vm
        :rtype: str
        """
        if cloud is None:
            cloud = Default.get("cloud", "general")
            print("get default cloud: " + str(cloud))
        if image is None:
            image = Default.get("image", cloud)
            print("get default image ", str(image))
        if flavor is None:
            flavor = Default.get("flavor", cloud)
            print("get default flavor ", str(flavor))
        if key is None:
            key = Default.get("key", str(cloud))
            print("get default key ", str(key))

        # command_key

        print("boot an image", image, flavor, key, cloud, arguments)
        pass
예제 #14
0
    def get_level():
        """
        get the log level from database
        :param cloudname: The name of the cloud
        :return: the log level
        """
        log_level = Default.get(name=LogUtil.LOG_LEVEL_KEY,
                                category=LogUtil.category)

        LOGGER.info("Returning Log Level: " + log_level)

        # return the level
        return log_level
예제 #15
0
    def save():
        """
        save the loglevel for a cloud to the cloudmesh.yaml file
        """
        # TODO: BUG: this seems inconsistant as loglevels via default
        # can now be defined for clouds, but the yaml file only
        # specifies one value for all clouds.

        # get the log level from database
        log_level = Default.get(
            name=LogUtil.LOG_LEVEL_KEY,
            category=LogUtil.category) or LogUtil.DEFAULT_LOG_LEVEL

        # Update the cloudmesh config
        config = ConfigDict("cloudmesh.yaml")
        config["cloudmesh"]["logging"]["level"] = log_level

        # Save this into cloudmesh yaml
        config.save()
예제 #16
0
    def do_usage(self, args, arguments):
        """
        ::

            Usage:
                usage list [--cloud=CLOUD] [--start=START] [--end=END] [--tenant=TENANT] [--format=FORMAT]

                Show usage data.

            Options:
               --format=FORMAT  the output format [default: table]
               --cloud=CLOUD    the cloud name
               --tenant=TENANT  the tenant name
               --start=START    Usage range start date ex 2012-01-20, default is: 4 weeks ago
               --end=END        Usage range end date, ex 2012-01-20, default is: tomorrow


            Examples:
                cm usage list

        """

        if arguments["list"]:
            cloud = arguments["--cloud"] or Default.get("cloud")

            if not cloud:
                Console.error("cloud doesn't exist")
                return ""
            output_format = arguments["--format"]
            start = arguments["--start"]
            end = arguments["--end"]
            tenant = arguments["--tenant"]
            usage = Usage.list(cloud,
                               start=start,
                               end=end,
                               tenant=tenant,
                               format=output_format)
            Console.msg(usage)
            return ""
예제 #17
0
    def do_hpc(self, args, arguments):
        # noinspection PyPep8
        """
                ::

                    Usage:
                        hpc queue [--job=NAME][--cluster=CLUSTER][--format=FORMAT]
                        hpc info [--cluster=CLUSTER][--format=FORMAT]
                        hpc run list [ID] [--cluster=CLUSTER]
                        hpc run output [ID] [--cluster=CLUSTER]
                        hpc run rm [ID] [--cluster=CLUSTER]
                        hpc run SCRIPT [--queue=QUEUE] [--t=TIME] [--N=nodes] [--name=NAME] [--cluster=CLUSTER][--dir=DIR][--group=GROUP][--format=FORMAT]
                        hpc delete --job=NAME [--cluster=CLUSTER][--group=GROUP]
                        hpc delete all [--cluster=CLUSTER][--group=GROUP][--format=FORMAT]
                        hpc status [--job=name] [--cluster=CLUSTER] [--group=GROUP]
                        hpc test --cluster=CLUSTER [--time=SECONDS]

                    Options:
                       --format=FORMAT  the output format [default: table]

                    Examples:

                        Special notes

                           if the group is specified only jobs from that group are
                           considered. Otherwise the default group is used. If the
                           group is set to None, all groups are used.

                        cm hpc queue
                            lists the details of the queues of the hpc cluster

                        cm hpc queue --job=NAME
                            lists the details of the job in the queue of the hpc cluster

                        cm hpc info
                            lists the details of the hpc cluster

                        cm hpc run SCRIPT
                            submits the script to the cluster. The script will be
                            copied prior to execution into the home directory on the
                            remote machine. If a DIR is specified it will be copied
                            into that dir.
                            The name of the script is either specified in the script
                            itself, or if not the default naming scheme of
                            cloudmesh is used using the same index incremented name
                            as in vms fro clouds: cloudmes husername-index

                        cm hpc delete all
                            kills all jobs on the default hpc group

                        cm hpc delete --job=NAME
                            kills a job with a given name or job id

                        cm default cluster=NAME
                            sets the default hpc cluster

                        cm hpc status
                            returns the status of all jobs

                        cm hpc status job=ID
                            returns the status of the named job

                        cm hpc test --cluster=CLUSTER --time=SECONDS
                            submits a simple test job to the named cluster and returns
                            if the job could be successfully executed. This is a
                            blocking call and may take a long time to complete
                            dependent on if the queuing system of that cluster is
                            busy. It will only use one node/core and print the message

                            #CLOUDMESH: Test ok

                            in that is being looked for to identify if the test is
                            successful. If time is used, the job is terminated
                            after the time is elapsed.

                    Examples:
                        cm hpc queue
                        cm hpc queue --job=xxx
                        cm hpc info
                        cm hpc delete --job=6
                        cm hpc delete all
                        cm hpc status
                        cm hpc status --job=6
                        cm hpc run uname
                        cm hpc run ~/test.sh --cluster=india
                """

        format = arguments['--format']
        cluster = arguments['--cluster'] or Default.get_cluster()
        arguments["CLUSTER"] = cluster

        if cluster is None:
            Console.error("Default cluster doesn't exist")
            return

        batch = BatchProvider(cluster)

        if arguments["queue"]:
            name = arguments['--job']
            result = batch.queue(cluster, format=format, job=name)
            Console.msg(result)

        elif arguments["info"]:
            Console.msg(batch.info(cluster, format))

        elif arguments['delete'] and arguments['all']:
            group = arguments['--group'] or Default.get('group')
            if group is None:
                Console.error('set default group using: default group=<value> --cloud=general')
                return
            Console.ok(batch.delete(cluster, None, group))

        elif arguments["delete"]:
            job = arguments['--job']
            Console.ok(batch.delete(cluster, job))

        elif arguments["status"]:
            name = arguments['--job']
            result = batch.queue(cluster, format=format, job=name)
            Console.msg(result)

        elif arguments["test"]:
            time_secs = arguments['--time']
            if time_secs:
                time = '00:00:' + time_secs
            else:
                time = '00:00:10'  # give a  default time of 10 secs
            print(batch.test(cluster, time))

        elif arguments["run"] and arguments["list"]:
            # hpc experiment list [--cluster=CLUSTER]
            if arguments["ID"]:
                print ("# List of experiment {ID} on Cluster {CLUSTER}".format(**arguments))
                result = Experiment.list(cluster, id=arguments["ID"], format="list")
                if result is not None:
                    print ("\n".join(result))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))
            else:
                print ("# List of experiments on Cluster {CLUSTER}".format(**arguments))
                ids = Experiment.list(cluster, id=None, format="list")
                if ids is not None:
                    print (", ".join([str(i) for i in ids]))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))

        elif arguments["run"] and arguments["rm"]:
            # hpc experiment list [--cluster=CLUSTER]
            if arguments["ID"]:

                force = yn_choice("Would you like to delete experiment {ID} on Cluster {CLUSTER}".format(**arguments))
                if force:
                    try:
                        result = Experiment.rm(cluster, id=arguments["ID"])
                        Console.ok("Experiment {ID} on Cluster {CLUSTER} deleted".format(**arguments))
                    except:
                        Console.error("Could not delete experiment {ID} on {CLUSTER}".format(**arguments))
            else:
                result = Experiment.list(cluster, id=None, format="list")
                if result is not None:
                    arguments['experiments'] = ", ".join([str(i) for i in result])
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))
                    return ""

                force = yn_choice("Would you like to delete the experiments {experiments} on Cluster {CLUSTER}".format(
                    **arguments))
                if force:
                    try:
                        result = Experiment.rm(cluster, id=None)
                        Console.ok("Experiments {experiments} on Cluster {CLUSTER} deleted".format(**arguments))
                    except:
                        Console.error("Could delete the experiments on {CLUSTER}".format(**arguments))
                return ""

        elif arguments["run"] and arguments["output"]:
            # hpc experiment list [--cluster=CLUSTER]
            if arguments["ID"]:
                print ("# List of experiment {ID} on Cluster {CLUSTER}".format(**arguments))
                result = Experiment.output(cluster, id=arguments["ID"], format="list")
                if result is not None:
                    print ("\n".join(result))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))
            else:
                print ("# List of experiments on Cluster {CLUSTER}".format(**arguments))
                ids = Experiment.output(cluster, id=None, format="list")
                if ids is not None:
                    print (", ".join([str(i) for i in ids]))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))

        elif arguments["run"]:
            queue = arguments['--queue'] or Default.get('queue')
            # if not queue:
            #    Console.error('set default queue using: default queue=<value>')
            #    return
            group = arguments['--group'] or Default.get('group')
            if group is None:
                Console.error('set default group using: default group=<value> --cloud=general')
                return

            script = arguments['SCRIPT']
            arg_dict = {
                '-name': arguments['--name'],
                '-p': queue,
                '-t': arguments['--t'],
                '-N': arguments['--N']
            }

            result = batch.run(cluster, group, script, **arg_dict)
            if isinstance(result, dict):
                print (attribute_printer(result))
                Console.ok("Experiment {count}: Started batch job {job_id} on {cluster}".format(**result))
            else:
                Console.error(result)

        return ""
예제 #18
0
    def do_vm(self, args, arguments):
        """
        ::

            Usage:
                vm default [--cloud=CLOUD][--format=FORMAT]
                vm refresh [--cloud=CLOUD]
                vm boot [--name=NAME]
                        [--cloud=CLOUD]
                        [--image=IMAGE_OR_ID]
                        [--flavor=FLAVOR_OR_ID]
                        [--group=GROUP]
                        [--secgroup=SECGROUP]
                        [--key=KEY]
                        [--dryrun]
                vm start [NAME]...
                         [--group=GROUP]
                         [--cloud=CLOUD]
                         [--force]
                vm stop [NAME]...
                        [--group=GROUP]
                        [--cloud=CLOUD]
                        [--force]
                vm delete [NAME]...
                          [--group=GROUP]
                          [--cloud=CLOUD]
                          [--force]
                vm ip assign [NAME]...
                          [--cloud=CLOUD]
                vm ip show [NAME]...
                           [--group=GROUP]
                           [--cloud=CLOUD]
                           [--format=FORMAT]
                           [--refresh]
                vm login [NAME] [--user=USER]
                         [--ip=IP]
                         [--cloud=CLOUD]
                         [--key=KEY]
                         [--command=COMMAND]
                vm rename [NAME]...
                          [--new=NEWNAME]
                          [--cloud=CLOUD]
                vm list [NAME_OR_ID]
                        [--cloud=CLOUD|--all]
                        [--group=GROUP]
                        [--format=FORMAT]
                        [--refresh]
                vm status [--cloud=CLOUD]
                vm info [--cloud=CLOUD]
                        [--format=FORMAT]

            Arguments:
                COMMAND        positional arguments, the commands you want to
                               execute on the server(e.g. ls -a) separated by ';',
                               you will get a return of executing result instead of login to
                               the server, note that type in -- is suggested before
                               you input the commands
                NAME           server name. By default it is set to the name of last vm from database.
                NAME_OR_ID     server name or ID
                KEYPAIR_NAME   Name of the openstack keypair to be used to create VM. Note this is not a path to key.
                NEWNAME        New name of the VM while renaming.

            Options:
                --ip=IP          give the public ip of the server
                --cloud=CLOUD    give a cloud to work on, if not given, selected
                                 or default cloud will be used
                --count=COUNT    give the number of servers to start
                --detail         for table print format, a brief version
                                 is used as default, use this flag to print
                                 detailed table
                --flavor=FLAVOR_OR_ID  give the name or id of the flavor
                --group=GROUP          give the group name of server
                --secgroup=SECGROUP    security group name for the server
                --image=IMAGE_OR_ID    give the name or id of the image
                --key=KEY        specify a key to use, input a string which
                                 is the full path to the private key file
                --keypair_name=KEYPAIR_NAME   Name of the openstack keypair to be used to create VM.
                                              Note this is not a path to key.
                --user=USER      give the user name of the server that you want
                                 to use to login
                --name=NAME      give the name of the virtual machine
                --force          delete vms without user's confirmation
                --command=COMMAND
                                 specify the commands to be executed
                --new=NEWNAME    Specify the new name for a VM while renaming.
                                 By default, this will be set to <username>-<count> format.



            Description:
                commands used to boot, start or delete servers of a cloud

                vm default [options...]     Displays default parameters that are set for VM boot.
                vm boot [options...]        Boots servers on a cloud, user may specify
                                            flavor, image .etc, otherwise default values
                                            will be used, see how to set default values
                                            of a cloud: cloud help
                vm start [options...]       Starts a suspended or stopped vm instance.
                vm stop [options...]        Stops a vm instance .
                vm delete [options...]      delete servers of a cloud, user may delete
                                            a server by its name or id, delete servers
                                            of a group or servers of a cloud, give prefix
                                            and/or range to find servers by their names.
                                            Or user may specify more options to narrow
                                            the search
                vm floating_ip_assign [options...]   assign a public ip to a VM of a cloud
                vm ip show [options...]     show the ips of VMs
                vm login [options...]       login to a server or execute commands on it
                vm list [options...]        same as command "list vm", please refer to it
                vm status [options...]      Retrieves status of last VM booted on cloud and displays it.

            Tip:
                give the VM name, but in a hostlist style, which is very
                convenient when you need a range of VMs e.g. sample[1-3]
                => ['sample1', 'sample2', 'sample3']
                sample[1-3,18] => ['sample1', 'sample2', 'sample3', 'sample18']

        """

        def _print_dict(d, header=None, format='table'):
            if format == "json":
                return json.dumps(d, indent=4)
            elif format == "yaml":
                return pyaml.dump(d)
            elif format == "table":
                return dict_printer(d,
                                    order=["id",
                                           "name",
                                           "status"],
                                    output="table",
                                    sort_keys=True)
            else:
                return d

        def _print_dict_ip(d, header=None, format='table'):
            if format == "json":
                return json.dumps(d, indent=4)
            elif format == "yaml":
                return pyaml.dump(d)
            elif format == "table":
                return dict_printer(d,
                                    order=["network",
                                           "version",
                                           "addr"],
                                    output="table",
                                    sort_keys=True)
            else:
                return d

        """
        def list_vms_on_cloud(cloud="kilo", group=None, format="table"):

            Utility reusable function to list vms on the cloud.
            :param cloud:
            :param group:
            :param format:
            :return:

            _cloud = cloud
            _group = group
            _format = format

            cloud_provider = CloudProvider(_cloud).provider
            servers = cloud_provider.list_vm(_cloud)


            server_list = {}
            index = 0
            # TODO: Improve the implementation to display more fields if required.
            for server in servers:
                server_list[index] = {}
                server_list[index]["name"] = server.name
                server_list[index]["id"] = server.id
                server_list[index]["status"] = server.status
                index += 1


            # TODO: Get this printed in a table
            print("Print table")
            dict_printer(servers, output=_format)
        """

        # pprint(arguments)

        def _refresh():
            try:
                msg = "Refresh VMs for cloud {:}.".format(cloud)
                if Vm.refresh(cloud=cloud):
                    Console.ok("{:} OK.".format(msg))
                else:
                    Console.error("{:} failed".format(msg))
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem running VM refresh")

        cloud = arguments["--cloud"] or Default.get_cloud()

        if arguments["boot"]:
            name = None
            try:
                name = arguments["--name"]
                is_name_provided = True

                if name is None:
                    is_name_provided = False

                    count = Counter.get()
                    prefix = Username()

                    if prefix is None or count is None:
                        Console.error("Prefix and Count could not be retrieved correctly.")
                        return

                    # BUG THE Z FILL SHOULD BE detected from yaml file
                    name = prefix + "-" + str(count).zfill(3)

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                image = arguments["--image"] or Default.get("image",
                                                            category=cloud)
                # if default image not set, return error
                if not image:
                    Console.error("Default image not set.")
                    return ""

                flavor = arguments["--flavor"] or Default.get("flavor",
                                                              category=cloud)
                # if default flavor not set, return error
                if not flavor:
                    Console.error("Default flavor not set.")
                    return ""

                group = arguments["--group"] or Default.get_group()

                # if default group not set, return error
                if not group:
                    group = "default"
                    Default.set_group(group)

                secgroup = arguments["--secgroup"] or Default.get(
                    "secgroup", category=cloud)
                # print("SecurityGrp : {:}".format(secgroup))
                secgroup_list = ["default"]
                if secgroup is not None:
                    secgroup_list.append(secgroup)

                key_name = arguments["--key"] or Default.get_key()
                # if default keypair not set, return error
                if not key_name:
                    Console.error("Default key not set.")
                    return ""

                if arguments["--dryrun"]:

                    data = {
                        "cloud": cloud,
                        "name": name,
                        "image": image,
                        "flavor": flavor,
                        "key_name": key_name,
                        "secgroup_list": secgroup_list,
                        "group": group
                    }
                    print (attribute_printer(data, output="table"))
                    msg = "dryrun info. OK."
                    Console.ok(msg)
                else:
                    vm_id = Vm.boot(cloud=cloud,
                                    name=name,
                                    image=image,
                                    flavor=flavor,
                                    key_name=key_name,
                                    secgroup_list=secgroup_list)
                    Default.set("last_vm_id", vm_id)
                    Default.set("last_vm_name", name)

                    # SHOULD WE NOT DO THIS BY DEFAULT EVEN IF WE SPECIFY THE NAME?
                    if is_name_provided is False:
                        # Incrementing count
                        Counter.incr()

                    # Add to group
                    if vm_id is not None:
                        Group.add(name=group, type="vm", id=name,
                                  category=cloud)

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

            except Exception as e:
                Error.traceback(e)
                Console.error("Problem booting instance {:}".format(name))

        elif arguments["default"]:
            try:
                count = Counter.get()
                prefix = Username()

                if prefix is None or count is None:
                    Console.error("Prefix and Count could not be retrieved correctly.")
                    return

                vm_name = prefix + "-" + str(count).zfill(3)
                data = {"name": vm_name,
                        "cloud": arguments["--cloud"] or Default.get_cloud()}
                for attribute in ["image", "flavor", "key", "login_key", "group", "secgroup"]:
                    data[attribute] = Default.get(attribute, category=cloud)
                output_format = arguments["--format"] or "table"
                print (attribute_printer(data, output=output_format))
                msg = "info. OK."
                Console.ok(msg)
                ValueError("default command not implemented properly. Upon "
                           "first install the defaults should be read from yaml.")
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem listing defaults")

        elif arguments["status"]:
            try:
                cloud_provider = CloudProvider(cloud).provider
                vm_list = cloud_provider.list_vm(cloud)
                print("Status of VM {} is {}".format(vm_list[0]["name"], vm_list[0]["status"]))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem retrieving status of the VM")

        elif arguments["info"]:
            try:
                cloud_provider = CloudProvider(cloud).provider
                vms = cloud_provider.list_vm(cloud)
                vm = vms[0]
                output_format = arguments["--format"] or "table"
                print (attribute_printer(vm, output=output_format))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem retrieving status of the VM")

        elif arguments["start"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error("No VM records in database. Please run vm refresh.")
                        return ""
                    name = last_vm["name"]
                    # print(name)
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""
                Vm.start(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem starting instances")

        elif arguments["stop"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error("No VM records in database. Please run vm refresh.")
                        return ""
                    name = last_vm["name"]
                    # print(name)
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                Vm.stop(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem stopping instances")

        elif arguments["refresh"]:

            _refresh()

        elif arguments["delete"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error("No VM records in database. Please run vm refresh.")
                        return ""
                    name = last_vm["name"]
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                Vm.delete(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem deleting instances")

        elif arguments["ip"] and arguments["assign"]:
            vmids = arguments["NAME"]

            # If names not provided, take the last vm from DB.
            if vmids is None or len(vmids) == 0:
                last_vm = Vm.get_last_vm(cloud=cloud)
                if last_vm is None:
                    Console.error("No VM records in database. Please run vm refresh.")
                    return ""
                name = last_vm["name"]
                vmids = list()
                vmids.append(name)

            # if default cloud not set, return error
            if not cloud:
                Console.error("Default cloud not set.")
                return ""
            try:
                cloud_provider = CloudProvider(cloud).provider
                for sname in vmids:
                    floating_ip = cloud_provider.create_assign_floating_ip(
                        sname)
                    if floating_ip is not None:
                        print(
                            "Floating IP assigned to {:} successfully and it is: {:}".format(
                                sname, floating_ip))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem assigning floating ips.")

        elif arguments["ip"] and arguments["show"]:
            vmids = arguments["NAME"]

            # If names not provided, take the last vm from DB.
            if vmids is None or len(vmids) == 0:
                last_vm = Vm.get_last_vm(cloud=cloud)
                if last_vm is None:
                    Console.error("No VM records in database. Please run vm refresh.")
                    return ""
                name = last_vm["name"]
                vmids = list()
                vmids.append(name)

            group = arguments["--group"]
            output_format = arguments["--format"] or "table"
            refresh = arguments["--refresh"]

            # if default cloud not set, return error
            if not cloud:
                Console.error("Default cloud not set.")
                return ""

            try:
                cloud_provider = CloudProvider(cloud).provider
                for server in vmids:
                    ip_addr = cloud_provider.get_ips(server)

                    ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud)

                    print(
                        "IP Addresses of instance {:} are as follows:-".format(
                            server))
                    print(_print_dict_ip(ipaddr_dict, format=output_format))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error(
                    "Problem getting ip addresses for instance {:}".format(id))

        elif arguments["login"]:
            vm_names = arguments["NAME"]

            # If names not provided, take the last vm from DB.
            if vm_names is None or len(vm_names) == 0:
                last_vm = Vm.get_last_vm(cloud=cloud)
                if last_vm is None:
                    Console.error("No VM records in database. Please run vm refresh.")
                    return ""
                name = last_vm["name"]
            else:
                name = vm_names[0]

            print("Logging in into {:} machine...".format(name))

            user = arguments["--user"]

            # Get user if user argument not specified.
            if user is None:
                user_from_db = Vm.get_vm_login_user(name, cloud)
                user_suggest = user_from_db or getpass.getuser()
                user = input("Enter the user to login (Default: {}):".format(user_suggest)) or user_suggest
                Vm.set_vm_login_user(name, cloud, user)

            ip = arguments["--ip"]
            commands = arguments["--command"]

            # if default cloud not set, return error
            if not cloud:
                Console.error("Default cloud not set.")
                return ""

            key = arguments["--key"] or Default.get("login_key",
                                                    category=cloud)
            if not key:
                Console.error("Default login_key not set.")
                return ""

            cloud_provider = CloudProvider(cloud).provider
            # print("Name : {:}".format(name))
            ip_addr = cloud_provider.get_ips(name)

            ip_addresses = []
            ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud)
            for entry in ipaddr_dict:
                ip_addresses.append(ipaddr_dict[entry]["addr"])

            if ip is not None:
                if ip not in ip_addresses:
                    print(
                        "ERROR: IP Address specified does not match with the host.")
                    return ""
            else:
                print("Determining IP Address to use with a ping test.")
                # This part assumes that the ping is allowed to the machine.
                for ipadd in ip_addresses:
                    print("Checking {:}...".format(ipadd))
                    try:
                        socket.gethostbyaddr(ipadd)
                        # ip will be set if above command is successful.
                        ip = ipadd
                    except socket.herror:
                        print("Cannot reach {:}.".format(ipadd))

            if ip is None:
                print("SORRY. Unable to connect to the machine")
                return ""
            else:
                print("IP to be used is: {:}".format(ip))

            SecGroup.enable_ssh(cloud=cloud)
            # print("COMMANDS : {:}".format(commands))

            # Constructing the ssh command to connect to the machine.
            sshcommand = "ssh"
            if key is not None:
                sshcommand += " -i {:}".format(key)
            sshcommand += " -o StrictHostKeyChecking=no"
            sshcommand += " {:}@{:}".format(user, ip)
            if commands is not None:
                sshcommand += " \"{:}\"".format(commands)

            # print(sshcommand)
            os.system(sshcommand)

        elif arguments["list"]:

            if arguments["--all"]:
                try:
                    _format = arguments["--format"] or "table"
                    d = ConfigDict("cloudmesh.yaml")
                    for cloud in d["cloudmesh"]["clouds"]:

                        if arguments["--refresh"] or Default.refresh():
                            _refresh()

                        print("Listing VMs on Cloud: {:}".format(cloud))
                        result = Vm.list(cloud=cloud, output_format=_format)
                        if result is not None:
                            print(result)
                        else:
                            print("Sorry. No data found with requested parameters in DB.")
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing all instances")
            else:

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                try:
                    name_or_id = arguments["NAME_OR_ID"]
                    group = arguments["--group"]
                    _format = arguments["--format"] or "table"

                    # list_vms_on_cloud(cloud, group, _format)
                    if arguments["--refresh"] or Default.refresh():
                        _refresh()

                    result = Vm.list(name_or_id=name_or_id, cloud=cloud, output_format=_format)

                    if result is not None:
                        print(result)
                    else:
                        print("No data found with the requested parameters.")

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

                except Exception as e:
                    Error.traceback(e)
                    Console.error(
                        "Problem listing instances on cloud {:}".format(cloud))

        elif arguments["rename"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error("No VM records in database. Please run vm refresh.")
                        return ""
                    name = last_vm["name"]
                    servers = list()
                    servers.append(name)

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                new_name = arguments["--new"]
                is_name_provided = True

                # If the new name is not provided, make the new new name in format username-count.
                if new_name is None or len(new_name) == 0:

                    is_name_provided = False

                    count = Counter.get()
                    prefix = Username()

                    if prefix is None or count is None:
                        Console.error("Prefix and Count could not be retrieved correctly.")
                        return

                    # BUG THE Z FILL SHOULD BE detected from yaml file
                    new_name = prefix + "-" + str(count).zfill(3)

                Vm.rename(cloud=cloud, servers=servers, new_name=new_name)

                if is_name_provided is False:
                    # Incrementing count
                    Counter.incr()

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem deleting instances")

        return ""
예제 #19
0
    def do_hpc(self, args, arguments):
        # noinspection PyPep8
        """
                ::

                    Usage:
                        hpc queue [--job=NAME][--cluster=CLUSTER][--format=FORMAT]
                        hpc info [--cluster=CLUSTER][--format=FORMAT]
                        hpc run list [ID] [--cluster=CLUSTER]
                        hpc run output [ID] [--cluster=CLUSTER]
                        hpc run rm [ID] [--cluster=CLUSTER]
                        hpc run SCRIPT [--queue=QUEUE] [--t=TIME] [--N=nodes] [--name=NAME] [--cluster=CLUSTER][--dir=DIR][--group=GROUP][--format=FORMAT]
                        hpc delete --job=NAME [--cluster=CLUSTER][--group=GROUP]
                        hpc delete all [--cluster=CLUSTER][--group=GROUP][--format=FORMAT]
                        hpc status [--job=name] [--cluster=CLUSTER] [--group=GROUP]
                        hpc test --cluster=CLUSTER [--time=SECONDS]

                    Options:
                       --format=FORMAT  the output format [default: table]

                    Examples:

                        Special notes

                           if the group is specified only jobs from that group are
                           considered. Otherwise the default group is used. If the
                           group is set to None, all groups are used.

                        cm hpc queue
                            lists the details of the queues of the hpc cluster

                        cm hpc queue --job=NAME
                            lists the details of the job in the queue of the hpc cluster

                        cm hpc info
                            lists the details of the hpc cluster

                        cm hpc run SCRIPT
                            submits the script to the cluster. The script will be
                            copied prior to execution into the home directory on the
                            remote machine. If a DIR is specified it will be copied
                            into that dir.
                            The name of the script is either specified in the script
                            itself, or if not the default naming scheme of
                            cloudmesh is used using the same index incremented name
                            as in vms fro clouds: cloudmes husername-index

                        cm hpc delete all
                            kills all jobs on the default hpc group

                        cm hpc delete --job=NAME
                            kills a job with a given name or job id

                        cm default cluster=NAME
                            sets the default hpc cluster

                        cm hpc status
                            returns the status of all jobs

                        cm hpc status job=ID
                            returns the status of the named job

                        cm hpc test --cluster=CLUSTER --time=SECONDS
                            submits a simple test job to the named cluster and returns
                            if the job could be successfully executed. This is a
                            blocking call and may take a long time to complete
                            dependent on if the queuing system of that cluster is
                            busy. It will only use one node/core and print the message

                            #CLOUDMESH: Test ok

                            in that is being looked for to identify if the test is
                            successful. If time is used, the job is terminated
                            after the time is elapsed.

                    Examples:
                        cm hpc queue
                        cm hpc queue --job=xxx
                        cm hpc info
                        cm hpc delete --job=6
                        cm hpc delete all
                        cm hpc status
                        cm hpc status --job=6
                        cm hpc run uname
                        cm hpc run ~/test.sh --cluster=india
                """

        format = arguments['--format']
        cluster = arguments['--cluster'] or Default.cluster
        arguments["CLUSTER"] = cluster

        if cluster is None:
            Console.error("Default cluster doesn't exist")
            return

        batch = BatchProvider(cluster)

        if arguments["queue"]:
            name = arguments['--job']
            result = batch.queue(cluster, format=format, job=name)
            Console.msg(result)

        elif arguments["info"]:
            Console.msg(batch.info(cluster, format))

        elif arguments['delete'] and arguments['all']:
            group = arguments['--group'] or Default.get(name='group')
            if group is None:
                Console.error('set default group using: default group=<value> --cloud=general')
                return
            Console.ok(batch.delete(cluster, None, group))

        elif arguments["delete"]:
            job = arguments['--job']
            Console.ok(batch.delete(cluster, job))

        elif arguments["status"]:
            name = arguments['--job']
            result = batch.queue(cluster, format=format, job=name)
            Console.msg(result)

        elif arguments["test"]:
            time_secs = arguments['--time']
            if time_secs:
                time = '00:00:' + time_secs
            else:
                time = '00:00:10'  # give a  default time of 10 secs
            print(batch.test(cluster, time))

        elif arguments["run"] and arguments["list"]:
            # hpc experiment list [--cluster=CLUSTER]
            if arguments["ID"]:
                print("# List of experiment {ID} on Cluster {CLUSTER}".format(**arguments))
                result = Experiment.list(cluster, id=arguments["ID"], format="list")
                if result is not None:
                    print("\n".join(result))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))
            else:
                print("# List of experiments on Cluster {CLUSTER}".format(**arguments))
                ids = Experiment.list(cluster, id=None, format="list")
                if ids is not None:
                    print(", ".join([str(i) for i in ids]))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))

        elif arguments["run"] and arguments["rm"]:
            # hpc experiment list [--cluster=CLUSTER]
            if arguments["ID"]:

                force = yn_choice("Would you like to delete experiment {ID} on Cluster {CLUSTER}".format(**arguments))
                if force:
                    try:
                        result = Experiment.rm(cluster, id=arguments["ID"])
                        Console.ok("Experiment {ID} on Cluster {CLUSTER} deleted".format(**arguments))
                    except:
                        Console.error("Could not delete experiment {ID} on {CLUSTER}".format(**arguments))
            else:
                result = Experiment.list(cluster, id=None, format="list")
                if result is not None:
                    arguments['experiments'] = ", ".join([str(i) for i in result])
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))
                    return ""

                force = yn_choice("Would you like to delete the experiments {experiments} on Cluster {CLUSTER}".format(
                    **arguments))
                if force:
                    try:
                        result = Experiment.rm(cluster, id=None)
                        Console.ok("Experiments {experiments} on Cluster {CLUSTER} deleted".format(**arguments))
                    except:
                        Console.error("Could delete the experiments on {CLUSTER}".format(**arguments))
                return ""

        elif arguments["run"] and arguments["output"]:
            # hpc experiment list [--cluster=CLUSTER]
            if arguments["ID"]:
                print("# List of experiment {ID} on Cluster {CLUSTER}".format(**arguments))
                result = Experiment.output(cluster, id=arguments["ID"], format="list")
                if result is not None:
                    print("\n".join(result))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))
            else:
                print("# List of experiments on Cluster {CLUSTER}".format(**arguments))
                ids = Experiment.output(cluster, id=None, format="list")
                if ids is not None:
                    print(", ".join([str(i) for i in ids]))
                else:
                    Console.error("Could not find experiment {ID} on {CLUSTER}".format(**arguments))

        elif arguments["run"]:
            queue = arguments['--queue'] or Default.get(name='queue')
            # if not queue:
            #    Console.error('set default queue using: default queue=<value>')
            #    return
            group = arguments['--group'] or Default.get(name='group')
            if group is None:
                Console.error('set default group using: default group=<value> --cloud=general')
                return

            script = arguments['SCRIPT']
            arg_dict = {
                '-name': arguments['--name'],
                '-p': queue,
                '-t': arguments['--t'],
                '-N': arguments['--N']
            }

            result = batch.run(cluster, group, script, **arg_dict)
            if isinstance(result, dict):
                print(Printer.attribute(result))
                Console.ok("Experiment {count}: Started batch job {job_id} on {cluster}".format(**result))
            else:
                Console.error(result)

        return ""
예제 #20
0
    def do_cluster(self, args, arguments):
        """
        ::

          Usage:
              cluster list [--format=FORMAT]
              cluster list NAME
                           [--format=FORMAT]
                           [--column=COLUMN]
                           [--short]
              cluster create NAME
                             [--count=COUNT]
                             [--login=USERNAME]
                             [--cloud=CLOUD]
                             [--image=IMAGE]
                             [--flavor=FLAVOR]
                             [--add]
              cluster delete NAME
              cluster setup NAME [--username]
              cluster inventory NAME

          Description:
              with the help of the cluster command you can create a number
              of virtual machines that are integrated in a named virtual cluster.
              You will be able to login between the nodes of the virtual cluster
              while using public keys.

              cluster setup NAME
                sets up the keys between the cluster node as well as the machine that
                executes the cm command

              cluster inventory NAME
                creates an inventory.txt file to be used by ansible in the current directory

              cluster create NAME
                 creates the virtual machines used for the cluster

              cluster list NAME
                 lists selected details of the vms for the cluster

              cluster delete NAME
                  remove the cluster and its VMs

          Examples:
              cluster list
                  list the clusters

              cluster create NAME --count=COUNT --login=USERNAME [options...]
                  Start a cluster of VMs, and each of them can log into each other.
                  CAUTION: you should specify defaults before using this command:
                  1. select cloud to work on, e.g. cloud select kilo
                       default cloud=kilo
                  2. test if you can create a single VM on the cloud to see if
                     everything is set up
                  3. set the default key to start VMs, e.g. key default [USERNAME-key]
                  5. set image of VMs, e.g. default image
                  6. set flavor of VMs, e.g. default flavor
                  7. Make sure to use a new unused group name

          Arguments:
              NAME              cluster name or group name

          Options:
              --count=COUNT     give the number of VMs to add into the cluster
              --login=USERNAME  give a login name for the VMs, e.g. ubuntu
              --cloud=CLOUD     give a cloud to work on
              --flavor=FLAVOR   give the name of the flavor or flavor id
              --image=IMAGE     give the name of the image or image id
              --add             if a group exists and there are VMs in it
                                additional vms will be added to this cluster and the
                                keys will be added to each other so one can login between
                                them
              FORMAT            output format: table, json, csv
              COLUMN            customize what information to display, for example:
                                --column=status,addresses prints the columns status
                                and addresses
              --detail          for table print format, a brief version
                                is used as default, use this flag to print
                                detailed table

        """
        def get_vms(group_name):
            groups = Vm.get_vms_by_group(group_name)
            vms = []
            for group in groups:
                name = group["member"]
                print(name)
                vm = Vm.get_vm(name)
                vm['cluster'] = group_name
                vms.append(vm)
            return vms

        def _print(f):
            print(f)

        def write(filename, msg):
            with open(path_expand(filename), 'w') as f:
                output = f.write(msg)

        arg = dotdict(arguments)

        arg.format = arguments["--format"] or "table"
        arg.count = int(arguments["--count"] or 1)
        arg.username = arguments["--login"]
        arg.cloud = arguments["--cloud"] or Default.cloud
        arg.image = arguments["--image"] or Default.get(name="image",
                                                        category=arg.cloud)
        arg.flavor = arguments["--flavor"] or Default.get(name="flavor",
                                                          category=arg.cloud)
        arg.add = arguments["--add"]
        arg.group = arg.NAME
        arg.name = None
        arg.key = Default.key
        arg.secgroup = Default.secgroup
        arg.group = arg.NAME
        arg.short = arguments["--short"]

        if arg.create:

            boot_from_args(arg)

        elif arg.inventory:

            group = Vm.get_vms_by_group(arg.group)

            result = ""
            if arg.format is "table":
                result = "[servers]\n"

            for element in group:
                name = element["member"]
                vm = Vm.get_vm(name)[0]
                vm['cluster'] = arg.group
                result += "{floating_ip}\n".format(**vm)

            Console.ok("Writing ips to inventory.txt")
            print(result)

            write("inventory.txt", result)

            Console.ok(".ok")
            return ""

        elif arg.list and arg.NAME is not None:

            if arg.short:

                vms = Vm.get_vms_by_group(arg.group)

                if vms is None:
                    Console.error("no vms found for {}".format(arg.group))
                else:

                    print(
                        Printer.list(vms,
                                     header=['Group', 'Vm'],
                                     order=['name', 'member'],
                                     output=arg.format))

            else:

                groups = Vm.get_vms_by_group(arg.group)

                pprint(groups)

                vms = []
                for group in groups:
                    name = group["member"]
                    vm = Vm.get_vm(name)[0]
                    vm['cluster'] = arg.group
                    if vm is not None:
                        vms.append(vm)

                pprint(vms)

                if vms is None:
                    Console.error("no vms found for {}".format(arg.group))
                else:

                    print(
                        Printer.list(vms,
                                     order=[
                                         'name', 'cluster', 'flavor', 'image',
                                         'status', 'user_id', 'floating_ip'
                                     ],
                                     output=arg.format))
            return ""

        elif arg.setup:

            def push(from_path, vm):
                vm.ip = vm.floating_ip
                if vm.ip is not None:
                    if arg.verbose:
                        Console.info("Connecting to Instance at IP:" +
                                     format(vm.ip))

                    sshcommand = "scp"
                    sshcommand += " -o StrictHostKeyChecking=no"
                    sshcommand += " {:}".format(from_path)
                    sshcommand += " {username}@{ip}:.ssh/authorized_keys".format(
                        **vm)

                    print(sshcommand)
                    os.system(sshcommand)
                else:
                    Console.error("No Public IPs found for the instance",
                                  traceflag=False)

            groups = Vm.get_vms_by_group(arg.group)

            pprint(groups)

            vms = []
            for group in groups:
                name = group["member"]
                vm = Vm.get_vm(name)[0]
                vm['cluster'] = arg.group
                if vm is not None:
                    vms.append(vm)

            pprint(vms)

            if vms is None:
                Console.error("no vms found for {}".format(arg.group))
            else:

                print(
                    Printer.list(vms,
                                 order=[
                                     'name', 'cluster', 'flavor', 'image',
                                     'status', 'user_id', 'floating_ip'
                                 ],
                                 output=arg.format))

                keys = ""
                for vm in vms:
                    vm = dotdict(vm)
                    cloud = vm.category

                    if vm.username is None:
                        vm.username = arguments[
                            "--username"] or Image.guess_username(arg.image)

                    chameleon = "chameleon" in ConfigDict(
                        filename="cloudmesh.yaml"
                    )["cloudmesh"]["clouds"][cloud]["cm_host"]

                    print("C", chameleon)

                    if chameleon:
                        vm.username = "******"
                    elif vm.category == "azure":
                        vm.username = ConfigDict(
                            filename="cloudmesh.yaml")["cloudmesh"]["clouds"][
                                "azure"]["default"]["username"]
                    else:
                        if vm.username is None:
                            Console.error(
                                "Could not guess the username of the vm",
                                traceflag=False)
                            return

                    Vm.set_login_user(name=vm.name,
                                      cloud=vm.category,
                                      username=vm.username)
                    vm.ip = vm.floating_ip

                    def execute(commands):
                        if vm.ip is not None:
                            if arg.verbose:
                                Console.info("Connecting to Instance at IP:" +
                                             format(vm.ip))

                            sshcommand = "ssh"
                            if arg.key is not None:
                                sshcommand += " -i {:}".format(arg.key)
                            sshcommand += " -o StrictHostKeyChecking=no"
                            sshcommand += " {username}@{ip}".format(**vm)
                            sshcommand += " \'{:}\'".format(commands)

                            print(sshcommand)
                            os.system(sshcommand)
                        else:
                            Console.error(
                                "No Public IPs found for the instance",
                                traceflag=False)

                    def copy(commands):
                        if vm.ip is not None:
                            if arg.verbose:
                                Console.info("Connecting to Instance at IP:" +
                                             format(vm.ip))

                            sshcommand = "scp"
                            sshcommand += " -o StrictHostKeyChecking=no"
                            sshcommand += " {username}@{ip}".format(**vm)
                            sshcommand += ":{:}".format(commands)

                            print(sshcommand)
                            os.system(sshcommand)
                        else:
                            Console.error(
                                "No Public IPs found for the instance",
                                traceflag=False)

                    def cat(filename):
                        with open(path_expand(filename), 'r') as f:
                            output = f.read()
                        return output

                    execute('cat /dev/zero | ssh-keygen -q -N ""')
                    copy(".ssh/id_rsa.pub ~/.ssh/id_rsa_{name}.pub".format(
                        **vm))

                    output = "~/.ssh/id_rsa_{name}.pub".format(**vm)

                    keys = keys + cat(output)

                print("WRITE KEYS")
                keys = keys + cat("~/.ssh/id_rsa.pub")
                output = "~/.ssh/id_rsa_{group}.pub".format(**arg)
                write(output, keys)

                print("PUSH KEYS")
                for vm in vms:
                    vm = dotdict(vm)
                    push("~/.ssh/id_rsa_{group}.pub".format(**arg), vm)

        return ""
예제 #21
0
    def do_list(self, args, arguments):
        """
        ::

            Usage:
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] default
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] vm
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] flavor
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] image

            List the items stored in the database

            Options:
                --cloud=CLOUD    the name of the cloud
                --format=FORMAT  the output format
                --tenant=TENANT     Name of the tenant, e.g. fg82.

            Description:
                List command prints the values stored in the database
                for [default/vm/flavor/image].
                Result can be filtered based on the cloud, user & tenant arguments.
                If these arguments are not specified, it reads the default

            Examples:
                $ list --cloud india default
                $ list --cloud india --format table flavor
                $ list --cloud india --user albert --tenant fg82 flavor
        """

        # pprint(arguments)

        # Method to get the kind from args
        #
        # TODO: the kind are defined in the provider,
        # TODO: keep the kind lower case
        # why is there a reason to make the gind upper case
        def get_kind():
            for k in ["vm", "image", "flavor", "default"]:
                if arguments[k]:
                    # kinds are all uppercase in model.py
                    return k.upper()
            return "help"

        # Read commandline arguments
        output_format = arguments['--format']
        cloud = arguments['--cloud'] or Default.cloud
        user = arguments['--user']
        tenant = arguments['--tenant']

        # If format is not specified, read default
        if output_format is None:
            output_format = Default.get(name="format") or "table"

        # If cloud is not specified, get default
        if cloud is None:
            cloud = Default.get(name="cloud") or ConfigDict(
                filename="cloudmesh.yaml")["cloudmesh"]["active"][0]

        # If user is not specified, get default
        if user is None:
            user = Default.get(name="user")

        # If tenant is not specified, get default
        if tenant is None:
            tenant = Default.get(name="tenant")

        # Get the kind
        kind = get_kind()
        header = None
        order = None

        # print help message
        if kind == 'help':
            Console.ok("Print help!")
            return ""

        # Prepare the order & header based on kind
        # TODO: use lower case so we have a convention thats easy to follow
        # TODO: add quota
        # TODO: add limits
        # TODO: add usage

        #
        # TODO: BUG: use the get attribute from the provider.
        # TODO:: call the cm xyz list functions and do not
        # reimplement this here
        # possibly introduce List.py

        result = None
        if kind == 'FLAVOR':
            result = Flavor.list(cloud, format=output_format)
        elif kind == 'DEFAULT':
            result = Default.list(order=order, output=output_format)
        elif kind == 'IMAGE':
            result = Image.list(cloud, format=output_format)
        elif kind == 'VM':
            result = Vm.list(cloud=cloud, output_format=output_format)

        if result:
            print(result)
        else:
            Console.error("No {}s found in the database.".format(kind.lower()))

        return ""
예제 #22
0
    def do_network(self, args, arguments):
        """
        ::

            Usage:
                network get fixed [ip] [--cloud=CLOUD] FIXED_IP
                network get floating [ip] [--cloud=CLOUD] FLOATING_IP_ID
                network reserve fixed [ip] [--cloud=CLOUD] FIXED_IP
                network unreserve fixed [ip] [--cloud=CLOUD] FIXED_IP
                network associate floating [ip] [--cloud=CLOUD] [--group=GROUP]
                                           [--instance=INS_ID_OR_NAME] [FLOATING_IP]
                network disassociate floating [ip] [--cloud=CLOUD] [--group=GROUP]
                                              [--instance=INS_ID_OR_NAME] [FLOATING_IP]
                network create floating [ip] [--cloud=CLOUD] [--pool=FLOATING_IP_POOL]
                network delete floating [ip] [--cloud=CLOUD] [--unused] [FLOATING_IP]
                network list floating pool [--cloud=CLOUD]
                network list floating [ip] [--cloud=CLOUD] [--unused] [--instance=INS_ID_OR_NAME] [IP_OR_ID]
                network create cluster --group=demo_group
                network -h | --help

            Options:
                -h                          help message
                --unused                    unused floating ips
                --cloud=CLOUD               Name of the IaaS cloud e.g. india_openstack_grizzly.
                --group=GROUP               Name of the group in Cloudmesh
                --pool=FLOATING_IP_POOL     Name of Floating IP Pool
                --instance=INS_ID_OR_NAME   ID or Name of the vm instance

            Arguments:
                IP_OR_ID        IP Address or ID of IP Address
                FIXED_IP        Fixed IP Address, e.g. 10.1.5.2
                FLOATING_IP     Floating IP Address, e.g. 192.1.66.8
                FLOATING_IP_ID  ID associated with Floating IP, e.g. 185c5195-e824-4e7b-8581-703abec4bc01

            Examples:
                network get fixed ip --cloud=india 10.1.2.5
                network get fixed --cloud=india 10.1.2.5
                network get floating ip --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01
                network get floating --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01
                network reserve fixed ip --cloud=india 10.1.2.5
                network reserve fixed --cloud=india 10.1.2.5
                network unreserve fixed ip --cloud=india 10.1.2.5
                network unreserve fixed --cloud=india 10.1.2.5
                network associate floating ip --cloud=india --instance=albert-001 192.1.66.8
                network associate floating --cloud=india --instance=albert-001
                network associate floating --cloud=india --group=albert_group
                network disassociate floating ip --cloud=india --instance=albert-001 192.1.66.8
                network disassociate floating --cloud=india --instance=albert-001 192.1.66.8
                network create floating ip --cloud=india --pool=albert-f01
                network create floating --cloud=india --pool=albert-f01
                network delete floating ip --cloud=india 192.1.66.8 192.1.66.9
                network delete floating --cloud=india 192.1.66.8 192.1.66.9
                network list floating ip --cloud=india
                network list floating --cloud=india
                network list floating --cloud=india --unused
                network list floating --cloud=india 192.1.66.8
                network list floating --cloud=india --instance=323c5195-7yy34-4e7b-8581-703abec4b
                network list floating pool --cloud=india
                network create cluster --group=demo_group

        """
        # pprint(arguments)
        # Get the cloud parameter OR read default
        cloudname = arguments["--cloud"] or Default.cloud

        if cloudname is None:
            Console.error("Default cloud has not been set!"
                          "Please use the following to set it:\n"
                          "cm default cloud=CLOUDNAME\n"
                          "or provide it via the --cloud=CLOUDNAME argument.")
            return ""

        # Fixed IP info
        if arguments["get"] \
                and arguments["fixed"]:
            fixed_ip = arguments["FIXED_IP"]
            result = Network.get_fixed_ip(cloudname,
                                          fixed_ip_addr=fixed_ip)
            Console.msg(result)

        # Floating IP info
        elif arguments["get"] \
                and arguments["floating"]:
            floating_ip_id = arguments["FLOATING_IP_ID"]
            result = Network.get_floating_ip(cloudname,
                                             floating_ip_or_id=floating_ip_id)
            Console.msg(result)

        # Reserve a fixed ip
        elif arguments["reserve"] \
                and arguments["fixed"]:
            fixed_ip = arguments["FIXED_IP"]
            result = Network.reserve_fixed_ip(cloudname=cloudname,
                                              fixed_ip_addr=fixed_ip)
            if result is not None:
                Console.ok("Reserve fixed ip address {} complete.".format(fixed_ip))

        # Un-Reserve a fixed ip
        elif arguments["unreserve"] \
                and arguments["fixed"]:
            fixed_ip = arguments["FIXED_IP"]
            result = Network.unreserve_fixed_ip(cloudname=cloudname,
                                                fixed_ip_addr=fixed_ip)
            if result is not None:
                Console.ok("Un-Reserve fixed ip address {} complete.".format(fixed_ip))

        # Associate floating IP
        elif arguments["associate"] \
                and arguments["floating"]:

            # Get all command-line arguments
            group_name = arguments["--group"]
            instance_id = arguments["--instance"]
            floating_ip = arguments["FLOATING_IP"]

            # group supplied
            if group_name is not None:
                """
                Group name has been provided.
                Assign floating IPs to all vms in the group
                and return
                """
                # Get the group information
                group = Group.get_info(name=group_name,
                                       category=cloudname,
                                       output="json")
                if group is not None:
                    # Convert from str to json
                    group = json.loads(group)
                    # For each vm in the group
                    # Create and assign a floating IP
                    for item in group:
                        instance_id = group[item]["value"]
                        floating_ip = Network.find_assign_floating_ip(cloudname=cloudname,
                                                                      instance_id=instance_id)
                        if floating_ip is not None:
                            Console.ok("Created and assigned Floating IP {} to instance {}."
                                       .format(floating_ip, instance_id))
                            # Refresh VM in db
                            self.refresh_vm(cloudname)
                else:
                    Console.error("No group {} in the Cloudmesh database."
                                  .format(group_name))
                    return ""

            # floating-ip not supplied, instance-id supplied
            elif not floating_ip and instance_id is not None:
                """
                Floating IP has not been provided, instance-id provided.
                Generate one from the pool, and assign to vm
                and return
                """
                floating_ip = Network.find_assign_floating_ip(cloudname=cloudname,
                                                              instance_id=instance_id)
                if floating_ip is not None:
                    Console.ok("Associated floating IP {} to instance {}."
                               .format(floating_ip, instance_id))

            # instance-id & floating-ip supplied
            elif instance_id is not None:
                """
                Floating IP & Instance ID have been provided
                Associate the IP to the instance
                and return
                """
                Network.find_assign_floating_ip(cloudname=cloudname,
                                                instance_id=instance_id,
                                                floating_ip=floating_ip[0])

            # Invalid parameters
            else:
                Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n"
                              "You can also provide [FLOATING_IP] AND [--instance] parameters.\n"
                              "See 'cm network --help' for more info.")
                return ""

            # Refresh VM in db
            self.refresh_vm(cloudname)

        elif arguments["disassociate"] \
                and arguments["floating"]:

            # Get all command-line arguments
            group_name = arguments["--group"]
            instance_id = arguments["--instance"]
            floating_ip = arguments["FLOATING_IP"]

            # group supplied
            if group_name is not None:
                """
                Group name has been provided.
                Remove floating IPs of all vms in the group
                and return
                """
                # Get the group information
                group = Group.get_info(name=group_name,
                                       category=cloudname,
                                       output="json")
                if group is not None:
                    # Convert from str to json
                    group = json.loads(group)
                    # For each vm in the group
                    # Create and assign a floating IP
                    for item in group:
                        instance_id = group[item]["value"]
                        # Get the instance dict
                        instance_dict = Network.get_instance_dict(cloudname=cloudname,
                                                                  instance_id=instance_id)
                        # Instance not found
                        if instance_dict is None:
                            Console.error("Instance {} not found in the cloudmesh database!"
                                          .format(instance_id))
                            return ""

                        # Get the instance name
                        instance_name = instance_dict["name"]
                        floating_ip = instance_dict["floating_ip"]

                        # Floating ip argument invalid
                        if floating_ip is None:
                            Console.error("Instance{} does not have a floating_ip."
                                          .format(instance_name))
                            return ""

                        result = Network.disassociate_floating_ip(cloudname=cloudname,
                                                                  instance_name=instance_name,
                                                                  floating_ip=floating_ip)
                        if result is not None:
                            Console.ok("Disassociated Floating IP {} from instance {}."
                                       .format(floating_ip, instance_name))
                else:
                    Console.error("No group {} in the Cloudmesh database."
                                  .format(group_name))
                    return ""

            # floating-ip not supplied, instance-id supplied
            elif len(floating_ip) == 0 and instance_id is not None:
                """
                Floating IP has not been provided, instance-id provided.
                Remove floating ip allocated to vm
                and return
                """
                instance_dict = Network.get_instance_dict(cloudname=cloudname,
                                                          instance_id=instance_id)
                # Instance not found
                if instance_dict is None:
                    Console.error("Instance {} not found in the cloudmesh database!"
                                  .format(instance_id))
                    return ""

                instance_name = instance_dict["name"]
                floating_ip = instance_dict["floating_ip"]

                # Floating ip argument invalid
                if floating_ip is None:
                    Console.error("Instance{} does not have a floating_ip."
                                  .format(instance_name))
                    return ""

                result = Network.disassociate_floating_ip(cloudname=cloudname,
                                                          instance_name=instance_name,
                                                          floating_ip=floating_ip)
                if result is not None:
                    Console.ok("Disassociated Floating IP {} from instance {}."
                               .format(floating_ip, instance_name))

            # instance-id & floating-ip supplied
            elif instance_id is not None:
                """
                Floating IP & Instance ID have been provided
                Remove the IP from the instance
                and return
                """
                instance_dict = Network.get_instance_dict(cloudname=cloudname,
                                                          instance_id=instance_id)
                floating_ip = floating_ip[0]

                # Instance not found
                if instance_dict is None:
                    Console.error("Instance {} not found in the cloudmesh database!"
                                  .format(instance_id))
                    return ""

                instance_name = instance_dict["name"]
                _floating_ip = instance_dict["floating_ip"]

                # Floating ip argument invalid
                if _floating_ip != floating_ip:
                    Console.error("Invalid floating_ip {} for instance {}."
                                  .format(floating_ip, instance_name))
                    return ""

                result = Network.disassociate_floating_ip(cloudname=cloudname,
                                                          instance_name=instance_name,
                                                          floating_ip=floating_ip)
                if result is not None:
                    Console.ok("Disassociated Floating IP {} from instance {}."
                               .format(floating_ip, instance_name))

            # Invalid parameters
            else:
                Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n"
                              "You can also provide [FLOATING_IP] AND [--instance] parameters.\n"
                              "See 'cm network --help' for more info.")
                return ""

            # Refresh VM in db
            self.refresh_vm(cloudname)

        # Create new floating ip under floating pool
        elif arguments["create"] \
                and arguments["floating"]:
            floating_pool = arguments["--pool"]
            result = Network.create_floating_ip(cloudname=cloudname,
                                                floating_pool=floating_pool)
            if result is not None:
                Console.ok("Created new floating IP {}".format(result))
            else:
                Console.error("Failed to create floating IP! Please check arguments.")

        # Delete a floating ip address
        elif arguments["delete"] \
                and arguments["floating"]:

            # delete all unused floating ips
            if arguments["--unused"]:
                unused_floating_ips = Network.get_unused_floating_ip_list(cloudname=cloudname)
                if unused_floating_ips:
                    for floating_ip in unused_floating_ips:
                        self._delete_floating_ip(cloudname=cloudname,
                                                 floating_ip=floating_ip["id"])
                else:
                    Console.msg("No unused floating ips exist at this moment. Ok.")
                return ""

            # delete specified floating ips
            floating_ips = Parameter.expand(arguments["FLOATING_IP"])

            for floating_ip in floating_ips:
                self._delete_floating_ip(cloudname=cloudname,
                                         floating_ip=floating_ip)

        # Floating IP Pool List
        elif arguments["list"] \
                and arguments["floating"] \
                and arguments["pool"]:
            result = Network.list_floating_ip_pool(cloudname)
            Console.msg(result)

        # Floating IP list [or info]
        elif arguments["list"] \
                and arguments["floating"]:

            ip_or_id = arguments["IP_OR_ID"]
            instance_id = arguments["--instance"]

            # List unused floating addr
            if arguments["--unused"]:
                result = Network.list_unused_floating_ip(cloudname=cloudname)
                Console.msg(result)
                return ""

            # Refresh VM in db
            self.refresh_vm(cloudname)

            # If instance id is supplied
            if instance_id is not None:
                instance_dict = Network.get_instance_dict(cloudname=cloudname,
                                                          instance_id=instance_id)
                # Instance not found
                if instance_dict is None:
                    Console.error("Instance {} not found in the cloudmesh database!"
                                  .format(instance_id))
                    return ""

                # Read the floating_ip from the dict
                ip_or_id = instance_dict["floating_ip"]

                if ip_or_id is None:
                    Console.error("Instance with ID {} does not have a floating IP address!"
                                  .format(instance_id))
                    return ""

            # If the floating ip or associated ID is supplied
            if ip_or_id is not None:
                result = Network.get_floating_ip(cloudname,
                                                 floating_ip_or_id=ip_or_id)

                if result is not None:
                    Console.msg(result)
                else:
                    Console.error("Floating IP not found! Please check your arguments.")
                    return ""
            # Retrieve the full list
            else:
                result = Network.list_floating_ip(cloudname)
                Console.msg(result)

        # Create a virtual cluster
        elif arguments["cluster"] and \
                arguments["create"]:

            group_name = arguments["--group"] or \
                         Default.get(name="group", category=cloudname)

            # Get the group information
            group = Group.get_info(name=group_name,
                                   category=cloudname,
                                   output="json")
            if group is not None:
                # Convert from str to json
                group = json.loads(group)

                # var contains pub key of all vms
                public_keys = ""
                login_users = []
                login_ips = []

                # For each vm in the group
                # Create and assign a floating IP
                for item in group:
                    instance_id = group[item]["value"]
                    # Get the instance dict
                    instance_dict = Network.get_instance_dict(cloudname=cloudname,
                                                              instance_id=instance_id)
                    # Instance not found
                    if instance_dict is None:
                        Console.error("Instance {} not found in the cloudmesh database!"
                                      .format(instance_id))
                        return ""

                    # Get the instance name
                    instance_name = instance_dict["name"]
                    floating_ip = instance_dict["floating_ip"]

                    # If vm does not have floating ip, then create
                    if floating_ip is None:
                        floating_ip = Network.create_assign_floating_ip(cloudname=cloudname,
                                                                        instance_name=instance_name)
                        if floating_ip is not None:
                            Console.ok("Created and assigned Floating IP {} to instance {}."
                                       .format(floating_ip, instance_name))
                            # Refresh VM in db
                            self.refresh_vm(cloudname)

                    # Get the login user for this machine
                    user = input("Enter the login user for VM {} : ".format(instance_name))
                    passphrase = getpass.getpass("Enter the passphrase key on VM {} : ".format(instance_name))

                    # create list for second iteration
                    login_users.append(user)
                    login_ips.append(floating_ip)

                    login_args = [
                        user + "@" + floating_ip,
                    ]

                    keygen_args = [
                        "ssh-keygen -t rsa -f ~/.ssh/id_rsa -N " + passphrase
                    ]

                    cat_pubkey_args = [
                        "cat ~/.ssh/id_rsa.pub"
                    ]

                    generate_keypair = login_args + keygen_args
                    result = Shell.ssh(*generate_keypair)

                    # print("***** Keygen *****")
                    # print(result)

                    cat_public_key = login_args + cat_pubkey_args
                    result = Shell.ssh(*cat_public_key)
                    public_keys += "\n" + result

                    # print("***** id_rsa.pub *****")
                    # print(result)

                # print("***** public keys *****")
                # print(public_keys)

                for user, ip in zip(login_users, login_ips):
                    arguments = [
                        user + "@" + ip,
                        "echo '" + public_keys + "' >> ~/.ssh/authorized_keys"
                    ]

                    # copy the public key contents to auth_keys
                    result = Shell.ssh(*arguments)

                Console.ok("Virtual cluster creation successfull.")
            else:
                Console.error("No group {} in the Cloudmesh database."
                              .format(group_name))
                return ""

        return ""
예제 #23
0
파일: cm.py 프로젝트: alistairking/client
    def __init__(self, context):
        cmd.Cmd.__init__(self)
        self.variables = {}
        self.command_topics = {}
        self.register_topics()
        self.context = context
        # TODO get loglevel from DB or yaml file, if not defined set to ERROR
        self.loglevel = "DEBUG"
        self._hist = []
        if self.context.debug:
            print("init CloudmeshConsole")

        self.prompt = 'cm> '
        self.doc_header = "Documented commands (type help <command>):"
        self.banner = textwrap.dedent("""
            +=======================================================+
            .   ____ _                 _                     _      .
            .  / ___| | ___  _   _  __| |_ __ ___   ___  ___| |__   .
            . | |   | |/ _ \| | | |/ _` | '_ ` _ \ / _ \/ __| '_ \  .
            . | |___| | (_) | |_| | (_| | | | | | |  __/\__ \ | | | .
            .  \____|_|\___/ \__,_|\__,_|_| |_| |_|\___||___/_| |_| .
            +=======================================================+
                                 Cloudmesh Shell
            """)
        # KeyCommands.__init__(self, context)

        #
        # set default cloud and default group if they do not exist
        # use the first cloud in cloudmesh.yaml as default
        #

        filename = path_expand("~/.cloudmesh/cloudmesh.yaml")
        create_cloudmesh_yaml(filename)

        # Initialize Logging
        # LogUtil.initialize_logging()

        # sys,exit(1)

        value = Default.get('cloud', category='general')
        if value is None:
            clouds = ConfigDict(filename=filename)["cloudmesh"]["clouds"]
            cloud = clouds.keys()[0]
            Default.set('cloud', cloud, category='general')

        value = Default.get('default', category='general')
        if value is None:
            Default.set('default', 'default', category='general')

        cluster = 'kilo'  # hardcode a value if not defined
        value = Default.get('cluster', category='general')
        if value is None:
            try:
                hosts = ssh_config().names()
                if hosts is not None:
                    cluster = hosts[0]
            except:
                pass  # use the hardcoded cluster

        else:
            cluster = value
        Default.set('cluster', cluster, category='general')

        group = Default.get_group()
        if group is None:
            Default.set_group("default")

        Default.load("cloudmesh.yaml")

        on = Default.timer()

        group = Default.get_group()
        if group is None:
            Default.set_group("default")

        r = Default.get_refresh()
        if r is None:
            Default.set_refresh("on")

        """
        try:
            sshm = SSHKeyManager()
            m = sshm.get_from_yaml(
                load_order="~/.cloudmesh/cloudmesh.yaml")
            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:
                    pass
        except Exception as e:
            Console.error("Problem adding keys from yaml file")
        """

        for c in CloudmeshConsole.__bases__[1:]:
            # noinspection PyArgumentList
            c.__init__(self, context)
예제 #24
0
    def do_group(self, args, arguments):
        """
        ::

            Usage:
                group add NAME [--type=TYPE] [--category=CLOUD] --id=IDs
                group list [--category=CLOUD] [--format=FORMAT] [NAME]
                group delete NAME [--category=CLOUD]
                group remove [--category=CLOUD] --name=NAME --id=ID
                group copy FROM TO
                group merge GROUPA GROUPB MERGEDGROUP

            manage the groups

            Arguments:

                NAME         name of a group
                FROM         name of a group
                TO           name of a group
                GROUPA       name of a group
                GROUPB       name of a group
                MERGEDGROUP  name of a group

            Options:
                --category=CLOUD       the name of the category
                --format=FORMAT     the output format
                --type=TYPE         the resource type
                --name=NAME         the name of the group
                --id=IDS            the ID(s) to add to the group


            Description:

                Todo: design parameters that are useful and match
                description
                Todo: discuss and propose command

                cloudmesh can manage groups of resources and category related
                objects. As it would be cumbersome to for example delete
                many virtual machines or delete VMs that are in the same
                group, but are running in different clouds.

                Hence it is possible to add a virtual machine to a
                specific group. The group name to be added to can be set
                as a default. This way all subsequent commands use this
                default group. It can also be set via a command parameter.
                Another convenience function is that the group command can
                use the last used virtual machine. If a vm is started it
                will be automatically added to the default group if it is set.

                The delete command has an optional category parameter so that
                deletion of vms of a partial group by cloud can be
                achieved.

                If finer grained deletion is needed, it can be achieved
                with the delete command that supports deletion by name

                It is also possible to remove a VM from the group using the
                remove command, by supplying the ID

            Example:
                default group mygroup

                group add --type=vm --id=albert-[001-003]
                    adds the vms with teh given name using the Parameter
                    see base

                group add --type=vm
                 adds the last vm to the group

                group delete --name=mygroup
                    deletes all objects in the group
        """
        # pprint(arguments)

        category = arguments["--category"] or Default.get_cloud()

        if arguments["list"]:

            output = arguments["--format"] or Default.get("format", category) or "table"
            name = arguments["NAME"]

            if name is None:

                result = Group.list(format=output, category=category)
                if result:
                    print(result)
                else:
                    print("There are no groups in the cloudmesh database!")

            else:

                result = Group.get_info(name=name, category=category,
                                        output=output)

                if result:
                    print(result)
                else:
                    msg_a = ("No group found with name `{name}` found in the "
                             "category `{category}`.".format(**locals()))

                    # find alternate
                    result = Group.get(name=name)
                    msg_b = ""
                    if result is not None:
                        msg_b = " However we found such a variable in " \
                                "category `{category}`. Please consider " \
                                "using --category={category}".format(**result)
                        Console.error(msg_a + msg_b)

                return

        elif arguments["add"]:
            type = arguments["--type"] or Default.get("type", category)

            category_id = arguments["--id"] or Default.get("id", category)

            data = {
                "name": arguments["NAME"],
                "type": type,
                "category": category,
                "id": category_id
            }

            Group.add(**data)
            return

        elif arguments["delete"]:
            data = {
                "name": arguments["NAME"],
                "category": category,
            }

            result = Group.delete(**data)
            if result:
                Console.ok("Deletion completed. ok.")
            else:
                Console.error(
                    "No group with name `{name}` found".format(**data))
            return

        elif arguments["remove"]:
            name = arguments["--name"]
            category_id = arguments["--id"]

            if not category:
                Console.error("Default category not set!")
                return

            result = Group.remove(name, category_id, category)
            if result:
                Console.ok(result)
            else:
                Console.error(
                    "Failed to delete ID [{}] from group [{}] in the database!".format(
                        category_id, name))
            return

        elif arguments["copy"]:
            _from = arguments["FROM"]
            _to = arguments["TO"]

            Group.copy(_from, _to)
            return

        elif arguments["merge"]:
            _groupA = arguments["GROUPA"]
            _groupB = arguments["GROUPB"]
            _mergedGroup = arguments["MERGEDGROUP"]

            Group.merge(_groupA, _groupB, _mergedGroup)
            return
예제 #25
0
    def do_group(self, args, arguments):
        """
        ::

            Usage:
                group list [GROUPNAME] [--format=FORMAT]
                group remove NAMES [--group=GROUPNAME]
                group add NAMES [--type=TYPE] [--group=GROUPNAME]
                group delete GROUPS
                group copy FROM TO
                group merge GROUPA GROUPB MERGEDGROUP

            manage the groups

            Arguments:

                NAMES        names of object to be added
                GROUPS       names of a groups
                FROM         name of a group
                TO           name of a group
                GROUPA       name of a group
                GROUPB       name of a group
                MERGEDGROUP  name of a group

            Options:
                --format=FORMAT     the output format
                --type=TYPE         the resource type
                --name=NAME         the name of the group
                --id=IDS            the ID(s) to add to the group


            Description:

                Todo: design parameters that are useful and match
                description
                Todo: discuss and propose command

                cloudmesh can manage groups of resource related
                objects. As it would be cumbersome to for example delete
                many virtual machines or delete VMs that are in the same
                group, but are running in different clouds.

                Hence it is possible to add a virtual machine to a
                specific group. The group name to be added to can be set
                as a default. This way all subsequent commands use this
                default group. It can also be set via a command parameter.
                Another convenience function is that the group command can
                use the last used virtual machine. If a vm is started it
                will be automatically added to the default group if it is set.

                If finer grained deletion is needed, it can be achieved
                with the delete command that supports deletion by name

                It is also possible to remove a VM from the group using the
                remove command, by supplying the ID

            Note:

                The type is internally called for the group species, we may
                eliminate the species column and just use the type column for it,

            Example:
                default group mygroup

                group add --type=vm --id=albert-[001-003]
                    adds the vms with the given name using the Parameter
                    see base

                group add --type=vm
                 adds the last vm to the group

                group delete --name=mygroup
                    deletes all objects in the group
        """
        # pprint(arguments)


        if arguments["list"]:

            output = arguments["--format"] or Default.get(name="format", category="general") or "table"
            name = arguments["GROUPNAME"]
            if name is None:

                result = Group.list(output=output)
                if result:
                    print(result)
                else:
                    print("No groups found other than the default group but it has no members.")

            else:

                result = Group.list(name=name,
                                    output=output)

                if result:
                    print(result)
                else:
                    msg_a = ("No group found with name `{name}` found in the "
                             "category `{category}`.".format(**locals()))

                '''
                    # find alternate
                    result = Group.get(name=name)

                    msg_b = ""
                    if result is not None and len(result) < 0:
                        msg_b = " However we found such a variable in " \
                                "category `{category}`. Please consider " \
                                "using --category={category}".format(**locals())
                        Console.error(msg_a + msg_b)
                    else:
                        Console.error("No group with name {name} exists.".format(**locals()))
                '''

                return ""

        elif arguments["add"]:
            # group add NAME... [--type=TYPE] [--category=CLOUD] [--group=GROUP]

            print ("AAA", arguments["NAMES"])
            members = Parameter.expand(arguments["NAMES"])
            print ("MMMM", members)
            data = dotdict({
                "species": arguments["--type"] or "vm",
                "name": arguments["--group"] or Default.group
            })
            print ("DDD", data)
            for member in members:
                data.member = member
                pprint(data)
                Group.add(**data)

            return ""

        elif arguments["delete"]:
            groups = Parameter.expand(arguments["GROUPS"])

            for group in groups:
                result = Group.delete(group)

                if result:
                    Console.ok(result)
                else:
                    Console.error(
                        "delete group {}. failed.".format(group))
            return ""

        elif arguments["remove"]:
            members = Parameter.expand(arguments["NAMES"])

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

            for member in members:
                result = Group.remove(group, member)

                if result:
                    Console.ok(result)
                else:
                    Console.error(
                        "remove {} from group {}. failed.".format(group, member))
            return ""

        elif arguments["copy"]:
            _from = arguments["FROM"]
            _to = arguments["TO"]

            Group.copy(_from, _to)
            return ""

        elif arguments["merge"]:
            _groupA = arguments["GROUPA"]
            _groupB = arguments["GROUPB"]
            _mergedGroup = arguments["MERGEDGROUP"]

            Group.merge(_groupA, _groupB, _mergedGroup)
            return ""
예제 #26
0
파일: cm.py 프로젝트: arpiagariu/client
    def __init__(self, context):
        cmd.Cmd.__init__(self)
        self.variables = {}
        self.command_topics = {}
        self.register_topics()
        self.context = context
        # TODO get loglevel from DB or yaml file, if not defined set to ERROR
        self.loglevel = "DEBUG"
        self._hist = []
        if self.context.debug:
            print("init CloudmeshConsole")

        self.prompt = 'cm> '
        self.doc_header = "Documented commands (type help <command>):"
        self.banner = textwrap.dedent("""
            +=======================================================+
            .   ____ _                 _                     _      .
            .  / ___| | ___  _   _  __| |_ __ ___   ___  ___| |__   .
            . | |   | |/ _ \| | | |/ _` | '_ ` _ \ / _ \/ __| '_ \  .
            . | |___| | (_) | |_| | (_| | | | | | |  __/\__ \ | | | .
            .  \____|_|\___/ \__,_|\__,_|_| |_| |_|\___||___/_| |_| .
            +=======================================================+
                                 Cloudmesh Shell
            """)
        # KeyCommands.__init__(self, context)

        #
        # set default cloud and default group if they do not exist
        # use the first cloud in cloudmesh.yaml as default
        #

        Console.set_debug(Default.debug)

        filename = path_expand("~/.cloudmesh/cloudmesh.yaml")
        # moved to import cloudmesh_client

        # create_cloudmesh_yaml(filename)

        setup_yaml()

        # Initialize Logging
        # LogUtil.initialize_logging()

        # sys,exit(1)

        # ##################
        # DEFAULTS
        #

        #
        # SET DEFAULT CLOUD
        #

        value = Default.get(name='cloud', category='general')

        if value is None:

            config = ConfigDict(filename=filename)["cloudmesh"]
            if 'active' in config:
                cloud = config["active"][0]
            else:
                clouds = config["clouds"]
                cloud = list(clouds.keys())[0]
            Default.set('cloud', cloud, category='general')


        #
        # NOT SURE WHAT THIS IS FOR
        #
        value = Default.get(name='default', category='general')
        if value is None:
            Default.set('default', 'default', category='general')

        #
        # SET DEFAULT CLUSTER
        #
        '''
        cluster = ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["active"][0]

        value = Default.get(name='cluster', category='general')
        if value is None:
            try:
                hosts = ssh_config().names()
                if hosts is not None:
                    cluster = hosts[0]
            except:
                pass  # use the hardcoded cluster

        else:
            cluster = value
        Default.set('cluster', cluster, category='general')
        '''

        #
        # SET DEFAULT GROUP
        #
        group = Default.group
        if group is None:
            Default.set_group("default")

        #
        # LOAD DEFAULTS FROM YAML
        #
        Default.load("cloudmesh.yaml")

        try:
            d = Key.get_from_dir("~/.ssh", store=False)
        except Exception as e:
            Console.error(e.message)

        #
        # SET DEFAULT TIMER
        #
        on = Default.timer


        #
        # SET DEFUALT SECGROUP
        #


        #
        # SET DEFAULT REFRESH
        #
        # r = Default.refresh
        # print ("REFRESH", r)
        # if r is None:
        #     Default.set_refresh("on")

        #
        # SET DEFAULT USER
        #
        user = Default.user
        if user is None:
            user = ConfigDict(filename=filename)["cloudmesh"]["profile"]["user"]
            Default.set_user(user)


        r = Default.secgroup

        if r is None:
            secgroup = "{}-default".format(Default.user)
            Default.set_secgroup(secgroup)
            SecGroup.add_rule_to_db(group=secgroup, name="ssh",from_port="22",to_port="22",protocol="tcp", cidr="0.0.0.0/0")
            SecGroup.add_rule_to_db(group=secgroup, name="http",from_port="80",to_port="80",protocol="tcp", cidr="0.0.0.0/0")
            SecGroup.add_rule_to_db(group=secgroup, name="https", from_port="443", to_port="443", protocol="tcp", cidr="0.0.0.0/0")

        """
        try:
            sshm = SSHKeyManager()
            m = sshm.get_from_yaml(
                load_order="~/.cloudmesh/cloudmesh.yaml")
            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:
                    pass
        except Exception as e:
            Console.error("Problem adding keys from yaml file")
        """

        for c in CloudmeshConsole.__bases__[1:]:
            # noinspection PyArgumentList
            c.__init__(self, context)
예제 #27
0
    def do_default(self, args, arguments):
        """
        ::

          Usage:
              default
              default list [--cloud=CLOUD] [--format=FORMAT] [--all]
              default delete KEY [--cloud=CLOUD]
              default KEY [--cloud=CLOUD]
              default KEY=VALUE [--cloud=CLOUD]

          Arguments:
            KEY    the name of the default
            VALUE  the value to set the key to

          Options:
             --cloud=CLOUD    the name of the cloud
             --format=FORMAT  the output format. Values include
                              table, json, csv, yaml.
             --all            lists all the default values

        Description:
            Cloudmesh has the ability to manage easily multiple
            clouds. One of the key concepts to manage multiple clouds
            is to use defaults for the cloud, the images, flavors,
            and other values. The default command is used to manage
            such default values. These defaults are used in other commands
            if they are not overwritten by a command parameter.

            The current default values can by listed with

                default list --all

            Via the default command you can list, set, get and delete
            default values. You can list the defaults with

               default list

            A default can be set with

                default KEY=VALUE

            To look up a default value you can say

                default KEY

            A default can be deleted with

                default delete KEY

            To be specific to a cloud you can specify the name of the
            cloud with the --cloud=CLOUD option. The list command can
            print the information in various formats iv specified.

        Examples:
            default
                lists the default for the current default cloud

            default list --all
                lists all default values

            default list --cloud=kilo
                lists the defaults for the cloud with the name kilo

            default image=xyz
                sets the default image for the default cloud to xyz

            default image=abc --cloud=kilo
                sets the default image for the cloud kilo to xyz

            default image
                list the default image of the default cloud

            default image --cloud=kilo
                list the default image of the cloud kilo

            default delete image
                deletes the value for the default image in the
                default cloud

            default delete image --cloud=kilo
                deletes the value for the default image in the
                cloud kilo

        """
        #print(arguments)
        #print (">", args, "<")
        """
        For these keys, the 'cloud' column in db
        will always be 'general'.
        """
        general_keys = [
            "cloud", "cluster", "queue", "key", "group", "user", "secgroup",
            "vm", "refresh", "debug", "interactive", "purge"
        ]
        """
        If the default cloud has been set (eg. default category=xxx),
        then subsequent defaults for any key (eg. default image=yyy),
        will have 'cloud' column in db as the default cloud that was set.
        (eg. image=yyy for category=xxx).
        """

        if arguments["KEY"] in general_keys:
            cloud = "general"
        elif args == '':
            cloud = "general"
            arguments["--cloud"] = cloud
            arguments["list"] = True
            order = ['name', 'value']
            output_format = arguments["--format"]
            result = Default.list(category=cloud,
                                  order=order,
                                  output=output_format)
            print(result)
            return ""

        else:
            cloud = arguments["--cloud"] or Default.get(
                name="cloud", category="general") or "general"

        if arguments["list"]:
            output_format = arguments["--format"] or Default.output or 'table'

            if arguments['--all'] or arguments["--cloud"] is None:
                cloud = None
            result = Default.list(category=cloud, output=output_format)

            if result is None:
                Console.error("No default values found")
            else:
                print(result)
            return ""

        elif arguments["delete"]:

            key = arguments["KEY"]
            if key in general_keys:
                cloud = "general"
            result = Default.delete(key, cloud)
            if not result:
                Console.error("default {} not present".format(key))
            else:
                Console.ok("Deleted key {} for cloud {}. ok.".format(
                    key, cloud))
            return ""

        elif "=" in arguments["KEY"]:
            key, value = arguments["KEY"].split("=")
            if key in general_keys:
                cloud = "general"
            if key in "debug":
                Default.set_debug(value)
            else:
                Default.set(key, value, category=cloud)
            Console.ok("set default {}={}. ok.".format(key, value))
            return ""

        elif arguments["KEY"]:
            key = arguments["KEY"]
            if key in general_keys:
                cloud = "general"
            result = Default.get(name=key, category=cloud)
            if result is None:
                Console.error("No default values found")
            else:
                Console.ok("{}".format(result))
            return ""
예제 #28
0
    def do_vm(self, args, arguments):
        """
        ::

            Usage:
                vm default [--cloud=CLOUD][--format=FORMAT]
                vm refresh [--cloud=CLOUD]
                vm boot [--name=NAME]
                        [--cloud=CLOUD]
                        [--image=IMAGE_OR_ID]
                        [--flavor=FLAVOR_OR_ID]
                        [--group=GROUP]
                        [--secgroup=SECGROUP]
                        [--key=KEY]
                        [--dryrun]
                vm start [NAME]...
                         [--group=GROUP]
                         [--cloud=CLOUD]
                         [--force]
                vm stop [NAME]...
                        [--group=GROUP]
                        [--cloud=CLOUD]
                        [--force]
                vm delete [NAME]...
                          [--group=GROUP]
                          [--cloud=CLOUD]
                          [--force]
                vm ip assign [NAME]...
                          [--cloud=CLOUD]
                vm ip show [NAME]...
                           [--group=GROUP]
                           [--cloud=CLOUD]
                           [--format=FORMAT]
                           [--refresh]
                vm login [NAME] [--user=USER]
                         [--ip=IP]
                         [--cloud=CLOUD]
                         [--key=KEY]
                         [--command=COMMAND]
                vm rename [NAME]...
                          [--new=NEWNAME]
                          [--cloud=CLOUD]
                vm list [NAME_OR_ID]
                        [--cloud=CLOUD|--all]
                        [--group=GROUP]
                        [--format=FORMAT]
                        [--refresh]
                vm status [--cloud=CLOUD]
                vm info [--cloud=CLOUD]
                        [--format=FORMAT]

            Arguments:
                COMMAND        positional arguments, the commands you want to
                               execute on the server(e.g. ls -a) separated by ';',
                               you will get a return of executing result instead of login to
                               the server, note that type in -- is suggested before
                               you input the commands
                NAME           server name. By default it is set to the name of last vm from database.
                NAME_OR_ID     server name or ID
                KEYPAIR_NAME   Name of the openstack keypair to be used to create VM. Note this is not a path to key.
                NEWNAME        New name of the VM while renaming.

            Options:
                --ip=IP          give the public ip of the server
                --cloud=CLOUD    give a cloud to work on, if not given, selected
                                 or default cloud will be used
                --count=COUNT    give the number of servers to start
                --detail         for table print format, a brief version
                                 is used as default, use this flag to print
                                 detailed table
                --flavor=FLAVOR_OR_ID  give the name or id of the flavor
                --group=GROUP          give the group name of server
                --secgroup=SECGROUP    security group name for the server
                --image=IMAGE_OR_ID    give the name or id of the image
                --key=KEY        specify a key to use, input a string which
                                 is the full path to the private key file
                --keypair_name=KEYPAIR_NAME   Name of the openstack keypair to be used to create VM.
                                              Note this is not a path to key.
                --user=USER      give the user name of the server that you want
                                 to use to login
                --name=NAME      give the name of the virtual machine
                --force          delete vms without user's confirmation
                --command=COMMAND
                                 specify the commands to be executed
                --new=NEWNAME    Specify the new name for a VM while renaming.
                                 By default, this will be set to <username>-<count> format.



            Description:
                commands used to boot, start or delete servers of a cloud

                vm default [options...]     Displays default parameters that are set for VM boot.
                vm boot [options...]        Boots servers on a cloud, user may specify
                                            flavor, image .etc, otherwise default values
                                            will be used, see how to set default values
                                            of a cloud: cloud help
                vm start [options...]       Starts a suspended or stopped vm instance.
                vm stop [options...]        Stops a vm instance .
                vm delete [options...]      delete servers of a cloud, user may delete
                                            a server by its name or id, delete servers
                                            of a group or servers of a cloud, give prefix
                                            and/or range to find servers by their names.
                                            Or user may specify more options to narrow
                                            the search
                vm floating_ip_assign [options...]   assign a public ip to a VM of a cloud
                vm ip show [options...]     show the ips of VMs
                vm login [options...]       login to a server or execute commands on it
                vm list [options...]        same as command "list vm", please refer to it
                vm status [options...]      Retrieves status of last VM booted on cloud and displays it.

            Tip:
                give the VM name, but in a hostlist style, which is very
                convenient when you need a range of VMs e.g. sample[1-3]
                => ['sample1', 'sample2', 'sample3']
                sample[1-3,18] => ['sample1', 'sample2', 'sample3', 'sample18']

        """
        def _print_dict(d, header=None, format='table'):
            if format == "json":
                return json.dumps(d, indent=4)
            elif format == "yaml":
                return pyaml.dump(d)
            elif format == "table":
                return dict_printer(d,
                                    order=["id", "name", "status"],
                                    output="table",
                                    sort_keys=True)
            else:
                return d

        def _print_dict_ip(d, header=None, format='table'):
            if format == "json":
                return json.dumps(d, indent=4)
            elif format == "yaml":
                return pyaml.dump(d)
            elif format == "table":
                return dict_printer(d,
                                    order=["network", "version", "addr"],
                                    output="table",
                                    sort_keys=True)
            else:
                return d

        """
        def list_vms_on_cloud(cloud="kilo", group=None, format="table"):

            Utility reusable function to list vms on the cloud.
            :param cloud:
            :param group:
            :param format:
            :return:

            _cloud = cloud
            _group = group
            _format = format

            cloud_provider = CloudProvider(_cloud).provider
            servers = cloud_provider.list_vm(_cloud)


            server_list = {}
            index = 0
            # TODO: Improve the implementation to display more fields if required.
            for server in servers:
                server_list[index] = {}
                server_list[index]["name"] = server.name
                server_list[index]["id"] = server.id
                server_list[index]["status"] = server.status
                index += 1


            # TODO: Get this printed in a table
            print("Print table")
            dict_printer(servers, output=_format)
        """

        # pprint(arguments)

        def _refresh():
            try:
                msg = "Refresh VMs for cloud {:}.".format(cloud)
                if Vm.refresh(cloud=cloud):
                    Console.ok("{:} OK.".format(msg))
                else:
                    Console.error("{:} failed".format(msg))
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem running VM refresh")

        cloud = arguments["--cloud"] or Default.get_cloud()

        if arguments["boot"]:
            name = None
            try:
                name = arguments["--name"]
                is_name_provided = True

                if name is None:
                    is_name_provided = False

                    count = Counter.get()
                    prefix = Username()

                    if prefix is None or count is None:
                        Console.error(
                            "Prefix and Count could not be retrieved correctly."
                        )
                        return

                    # BUG THE Z FILL SHOULD BE detected from yaml file
                    name = prefix + "-" + str(count).zfill(3)

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                image = arguments["--image"] or Default.get("image",
                                                            category=cloud)
                # if default image not set, return error
                if not image:
                    Console.error("Default image not set.")
                    return ""

                flavor = arguments["--flavor"] or Default.get("flavor",
                                                              category=cloud)
                # if default flavor not set, return error
                if not flavor:
                    Console.error("Default flavor not set.")
                    return ""

                group = arguments["--group"] or Default.get_group()

                # if default group not set, return error
                if not group:
                    group = "default"
                    Default.set_group(group)

                secgroup = arguments["--secgroup"] or Default.get(
                    "secgroup", category=cloud)
                # print("SecurityGrp : {:}".format(secgroup))
                secgroup_list = ["default"]
                if secgroup is not None:
                    secgroup_list.append(secgroup)

                key_name = arguments["--key"] or Default.get_key()
                # if default keypair not set, return error
                if not key_name:
                    Console.error("Default key not set.")
                    return ""

                if arguments["--dryrun"]:

                    data = {
                        "cloud": cloud,
                        "name": name,
                        "image": image,
                        "flavor": flavor,
                        "key_name": key_name,
                        "secgroup_list": secgroup_list,
                        "group": group
                    }
                    print(attribute_printer(data, output="table"))
                    msg = "dryrun info. OK."
                    Console.ok(msg)
                else:
                    vm_id = Vm.boot(cloud=cloud,
                                    name=name,
                                    image=image,
                                    flavor=flavor,
                                    key_name=key_name,
                                    secgroup_list=secgroup_list)
                    Default.set("last_vm_id", vm_id)
                    Default.set("last_vm_name", name)

                    # SHOULD WE NOT DO THIS BY DEFAULT EVEN IF WE SPECIFY THE NAME?
                    if is_name_provided is False:
                        # Incrementing count
                        Counter.incr()

                    # Add to group
                    if vm_id is not None:
                        Group.add(name=group,
                                  type="vm",
                                  id=name,
                                  category=cloud)

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

            except Exception as e:
                Error.traceback(e)
                Console.error("Problem booting instance {:}".format(name))

        elif arguments["default"]:
            try:
                count = Counter.get()
                prefix = Username()

                if prefix is None or count is None:
                    Console.error(
                        "Prefix and Count could not be retrieved correctly.")
                    return

                vm_name = prefix + "-" + str(count).zfill(3)
                data = {
                    "name": vm_name,
                    "cloud": arguments["--cloud"] or Default.get_cloud()
                }
                for attribute in [
                        "image", "flavor", "key", "login_key", "group",
                        "secgroup"
                ]:
                    data[attribute] = Default.get(attribute, category=cloud)
                output_format = arguments["--format"] or "table"
                print(attribute_printer(data, output=output_format))
                msg = "info. OK."
                Console.ok(msg)
                ValueError(
                    "default command not implemented properly. Upon "
                    "first install the defaults should be read from yaml.")
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem listing defaults")

        elif arguments["status"]:
            try:
                cloud_provider = CloudProvider(cloud).provider
                vm_list = cloud_provider.list_vm(cloud)
                print("Status of VM {} is {}".format(vm_list[0]["name"],
                                                     vm_list[0]["status"]))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem retrieving status of the VM")

        elif arguments["info"]:
            try:
                cloud_provider = CloudProvider(cloud).provider
                vms = cloud_provider.list_vm(cloud)
                vm = vms[0]
                output_format = arguments["--format"] or "table"
                print(attribute_printer(vm, output=output_format))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem retrieving status of the VM")

        elif arguments["start"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error(
                            "No VM records in database. Please run vm refresh."
                        )
                        return ""
                    name = last_vm["name"]
                    # print(name)
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""
                Vm.start(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem starting instances")

        elif arguments["stop"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error(
                            "No VM records in database. Please run vm refresh."
                        )
                        return ""
                    name = last_vm["name"]
                    # print(name)
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                Vm.stop(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem stopping instances")

        elif arguments["refresh"]:

            _refresh()

        elif arguments["delete"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error(
                            "No VM records in database. Please run vm refresh."
                        )
                        return ""
                    name = last_vm["name"]
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                Vm.delete(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem deleting instances")

        elif arguments["ip"] and arguments["assign"]:
            vmids = arguments["NAME"]

            # If names not provided, take the last vm from DB.
            if vmids is None or len(vmids) == 0:
                last_vm = Vm.get_last_vm(cloud=cloud)
                if last_vm is None:
                    Console.error(
                        "No VM records in database. Please run vm refresh.")
                    return ""
                name = last_vm["name"]
                vmids = list()
                vmids.append(name)

            # if default cloud not set, return error
            if not cloud:
                Console.error("Default cloud not set.")
                return ""
            try:
                cloud_provider = CloudProvider(cloud).provider
                for sname in vmids:
                    floating_ip = cloud_provider.create_assign_floating_ip(
                        sname)
                    if floating_ip is not None:
                        print(
                            "Floating IP assigned to {:} successfully and it is: {:}"
                            .format(sname, floating_ip))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem assigning floating ips.")

        elif arguments["ip"] and arguments["show"]:
            vmids = arguments["NAME"]

            # If names not provided, take the last vm from DB.
            if vmids is None or len(vmids) == 0:
                last_vm = Vm.get_last_vm(cloud=cloud)
                if last_vm is None:
                    Console.error(
                        "No VM records in database. Please run vm refresh.")
                    return ""
                name = last_vm["name"]
                vmids = list()
                vmids.append(name)

            group = arguments["--group"]
            output_format = arguments["--format"] or "table"
            refresh = arguments["--refresh"]

            # if default cloud not set, return error
            if not cloud:
                Console.error("Default cloud not set.")
                return ""

            try:
                cloud_provider = CloudProvider(cloud).provider
                for server in vmids:
                    ip_addr = cloud_provider.get_ips(server)

                    ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud)

                    print(
                        "IP Addresses of instance {:} are as follows:-".format(
                            server))
                    print(_print_dict_ip(ipaddr_dict, format=output_format))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error(
                    "Problem getting ip addresses for instance {:}".format(id))

        elif arguments["login"]:
            vm_names = arguments["NAME"]

            # If names not provided, take the last vm from DB.
            if vm_names is None or len(vm_names) == 0:
                last_vm = Vm.get_last_vm(cloud=cloud)
                if last_vm is None:
                    Console.error(
                        "No VM records in database. Please run vm refresh.")
                    return ""
                name = last_vm["name"]
            else:
                name = vm_names[0]

            print("Logging in into {:} machine...".format(name))

            user = arguments["--user"]

            # Get user if user argument not specified.
            if user is None:
                user_from_db = Vm.get_vm_login_user(name, cloud)
                user_suggest = user_from_db or getpass.getuser()
                user = input("Enter the user to login (Default: {}):".format(
                    user_suggest)) or user_suggest
                Vm.set_vm_login_user(name, cloud, user)

            ip = arguments["--ip"]
            commands = arguments["--command"]

            # if default cloud not set, return error
            if not cloud:
                Console.error("Default cloud not set.")
                return ""

            key = arguments["--key"] or Default.get("login_key",
                                                    category=cloud)
            if not key:
                Console.error("Default login_key not set.")
                return ""

            cloud_provider = CloudProvider(cloud).provider
            # print("Name : {:}".format(name))
            ip_addr = cloud_provider.get_ips(name)

            ip_addresses = []
            ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud)
            for entry in ipaddr_dict:
                ip_addresses.append(ipaddr_dict[entry]["addr"])

            if ip is not None:
                if ip not in ip_addresses:
                    print(
                        "ERROR: IP Address specified does not match with the host."
                    )
                    return ""
            else:
                print("Determining IP Address to use with a ping test.")
                # This part assumes that the ping is allowed to the machine.
                for ipadd in ip_addresses:
                    print("Checking {:}...".format(ipadd))
                    try:
                        socket.gethostbyaddr(ipadd)
                        # ip will be set if above command is successful.
                        ip = ipadd
                    except socket.herror:
                        print("Cannot reach {:}.".format(ipadd))

            if ip is None:
                print("SORRY. Unable to connect to the machine")
                return ""
            else:
                print("IP to be used is: {:}".format(ip))

            SecGroup.enable_ssh(cloud=cloud)
            # print("COMMANDS : {:}".format(commands))

            # Constructing the ssh command to connect to the machine.
            sshcommand = "ssh"
            if key is not None:
                sshcommand += " -i {:}".format(key)
            sshcommand += " -o StrictHostKeyChecking=no"
            sshcommand += " {:}@{:}".format(user, ip)
            if commands is not None:
                sshcommand += " \"{:}\"".format(commands)

            # print(sshcommand)
            os.system(sshcommand)

        elif arguments["list"]:

            if arguments["--all"]:
                try:
                    _format = arguments["--format"] or "table"
                    d = ConfigDict("cloudmesh.yaml")
                    for cloud in d["cloudmesh"]["clouds"]:

                        if arguments["--refresh"] or Default.refresh():
                            _refresh()

                        print("Listing VMs on Cloud: {:}".format(cloud))
                        result = Vm.list(cloud=cloud, output_format=_format)
                        if result is not None:
                            print(result)
                        else:
                            print(
                                "Sorry. No data found with requested parameters in DB."
                            )
                    msg = "info. OK."
                    Console.ok(msg)
                except Exception as e:
                    Error.traceback(e)
                    Console.error("Problem listing all instances")
            else:

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                try:
                    name_or_id = arguments["NAME_OR_ID"]
                    group = arguments["--group"]
                    _format = arguments["--format"] or "table"

                    # list_vms_on_cloud(cloud, group, _format)
                    if arguments["--refresh"] or Default.refresh():
                        _refresh()

                    result = Vm.list(name_or_id=name_or_id,
                                     cloud=cloud,
                                     output_format=_format)

                    if result is not None:
                        print(result)
                    else:
                        print("No data found with the requested parameters.")

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

                except Exception as e:
                    Error.traceback(e)
                    Console.error(
                        "Problem listing instances on cloud {:}".format(cloud))

        elif arguments["rename"]:
            try:
                servers = arguments["NAME"]

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Vm.get_last_vm(cloud=cloud)
                    if last_vm is None:
                        Console.error(
                            "No VM records in database. Please run vm refresh."
                        )
                        return ""
                    name = last_vm["name"]
                    servers = list()
                    servers.append(name)

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.")
                    return ""

                new_name = arguments["--new"]
                is_name_provided = True

                # If the new name is not provided, make the new new name in format username-count.
                if new_name is None or len(new_name) == 0:

                    is_name_provided = False

                    count = Counter.get()
                    prefix = Username()

                    if prefix is None or count is None:
                        Console.error(
                            "Prefix and Count could not be retrieved correctly."
                        )
                        return

                    # BUG THE Z FILL SHOULD BE detected from yaml file
                    new_name = prefix + "-" + str(count).zfill(3)

                Vm.rename(cloud=cloud, servers=servers, new_name=new_name)

                if is_name_provided is False:
                    # Incrementing count
                    Counter.incr()

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                Error.traceback(e)
                Console.error("Problem deleting instances")

        return ""
예제 #29
0
    def do_group(self, args, arguments):
        """
        ::

            Usage:
                group add NAME [--type=TYPE] [--category=CLOUD] --id=IDs
                group list [--category=CLOUD] [--format=FORMAT] [NAME]
                group delete NAME [--category=CLOUD]
                group remove [--category=CLOUD] --name=NAME --id=ID
                group copy FROM TO
                group merge GROUPA GROUPB MERGEDGROUP

            manage the groups

            Arguments:

                NAME         name of a group
                FROM         name of a group
                TO           name of a group
                GROUPA       name of a group
                GROUPB       name of a group
                MERGEDGROUP  name of a group

            Options:
                --category=CLOUD       the name of the category
                --format=FORMAT     the output format
                --type=TYPE         the resource type
                --name=NAME         the name of the group
                --id=IDS            the ID(s) to add to the group


            Description:

                Todo: design parameters that are useful and match
                description
                Todo: discuss and propose command

                cloudmesh can manage groups of resources and category related
                objects. As it would be cumbersome to for example delete
                many virtual machines or delete VMs that are in the same
                group, but are running in different clouds.

                Hence it is possible to add a virtual machine to a
                specific group. The group name to be added to can be set
                as a default. This way all subsequent commands use this
                default group. It can also be set via a command parameter.
                Another convenience function is that the group command can
                use the last used virtual machine. If a vm is started it
                will be automatically added to the default group if it is set.

                The delete command has an optional category parameter so that
                deletion of vms of a partial group by cloud can be
                achieved.

                If finer grained deletion is needed, it can be achieved
                with the delete command that supports deletion by name

                It is also possible to remove a VM from the group using the
                remove command, by supplying the ID

            Example:
                default group mygroup

                group add --type=vm --id=albert-[001-003]
                    adds the vms with teh given name using the Parameter
                    see base

                group add --type=vm
                 adds the last vm to the group

                group delete --name=mygroup
                    deletes all objects in the group
        """
        # pprint(arguments)

        category = arguments["--category"] or Default.get_cloud()

        if arguments["list"]:

            output = arguments["--format"] or Default.get("format",
                                                          category) or "table"
            name = arguments["NAME"]

            if name is None:

                result = Group.list(format=output, category=category)
                if result:
                    print(result)
                else:
                    print("There are no groups in the cloudmesh database!")

            else:

                result = Group.get_info(name=name,
                                        category=category,
                                        output=output)

                if result:
                    print(result)
                else:
                    msg_a = ("No group found with name `{name}` found in the "
                             "category `{category}`.".format(**locals()))

                    # find alternate
                    result = Group.get(name=name)
                    msg_b = ""
                    if result is not None:
                        msg_b = " However we found such a variable in " \
                                "category `{category}`. Please consider " \
                                "using --category={category}".format(**result)
                        Console.error(msg_a + msg_b)

                return

        elif arguments["add"]:
            type = arguments["--type"] or Default.get("type", category)

            category_id = arguments["--id"] or Default.get("id", category)

            data = {
                "name": arguments["NAME"],
                "type": type,
                "category": category,
                "id": category_id
            }

            Group.add(**data)
            return

        elif arguments["delete"]:
            data = {
                "name": arguments["NAME"],
                "category": category,
            }

            result = Group.delete(**data)
            if result:
                Console.ok("Deletion completed. ok.")
            else:
                Console.error(
                    "No group with name `{name}` found".format(**data))
            return

        elif arguments["remove"]:
            name = arguments["--name"]
            category_id = arguments["--id"]

            if not category:
                Console.error("Default category not set!")
                return

            result = Group.remove(name, category_id, category)
            if result:
                Console.ok(result)
            else:
                Console.error(
                    "Failed to delete ID [{}] from group [{}] in the database!"
                    .format(category_id, name))
            return

        elif arguments["copy"]:
            _from = arguments["FROM"]
            _to = arguments["TO"]

            Group.copy(_from, _to)
            return

        elif arguments["merge"]:
            _groupA = arguments["GROUPA"]
            _groupB = arguments["GROUPB"]
            _mergedGroup = arguments["MERGEDGROUP"]

            Group.merge(_groupA, _groupB, _mergedGroup)
            return
예제 #30
0
파일: cm.py 프로젝트: sohiljain/client
    def __init__(self, context):
        cmd.Cmd.__init__(self)
        self.variables = {}
        self.command_topics = {}
        self.register_topics()
        self.context = context
        # TODO get loglevel from DB or yaml file, if not defined set to ERROR
        self.loglevel = "DEBUG"
        self._hist = []
        if self.context.debug:
            print("init CloudmeshConsole")

        self.prompt = 'cm> '
        self.doc_header = "Documented commands (type help <command>):"
        self.banner = textwrap.dedent("""
            +=======================================================+
            .   ____ _                 _                     _      .
            .  / ___| | ___  _   _  __| |_ __ ___   ___  ___| |__   .
            . | |   | |/ _ \| | | |/ _` | '_ ` _ \ / _ \/ __| '_ \  .
            . | |___| | (_) | |_| | (_| | | | | | |  __/\__ \ | | | .
            .  \____|_|\___/ \__,_|\__,_|_| |_| |_|\___||___/_| |_| .
            +=======================================================+
                                 Cloudmesh Shell
            """)
        # KeyCommands.__init__(self, context)

        #
        # set default cloud and default group if they do not exist
        # use the first cloud in cloudmesh.yaml as default
        #

        filename = path_expand("~/.cloudmesh/cloudmesh.yaml")
        # moved to import cloudmesh_client

        # create_cloudmesh_yaml(filename)

        # Initialize Logging
        # LogUtil.initialize_logging()

        # sys,exit(1)

        value = Default.get('cloud', category='general')
        if value is None:
            clouds = ConfigDict(filename=filename)["cloudmesh"]["clouds"]
            cloud = list(clouds.keys())[0]
            Default.set('cloud', cloud, category='general')

        value = Default.get('default', category='general')
        if value is None:
            Default.set('default', 'default', category='general')

        cluster = 'kilo'  # hardcode a value if not defined
        value = Default.get('cluster', category='general')
        if value is None:
            try:
                hosts = ssh_config().names()
                if hosts is not None:
                    cluster = hosts[0]
            except:
                pass  # use the hardcoded cluster

        else:
            cluster = value
        Default.set('cluster', cluster, category='general')

        group = Default.get_group()
        if group is None:
            Default.set_group("default")

        Default.load("cloudmesh.yaml")

        on = Default.timer()

        group = Default.get_group()
        if group is None:
            Default.set_group("default")

        r = Default.get_refresh()
        if r is None:
            Default.set_refresh("on")
        """
        try:
            sshm = SSHKeyManager()
            m = sshm.get_from_yaml(
                load_order="~/.cloudmesh/cloudmesh.yaml")
            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:
                    pass
        except Exception as e:
            Console.error("Problem adding keys from yaml file")
        """

        for c in CloudmeshConsole.__bases__[1:]:
            # noinspection PyArgumentList
            c.__init__(self, context)
예제 #31
0
    def do_nova(self, args, arguments):
        """
        ::
        
            Usage:
                nova set CLOUD
                nova info [CLOUD] [--password]
                nova help
                nova [--group=GROUP] ARGUMENTS...

            A simple wrapper for the openstack nova command

            Arguments:
                GROUP           The group to add vms to
                ARGUMENTS       The arguments passed to nova
                help            Prints the nova manual
                set             reads the information from the current cloud
                                and updates the environment variables if
                                the cloud is an openstack cloud
                info            the environment values for OS

            Options:
                --group=GROUP   Add VM to GROUP group
                --password      Prints the password
                -v              verbose mode

        """
        # pprint(arguments)
        cloud = arguments['CLOUD'] or Default.get_cloud()
        if not cloud:
            Console.error("Default cloud not set!")
            return ""

        group = arguments["--group"] or Default.get("group", category=cloud)

        if not group:
            Console.error("Default group not set!")
            return ""

        if arguments["help"]:
            os.system("nova help")
            return ""
        elif arguments["info"]:
            set_os_environ(cloud)
            d = {}
            #
            # TODO: this naturally does not work as clouds will have
            # different parameters. ALos it does not unset previous
            # parameters from other clouds. See register
            #
            for attribute in [
                    'OS_USERNAME', 'OS_TENANT_NAME', 'OS_AUTH_URL',
                    'OS_CACERT', 'OS_PASSWORD', 'OS_REGION'
            ]:
                try:
                    d[attribute] = os.environ[attribute]
                except:
                    Console.warning(
                        "OS environment variable {:} not found".format(
                            attribute))
                    d[attribute] = None
                if not arguments["--password"]:
                    d['OS_PASSWORD'] = "******"
            print(row_table(d, order=None, labels=["Variable", "Value"]))
            msg = "info. OK."
            Console.ok(msg)
            return ""
        elif arguments["set"]:
            if cloud:

                set_os_environ(cloud)

                msg = "{0} is set".format(cloud)
                Console.ok(msg)
            else:
                Console.error("CLOUD is required")

        else:  # nova ARGUMENTS...
            print("Cloud = {0}".format(cloud))
            try:
                set_os_environ(cloud)
                args = arguments["ARGUMENTS"]

                # arguments may contain multiple optional arguments
                if len(args) == 1:
                    args = args[0].split()

                result = Shell.execute("nova", args)

                print(Nova.remove_subjectAltName_warning(result))
                """
                If request for nova boot,
                add the vm to group specified,
                or else add to default group
                """
                if "boot" in args:
                    # Logic to find ID of VM in the result
                    fields = []
                    for field in result.split("|"):
                        fields.append(field.strip())
                    index = fields.index('id') + 1
                    vm_id = fields[index]

                    # Add to group
                    Group.add(name=group, type="vm", id=vm_id, category=cloud)
            except Exception as ex:
                Console.error("Error executing Nova command: {}".format(ex))
            return ""
예제 #32
0
    def do_network(self, args, arguments):
        """
        ::

            Usage:
                network get fixed [ip] [--cloud=CLOUD] FIXED_IP
                network get floating [ip] [--cloud=CLOUD] FLOATING_IP_ID
                network reserve fixed [ip] [--cloud=CLOUD] FIXED_IP
                network unreserve fixed [ip] [--cloud=CLOUD] FIXED_IP
                network associate floating [ip] [--cloud=CLOUD] [--group=GROUP]
                                           [--instance=INS_ID_OR_NAME] [FLOATING_IP]
                network disassociate floating [ip] [--cloud=CLOUD] [--group=GROUP]
                                              [--instance=INS_ID_OR_NAME] [FLOATING_IP]
                network create floating [ip] [--cloud=CLOUD] [--pool=FLOATING_IP_POOL]
                network delete floating [ip] [--cloud=CLOUD] [--unused] [FLOATING_IP]
                network list floating pool [--cloud=CLOUD]
                network list floating [ip] [--cloud=CLOUD] [--unused] [--instance=INS_ID_OR_NAME] [IP_OR_ID]
                network create cluster --group=demo_group
                network -h | --help

            Options:
                -h                          help message
                --unused                    unused floating ips
                --cloud=CLOUD               Name of the IaaS cloud e.g. india_openstack_grizzly.
                --group=GROUP               Name of the group in Cloudmesh
                --pool=FLOATING_IP_POOL     Name of Floating IP Pool
                --instance=INS_ID_OR_NAME   ID or Name of the vm instance

            Arguments:
                IP_OR_ID        IP Address or ID of IP Address
                FIXED_IP        Fixed IP Address, e.g. 10.1.5.2
                FLOATING_IP     Floating IP Address, e.g. 192.1.66.8
                FLOATING_IP_ID  ID associated with Floating IP, e.g. 185c5195-e824-4e7b-8581-703abec4bc01

            Examples:
                network get fixed ip --cloud=india 10.1.2.5
                network get fixed --cloud=india 10.1.2.5
                network get floating ip --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01
                network get floating --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01
                network reserve fixed ip --cloud=india 10.1.2.5
                network reserve fixed --cloud=india 10.1.2.5
                network unreserve fixed ip --cloud=india 10.1.2.5
                network unreserve fixed --cloud=india 10.1.2.5
                network associate floating ip --cloud=india --instance=albert-001 192.1.66.8
                network associate floating --cloud=india --instance=albert-001
                network associate floating --cloud=india --group=albert_group
                network disassociate floating ip --cloud=india --instance=albert-001 192.1.66.8
                network disassociate floating --cloud=india --instance=albert-001 192.1.66.8
                network create floating ip --cloud=india --pool=albert-f01
                network create floating --cloud=india --pool=albert-f01
                network delete floating ip --cloud=india 192.1.66.8 192.1.66.9
                network delete floating --cloud=india 192.1.66.8 192.1.66.9
                network list floating ip --cloud=india
                network list floating --cloud=india
                network list floating --cloud=india --unused
                network list floating --cloud=india 192.1.66.8
                network list floating --cloud=india --instance=323c5195-7yy34-4e7b-8581-703abec4b
                network list floating pool --cloud=india
                network create cluster --group=demo_group

        """
        # pprint(arguments)
        # Get the cloud parameter OR read default
        cloudname = arguments["--cloud"] or Default.cloud

        if cloudname is None:
            Console.error("Default cloud has not been set!"
                          "Please use the following to set it:\n"
                          "cm default cloud=CLOUDNAME\n"
                          "or provide it via the --cloud=CLOUDNAME argument.")
            return ""

        # Fixed IP info
        if arguments["get"] \
                and arguments["fixed"]:
            fixed_ip = arguments["FIXED_IP"]
            result = Network.get_fixed_ip(cloudname, fixed_ip_addr=fixed_ip)
            Console.msg(result)

        # Floating IP info
        elif arguments["get"] \
                and arguments["floating"]:
            floating_ip_id = arguments["FLOATING_IP_ID"]
            result = Network.get_floating_ip(cloudname,
                                             floating_ip_or_id=floating_ip_id)
            Console.msg(result)

        # Reserve a fixed ip
        elif arguments["reserve"] \
                and arguments["fixed"]:
            fixed_ip = arguments["FIXED_IP"]
            result = Network.reserve_fixed_ip(cloudname=cloudname,
                                              fixed_ip_addr=fixed_ip)
            if result is not None:
                Console.ok(
                    "Reserve fixed ip address {} complete.".format(fixed_ip))

        # Un-Reserve a fixed ip
        elif arguments["unreserve"] \
                and arguments["fixed"]:
            fixed_ip = arguments["FIXED_IP"]
            result = Network.unreserve_fixed_ip(cloudname=cloudname,
                                                fixed_ip_addr=fixed_ip)
            if result is not None:
                Console.ok("Un-Reserve fixed ip address {} complete.".format(
                    fixed_ip))

        # Associate floating IP
        elif arguments["associate"] \
                and arguments["floating"]:

            # Get all command-line arguments
            group_name = arguments["--group"]
            instance_id = arguments["--instance"]
            floating_ip = arguments["FLOATING_IP"]

            # group supplied
            if group_name is not None:
                """
                Group name has been provided.
                Assign floating IPs to all vms in the group
                and return
                """
                # Get the group information
                group = Group.get_info(name=group_name,
                                       category=cloudname,
                                       output="json")
                if group is not None:
                    # Convert from str to json
                    group = json.loads(group)
                    # For each vm in the group
                    # Create and assign a floating IP
                    for item in group:
                        instance_id = group[item]["value"]
                        floating_ip = Network.find_assign_floating_ip(
                            cloudname=cloudname, instance_id=instance_id)
                        if floating_ip is not None:
                            Console.ok(
                                "Created and assigned Floating IP {} to instance {}."
                                .format(floating_ip, instance_id))
                            # Refresh VM in db
                            self.refresh_vm(cloudname)
                else:
                    Console.error(
                        "No group {} in the Cloudmesh database.".format(
                            group_name))
                    return ""

            # floating-ip not supplied, instance-id supplied
            elif not floating_ip and instance_id is not None:
                """
                Floating IP has not been provided, instance-id provided.
                Generate one from the pool, and assign to vm
                and return
                """
                floating_ip = Network.find_assign_floating_ip(
                    cloudname=cloudname, instance_id=instance_id)
                if floating_ip is not None:
                    Console.ok(
                        "Associated floating IP {} to instance {}.".format(
                            floating_ip, instance_id))

            # instance-id & floating-ip supplied
            elif instance_id is not None:
                """
                Floating IP & Instance ID have been provided
                Associate the IP to the instance
                and return
                """
                Network.find_assign_floating_ip(cloudname=cloudname,
                                                instance_id=instance_id,
                                                floating_ip=floating_ip[0])

            # Invalid parameters
            else:
                Console.error(
                    "Please provide at least one of [--group] OR [--instance] parameters.\n"
                    "You can also provide [FLOATING_IP] AND [--instance] parameters.\n"
                    "See 'cm network --help' for more info.")
                return ""

            # Refresh VM in db
            self.refresh_vm(cloudname)

        elif arguments["disassociate"] \
                and arguments["floating"]:

            # Get all command-line arguments
            group_name = arguments["--group"]
            instance_id = arguments["--instance"]
            floating_ip = arguments["FLOATING_IP"]

            # group supplied
            if group_name is not None:
                """
                Group name has been provided.
                Remove floating IPs of all vms in the group
                and return
                """
                # Get the group information
                group = Group.get_info(name=group_name,
                                       category=cloudname,
                                       output="json")
                if group is not None:
                    # Convert from str to json
                    group = json.loads(group)
                    # For each vm in the group
                    # Create and assign a floating IP
                    for item in group:
                        instance_id = group[item]["value"]
                        # Get the instance dict
                        instance_dict = Network.get_instance_dict(
                            cloudname=cloudname, instance_id=instance_id)
                        # Instance not found
                        if instance_dict is None:
                            Console.error(
                                "Instance {} not found in the cloudmesh database!"
                                .format(instance_id))
                            return ""

                        # Get the instance name
                        instance_name = instance_dict["name"]
                        floating_ip = instance_dict["floating_ip"]

                        # Floating ip argument invalid
                        if floating_ip is None:
                            Console.error(
                                "Instance{} does not have a floating_ip.".
                                format(instance_name))
                            return ""

                        result = Network.disassociate_floating_ip(
                            cloudname=cloudname,
                            instance_name=instance_name,
                            floating_ip=floating_ip)
                        if result is not None:
                            Console.ok(
                                "Disassociated Floating IP {} from instance {}."
                                .format(floating_ip, instance_name))
                else:
                    Console.error(
                        "No group {} in the Cloudmesh database.".format(
                            group_name))
                    return ""

            # floating-ip not supplied, instance-id supplied
            elif len(floating_ip) == 0 and instance_id is not None:
                """
                Floating IP has not been provided, instance-id provided.
                Remove floating ip allocated to vm
                and return
                """
                instance_dict = Network.get_instance_dict(
                    cloudname=cloudname, instance_id=instance_id)
                # Instance not found
                if instance_dict is None:
                    Console.error(
                        "Instance {} not found in the cloudmesh database!".
                        format(instance_id))
                    return ""

                instance_name = instance_dict["name"]
                floating_ip = instance_dict["floating_ip"]

                # Floating ip argument invalid
                if floating_ip is None:
                    Console.error(
                        "Instance{} does not have a floating_ip.".format(
                            instance_name))
                    return ""

                result = Network.disassociate_floating_ip(
                    cloudname=cloudname,
                    instance_name=instance_name,
                    floating_ip=floating_ip)
                if result is not None:
                    Console.ok(
                        "Disassociated Floating IP {} from instance {}.".
                        format(floating_ip, instance_name))

            # instance-id & floating-ip supplied
            elif instance_id is not None:
                """
                Floating IP & Instance ID have been provided
                Remove the IP from the instance
                and return
                """
                instance_dict = Network.get_instance_dict(
                    cloudname=cloudname, instance_id=instance_id)
                floating_ip = floating_ip[0]

                # Instance not found
                if instance_dict is None:
                    Console.error(
                        "Instance {} not found in the cloudmesh database!".
                        format(instance_id))
                    return ""

                instance_name = instance_dict["name"]
                _floating_ip = instance_dict["floating_ip"]

                # Floating ip argument invalid
                if _floating_ip != floating_ip:
                    Console.error(
                        "Invalid floating_ip {} for instance {}.".format(
                            floating_ip, instance_name))
                    return ""

                result = Network.disassociate_floating_ip(
                    cloudname=cloudname,
                    instance_name=instance_name,
                    floating_ip=floating_ip)
                if result is not None:
                    Console.ok(
                        "Disassociated Floating IP {} from instance {}.".
                        format(floating_ip, instance_name))

            # Invalid parameters
            else:
                Console.error(
                    "Please provide at least one of [--group] OR [--instance] parameters.\n"
                    "You can also provide [FLOATING_IP] AND [--instance] parameters.\n"
                    "See 'cm network --help' for more info.")
                return ""

            # Refresh VM in db
            self.refresh_vm(cloudname)

        # Create new floating ip under floating pool
        elif arguments["create"] \
                and arguments["floating"]:
            floating_pool = arguments["--pool"]
            result = Network.create_floating_ip(cloudname=cloudname,
                                                floating_pool=floating_pool)
            if result is not None:
                Console.ok("Created new floating IP {}".format(result))
            else:
                Console.error(
                    "Failed to create floating IP! Please check arguments.")

        # Delete a floating ip address
        elif arguments["delete"] \
                and arguments["floating"]:

            # delete all unused floating ips
            if arguments["--unused"]:
                unused_floating_ips = Network.get_unused_floating_ip_list(
                    cloudname=cloudname)
                if unused_floating_ips:
                    for floating_ip in unused_floating_ips:
                        self._delete_floating_ip(cloudname=cloudname,
                                                 floating_ip=floating_ip["id"])
                else:
                    Console.msg(
                        "No unused floating ips exist at this moment. Ok.")
                return ""

            # delete specified floating ips
            floating_ips = Parameter.expand(arguments["FLOATING_IP"])

            for floating_ip in floating_ips:
                self._delete_floating_ip(cloudname=cloudname,
                                         floating_ip=floating_ip)

        # Floating IP Pool List
        elif arguments["list"] \
                and arguments["floating"] \
                and arguments["pool"]:
            result = Network.list_floating_ip_pool(cloudname)
            Console.msg(result)

        # Floating IP list [or info]
        elif arguments["list"] \
                and arguments["floating"]:

            ip_or_id = arguments["IP_OR_ID"]
            instance_id = arguments["--instance"]

            # List unused floating addr
            if arguments["--unused"]:
                result = Network.list_unused_floating_ip(cloudname=cloudname)
                Console.msg(result)
                return ""

            # Refresh VM in db
            self.refresh_vm(cloudname)

            # If instance id is supplied
            if instance_id is not None:
                instance_dict = Network.get_instance_dict(
                    cloudname=cloudname, instance_id=instance_id)
                # Instance not found
                if instance_dict is None:
                    Console.error(
                        "Instance {} not found in the cloudmesh database!".
                        format(instance_id))
                    return ""

                # Read the floating_ip from the dict
                ip_or_id = instance_dict["floating_ip"]

                if ip_or_id is None:
                    Console.error(
                        "Instance with ID {} does not have a floating IP address!"
                        .format(instance_id))
                    return ""

            # If the floating ip or associated ID is supplied
            if ip_or_id is not None:
                result = Network.get_floating_ip(cloudname,
                                                 floating_ip_or_id=ip_or_id)

                if result is not None:
                    Console.msg(result)
                else:
                    Console.error(
                        "Floating IP not found! Please check your arguments.")
                    return ""
            # Retrieve the full list
            else:
                result = Network.list_floating_ip(cloudname)
                Console.msg(result)

        # Create a virtual cluster
        elif arguments["cluster"] and \
                arguments["create"]:

            group_name = arguments["--group"] or \
                         Default.get(name="group", category=cloudname)

            # Get the group information
            group = Group.get_info(name=group_name,
                                   category=cloudname,
                                   output="json")
            if group is not None:
                # Convert from str to json
                group = json.loads(group)

                # var contains pub key of all vms
                public_keys = ""
                login_users = []
                login_ips = []

                # For each vm in the group
                # Create and assign a floating IP
                for item in group:
                    instance_id = group[item]["value"]
                    # Get the instance dict
                    instance_dict = Network.get_instance_dict(
                        cloudname=cloudname, instance_id=instance_id)
                    # Instance not found
                    if instance_dict is None:
                        Console.error(
                            "Instance {} not found in the cloudmesh database!".
                            format(instance_id))
                        return ""

                    # Get the instance name
                    instance_name = instance_dict["name"]
                    floating_ip = instance_dict["floating_ip"]

                    # If vm does not have floating ip, then create
                    if floating_ip is None:
                        floating_ip = Network.create_assign_floating_ip(
                            cloudname=cloudname, instance_name=instance_name)
                        if floating_ip is not None:
                            Console.ok(
                                "Created and assigned Floating IP {} to instance {}."
                                .format(floating_ip, instance_name))
                            # Refresh VM in db
                            self.refresh_vm(cloudname)

                    # Get the login user for this machine
                    user = input("Enter the login user for VM {} : ".format(
                        instance_name))
                    passphrase = getpass.getpass(
                        "Enter the passphrase key on VM {} : ".format(
                            instance_name))

                    # create list for second iteration
                    login_users.append(user)
                    login_ips.append(floating_ip)

                    login_args = [
                        user + "@" + floating_ip,
                    ]

                    keygen_args = [
                        "ssh-keygen -t rsa -f ~/.ssh/id_rsa -N " + passphrase
                    ]

                    cat_pubkey_args = ["cat ~/.ssh/id_rsa.pub"]

                    generate_keypair = login_args + keygen_args
                    result = Shell.ssh(*generate_keypair)

                    # print("***** Keygen *****")
                    # print(result)

                    cat_public_key = login_args + cat_pubkey_args
                    result = Shell.ssh(*cat_public_key)
                    public_keys += "\n" + result

                    # print("***** id_rsa.pub *****")
                    # print(result)

                # print("***** public keys *****")
                # print(public_keys)

                for user, ip in zip(login_users, login_ips):
                    arguments = [
                        user + "@" + ip,
                        "echo '" + public_keys + "' >> ~/.ssh/authorized_keys"
                    ]

                    # copy the public key contents to auth_keys
                    result = Shell.ssh(*arguments)

                Console.ok("Virtual cluster creation successfull.")
            else:
                Console.error("No group {} in the Cloudmesh database.".format(
                    group_name))
                return ""

        return ""
예제 #33
0
    def do_default(self, args, arguments):
        """
        ::

          Usage:
              default
              default list [--cloud=CLOUD] [--format=FORMAT] [--all]
              default delete KEY [--cloud=CLOUD]
              default KEY [--cloud=CLOUD]
              default KEY=VALUE [--cloud=CLOUD]

          Arguments:
            KEY    the name of the default
            VALUE  the value to set the key to

          Options:
             --cloud=CLOUD    the name of the cloud
             --format=FORMAT  the output format. Values include
                              table, json, csv, yaml.
             --all            lists all the default values

        Description:
            Cloudmesh has the ability to manage easily multiple
            clouds. One of the key concepts to manage multiple clouds
            is to use defaults for the cloud, the images, flavors,
            and other values. The default command is used to manage
            such default values. These defaults are used in other commands
            if they are not overwritten by a command parameter.

            The current default values can by listed with

                default list --all

            Via the default command you can list, set, get and delete
            default values. You can list the defaults with

               default list

            A default can be set with

                default KEY=VALUE

            To look up a default value you can say

                default KEY

            A default can be deleted with

                default delete KEY

            To be specific to a cloud you can specify the name of the
            cloud with the --cloud=CLOUD option. The list command can
            print the information in various formats iv specified.

        Examples:
            default
                lists the default for the current default cloud

            default list --all
                lists all default values

            default list --cloud=kilo
                lists the defaults for the cloud with the name kilo

            default image=xyz
                sets the default image for the default cloud to xyz

            default image=abc --cloud=kilo
                sets the default image for the cloud kilo to xyz

            default image
                list the default image of the default cloud

            default image --cloud=kilo
                list the default image of the cloud kilo

            default delete image
                deletes the value for the default image in the
                default cloud

            default delete image --cloud=kilo
                deletes the value for the default image in the
                cloud kilo

        """
        #print(arguments)
        #print (">", args, "<")

        """
        For these keys, the 'cloud' column in db
        will always be 'general'.
        """
        general_keys = ["cloud", "cluster", "queue", "key", "group", "user", "secgroup", "vm",
                        "refresh", "debug", "interactive", "purge"]

        """
        If the default cloud has been set (eg. default category=xxx),
        then subsequent defaults for any key (eg. default image=yyy),
        will have 'cloud' column in db as the default cloud that was set.
        (eg. image=yyy for category=xxx).
        """

        if arguments["KEY"] in general_keys:
            cloud = "general"
        elif args == '':
            cloud = "general"
            arguments["--cloud"] = cloud
            arguments["list"] = True
            order = ['name', 'value']
            output_format = arguments["--format"]
            result = Default.list(category=cloud,
                                  order=order,
                                  output=output_format)
            print(result)
            return ""

        else:
            cloud = arguments["--cloud"] or Default.get(name="cloud", category="general") or "general"

        if arguments["list"]:
            output_format = arguments["--format"] or Default.output or 'table'

            if arguments['--all'] or arguments["--cloud"] is None:
                cloud = None
            result = Default.list(category=cloud, output=output_format)

            if result is None:
                Console.error("No default values found")
            else:
                print(result)
            return ""

        elif arguments["delete"]:

            key = arguments["KEY"]
            if key in general_keys:
                cloud = "general"
            result = Default.delete(key, cloud)
            if not result :
                Console.error("default {} not present".format(key))
            else:
                Console.ok("Deleted key {} for cloud {}. ok.".format(key,
                                                                     cloud))
            return ""

        elif "=" in arguments["KEY"]:
            key, value = arguments["KEY"].split("=")
            if key in general_keys:
                cloud = "general"
            if key in "debug":
                Default.set_debug(value)
            else:
                Default.set(key, value, category=cloud)
            Console.ok(
                "set default {}={}. ok.".format(key, value))
            return ""

        elif arguments["KEY"]:
            key = arguments["KEY"]
            if key in general_keys:
                cloud = "general"
            result = Default.get(name=key, category=cloud)
            if result is None:
                Console.error("No default values found")
            else:
                Console.ok("{}".format(result))
            return ""
예제 #34
0
    def do_list(self, args, arguments):
        """
        ::

            Usage:
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] default
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] vm
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] flavor
                list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] image

            List the items stored in the database

            Options:
                --cloud=CLOUD    the name of the cloud
                --format=FORMAT  the output format
                --tenant=TENANT     Name of the tenant, e.g. fg82.

            Description:
                List command prints the values stored in the database
                for [default/vm/flavor/image].
                Result can be filtered based on the cloud, user & tenant arguments.
                If these arguments are not specified, it reads the default

            Examples:
                $ list --cloud india default
                $ list --cloud india --format table flavor
                $ list --cloud india --user albert --tenant fg82 flavor
        """
        # pprint(arguments)

        # Method to get the kind from args
        #
        # TODO: the kind are defined in the provider,
        # TODO: keep the kind lower case
        # why is there a reason to make the gind upper case
        def get_kind():
            for k in ["vm", "image", "flavor", "default"]:
                if arguments[k]:
                    # kinds are all uppercase in model.py
                    return k.upper()
            return "help"

        # Read commandline arguments
        output_format = arguments['--format']
        cloud = arguments['--cloud'] or Default.get_cloud()
        user = arguments['--user']
        tenant = arguments['--tenant']

        # If format is not specified, read default
        if output_format is None:
            output_format = Default.get("format") or "table"

        # If cloud is not specified, get default
        if cloud is None:
            cloud = Default.get("cloud") or "kilo"

        # If user is not specified, get default
        if user is None:
            user = Default.get("user")

        # If tenant is not specified, get default
        if tenant is None:
            tenant = Default.get("tenant")

        # Get the kind
        kind = get_kind()
        header = None
        order = None

        # print help message
        if kind == 'help':
            Console.ok("Print help!")
            return ""

        # Prepare the order & header based on kind
        # TODO: use lower case so we have a convention thats easy to follow
        # TODO: add quota
        # TODO: add limits
        # TODO: add usage
        if kind == 'FLAVOR':
            order = [
                'cm_cloud',
                'disk',
                'ephemeral_disk',
                'id',
                'name',
                'ram',
                'vcpus'
            ]
        elif kind == 'DEFAULT':
            order = ['user',
                     'cloud',
                     'name',
                     'value',
                     'created_at',
                     'updated_at'
                     ]
        elif kind == 'IMAGE':
            order = [
                'cm_cloud',
                'cm_user',
                'instance_type_ephemeral_gb',
                'instance_type_flavorid',
                'instance_type_id',
                'instance_type_memory_mb',
                'instance_type_name',
                'instance_type_root_gb',
                'instance_type_rxtx_factor',
                'instance_type_swap',
                'instance_type_vcpus',
                'minDisk',
                'minRam',
                'name',
            ]
            header = [
                'cloud',
                'user',
                'ephemeral_gb',
                'flavorid',
                'id',
                'memory_mb',
                'flavor',
                'root_gb',
                'rxtx_factor',
                'swap',
                'vcpus',
                'minDisk',
                'minRam',
                'name',
            ]

        # Get the result & print it
        result = List.list(kind,
                           cloud,
                           user,
                           tenant,
                           order,
                           header,
                           output_format)
        if result:
            print(result)
        else:
            Console.error("No {}s found in the database."
                          .format(kind.lower()))
        return ""
예제 #35
0
    def do_group(self, args, arguments):
        """
        ::

            Usage:
                group list [GROUPNAME] [--format=FORMAT]
                group remove NAMES [--group=GROUPNAME]
                group add NAMES [--type=TYPE] [--group=GROUPNAME]
                group delete GROUPS
                group copy FROM TO
                group merge GROUPA GROUPB MERGEDGROUP

            manage the groups

            Arguments:

                NAMES        names of object to be added
                GROUPS       names of a groups
                FROM         name of a group
                TO           name of a group
                GROUPA       name of a group
                GROUPB       name of a group
                MERGEDGROUP  name of a group

            Options:
                --format=FORMAT     the output format
                --type=TYPE         the resource type
                --name=NAME         the name of the group
                --id=IDS            the ID(s) to add to the group


            Description:

                Todo: design parameters that are useful and match
                description
                Todo: discuss and propose command

                cloudmesh can manage groups of resource related
                objects. As it would be cumbersome to for example delete
                many virtual machines or delete VMs that are in the same
                group, but are running in different clouds.

                Hence it is possible to add a virtual machine to a
                specific group. The group name to be added to can be set
                as a default. This way all subsequent commands use this
                default group. It can also be set via a command parameter.
                Another convenience function is that the group command can
                use the last used virtual machine. If a vm is started it
                will be automatically added to the default group if it is set.

                If finer grained deletion is needed, it can be achieved
                with the delete command that supports deletion by name

                It is also possible to remove a VM from the group using the
                remove command, by supplying the ID

            Note:

                The type is internally called for the group species, we may
                eliminate the species column and just use the type column for it,

            Example:
                default group mygroup

                group add --type=vm --id=albert-[001-003]
                    adds the vms with the given name using the Parameter
                    see base

                group add --type=vm
                 adds the last vm to the group

                group delete --name=mygroup
                    deletes all objects in the group
        """
        # pprint(arguments)

        if arguments["list"]:

            output = arguments["--format"] or Default.get(
                name="format", category="general") or "table"
            name = arguments["GROUPNAME"]
            if name is None:

                result = Group.list(output=output)
                if result:
                    print(result)
                else:
                    print(
                        "No groups found other than the default group but it has no members."
                    )

            else:

                result = Group.list(name=name, output=output)

                if result:
                    print(result)
                else:
                    msg_a = ("No group found with name `{name}` found in the "
                             "category `{category}`.".format(**locals()))
                '''
                    # find alternate
                    result = Group.get(name=name)

                    msg_b = ""
                    if result is not None and len(result) < 0:
                        msg_b = " However we found such a variable in " \
                                "category `{category}`. Please consider " \
                                "using --category={category}".format(**locals())
                        Console.error(msg_a + msg_b)
                    else:
                        Console.error("No group with name {name} exists.".format(**locals()))
                '''

                return ""

        elif arguments["add"]:
            # group add NAME... [--type=TYPE] [--category=CLOUD] [--group=GROUP]

            print("AAA", arguments["NAMES"])
            members = Parameter.expand(arguments["NAMES"])
            print("MMMM", members)
            data = dotdict({
                "species": arguments["--type"] or "vm",
                "name": arguments["--group"] or Default.group
            })
            print("DDD", data)
            for member in members:
                data.member = member
                pprint(data)
                Group.add(**data)

            return ""

        elif arguments["delete"]:
            groups = Parameter.expand(arguments["GROUPS"])

            for group in groups:
                result = Group.delete(group)

                if result:
                    Console.ok(result)
                else:
                    Console.error("delete group {}. failed.".format(group))
            return ""

        elif arguments["remove"]:
            members = Parameter.expand(arguments["NAMES"])

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

            for member in members:
                result = Group.remove(group, member)

                if result:
                    Console.ok(result)
                else:
                    Console.error("remove {} from group {}. failed.".format(
                        group, member))
            return ""

        elif arguments["copy"]:
            _from = arguments["FROM"]
            _to = arguments["TO"]

            Group.copy(_from, _to)
            return ""

        elif arguments["merge"]:
            _groupA = arguments["GROUPA"]
            _groupB = arguments["GROUPB"]
            _mergedGroup = arguments["MERGEDGROUP"]

            Group.merge(_groupA, _groupB, _mergedGroup)
            return ""
예제 #36
0
    def do_vm(self, args, arguments):
        """
        ::

            Usage:
                vm default [--cloud=CLOUD][--format=FORMAT]
                vm refresh [all][--cloud=CLOUD]
                vm boot [--name=NAME]
                        [--cloud=CLOUD]
                        [--username=USERNAME]
                        [--image=IMAGE]
                        [--flavor=FLAVOR]
                        [--group=GROUP]
                        [--public]
                        [--secgroup=SECGROUP]
                        [--key=KEY]
                        [--dryrun]
                vm boot [--n=COUNT]
                        [--cloud=CLOUD]
                        [--username=USERNAME]
                        [--image=IMAGE]
                        [--flavor=FLAVOR]
                        [--group=GROUP]
                        [--public]
                        [--secgroup=SECGROUP]
                        [--key=KEY]
                        [--dryrun]
                vm ping [NAME] [N]
                vm console [NAME]
                         [--group=GROUP]
                         [--cloud=CLOUD]
                         [--force]
                vm start [NAMES]
                         [--group=GROUP]
                         [--cloud=CLOUD]
                         [--force]
                vm stop [NAMES]
                        [--group=GROUP]
                        [--cloud=CLOUD]
                        [--force]
                vm terminate [NAMES]
                          [--group=GROUP]
                          [--cloud=CLOUD]
                          [--force]
                vm delete [NAMES]
                          [--group=GROUP]
                          [--cloud=CLOUD]
                          [--keep]
                          [--dryrun]
                vm ip assign [NAMES]
                          [--cloud=CLOUD]
                vm ip show [NAMES]
                           [--group=GROUP]
                           [--cloud=CLOUD]
                           [--format=FORMAT]
                           [--refresh]
                vm ip inventory [NAMES]
                                [--header=HEADER]
                                [--file=FILE]
                vm ssh [NAME] [--username=USER]
                         [--quiet]
                         [--ip=IP]
                         [--cloud=CLOUD]
                         [--key=KEY]
                         [--command=COMMAND]
                vm rename [OLDNAMES] [NEWNAMES] [--force] [--dryrun]
                vm list [NAMES]
                        [--cloud=CLOUDS|--active]
                        [--group=GROUP]
                        [--format=FORMAT]
                        [--refresh]
                vm status [NAMES]
                vm wait [--cloud=CLOUD] [--interval=SECONDS]
                vm info [--cloud=CLOUD]
                        [--format=FORMAT]
                vm check NAME
                vm username USERNAME [NAMES] [--cloud=CLOUD]

            Arguments:
                COMMAND        positional arguments, the commands you want to
                               execute on the server(e.g. ls -a) separated by ';',
                               you will get a return of executing result instead of login to
                               the server, note that type in -- is suggested before
                               you input the commands
                NAME           server name. By default it is set to the name of last vm from database.
                NAMES          server name. By default it is set to the name of last vm from database.
                KEYPAIR_NAME   Name of the openstack keypair to be used to create VM. Note this is
                               not a path to key.
                NEWNAMES       New names of the VM while renaming.
                OLDNAMES       Old names of the VM while renaming.

            Options:
                --username=USERNAME  the username to login into the vm. If not specified it will be guessed
                                     from the image name and the cloud
                --ip=IP          give the public ip of the server
                --cloud=CLOUD    give a cloud to work on, if not given, selected
                                 or default cloud will be used
                --count=COUNT    give the number of servers to start
                --detail         for table print format, a brief version
                                 is used as default, use this flag to print
                                 detailed table
                --flavor=FLAVOR  give the name or id of the flavor
                --group=GROUP          give the group name of server
                --secgroup=SECGROUP    security group name for the server
                --image=IMAGE    give the name or id of the image
                --key=KEY        specify a key to use, input a string which
                                 is the full path to the private key file
                --keypair_name=KEYPAIR_NAME   Name of the openstack keypair to be used to create VM.
                                              Note this is not a path to key.
                --user=USER      give the user name of the server that you want
                                 to use to login
                --name=NAME      give the name of the virtual machine
                --force          rename/ delete vms without user's confirmation
                --command=COMMAND
                                 specify the commands to be executed


            Description:
                commands used to boot, start or delete servers of a cloud

                vm default [options...]
                    Displays default parameters that are set for vm boot either on the
                    default cloud or the specified cloud.

                vm boot [options...]
                    Boots servers on a cloud, user may specify flavor, image .etc, otherwise default values
                    will be used, see how to set default values of a cloud: cloud help

                vm start [options...]
                    Starts a suspended or stopped vm instance.

                vm stop [options...]
                    Stops a vm instance .

                vm delete [options...]
                    Delete servers of a cloud, user may delete a server by its name or id, delete servers
                    of a group or servers of a cloud, give prefix and/or range to find servers by their names.
                    Or user may specify more options to narrow the search

                vm floating_ip_assign [options...]
                    assign a public ip to a VM of a cloud

                vm ip show [options...]
                    show the ips of VMs

                vm ssh [options...]
                    login to a server or execute commands on it

                vm list [options...]
                    same as command "list vm", please refer to it

                vm status [options...]
                    Retrieves status of last VM booted on cloud and displays it.

            Tip:
                give the VM name, but in a hostlist style, which is very
                convenient when you need a range of VMs e.g. sample[1-3]
                => ['sample1', 'sample2', 'sample3']
                sample[1-3,18] => ['sample1', 'sample2', 'sample3', 'sample18']

            Quoting commands:
                cm vm login gvonlasz-004 --command=\"uname -a\"
        """

        """

        # terminate
        #  issues a termination to the cloud, keeps vm in database

        # delete
        #   issues a terminate if not already done
        #      (remember you do not have to go to cloud if state is already terminated)
        #   deletes the vm from database
        #


        # bulk rename

        rename abc[0-1] def[3-4]       renames the abc0,abc1 -> def3,def4

        if arguments["rename"]:
            oldnames = Parameter.expand(arguments["OLDNAME"])
            newnames = Parameter.expand(arguments["NEWNAME"])

            # check if new names ar not already taken
            # to be implemented

            if len(oldnames) == len(newnames):
                for i in range(0, len(oldnames)):
                    oldname = oldnames[i]
                    newname = newnames[i]
                if newname is None or newname == '':
                    print("New node name cannot be empty")
                else:
                    print(Cluster.rename_node(clusterid, oldname, newname))
        """

        cm = CloudmeshDatabase()

        def _print_dict(d, header=None, output='table'):
            return Printer.write(d, order=["id", "name", "status"], output=output, sort_keys=True)

        def _print_dict_ip(d, header=None, output='table'):
            return Printer.write(d, order=["network", "version", "addr"], output=output, sort_keys=True)

        def get_vm_name(name=None, offset=0, fill=3):

            if name is None:
                count = Default.get_counter(name='name') + offset
                prefix = Default.user
                if prefix is None or count is None:
                    Console.error("Prefix and Count could not be retrieved correctly.", traceflag=False)
                    return
                name = prefix + "-" + str(count).zfill(fill)
            return name

        def _refresh_cloud(cloud):
            try:
                msg = "Refresh VMs for cloud {:}.".format(cloud)
                if Vm.refresh(cloud=cloud):
                    Console.ok("{:} OK.".format(msg))
                else:
                    Console.error("{:} failed".format(msg), traceflag=False)
            except Exception as e:
                Console.error("Problem running VM refresh", traceflag=False)

        def _get_vm_names():

            vm_list  = cm.find(kind="vm")

            vms = [vm["name"] for vm in vm_list]

            names = pattern = arguments["NAMES"]
            if pattern is not None:
                if "*" in pattern:
                    names = search(vms, pattern)
                else:
                    names = Parameter.expand(names)

            if names == ['last'] or names is None:
                names == [Default.vm]

            return vm_list, names

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

        config = ConfigDict("cloudmesh.yaml")
        active_clouds = config["cloudmesh"]["active"]

        def _refresh(cloud):
            all = arguments["all"] or None

            if all is None:

                _refresh_cloud(cloud)
            else:
                for cloud in active_clouds:
                    _refresh_cloud(cloud)

        arg = dotdict(arguments)

        arg.cloud = arguments["--cloud"] or Default.cloud
        arg.image = arguments["--image"] or Default.get(name="image", category=arg.cloud)
        arg.flavor = arguments["--flavor"] or Default.get(name="flavor", category=arg.cloud)
        arg.group = arguments["--group"] or Default.group
        arg.secgroup = arguments["--secgroup"] or Default.secgroup
        arg.key = arguments["--key"] or Default.key
        arg.dryrun = arguments["--dryrun"]
        arg.name = arguments["--name"]
        arg.format = arguments["--format"] or 'table'
        arg.refresh = Default.refresh or arguments["--refresh"]
        arg.count = int(arguments["--n"] or 1)
        arg.dryrun = arguments["--dryrun"]
        arg.verbose = not arguments["--quiet"]

        #
        # in many cases use NAMES
        # if arg.NAMES is not None:
        #   arg.names = Parameter.expand(arg.NAMES)   #  gvonlasz[001-002]  gives ["gvonlasz-001", "gvonlasz-002"]
        # else:
        #    arg.names = None
        #

        if arguments["boot"]:

            arg.username = arguments["--username"] or Image.guess_username(arg.image)
            is_name_provided = arg.name is not None

            arg.user = Default.user

            for index in range(0, arg.count):
                vm_details = dotdict({
                    "cloud": arg.cloud,
                    "name": get_vm_name(arg.name, index),
                    "image": arg.image,
                    "flavor": arg.flavor,
                    "key": arg.key,
                    "secgroup": arg.secgroup,
                    "group": arg.group,
                    "username": arg.username,
                    "user": arg.user
                })
                # correct the username
                vm_details.username = Image.guess_username_from_category(
                    vm_details.cloud,
                    vm_details.image,
                    username=arg.username)
                try:

                    if arg.dryrun:
                        print(Printer.attribute(vm_details, output=arg.format))
                        msg = "dryrun info. OK."
                        Console.ok(msg)
                    else:
                        vm_id = Vm.boot(**vm_details)

                        if vm_id is None:
                            msg = "info. failed."
                            Console.error(msg, traceflag=False)
                            return ""

                        # set name and counter in defaults
                        Default.set_vm(value=vm_details.name)
                        if is_name_provided is False:
                            Default.incr_counter("name")

                        # Add to group
                        if vm_id is not None:
                            Group.add(name=vm_details.group,
                                      species="vm",
                                      member=vm_details.name,
                                      category=vm_details.cloud)

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

                except Exception as e:
                    Console.error("Problem booting instance {name}".format(**vm_details), traceflag=False)

        elif arguments["username"]:

            arg.username = arguments["--username"] or Image.guess_username(arg.image)

            cloud = arg.cloud
            username = arg.USERNAME
            if arg.NAMES is None:
                names = [Default.vm]
            else:
                names = Parameter.expand(arg.NAMES)

            if len(names) == 0:
                return

            for name in names:
                arg.name = name
                Console.ok("Set username for {cloud}:{name} to {USERNAME}".format(**arg))
                Vm.set_login_user(name=name, cloud=cloud, username=username)

        elif arguments["default"]:
            try:
                count = Default.get_counter()
                prefix = Username()

                if prefix is None or count is None:
                    Console.error("Prefix and Count could not be retrieved correctly.", traceflag=False)
                    return

                vm_name = prefix + "-" + str(count).zfill(3)
                arg = {
                    "name": vm_name,
                    "cloud": arguments["--cloud"] or Default.cloud
                }
                for attribute in ["image", "flavor"]:
                    arg[attribute] = Default.get(name=attribute, category=cloud)
                for attribute in ["key", "group", "secgroup"]:
                    arg[attribute] = Default.get(name=attribute, category='general')

                output = arguments["--format"] or "table"
                print(Printer.attribute(arg, output=output))
                msg = "info. OK."
                Console.ok(msg)
                ValueError("default command not implemented properly. Upon "
                           "first install the defaults should be read from yaml.")
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem listing defaults", traceflag=False)

        elif arguments["ping"]:
            try:
                if arguments["NAME"] is None and arguments["N"] is None:
                    name = arguments["NAME"] or Default.vm
                    n = arguments["N"] or 1
                elif arguments["NAME"].isdigit():
                    n = arguments["NAME"]
                    name = Default.vm
                else:
                    name = arguments["NAME"] or Default.vm
                    n = arguments["N"] or 1

                print("Ping:", name, str(n))

                vm = dotdict(Vm.list(name=name, category=cloud, output="dict")["dict"])

                ip = vm.floating_ip

                result = Shell.ping(host=ip, count=n)
                print(result)

            except Exception as e:
                Console.error(e.message, traceflag=False)

        elif arguments["console"]:
            try:
                name = arguments["NAME"] or Default.vm

                vm = dotdict(Vm.list(name=name, category=cloud, output="dict")["dict"])

                cloud_provider = CloudProvider(cloud).provider
                vm_list = cloud_provider.list_console(vm.uuid)
                print(vm_list)
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem retrieving status of the VM", traceflag=False)

        elif arguments["status"]:
            try:
                cloud_provider = CloudProvider(cloud).provider
                vm_list = cloud_provider.list_vm(cloud)

                vms = [vm_list[i]["name"] for i in vm_list ]
                print ("V", vms)

                pattern = arguments["NAMES"]
                if pattern is not None:
                    if "*" in pattern:
                        print ("serach")
                        names  = search(vms, pattern)
                    else:
                        names = Parameter.expand()
                    for i in vm_list:
                        if vm_list[i]["name"] in names:
                            print("{} {}".format(vm_list[i]["status"], vm_list[i]["name"]))
                else:
                    print("{} {}".format(vm_list[0]["status"], vm_list[0]["name"]))
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem retrieving status of the VM", traceflag=True)
        elif arguments["wait"]:
            interval = arguments["--interval"] or 5
            try:
                cloud_provider = CloudProvider(cloud).provider
                for i in range(1,10):
                    vm_list = cloud_provider.list_vm(cloud)
                    time.sleep(float(1))
                    d = {}
                    for id in vm_list:
                        vm = vm_list[id]
                        d[vm["name"]] = vm["status"]
                    print (d)
                    print("{} {}".format(vm_list[0]["status"], vm_list[0]["name"]))
                    if vm_list[0]["status"] in ['ACTIVE']:
                        return
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem retrieving status of the VM", traceflag=True)

        elif arguments["info"]:
            try:
                cloud_provider = CloudProvider(cloud).provider
                vms = cloud_provider.list_vm(cloud)
                vm = vms[0]
                output_format = arguments["--format"] or "table"
                print(Printer.attribute(vm, output=output_format))
                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem retrieving status of the VM", traceflag=False)

        elif arguments["check"]:

            test = {}
            try:

                names = Parameter.expand(arguments["NAME"])
                id = 0
                for name in names:
                    print("Not implemented: {}".format(name))
                    # TODO: check the status of the vms
                    status = "active"
                    # TODO: check if they have a floating ip
                    # TODO: get ip
                    floating_ip = "127.0.0.1"
                    ip = True
                    # ping
                    # TODO: ping the machine with the shell command
                    ping = True
                    # check if one can login and run a command
                    check = False
                    try:
                        r = Shell.execute("uname", "-a")
                        # do a real check
                        check = True
                    except:
                        check = False
                    test[name] = {
                        "id": id,
                        "name": name,
                        "status": status,
                        "ip": ip,
                        "ping": ping,
                        "login": check
                    }
                    id += 1

                pprint(test)

                print(Printer.write(test,
                                    order=["id",
                                           "name",
                                           "status",
                                           "ip",
                                           "ping",
                                           "login"],
                                    output="table",
                                    sort_keys=True))

                msg = "not yet implemented. failed."
                Console.error(msg, traceflag=False)
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem retrieving status of the VM", traceflag=False)

        elif arguments["start"]:
            try:
                servers = Parameter.expand(arguments["NAMES"])

                # If names not provided, take the last vm from DB.
                if len(servers) == 0:
                    last_vm = Default.vm
                    if last_vm is None:
                        Console.error("No VM records in database. Please run vm refresh.", traceflag=False)
                        return ""
                    name = last_vm["name"]
                    # print(name)
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.", traceflag=False)
                    return ""

                Vm.start(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem starting instances", traceflag=False)

        elif arguments["stop"]:
            try:
                servers = Parameter.expand(arguments["NAMES"])

                # If names not provided, take the last vm from DB.
                if servers is None or len(servers) == 0:
                    last_vm = Default.vm
                    if last_vm is None:
                        Console.error("No VM records in database. Please run vm refresh.", traceflag=False)
                        return ""
                    name = last_vm["name"]
                    # print(name)
                    servers = list()
                    servers.append(name)

                group = arguments["--group"]
                force = arguments["--force"]

                # if default cloud not set, return error
                if not cloud:
                    Console.error("Default cloud not set.", traceflag=False)
                    return ""

                Vm.stop(cloud=cloud, servers=servers)

                msg = "info. OK."
                Console.ok(msg)
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem stopping instances", traceflag=False)

        elif arguments["refresh"]:

            _refresh(cloud)

        elif arguments["delete"]:

            dryrun = arguments["--dryrun"]
            group = arguments["--group"]
            force = not arguments["--keep"]
            cloud = arguments["--cloud"]
            vms, servers = _get_vm_names()

            if servers in [None, []]:
                Console.error("No vms found.", traceflag=False)
                return ""

            for server in servers:
                if dryrun:
                    Console.ok("Dryrun: delete {}".format(server))
                else:
                   Vm.delete(servers=[server], force=force)

            return ""

        elif arguments["ip"] and arguments["assign"]:
            if arguments["NAMES"] is None:
                names = [Default.vm]
            else:
                names = Parameter.expand(arguments["NAMES"])

            for name in names:

                # ip = Network.get_floatingip(....)

                vm = dotdict(Vm.list(name=name, category=cloud, output="dict")["dict"])

                if vm.floating_ip is None:

                    Console.ok("Assign IP to {}".format(name))

                    try:
                        floating_ip = Network.find_assign_floating_ip(cloudname=cloud,
                                                                      instance_id=name)

                        Vm.refresh(cloud=cloud)

                        if floating_ip is not None:
                            print(
                                "Floating IP assigned to {:} is {:}".format(
                                    name, floating_ip))
                            msg = "info. OK."
                            Console.ok(msg)
                    except Exception as e:

                        Console.error("Problem assigning floating ips.", traceflag=False)

                else:
                    Console.error("VM {} already has a floating ip: {}".format(name, vm.floating_ip), traceflag=False)


        elif arguments["ip"] and arguments["inventory"]:

            vms, names = _get_vm_names()

            if names in [None, []]:
                if str(Default.vm) in ['None', None]:
                    Console.error("The default vm is not set.", traceflag=False)
                    return ""
                else:
                    names = [Default.vm]

            header = arguments["--header"] or "[servers]"
            filename = arguments["--file"] or "inventory.txt"

            try:
                vm_ips = []
                for vm in vms:
                    if  vm["name"] in names:
                        print (vm["name"])
                        vm_ips.append(vm["floating_ip"])

                result = header + "\n"

                result += '\n'.join(vm_ips)
                Console.ok("Creating inventory file: {}".format(filename))

                Console.ok(result)

                with open(filename, 'w') as f:
                    f.write(result)



            except Exception as e:
                Console.error("Problem getting ip addresses for instance", traceflag=True)

        elif arguments["ip"] and arguments["show"]:
            if arguments["NAMES"] is None:
                if str(Default.vm) in ['None', None]:
                    Console.error("The default vm is not set.", traceflag=False)
                    return ""
                else:
                    names = [Default.vm]
            else:
                names = Parameter.expand(arguments["NAMES"])

            group = arguments["--group"]
            output_format = arguments["--format"] or "table"
            refresh = arguments["--refresh"]

            try:

                ips = Ip.list(cloud=arg.cloud, output=output_format, names=names)
                print(ips)
            except Exception as e:
                Console.error("Problem getting ip addresses for instance", traceflag=False)

        elif arguments["ssh"]:

            def _print(msg):
                if arg.verbose:
                    Console.msg(msg)

            chameleon = "chameleon" in ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["clouds"][arg.cloud][
                "cm_host"]

            if chameleon:
                arg.username = "******"
            elif arg.cloud == "azure":
                arg.username = ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["clouds"]["azure"]["default"]["username"]
            else:
                if arg.username is None:
                    Console.error("Could not guess the username of the vm", traceflag=False)
                    return
                arg.username = arguments["--username"] or Image.guess_username(arg.image)
            arg.command = arguments["--command"]

            data = dotdict({
                'name': arguments["NAME"] or Default.vm,
                'username': arg.username,
                'cloud': arg.cloud,
                'command': arg.command
            })

            _print("login {cloud}:{username}@{name}".format(**data))

            vm = Vm.get(data.name, category=data.cloud)


            Vm.set_login_user(name=data.name, cloud=data.cloud, username=data.username)

            data.floating_ip = vm.floating_ip
            data.key = arguments["--key"] or Default.key

            _print(Printer.attribute(data))

            '''
            if vm.username is None:
                user_from_db = Vm.get_login_user(vm.name, vm.cloud)

                user_suggest = user_from_db or Default.user
                username = input("Username (Default: {}):".format(user_suggest)) or user_suggest

            Vm.set_login_user(name=data.name, cloud=cloud, username=data.username)
            '''

            ip = arguments["--ip"]
            commands = arguments["--command"]

            ip_addresses = []

            cloud_provider = CloudProvider(cloud).provider
            ip_addr = cloud_provider.get_ips(vm.name)

            ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud)
            for entry in ipaddr_dict:
                ip_addresses.append(ipaddr_dict[entry]["addr"])

            if len(ip_addresses) > 0:
                if ip is not None:
                    if ip not in ip_addresses:
                        Console.error("IP Address specified does not match with the host.", traceflag=False)
                        return ""
                else:
                    _print("Determining IP Address to use with a ping test.")
                    # This part assumes that the ping is allowed to the machine.
                    for ipadd in ip_addresses:
                        _print("Checking {:}...".format(ipadd))
                        try:
                            # Evading ping test, as ping is not enabled for VMs on Azure cloud
                            # socket.gethostbyaddr(ipadd)
                            # ip will be set if above command is successful.
                            ip = ipadd
                        except socket.herror:
                            _print("Cannot reach {:}.".format(ipadd))

                if ip is None:
                    _print("Unable to connect to the machine")
                    return ""
                else:
                    _print("IP to be used is: {:}".format(ip))

                #
                # TODO: is this correctly implemented
                #
                if not cloud == 'azure':
                    SecGroup.enable_ssh(cloud=cloud)

                if arg.verbose:
                    Console.info("Connecting to Instance at IP:" + format(ip))
                # Constructing the ssh command to connect to the machine.
                sshcommand = "ssh"
                if arg.key is not None:
                    sshcommand += " -i {:}".format(arg.key)
                sshcommand += " -o StrictHostKeyChecking=no"
                sshcommand += " {:}@{:}".format(data.username, ip)
                if commands is not None:
                    sshcommand += " \"{:}\"".format(commands)

                # print(sshcommand)
                os.system(sshcommand)
            else:
                Console.error("No Public IPs found for the instance", traceflag=False)

        elif arguments["list"]:

            # groups = Group.list(output="dict")

            arg = dotdict(arguments)
            arg.names = arguments["NAMES"]

            arg.group = arguments["--group"]
            if arg.group is None:
                arg.group = []
            else:
                arg.group = Parameter.expand(arguments["--group"])

            arg.refresh = arguments["--refresh"] or Default.refresh

            if arg.NAMES is not None:
                arg.names = Parameter.expand(arguments["NAMES"])
            else:
                arg.names = ["all"]

            _format = arguments["--format"] or "table"

            if arguments["--active"]:
                clouds = active_clouds
            else:
                if arguments["--cloud"]:
                    clouds = Parameter.expand(arguments["--cloud"])
                else:
                    clouds = [Default.cloud]

            try:

                d = ConfigDict("cloudmesh.yaml")
                for cloud in clouds:

                    if arg.refresh:
                        _refresh(cloud)

                    Console.ok("Listing VMs on Cloud: {:}".format(cloud))

                    vms = Vm.list(category=cloud, output="raw")

                    # print ("XXX", type(vms), vms)

                    if vms is None:
                        break

                    result = []
                    if "all" in arg.names:
                        if result is None:
                            result = []
                        else:
                            result = vms
                    elif arg.group is not None and len(arg.group) > 0:
                        for vm in vms:
                            if vm["group"] in arg.group:
                                result.append(vm)
                    elif arg.names is not None and len(arg.names) > 0:
                        for vm in vms:
                            if vm["name"] in arg.names:
                                result.append(vm)

                    if len(result) > 0:
                        # print(result)
                        (order, header) = CloudProvider(cloud).get_attributes("vm")
                        print(Printer.write(result,
                                            order=order,
                                            output=_format)
                              )
                    else:
                        Console.error("No data found with requested parameters.", traceflag=False)
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem listing all instances", traceflag=False)


        elif arguments["rename"]:
            try:
                oldnames = Parameter.expand(arguments["OLDNAMES"])
                newnames = Parameter.expand(arguments["NEWNAMES"])
                force = arguments["--force"]

                if oldnames is None or newnames is None:
                    Console.error("Wrong VMs specified for rename", traceflag=False)
                elif len(oldnames) != len(newnames):
                    Console.error("The number of VMs to be renamed is wrong",
                                  traceflat=False)
                else:
                    for i in range(0, len(oldnames)):
                        oldname = oldnames[i]
                        newname = newnames[i]
                        if arguments["--dryrun"]:
                            Console.ok("Rename {} to {}".format(oldname, newname))
                        else:
                            Vm.rename(cloud=cloud,
                                      oldname=oldname,
                                      newname=newname,
                                      force=force
                                      )
                    msg = "info. OK."
                    Console.ok(msg)
            except Exception as e:
                # Error.traceback(e)
                Console.error("Problem deleting instances", traceflag=False)

        return ""
예제 #37
0
    def __init__(self, context):
        cmd.Cmd.__init__(self)
        self.variables = {}
        self.command_topics = {}
        self.register_topics()
        self.context = context
        # TODO get loglevel from DB or yaml file, if not defined set to ERROR
        self.loglevel = "DEBUG"
        self._hist = []
        if self.context.debug:
            print("init CloudmeshConsole")

        self.prompt = 'cm> '
        self.doc_header = "Documented commands (type help <command>):"
        self.banner = textwrap.dedent("""
            +=======================================================+
            .   ____ _                 _                     _      .
            .  / ___| | ___  _   _  __| |_ __ ___   ___  ___| |__   .
            . | |   | |/ _ \| | | |/ _` | '_ ` _ \ / _ \/ __| '_ \  .
            . | |___| | (_) | |_| | (_| | | | | | |  __/\__ \ | | | .
            .  \____|_|\___/ \__,_|\__,_|_| |_| |_|\___||___/_| |_| .
            +=======================================================+
                                 Cloudmesh Shell
            """)
        # KeyCommands.__init__(self, context)

        #
        # set default cloud and default group if they do not exist
        # use the first cloud in cloudmesh.yaml as default
        #

        Console.set_debug(Default.debug)

        filename = path_expand("~/.cloudmesh/cloudmesh.yaml")
        # moved to import cloudmesh_client

        # create_cloudmesh_yaml(filename)

        setup_yaml()

        # Initialize Logging
        # LogUtil.initialize_logging()

        # sys,exit(1)

        # ##################
        # DEFAULTS
        #

        #
        # SET DEFAULT CLOUD
        #

        value = Default.get(name='cloud', category='general')

        if value is None:

            config = ConfigDict(filename=filename)["cloudmesh"]
            if 'active' in config:
                cloud = config["active"][0]
            else:
                clouds = config["clouds"]
                cloud = list(clouds.keys())[0]
            Default.set('cloud', cloud, category='general')

        #
        # NOT SURE WHAT THIS IS FOR
        #
        value = Default.get(name='default', category='general')
        if value is None:
            Default.set('default', 'default', category='general')

        #
        # SET DEFAULT CLUSTER
        #
        '''
        cluster = ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["active"][0]

        value = Default.get(name='cluster', category='general')
        if value is None:
            try:
                hosts = ssh_config().names()
                if hosts is not None:
                    cluster = hosts[0]
            except:
                pass  # use the hardcoded cluster

        else:
            cluster = value
        Default.set('cluster', cluster, category='general')
        '''

        #
        # SET DEFAULT GROUP
        #
        group = Default.group
        if group is None:
            Default.set_group("default")

        #
        # LOAD DEFAULTS FROM YAML
        #
        Default.load("cloudmesh.yaml")

        try:
            d = Key.get_from_dir("~/.ssh", store=False)
        except Exception as e:
            Console.error(e.message)

        #
        # SET DEFAULT TIMER
        #
        on = Default.timer

        #
        # SET DEFUALT SECGROUP
        #

        #
        # SET DEFAULT REFRESH
        #
        # r = Default.refresh
        # print ("REFRESH", r)
        # if r is None:
        #     Default.set_refresh("on")

        #
        # SET DEFAULT USER
        #
        user = Default.user
        if user is None:
            user = ConfigDict(
                filename=filename)["cloudmesh"]["profile"]["user"]
            Default.set_user(user)

        r = Default.secgroup

        if r is None:
            SecGroup.reset_defaults()
            '''
            #secgroup = "{}-default".format(Default.user)
            secgroup = "default"
            Default.set_secgroup(secgroup)
            SecGroup.add_rule_to_db(group=secgroup, name="ssh",from_port="22",to_port="22",protocol="tcp", cidr="0.0.0.0/0")
            SecGroup.add_rule_to_db(group=secgroup, name="http",from_port="80",to_port="80",protocol="tcp", cidr="0.0.0.0/0")
            SecGroup.add_rule_to_db(group=secgroup, name="https", from_port="443", to_port="443", protocol="tcp", cidr="0.0.0.0/0")
            SecGroup.add_rule_to_db(group=secgroup, name="ping", from_port="0", to_port="0", protocol="icmp", cidr="0.0.0.0/0")
            '''
        """
        try:
            sshm = SSHKeyManager()
            m = sshm.get_from_yaml(
                load_order="~/.cloudmesh/cloudmesh.yaml")
            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:
                    pass
        except Exception as e:
            Console.error("Problem adding keys from yaml file")
        """

        for c in CloudmeshConsole.__bases__[1:]:
            # noinspection PyArgumentList
            c.__init__(self, context)
예제 #38
0
    def do_cluster(self, args, arguments):
        """
        ::

          Usage:
              cluster list [--format=FORMAT]
              cluster list NAME
                           [--format=FORMAT]
                           [--column=COLUMN]
                           [--short]
              cluster create NAME
                             [--count=COUNT]
                             [--login=USERNAME]
                             [--cloud=CLOUD]
                             [--image=IMAGE]
                             [--flavor=FLAVOR]
                             [--add]
              cluster delete NAME
              cluster setup NAME [--username]
              cluster inventory NAME

          Description:
              with the help of the cluster command you can create a number
              of virtual machines that are integrated in a named virtual cluster.
              You will be able to login between the nodes of the virtual cluster
              while using public keys.

              cluster setup NAME
                sets up the keys between the cluster node as well as the machine that
                executes the cm command

              cluster inventory NAME
                creates an inventory.txt file to be used by ansible in the current directory

              cluster create NAME
                 creates the virtual machines used for the cluster

              cluster list NAME
                 lists selected details of the vms for the cluster

              cluster delete NAME
                  remove the cluster and its VMs

          Examples:
              cluster list
                  list the clusters

              cluster create NAME --count=COUNT --login=USERNAME [options...]
                  Start a cluster of VMs, and each of them can log into each other.
                  CAUTION: you should specify defaults before using this command:
                  1. select cloud to work on, e.g. cloud select kilo
                       default cloud=kilo
                  2. test if you can create a single VM on the cloud to see if
                     everything is set up
                  3. set the default key to start VMs, e.g. key default [USERNAME-key]
                  5. set image of VMs, e.g. default image
                  6. set flavor of VMs, e.g. default flavor
                  7. Make sure to use a new unused group name

          Arguments:
              NAME              cluster name or group name

          Options:
              --count=COUNT     give the number of VMs to add into the cluster
              --login=USERNAME  give a login name for the VMs, e.g. ubuntu
              --cloud=CLOUD     give a cloud to work on
              --flavor=FLAVOR   give the name of the flavor or flavor id
              --image=IMAGE     give the name of the image or image id
              --add             if a group exists and there are VMs in it
                                additional vms will be added to this cluster and the
                                keys will be added to each other so one can login between
                                them
              FORMAT            output format: table, json, csv
              COLUMN            customize what information to display, for example:
                                --column=status,addresses prints the columns status
                                and addresses
              --detail          for table print format, a brief version
                                is used as default, use this flag to print
                                detailed table

        """

        def get_vms(group_name):
            groups = Vm.get_vms_by_group(group_name)
            vms = []
            for group in groups:
                name = group["member"]
                print(name)
                vm = Vm.get_vm(name)
                vm['cluster'] = group_name
                vms.append(vm)
            return vms

        def _print(f):
                print (f)

        def write(filename, msg):
            with open(path_expand(filename), 'w') as f:
                output = f.write(msg)

        arg = dotdict(arguments)

        arg.format = arguments["--format"] or "table"
        arg.count = int(arguments["--count"] or 1)
        arg.username = arguments["--login"]
        arg.cloud = arguments["--cloud"] or Default.cloud
        arg.image = arguments["--image"] or Default.get(name="image", category=arg.cloud)
        arg.flavor = arguments["--flavor"] or Default.get(name="flavor", category=arg.cloud)
        arg.add = arguments["--add"]
        arg.group = arg.NAME
        arg.name = None
        arg.key = Default.key
        arg.secgroup = Default.secgroup
        arg.group = arg.NAME
        arg.short = arguments["--short"]

        if arg.create:

            boot_from_args(arg)

        elif arg.inventory:

            group = Vm.get_vms_by_group(arg.group)

            result = ""
            if arg.format is "table":
                result = "[servers]\n"

            for element in group:
                name = element["member"]
                vm = Vm.get_vm(name)[0]
                vm['cluster'] = arg.group
                result += "{floating_ip}\n".format(**vm)

            Console.ok("Writing ips to inventory.txt")
            print(result)

            write("inventory.txt", result)

            Console.ok(".ok")
            return ""


        elif arg.list and arg.NAME is not None:

            if arg.short:

                vms = Vm.get_vms_by_group(arg.group)

                if vms is None:
                    Console.error("no vms found for {}".format(arg.group))
                else:

                    print(Printer.list(vms,
                               header=['Group', 'Vm'],
                               order=['name', 'member'],
                               output=arg.format))

            else:

                groups = Vm.get_vms_by_group(arg.group)

                pprint(groups)

                vms = []
                for group in groups:
                    name = group["member"]
                    vm = Vm.get_vm(name)[0]
                    vm['cluster'] = arg.group
                    if vm is not None:
                        vms.append(vm)

                pprint(vms)


                if vms is None:
                    Console.error("no vms found for {}".format(arg.group))
                else:

                    print(Printer.list(vms,
                                   order=['name', 'cluster', 'flavor', 'image', 'status', 'user_id', 'floating_ip'],
                                   output=arg.format))
            return ""

        elif arg.setup:

            def push(from_path, vm):
                vm.ip = vm.floating_ip
                if vm.ip is not None:
                    if arg.verbose:
                        Console.info("Connecting to Instance at IP:" + format(vm.ip))

                    sshcommand = "scp"
                    sshcommand += " -o StrictHostKeyChecking=no"
                    sshcommand += " {:}".format(from_path)
                    sshcommand += " {username}@{ip}:.ssh/authorized_keys".format(**vm)

                    print(sshcommand)
                    os.system(sshcommand)
                else:
                    Console.error("No Public IPs found for the instance", traceflag=False)


            groups = Vm.get_vms_by_group(arg.group)

            pprint (groups)

            vms = []
            for group in groups:
                name = group["member"]
                vm = Vm.get_vm(name)[0]
                vm['cluster'] = arg.group
                if vm is not None:
                    vms.append(vm)

            pprint(vms)

            if vms is None:
                Console.error("no vms found for {}".format(arg.group))
            else:

                print(Printer.list(vms,
                           order=['name', 'cluster', 'flavor', 'image', 'status', 'user_id', 'floating_ip'],
                           output=arg.format))

                keys = ""
                for vm in vms:
                    vm = dotdict(vm)
                    cloud = vm.category

                    if vm.username is None:
                        vm.username = arguments["--username"] or Image.guess_username(arg.image)



                    chameleon = "chameleon" in ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["clouds"][cloud][
                        "cm_host"]


                    print ("C", chameleon)

                    if chameleon:
                        vm.username = "******"
                    elif vm.category == "azure":
                        vm.username = ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["clouds"]["azure"]["default"][
                        "username"]
                    else:
                        if vm.username is None:
                            Console.error("Could not guess the username of the vm", traceflag=False)
                            return


                    Vm.set_login_user(name=vm.name, cloud=vm.category, username=vm.username)
                    vm.ip = vm.floating_ip


                    def execute(commands):
                        if vm.ip is not None:
                            if arg.verbose:
                                Console.info("Connecting to Instance at IP:" + format(vm.ip))

                            sshcommand = "ssh"
                            if arg.key is not None:
                                sshcommand += " -i {:}".format(arg.key)
                            sshcommand += " -o StrictHostKeyChecking=no"
                            sshcommand += " {username}@{ip}".format(**vm)
                            sshcommand += " \'{:}\'".format(commands)

                            print(sshcommand)
                            os.system(sshcommand)
                        else:
                            Console.error("No Public IPs found for the instance", traceflag=False)

                    def copy(commands):
                        if vm.ip is not None:
                            if arg.verbose:
                                Console.info("Connecting to Instance at IP:" + format(vm.ip))

                            sshcommand = "scp"
                            sshcommand += " -o StrictHostKeyChecking=no"
                            sshcommand += " {username}@{ip}".format(**vm)
                            sshcommand += ":{:}".format(commands)

                            print(sshcommand)
                            os.system(sshcommand)
                        else:
                            Console.error("No Public IPs found for the instance", traceflag=False)


                    def cat(filename):
                        with open(path_expand(filename), 'r') as f:
                            output = f.read()
                        return output



                    execute('cat /dev/zero | ssh-keygen -q -N ""')
                    copy(".ssh/id_rsa.pub ~/.ssh/id_rsa_{name}.pub".format(**vm))

                    output = "~/.ssh/id_rsa_{name}.pub".format(**vm)

                    keys = keys + cat(output)

                print ("WRITE KEYS")
                keys = keys + cat("~/.ssh/id_rsa.pub")
                output = "~/.ssh/id_rsa_{group}.pub".format(**arg)
                write(output, keys)

                print("PUSH KEYS")
                for vm in vms:
                    vm = dotdict(vm)
                    push("~/.ssh/id_rsa_{group}.pub".format(**arg), vm)

        return ""
예제 #39
0
    def do_nova(self, args, arguments):
        """
        ::
        
            Usage:
                nova set CLOUD
                nova info [CLOUD] [--password]
                nova help
                nova [--group=GROUP] ARGUMENTS...

            A simple wrapper for the openstack nova command

            Arguments:
                GROUP           The group to add vms to
                ARGUMENTS       The arguments passed to nova
                help            Prints the nova manual
                set             reads the information from the current cloud
                                and updates the environment variables if
                                the cloud is an openstack cloud
                info            the environment values for OS

            Options:
                --group=GROUP   Add VM to GROUP group
                --password      Prints the password
                -v              verbose mode

        """
        # pprint(arguments)
        cloud = arguments['CLOUD'] or Default.get_cloud()
        if not cloud:
            Console.error("Default cloud not set!")
            return ""

        group = arguments["--group"] or Default.get("group", category=cloud)

        if not group:
            Console.error("Default group not set!")
            return ""

        if arguments["help"]:
            os.system("nova help")
            return ""
        elif arguments["info"]:
            set_os_environ(cloud)
            d = {}
            #
            # TODO: this naturally does not work as clouds will have
            # different parameters. ALos it does not unset previous
            # parameters from other clouds. See register
            #
            for attribute in ['OS_USERNAME',
                              'OS_TENANT_NAME',
                              'OS_AUTH_URL',
                              'OS_CACERT',
                              'OS_PASSWORD',
                              'OS_REGION']:
                try:
                    d[attribute] = os.environ[attribute]
                except:
                    Console.warning("OS environment variable {:} not found"
                                    .format(attribute))
                    d[attribute] = None
                if not arguments["--password"]:
                    d['OS_PASSWORD'] = "******"
            print(row_table(d, order=None, labels=["Variable", "Value"]))
            msg = "info. OK."
            Console.ok(msg)
            return ""
        elif arguments["set"]:
            if cloud:

                set_os_environ(cloud)

                msg = "{0} is set".format(cloud)
                Console.ok(msg)
            else:
                Console.error("CLOUD is required")

        else:  # nova ARGUMENTS...
            print("Cloud = {0}".format(cloud))
            try:
                set_os_environ(cloud)
                args = arguments["ARGUMENTS"]

                # arguments may contain multiple optional arguments
                if len(args) == 1:
                    args = args[0].split()

                result = Shell.execute("nova", args)

                print(Nova.remove_subjectAltName_warning(result))

                """
                If request for nova boot,
                add the vm to group specified,
                or else add to default group
                """
                if "boot" in args:
                    # Logic to find ID of VM in the result
                    fields = []
                    for field in result.split("|"):
                        fields.append(field.strip())
                    index = fields.index('id') + 1
                    vm_id = fields[index]

                    # Add to group
                    Group.add(name=group, type="vm", id=vm_id, category=cloud)
            except Exception as ex:
                Console.error("Error executing Nova command: {}".format(ex))
            return ""