コード例 #1
0
    def json_to_yaml(cls, name, filename="~/.cloudmesh/security/google.json"):
        """
        Given a json file downloaded from google, copies the content into the
        cloudmesh yaml file, while overwriting or creating a new compute provider
        :param cls:
        :param name:
        :param filename: Service Account Key file downloaded from google cloud.
        :return: None
        """
        path = path_expand(filename)

        # Open and load the JSON file.
        with open(path, "r") as file:
            d = json.load(file)

        # Get the project id and client email.
        project_id = d["project_id"]
        client_email = d["client_email"]

        # Format the sample with json file details.
        format_sample = cls.sample.format_map(locals())
        # Convert the yaml sample to JSON.
        google_yaml = yaml.load(format_sample, Loader=yaml.SafeLoader)
        # Extract the google compute section
        google_config = google_yaml["cloudmesh"]["cloud"]

        # Update the google cloud section of cloudmesh.yaml config file.
        config = Config()
        config["cloudmesh"]["cloud"][name] = google_config
        config.save()
        banner("Result")
        pprint(config["cloudmesh"]["cloud"][name])
コード例 #2
0
    def edit(key, caps=True, show=False):

        global gui_enabled

        if not gui_enabled:
            Console.Warning(
                "Cloudmesh Gui not supported, can not find tkinter")
            return ""

        config = Config()

        entry = dict(FlatDict(config[key], sep='.'))

        layout = [[gui.Text(f'Cloudmesh Configuration Editor: {key}')]]

        length = 1
        for _key, _value in entry.items():
            length = max(length, len(_key))

        length = length + 3

        for _key, _value in entry.items():
            if caps:
                label = _key.capitalize()
            else:
                label = _key

            secrets = Config.secrets()

            if _key in secrets and not show:
                field = [
                    gui.Text(label, size=(length, 1)),
                    gui.InputText(key=f"{key}.{_key}",
                                  password_char="*",
                                  default_text=_value)
                ]
            else:
                field = [
                    gui.Text(label, size=(length, 1)),
                    gui.InputText(key=f"{key}.{_key}", default_text=_value)
                ]
            layout.append(field)

        layout.append([gui.Submit(), gui.Cancel()])

        window = gui.Window('Cloudmesh Configuration Editor',
                            layout,
                            background_color="white")
        event, values = window.Read()
        window.Close()

        if event == "Submit":
            for _key, _value in values.items():
                config[_key] = _value
                if show:
                    Console.ok(f"{_key}={_value}")
            config.save()
        else:
            print(event)
コード例 #3
0
    def activate():

        global gui_enabled

        if not gui_enabled:
            Console.Warning(
                "Cloudmesh Gui not supported, can not find tkinter")
            return ""

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

        gui.SetOptions(text_justification='right')

        layout = [[
            gui.Text('Cloudmesh Cloud Activation', font=('Helvetica', 16))
        ], [gui.Text('Compute Services')]]

        layout.append([gui.Text('_' * 100, size=(65, 1))])

        for cloud in clouds:
            tbd = "TBD" in str(config[f"cloudmesh.cloud.{cloud}.credentials"])
            active = config[f"cloudmesh.cloud.{cloud}.cm.active"]
            if tbd:
                color = 'red'
            else:
                color = "green"

            choice = [
                gui.Checkbox(cloud,
                             key=cloud,
                             text_color=color,
                             default=active)
            ]
            layout.append(choice)

        layout.append([gui.Text('_' * 100, size=(65, 1))])

        layout.append([gui.Submit(), gui.Cancel()])

        window = gui.Window('Cloudmesh Configuration',
                            layout,
                            font=("Helvetica", 12))

        event, values = window.Read()

        if event == "Submit":
            for cloud in values:

                active = values[cloud] or False
                config[f"cloudmesh.cloud.{cloud}.cm.active"] = str(active)
                if active:
                    Console.ok(f"Cloud {cloud} is active")

            config.save()
        else:
            print(event)
コード例 #4
0
class AzRegister(object):
    def __init__(self, cloud='azure'):

        self.config = Config()
        self.credentials = self.config[f'cloudmesh.cloud.{cloud}.credentials']

    def set_credentials(self, creds):
        self.credentials['AZURE_TENANT_ID'] = creds['Access key ID']
        self.credentials['AZURE_SUBSCRIPTION_ID'] = creds['Secret access key']
        self.credentials['AZURE_APPLICATION_ID'] = creds['Secret access key']
        self.credentials['AZURE_SECRET_KEY'] = creds['Secret access key']
        self.config.save()

    def azString2Dict(self, azString):
        azDict = dict()
        for i in azString.strip().splitlines():
            x = i.split(":")
            if len(x) == 2:
                azDict[x[0].strip(' ,"')] = x[1].strip(' ,"')
        return azDict

    def register(self, cloud='azure'):
        # Opens web browser and prompts user to login
        subprocess.Popen('az login')

        # once user has logged in, collects account information, such as subscription id
        accountInfo = subprocess.getoutput('az account show')
        print(accountInfo)

        azoutput = self.azString2Dict(accountInfo)

        AZURE_SUBSCRIPTION_ID = azoutput['id']
        AZURE_TENANT_ID = azoutput['tenantId']

        # WARNING: FOLLOWING CODE WILL RENDER OLD SECRET KEY INVALID
        azAppKeyStr = subprocess.getoutput(
            'az ad sp create-for-rbac --name http://cloudmesh')
        azAppKeyDict = self.azString2Dict(azAppKeyStr)

        AZURE_APPLICATION_ID = azAppKeyDict['appId']
        AZURE_SECRET_KEY = azAppKeyDict['password']

        creds = {
            'AZURE_SUBSCRIPTION_ID': AZURE_SUBSCRIPTION_ID,
            'AZURE_TENANT_ID': AZURE_TENANT_ID,
            'AZURE_APPLICATION_ID': AZURE_APPLICATION_ID,
            'AZURE_SECRET_KEY': AZURE_SECRET_KEY
        }

        self.set_credentials(creds)

        Console.info(
            "Azure Tenant, Subscription, Application, and Secret Key have been added to the cloudmesh.yaml file."
        )
コード例 #5
0
    def json_to_yaml(name, filename="~/.cloudmesh/google.json"):
        """
        given a json file downloaded from google, copies the content into the cloudmesh yaml file, while overwriting or creating a new storage provider
        :param filename:
        :return:
        """
        # creates cloud,esh.storgae.{name}

        path = path_expand(filename)

        with open(path, "r") as file:
            d = json.load(file)
        config = Config()
        #
        # BUG START FROM THE sample
        #
        element = {
            "cm": {
                "name": name,
                "active": 'true',
                "heading": "GCP",
                "host": "https://console.cloud.google.com/storage",
                "kind": "google",
                "version": "TBD",
                "service": "storage"
            },
            "default": {
                "directory": "cloudmesh_gcp",
                "Location_type": "Region",
                "Location": "us - east1",
                "Default_storage_class": "Standard",
                "Access_control": "Uniform",
                "Encryption": "Google-managed",
                "Link_URL":
                "https://console.cloud.google.com/storage/browser/cloudmesh_gcp",
                "Link_for_gsutil": "gs://cloudmesh_gcp"
            },
            "credentials": d
        }
        config["cloudmesh"]["storage"][name] = element
        config.save()
        pprint(config["cloudmesh"]["storage"][name])
