def update(self, kinds, clouds): """ GREGOR WORKS ON THIS updates the data in the database :param kind: vm, image, flavor :param cloud: name of the cloud :return: """ if type(kinds) == str: kinds = Parameter.expand(kinds) if type(clouds) == str: clouds = Parameter.expand(clouds) for cloud in clouds: cloudname = cloud.lower() cloud = OpenStack_libcloud(cloud, cm_user=self.cm_user) for k in kinds: kind = k.lower() results = cloud.list(kind, output="flat") for element in results: result = results[element] result["cm_id"] = self.getID(kind, str(result["id"]), cloudname) result["cm_type"] = kind self.update_from_dict(result) self.save() '''
def list(self, kind, cloud=None, output=None): """ :param kind: :param cloud: :return: """ if cloud is None: # find all clouds clouds = ["india"] else: clouds = Parameter.expand(cloud) if type(kind) == str: table = database.get_table(kind) else: table = kind result = {} if cloud is None: result = self.session.query(table).all() result = self.object_to_dict(result) else: # TODO for cloud in clouds: result[cloud] = self.session.query(table).filter_by(cloud=cloud).all() result[cloud] = self.object_to_dict(result[cloud]) return result
def do_search(cls, table, order, filter): c = cm() if filter: for i in range(len(filter)): regex = re.compile("(!=|>=|<=|=|>|<)", re.I) sep = regex.search(filter[i]).groups() if sep: separator = sep[0] else: Console.error("Please specify a valid filter") return split = filter[i].split(separator) if '[' in filter[i]: parameters = Parameter.expand(split[1]) parameters = ['{} = \'{}\''.format(split[0], parameters[j]) for j in range(len(parameters))] parameters = """ OR """.join(parameters) where = '( {} )'.format(parameters) filter[i] = where else: where = '{} {} \'{}\''.format(split[0], separator, split[1]) filter[i] = where where = """ AND """.join(filter) where = ' WHERE {}'.format(where) else: where = "" _table = table.upper() sql = text(""" SELECT * FROM {}{}""".format(_table, where)) try: if table == 'vm' or table == 'flavor' or table == 'image': model = globals()[_table] r = c.session.query(model).from_statement(sql).all() else: Console.error("Please specify a valid table") return except Exception: Console.error("Please specify a valid search") return if r: print "{} TABLE".format(_table) result = c.object_to_dict(r) if order: _order = order.split(',') else: _order = None output = models.dict_printer(result, order=_order, header=None, output="table", sort_keys=True) print(output) else: print("Nothing found")
def test_011(self): """011: hostlist""" HEADING() from cloudmesh_base.hostlist import Parameter parameter = "india[01-03]" result = Parameter.expand(parameter) print (result) assert str(result) == "['india01', 'india02', 'india03']"
def delete(self, ids): """ delete the vms Example: delete("gregor-[001-010]") :param ids: host ids specified in hostlist format :return: """ names = Parameter.expand(ids) for name in names: print("delete", name)
def info(self, what=None, kind=None): """ prints information about the database """ count_result = {} if kind is None: kinds = "VM,FLAVOR,IMAGE,DEFAULT" else: kinds = Parameter.expand(kind) if what is None: infos = "table,count" else: infos = Parameter.expand(what) banner("Databse table information", c="-") inspector = inspect(self.db.engine) if "table" in infos: for table_name in inspector.get_table_names(): if table_name.upper() in kinds: print(table_name + ":") for column in inspector.get_columns(table_name): print(" ", column['name'], column['type']) sum = 0 if "count" in infos: for table in [VM, FLAVOR, IMAGE, DEFAULT]: rows = self.session.query(table).count() name = str(table.name).replace(".name", "") count_result[name] = rows if name in kinds: print("Count {:}: {:}".format(name, rows)) sum = sum + rows count_result['sum'] = sum return count_result
def info(self, what=None, kind=None): """ prints information about the database """ count_result = {} if kind is None: kinds = tablenames() else: kinds = Parameter.expand(kind) if what is None: infos = "table,count" else: infos = Parameter.expand(what) banner("Databse table information", c="-") inspector = inspect(self.db.engine) if "table" in infos: for table_name in inspector.get_table_names(): if table_name in kinds: print(table_name + ":") for column in inspector.get_columns(table_name): print(" ", column["name"], column["type"]) counter = 0 if "count" in infos: for table_name in inspector.get_table_names(): if table_name in kinds: t = table(table_name) rows = self.session.query(t).count() count_result[table_name] = rows print("Count {:}: {:}".format(table_name, rows)) counter = counter + rows count_result["sum"] = counter return count_result
def update(self, clouds, cloudobject): """ :param clouds: cloudnames from which the update is called either as Parameter string or list :type clouds: Parameter of cloud names :param cloudobject: vm, images, or flavors specified in as Parameter string or list :type cloudobject: Parameter of CloudObjects :return: """ kinds = Parameter.expand(cloudobject) for kind in kinds: if kind == "vm": pass elif kind == "flavor": pass elif kind == "image": pass
def do_search(cls, table, order, filter): c = cm() if filter: for i in range(len(filter)): regex = re.compile("(!=|>=|<=|=|>|<)", re.I) sep = regex.search(filter[i]).groups() if sep: separator = sep[0] else: Console.error("Please specify a valid filter") return split = filter[i].split(separator) if '[' in filter[i]: parameters = Parameter.expand(split[1]) parameters = [ '{} = \'{}\''.format(split[0], parameters[j]) for j in range(len(parameters)) ] parameters = """ OR """.join(parameters) where = '( {} )'.format(parameters) filter[i] = where else: where = '{} {} \'{}\''.format(split[0], separator, split[1]) filter[i] = where where = """ AND """.join(filter) where = ' WHERE {}'.format(where) else: where = "" _table = table.upper() sql = text(""" SELECT * FROM {}{}""".format(_table, where)) try: if table == 'vm' or table == 'flavor' or table == 'image': model = globals()[_table] r = c.session.query(model).from_statement(sql).all() else: Console.error("Please specify a valid table") return except Exception: Console.error("Please specify a valid search") return if r: print "{} TABLE".format(_table) result = c.object_to_dict(r) if order: _order = order.split(',') else: _order = None output = models.dict_printer(result, order=_order, header=None, output="table", sort_keys=True) print(output) else: print("Nothing found")
def delete(self, names): result = Parameter.expand(names) for name in result: self.delete_by_name(name)
def do_inventory(self, args, arguments): """ :: Usage: inventory add NAMES [--label=LABEL] [--service=SERVICES] [--project=PROJECT] [--owners=OWNERS] [--comment=COMMENT] [--cluster=CLUSTER] [--ip=IP] inventory set NAMES for ATTRIBUTE to VALUES inventory delete NAMES inventory clone NAMES from SOURCE inventory list [NAMES] [--format=FORMAT] [--columns=COLUMNS] inventory info Arguments: NAMES Name of the resources (example i[10-20]) FORMAT The format of the output is either txt, yaml, dict, table [default: table]. OWNERS a comma separated list of owners for this resource LABEL a unique label for this resource SERVICE a string that identifies the service PROJECT a string that identifies the project SOURCE a single host name to clone from COMMENT a comment Options: -v verbose mode Description: add -- adds a resource to the resource inventory list -- lists the resources in the given format delete -- deletes objects from the table clone -- copies the content of an existing object and creates new once with it set -- sets for the specified objects the attribute to the given value or values. If multiple values are used the values are assigned to the and objects in order. See examples map -- allows to set attibutes on a set of objects with a set of values Examples: cm inventory add x[0-3] --service=openstack adds hosts x0, x1, x2, x3 and puts the string openstack into the service column cm lists lists the repository cm x[3-4] set temperature to 32 sets for the resources x3, x4 the value of the temperature to 32 cm x[7-8] set ip 128.0.0.[0-1] sets the value of x7 to 128.0.0.0 sets the value of x8 to 128.0.0.1 cm clone x[5-6] from x3 clones the values for x5, x6 from x3 """ print(arguments) filename = config_file("/cloudmesh_inventory.yaml") sorted_keys = True if arguments["info"]: i = Inventory() i.read() i.info() elif arguments["list"]: i = Inventory() i.read() if arguments["--columns"]: order = arguments["--columns"].split(",") else: order = i.order print(i.list(format="table", order=order)) elif arguments["NAMES"] is None: Console.error("Please specify a host name") # elif arguments["set"]: # hosts = Parameter.expand_hostlist(arguments["NAMES"]) # i = inventory() # i.read() # element = {} # for attribute in i.order: # try: # attribute = arguments["ATTRIBUTE"] # value = arguments["VALUE"] # if value is not None: # element[attribute] = value # except: # pass # element['host'] = arguments["NAMES"] # i.add(**element) # print (i.list(format="table")) elif arguments["set"]: hosts = Parameter.expand(arguments["NAMES"]) values = Parameter.expand(arguments["VALUES"]) if len(values) == 1: values *= len(hosts) print(hosts) print(values) attribute = arguments["ATTRIBUTE"] if len(hosts) != len(values): Console.error( "Number of names {:} != number of values{:}".format( len(hosts), len(values))) i = Inventory() i.read() for index in range(0, len(hosts)): host = hosts[index] value = values[index] host_object = {'host': host, attribute: value} i.add(**host_object) print(i.list(format="table")) elif arguments["add"]: hosts = Parameter.expand(arguments["NAMES"]) i = Inventory() i.read() element = {} for attribute in i.order: try: value = arguments["--" + attribute] if value is not None: element[attribute] = value except: pass element['host'] = arguments["NAMES"] i.add(**element) print(i.list(format="table")) elif arguments["delete"]: hosts = Parameter.expand(arguments["NAMES"]) i = Inventory() i.read() for host in hosts: del i.data[host] i.save() elif arguments["clone"]: hosts = Parameter.expand(arguments["NAMES"]) source = arguments["SOURCE"] i = Inventory() i.read() if source in i.data: for host in hosts: i.data[host] = dict(i.data[source]) i.save() else: Console.error("The source {:} does not exist".format(source)) return ""
def do_cluster(self, args, arguments): """ :: Usage: cluster info [--user=USER] [--project=PROJECT] cluster list [--name=NAMES] [--user=USER] [--project=PROJECT] [--hosts=HOSTS] [--start=TIME_START] [--end=TIME_END] [--hosts=HOSTS] [--format=FORMAT] [ID] cluster start ID cluster stop ID cluster power (on|off) CLUSTERID COMPUTEIDS cluster delete [all] [--user=USER] [--project=PROJECT] [--name=NAMES] [--hosts=HOSTS] [--start=TIME_START] [--end=TIME_END] [--host=HOST] cluster delete --file=FILE cluster update [--name=NAMES] [--hosts=HOSTS] [--start=TIME_START] [--end=TIME_END] cluster add [--user=USER] [--project=PROJECT] [--host=HOST] [--description=DESCRIPTION] [--start=TIME_START] [--end=TIME_END] NAME cluster add --file=FILE Options: --user=USER user name --name=NAMES Names of the vcluster --start=TIME_START Start time of the vcluster, in YYYY/MM/DD HH:MM:SS format. [default: 1901-01-01] --end=TIME_END End time of the vcluster, in YYYY/MM/DD HH:MM:SS format. In addition a duratio can be specified if the + sign is the first sig The duration will than be added to the start time. [default: 2100-12-31] --project=PROJECT project id --host=HOST host name --description=DESCRIPTION description summary of the vcluster --file=FILE Adding multiple vclusters from one file --format=FORMAT Format is either table, json, yaml or csv [default: table] Description: vcluster info lists the resources that support vcluster for a given user or project. """ print(arguments) if arguments["list"]: id = arguments["ID"] Cluster.list(id) elif arguments["add"]: print ("add the cluster") elif arguments["start"]: id = arguments["ID"] print("start", id) Cluster.start(id) elif arguments["stop"]: id = arguments["ID"] print("stop", id) Cluster.stop(id) elif arguments["power"]: clusterid = arguments["CLUSTERID"] computeids = Parameter.expand(arguments["COMPUTEIDS"]) if arguments["on"]: on = True Cluster.power(clusterid, computeids, on)
def power(clusterid, subject, param=None, action=None): # print("SUBJECT to perform action on: {}".format(subject)) # print("\ton cluster: {}".format(clusterid)) # print("\tAction: {}".format(action)) # print("\tParameter: {}".format(param)) # the API is now accepting hostlist format directly # computeIdsHostlist = hostlist.collect_hostlist(computeids) # print (computeIdsHostlist) ret = '' if 'HOSTS' == subject: url = Comet.url("computeset/") # data = { # "computes": [{"name": vm, "host": "comet-{:}".format(vm)} for vm in # computeids], "cluster": "%s" % id} data = {"computes": "%s" % param, "cluster": "%s" % clusterid, "walltime_mins": "%s" % Cluster.WALLTIME_MINS} # print (data) if "on" == action: # print("Issuing request to poweron nodes...") posturl = url # print (data) r = Comet.post(posturl, data=data) # print("RETURNED RESULTS:") # print (r) if 'cluster' in r: if 'state' in r and \ ('queued' == r['state'] or 'submitted' == r['state']): computesetid = r['id'] ret = 'Request accepted! Check status with:\n' \ 'comet cluster {}\n'.format(clusterid) + \ 'or:\n' \ 'comet computeset {}\n'.format(computesetid) else: # in case of some internal problem ret = '' elif 'error' in r: ret = "An error occurred: {}".format(r['error']) else: ret = "An internal error occured. " \ "Please submit a ticket with following info:\n {}\n" \ .format(r) # print(ret) elif action in ["off", "reboot", "reset", "shutdown"]: if action in ["off"]: action = "power{}".format(action) # print("finding the computesetid of the specified nodes...") computesets = Comet.get_computeset() # print ("computesets") # pprint (computesets) is_valid_set = False # computesetid = -1 for computeset in computesets: if computeset["cluster"] == clusterid \ and (computeset["state"] == "started" \ or computeset["state"] == "running"): computesetid = computeset["id"] # print (computesetid) hosts = set() for compute in computeset["computes"]: hosts.add(compute["name"]) # print (hosts) is_valid_set = True hostsparam = Parameter.expand(param) for host in hostsparam: if host not in hosts: is_valid_set = False break # a cluster could have multiple 'started' set if is_valid_set: break if is_valid_set: # print("Issuing request to poweroff nodes...") # print("computesetid: {}".format(computesetid)) puturl = "{:}{:}/{}".format(url, computesetid, action) # print (puturl) r = Comet.put(puturl) # print("RETURNED RESULTS:") # print(r) if r is not None: if '' != r.strip(): ret = r # print(r) else: ret = "Requeset Accepted. "\ "In the process of {} the nodes".format(action) else: ret = "Unknown error: POWER, HOSTS" else: ret = "All the nodes are not in the specified cluster, "\ "or they are not running" else: ret = "Action not supported! Try these: on/off/reboot/reset/shutdown" elif 'FE' == subject: url = Comet.url("cluster/{}/frontend/".format(clusterid)) if action in ["on", "off", "reboot", "reset", "shutdown"]: if action in ["on", "off"]: action = "power{}".format(action) puturl = "{}{}".format(url, action) # print (puturl) r = Comet.put(puturl) if r is not None: if '' != r.strip(): ret = r else: ret = "Requeset Accepted. "\ "In the process of {} the nodes".format(action) else: ret = "Problem executing the request. "\ "Check if the cluster exists" else: ret = "Action not supported! Try these: on/off/reboot/reset/shutdown" elif 'COMPUTESET' == subject: url = Comet.url("computeset/") if 'on' == action: ret = "NOT SUPPORTED! Use hostslist to specify the hosts to power on!" elif action in ["off", "reboot", "reset", "shutdown"]: if action in ["off"]: action = "power{}".format(action) puturl = "{:}{:}/{}".format(url, param, action) # print (puturl) r = Comet.put(puturl) if r is not None: if '' != r.strip(): ret = r else: ret = "Requeset Accepted. "\ "In the process of {} the nodes".format(action) else: ret = "Problem executing the request. "\ "Check if the computeset exists" else: ret = "Action not supported! Try these: on/off/reboot/reset/shutdown" elif 'HOST' == subject: url = Comet.url("cluster/{}/compute/{}/".format(clusterid, param)) if action in ["on", "off", "reboot", "reset", "shutdown"]: if action in ["on", "off"]: action = "power{}".format(action) puturl = "{}{}".format(url, action) # print (puturl) r = Comet.put(puturl) if r is not None: if '' != r.strip(): ret = r else: ret = "Requeset Accepted. "\ "In the process of {} the nodes".format(action) else: ret = "Problem executing the request. "\ "Check if the node belongs to the cluster" else: ret = "Action not supported! Try these: on/off/reboot/reset/shutdown" return ret