def test_cms_info_cloud(self):
     HEADING()
     cmd = "cms info"
     result = Shell.run(cmd)
     print(result)
     assert "cloudmesh.cloud" in result
def run(label, command):
    result = Shell.run_timed(label, command, service=cloud)
    print(result)
    return result
Пример #3
0
 def az(self, command):
     print(command)
     r = Shell.execute(command, shell=True)
     data = json.loads(r)
     return data
Пример #4
0
from cloudmesh.common.Shell import Shell

result = Shell.execute('pwd')  # Printing working directory
print("result: ", result)

result1 = Shell.execute('ls', ["-l"])
print("result1: ", result1)

result2 = Shell.ls("-a", "-u", "-x")  # build in functions of Shell
print("result2: ", result2)
Пример #5
0
def run(command):
    parameter = command.split(" ")
    shell_command = parameter[0]
    args = parameter[1:]
    result = Shell.execute(shell_command, args)
    return str(result)
Пример #6
0
    def info(self, name=None):
        """
        gets the information of a node with a given name

        :param name:
        :return: The dict representing the node including updated status
        """

        arg = dotdict()
        arg.name = name

        config = Config()

        cloud = "vagrant"  # TODO: must come through parameter or set cloud
        arg.path = config.data["cloudmesh"]["cloud"][cloud]["default"]["path"]
        arg.directory = os.path.expanduser("{path}/{name}".format(**arg))

        data = {
            "cm": {
                "name": name,
                "directory": arg.directory,
                "path": arg.path,
                "cloud": cloud,
                "status": "unkown"
            }
        }
        result = None

        result = Shell.execute("vagrant", ["ssh-config"],
                               cwd=arg.directory,
                               traceflag=False,
                               witherror=False)

        if result is None:
            data_vagrant = None
            data["cm"]["status"] = "poweroff"
        else:
            print(result)
            lines = result.split("\n")
            data_vagrant = {}
            for line in lines:
                attribute, value = line.strip().split(" ", 1)
                if attribute == "IdentityFile":
                    value = value.replace('"', '')

                data_vagrant[attribute] = value

        vms = Shell.execute('VBoxManage', ["list", "vms"]).split("\n")
        #
        # find vm
        #
        vbox_name_prefix = "{name}_{name}_".format(**arg)
        # print (vbox_name_prefix)
        details = None
        for vm in vms:
            vm = vm.replace("\"", "")
            vname = vm.split(" {")[0]
            if vname.startswith(vbox_name_prefix):
                details = Shell.execute(
                    "VBoxManage", ["showvminfo", "--machinereadable", vname])
                # print (details)
                break
        vbox_dict = self._convert_assignment_to_dict(details)

        # combined = {**data, **details}
        # data = combined
        if data_vagrant is not None:
            data["vagrant"] = data_vagrant
        data["vbox"] = vbox_dict
        if "VMState" in vbox_dict:
            data["cm"]["status"] = vbox_dict["VMState"]

        return data
Пример #7
0
    def do_vbox(self, args, arguments):
        """
        ::

          Usage:
            vbox version [--format=FORMAT]
            vbox image list [--format=FORMAT]
            vbox image find KEYWORDS...
            vbox image add NAME
            vbox image delete NAME
            vbox vm info NAME
            vbox vm list [--format=FORMAT] [-v]
            vbox vm delete NAME
            vbox vm ip [NAME] [--all]
            vbox vm create [NAME] ([--memory=MEMORY] [--image=IMAGE] [--port=PORT] [--script=SCRIPT]  | list)
            vbox vm boot [NAME] ([--memory=MEMORY] [--image=IMAGE] [--port=PORT] [--script=SCRIPT] | list)
            vbox vm ssh [NAME] [-e COMMAND]
        """

        arguments.format = arguments["--format"] or "table"
        arguments.verbose = arguments["-v"]
        arguments.all = arguments["--all"]

        #
        # ok
        #
        def list_images():
            images = VboxProvider().list_images()
            _LIST_PRINT(images,
                        arguments.format,
                        order=["name", "provider", "date"])

        #
        # ok
        #
        # noinspection PyShadowingNames
        def image_command(func):
            try:
                images = func(arguments.NAME)
                print(images)
                list_images()
            except Exception as e:
                print(e)
            return ""

        #
        # ok
        #
        if arguments.version:
            versions = {
                "cm": {
                    "attribute": "cm",
                    "description": "Cloudmesh vbox Version",
                    "version": __version__
                },
                "vbox": {
                    "attribute": "vbox",
                    "description": "Vagrant Version",
                    "version": "TBD"  # cloudmesh.vbox.api.version(),
                }
            }
            result = Printer.write(
                versions,
                order=["attribute", "version", "description"],
                output=arguments.format)
            print(result)

        #
        # ok
        #
        elif arguments.image and arguments.list:
            list_images()
        #
        # ok
        #
        elif arguments.image and arguments.delete:
            image_command(VboxProvider().delete_image)
        #
        # ok
        #
        elif arguments.image and arguments.put:
            image_command(VboxProvider().add_image)

        #
        # ok
        #
        elif arguments.image and arguments.find:
            VboxProvider().find_image(arguments.KEYWORDS)
            return ""

        #
        # ok, but only vagrant details
        #
        elif arguments.vm and arguments.list:

            provider = VboxProvider().nodes()
            _LIST_PRINT(provider,
                        arguments.format,
                        order=["name", "state", "id", "provider", "directory"])
            return ""

        #
        # unclear: this function is unclear
        #
        elif arguments.create and arguments.list:

            result = Shell.cat("{NAME}/Vagrantfile".format(**arguments))
            if result is not None:
                print(result)
            return ""

        elif arguments.create:

            d = defaults()

            print("LLLL", d)

            arguments.memory = arguments["--memory"] or d.memory
            arguments.image = arguments["--image"] or d.image
            arguments.script = arguments["--script"] or d.script
            arguments.port = arguments["--port"] or d.port

            server = VboxProvider()
            server.create(**arguments)

        elif arguments.info:

            # arguments.NAME
            d = VboxProvider().info(name=arguments.NAME)

            result = Printer.write(d, output=arguments.format)

            print(result)

        elif arguments.ip:

            data = []
            result = VboxProvider().execute(arguments.NAME, "ifconfig")
            if result is not None:
                lines = result.splitlines()[:-1]
                for line in lines:
                    if "inet addr" in line:
                        line = line.replace("inet addr", "ip")
                        line = ' '.join(line.split())
                        _adresses = line.split(" ")
                        address = {}
                        for element in _adresses:
                            attribute, value = element.split(":")
                            address[attribute] = value
                        data.append(address)
            if arguments.all:
                d = {}
                i = 0
                for e in data:
                    d[str(i)] = e
                    i = i + 1
                result = Printer.attribute(d, output=arguments.format)
                print(result)
            else:
                for element in data:
                    ip = element['ip']
                    if ip == "127.0.0.1" or ip.startswith("10."):
                        pass
                    else:
                        print(element['ip'])

        elif arguments.boot:

            d = defaults()

            arguments.memory = arguments["--memory"] or d.memory
            arguments.image = arguments["--image"] or d.image
            arguments.script = arguments["--script"] or d.script
            arguments.port = arguments["--port"] or d.port

            node = VboxProvider().boot(name=arguments.NAME,
                                       memory=arguments.memory,
                                       image=arguments.image,
                                       script=arguments.script,
                                       port=arguments.port)

        elif arguments.delete:

            result = VboxProvider().delete(name=arguments.NAME)
            print(result)

        elif arguments.ssh:

            if arguments.COMMAND is None:
                os.system("cd {NAME}; vbox ssh {NAME}".format(**arguments))
            else:
                result = VboxProvider().execute(arguments.NAME,
                                                arguments.COMMAND)
                if result is not None:
                    lines = result.splitlines()[:-1]
                    for line in lines:
                        print(line)

        else:

            print("use help")

        result = ""
        return result