コード例 #6
0
ファイル: Register.py プロジェクト: xin-gu/cloudmesh-cloud
    def remove(service, name):
        removed_item = None
        try:
            # Update the google cloud section of cloudmesh.yaml config file.
            config = Config()
            config_service = config["cloudmesh"][service]

            if name in config_service:
                removed_item = config_service.pop(name, None)
                config.save()

                Console.ok(f"Removed {name} from {service} service.")

            else:
                Console.warning(
                    f"{name} is not registered for cloudmesh.{service}")

        except Exception as se:
            Console.error(f"Error removing {service}-{name} :: {se}")

        return removed_item
コード例 #7
0
ファイル: Entry.py プロジェクト: xin-gu/cloudmesh-cloud
    def add(entry=None,
            base="cloudmesh.cloud",
            path="~/.cloudmesh/cloudmesh.yaml"):

        try:
            _entry = dedent(entry)

            data = yaml.safe_load(_entry)

            name, entry = Entry.extract(data, base)

            if Entry.verify(entry):
                Console.ok("Verification passed")
                config = Config()  # todo: add the path
                config[base][name] = entry
                config.save()
            else:
                Console.error("entry format is wrong")
                return ""

        except yaml.YAMLError:
            Console.error(f"parsing YAML entry: {entry}")
            sys.exit()
コード例 #8
0
class AWSRegister(object):
    def __init__(self, cloud='aws'):

        self.config = Config()
        self.credentials = self.config[f'cloudmesh.cloud.{cloud}.credentials']

    def set_credentials(self, creds):
        self.credentials['EC2_ACCESS_ID'] = creds['Access key ID'][0]
        self.credentials['EC2_SECRET_KEY'] = creds['Secret access key'][0]
        self.config.save()

    def register(self, cloud='aws'):
        if platform == "linux" or platform == "linux2":
            # check if chrome installed

            chrome_ver1 = subprocess.getoutput(
                'google-chrome-stable --version')
            chrome_ver2 = subprocess.getoutput('google-chrome --version')

            if 'not found' in chrome_ver1.lower(
            ) or 'not found' in chrome_ver2.lower():
                Console.error("google chrome is not installed")
                return
            # self.driver = webdriver.Chrome()
            try:
                self.driver = webdriver.Chrome()
                # register = AWSRegister(self.driver)
            except WebDriverException as e:
                Console.error(e)

                Console.error(
                    "Chrome geckodriver not installed. Follow these steps for installation: \n"
                    "1) Download the driver from the following link: \n\t "
                    "https://sites.google.com/a/chromium.org/chromedriver/downloads \n"
                    "2) Copy the `chromedriver` to '/usr/bin' \n"
                    "3) Set the permission using:\n\t"
                    "'sudo chmod +x /usr/bin/chromedriver'")

                return

            credentials_file_name = self.create_user()

            credentials_csv_path = Path.home().joinpath('Downloads').joinpath(
                credentials_file_name).resolve()
            cloudmesh_folder = Path.home().joinpath('.cloudmesh').resolve()

            os.rename(
                credentials_csv_path,
                cloudmesh_folder.joinpath(credentials_file_name).resolve())
            Console.info("{filename} moved to ~/.cloudmesh folder".format(
                filename=credentials_file_name))

            creds = pandas.read_csv("{cm}/{filename}".format(
                cm=cloudmesh_folder, filename=credentials_file_name))

            self.set_credentials(creds)

            self.config.save()

            Console.info(
                "AWS 'Access Key ID' and 'Secret Access Key' in the cloudmesh.yaml updated"
            )

        elif platform == "darwin":
            chrome = Path(
                "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome")
            if not chrome.is_file():
                Console.error("Google chrome is not installed")
                return
            try:
                self.driver = webdriver.Chrome()
            except WebDriverException as e:
                Console.error(e)
                Console.error(
                    "Chrome geckodriver not installed. Follow these steps for installation: \n"
                    "1) Download the driver from the following link: \n\t "
                    "https://sites.google.com/a/chromium.org/chromedriver/downloads \n"
                    "2) Copy the `chromedriver` to '/usr/local/bin' \n"
                    "3) Set the permission using:\n\t"
                    "'chmod +x /usr/local/bin/chromedriver'")
                return

            credentials_file_name = self.create_user()
            credentials_csv_path = Path.home().joinpath('Downloads').joinpath(
                credentials_file_name).resolve()
            # check if the DOwanloaded file exists
            # Path("~/.cloudmesh/{credentials_file_name}).resolve()

            cloudmesh_folder = Path.home().joinpath('.cloudmesh').resolve()
            os.rename(
                credentials_csv_path,
                cloudmesh_folder.joinpath(credentials_file_name).resolve())
            Console.info(
                f"{credentials_file_name} moved to ~/.cloudmesh folder")

            creds = pandas.read_csv("{cm}/{filename}".format(
                cm=cloudmesh_folder, filename=credentials_file_name))

            self.set_credentials(creds)

            Console.info(
                "AWS 'Access Key ID' and 'Secret Access Key' in the cloudmesh.yaml updated"
            )

        elif platform == "win32":
            chrome = Path(
                "C:\Program Files (x86)\Google\Chrome\Application\Chrome.exe")
            if not chrome.is_file():
                Console.error("Google chrome is not installed")
                return
            try:
                self.driver = webdriver.Chrome()
            except WebDriverException as e:
                Console.error(e)
                Console.error(
                    "Chrome geckodriver not installed. Follow these steps for installation: \n"
                    "1) Download the driver from the following link: \n\t "
                    "https://sites.google.com/a/chromium.org/chromedriver/downloads \n"
                    "2) Copy the `chromedriver` to path, for instance you can add "
                    "it to the followtin path: "
                    "\n\t %USERPROFILE%\\AppData\\Local\\Microsoft\\WindowsApps"
                )
                return
            credentials_file_name = self.create_user()

            credentials_csv_path = Path.home().joinpath('Downloads').joinpath(
                credentials_file_name).resolve()
            cloudmesh_folder = Path.home().joinpath('.cloudmesh').resolve()
            os.rename(
                credentials_csv_path,
                cloudmesh_folder.joinpath(credentials_file_name).resolve())

            Console.info(
                f"{credentials_file_name} moved to ~/.cloudmesh folder")

            creds = pandas.read_csv("{cm}/{filename}".format(
                cm=cloudmesh_folder, filename=credentials_file_name))

            self.set_credentials(creds)

            Console.info(
                "AWS 'Access Key ID' and 'Secret Access Key' in the cloudmesh.yaml updated"
            )

    def slow_typer(self, element, text):
        for character in text:
            element.send_keys(character)
            sleep(random.random() * 0.05)

    def check_captcha(self):
        if "Type the characters seen in the image below" in self.driver.page_source:
            text = input(
                "Captcha encountered. Please enter the captcha and press Submit then press Enter to continue"
            )
            while (text != ""):
                text = input(
                    "Captcha encountered. Please enter the captcha and press Submit then press Enter to continue"
                )

    def create_user(self):
        '''
        Creates the user or if the user exists creates another access key
        :return: the name of the file containing the access key
        '''
        email = input("Enter your email: ")
        passw = getpass.getpass("Enter your password: "******"https://console.aws.amazon.com/iam/home#/users")
        assert "Amazon Web Services" in self.driver.title, "Unexpected login page, aborting"
        sleep(1.5)
        self.driver.find_element_by_id("resolving_input").send_keys(email)
        self.driver.find_element_by_id("next_button").click()
        sleep(1.5)
        self.check_captcha()

        self.driver.find_element_by_id("password").send_keys(passw)
        self.driver.find_element_by_id("signin_button").click()
        sleep(1.5)
        self.check_captcha()

        # adding cloudmesh user
        if self.user_exists():
            self.create_accesskey_on_current_account()
            return "accessKeys.csv"

        self.driver.find_element_by_link_text("Add user").click()
        sleep(1.5)

        self.driver.find_element_by_id("awsui-textfield-17").send_keys(
            "cloudmesh")
        self.driver.find_element_by_name("accessKey").click()
        sleep(1.5)

        self.driver.find_element_by_class_name("wizard-next-button").click()
        sleep(1.5)

        self.driver.find_element_by_class_name("awsui-util-pt-s").click()
        sleep(1.5)

        self.driver.find_element_by_xpath(
            "//awsui-textfield[@ng-model='createGroupModal.groupName']/input"
        ).send_keys("cloudmesh")
        sleep(1.5)
        self.driver.find_element_by_xpath(
            '//*/policies-table//table-search//search/div/input').send_keys(
                "AmazonEC2FullAccess")
        sleep(1.5)
        self.driver.find_element_by_xpath(
            '//div[@data-item-id="arn:aws:iam::aws:policy/AmazonEC2FullAccess"]//awsui-checkbox//div'
        ).click()
        sleep(1.5)
        self.driver.find_element_by_xpath(
            "//awsui-button[@click-tracker='CreateGroup']").click()
        sleep(1.5)
        Console.info("'cloudmesh' group created")

        self.driver.find_element_by_class_name("wizard-next-button").click()
        sleep(1.5)
        self.driver.find_element_by_class_name("wizard-next-button").click()
        sleep(1.5)

        Console.info("'cloudmesh' user created")
        self.driver.find_element_by_class_name("wizard-next-button").click()
        sleep(1.5)
        self.driver.find_element_by_xpath(
            "//awsui-button[@text='Download .csv']").click()
        Console.info("credentials.csv downloaded")
        sleep(2)

        self.driver.find_element_by_xpath(
            "//awsui-button[@text='Close']").click()
        sleep(4)
        return "credentials.csv"

    def user_exists(self):
        sleep(1.5)
        return len(self.driver.find_elements_by_link_text("cloudmesh")) > 0

    def create_accesskey_on_current_account(self):
        self.driver.find_element_by_xpath(
            '//a[@href="#/users/cloudmesh"]').click()
        sleep(1.5)

        self.driver.find_element_by_link_text("Security credentials").click()
        sleep(1.5)

        while len(
                self.driver.find_elements_by_xpath(
                    '//span[text()="Make inactive"]')) == 2:
            input(
                "Two access keys already exist for the user, remove one manually before creating another one and press Enter"
            )

        self.driver.find_element_by_xpath(
            '//button[.//span[text()="Create access key"]]').click()
        sleep(1.5)
        self.driver.find_element_by_xpath(
            '//*[@id="modal-container"]//awsui-button[contains(@text,"Download .csv file")]'
        ).click()
        sleep(1.5)

        Console.info("accessKeys.csv downloaded")
