def do_exec(self, filename): """ :: Usage: exec FILENAME executes the commands in the file. See also the script command. Arguments: FILENAME The name of the file """ if not filename: Console.error("the command requires a filename as parameter") return if os.path.exists(filename): with open(filename, "r") as f: for line in f: if self.context.echo: Console.ok("cm> {:}".format(str(line))) self.precmd(line) stop = self.onecmd(line) self.postcmd(stop, line) else: Console.error('file "{:}" does not exist.'.format(filename)) sys.exit()
def list(cls, name, live=False, format="table"): """ This method lists all workflows of the cloud :param cloud: the cloud name """ # Console.TODO("this method is not yet implemented") # return try: elements = cls.cm.find(kind="workflow", category='general') # pprint(elements) # (order, header) = CloudProvider(cloud).get_attributes("workflow") order = None header= None # Console.msg(elements) return Printer.write(elements, order=order, header=header, output=format) except Exception as ex: Console.error(ex.message)
def table(cls, provider=None, kind=None, name=None): """ :param category: :param kind: :return: the table class based on a given table name. In case the table does not exist an exception is thrown """ t = None if name is not None: for t in cls.tables: if t.__tablename__ == name: return t if provider is None and kind is not None: t = cls.get_table_from_kind(kind) return t if provider is None and kind is None: Console.error("No Kind specified") return None for t in cls.tables: if t.__kind__ == kind and t.__provider__ == provider: return t Console.error("No table found for name={}, provider={}, kind={}".format(name, provider, kind))
def var_replacer(self, line, c='$'): vars = self.var_finder(line, c=c) for v in vars["normal"]: value = str(Var.get(v)) line = line.replace(c + v, value) # replace in line the variable $v with value for v in vars["os"]: name = v.replace('os.', '') if name in os.environ: value = os.environ[name] line = line.replace(c + v, value) else: Console.error("can not find environment variable {}".format( v)) if c + v in line: value = os.environ(v) # replace in line the variable $v with value for v in vars["dot"]: try: config = ConfigDict("cloudmesh.yaml") print(config["cloudmesh.profile"]) value = config[v] line = line.replace(c + v, value) except Exception as e: Console.error("can not find variable {} in cloudmesh.yaml".format(value)) return line
def __repr__(self): try: return ("<{}> id={} name={} category={}: dict={}".format(self.kind, self.cm_id, self.name, self.category, self.__dict__)) except: Console.error("could not print object") return None
def list_floating_ip(cls, cloudname): """ Method to list floating ips :param cloudname: :return: floating ip list """ try: floating_ips = cls.get_floating_ip_list(cloudname) for floating_ip in floating_ips.values(): # Get instance_id associated with instance instance_id = floating_ip["instance_id"] if instance_id is not None: try: instance_name = cls.find_instance_name(cloudname=cloudname, instance_id=instance_id) # Assign it to the dict floating_ip["instance_name"] = instance_name except Exception as ex: Console.error(ex.message) continue else: # If no instance associated, keep None floating_ip["instance_name"] = None (order, header) = CloudProvider(cloudname).get_attributes("floating_ip") return dict_printer(floating_ips, order=order, header=header) except Exception as ex: Console.error(ex.message, ex) return
def list(cls, **kwargs): """ This method lists all VMs of the cloud :param cloud: the cloud name """ try: if "name_or_id" in kwargs and kwargs["name_or_id"] is not None: if cls.isUuid(kwargs["name_or_id"]): elements = cls.cm.find("vm", cloud=kwargs["cloud"], uuid=kwargs["name_or_id"]) else: elements = cls.cm.find("vm", cloud=kwargs["cloud"], label=kwargs["name_or_id"]) else: elements = cls.cm.find("vm", cloud=kwargs["cloud"]) # print(elements) # order = ['id', 'uuid', 'name', 'cloud'] (order, header) = CloudProvider(kwargs["cloud"]).get_attributes("vm") # order = None if "name_or_id" in kwargs and kwargs["name_or_id"] is not None: return attribute_printer(elements.values()[0], output=kwargs["output_format"]) else: return dict_printer(elements, order=order, output=kwargs["output_format"]) except Exception as ex: Console.error(ex.message, ex)
def kill_tunnel(): pid = Comet.find_tunnel() if pid is None: Console.error("No tunnel to comet found") else: Console.ok("Killing the tunnel to comet") os.kill(pid, signal.SIGTERM)
def do_quota(self, args, arguments): """ :: Usage: quota list [--cloud=CLOUD] [--tenant=TENANT] [--format=FORMAT] Prints quota limit on a current project/tenant Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --tenant=TENANT the tenant id Examples: cm quota list cm quota list --cloud=india --format=csv """ if arguments["list"]: cloud = arguments["--cloud"] or Default.get_cloud() if not cloud: Console.error("Default cloud doesn't exist") return tenant = arguments["--tenant"] output_format = arguments["--format"] list_quotas = Quota.list(cloud, tenant, output=output_format) Console.msg(list_quotas) return
def check_yaml_for_completeness(cls, filename): """ outputs how many values has to be fixed in cloudmesh.yaml file :param filename: the file name :type filename: string :return: """ if filename is None: filename = "cloudmesh.yaml" config = ConfigDict(filename) content = config.yaml Console.ok("Checking the yaml file") count = 0 output = [] for line in content.split("\n"): if "TBD" in line: output.append(textwrap.dedent(line)) count += 1 if count > 0: Console.error("The file has {:} values to be fixed".format(count)) print("") for line in output: Console.error(" " + line, prefix=False)
def get(cls, name=None, cloud="general"): """ This method queries the database to fetch secgroup with given name filtered by cloud. :param name: :param cloud: :return: """ try: args = { "name": name, 'scope': 'fisrt', 'kind': "secgroup", "output": "object", } if cloud is not None and cloud is not 'general': args["category"] = cloud secgroup = cls.cm.find(**args) if secgroup is None: return None else: return secgroup[0] except Exception as ex: Console.error("get secgroup") return None
def delete_rule(cls, cloud, secgroup, from_port, to_port, protocol, cidr): try: args = { "group": secgroup["uuid"], "fromPort": from_port, "toPort": to_port, "protocol": protocol, "cidr": cidr } rule = cls.cm.find(kind="secgrouprule", output="object", scope="first", **args) if rule is not None: # get the nova client for cloud cloud_provider = CloudProvider(cloud).provider # delete the rule from the cloud cloud_provider.delete_secgroup_rule(rule.uuid) # delete the local db record cls.cm.delete(rule) return "Rule [{fromPort} | {toPort} | {protocol} | {cidr}] deleted" \ .format(**args) else: return None except Exception as ex: Console.error("delete rule") return
def vm_groups(vm): """ :param vm: name of the vm :return: a list of groups the vm is in """ try: query = { 'kind': "group", 'provider': 'general', "species": "vm", "member": vm, "scope": 'all', "output": 'dict' } d = cls.cm.find(**query) groups_vm = set() if d is not None and len(d) > 0: for vm in d: groups_vm.add(vm['name']) return list(groups_vm) except Exception as ex: Console.error(ex.message) return []
def list(cls, cloud=None, names=None, output='table', live=False): try: if live: cls.refresh(cloud) elements = cls.cm.find(kind="vm", category=cloud) result = [] if "all" in names: for element in elements: result.append(element) elif names is not None: for element in elements: if element["name"] in names: result.append(element) (order, header) = CloudProvider(cloud).get_attributes("ip") return Printer.write(result, order=order, header=header, output=output) except Exception as ex: Console.error(ex.message)
def do_verbose(self, args, arguments): """ Usage: verbose (True | False) verbose NOTE: NOT YET IMPLEMENTED. If it sets to True, a command will be printed before execution. In the interactive mode, you may want to set it to False. When you use scripts, we recommend to set it to True. The default is set to False If verbose is specified without parameter the flag is toggled. """ # if args == '': # self.echo = not self.echo # else: # self.echo = arguments['True'] Console.error("verbose NOT YET IMPLEMENTED") return ""
def get_apikey(endpoint): config = ConfigDict("cloudmesh.yaml") cometConf = config["cloudmesh.comet"] defaultUser = cometConf["username"] user = input("Comet Nucleus Usename [%s]: " \ % defaultUser) if not user: user = defaultUser password = getpass.getpass() keyurl = "%s/getkey" % cometConf["endpoints"][endpoint]["nucleus_base_url"] headers = {"ACCEPT": "application/json"} r = requests.get(keyurl, headers=headers, auth=HTTPBasicAuth(user, password)) if r.status_code == 200: keyobj = r.json() api_key = keyobj["key_name"] api_secret = keyobj["key"] config = ConfigDict("cloudmesh.yaml") config.data["cloudmesh"]["comet"]["endpoints"]\ [endpoint]["auth_provider"] = 'apikey' config.data["cloudmesh"]["comet"]["endpoints"]\ [endpoint]["apikey"]["api_key"] = api_key config.data["cloudmesh"]["comet"]["endpoints"]\ [endpoint]["apikey"]["api_secret"] = api_secret config.save() Console.ok("api key retrieval and set was successful!") else: Console.error("Error getting api key. " \ "Please check your username/password", traceflag=False)
def get_vms(cls, name): """ returns a list of vms within this group :param name: :return: """ try: query = { "species": "vm", "scope": "all", "category": "general", "kind": "group" } if name is not None: query["name"] = name d = cls.cm.find(**query) if d is None: return None names = set() for vm in d: names.add(vm['member']) return list(names) except Exception as ex: Console.error(ex.message)
def set(cls, key, value, category='general', user=None, type='str'): """ sets the default value for a given category :param key: the dictionary key of the value to store it at. :param value: the value :param user: the username to store this default value at. :return: """ try: o = cls.get(name=key, category=category) if o is not None: cls.cm.update(kind=cls.__kind__, provider=cls.__provider__, filter={'name': key}, update={'value': value, 'type': type, 'user': user, 'category': category}) else: t = cls.cm.table(provider=cls.__provider__, kind=cls.__kind__) o = t(name=key, value=value, type=type, user=user, category=category) cls.cm.add(o) cls.cm.save() except Exception as e: Console.error("problem setting key value {}={}".format(key, value), traceflag=False)
def do_check(self, args, arguments): """ :: Usage: check --cloud=CLOUD check checks some elementary setting for cloudmesh Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name Examples: cm check cm check --cloud=kilo """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") print(locals()) Console.ok("{:} ok".format(cloud)) return ""
def remove(cls, name, member): """ Method to remove an ID from the group in the cloudmesh database :param name: :param id: :param category: :return: """ try: # group = cls.get(name=name, category=category) args = { "name": name, "category": "general", "member": member, } # Find an existing group with name & category group = cls.cm.find(kind="group", scope='all', output="dict", **args) print ("YYYY", group, args) if group is not None: for element in group: print("ELEMENT", element) cls.cm.delete(**element) return "Removed {} from the group {}. ok.".format(member, name) except Exception as ex: Console.error(ex.message) return None
def details(self, kind, cloud, id, format="table"): from cloudmesh_client.db.CloudmeshDatabase import CloudmeshDatabase try: cm = CloudmeshDatabase() if kind not in self.kind: raise ValueError('{} not defined'.format(kind)) elements = None for idkey in ["name", "uuid", "id"]: s = {idkey: id} try: elements = cm.find(kind, cloud=cloud, **s) except: pass if len(elements) > 0: break if len(elements) == 0: return None if format == "table": element = elements.values()[0] return attribute_printer(element) else: return dict_printer(elements, output=format) except Exception as ex: Console.error(ex.message, ex)
def list(cls, project, cloud="general"): """ This method queries the database to fetch list of secgroups filtered by cloud, tenant. :param project: :param cloud: :return: """ # noinspection PyUnreachableCode try: """ elements = cls.cm_db.query(model.SECGROUP).filter( model.SECGROUP.cloud == cloud, model.SECGROUP.project == project ).all() d = cls.toDict(elements) """ nova_client = CloudProvider.set(cloud) os_result = nova_client.security_groups.list() d = SecGroup.convert_list_to_dict(os_result) return dict_printer(d, order=["Id", "Name", "Description"], output="table") except Exception as ex: Console.error(ex.message, ex)
def delete_secgroup(cls, label, cloud, tenant): try: # Find the secgroup from the cloud nova_client = CloudProvider.set(cloud) sec_group = nova_client.security_groups.find(name=label) if not sec_group: return None # delete the secgroup in the cloud nova_client.security_groups.delete(sec_group) # perform local db deletion sec_group = cls.get(label, tenant, cloud) if sec_group: # Delete all rules for group cls.delete_all_rules(sec_group) cls.cm_db.delete(sec_group) return "Security Group [{}] for cloud [{}], & tenant [{}] deleted".format(label, cloud, tenant) else: return None except Exception as ex: Console.error(ex.message, ex) return
def do_cloud(self, args, arguments): """ :: Usage: cloud list [--cloud=CLOUD] [--format=FORMAT] cloud activate CLOUD cloud deactivate CLOUD cloud info CLOUD managing the admins test test test test Arguments: KEY the name of the admin VALUE the value to set the key to Options: --cloud=CLOUD the name of the cloud [default: general] --format=FORMAT the output format [default: table] Description: Cloudmesh contains a cloudmesh.yaml file that contains templates for multiple clouds that you may or may not have access to. Hence it is useful to activate and deacivate clouds you like to use in other commands. To activate a cloud a user can simply use the activate command followed by the name of the cloud to be activated. To find out which clouds are available you can use the list command that will provide you with some basic information. As default it will print a table. Thus the commands:: cloud activate india cloud deactivate aws Will result in +----------------------+--------+-------------------+ | Cloud name | Active | Type | +----------------------+--------+-------------------+ | india | True | Openstack | +----------------------+--------+-------------------+ | aws | False | AWS | +----------------------+--------+-------------------+ To get ore information about the cloud you can use the command cloud info CLOUD It will call internally also the command uses in register See also: register """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() output_format = arguments["--format"] Console.error("TODO: Command not yet implemented.") pass
def get_info(cls, cloud="kilo", name=None, output="table"): """ Method to get info about a group :param cloud: :param name: :param output: :return: """ try: cloud = cloud or Default.get("cloud") args = { "name": name, "cloud": cloud } # group = cls.get(name=name, cloud=cloud) group = cls.cm.find("group", output="object", **args).first() if group is not None: d = cls.to_dict(group) # Transform the dict to show multiple rows per vm newdict = Group.transform_dict(d) else: return None return dict_printer(newdict, order=cls.order, output=output) except Exception as ex: Console.error(ex.message, ex)
def do_who(self, args, arguments): """ :: Usage: who hostname """ try: logon = who.logon() if logon is False: Console.error("Could not logon") return except: Console.error("Could not logon") # pprint (arguments) output_format = arguments["--format"] or "table" if arguments["status"]: pass ValueError("NOT yet implemented") return ""
def get(cls, **kwargs): """ This method queries the database to fetch group(s) with given name filtered by cloud. :param name: :param cloud: :return: """ query = dict(kwargs) if 'output' in kwargs: for key, value in kwargs.iteritems(): if value is None: query[key] = "None" del query['output'] try: group = cls.cm.find_by_name("group", **query) if group is not None \ and "output" in kwargs: d = {"0": group} group = dict_printer(d) return group except Exception as ex: Console.error(ex.message, ex)
def do_open(self, args, arguments): """ :: Usage: open FILENAME ARGUMENTS: FILENAME the file to open in the cwd if . is specified. If file in in cwd you must specify it with ./FILENAME Opens the given URL in a browser window. """ filename = arguments['FILENAME'] filename = self._expand_filename(filename) Console.ok("open {0}".format(filename)) if not (filename.startswith("file:") or filename.startswith("http:")): try: with open(filename): pass filename += "file://" except: Console.error( "unsupported browser format in file {0}".format(filename)) return "" try: webbrowser.open("%s" % filename) except: Console.error( "can not open browser with file {0}".format(filename))
def entry(cls, name): banner("Register {}".format(name)) name = str(name) etc_config = ConfigDict("cloudmesh.yaml", etc=True) config = ConfigDict("cloudmesh.yaml") clouds = config["cloudmesh.clouds"] clusters = config["cloudmesh.hpc.clusters"] if name in clouds: name = "cloudmesh.clouds.{}.credentials".format(name) elif name in clusters: name = "cloudmesh.hpc.clusters.{}.credentials".format(name) elif not name.startswith("cloudmesh."): name = "cloudmesh." + name try: etc = etc_config[name] yaml = config[name] # walk yaml for key in etc: if etc[key] == "TBD": result = input("Enter {:} ({:}): ".format(key, yaml[key])) if result != '': yaml[key] = result config.save() except Exception as e: Console.error("Could not find {} in the yaml file".format(name), traceflag=False)
def do_reset(self, args, arguments): """ :: Usage: reset Description: DANGER: This method erases the database. Examples: clean """ filename = path_expand("~/.cloudmesh/cloudmesh.db") if os.path.exists(filename): os.remove(filename) Console.ok("Database reset") r = self.do_quit(None) Console.error( "Quitting the shell does not yet work. please exit the shell now.") return ""
def create_assign_floating_ip(cls, cloudname, instance_name): """ Method to create a new floating-ip and associate it with the instance :param cloudname: cloud :param instance_name: name of instance :return: floating_ip """ try: cloud_provider = CloudProvider(cloudname).provider floating_ip = cloud_provider.create_assign_floating_ip( instance_name) return floating_ip except Exception as ex: Console.error(ex.message, ex) return
def construct_ip_dict(cls, ip_addr, name=None): # TODO kilo cloud as defualt should be avoided if name is None: Console.error("cloud name not set") return None try: d = ConfigDict("cloudmesh.yaml") cloud_details = d["cloudmesh"]["clouds"][name] # Handle Openstack Specific Output if cloud_details["cm_type"] == "openstack": ipaddr = {} for network in ip_addr: index = 0 for ip in ip_addr[network]: ipaddr[index] = {} ipaddr[index]["network"] = network ipaddr[index]["version"] = ip["version"] ipaddr[index]["addr"] = ip["addr"] index += 1 return ipaddr # Handle EC2 Specific Output if cloud_details["cm_type"] == "ec2": # Console.TODO("ec2 ip dict yet to be implemented") # TODO.implement() # :type str: ip_addr index = 0 ipaddr = {} ipaddr[index] = {} ipaddr[index]['addr'] = ip_addr return ipaddr # Handle Azure Specific Output if cloud_details["cm_type"] == "azure": index = 0 ipaddr = {} for ip in ip_addr: ipaddr[index] = {} ipaddr[index]["network"] = ip ipaddr[index]["version"] = 'ipv4' ipaddr[index]["addr"] = ip index += 1 return ipaddr except Exception as e: Console.error("error in vm construct dict %s" % e, traceflag=True)
def delete_all_rules(cls, secgroup): try: args = {"groupid": secgroup.uuid} rules = cls.cm_db.find("secgrouprule", output="object", **args) if rules is not None: for rule in rules: cls.cm_db.delete(rule) Console.ok("Rule [{} | {} | {} | {}] deleted".format( rule.fromPort, rule.toPort, rule.protocol, rule.cidr)) else: pass except Exception as ex: Console.error(ex.message, ex) return
def list(cls, kind, cloud, user=None, tenant=None, order=None, header=None, output="table"): """ Method lists the data in the db for given cloud and of given kind :param kind: :param cloud: :param tenant: :param user: :param order: :param header: :param output: :return: """ try: # get the model object table = cls.cm.get_table(kind) filter = {} if cloud is not None: filter["category"] = cloud if user is not None: filter["user"] = user if tenant is not None: filter["tenant"] = tenant elements = cls.cm.find(table, **filter) if elements is not None or elements is not {}: # convert the output to a dict return (Printer.write(elements, order=order, header=header, output=output)) else: return None except Exception as ex: Console.error(ex.message)
def rename(cls, **kwargs): arg = dotdict(kwargs) cloud_provider = CloudProvider(kwargs["cloud"]).provider # Check for vms with duplicate names in DB. vms = cls.get_vms_by_name(name=arg.oldname, cloud=arg.cloud) if len(vms) > 1: users_choice = "y" if not arg.force: print("More than 1 vms found with the same name as {}.".format( server)) users_choice = input( "Would you like to auto-order the new names? (y/n): ") if users_choice.strip() == "y": count = 1 for index in vms: count_new_name = "{0}{1}".format(arg.newname, count) # print(vms[index]) cloud_provider.rename_vm(vms[index]["uuid"], count_new_name) print( "Machine {0} with UUID {1} renamed to {2} on {3} cloud" .format(vms[index]["name"], vms[index]["uuid"], count_new_name, cloud_provider.cloud)) count += 1 elif users_choice.strip() == "n": cloud_provider.rename_vm(arg.oldname, arg.newname) print("Machine {0} renamed to {1} on {2} Cloud...".format( arg.oldname, arg.newname, cloud_provider.cloud)) else: Console.error("Invalid Choice.") return else: cloud_provider.rename_vm(arg.oldname, arg.newname) print("Machine {0} renamed to {1} on {2} Cloud...".format( arg.oldname, arg.newname, cloud_provider.cloud)) # Explicit refresh called after VM rename, to update db. cls.refresh(cloud=arg.cloud)
def copy(commands): if vm.ip is not None: if arg.verbose: Console.info("Connecting to Instance at IP:" + format(vm.ip)) sshcommand = "scp" sshcommand += " -o StrictHostKeyChecking=no" sshcommand += " {username}@{ip}".format(**vm) sshcommand += ":{:}".format(commands) print(sshcommand) os.system(sshcommand) else: Console.error( "No Public IPs found for the instance", traceflag=False)
def info(self): banner("Configuration") Console.ok('Object Attibutes: {:}'.format(', '.join(self.order))) Console.ok('Objects: {:}'.format(len(self.data))) Console.ok('Configuration File: {:}'.format(self.config_filename)) Console.ok('Configuration:') print(self.config) try: config = ConfigDict(filename=self.config_filename) except Exception as e: Console.error("Problem reading the yaml file {:}".format( self.config_filename)) Console.error("Please check if the file exists or is empty") print(e) banner("")
def push(from_path, vm): vm.ip = vm.floating_ip if vm.ip is not None: if arg.verbose: Console.info("Connecting to Instance at IP:" + format(vm.ip)) sshcommand = "scp" sshcommand += " -o StrictHostKeyChecking=no" sshcommand += " {:}".format(from_path) sshcommand += " {username}@{ip}:.ssh/authorized_keys".format( **vm) print(sshcommand) os.system(sshcommand) else: Console.error("No Public IPs found for the instance", traceflag=False)
def clear(self, kind, category): """ This method deletes all 'kind' entries from the cloudmesh database :param category: the category name """ try: elements = self.find(kind, output='object', scope="all", category=category) # pprint(elements) for element in elements: # pprint(element) self.delete(element) except Exception as ex: Console.error(ex.message, ex)
def get_fixed_ip(cls, cloudname, fixed_ip_addr, output='table'): """ Method retrieves fixed ip info :param cloudname: :param fixed_ip_addr: :return: fixed_ip_info """ try: cloud_provider = CloudProvider(cloudname).provider result = cloud_provider.get_fixed_ip(fixed_ip_addr=fixed_ip_addr) return Printer.attribute(result, header=["name", "value"], output=output) except Exception as ex: Console.error(ex.message) return
def get(url, headers=None, allow_redirects=True, data=None, authuser=None, authpass=None): try: return Comet.http(url, action="get", headers=headers, data=data, authuser=authuser, authpass=authpass, allow_redirects=allow_redirects) except ConnectionError: Console.error("Error connecting to the Comet nucleus service", traceflag=False) return None
def delete_all_rules(cls, secgroup): try: args = {"group": secgroup["uuid"]} rules = cls.cm.find(kind="secgrouprule", output="object", **args) if rules is not None: for rule in rules: cls.cm.delete(rule) Console.ok( "Rule [{fromPort} | {toPort} | {protocol} | {cidr}] deleted" .format(**rule)) else: pass except Exception as ex: Console.error("delete all rules") return
def _assign_floating_ip(cls, cloudname, instance_id, floating_ip): # find instance in db instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error( "Instance {} not found in the cloudmesh database!".format( instance_id)) return "" instance_name = instance_dict["name"] result = Network.associate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Associated Floating IP {} to instance {}.".format( floating_ip, instance_name))
def list_floating_ip_pool(cls, cloudname): """ Method to list floating ip pool :param cloudname: :return: """ try: cloud_provider = CloudProvider(cloudname).provider floating_ip_pools = cloud_provider.list_floating_ip_pools() (order, header ) = CloudProvider(cloudname).get_attributes("floating_ip_pool") return Printer.write(floating_ip_pools, order=order, header=header) except Exception as ex: Console.error(ex.message) pass
def all(cls, provider='general', category=None, kind=None, table=None): t = table data = { "provider": provider, "kind": kind, } if provider is not None and kind is not None: t = cls.table(provider=provider, kind=kind) elif provider is None and kind is not None: t = cls.table(kind=kind) else: Console.error( "find is improperly used provider={provider} kind={kind}". format(**data)) result = cls.session.query(t).all() return cls.to_list(result)
def disassociate_floating_ip(cls, cloudname, instance_name, floating_ip): """ Disassociates a floating ip from an instance :param cloudname: :param instance_name: :param floating_ip: :return: """ try: cloud_provider = CloudProvider(cloudname).provider # Find the server instance server = cloud_provider.provider.servers.find(name=instance_name) # Add the floating ip to the instance server.remove_floating_ip(floating_ip) return "Success." except Exception as ex: Console.error(ex.message, ex) return pass
def list(cls, cloud, format="table"): """ This method lists all images of the cloud :param cloud: the cloud name """ # TODO: make a CloudmeshDatabase without requiring the user= try: elements = cls.cm.find(kind="image", category=cloud, scope="all") (order, header) = CloudProvider(cloud).get_attributes("image") return Printer.write(elements, order=order, header=header, output=format) except Exception as ex: Console.error(ex.message)
def list(cls, cloud="general", format="table"): """ This method queries the database to fetch list of secgroups filtered by cloud. :param cloud: :return: """ try: elements = cls.cm_db.find("secgroup", category=cloud) #pprint(elements) (order, header) = CloudProvider(cloud).get_attributes("secgroup") return dict_printer(elements, order=order, header=header, output=format) except Exception as ex: Console.error(ex.message, ex)
def get_from_git(cls, username, store=True): """ :param username: the github username :return: an array of public keys :rtype: list """ uri = 'https://github.com/{:}.keys'.format(username) content = requests.get(uri).text.strip("\n").split("\n") d = [] for key in range(0, len(content)): value = content[key] thekey = {} name = "{}_git_{}".format(username, key) thekey = { 'uri': uri, 'string': value, 'fingerprint': SSHkey._fingerprint(value), 'name': name, 'comment': name, 'cm_id': name, 'source': 'git', 'kind': 'key' } thekey["type"], thekey["key"], thekey["comment"] = SSHkey._parse( value) if thekey["comment"] is None: thekey["comment"] = name d.append(thekey) if store: try: cls.cm.add(thekey) except: Console.error("Key already in db", traceflag=False) if not store: return d
def get(cls, name, cloud="general"): """ This method queries the database to fetch secgroup with given name filtered by cloud. :param name: :param cloud: :return: """ try: args = { "name": name, "category": cloud, } secgroup = cls.cm_db.find("secgroup", output="object", **args).first() return secgroup except Exception as ex: Console.error(ex.message, ex)
def enable_ssh(self, cloud, secgroup_name='default'): if cloud == "aws": params = { 'Action': 'AuthorizeSecurityGroupIngress', 'GroupName': secgroup_name, 'IpProtocol': 'tcp', 'FromPort': '22', 'ToPort': '22', 'CidrIp': '0.0.0.0/0' } try: self.provider.connection.request(self.provider.path, params=params).object Console.info("Permission added.ok") except Exception as e: if e.args[0].find("InvalidPermission.Duplicate") == -1: Console.info("Permission already exists.ok") else: Console.error("Enable SSH not implemented for others")
def do_load(self, args, arguments): """ :: Usage: load MODULE [PYPI] ARGUMENTS: MODULE The name of the module PREDEFINED MODULE NAMES: vbox loads vbox command Examples: cm load cloudmesh_vagrant.cm_vbox.do_vbox lists the plugins currently loaded """ arg = dotdict(arguments) # importlib.import_module('matplotlib.text') plugins = ConfigDict(filename="cloudmesh.yaml") if arg.MODULE == "vbox": arg.MODULE = "cloudmesh_vagrant.cm_vbox.do_vbox" arg.PYPI = "cloudmesh_vagrant" if arg.PYPI is not None: try: import cloudmesh_vagrant except: os.system("pip install cloudmesh_vagrant") try: print("LOADING ->", arg.MODULE) self.load_instancemethod(arg.MODULE) except: Console.error("Problem loading module {}".format(arg.MODULE), traceflag=True) return ""
def list(cls, name=None, order=None, header=None, output='table'): """ lists the default values in the specified format. TODO: This method has a bug as it uses format and output, only one should be used. :param category: the category of the default value. If general is used it is a special category that is used for global values. :param format: json, table, yaml, dict, csv :param order: The order in which the attributes are returned :param output: The output format. :return: """ if order is None: order, header = None, None # order = ['user', # 'category', # 'name', # 'value', # 'updated_at'] # order, header = Attributes(cls.__kind__, provider=cls.__provider__) try: query = { "provider": cls.__provider__, "kind": cls.__kind__, "category": 'general' } result = None if name is not None: query["name"] = name result = cls.cm.find(**query) if result is None: table = None else: table = Printer.write(result, output='table') return table except Exception as e: Console.error("Error creating list", traceflag=False) Console.error(e.message) return None
def initialize(self, cloudname, user=None): Console.info("Initializing libcloud-ec2 for " + cloudname) cls = get_driver(Provider.EC2) d = ConfigDict("cloudmesh.yaml") self.config = d["cloudmesh"]["clouds"][cloudname] credentials = self.config["credentials"] cm_type = self.config["cm_type"] ec2_access_key = credentials['EC2_ACCESS_KEY'] ec2_secret_key = credentials['EC2_SECRET_KEY'] if not cloudname == "aws": auth_url = credentials["EC2_URL"] searchobj = re.match(r'^http[s]?://(.+):([0-9]+)/([a-zA-Z/]*)', auth_url, re.M | re.I) path = None host = None port = None if searchobj: host = searchobj.group(1) port = searchobj.group(2) path = searchobj.group(3) Console.info("url : " + searchobj.group()) Console.info("host: " + host) Console.info("port: " + port) Console.info("path: " + path) extra_args = {'path': path} else: Console.error("Authentication url incorrect: {}".format(auth_url)) self.provider = cls(ec2_access_key, ec2_secret_key, host=host, port=port, **extra_args) else: Console.info("AWS INIT") self.provider = cls(ec2_access_key, ec2_secret_key)
def add(cls, name=None, species="vm", member=None, category=None): """ Add an instance to a new group or add it to an existing one :param name: :param species: :param member: :param cloud: :return: """ # user logged into cloudmesh #user = ConfigDict.getUser(category) or cls.cm.user user = cls.cm.user category = category or "general" try: # See if group already exists. If yes, add id to the group data = dotdict({ 'member': member, 'name': name, 'kind': 'group', 'provider': 'general' }) group = cls.cm.find(**data) if group is None: t = cls.cm.table(provider="general", kind="group") group = t(name=name, member=member, category="general", user=user, species=species) cls.cm.add(group, replace=False) return except Exception as ex: Console.error(ex.message) return
def test_002(self): HEADING("VM DB test") self.cm.clean() print("ADD TO OS ") d = { 'user': "******", 'category': self.data.cloud } for index in range(1, 6): name = "vm_" + str(index).zfill(3) banner(name) print("ADD", name) try: d['name'] = name d['uuid'] = "uuid_" + str(index) vm = VM_OPENSTACK(**d) pprint(vm.__dict__) except Exception as e: Console.error("issue adding vm", traceflag=True) self.cm.add(vm) print("VM added. ok") print("ADD TO LIBCLOUD ") for index in range(6, 11): name = "vm_" + str(index).zfill(3) banner(name) print("ADD", name) d['name'] = name d['uuid'] = "uuid_" + str(index) vm = VM_LIBCLOUD(**d) print("VM", vm.__dict__) self.cm.add(vm) self.cm.save() result = self.run("cm refresh off") print(result) vms = self.cm.find(kind="vm", scope="all", output='dict') pprint(vms) print (len(vms)) assert len(vms) == 10
def post(url, headers=None, data=None, md5=None, files=None, cacert=True, allow_redirects=True): try: return Comet.http(url, action="post", headers=headers, data=data, files=files, md5=md5, cacert=cacert, allow_redirects=allow_redirects) except ConnectionError: Console.error("Error connecting to the Comet nucleus service", traceflag=False) return None
def list_on_cloud(cls, cloud, live=False, format="table"): """ This method lists all flavors of the cloud :param cloud: the cloud name """ try: keys = CloudProvider(cloud).provider.list_key(cloud) for key in keys: keys[key]["category"] = cloud if keys is None or keys is []: return None (order, header) = CloudProvider(cloud).get_attributes("key") return Printer.write(keys, order=order, header=header, output=format) except Exception as ex: Console.error(ex.message)
def delete_vm(self, name, group=None, force=None): """ Delete a VM instance whose instance name is given by name :param name: :param group: :param force: :return: """ Console.info("Delete VM for " + name) nodes_list = self.provider.list_nodes() node_obj = None for node in nodes_list: if node.name == name: node_obj = node break if node_obj is not None: self.provider.destroy_node(node_obj) Console.info("VM delete success.ok.") else: Console.error("No valid node found with the name " + name)
def nodes(self, cluster=None): """Retrieve the nodes of a cluster If no cluster is specified, use the currently active cluster. :param Cluster cluster: the cluster (default: currently active) :returns: a list of instances :rtype: a VM instance """ try: name = cluster or Default.cluster cluster = Cluster.from_name(name) return cluster.list() except: Console.error( 'Cluster {} is active. Did you forget to allocate?'.format( name)) return []