Пример #8
0
    def do_init(self, args, arguments):
        """
        ::

            Usage:
                init [CLOUD] [--debug]
                init yaml

            Description:

                Initializes cloudmesh while using data from
                ~/.cloudmesh/cloudmesh.yaml.

                If no cloud is specified a number of local collections are
                created. If a cloud is specified it also uploads the
                information about images, flavors, vms. It also uploads the
                security groups defined by default to the cloud.

            Bug:

                cms init
                cms init

                    On Windows you have to run the cms init command twice upon
                    first installation
        """

        if arguments.CLOUD == "yaml":

            config = Config()

            location = path_expand("~/.cloudmesh/cloudmesh.yaml")
            path = Path(location)
            if path.is_file():
                print()
                if yn_choice(
                    "The file ~/.cloudmesh/cloudmesh.yaml exists, do you wnat to overwrite it",
                    default='n'):
                    config.fetch()
                    print()
                    Console.ok("File cloudmesh.yaml downloaded from Github")
                else:
                    print()
                    Console.warning("Download canceled")
                print()

        else:
            variables = Variables()
            config = Config()
            try:
                print("MongoDB stop")
                MongoDBController().stop()
            except:
                Console.ok("MongoDB is not running. ok")
            machine = platform.lower()
            location = path_expand(config[
                                       f'cloudmesh.data.mongo.MONGO_DOWNLOAD.{machine}.MONGO_PATH'])
            try:
                shutil.rmtree(location)
                print("MongoDB folder deleted")
            except:
                Console.error(f"Could not delete {location}")
                if platform == 'win32':
                    Console.error(f"Please try to run cms init again ... ")
                    exit(1)

            config = Config()
            user = config["cloudmesh.profile.user"]

            secgroup = "flask"

            print("Set key")
            if user == "TBD":
                Console.error(
                    "the user is not set in the yaml file for cloudmesh.profile.user")
                sys.exit()

            variables["key"] = user

            Console.ok("Config Security Initialization")
            Shell.execute("cms", ["config", "secinit"])

            print("MongoDB create")
            os.system("cms admin mongo create")
            os.system("cms admin mongo start")
            os.system("cms sec load")

            if arguments.CLOUD is not None:
                cloud = arguments.CLOUD

                variables['cloud'] = cloud
                os.system(f"cms key upload {user} --cloud={cloud}")
                os.system(f"cms flavor list --refresh")
                os.system(f"cms image list --refresh")
                os.system(f"cms vm list --refresh")
                os.system(f"cms sec group load {secgroup} --cloud={cloud}")
                os.system(f"cms set secgroup={secgroup}")

            if arguments.debug:
                variables['debug'] = True
                variables['timer'] = 'on'
                variables['trace'] = True
                variables['verbose'] = '10'

            print()
            print("Variables")
            print()
            for name in variables:
                value = variables[name]
                print(f"    {name}={value}")
Пример #9
0
 def _execute_src_dest(self, cmd, src, dest=None):
     if dest is None:
         return Shell.execute('ampy', ['--port', self.port, cmd, src])
     else:
         return Shell.execute('ampy', ['--port', self.port, cmd, src, dest])
# fa19-516-163 E.Cloudmesh.Common.3

# Cloudmesh imports
from cloudmesh.common.Shell import Shell
from cloudmesh.common.util import banner

# Ping a host
banner("Ping API: itpeople-api.apps.iu.edu")
ping = Shell.ping("itpeople-api.apps.iu.edu")

# Print the result
banner("Ping result")
print(ping)

from cloudmesh.common.Shell import Shell
from pprint import pprint

print("Starting debug")
result = Shell.execute("cms", ["storage", "--storage=local", "list", "a"])

pprint(result)
Пример #12
0
    def check(self, path=None):
        # bug: path not needed

        error = False
        # path = path_expand(path or self.location.config())

        path = path_expand(path or self.location.config())

        #
        # bug path not passed along ;-) we can just remove it
        #
        config = Config()

        banner("Check for CLOUDMESH_CONFIG_DIR")

        if os.path.isfile(path):
            print("Config found in:", path)
        if "CLOUDMESH_CONFIG_DIR" in os.environ:
            directory = os.environ("CLOUDMESH_CONFIG_DIR")
            print("CLOUDMESH_CONFIG_DIR={directory}")
            config_path = str(Path(directory) / "cloudmesh.yaml")
            if os.path.isfile(path):
                print("Config found in:", path)
            else:
                Console.error(f"File {config_path} not found.")
            if path != config_path:
                Console.warning("You may have two cloudmesh.yaml file.")
                Console.warning("We use: {config_path is use}")

        banner("Check Version")

        dist_version = config.version()
        yaml_version = config["cloudmesh.version"]

        if dist_version == yaml_version:
            Console.ok(f"The version is {dist_version}")
        else:
            Console.error("Your version do not match")
            print()
            print("Found ~/.cloudmesh/cloudmesh.yaml:", yaml_version)
            print("Please update to version         :", dist_version)
            print("")
            print("See also: ")
            print()
            print(
                "  https://github.com/cloudmesh/cloudmesh-configuration/blob/master/cloudmesh/configuration/etc/cloudmesh.yaml"
            )

        banner("Check for TAB Characters")

        error = Config.check_for_tabs(path)

        if not error:
            Console.ok("OK. No TABs found")

        banner("yamllint")

        try:
            import yamllint

            options = \
                '-f colored ' \
                '-d "{extends: relaxed, ""rules: {line-length: {max: 256}}}"'
            r = Shell.live('yamllint {options} {path}'.format(**locals()))

            if 'error' in r or 'warning' in r:
                print(70 * '-')
                print(" line:column  description")
                print()
            else:
                Console.ok("OK. No issues found")
                print()
        except:
            Console.error("Could not execute yamllint. Please add with")
            Console.error("pip install yamllint")
