Exemplo n.º 1
0
class DatabaseImportAsJson:
    """
    Updating the database using MongoImport.

    expects a dictionary with the following format:

    { 'db': Name of the database (cloudmesh by default),
      'collection': Name of the collection to be saved in the db,
      'data' : DATA}

    The data should be an array of dict.
    """

    # noinspection PyUnusedLocal
    def __init__(self, **kwargs):
        self.database = CmDatabase()

    def __call__(self, f):
        def wrapper(*args, **kwargs):
            current = f(*args, **kwargs)
            if type(current) == dict:
                db = current['db'] if current['db'] is not None else 'cloudmesh'
                collection = current['collection']
                data = current['data']

            if current is None or type(current) != dict:
                return []

            result = self.database.importAsFile(data, collection, db)
            self.database.close_client()
            return result

        return wrapper
Exemplo n.º 2
0
 def get_last_volume():
     cm = CmDatabase()
     cloud = arguments['--cloud'] or variables["cloud"]
     #how to get updated cloud names? or only search the last volume in --cloud?
     last_entry = cm.find(cloud=cloud, kind='volume')[-1]
     cm.close_client()
     for tag in last_entry['Tags']:
         if tag['key'] == 'Name':
             name = tag['Value']
         else:
             raise ("Please name the volume!")
     return name
Exemplo n.º 3
0
    def ssh(self, vm=None, command=None):
        #
        # TODO: fix user name issue, should be stored in db
        #

        # VERBOSE(vm)

        ip = vm['ip_public']
        key_name = vm['key_name']
        image = vm['metadata']['image']
        user = Image.guess_username(image)

        cm = CmDatabase()

        keys = cm.find_all_by_name(name=key_name, kind="key")
        for k in keys:
            if 'location' in k.keys():
                if 'private' in k['location'].keys():
                    key = k['location']['private']
                    break

        cm.close_client()

        if command is None:
            command = ""

        if user is None:
            location = ip
        else:
            location = user + '@' + ip
        cmd = "ssh " \
              "-o StrictHostKeyChecking=no " \
              "-o UserKnownHostsFile=/dev/null " \
              f"-i {key} {location} {command}"
        cmd = cmd.strip()
        # VERBOSE(cmd)

        if command == "":
            if platform.lower() == 'win32':
                class disable_file_system_redirection:
                    _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
                    _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection

                    def __enter__(self):
                        self.old_value = ctypes.c_long()
                        self.success = self._disable(ctypes.byref(self.old_value))

                    def __exit__(self, type, value, traceback):
                        if self.success:
                            self._revert(self.old_value)
                with disable_file_system_redirection():
                    os.system(cmd)
            else:
                os.system(cmd)
        else:
            if platform.lower() == 'win32':
                class disable_file_system_redirection:
                    _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
                    _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection

                    def __enter__(self):
                        self.old_value = ctypes.c_long()
                        self.success = self._disable(ctypes.byref(self.old_value))

                    def __exit__(self, type, value, traceback):
                        if self.success:
                            self._revert(self.old_value)
                with disable_file_system_redirection():
                    ssh = subprocess.Popen(cmd,
                                           shell=True,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
            else:
                ssh = subprocess.Popen(cmd,
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            result = ssh.stdout.read().decode("utf-8")
            if not result:
                error = ssh.stderr.readlines()
                print("ERROR: %s" % error)
            else:
                return result
Exemplo n.º 4
0
    def create(self, **kwargs):

        arguments = dotdict(kwargs)
        name = arguments.name
        cloud = arguments.cloud

        if name is None:
            name_generator = Name()
            vms = [str(name_generator)]
        else:
            vms = self.expand(name)

        #
        # Step 0, find the cloud
        #
        variables = Variables()
        if cloud is None:
            arguments.cloud = cloud = variables['cloud']

        # Step 1. iterate through the names to see if they already exist in
        # the DB and fail if one of them already exists

        database = CmDatabase()
        defaults = Config()[f"cloudmesh.cloud.{cloud}.default"]

        duplicates = []
        for vm in vms:
            query = {"name": vm}
            duplicates += database.find(collection=f'{cloud}-node', query=query)
        database.close_client()

        if len(duplicates) > 0:
            print(Printer.flatwrite(duplicates,
                                    order=['cm.name', 'cm.cloud'],
                                    header=['Name', 'Cloud'],
                                    output='table'))
            raise Exception("these vms already exists")

        # Step 2. identify the image and flavor from kwargs and if they do
        # not exist read them for that cloud from the yaml file

        if arguments.image is None:
            arguments.image = self.find_attribute('image', [variables, defaults])

        if arguments.image is None:
            raise ValueError("image not specified")

        if arguments.group is None:
            arguments.group = self.find_attribute('group', [variables, defaults])

        if arguments.group is None:
            arguments.group = "default"

        if arguments.size is None:
            arguments.size = self.find_attribute('size', [variables, defaults])

        if arguments.size is None:
            raise ValueError("size not specified")

        # Step 3: use the create command to create the vms

        # created = self.loop(vms, self.p.create, **arguments)
        arguments['name'] = vms

        created = self.loop(self._create, **arguments)

        VERBOSE(created)

        self.list()

        return created
Exemplo n.º 5
0
class DatabaseUpdate:
    """
    The data base decorator automatically replaces an entry in the database with
    the dictionary returned by a function.

    It is added to a MongoDB collection. The location is determined from the
    values in the dictionary.

    The name of the collection is determined from cloud and kind:

       cloud-kind

    In addition each entry in the collection has a name that must be unique in
    that collection.

    In most examples it is pest to separate the upload from the actual return
    class. This way we essentially provide two functions one that provide the
    dict and another that is responsible for the upload to the database.

    Example:

    cloudmesh.example.foo contains:

        class Provider(object)

            def entries(self):
                return {
                   "cm": {
                     "cloud": "foo",
                     "kind"": "entries",
                     "name": "test01"
                     "test": "hello"}
                   }
                   "cloud": "foo",
                   "kind"": "entries",
                   "name": "test01"
                   "test": "hello"}


    cloudmesh.example.bar contains:

        class Provider(object)

            def entries(self):
                return {
                   "cloud": "bar",
                   "kind"": "entries",
                   "name": "test01"
                   "test": "hello"}

    cloudmesh.example.provider.foo:

        from cloudmesh.example.foo import Provider as FooProvider
        from cloudmesh.example.foo import Provider as BarProvider

        class Provider(object)

            def __init__(self, provider):
               if provider == "foo":
                  provider = FooProvider()
               elif provider == "bar":
                  provider = BarProvider()

            @DatabaseUpdate
            def entries(self):
                provider.entries()


    Separating the database and the dictionary creation allows the developer to
    implement different providers but only use one class with the same methods
    to interact for all providers with the database.

    In the combined provider a find function to for example search for entries
    by name across collections could be implemented.

    """

    # noinspection PyUnusedLocal
    def __init__(self, **kwargs):
        self.database = CmDatabase()

    def __call__(self, f):
        def wrapper(*args, **kwargs):
            current = f(*args, **kwargs)
            if type(current) == dict:
                current = [current]

            if current is None:
                return []

            result = self.database.update(current)
            self.database.close_client()
            return result

        return wrapper