コード例 #9
0
    else:
        color = "green"

    choice = [gui.Checkbox(cloud,
                           text_color=color,
                           default=active)]
    layout.append(choice)

layout.append([gui.Text('_' * 100, size=(65, 1))])

layout.append([gui.Submit(), gui.Cancel()])

window = gui.Window('Cloudmesh Configuration', layout, font=("Helvetica", 12))

event, values = window.Read()

selected = []
for i in range(0, len(clouds)):
    cloud = clouds[i]
    if values[i]:
        selected.append(cloud)
        Console.ok(f"Activate Cloud {cloud}")

for cloud in clouds:
    active = False
    if cloud in selected:
        active = True
    config[f"cloudmesh.cloud.{cloud}.cm.active"] = str(active)

config.save()
コード例 #10
0
    def do_key(self, args, arguments):
        """
        ::

           Usage:
             key  -h | --help
             key list --cloud=CLOUDS [--output=OUTPUT]
             key list --source=ssh [--dir=DIR] [--output=OUTPUT]
             key list --source=git [--output=OUTPUT] [--username=USERNAME]
             key list [--output=OUTPUT]
             key init
             key add NAME --filename=FILENAME [--output=OUTPUT]
             key add [NAME] [--source=FILENAME]
             key add [NAME] [--source=git]
             key add [NAME] [--source=ssh]
             key delete NAMES [--cloud=CLOUDS] [--dryrun]
             key upload [NAMES] [--cloud=CLOUDS] [--dryrun]
             key upload [NAMES] [VMS] [--dryrun]
             key group upload [NAMES] [--group=GROUPNAMES] [--cloud=CLOUDS] [--dryrun]
             key group add [--group=GROUPNAMES] [--cloud=CLOUDS] [--dryrun]
             key group add --file=FILENAME
             key group delete [--group=GROUPNAMES] [NAMES] [--dryrun]
             key group list [--group=GROUPNAMES] [--output=OUTPUT]
             key group export --group=GROUNAMES --filename=FILENAME
             key gen (rsa | ssh) [--filename=FILENAME] [--nopass] [--set_path]
             key verify (ssh | pem) --filename=FILENAME [--pub]

           Arguments:
             VMS            Parameterized list of virtual machines
             CLOUDS         The clouds
             NAME           The name of the key.
             SOURCE         db, ssh, all
             KEYNAME        The desired full path name to the key file
             OUTPUT         The format of the output (table, json, yaml)
             FILENAME       The filename with full path in which the key is located

           Options:
              --dir=DIR             the directory with keys [default: ~/.ssh]
              --filename=FILENAME   the name and full path to the file
              --nopass              Flag indicating if the key has no password
              --output=OUTPUT       the format of the output [default: table]
              --pub                 Indicates that the public key is passed in
              --set_path            Sets the security key paths to KEYNAME
              --source=SOURCE       the source for the keys
              --username=USERNAME   the source for the keys [default: none]


           Description:

               Please note that some values are read from the cloudmesh.yaml
               file. One such value is cloudmesh.profile.user

               Manages public keys is an essential component of accessing
               virtual machine sin the cloud. There are a number of sources
               where you can find public keys. This includes teh ~/.ssh
               directory and for example github.

               Keys will be uploaded into cloudmesh database with the add
               command under the given NAME. If the name is not specified the name
               cloudmesh.profile.user is assumed.

                key add NAME  --source=ssh
                    adds the default key in ~/.ssh/id_rsa.pub
                key add NAME  --source=FILENAME
                    adds the key specified by the filename with the given name
                key add NAME --git --username=username
                    adds a named github key from a user with the given github
                    username.

                key set
                    adds the ~/.ssh/id_rsa.pub key with the name specified in
                    cloudmesh.profile.user.
                    It also sets the variable key to that user.


               Once the keys are uploaded to github, they can be listed
               To list these keys the following list functions are provided.

                key list --source=git  [--username=USERNAME]
                    lists all keys in git for the specified user. If the
                    name is not specified it is read from cloudmesh.yaml
                key list --source=ssh  [--dir=DIR] [--output=OUTPUT]
                    lists all keys in the directory. If the directory is not
                    specified the default will be ~/.ssh

                key list NAMES
                    lists all keys in the named virtual machines.


                List command can use the [--output=OUTPUT] option

                    list the keys loaded to cloudmesh in the given format:
                    json, yaml, table. table is default. The NAME can be
                    specified and if omitted the name cloudmesh.profile.user
                    is assumed.

                To get keys from the cloudmesh database the following commands
                are available:

                key delete NAMES
                    deletes the Named keys. This may also have an impact on groups
                key rename NAME NEW
                    renames the key from NAME to NEW in the cloudmesh database.

               Group management of keys is an important concept in cloudmesh,
               allowing multiple users to be added to virtual machines while
               managing the keys associated with them. The keys must be uploaded
               to cloudmesh database with a name so they can be used in a
               group. The --dryrun option executes the command without
               uploading the information to the clouds. If no group name is
               specified the group name default is assumed. If no cloudnamesh
               are specified, all active clouds are assumed. active clouds
               can be set in the cloudmesh.yaml file.

                key group delete [GROUPNAMES] [NAMES] [--dryrun]
                    deletes the named keys from the named groups.

                key group list [GROUPNAMES] [--output=OUTPUT]
                    list the key names and details in the group.

                key group upload [GROUPNAMES] [CLOUDS] [--dryrun]
                    uploads the named groups to the specified clouds.

               In some cases you may want to store the public keys in files. For
               this reason we support the following commands.

                key group add --group=GROUPNAME --file=FILENAME
                    the command adds the keys to the given group. The keys are
                    written in the files in yaml format.


                key group export --group=GROUNAMES --filename=FILENAME
                    the command exports the keys to the given group. The keys are
                    written in the files in yaml format.


                The yaml format is as follows:

                cloudmesh:
                  keys:
                    NAMEOFKEY:
                      name: NAMEOFKEY
                      key: ssh-rsa AAAA..... comment
                      group:
                      - GROUPNAME
                    ...

                If a key is included in multiple groups they will be added
                to the grouplist of the key
        """
        def print_keys(keys):
            print(
                Printer.write(
                    keys,
                    sort_keys=["name"],
                    order=["name", "type", "fingerprint", "comment"],
                    header=["Name", "Type", "Fingerprint", "Comment"],
                    output=arguments.output))

        map_parameters(arguments, 'cloud', 'dir', 'dryrun', 'filename', 'name',
                       'nopass', 'output', 'pub', 'pwd', 'set_path', 'source')

        variables = Variables()

        if arguments.list and arguments.source == "git":

            config = Config()
            username = config["cloudmesh.profile.github"]
            keys = SSHkey().get_from_git(username)

            print_keys(keys)

            return ""

        elif arguments.list and arguments.source == "ssh":
            # this is much simpler

            sshkey = SSHkey()

            print_keys([sshkey])

            return ""

        elif arguments.list and arguments.cloud:

            clouds = Parameter.expand(arguments.cloud)

            if len(clouds) == 0:
                variables = Variables()
                cloudname = variables['cloud']
                clouds = [cloudname]
            keys = []

            for cloud in clouds:
                print(f"cloud {cloud}")
                provider = Provider(name=cloud)
                keys = provider.keys()

                provider.Print(keys, output=arguments.output, kind="key")

            return ""

        elif arguments.list:

            cloud = "local"
            db = CmDatabase()
            keys = db.find(collection=f"{cloud}-key")

            print_keys(keys)

            return ""

        elif arguments.add:
            """
             key add [NAME] [--source=FILENAME] # NOT IMPLEMENTED YET
             key add [NAME] [--source=git]
             key add [NAME] [--source=ssh]
             """
            key = Key()

            if arguments["--source"] == "ssh":
                name = arguments.NAME or "ssh"
                key.add(name, "ssh")
            elif arguments["--source"] == "git":
                name = arguments.NAME or "git"
                key.add("git", "git")
            else:
                config = Config()
                name = config["cloudmesh.profile.user"]
                kind = "ssh"
                key.add(name, kind)

        elif arguments.init:
            """
            key init 
            """

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

            if username == "TBD":
                Console.error(
                    "Please set cloudmesh.profile.user in ~/.cloudmesh.yaml")
                u = os.environ["USER"].lower().replace(" ", "")
                Console.msg(
                    f"To change it you can use the command. Define a NAME such as '{u}' e.g."
                )
                Console.msg("")
                Console.msg(f"  cms config set cloudmesh.profile.user={u}")
                Console.msg("")
                return ""

            key = Key()

            key.add(username, "ssh")
            variables['key'] = username

        elif arguments.upload:
            """
            key upload [NAMES] [--cloud=CLOUDS] [--dryrun]
            key upload [NAMES] [VMS] [--dryrun]
            """

            names = Parameter.expand(arguments.NAMES)

            # this may have a bug if NAMES is ommitted

            #
            # Step 0. Set keyname to variable
            #

            if names is None or len(names) == 0:
                config = Config()
                username = config["cloudmesh.profile.user"]
                names = [username]

            if len(names) == 1:
                name = names[0]
                variables = Variables()
                if "key" in variables:
                    old = variables["key"]
                    if old != name:
                        Console.msg(
                            f"Changing defualt key from {old} to {name}")
                        variables["key"] = name

            #
            # Step 1. keys = find keys to upload
            #

            cloud = "local"
            db = CmDatabase()
            db_keys = db.find(collection=f"{cloud}-key")

            keys = []
            for key in db_keys:
                if key["name"] in names:
                    keys.append(key)

            if len(keys) == 0:
                Console.error(
                    f"No keys with the names {names} found in cloudmesh. \n"
                    "       Use the command 'key add' to add the key.")

            #
            # Step 2. iterate over the clouds to upload
            #

            clouds, names = Arguments.get_cloud_and_names(
                "list", arguments, variables)

            for cloud in clouds:
                print(f"cloud {cloud}")
                provider = Provider(name=cloud)
                for key in db_keys:
                    name = key['name']
                    if name in names:
                        try:
                            r = provider.key_upload(key)
                            Console.ok(f"upload key '{name} successful'. ")
                        except ValueError as e:
                            Console.error(
                                f"key '{name} already exists in {cloud}.")

            return ""

        elif arguments.delete and arguments.cloud and arguments.NAMES:

            # key delete NAMES --cloud=CLOUDS [--dryrun]
            names = Parameter.expand(arguments.NAMES)
            clouds = Parameter.expand(arguments.cloud)

            for cloud in clouds:
                provider = Provider(name=cloud)
                for name in names:
                    if arguments.dryrun:
                        Console.ok(f"Dryrun: delete {name} in {cloud}")
                    else:
                        images = provider.key_delete(name)

            return ""

        elif arguments.gen:
            """
            key gen (rsa | ssh) [--filename=FILENAME] [--nopass] [--set_path]
            Generate an RSA key pair with pem or ssh encoding for the public
            key. The private key is always encoded as a PEM file.
            """
            config = Config()

            # Check if password will be requested
            ap = not arguments.nopass

            if not ap:
                Console.warning("Private key will NOT have a password")
                cnt = yn_choice(message="Continue, despite risk?", default="N")
                if not cnt:
                    sys.exit()

            # Discern the name of the public and private keys
            rk_path = None
            uk_path = None
            if arguments.filename:
                if arguments.filename[-4:] == ".pub":
                    rk_path = path_expand(arguments.name[-4:])
                    uk_path = path_expand(arguments.name)
                elif arguments.filename[-5:] == ".priv":
                    rk_path = path_expand(arguments.name)
                    uk_path = path_expand(arguments.name[-5:])
                else:
                    rk_path = path_expand(arguments.filename)
                    uk_path = rk_path + ".pub"
            else:
                rk_path = path_expand(config['cloudmesh.security.privatekey'])
                uk_path = path_expand(config['cloudmesh.security.publickey'])

            # Set the path if requested
            if arguments.set_path and arguments.filename:
                config['cloudmesh.security.privatekey'] = rk_path
                config['cloudmesh.security.publickey'] = uk_path
                config.save()

            Console.msg(f"\nPrivate key: {rk_path}")
            Console.msg(f"Public  key: {uk_path}\n")

            # Generate the Private and Public keys
            kh = KeyHandler()
            r = kh.new_rsa_key()
            u = kh.get_pub_key(priv=r)

            # Serialize and write the private key to the path
            sr = kh.serialize_key(key=r,
                                  key_type="PRIV",
                                  encoding="PEM",
                                  format="PKCS8",
                                  ask_pass=ap)
            kh.write_key(key=sr, path=rk_path)

            # Determine the public key format and encoding
            enc = None
            forma = None
            if arguments.ssh:
                enc = "SSH"
                forma = "SSH"
            elif arguments.rsa:
                enc = "PEM"
                forma = "SubjectInfo"

            # Serialize and write the public key to the path
            su = kh.serialize_key(key=u,
                                  key_type="PUB",
                                  encoding=enc,
                                  format=forma,
                                  ask_pass=False)
            kh.write_key(key=su, path=uk_path)

            Console.ok("Success")

        elif arguments.verify:
            """
            key verify (ssh | pem) --filename=FILENAME --pub
            Verifies the encoding (pem or ssh) of the key (private or public)
            """
            kh = KeyHandler()
            fp = arguments.filename
            kt = None
            enc = None

            # Discern key type
            if arguments.pub:
                kt = "public"
                # Discern public key encoding
                if arguments.ssh:
                    enc, e = "OpenSSH", "SSH"
                elif arguments.pem:  #PEM encoding
                    enc = e = "PEM"

                # Load the public key, if no error occurs formatting is correct
                u = kh.load_key(path=fp,
                                key_type="PUB",
                                encoding=e,
                                ask_pass=False)

            else:
                kt, enc = "private", "PEM"

                # Load the private key to verify the formatting and password of
                # the key file. If no error occurs the format and pwd are correct
                r = kh.load_key(path=fp,
                                key_type="PRIV",
                                encoding=enc,
                                ask_pass=True)

            m = f"Success the {kt} key {fp} has proper {enc} format"
            Console.ok(m)

        elif arguments.delete and arguments.NAMES:
            # key delete NAMES [--dryrun]

            names = Parameter.expand(arguments.NAMES)

            cloud = "local"
            db = CmDatabase()
            db_keys = db.find(collection=f"{cloud}-key")

            error = []
            for key in db_keys:
                name = key['name']
                if name in names:
                    if arguments.dryrun:
                        Console.ok(f"Dryrun: delete {name}")
                    else:
                        db.delete(collection="local-key", name=name)
                        Console.ok(f"delete {name}")
            return ""

        elif arguments.group:

            raise NotImplementedError

        return ""