Пример #13
0
    def do_host(self, args, arguments):
        """
        ::

          Usage:
              host scp NAMES SOURCE DESTINATION [--dryrun]
              host ssh NAMES COMMAND [--dryrun] [--output=FORMAT]
              host config NAMES --ips=IPS [--user=USER] [--key=PUBLIC]
              host config --proxy=PROXY NAMES [--user=USER] [--append] [--local=no] [--StrictHostKeyChecking=no] [--cluster=name]
              host config NAMES [--user=USER] [--append] [--local=no] [--StrictHostKeyChecking=no] [--cluster=name]
              host find [NAMES] [--user=USER] [--table|--json] [--verbose]
              host check NAMES [--user=USER] [--key=PUBLIC]
              host key create NAMES [--user=USER] [--dryrun] [--output=FORMAT]
              host key list NAMES [--output=FORMAT]
              host key setup NAMES
              host key gather NAMES [--authorized_keys] [FILE]
              host key scatter NAMES [FILE] [--user=USER]
              host key add NAMES [FILE]
              host key delete NAMES [FILE]
              host key access NAMES [FILE] [--user=USER]
              host tunnel create NAMES [--port=PORT]
              host mac NAMES [--eth] [--wlan] [--output=FORMAT]
              host setup WORKERS [LAPTOP]
              host shutdown NAMES
              host reboot NAMES
              host adduser NAMES USER
              host passwd NAMES USER
              host addsudo NAMES USER
              host deluser NAMES USER
              host ping NAMES
              host info NAMES


          This command does some useful things.

          Arguments:
              FILE   a file name

          Options:
              --dryrun         shows what would be done but does not execute
              --output=FORMAT  the format of the output
              --port=PORT      starting local port for tunnel assignment
              --local=no       do not append .local to manager hostname [default: yes]
              --user=USER      username for manager and workers [default: pi]
              --ips=IPS        ip addresses of the manager and workers
              --StrictHostKeyChecking=no  if set to yes, strict host checking is enforced [default: no]
              --ProxyJump=no  if set to yes, a proxyjump is performed for each worker through the manager [default: yes]

          Description:

              host scp NAMES SOURCE DESTINATION

                Uses scp to transfer Source to NAMES:DESTINATION.

              host ssh NAMES COMMAND

                runs the command on all specified hosts
                Example:
                     ssh red[01-10] \"uname -a\"

              host key create NAMES
                create a ~/.ssh/id_rsa and id_rsa.pub on all hosts specified
                Example:
                    ssh key create "red[01-10]"

              host key list NAMES

                list all id_rsa.pub keys from all hosts specifed
                 Example:
                     ssh key list red[01-10]

              host key gather HOSTS FILE

                gathers all keys from file FILE including the one from localhost.

                    ssh key gather "red[01-10]" keys.txt

              host key scatter HOSTS FILE [--user=USER]

                copies all keys from file FILE to authorized_keys on all hosts,
                but also makes sure that the users ~/.ssh/id_rsa.pub key is in
                the file. If provided the optional user, it will add the keys to
                that user's .ssh directory. This is often required when
                adding a new user in which case HOSTS should still a sudo
                user with ssh currently enabled.

                1) adds ~/.id_rsa.pub to the FILE only if its not already in it
                2) removes all duplicated keys

                Example:
                    ssh key scatter "red[01-10]"
                    ssh key scatter pi@red[01-10] keys.txt --user=alice

              host key add NAMES FILE

                Adds all keys in FILE into the authorized_keys of NAMES.

                Example:
                    cms host key add worker001 ~/.ssh/id_rsa.pub

              host key delete NAMES FILE

                Deletes all keys in fILE from authorized_keys of NAMES if they exist.

                Example
                    cms host key delete worker001 ~/.ssh/id_rsa.pub

              host key scp NAMES FILE

                copies all keys from file FILE to authorized_keys on all hosts
                but also makes sure that the users ~/.ssh/id_rsa.pub key is in
                the file and removes duplicates, e.g. it calls fix before upload

                Example:
                    ssh key list red[01-10] > pubkeys.txt
                    ssh key scp red[01-10] pubkeys.txt

              host config NAMES IPS [--user=USER] [--key=PUBLIC]

                generates an ssh config file tempalte that can be added to your
                .ssh/config file

                Example:
                    cms host config "red,red[01-03]" "198.168.1.[1-4]" --user=pi

              host check NAMES [--user=USER] [--key=PUBLIC]

                This command is used to test if you can login to the specified
                hosts. It executes the hostname command and compares it.
                It provides a table  with a sucess column

                cms host check "red,red[01-03]"

                    +-------+---------+--------+
                    | host  | success | stdout |
                    +-------+---------+--------+
                    | red   | True    | red    |
                    | red01 | True    | red01  |
                    | red02 | True    | red02  |
                    | red03 | True    | red03  |
                    +-------+---------+--------+

              host tunnel create NAMES [--port=PORT]

                This command is used to create a persistent local port
                forward on the host to permit ssh tunnelling from the wlan to
                the physical network (eth). This registers an autossh service in
                systemd with the defualt port starting at 8001.

                Example:
                    cms host tunnel create red00[1-3]

              host mac NAMES

                returns the list of mac addresses of the named pis.

              host setup WORKERS [LAPTOP]

                Executes the following steps

                    cms bridge create --interface='wlan0'
                    cms host key create red00[1-3]
                    cms host key gather red00[1-3],[email protected] keys.txt
                    cms host key scatter red00[1-3],localhost keys.txt
                    rm keys.txt
                    cms host tunnel create red00[1-3]

              host shutdown NAMES

                Shutsdown NAMES with `sudo shutdown -h now`. If localhost in
                names, it is shutdown last.

              host reboot NAMES

                Reboots NAMES with `sudo reboot`. If localhost in names,
                it is rebooted last.

              host adduser NAMES USER

                Adds a user with user name USER to the hosts identified by
                NAMES. Password is disabled, see host passwd to enable.

              host addsudo NAMES USER

                Adds sudo rights to USER at NAMES

              host passwd NAMES USER

                Changes the password for USER at NAMES

              host deluser NAMES USER

                Deleted USER from NAMES. Home directory will be removed.

              host config proxy PROXY NAMES

                This adds to your ~/.ssh/config file a ProxyJump
                configuration to reach NAMES via PROXY. This is useful when
                the PROXY is acting as a network bridge for NAMES to your
                current device.

                Example:
                    cms host config proxy [email protected] red00[1-2]
        """
        def _print(results):
            arguments.output = arguments.output or 'table'

            if arguments.output in ['table', 'yaml']:
                print(
                    Printer.write(
                        results,
                        order=['host', 'success', 'stdout', 'stderr'],
                        output=arguments.output))
            else:
                pprint(results)

        def _print_pis(results):
            arguments.output = arguments.output or 'table'

            if arguments.output in ['table', 'yaml']:
                print(
                    Printer.write(results,
                                  order=[
                                      'name', 'ip', 'user', 'os', 'mac',
                                      'model', 'memory', 'serial', ".local"
                                  ],
                                  output=arguments.output))
                # not printed         "revision"
                # not printed         "hardware"
            else:
                pprint(results)

        def get_filename(filename, hosts):
            if filename is not None:
                return filename
            if type(hosts) == str:
                hosts = Parameter.expand(hosts)
            label = hosts[0]
            return path_expand(f"~/.ssh/cluster_keys_{label}")

        map_parameters(arguments, 'eth', 'wlan'
                       'dryrun', 'output', 'user', 'port', 'append',
                       'StrictHostKeyChecking', 'local', 'proxy', 'ips',
                       'cluster')
        dryrun = arguments.dryrun

        # VERBOSE(arguments)

        if dryrun:
            VERBOSE(arguments)

        if arguments.info:

            names = Parameter.expand(arguments.names)

            # check if .local
            # check if mesh network
            # check if static network

            # use arp - a di find hosts ips
            # if linux
            #    dig +short -x  192.168.50.1

            Console.error("Not yet Implemented")

        elif arguments.find:

            verbose = arguments["--verbose"]

            names = Parameter.expand(arguments.NAMES)

            # temporary so we can easy modify while not needing to update cloudmesh.common
            from cloudmesh.host.network import PiNetwork

            network = PiNetwork()

            pis = network.find_pis(user=arguments.user, verbose=verbose)
            if arguments["--json"]:
                print(pis)
            else:
                _print_pis(pis)

        elif arguments.mac:

            names = Parameter.expand(arguments.NAMES)

            if not arguments.eth and not arguments.wlan:
                arguments.eth = True
                arguments.wlan = True

            eth = 'cat /sys/class/net/eth0/address'
            wlan = 'cat /sys/class/net/wlan0/address'
            if arguments.eth:
                results = Host.ssh(hosts=names,
                                   command=eth,
                                   username=arguments.user)
                print("eth0:")
                _print(results)

            if arguments.wlan:

                results = Host.ssh(hosts=names,
                                   command=wlan,
                                   username=arguments.user)
                print("wlan0:")
                _print(results)

        elif arguments.setup:

            HostCreate.setup(workers=arguments.WORKERS,
                             laptop=arguments.LAPTOP)

        elif arguments.scp and not arguments.key:

            result = Host.put(hosts=arguments.NAMES,
                              source=arguments.SOURCE,
                              destination=arguments.DESTINATION)

            _print(result)

        elif arguments.ping:
            names = Parameter.expand(arguments.NAMES)

            # print (names)

            results = Host.ping(hosts=names)

            _print(results)

        elif arguments.ssh:
            names = Parameter.expand(arguments.NAMES)

            # print (names)

            results = Host.ssh(hosts=names, command=arguments.COMMAND)
            _print(results)

        elif arguments.key and arguments.create:

            results = Host.ssh_keygen(hosts=arguments.NAMES,
                                      username=arguments.user,
                                      dryrun=dryrun)

            _print(results)

        elif arguments.key and arguments.list:

            names = Parameter.expand(arguments.NAMES)

            results = Host.ssh(hosts=names,
                               command='cat .ssh/id_rsa.pub',
                               username=arguments.user)

            _print(results)

        elif arguments.key and arguments.add:
            filename = get_filename(arguments.NAMES)
            if not os.path.isfile(filename):
                Console.error(f"Cannot find file {filename}")
                return

            # Copy to temp location
            Host.put(hosts=arguments.NAMES,
                     source=filename,
                     destination="~/.ssh/key.tmp")
            # Execute append command and remove command
            command = 'cat ~/.ssh/key.tmp >> ~/.ssh/authorized_keys && rm ~/.ssh/key.tmp'
            Host.ssh(hosts=arguments.NAMES, command=command)

        elif arguments.key and arguments.delete:
            Console.ok("key delete")
            filename = get_filename(arguments.FILE, arguments.NAMES)
            if not os.path.isfile(filename):
                Console.error(f"Cannot find file {filename}")
                return
            # Copy to temp location
            remote_temp = "~/.ssh/key.tmp"
            Host.put(hosts=arguments.NAMES,
                     source=filename,
                     destination=remote_temp)
            # grep can read multiple patterns from a file, one per line. Combine with
            # the options -v to output non-matching lines, and -F to match strings
            # instead of regex and -x to require that the whole line matches.
            command = f"""grep -Fvx -f {remote_temp} ~/.ssh/authorized_keys >remaining_keys && \
            mv remaining_keys ~/.ssh/authorized_keys && \
            rm {remote_temp}"""
            Host.ssh(hosts=arguments.NAMES, command=command)
            Console.ok(f"Delete keys from {filename} on {arguments.NAMES}")

        elif arguments.key and arguments.setup:

            label = Parameter.expand(arguments.NAMES)[0]
            filename = get_filename(arguments.FILE, arguments.NAMES)
            directory = os.path.dirname(filename)

            if directory:
                Shell.mkdir(directory)

            output = Host.gather_keys(username=arguments.user,
                                      hosts=arguments.NAMES,
                                      filename="~/.ssh/id_rsa.pub",
                                      key="~/.ssh/id_rsa",
                                      processors=3,
                                      dryrun=False)

            with open(filename, "w") as f:
                f.write(output)

            # scatter
            # place .ssh/config a trict host check to no

        elif arguments.key and arguments.gather:

            output = Host.gather_keys(username=arguments.user,
                                      hosts=arguments.NAMES,
                                      filename="~/.ssh/id_rsa.pub",
                                      key="~/.ssh/id_rsa",
                                      processors=3,
                                      dryrun=False)

            VERBOSE(arguments)

            filename = get_filename(arguments.FILE, arguments.NAMES)

            print(output)

            banner(f"Writing Keys to file {filename}")

            directory = os.path.dirname(filename)
            print('command directory', directory)
            if directory:
                Shell.mkdir(directory)

            if os.path.isfile(filename) and yn_choice(
                    f'{filename} is not empty. Do you wish to overwrite it? (If no you will append).'
            ):
                with open(filename, "w") as f:
                    f.write(output)
            else:
                with open(filename, "a") as f:
                    f.write(output)

        elif arguments.key and arguments.scatter:

            #
            # this should be a function in Host
            #

            filename = get_filename(arguments.FILE, arguments.NAMES)

            names = arguments.NAMES
            user = arguments.user

            if not os.path.isfile(filename):
                Console.error("The file does not exist")
                return ""

            if not user:
                result = Host.put(hosts=names,
                                  source=filename,
                                  destination=".ssh/authorized_keys")

                _print(result)
            else:
                Console.info('SCP to ./temp_authorzied_keys_temp')
                result = Host.put(hosts=names,
                                  source=filename,
                                  destination="temp_authorized_keys_temp")
                _print(result)

                Console.info(f'Mkdir /home/{user}/.ssh if not exist')
                command = f'sudo mkdir -p /home/' \
                          f'{user}/.ssh/'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

                Console.info(f'Chown /home/{user}/.ssh to {user}')
                command = f'sudo chown {user}:{user} /home/' \
                          f'{user}/.ssh/'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

                Console.info(f'Chmod /home/{user}/.ssh to 700')
                command = f'sudo chmod 700 /home/' \
                          f'{user}/.ssh/'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

                Console.info(f'Mv temp_authorized_keys_temp to /home/'
                             f'{user}/.ssh/authorized_keys')
                command = f'sudo mv temp_authorized_keys_temp /home/' \
                          f'{user}/.ssh/authorized_keys'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

                Console.info(f'Chown /home/{user}/.ssh/authorized_keys to '
                             f'{user}')
                command = f'sudo chown {user}:{user} /home/' \
                          f'{user}/.ssh/authorized_keys'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

        elif arguments.key and arguments.access:

            #
            # this should be a function in Host
            #

            names = arguments.NAMES
            user = arguments.user

            filename = arguments.FILE
            temp = path_expand("~/.cloudmesh/temp_config")

            if filename:
                config = readfile(filename)
            else:
                config = textwrap.dedent("""
                Host *
                    StrictHostKeyChecking no
                """).strip()
            writefile(temp, config)

            if not os.path.isfile(temp):
                Console.error("The file does not exist")
                return ""

            if not user:
                result = Host.put(hosts=names,
                                  source=temp,
                                  destination=".ssh/config")

                _print(result)
            else:
                Console.info(f'Mkdir /home/{user}/.ssh if not exist')
                command = f'sudo mkdir -p /home/' \
                          f'{user}/.ssh/'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

                Console.info('SCP to ./temp_config')
                result = Host.put(hosts=names,
                                  source=temp,
                                  destination=".ssh/config")
                _print(result)

                Console.info(f'Chown /home/{user}/.ssh to {user}')
                command = f'sudo chown {user}:{user} /home/' \
                          f'{user}/.ssh/'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

                Console.info(f'Chmod /home/{user}/.ssh to 700')
                command = f'sudo chmod 700 /home/' \
                          f'{user}/.ssh/'
                result = Host.ssh(hosts=names, command=command)
                _print(result)

        elif arguments.config and arguments.ips:

            print("NNNNNNNN")

            key = arguments.key or "~/.ssh/id_rsa.pub"
            result = Host.config(hosts=arguments.NAMES,
                                 ips=arguments.IPS,
                                 username=arguments.user,
                                 key=key)
            print(result)
            """
            host config NAMES --ips=IPS [--user=USER] [--key=PUBLIC]
            host config --proxy=PROXY NAMES [--user=USER] [--append] [--local=no] [--StrictHostKeyChecking=no]
            host config NAMES [--user=USER] [--append] [--local=no] [--StrictHostKeyChecking=no]
            """

        elif arguments.config:

            if str_bool(arguments.local):
                local_str = ".local"
            else:
                local_str = ""

            if str_bool(arguments.StrictHostKeyChecking):
                strict_host_str = "yes"
            else:
                strict_host_str = "no"

            names = Parameter.expand(arguments.NAMES)
            user = arguments.user
            if arguments.cluster:
                cluster = arguments.cluster
            else:
                # take the first name and remove spaces
                cluster = ''.join([i for i in names[0] if not i.isdigit()])

            ssh_config_output = ""
            ssh_config_output = f'\n##### CLOUDMESH PROXY CONFIG {cluster} #####\n\n'

            if arguments.proxy:
                proxy_host = arguments.proxy
                proxy_jump = f'     ProxyJump {proxy_host}\n'
                ssh_config_output += \
                                    f'Host {proxy_host}\n' \
                                    f'     HostName {proxy_host}{local_str}\n' \
                                    f'     User {user}\n' \
                                    f'     PreferredAuthentications publickey\n' + \
                                    f'     StrictHostKeyChecking {strict_host_str}\n'
                ssh_config_output += '\n'

            else:
                proxy_jump = ""
            """
            ssh_config_output = f'\n##### CLOUDMESH PROXY CONFIG {cluster} #####\n\n'\
                                f'Host {proxy_host}\n' \
                                f'     HostName {proxy_host}{local_str}\n' \
                                f'     User {user}\n' \
                                f'     StrictHostKeyChecking {strict_host_str}\n\n'
            """

            ### the local_str in the hostname may be wrong since its not manager
            for name in names:
                ssh_config_template = f'Host {name}\n' \
                                      f'     HostName {name}{local_str}\n' \
                                      f'     User {user}\n' \
                                      f'     PreferredAuthentications publickey\n' + \
                                      f'     StrictHostKeyChecking {strict_host_str}\n' + \
                                      proxy_jump

                ssh_config_template += '\n'

                ssh_config_output += ssh_config_template

            ssh_config_output += f'##### CLOUDMESH PROXY CONFIG {cluster} #####\n'

            print('Adding to ~/.ssh/config')
            print(ssh_config_output)

            if not os.path.exists(path_expand('~/.ssh/config')):
                with open(path_expand('~/.ssh/config'), 'w+') as f:
                    f.write(ssh_config_output)
            else:
                f = open(path_expand('~/.ssh/config'), 'r')
                lines = f.readlines()
                f.close()
                with open(path_expand('~/.ssh/config'), 'w+') as f:
                    if f'##### CLOUDMESH PROXY CONFIG {cluster} #####\n' in lines:
                        start = lines.index(
                            f'##### CLOUDMESH PROXY CONFIG {cluster} #####\n')
                        lines.reverse()
                        end = lines.index(
                            f'##### CLOUDMESH PROXY CONFIG {cluster} #####\n')
                        end = len(lines) - end - 1
                        lines.reverse()
                        original_config = lines[start:end + 1]
                        del lines[start:end + 1]
                        f.writelines(lines)
                        if arguments.append:
                            f.writelines(original_config)
                            f.write(ssh_config_output)
                        else:
                            f.write(ssh_config_output)
                    else:
                        f.writelines(lines)
                        f.write(ssh_config_output)
                        f.close()

        elif arguments.check:

            key = arguments.key or "~/.ssh/id_rsa.pub"
            result = Host.check(hosts=arguments.NAMES,
                                username=arguments.user,
                                key=key)
            for entry in result:
                entry['success'] = entry['stdout'] == entry['host']

            _print(result)

        elif arguments.tunnel and arguments.create:

            wlan_ip = Shell.run("hostname -I | awk '{print $2}'").strip()
            print(f'\nUsing wlan0 IP = {wlan_ip}')
            hostname = Shell.run("hostname").strip()
            print(f'Using cluster hostname = {hostname}')

            names = Parameter.expand(arguments.NAMES)
            port = arguments.port or "8001"
            ssh_config_output = f'Host {hostname}\n' \
                                f'     HostName {hostname}.local\n' \
                                f'     User pi\n\n'

            for name in names:
                service_name = f"autossh-{name}.service"

                service_template = "[Unit]\n" \
                                   f"Description=AutoSSH tunnel service to {name} on local port " \
                                   f"{port}\n" \
                                   "After=multi-user.target\n\n" \
                                   "[Service]\n" \
                                   "User=pi\n" \
                                   "Group=pi\n" \
                                   'Environment="AUTOSSH_GATETIME=0"\n' \
                                   'ExecStart=/usr/bin/autossh -M 0 -o "ServerAliveInterval 30" ' \
                                   '-o "ServerAliveCountMax 3" -i ' \
                                   '/home/pi/.ssh/id_rsa -NL ' \
                                   f'{wlan_ip}:{port}:localhost:22 p' \
                                   f'i@{name}\n\n' \
                                   "[Install]\n" \
                                   "WantedBy=multi-user.target"

                ssh_config_template = f'Host {name}\n' \
                                      f'     HostName {hostname}.local\n' \
                                      f'     User pi\n' \
                                      f'     Port {port}\n\n'

                ssh_config_output += ssh_config_template
                Sudo.writefile(f'/etc/systemd/system/{service_name}',
                               service_template)
                port = str(int(port) + 1)

            os.system('sudo systemctl daemon-reload')
            for name in names:
                servicename = f"autossh-{name}.service"
                os.system(f'sudo systemctl start {servicename}')
                os.system(f'sudo systemctl enable {servicename}')

            print('\nTunnels created.\n\nPlease place the following in your '
                  'remote machine\'s (i.e. laptop) ~/.ssh/config file to '
                  'alias simple ssh access (i.e. ssh red001).')
            banner('copy to ~/.ssh/config on remote host (i.e laptop)')
            print(ssh_config_output)

        elif arguments.shutdown or arguments.reboot:

            if arguments.shutdown:
                command = 'sudo shutdown -h now'
            elif arguments.reboot:
                command = 'sudo reboot'

            names = Parameter.expand(arguments.NAMES)
            hostname = Shell.run("hostname").strip()

            localhost = None
            if "localhost" in names:
                names.remove("localhost")
                localhost = True
            if hostname in names:
                names.remove(hostname)
                localhost = True

            manager, workers = Host.get_hostnames(names)

            if workers:
                Console.info(f'Executing `{command}` for {workers}')
                Host.ssh(hosts=workers, command=command)

            if manager:
                Console.info(f'Executing `{command}` for {manager}')
                Host.ssh(hosts=manager, command=command)

            #_print(results)
            # results can be misleading becuase there is a race between the
            # shutdown and the error code being returned from the ssh processes.

            if localhost:
                os.system(command)

        elif arguments.adduser:
            names = Parameter.expand(arguments.NAMES)
            user = arguments.USER

            localhost = None
            if 'localhost' in names:
                localhost = 'localhost'
            elif platform.node() in names:
                localhost = platform.node()

            if localhost in names:
                print('\nAdding user to localhost')
                result = Shell.run(f'sudo adduser {user} '
                                   f'--disabled-password '
                                   f'--gecos "" ')
                print(result)
                names.remove(localhost)

            if len(names) > 0:
                command = f"sudo adduser {user} --disabled-password --gecos ',' "
                results = Host.ssh(hosts=names, command=command)
                _print(results)

        elif arguments.passwd:
            names = Parameter.expand(arguments.NAMES)
            user = arguments.USER

            localhost = None
            if 'localhost' in names:
                localhost = 'localhost'
            elif platform.node() in names:
                localhost = platform.node()

            if localhost in names:
                print("\nSetting password on localhost, please provide user "
                      "password")
                result = os.system(f'sudo passwd {user}')
                print(result)
                names.remove(localhost)

            if len(names) > 0:
                print("\nSetting password on remote hosts, please enter user "
                      "password\n")
                password = getpass("Please enter the user password:"******"{password}\n{password}" | sudo passwd {user}'
                results = Host.ssh(hosts=names, command=command)
                _print(results)

        elif arguments.addsudo:
            names = Parameter.expand(arguments.NAMES)
            user = arguments.USER

            localhost = None
            if 'localhost' in names:
                localhost = 'localhost'
            elif platform.node() in names:
                localhost = platform.node()

            if localhost in names:
                print('\nAdding user to sudo group on localhost')
                result = Shell.run(f'sudo adduser {user} sudo')
                print(result)
                names.remove(localhost)

            if len(names) > 0:
                command = f'sudo adduser {user} sudo'
                results = Host.ssh(hosts=names, command=command)
                _print(results)

        elif arguments.deluser:
            names = Parameter.expand(arguments.NAMES)
            user = arguments.USER

            if 'localhost' in names:
                localhost = 'localhost'
            elif platform.node() in names:
                localhost = platform.node()

            if localhost in names:
                print('\nDeleting user on localhost')
                result = Shell.run(f'sudo userdel -r {user}')
                print(result)
                names.remove(localhost)

            if len(names) > 0:
                command = f'sudo userdel -r {user}'
                results = Host.ssh(hosts=names, command=command)
                _print(results)

        return ""
Пример #14
0
 def installed():
     r = Shell.which("rpi-imager")
     return r is not None
Пример #15
0
#!/usr/bin/env python3

# Josh Goodman sp20-516-220 E.Cloudmesh.Common.4

from cloudmesh.common.Shell import Shell

if __name__ == "__main__":
    lines = Shell.grep('Josh', __file__)
    print(f"The following lines match 'Josh' in {__file__}:\n\n{lines}")



Пример #16
0
 def _execute(self, cmd, src):
     return Shell.execute('ampy', ['--port', self.port, cmd, src])
Пример #17
0
def aws_delete():
    print("setting cloud to aws")
    Shell.execute("cms set cloud=aws", shell=True)
    print("deleting austin-vm-aws_a1...")
    Shell.execute("cms vm delete austin-vm-aws_a1", shell=True)
Пример #18
0
    def do_cluster(self, args, arguments):
        """
		::

		Usage:
			cluster test
			cluster build --id=ID LABEL
			cluster create --cloud=CLOUD --n=N LABEL
			cluster add --id="[ID]" --all LABEL
			cluster remove --id="[ID]" --all LABEL
			cluster terminate --all LABEL
			cluster info [--verbose=V] [LABEL]

		This command allows you to create and interact with an available cluster of machines.

		Arguments:
			ID		An existing machine ID to be reserved for the cluster.
			LABEL		The label for the cluster.
			CLOUD		Cloud platform to initialize VMs.
			N			Number of instances to request.
			V			Verbosity level.
			
		Options:
			--id      Specify string containing list of IDs, comma delimited format "id1,id2,...,idx".
			--cloud	Specify cloud platform {AWS, Azure, Openstack}.
			--n		Specify number of VMs to initialize.
			--all		OPTIONAL.  Overrides --id, will pass all machines as an argument.
			--verbose OPTIONAL.  Provides verbosity level for info.

		Description:

			cluster build --id=ID LABEL

				Groups together existing machines and reserves them for cluster use.  Pass a comma-delimited list of machine ID's as a string.
				Pass --all to associate all available machines to cluster.
				
			cluster create --cloud=CLOUD --n=N LABEL
				
				Automatically requests VMs from the cloud service requested.
			
			cluster add --id="[ID]" --all LABEL

				Adds given machine IDs to cluster.  Pass --all to associate all available machines to cluster.

			cluster remove --id="[ID]" LABEL
			
				Removes given machine IDs from cluster.  Pass --all to disassociate all machines from cluster.

			cluster terminate --all LABEL

				Terminates all instances associated with the cluster, wipes cluster data.  If --all is passed, terminates all running clusters.

			cluster info --all --verbose=v [LABEL]

				Retrieves cluster data and machine data associatred with cluster.  Verbosity level 1 provides high-level cluster information
				and list of machines associated.  Verbosity level 2 provides cluster information, machine information and status.  Verbosity 
				level 3 provides all available information.

		"""
        map_parameters(arguments, 'id', 'label', 'cloud', 'n', 'v', 'all',
                       'verbose')

        # inv = Inventory()
        # inv.read()

        config = Config()
        user = config["cloudmesh.profile.user"]
        s = Shell()
        cmdb = CmDatabase()

        if arguments.test:
            cmdb = CmDatabase()
            virtual_clusters = cmdb.collection("cluster-virtual")
            print(*[index for index in virtual_clusters.list_indexes()])

        if arguments.build:
            ids, label = arguments.id, arguments.LABEL

            # Builds and stores a cluster connected to existing machine ids
            machines = ids.split(",")
            cluster_machines = []
            for i, machine in enumerate(machines):
                cluster_machines.append({
                    f"{machine}_{i}": {
                        "type": "cloud",
                        "cloud": None,
                        "status": "available",
                        "deployment": None
                    }
                })
            print(f"Adding the following machines to cluster-cloud {label}: ")
            VERBOSE(cluster_machines)
            collection = cmdb.collection("cluster-cloud")
            collection.insert_one({label: cluster_machines})

        # # TODO Revise to update to correct mongo create/update
        # cmdb.UPDATE(clusters)

        if arguments.create:
            n, label, cloud = arguments.n, arguments.label, arguments.cloud
            ids = [f"label_{i}" for i in range(n)].join(",")
            starting = [
                s.run(f"cms vm boot --name={id} --cloud={cloud}") for id in ids
            ]
            s.run(f"cms cluster build --id={ids} {label}")
            print(f"Starting {starting}")

        elif arguments.add:
            pass

        elif arguments.remove:
            pass

        elif arguments.terminate:
            pass

        elif arguments.info:
            v, label = arguments.verbose or arguments.v or None, arguments.LABEL or None
            if label: print(f"Searching for {label}")
            virtual_clusters, cloud_clusters = cmdb.collection(
                "cluster-virtual"), cmdb.collection("cluster-cloud")
            output = {
                'virtual': [i for i in virtual_clusters.find(label)],
                'cloud': [i for i in cloud_clusters.find(label)]
            }

            print(output)
        return ""
Пример #19
0
[![image](https://img.shields.io/github/license/TankerHQ/python-{repo}.svg)](https://github.com/TankerHQ/python-{repo}/blob/main/LICENSE)
"""

#
# Find Tests
#
tests = glob.glob('tests/test_**.py')
links = [
    "[{name}]({x})".format(x=x, name=os.path.basename(x).replace('.py', '')) for
    x in tests]
tests = " * " + "\n * ".join(links)

#
# get manual
#
manual = Shell.run("cms help openapi")
man = []
start = False
for line in manual.splitlines():
    start = start or "Usage:" in line
    if start:
        if not line.startswith("Timer:"):
            man.append(line)
manual = textwrap.dedent('\n'.join(man)).strip()
manual = "```bash\n" + manual + "\n```\n"

#
# create readme
#
source = readfile("README-source.md")
readme = source.format(**locals())
 def create_file(self, location, content):
     Shell.mkdir(os.dirname(path_expand(location)))
     writefile(location, content)
Пример #21
0
 def __init__(self):
     self.update()
     self.IP = Shell.run("minikube ip").strip()
Пример #22
0
    def do_admin(self, args, arguments):
        """
        ::

          Usage:
            admin mongo install [--brew] [--download=PATH]
            admin mongo create
            admin mongo status
            admin mongo stats
            admin mongo version
            admin mongo start
            admin mongo stop
            admin mongo backup FILENAME
            admin mongo load FILENAME
            admin mongo security
            admin mongo password PASSWORD
            admin mongo list
            admin rest status
            admin rest start
            admin rest stop
            admin status
            admin system info
            admin yaml cat
            admin yaml check

          The admin command performs some administrative functions, such as installing packages, software and services.
          It also is used to start services and configure them.

          Arguments:
            FILENAME  the filename for backups

          Options:
            -f      specify the file

          Description:

            Mongo DB

              MongoDB is managed through a number of commands.

              The configuration is read from ~/.cloudmesh/cloudmesh4.yaml

              First, you need to create a MongoDB database with

                cms admin mongo create

              Second, you need to start it with

                 cms admin mongo start

              Now you can interact with it to find out the status, the stats,
              and the database listing with the commands

                 cms admin mongo status
                 cms admin mongo stats
                 cms admin mongo list

              To stop it from running use the command

                 cms admin mongo stop

              System information about your machine can be returned by

                 cms admin system info

              This can be very useful in case you are filing an issue or bug.
        """

        # arguments.PATH = arguments['--download'] or None
        result = None

        if arguments.mongo:

            if arguments.install:

                print("MongoDB install")
                print(79 * "=")
                installer = MongoInstaller()
                r = installer.install()
                return r

            elif arguments.status:

                mongo = MongoDBController()
                state = mongo.status()

                if "error" in state["status"]:
                    Console.error(state["message"])
                    print(Printer.attribute(state))
                else:
                    data = dotdict()

                    for pid in state['output']:
                        entry = state['output'][pid]
                        data["pid"] = state['output'][pid]
                        data["command"] = state['output'][pid][
                            'command'].strip()

                    print(Printer.dict(data, order=["pid", "command"]))
                    Console.ok(str(data.pid['pid']) + " " + state["message"])

            elif arguments.version:
                print("MongoDB Version")
                print(79 * "=")
                mongo = MongoDBController()
                r = mongo.version()
                print(r)

            elif arguments.security:

                mongo = MongoDBController()
                mongo.set_auth()
                print()

            elif arguments.create:

                print("MongoDB create")
                MongoDBController().create()

            elif arguments.start:

                print("MongoDB start")
                MongoDBController().start(security=True)

            elif arguments.stop:

                print("MongoDB stop")
                MongoDBController().stop()

            elif arguments.backup:

                print("MongoDB backup")
                MongoDBController().dump(arguments.get('FILENAME'))

            elif arguments.load:

                print("MongoDB backup")
                MongoDBController().restore(arguments.get('FILENAME'))

            elif arguments.stats:

                mongo = MongoDBController()
                r = mongo.stats()

                if len(r) > 0:
                    print(Printer.attribute(r))
                    Console.ok("ok")
                else:
                    Console.ok("is your MongoDB server running")

            elif arguments.list:

                mongo = MongoDBController()
                r = mongo.list()

                if len(r) > 0:
                    print(
                        Printer.dict(r, order=["name", "sizeOnDisk", "empty"]))
                    Console.ok("ok")
                else:
                    Console.ok("is your MongoDB server running")

        elif arguments.yaml and arguments.cat:

            path = path_expand("~/.cloudmesh/cloudmesh4.yaml")

            secrets = [
                "AZURE_SUBSCRIPTION_ID", "AZURE_TENANTID", "EC2_ACCESS_ID",
                "EC2_SECRET_KEY", "OS_PASSWORD", "MONGO_PASSWORD"
            ]

            with open(path) as f:
                content = f.read().split("\n")

            for line in content:
                if "TBD" not in line:
                    for attribute in secrets:
                        if attribute + ":" in line:
                            line = line.split(":")[0] + ": ********"
                            break
                print(line)
            return ""

        elif arguments.yaml and arguments.check:

            path = path_expand("~/.cloudmesh/cloudmesh4.yaml")
            print()
            r = Shell.live('/Users/grey/.pyenv/shims/yamllint ' + path)
            print(70 * '-')
            print(" line:column  description")
            print()

        elif arguments.rest:

            if arguments.start:

                print("Rest Service start")
                raise NotImplementedError

            elif arguments.stop:

                print("Rest Service stop")
                raise NotImplementedError

            elif arguments.status:

                print("Rest Service status")
                raise NotImplementedError

        elif arguments.status:

            config = Config()
            data = config.data["cloudmesh"]["data"]["mongo"]
            # self.expanduser()

            print("Rest Service status")

            print("MongoDB status")

            mongo = MongoDBController()

            print(mongo)
            # mongo.expanduser()
            # data = mongo.data
            # print ("DDD", data)

            # data["MONGO_VERSION"]  = '.'.join(str(x) for x in mongo.version())

            # print (data)
            # print(Printer.attribute(data))
            # mongo.set_auth()

        elif arguments.system:

            s = OperatingSystem.get()
            print(Printer.attribute(s))

        return result
Пример #23
0
    def do_config(self, args, arguments):
        """
        ::

           Usage:
             config  -h | --help
             config cat [less]
             config check
             config secinit
             config security add (--secret=REGEXP | --exception=REGEXP )
             config security rmv (--secret=REGEXP | --exception=REGEXP )
             config security list
             config encrypt 
             config decrypt [--nopass]
             config edit [ATTRIBUTE]
             config set ATTRIBUTE=VALUE
             config get ATTRIBUTE [--output=OUTPUT]
             config value ATTRIBUTE
             config cloud verify NAME [KIND]
             config cloud edit [NAME] [KIND]
             config cloud list NAME [KIND] [--secrets]


           Arguments:
             SOURCE           the file to encrypted or decrypted.
                              an .enc is added to the filename or removed form it
                              dependent of if you encrypt or decrypt
             ATTRIBUTE=VALUE  sets the attribute with . notation in the
                              configuration file.
             ATTRIBUTE        reads the attribute from the container and sets it
                              in the configuration file
                              If the attribute is a password, * is written instead
                              of the character included
             REGEXP           python regular expression

           Options:
              --secret=REGEXP       ensures all attributes within cloudmesh.yaml 
                                    whose dot path matches REGEXP are not encrypted
                                    (even if listed in secrets)
              --exception=REGEXP    ensures attributes within cloudmesh.yaml whose 
                                    dot path matches REGEXP are encrypted
              --name=KEYNAME        The name of a key
              --nopass              Indicates if private key is password protected
              --output=OUTPUT       The output format [default: yaml]
              --secrets             Print the secrets. Use carefully.

           Description:

             config check
                checks if the ssh key ~/.ssh/id_rsa has a password. Verifies it
                through entering the passphrase

             Key generation

                Keys can be generated with 

                    cms key gen (ssh | pem) 

                Key validity and password can be verified with

                    cms key verify (ssh | pem) 

             key verify (ssh | pem) [--filename=FILENAME] [--pub]

                ssh-add

                cms config encrypt 
                    Encrypts the config data at-rest. This means that the data
                    is encrypted when not in use. This command is reliant upon
                    the cloudmesh.security.secrets attribute and the
                    cloudmesh.security.exceptions attribute within the
                    cloudmesh.yaml file. Note, that the encrypted data is not 
                    encrypted upon request/query to the attribute. This means 
                    you must decrypt the config when needed in use and
                    re-encrypt when not using the file, or delivering the file.

                        1. cloudmesh.security.secrets:
                            This attribute will hold a list of python regular
                            expressions that detail which attributes will be 
                            encrypted by the command. 
                            ex) .*: will encrypt all attributes
                            ex) .*mdbpwd.*: will encrypt all paths with mdbpwd

                        2. cloudmesh.security.exceptions:
                            This attribute will hold a list of python regular
                            expressions that detail which attributes will not
                            be encrypted by the command. 
                            ex) .*pubkey.*: ensures no pubkey path is encrypted 
                    
                security add --secret=REGEXP 
                    Adds valid REGEXP to the cloudmesh.security.secrets section

                security rmv --secret=REGEXP 
                    Removes REGEXP from the cloudmesh.security.secrets section

                security add --exception=REGEXP
                    Adds valid REGEXP to cloudmesh.security.exceptions section

                security rmv --exception=REGEXP
                    Removes REGEXP from cloudmesh.security.exceptions section

                security list
                    Prints a list of all the attribute dot-paths that are 
                    referenced by cms config encryption and decryption commands

                cms config decrypt 
                    Decrypts the config data that was held in rest. This 
                    command decrypts and attributes that were encrypted
                    using the sister `cms config encrypt` command. 

                config set ATTRIBUTE=VALUE

                    config set profile.name=Gregor

                In case the ATTRIBUTE is the name of a cloud defined under
                cloudmesh.cloud, the value will be written into the credentials
                attributes for that cloud this way you can safe a lot of
                typing. An example is

                    cms config set aws.AWS_TEST=Gregor

                which would write the AWS_TEST attribute in the credentials
                of the cloud aws. This can naturally be used to set for
                example username and password.

        """
        # d = Config()                #~/.cloudmesh/cloudmesh.yaml
        # d = Config(encryted=True)   # ~/.cloudmesh/cloudmesh.yaml.enc

        map_parameters(arguments, "exception", "keep", "nopass", "output",
                       "secret", "secrets")

        source = arguments.SOURCE or path_expand("~/.cloudmesh/cloudmesh.yaml")
        destination = source + ".enc"

        if arguments.cloud and arguments.edit and arguments.NAME is None:
            path = path_expand("~/.cloudmesh/cloudmesh.yaml")
            print(path)
            Shell.edit(path)
            return ""

        cloud = arguments.NAME
        kind = arguments.KIND
        if kind is None:
            kind = "cloud"

        configuration = Config()

        if arguments.cloud and arguments.verify:
            service = configuration[f"cloudmesh.{kind}.{cloud}"]

            result = {"cloudmesh": {"cloud": {cloud: service}}}

            action = "verify"
            banner(
                f"{action} cloudmesh.{kind}.{cloud} in ~/.cloudmesh/cloudmesh.yaml"
            )

            print(yaml.dump(result))

            flat = flatten(service, sep=".")

            for attribute in flat:
                if "TBD" in str(flat[attribute]):
                    Console.error(
                        f"~/.cloudmesh.yaml: Attribute cloudmesh.{cloud}.{attribute} contains TBD"
                    )

        elif arguments.cloud and arguments.list:
            service = configuration[f"cloudmesh.{kind}.{cloud}"]
            result = {"cloudmesh": {"cloud": {cloud: service}}}

            action = "list"
            banner(
                f"{action} cloudmesh.{kind}.{cloud} in ~/.cloudmesh/cloudmesh.yaml"
            )

            lines = yaml.dump(result).split("\n")
            secrets = not arguments.secrets
            result = Config.cat_lines(lines, mask_secrets=secrets)
            print(result)

        elif arguments.cloud and arguments.edit:

            #
            # there is a duplicated code in config.py for this
            #
            action = "edit"
            banner(
                f"{action} cloudmesh.{kind}.{cloud}.credentials in ~/.cloudmesh/cloudmesh.yaml"
            )

            credentials = configuration[
                f"cloudmesh.{kind}.{cloud}.credentials"]

            print(yaml.dump(credentials))

            for attribute in credentials:
                if "TBD" in credentials[str(attribute)]:
                    value = credentials[attribute]
                    result = input(f"Please enter {attribute}[{value}]: ")
                    credentials[attribute] = result

            # configuration[f"cloudmesh.{kind}.{cloud}.credentials"] = credentials

            print(
                yaml.dump(
                    configuration[f"cloudmesh.{kind}.{cloud}.credentials"]))

        elif arguments["edit"] and arguments["ATTRIBUTE"]:

            attribute = arguments.ATTRIBUTE

            config = Config()

            config.edit(attribute)

            config.save()

            return ""

        elif arguments.cat:

            content = Config.cat()

            import shutil
            columns, rows = shutil.get_terminal_size(fallback=(80, 24))

            lines = content.split("\n")

            counter = 1
            for line in lines:
                if arguments.less:
                    if counter % (rows - 2) == 0:
                        x = input().split("\n")[0].strip()
                        if x != '' and x in 'qQxX':
                            return ""
                print(line)
                counter += 1

            return ""

        elif arguments.check:

            Config.check()

        elif arguments.encrypt:
            config = Config()
            config.encrypt()

        elif arguments.decrypt:
            config = Config()
            config.decrypt(ask_pass=not arguments.nopass)

        elif arguments.set:

            config = Config()
            clouds = config["cloudmesh.cloud"].keys()

            line = arguments["ATTRIBUTE=VALUE"]
            attribute, value = line.split("=", 1)

            cloud, field = attribute.split(".", 1)

            if cloud in clouds:
                attribute = f"cloudmesh.cloud.{cloud}.credentials.{field}"

            elif not attribute.startswith("cloudmesh."):
                attribute = f"cloudmesh.{attribute}"

            config[attribute] = value
            config.save()

        elif arguments.value:

            config = Config()

            attribute = arguments.ATTRIBUTE
            if not attribute.startswith("cloudmesh."):
                attribute = f"cloudmesh.{attribute}"

            try:
                value = config[attribute]
                if type(value) == dict:
                    raise Console.error("the variable is a dict")
                else:
                    print(f"{value}")

            except Exception as e:
                print(e)
                return ""

        elif arguments.secinit:
            config = Config()
            secpath = path_expand(config['cloudmesh.security.secpath'])
            if not os.path.isdir(secpath):
                Shell.mkdir(secpath)  # Use Shell that makes all dirs as needed

        elif arguments.security and arguments.list:
            config = Config()
            secrets = config.get_list_secrets()
            for s in secrets:
                Console.msg(s)

        elif arguments.security:
            # Get the regular expression from command line
            regexp = None
            if arguments.secret:
                regexp = arguments.secret
            elif arguments.exception:
                regexp = arguments.exception

            # Verify argument is valid python regular expression
            try:
                r = re.compile(regexp)
            except re.error:
                Console.error(f"Invalid Python RegExp:{regexp}")
                sys.exit()

            config = Config()
            path = None
            section = None

            # Assign information based on arguments
            if arguments.secret:
                path = 'cloudmesh.security.secrets'
                section = "secrets"
            elif arguments.exception:
                path = 'cloudmesh.security.exceptions'
                section = "exceptions"

            # Get current list of regular expressions from related section
            exps = config[path]

            # Add argument to expressions in related section
            if arguments.add:
                if regexp not in exps:
                    config[path].append(regexp)
                    config.save()
                    Console.ok(f"Added {regexp} to {section}")
                else:
                    Console.warning(f"{regexp} already in {section}")
            # Remove argument from expressions in related section
            elif arguments.rmv:
                if regexp in exps:
                    config[path].remove(regexp)
                    config.save()
                    Console.ok(f"Removed {regexp} from {section}")
                else:
                    Console.warning(f"{regexp} not in {section}")

        elif arguments.get:

            print()

            config = Config()
            clouds = config["cloudmesh.cloud"].keys()

            attribute = arguments.ATTRIBUTE

            try:
                cloud, field = attribute.split(".", 1)
                field = f".{field}"
            except:
                cloud = attribute
                field = ""

            if cloud in clouds:
                attribute = f"cloudmesh.cloud.{cloud}{field}"
            elif not attribute.startswith("cloudmesh."):
                attribute = f"cloudmesh.{attribute}"

            try:
                value = config[attribute]
                if type(value) == dict:
                    print(Printer.write(value, output=arguments.output))
                else:
                    print(f"{attribute}={value}")

            except Exception as e:
                print(e)
                return ""

        return ""
Пример #24
0
    def do_var(self, args, arguments):
        """
        ::

            Usage:
                var list
                var clear
                var delete NAME
                var NAME=VALUE
                var NAME
                var

            Arguments:
                NAME      the name of the variable
                VALUE     the value of the variable
                FILENAME  the filename of the variable

            Description:
                Manage persistent variables

                var NAME=VALUE
                   sets the variable with the name to the value
                   if the value is one of data, time, now it will be
                   replaced with the value at this time, the format will be
                    date    2017-04-14
                    time    11:30:33
                    now     2017-04-14 11:30:41
                It will wbe replaced accordingly

                The value can also refer to another variable name.
                In this case the current value will be copied in the named
                variable. As we use the $ sign it is important to distinguish
                shell variables from cms variables while using proper quoting.

                Examples include:

                   cms var a=\$b
                   cms var 'a=$b'
                   cms var a=val.b

                The previous command copy the value from b to a. The val command
                was added to avoid quoting.


        """  # noqa: W605

        if args == '':
            arguments["list"] = True

        variables = Variables()

        if arguments["NAME=VALUE"]:
            if '=' in arguments["NAME=VALUE"]:
                name, value = arguments["NAME=VALUE"].split("=", 1)

                if name in ['debug', 'trace', 'timer']:
                    value = str(str(value).lower() in ['1', 'on', 'true'])

            else:
                name = arguments["NAME=VALUE"]
                try:
                    value = variables[name]
                except:
                    value = None

        if arguments["clear"]:
            variables.clear()

        elif arguments["list"]:
            for name in variables:
                value = variables[name]
                print(name, "=", "'", value, "'", sep="")

        elif arguments.delete:
            del variables[arguments.NAME]

        elif name and not value:
            Console.error("variable {name} does not exist".format(name=name))

        elif name and not value:
            print(variables[arguments.NAME])

        elif name and value:
            if name in ["dryrun"]:
                if value.lower() in ["on", "true", "1", "t"]:
                    value = True
                elif value.lower() in ["off", "false", "0", "f"]:
                    value = True
                else:
                    Console.error(f"value of {name} must be True/False")
                    return ""
            elif value.startswith("cloudmesh."):
                try:
                    from cloudmesh.configuration.Config import Config
                    config = Config()
                except:
                    Console.error("cloudmesh configuration not loaded.")
                try:
                    value = config[value]
                except:
                    Console.error(f"problem reading {value}")
                    return ""
            elif value.startswith("!"):
                # cms set a=\!pwd
                command = value[1:]
                value = Shell.run(command)
            elif value.startswith("py "):
                # cms set a=\!pwd
                command = value.split("py ")[1]
                value = eval(command)

            elif value == "time":
                value = datetime.now().strftime("%H:%M:%S")
            elif value == "date":
                value = datetime.now().strftime("%Y-%m-%d")
            elif value == "now":
                value = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            elif value.startswith("value."):
                var = value.replace("value.", "")
                value = variables[var]
            elif value.startswith("$"):
                var = value.replace("$", "")
                value = variables[var]

            print(name, "=", "'", value, "'", sep="")
            variables[name] = value
Пример #25
0
# fa19-516-156 E.Cloudmesh.Common.4
# Develop a program that demonstartes the use of cloudmesh.common.Shell.

from cloudmesh.common.Shell import Shell

##Check Python Version
result = Shell.check_python()
print(result)

## Check Valid Shell command
result = Shell.command_exists("print")
print(result)

result = Shell.command_exists("output")
print(result)


result = Shell.terminal_type()
print(result)

Пример #26
0
 def tree(self, directory=None):
     source = self._dirname(directory)
     r = Shell.execute(f"tree {source}")
     print(r)
Пример #27
0
    def do_version(self, args, arguments):
        """
        ::

          Usage:
            version pip [PACKAGE]
            version [--format=FORMAT] [--check=CHECK] [--number]

          Options:
            --format=FORMAT  the format to print the versions in [default: table]
            --check=CHECK    boolean tp conduct an additional check [default: True]

          Description:
            version
                Prints out the version number
            version pip
                Prints the contents of pip list

          Limitations:
            Package names must not have a . in them instead you need to use -
            Thus to query for cloudmesh-cmd5 use

              cms version pip cloudmesh-cmd5

        """

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

        if arguments["pip"]:
            # noinspection PyBroadException
            try:
                package = arguments["PACKAGE"]

                if package is None:
                    result = Shell.execute('pip', ['list', '--format=columns'],
                                           traceflag=False,
                                           witherror=False)
                    print(result)
                else:
                    if "." in package:
                        package = package.replace(".", "-")
                    result = Shell.execute('pip', ['show', package],
                                           traceflag=False,
                                           witherror=False)
                    print(result)

            except Exception as e:  # noqa: F841
                result = 'N/A'
            return ""

        python_version, pip_version = Shell.get_python()

        # noinspection PyBroadException
        try:
            git_hash_version = Shell.execute('git',
                                             'log -1 --format=%h',
                                             traceflag=False,
                                             witherror=False)
        except:  # noqa: E722
            git_hash_version = 'N/A'

        versions = {
            "python": {
                "name": "python",
                "version": str(python_version)
            },
            "pip": {
                "name": "pip",
                "version": str(pip_version)
            },
            "git": {
                "name": "git hash",
                "version": str(git_hash_version)
            }
        }

        # dynamically check all installed cloudmesh packages and versions
        pipcheck = subprocess.Popen(('pip', 'freeze'), stdout=subprocess.PIPE)
        try:
            # python 3 returns byte sequence so the decode is necessary
            output = subprocess.check_output(
                ('grep', "cloudmesh"), stdin=pipcheck.stdout).decode("utf-8")
            pkglines = output.strip().splitlines()

            for pkgline in pkglines:
                # print (pkgline)
                if "==" in pkgline:
                    values = pkgline.split("==")
                    pkg = values[0]
                    version = values[1].strip()
                    if pkg != 'cloudmesh-installer':
                        pname = pkg.replace("cloudmesh-", "cloudmesh.")
                        i = importlib.import_module(pname)

                        location = i.__file__

                        try:
                            vlocation = path_expand(
                                os.path.join(os.path.dirname(location),
                                             "__version__.py"))
                            v = readfile(vlocation).split('"')[1].strip()
                        except:  # noqa: E722
                            v = "not found"

                        versions[pkg] = {
                            "name": pkg,
                            "package": pname,
                            "version": version,
                            "source": location,
                            "VERSION": v
                        }
                elif "git" in pkgline and ("installer" not in pkgline) and (
                        "pi_burn" not in pkgline):

                    pkgline = pkgline.replace(
                        "-e [email protected]:cloudmesh-community/", "")
                    pkgline = pkgline.replace(
                        "-e git+https://github.com/cloudmesh/", "")
                    pkgline = pkgline.replace("egg=", "")

                    version, pkg = pkgline.split("#")
                    pname = pkg.replace("cloudmesh-", "cloudmesh.")
                    #
                    # The next line needed to be added as for some reason the is an _ here
                    #
                    pname = pkg.replace("cloudmesh_", "cloudmesh.")

                    try:
                        i = importlib.import_module(pname)
                    except:  # noqa: E722
                        continue

                    location = i.__file__

                    try:
                        vlocation = path_expand(
                            os.path.join(os.path.dirname(location),
                                         "__version__.py"))
                        v = readfile(vlocation).split('"')[1].strip()
                    except:  # noqa: E722
                        v = "not found"

                    versions[pkg] = {
                        "name": pkg,
                        "package": pname,
                        "version": version,
                        "source": location,
                        "VERSION": v
                    }
        except subprocess.CalledProcessError as e:  # noqa: F841
            pass
        pipcheck.wait()

        # installedpkgs = []
        #
        # for a preset set of named packages
        '''
        #pkgs = ['cloudmesh-common', 'cloudmesh-cmd5', 'cloudmesh.comet']
        for package in pkgs:
            # check version from pip
            pipcheck = subprocess.Popen(('pip', 'freeze'), stdout=subprocess.PIPE)
            try:
                output = subprocess.check_output(('grep', package), stdin=pipcheck.stdout)
                version = output.split("==")[1].strip()
                versions[package] = {"name": package,
                                     "version": version
                                     }
            except subprocess.CalledProcessError as e:
                pass
            pipcheck.wait()
        '''

        # __version__ not maintained in package file so this won't work
        '''
            try:
                print ("trying package |%s|" % package)
                try_module = __import__(package)
                print ("added one package into the list...")
                installedpkgs.append(package)
            except ImportError as e:
                print ("error importing |%s|" % package)
                pass

        #print (installedpkgs)
        for package in installedpkgs:
            versions[package] = {package: {"name": package,
                                           "version": str(package.__version__)
                                           }
                                 }
        print (versions)
        '''

        if arguments["--number"]:

            data = []
            for key, entry in versions.items():
                try:
                    d = {'name': entry['package'], 'version': entry['VERSION']}
                    data.append(d)
                except:
                    pass

            print(
                Printer.write(data,
                              output=arguments["--format"],
                              order=["name", "version"],
                              header=["Package", "Version"],
                              sort_keys="name"))
            return ""
        else:
            print(
                Printer.write(
                    versions,
                    output=arguments["--format"],
                    order=["name", "package", "VERSION", "version", "source"],
                    sort_keys="name"))
        if arguments["--check"] in ["True"]:
            Shell.check_python()
##E.Cloudmesh.Shell.1,2,3
# E.Cloudmesh.Shell.1 - Installed cmd5 and command cms.

from cloudmesh.common.Shell import Shell

# E.Cloudmesh.Shell.2 - New command with firstname as command name.
## cloudmesh-pratibha directory has been uploaded:
##https://github.com/cloudmesh-community/fa19-516-152/tree/master/cloudmesh-exercises/cloudmesh-pratibha

shell2_result = Shell.execute('cms', 'pratibha --text HelloWorld')
print(shell2_result)

# E.Cloudmesh.Shell.3 - New command with firstname as command name.
## cloudmesh-shell3 directory has been uploaded:
## https://github.com/cloudmesh-community/fa19-516-152/tree/master/cloudmesh-exercises/cloudmesh-shell3

shell3_result = Shell.execute('cms', 'shell3 --text abcd')
print(shell3_result)

shell3_result1 = Shell.execute('cms', 'shell3 --number 45')
print(shell3_result1)

shell3_result2 = Shell.execute('cms', 'shell3 list')
print(shell3_result2)
Пример #29
0
 def login(self):
     r = Shell.execute("az login", shell=True)
     r = r.replace("true", "True")
     r = eval("[\n" + r.split("[")[1])
     return r
Пример #30
0
def azure_delete():
        print("setting cloud to azure")
        Shell.execute("cms set cloud=azure",shell=True)
        print("deleting austin-vm-azure_a1...")
        Shell.execute("cms vm delete austin-vm-azure_a1", shell=True)