コード例 #11
0
ファイル: config.py プロジェクト: kpimparkar/cloudmesh-cloud
    def do_config(self, args, arguments):
        """
        ::

           Usage:
             config  -h | --help
             config cat [less]
             config check
             config secinit
             config encrypt 
             config decrypt 
             config edit [ATTRIBUTE]
             config set ATTRIBUTE=VALUE
             config get ATTRIBUTE [--output=OUTPUT]
             config value ATTRIBUTE
             config ssh keygen
             config ssh verify
             config ssh check
             config ssh pem
             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

           Options:
              --name=KEYNAME     The name of a key
              --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 must be generated with

                    ssh-keygen -t rsa -m pem
                    openssl rsa -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa.pem

                or
                    cms config ssh keygen

                Key validity can be checked with

                    cms config check

                The key password can be verified with

                    cms config verify


                ssh-add

                cms config encrypt ~/.cloudmesh/cloudmesh.yaml
                cms config decrypt ~/.cloudmesh/cloudmesh.yaml


                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, "keep", "secrets", "output")

        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 and not arguments.ssh:

            Config.check()

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

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

        elif arguments.ssh and arguments.verify:

            e = EncryptFile(source, destination)

            e.pem_verify()

        elif arguments.ssh and arguments.check:

            e = EncryptFile(source, destination)

            key = path_expand("~/.ssh/id_rsa")
            r = e.check_key(key)
            if r:
                Console.ok(f"Key {key} is valid")
            # does not work as it does not change it to pem format
            # e.check_passphrase()

        elif arguments.ssh and arguments.pem:

            e = EncryptFile(source, destination)

            r = e.pem_create()

        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'])
            gcm_path = f"{secpath}/gcm"  # Location of nonces and keys for encryption
            if not os.path.isdir(gcm_path):
                Shell.mkdir(gcm_path)  # Use Shell that makes all dirs as needed

        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 ""

        elif arguments.ssh and arguments.keygen:

            e = EncryptFile(source, destination)

            e.ssh_keygen()

        return ""
コード例 #12
0
    def do_key(self, args, arguments):
        """
        ::

           Usage:
             key  -h | --help
             key list --cloud=CLOUDS [--output=OUTPUT]
             key list --source=ssh [--dir=DIR] [--output=OUTPUT]
             key list --source=git [--output=OUTPUT] [--username=USERNAME]
             key list [--output=OUTPUT]
             key init
             key add NAME --filename=FILENAME [--output=OUTPUT]
             key add [NAME] [--source=FILENAME]
             key add [NAME] [--source=git]
             key add [NAME] [--source=ssh]
             key delete NAMES [--cloud=CLOUDS] [--dryrun]
             key upload [NAMES] [--cloud=CLOUDS] [--dryrun]
             key upload [NAMES] [VMS] [--dryrun]
             key group upload [NAMES] [--group=GROUPNAMES] [--cloud=CLOUDS] [--dryrun]
             key group add [NAMES] [--group=GROUPNAMES] [--cloud=CLOUDS] [--dryrun]
             key group delete [--group=GROUPNAMES] [NAMES] [--dryrun]
             key group list [--group=GROUPNAMES] [--output=OUTPUT]
             key group export --group=GROUNAMES --filename=FILENAME
             key gen (ssh | pem) [--filename=FILENAME] [--nopass] [--set_path] [--force]
             key reformat (ssh | pem) [--filename=FILENAME] [--format=FORMAT]
                                      [--nopass] [--pub]
             key verify (ssh | pem) [--filename=FILENAME] [--pub] [--check_pass]

           Arguments:
             VMS        Parameterized list of virtual machines
             CLOUDS     The clouds
             NAME       The name of the key.
             SOURCE     db, ssh, all
             OUTPUT     The format of the output (table, json, yaml)
             FILENAME   The filename with full path in which the key is located
             FORMAT     Desired key format (SubjectInfo, SSH, OpenSSL, PKCS8)

           Options:
              --dir=DIR             the directory with keys [default: ~/.ssh]
              --check_pass          Flag where program query user for password
              --filename=FILENAME   the name and full path to the file
              --nopass              Flag indicating if the key has no password
              --output=OUTPUT       the format of the output [default: table]
              --pub                 Indicates that the public key is passed in
              --set_path            Sets the cloudmesh encryption key path to
                                    the full path of the generated keys
              --source=SOURCE       the source for the keys
              --username=USERNAME   the source for the keys [default: none]


           Description:

               Please note that some values are read from the cloudmesh.yaml
               file. One such value is cloudmesh.profile.user

               Management of public keys is an essential component of accessing
               virtual machines in the cloud. There are a number of sources
               where you can find public keys. This includes the ~/.ssh
               directory and for example github. If you do not already have a
               public-private key pair they can be generated using cloudmesh

               key gen ssh 
                   This will create the public-private keypair of ~/.ssh/id_rsa
                   and ~/.ssh/id_rsa.pub in OpenSSH format

               key gen pem 
                   This will create the public-private keypair of ~/.ssh/id_rsa
                   and ~/.ssh/id_rsa.pub in PEM format

               key gen (ssh | pem) --filename=~/.cloudmesh/foobar
                   This will generate the public-private key pair of 
                   ~/.cloudmesh/foobar and ~/.cloudmesh/foobar.pub

               key gen (ssh | pem) --filename=~/.cloudmesh/foobar --set_path
                   This will generate the keys as stated above, but it will
                   also set cloudmesh to use these keys for encryption.

               Keys can also be verified for their formatting and passwords.
               By default cloudmesh checks ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub
               If the key is password protected the formatting can only be
               verified if the password is provided (--check_pass argument)

               key verify pem
                   Verifies that ~/.ssh/id_rsa has PEM format

               key verify ssh --pub
                   Verifies that ~/.ssh/id_rsa.pub has OpenSSH format

               key verify pem --filename=~/.cloudmesh/foobar
                   Verifies if the private key located at ~/.cloudmesh/foobar
                   is password protected

               key verify pem --filenam=~/.cloudmesh/foobar --check_pass
                   Request the password to the file, then checks if the
                   key is in proper PEM format

               You may find the need to keep the values of your keys but
               different encodings or formats. These aspects of your key can
               also be changed using cloudmesh.

               key reformat pem
                   Will reformat the ~/.id_rsa.pub key from PEM to OpenSSH

               key reformat ssh
                   Will reformat the ~/.id_rsa.pub key from OpenSSH to PEM

               key reformat --filename=~/.id_rsa --format=PKCS8
                   Will reformat the private key to PKCS8 format

               Keys will be uploaded into cloudmesh database with the add
               command under the given NAME. If the name is not specified the name
               cloudmesh.profile.user is assumed.

                key add NAME  --source=ssh
                    adds the default key in ~/.ssh/id_rsa.pub
                key add NAME  --source=FILENAME
                    adds the key specified by the filename with the given name
                key add NAME --git --username=username
                    adds a named github key from a user with the given github
                    username.

                key set
                    adds the ~/.ssh/id_rsa.pub key with the name specified in
                    cloudmesh.profile.user.
                    It also sets the variable key to that user.


               Once the keys are uploaded to github, they can be listed
               To list these keys the following list functions are provided.

                key list --source=git  [--username=USERNAME]
                    lists all keys in git for the specified user. If the
                    name is not specified it is read from cloudmesh.yaml
                key list --source=ssh  [--dir=DIR] [--output=OUTPUT]
                    lists all keys in the directory. If the directory is not
                    specified the default will be ~/.ssh

                key list NAMES
                    lists all keys in the named virtual machines.


                List command can use the [--output=OUTPUT] option

                    list the keys loaded to cloudmesh in the given format:
                    json, yaml, table. table is default. The NAME can be
                    specified and if omitted the name cloudmesh.profile.user
                    is assumed.

                To get keys from the cloudmesh database the following commands
                are available:

                key delete NAMES
                    deletes the Named keys. This may also have an impact on groups
                key rename NAME NEW
                    renames the key from NAME to NEW in the cloudmesh database.

               Group management of keys is an important concept in cloudmesh,
               allowing multiple users to be added to virtual machines while
               managing the keys associated with them. The keys must be uploaded
               to cloudmesh database with a name so they can be used in a
               group. The --dryrun option executes the command without
               uploading the information to the clouds. If no group name is
               specified the group name default is assumed. If no cloudnamesh
               are specified, all active clouds are assumed. active clouds
               can be set in the cloudmesh.yaml file.

                key group delete [GROUPNAMES] [NAMES] [--dryrun]
                    deletes the named keys from the named groups.

                key group list [GROUPNAMES] [--output=OUTPUT]
                    list the key names and details in the group.

                key group upload [GROUPNAMES] [CLOUDS] [--dryrun]
                    uploads the named groups to the specified clouds.

               In some cases you may want to store the public keys in files. For
               this reason we support the following commands.

                key group add --group=GROUPNAME --file=FILENAME
                    the command adds the keys to the given group. The keys are
                    written in the files in yaml format.


                key group export --group=GROUNAMES --filename=FILENAME
                    the command exports the keys to the given group. The keys are
                    written in the files in yaml format.


                The yaml format is as follows:

                cloudmesh:
                  keys:
                    NAMEOFKEY:
                      name: NAMEOFKEY
                      key: ssh-rsa AAAA..... comment
                      group:
                      - GROUPNAME
                    ...

                If a key is included in multiple groups they will be added
                to the grouplist of the key
        """
        def print_keys(keys):
            print(
                Printer.write(
                    keys,
                    sort_keys=["name"],
                    order=["name", "type", "fingerprint", "comment"],
                    header=["Name", "Type", "Fingerprint", "Comment"],
                    output=arguments.output))

        map_parameters(arguments, 'check_pass', 'cloud', 'dir', 'dryrun',
                       'filename', 'force', 'format', 'name', 'nopass',
                       'output', 'pub', 'pwd', 'set_path', 'source')

        variables = Variables()

        if arguments.list and arguments.source == "git":

            config = Config()
            username = config["cloudmesh.profile.github"]
            keys = SSHkey().get_from_git(username)

            print_keys(keys)

            return ""

        elif arguments.list and arguments.source == "ssh":
            # this is much simpler

            sshkey = SSHkey()

            print_keys([sshkey])

            return ""

        elif arguments.list and arguments.cloud:

            clouds = Parameter.expand(arguments.cloud)

            if len(clouds) == 0:
                variables = Variables()
                cloudname = variables['cloud']
                clouds = [cloudname]
            keys = []

            for cloud in clouds:
                print(f"cloud {cloud}")
                provider = Provider(name=cloud)
                keys = provider.keys()

                provider.Print(keys, output=arguments.output, kind="key")

            return ""

        elif arguments.list:

            cloud = "local"
            db = CmDatabase()
            keys = db.find(collection=f"{cloud}-key")

            print_keys(keys)

            return ""

        elif arguments.add:
            """
            key add [NAME] [--source=FILENAME] # NOT IMPLEMENTED YET
            key add [NAME] [--source=git]
            key add [NAME] [--source=ssh]
            """

            key = Key()

            if arguments["--source"] == "ssh":
                name = arguments.NAME or "ssh"
                key.add(name, "ssh")
            elif arguments["--source"] == "git":
                name = arguments.NAME or "git"
                key.add("git", "git")
            else:
                config = Config()
                name = config["cloudmesh.profile.user"]
                kind = "ssh"
                key.add(name, kind)

        elif arguments.init:
            """
            key init 
            """

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

            if username == "TBD":
                Console.error(
                    "Please set cloudmesh.profile.user in ~/.cloudmesh.yaml")
                u = os.environ["USER"].lower().replace(" ", "")
                Console.msg(
                    f"To change it you can use the command. Define a NAME such as '{u}' e.g."
                )
                Console.msg("")
                Console.msg(f"  cms config set cloudmesh.profile.user={u}")
                Console.msg("")
                return ""

            key = Key()

            key.add(username, "ssh")
            variables['key'] = username

        elif arguments.upload:
            """
            key upload [NAMES] [--cloud=CLOUDS] [--dryrun]
            key upload [NAMES] [VMS] [--dryrun]
            """

            names = Parameter.expand(arguments.NAMES)

            # this may have a bug if NAMES is ommitted

            #
            # Step 0. Set keyname to variable
            #

            if names is None or len(names) == 0:
                config = Config()
                username = config["cloudmesh.profile.user"]
                names = [username]

            if len(names) == 1:
                name = names[0]
                variables = Variables()
                if "key" in variables:
                    old = variables["key"]
                    if old != name:
                        Console.msg(
                            f"Changing default key from {old} to {name}")
                        variables["key"] = name

            #
            # Step 1. keys = find keys to upload
            #

            cloud = "local"
            db = CmDatabase()
            db_keys = db.find(collection=f"{cloud}-key")

            keys = []
            for key in db_keys:
                if key["name"] in names:
                    keys.append(key)

            if len(keys) == 0:
                Console.error(
                    f"No keys with the names {names} found in cloudmesh. \n"
                    "       Use the command 'key add' to add the key.")

            #
            # Step 2. iterate over the clouds to upload
            #

            clouds, vmnames = Arguments.get_cloud_and_names(
                "list", arguments, variables)

            for cloud in clouds:
                print(f"cloud {cloud}")
                provider = Provider(name=cloud)
                for key in db_keys:
                    name = key['name']
                    if name in names:
                        try:
                            r = provider.key_upload(key)
                            Console.ok(f"upload key '{name} successful'. ")
                        except ValueError as e:
                            Console.error(
                                f"key '{name} already exists in {cloud}.")

            return ""

        elif arguments.delete and arguments.cloud and arguments.NAMES:

            # key delete NAMES --cloud=CLOUDS [--dryrun]
            names = Parameter.expand(arguments.NAMES)
            clouds = Parameter.expand(arguments.cloud)

            for cloud in clouds:
                provider = Provider(name=cloud)
                for name in names:
                    if arguments.dryrun:
                        Console.ok(f"Dryrun: delete {name} in {cloud}")
                    else:
                        images = provider.key_delete(name)

            return ""

        elif arguments.gen:
            """
            key gen (ssh | pem) [--filename=FILENAME] [--nopass] [--set_path]
                    [--force]
            Generate an RSA key pair with pem or ssh encoding for the public
            key. The private key is always encoded as a PEM file.
            """
            config = Config()

            # Check if password will be requested
            ap = not arguments.nopass

            if not ap:
                Console.warning("Private key will NOT have a password")
                cnt = yn_choice(message="Continue, despite risk?", default="N")
                if not cnt:
                    sys.exit()

            # Discern the name of the public and private keys
            rk_path = None
            uk_path = None
            if arguments.filename:
                fp = path_expand(arguments.filename)
                fname, fext = os.path.splitext(fp)
                if fext == ".pub" or fext == ".ssh":
                    rk_path = fname
                    uk_path = fp
                elif fext == ".priv" or fext == ".pem":
                    rk_path = fp
                    uk_path = fname + ".pub"
                else:
                    rk_path = fp
                    uk_path = rk_path + ".pub"
            else:
                rk_path = path_expand("~/.ssh/id_rsa")
                uk_path = rk_path + ".pub"

            # Check if the file exist, if so confirm overwrite
            def check_exists(path):
                if os.path.exists(path):
                    Console.info(f"{path} already exists")
                    ovwr_r = yn_choice(message=f"overwrite {path}?",
                                       default="N")
                    if not ovwr_r:
                        Console.info(f"Not overwriting {path}. Quitting")
                        sys.exit()

            if not arguments.force:
                check_exists(rk_path)
                check_exists(uk_path)

            # Set the path if requested
            if arguments.set_path:
                config['cloudmesh.security.privatekey'] = rk_path
                config['cloudmesh.security.publickey'] = uk_path
                config.save()

            Console.msg(f"\nPrivate key: {rk_path}")
            Console.msg(f"Public  key: {uk_path}\n")

            # Generate the Private and Public keys
            kh = KeyHandler()
            r = kh.new_rsa_key()
            u = kh.get_pub_key(priv=r)

            # Serialize and write the private key to the path
            sr = kh.serialize_key(key=r,
                                  key_type="PRIV",
                                  encoding="PEM",
                                  format="PKCS8",
                                  ask_pass=ap)

            # Force write the key (since we check file existence above)
            kh.write_key(key=sr, path=rk_path, force=True)

            # Determine the public key format and encoding
            enc = None
            forma = None
            if arguments.ssh:
                enc = "SSH"
                forma = "SSH"
            elif arguments.pem:
                enc = "PEM"
                forma = "SubjectInfo"

            # Serialize and write the public key to the path
            su = kh.serialize_key(key=u,
                                  key_type="PUB",
                                  encoding=enc,
                                  format=forma,
                                  ask_pass=False)

            # Force write the key (since we check file existence above)
            kh.write_key(key=su, path=uk_path, force=True)

            Console.ok("Success")

        elif arguments.verify:
            """
            key verify (ssh | pem) [--filename=FILENAME] [--pub] [--check_pass]
            Verifies the encoding (pem or ssh) of the key (private or public)
            """
            # Initialize variables
            kh = KeyHandler()

            # Determine filepath
            fp = None
            if arguments.filename is None:
                config = Config()
                kp = path_expand("~/.ssh/id_rsa")
                if arguments.pub:
                    fp = kp + ".pub"
                else:
                    fp = kp
            else:
                fp = arguments.filename

            # Discern key type
            kt = enc = None
            ap = True
            if arguments.pub:
                # Load the public key, if no error occurs formatting is correct
                kt, kta, ap = "public", "PUB", False
                # Discern public key encoding
                if arguments.ssh:
                    enc, e = "OpenSSH", "SSH"
                elif arguments.pem:  # PEM encoding
                    enc = e = "PEM"
            else:
                # Load the private key to verify the format and password of the
                # key file. If no error occurs the format and pwd are correct
                kt, kta = "private", "PRIV"
                enc = e = "PEM"
                ap = False
                if arguments.check_pass:
                    ap = True

            try:
                k = kh.load_key(path=fp, key_type=kta, encoding=e, ask_pass=ap)
                m = f"Success the {kt} key {fp} has proper {enc} format"
                Console.ok(m)
            except ValueError as e:
                # The formatting was incorrect
                m = f"Failure, {kt} key {fp} does not have proper {enc} format"
                Console.error(m)
                raise e
            except TypeError as e:
                # Success, we didn't ask the user for the key password and
                # we received an error for not entering the password, thus
                # the key is password protectd
                if not arguments.check_pass:
                    Console.ok("The key is password protected")
                else:
                    # Error Message handled in kh.load_key()
                    raise e

        elif arguments.reformat:
            """
            key reformat (ssh | pem) [--filename=FILENAME] [--format=FORMAT]
                                      [--nopass] [--pub]
            Restructures a key's format, encoding, and password
            """

            # Initialize variables
            kh = KeyHandler()

            # Determine key type
            fname, fext = os.path.splitext(arguments.filename)
            kt = "PRIV"
            if arguments.pub or fext == ".pub":
                kt = "PUB"

            # Determine new encoding
            use_pem = True
            if arguments.ssh:
                use_pem = False

            kh.reformat_key(path=arguments.filename,
                            key_type=kt,
                            use_pem=use_pem,
                            new_format=arguments.format,
                            ask_pass=not arguments.nopass)

        elif arguments.delete and arguments.NAMES:
            # key delete NAMES [--dryrun]

            names = Parameter.expand(arguments.NAMES)

            cloud = "local"
            db = CmDatabase()
            db_keys = db.find(collection=f"{cloud}-key")

            error = []
            for key in db_keys:
                name = key['name']
                if name in names:
                    if arguments.dryrun:
                        Console.ok(f"Dryrun: delete {name}")
                    else:
                        db.delete(collection="local-key", name=name)
                        Console.ok(f"delete {name}")
            return ""

        elif arguments.group:

            raise NotImplementedError

        return ""
コード例 #13
0
    def do_config(self, args, arguments):
        """
        ::

           Usage:
             config  -h | --help
             config cat [less]
             config check
             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]
             config security add (--secret=REGEXP | --exception=REGEXP )
             config security rmv (--secret=REGEXP | --exception=REGEXP )
             config security list


           Arguments:
             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:
              --name=KEYNAME        The name of a key
              --nopass              Indicates if private key is password protected
              --output=OUTPUT       The output format [default: yaml]

           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

             Setting configuration


                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",
                       "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).splitlines()
            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.splitlines()

            counter = 1
            for line in lines:
                if arguments.less:
                    if counter % (rows - 2) == 0:
                        x = input()
                        if x != '' and 'q' in x.lower():
                            return ""
                print(line)
                counter += 1

            return ""

        elif arguments.check:

            Config.check()

        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.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 ""
コード例 #14
0
ファイル: config.py プロジェクト: nayeembaig/cloudmesh-cloud
    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 ""
コード例 #15
0
    def do_admin(self, args, arguments):
        """
        ::

          Usage:
            admin mongo install [--brew] [--download=PATH] [--nosudo] [--docker] [--dryrun] [--force]
            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 [--output=OUTPUT]
            admin mongo ssh
            admin mongo mode [MODE]
            admin status
            admin system info

          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/cloudmesh.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.

              The command

                cms admin mongo ssh

              is only supported for docker and allows for debugging to login
              to the running container. This function may be disabled in future.


            admin mongo mode native
               switches configuration file to use native mode

            admin mongo mode running
                switches the configuration to use running mode

        """

        map_parameters(arguments, "output", "nosudo", "docker", "dryrun",
                       "force")
        arguments.output = arguments.output or "table"

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

        if arguments.mongo:

            if arguments.install and arguments.docker:

                installer = MongoInstaller(dryrun=arguments.dryrun,
                                           force=arguments.force)
                r = installer.docker()
                return r

            elif arguments.install:

                print("MongoDB install")
                print(79 * "=")
                # print(arguments.force)
                installer = MongoInstaller(dryrun=arguments.dryrun,
                                           force=arguments.force)

                sudo = not arguments.nosudo
                # if 'linux' in platform.lower() :
                #     print("SUDO:", sudo)
                # r = installer.install(sudo=sudo)
                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.ssh:

                print("MongoDB ssh")
                MongoDBController().ssh()

            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:
                    if arguments.output == 'table':
                        print(
                            Printer.dict(r,
                                         order=[
                                             "name", "sizeOnDisk", "empty",
                                             "collections"
                                         ],
                                         output=arguments.output), )
                    else:
                        print(Printer.write(r, output=arguments.output))
                    Console.ok("ok")
                else:
                    Console.ok("is your MongoDB server running")

            elif arguments.mode:

                if arguments.MODE:

                    if arguments.MODE not in ["native", "running", "docker"]:
                        Console.error("The mode is not supported")
                    config = Config()
                    config["cloudmesh.data.mongo.MODE"] = arguments.MODE
                    config.save()

                else:
                    config = Config()
                    mode = config["cloudmesh.data.mongo.MODE"]
                    print(mode)
                    return ""

        elif arguments.status:

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

            print("Rest Service status")

            print("MongoDB status")

            try:
                mongo = MongoDBController()
                mongo.login()
                if mongo.status()['status'] == 'ok':
                    Console.ok("Mongo is running")
            except Exception as e:
                Console.error("Mongo is not running")
                print(e)

        elif arguments.system:

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

        return result
コード例 #16
0
 def add_user(cls, user, password):
     config = Config()
     config[cls.CONFIG_ATTRIBUTE_AUTH] = cls.CONFIG_VALUE_AUTH
     config[cls.CONFIG_ATTRIBUTE_USER] = user
     config[cls.CONFIG_ATTRIBUTE_PASSWORD] = cls._encode(password)
     config.save()