def cloudmesh_cloud(request, cloud=None): if cloud is None: cloud = Default.get_cloud() config = ConfigDict(filename="cloudmesh.yaml") cloud_config = dict(config["cloudmesh.clouds"][cloud]) active = cloud in config["cloudmesh.active"] default = Default.get_cloud() if 'OS_PASSWORD' in cloud_config['credentials']: cloud_config['credentials']['OS_PASSWORD'] = '******' context = { 'data': cloud_config, 'title': "Cloud {cm_heading}".format(**cloud_config), } return render(request, 'cloudmesh_portal/cm/cloud_table.jinja', context)
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 cloudmesh_refresh(request, action=None, cloud=None): if action is None: action = ['image', 'flavor', 'vm'] else: action = [action] if cloud is None: cloud = Default.get_cloud() # TODO: should actually be all active clouds data = Vm.list(cloud=cloud, output_format='dict') print json.dumps(data, indent=4) order = ['id', 'uuid', 'label', 'status', 'static_ip', 'floating_ip', 'key_name', 'project', 'user', 'cloud'] return dict_table(request, title="Cloudmesh VMs {}".format(cloud), data=data, order=order)
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 do_limits(self, args, arguments): """ :: Usage: limits list [--cloud=CLOUD] [--tenant=TENANT] [--format=FORMAT] Current list data with limits on a selected project/tenant. The --tenant option can be used by admin only Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --tenant=TENANT the tenant name Examples: cm limits list cm limits list --cloud=kilo --format=csv """ if arguments["list"]: cloud = arguments["--cloud"] or Default.get_cloud() if not cloud: Console.error("cloud doesn't exist") return "" output_format = arguments["--format"] tenant = arguments["--tenant"] result = Limits.list(cloud, output=output_format, tenant=tenant) Console.msg(result) return ""
def do_image(self, args, arguments): """ :: Usage: image refresh [--cloud=CLOUD] image list [ID] [--cloud=CLOUD] [--format=FORMAT] [--refresh] This lists out the images present for a cloud Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --refresh live data taken from the cloud Examples: cm image refresh cm image list cm image list --format=csv cm image list 58c9552c-8d93-42c0-9dea-5f48d90a3188 --refresh """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") return if arguments["refresh"] or Default.refresh(): msg = "Refresh image for cloud {:}.".format(cloud) if Image.refresh(cloud): Console.ok("{:} ok.".format(msg)) else: Console.error("{:} failed.".format(msg)) return "" if arguments["list"]: id = arguments['ID'] live = arguments['--refresh'] output_format = arguments["--format"] counter = 0 result = None while counter < 2: if id is None: result = Image.list(cloud, output_format) else: result = Image.details(cloud, id, live, output_format) if counter == 0 and result is None: if not Image.refresh(cloud): msg = "Refresh image for cloud {:}.".format(cloud) Console.error("{:} failed.".format(msg)) counter += 1 if result is None: Console.error("No image(s) found. Failed.") else: print(result) return ""
def do_loglevel(self, args, arguments): """ :: Usage: loglevel set MODE [--cloud=CLOUD] loglevel get [--cloud=CLOUD] loglevel save [--cloud=CLOUD] Arguments: MODE log level mode [DEBUG/INFO/WARNING/CRITICAL/ERROR] Options: --cloud=CLOUD the name of the cloud Description: loglevel command sets the default logging level for a cloud. Examples: loglevel set DEBUG --cloud=kilo sets the default log level to DEBUG for kilo. loglevel get --cloud=kilo retreives the default log level for kilo cloud. loglevel save --cloud=kilo saves the log level preference to the db & yaml file. """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() LOGGER.info("Cloud: " + cloud + ", Arguments: " + str(arguments)) if arguments["set"]: try: log_level = arguments["MODE"] response = LogUtil.set_level(log_level=log_level, cloudname=cloud) if response is not None: Console.ok(response) except Exception as ex: Console.error(ex.message, ex) elif arguments["get"]: try: log_level = LogUtil.get_level(cloudname=cloud) Console.ok("Current Log Level = " + log_level + ". Ok.") except Exception as ex: Console.error(ex.message, ex) elif arguments["save"]: LogUtil.save(cloudname=cloud) pass
def test_002(self): """ set default cloud :return: """ HEADING() result = Default.list() print(result) name = "mycloud" Default.set_cloud(name) result = Default.list() print(result) print("KKK", Default.get_cloud()) assert Default.get_cloud() == name self._check(name)
def cloudmesh_clouds(request): config = ConfigDict(filename="cloudmesh.yaml") clouds = config["cloudmesh.clouds"] active = config["cloudmesh.active"] default = Default.get_cloud() data = {} attributes = [ 'cm_label', 'cm_host', 'cm_heading', 'cm_type', 'cm_type_version' ] for cloud in clouds: name = {'cloud': cloud} data[cloud] = {} for attribute in attributes: data[cloud][attribute] = clouds[cloud][attribute] print clouds[cloud]['cm_type'] if clouds[cloud]['cm_type'] == "ec2": data[cloud]['username'] = clouds[cloud]['credentials']['userid'] elif clouds[cloud]['cm_type'] == "azure": data[cloud]['username'] = '******' elif clouds[cloud]['cm_type'] == "openstack": data[cloud]['username'] = clouds[cloud]['credentials'][ 'OS_USERNAME'] if cloud in active: data[cloud]['active'] = 'yes' else: data[cloud]['active'] = 'no' if cloud in [default]: data[cloud]['default'] = 'yes' else: data[cloud]['default'] = 'no' data[cloud]['info'] = ", ".join([ url('d', '/cm/cloud/{cloud}/'.format(**name)), url('i', '/cm/image/{cloud}/'.format(**name)), url('f', '/cm/flavor/{cloud}/'.format(**name)), url('v', '/cm/vm/{cloud}/'.format(**name)) ]) order = [ 'default', 'active', 'cm_label', 'info', 'username', 'cm_host', 'cm_heading', 'cm_type', 'cm_type_version' ] header = [ 'Default', 'Active', 'Label', 'Info', 'Username', 'Host', 'Description', 'Type', 'Version' ] pprint(data) context = { 'data': data, 'title': "Cloud List", 'order': order, 'header': header, } return render(request, 'cloudmesh_portal/dict_table.jinja', context)
def test_002(self): """ set default cloud :return: """ HEADING() result = Default.list() print(result) name = "mycloud" Default.set_cloud(name) result = Default.list() print(result) print ("KKK", Default.get_cloud()) assert Default.get_cloud() == name self._check(name)
def cloudmesh_vms(request, cloud=None): if cloud is None: cloud = Default.get_cloud() data = Vm.list(cloud=cloud, output_format='dict') print json.dumps(data, indent=4) order = [ 'id', 'uuid', 'label', 'status', 'static_ip', 'floating_ip', 'key_name', 'project', 'user', 'cloud' ] return dict_table(request, title="Cloudmesh VMs {}".format(cloud), data=data, order=order)
def cloudmesh_vms(request, cloud=None): if cloud is None: cloud = Default.get_cloud() data = Vm.list(cloud=cloud, output_format='dict') print json.dumps(data, indent=4) order = ['id', 'uuid', 'label', 'status', 'static_ip', 'floating_ip', 'key_name', 'project', 'user', 'cloud'] return dict_table(request, title="Cloudmesh VMs {}".format(cloud), data=data, order=order)
def cloudmesh_refresh(request, action=None, cloud=None): if action is None: action = ['image', 'flavor', 'vm'] else: action = [action] if cloud is None: cloud = Default.get_cloud() # TODO: should actually be all active clouds data = Vm.list(cloud=cloud, output_format='dict') print json.dumps(data, indent=4) order = [ 'id', 'uuid', 'label', 'status', 'static_ip', 'floating_ip', 'key_name', 'project', 'user', 'cloud' ] return dict_table(request, title="Cloudmesh VMs {}".format(cloud), data=data, order=order)
def cloudmesh_images(request, cloud=None): banner("images") if cloud is None: cloud = Default.get_cloud() # TODO: make the cloudname a parameter data = Image.list(cloud, format='dict') print json.dumps(data, indent=4) # TODO set proper columns order = [ 'id', 'name', 'cloud', 'minDisk', 'minRam', 'os_image_size', 'progress', 'project', 'status', ] return (dict_table(request, title="Cloudmesh Images {}".format(cloud), data=data, order=order))
def cloudmesh_flavors(request, cloud=None): if cloud is None: cloud = Default.get_cloud() data = Flavor.list(cloud, format='dict') print json.dumps(data, indent=4) order = [ 'id', 'name', 'cloud', 'disk', 'os_flavor_acces', 'os_flv_disabled', 'os_flv_ext_data', 'project', 'ram', 'rxtx_factor', 'swap', 'vcpus', ] return dict_table(request, title="Cloudmesh Flavors {}".format(cloud), data=data, order=order)
def do_key(self, args, arguments): """ :: Usage: key -h | --help key list [--source=db] [--format=FORMAT] key list --source=cloudmesh [--format=FORMAT] key list --source=ssh [--dir=DIR] [--format=FORMAT] key load [--format=FORMAT] key list --source=git [--format=FORMAT] [--username=USERNAME] key add --git [--name=KEYNAME] FILENAME key add --ssh [--name=KEYNAME] key add [--name=KEYNAME] FILENAME key get NAME key default [KEYNAME | --select] key delete (KEYNAME | --select | --all) [--force] key upload [KEYNAME] [--cloud=CLOUD] key map [--cloud=CLOUD] Manages the keys Arguments: SOURCE db, ssh, all KEYNAME The name of a key. For key upload it defaults to the default key name. FORMAT The format of the output (table, json, yaml) FILENAME The filename with full path in which the key is located NAME_ON_CLOUD Typically the name of the keypair on the cloud. Options: --dir=DIR the directory with keys [default: ~/.ssh] --format=FORMAT the format of the output [default: table] --source=SOURCE the source for the keys [default: db] --username=USERNAME the source for the keys [default: none] --name=KEYNAME The name of a key --all delete all keys --force delete the key form the cloud --name_on_cloud=NAME_ON_CLOUD Typically the name of the keypair on the cloud. Description: 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] [--format=FORMAT] lists all keys in the directory. If the directory is not specified the default will be ~/.ssh key list --source=cloudmesh [--dir=DIR] [--format=FORMAT] lists all keys in cloudmesh.yaml file in the specified directory. dir is by default ~/.cloudmesh key list [--format=FORMAT] list the keys in teh giiven format: json, yaml, table. table is default key list Prints list of keys. NAME of the key can be specified key add [--name=keyname] FILENAME adds the key specifid by the filename to the key database key get NAME Retrieves the key indicated by the NAME parameter from database and prints its fingerprint. key default [NAME] Used to set a key from the key-list as the default key if NAME is given. Otherwise print the current default key key delete NAME deletes a key. In yaml mode it can delete only key that are not saved in the database key rename NAME NEW renames the key from NAME to NEW. """ # pprint(arguments) def _print_dict(d, header=None, format='table'): if format == "json": return json.dumps(d, indent=4) elif format == "yaml": return yaml.dump(d, default_flow_style=False) elif format == "table": return dict_printer(d, order=["name", "comment", "uri", "fingerprint", "source"], output="table", sort_keys=True) else: return d # return dict_printer(d,order=['cm_id, name, fingerprint']) directory = Config.path_expand(arguments["--dir"]) if arguments['list']: _format = arguments['--format'] _source = arguments['--source'] _dir = arguments['--dir'] if arguments['--source'] == 'ssh': try: sshm = SSHKeyManager() sshm.get_from_dir(directory) d = dict(sshm.__keys__) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem listing keys from ssh") elif arguments['--source'] in ['cm', 'cloudmesh']: try: sshm = SSHKeyManager() m = sshm.get_from_yaml(load_order=directory) d = dict(m.__keys__) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem listing keys from `{:}`".format(arguments['--source'])) elif arguments['--source'] in ['git']: username = arguments["--username"] # print(username) if username == 'none': conf = ConfigDict("cloudmesh.yaml") username = conf["cloudmesh.github.username"] sshm = SSHKeyManager() try: sshm.get_from_git(username) d = dict(sshm.__keys__) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem listing git keys from database") return "" elif arguments['--source'] == 'db': try: sshdb = SSHKeyDBManager() d = sshdb.table_dict() if d != {}: print(_print_dict(d, format=arguments['--format'])) msg = "info. OK." Console.ok(msg) else: Console.error("No keys in the database") except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem listing keys from database") elif arguments['load']: _format = arguments['--format'] _dir = arguments['--dir'] try: sshm = SSHKeyManager() m = sshm.get_from_yaml(load_order=directory) d = dict(m.__keys__) sshdb = SSHKeyDBManager() for keyname in m.__keys__: filename = m[keyname]["path"] try: sshdb.add(filename, keyname, source="yaml", uri="file://" + filename) except Exception as e: Console.error("problem adding key {}:{}".format( keyname, filename)) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Console.error("Problem adding keys from yaml file") elif arguments['get']: try: name = arguments['NAME'] sshdb = SSHKeyDBManager() d = sshdb.table_dict() for i in d: if d[i]["name"] == name: key = d[i] print("{:}: {:}".format(key['name'], key['fingerprint'])) msg = "info. OK." Console.ok(msg) return "" else: pass Console.error("The key is not in the database") except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("The key is not in the database") # key add --git KEYNAME # key add --ssh KEYNAME # key add [--path=PATH] KEYNAME elif arguments['add'] and arguments["--git"]: print('git add') sshdb = SSHKeyDBManager() keyname = arguments['--name'] gitkeyname = arguments['NAME'] filename = arguments['FILENAME'] # Are we adding to the database as well? # sshdb.add(filename, keyname, source="ssh", uri="file://"+filename) username = arguments["--username"] if username == 'none': conf = ConfigDict("cloudmesh.yaml") username = conf["cloudmesh.github.username"] print(username) sshm = SSHKeyManager() try: sshm.get_from_git(username) d = dict(sshm.__keys__) print(d) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem adding keys to git for user: "******"" try: # FIXME: correct code to add to git d[gitkeyname]['keyname'] = keyname d[gitkeyname]['user'] = None d[gitkeyname]['source'] = 'git' # sshdb.add_from_dict(d[gitkeyname]) except Exception as e: Console.error("The key already exists") elif arguments['add'] and arguments["--ssh"]: # print('ssh add') sshdb = SSHKeyDBManager() keyname = arguments['--name'] filename = Config.path_expand("~/.ssh/id_rsa.pub") try: sshdb.add(filename, keyname, source="ssh", uri="file://" + filename) print("Key {:} successfully added to the database".format(keyname or "")) msg = "info. OK." Console.ok(msg) except Exception as e: """ import traceback print(traceback.format_exc()) print (e) print (keyname) print (filename) """ Console.error("Problem adding the key `{}` from file `{}`".format(keyname, filename)) elif arguments['add'] and not arguments["--git"]: # print('ssh add') sshdb = SSHKeyDBManager() keyname = arguments['--name'] filename = arguments['FILENAME'] try: sshdb.add(filename, keyname, source="ssh", uri="file://" + filename) print("Key {:} successfully added to the database".format(keyname or "")) msg = "info. OK." Console.ok(msg) except ValueError as e: Console.error("The key `{}` already exists".format(keyname), traceflag=False) """ except Exception as e: import traceback print(traceback.format_exc()) print (e) print (keyname) print (filename) Console.error("Problem adding the key `{}` from file `{}`".format(keyname, filename)) """ return "" elif arguments['default']: # print("default") if arguments['KEYNAME']: keyname = None try: keyname = arguments['KEYNAME'] sshdb = SSHKeyDBManager() sshdb.set_default(keyname) Default.set_key(keyname) print("Key {:} set as default".format(keyname)) msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Setting default for key {:} failed.".format(keyname)) elif arguments['--select']: keyname = None try: sshdb = SSHKeyDBManager() select = sshdb.select() if select != 'q': keyname = select.split(':')[0] print("Setting key: {:} as default.".format(keyname)) sshdb.set_default(keyname) msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Setting default for selected key {:} failed.".format(keyname)) else: try: sshdb = SSHKeyDBManager() d = sshdb.table_dict() for i in d: if d[i]["is_default"] == "True": key = d[i] print("{:}: {:}".format(key['name'], key['fingerprint'])) msg = "info. OK." Console.ok(msg) return "" else: pass Console.error("The key is not in the database") except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem retrieving default key.") elif arguments['delete']: delete_on_cloud = arguments["--force"] or False # print ("DDD", delete_on_cloud) if arguments['--all']: try: sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud) sshm.delete_all_keys() print("All keys from the database deleted successfully.") msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem deleting keys") elif arguments['--select']: keyname = None sshdb = SSHKeyDBManager() select = sshdb.select() if select != 'q': try: keyname = select.split(':')[0] print("Deleting key: {:}...".format(keyname)) sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud) sshm.delete_key(keyname) msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem deleting the key `{:}`".format(keyname)) else: keyname = None try: keyname = arguments['KEYNAME'] sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud) sshm.delete_key(keyname) print("Key {:} deleted successfully from database.".format(keyname)) msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem deleting the key `{:}`".format(keyname)) elif arguments['upload']: try: # # get username # conf = ConfigDict("cloudmesh.yaml") username = conf["cloudmesh"]["profile"]["username"] if username in ['None', 'TBD']: username = None # # get cloudnames # clouds = [] cloud = arguments["--cloud"] or Default.get_cloud() if cloud == "all": config = ConfigDict("cloudmesh.yaml") clouds = config["cloudmesh"]["clouds"] else: clouds.append(cloud) # # get keyname # for cloud in clouds: status = 0 sshdb = SSHKeyDBManager() sshm = SSHKeyManager() keys = sshdb.find_all() for keyid in keys: key = keys[keyid] print ("upload key {} -> {}".format(key["name"], cloud)) try: status = sshm.add_key_to_cloud( username, key["name"], cloud, key["name"]) except Exception as e: print (e) if "already exists" in str(e): print ("key already exists. Skipping " "upload. ok.") if status == 1: print("Problem uploading key. failed.") msg = "info. OK." Console.ok(msg) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem adding key to cloud") elif arguments['map']: try: cloud = arguments["--cloud"] or Default.get_cloud() sshm = SSHKeyManager() map_dict = sshm.get_key_cloud_maps(cloud) print(dict_printer(map_dict, order=["user", "key_name", "cloud_name", "key_name_on_cloud"])) except Exception as e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem adding key to cloud")
def do_nova(self, args, arguments): """ :: Usage: nova set CLOUD nova info [CLOUD] [--password] nova help nova [--group=GROUP] ARGUMENTS... A simple wrapper for the openstack nova command Arguments: GROUP The group to add vms to ARGUMENTS The arguments passed to nova help Prints the nova manual set reads the information from the current cloud and updates the environment variables if the cloud is an openstack cloud info the environment values for OS Options: --group=GROUP Add VM to GROUP group --password Prints the password -v verbose mode """ # pprint(arguments) cloud = arguments['CLOUD'] or Default.get_cloud() if not cloud: Console.error("Default cloud not set!") return "" group = arguments["--group"] or Default.get("group", category=cloud) if not group: Console.error("Default group not set!") return "" if arguments["help"]: os.system("nova help") return "" elif arguments["info"]: set_os_environ(cloud) d = {} # # TODO: this naturally does not work as clouds will have # different parameters. ALos it does not unset previous # parameters from other clouds. See register # for attribute in [ 'OS_USERNAME', 'OS_TENANT_NAME', 'OS_AUTH_URL', 'OS_CACERT', 'OS_PASSWORD', 'OS_REGION' ]: try: d[attribute] = os.environ[attribute] except: Console.warning( "OS environment variable {:} not found".format( attribute)) d[attribute] = None if not arguments["--password"]: d['OS_PASSWORD'] = "******" print(row_table(d, order=None, labels=["Variable", "Value"])) msg = "info. OK." Console.ok(msg) return "" elif arguments["set"]: if cloud: set_os_environ(cloud) msg = "{0} is set".format(cloud) Console.ok(msg) else: Console.error("CLOUD is required") else: # nova ARGUMENTS... print("Cloud = {0}".format(cloud)) try: set_os_environ(cloud) args = arguments["ARGUMENTS"] # arguments may contain multiple optional arguments if len(args) == 1: args = args[0].split() result = Shell.execute("nova", args) print(Nova.remove_subjectAltName_warning(result)) """ If request for nova boot, add the vm to group specified, or else add to default group """ if "boot" in args: # Logic to find ID of VM in the result fields = [] for field in result.split("|"): fields.append(field.strip()) index = fields.index('id') + 1 vm_id = fields[index] # Add to group Group.add(name=group, type="vm", id=vm_id, category=cloud) except Exception as ex: Console.error("Error executing Nova command: {}".format(ex)) return ""
def do_secgroup(self, args, arguments): """ :: Usage: secgroup list [--cloud=CLOUD] secgroup create [--cloud=CLOUD] LABEL secgroup delete [--cloud=CLOUD] LABEL secgroup rules-list [--cloud=CLOUD] LABEL secgroup rules-add [--cloud=CLOUD] LABEL FROMPORT TOPORT PROTOCOL CIDR secgroup rules-delete [--cloud=CLOUD] [--all] LABEL [FROMPORT] [TOPORT] [PROTOCOL] [CIDR] secgroup refresh [--cloud=CLOUD] secgroup -h | --help secgroup --version Options: -h help message --cloud=CLOUD Name of the IaaS cloud e.g. india_openstack_grizzly. Arguments: LABEL The label/name of the security group FROMPORT Staring port of the rule, e.g. 22 TOPORT Ending port of the rule, e.g. 22 PROTOCOL Protocol applied, e.g. TCP,UDP,ICMP CIDR IP address range in CIDR format, e.g., 129.79.0.0/16 Description: security_group command provides list/add/delete security_groups for a tenant of a cloud, as well as list/add/delete of rules for a security group from a specified cloud and tenant. Examples: secgroup list --cloud india secgroup rules-list --cloud=kilo default secgroup create --cloud=kilo webservice secgroup rules-add --cloud=kilo webservice 8080 8088 TCP 129.79.0.0/16 secgroup rules-delete --cloud=kilo webservice 8080 8088 TCP 129.79.0.0/16 secgroup rules-delete --all """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() # if refresh ON, pull data from cloud to db if arguments["refresh"] or \ Default.refresh(): msg = "Refresh secgroup for cloud {:}.".format(cloud) if SecGroup.refresh(cloud): Console.ok("{:} ok".format(msg)) else: Console.error("{:} failed".format(msg)) # list all security-groups in cloud if arguments["list"]: # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return result = SecGroup.list(cloud=cloud) if result: print(result) else: Console.error( "No Security Groups found in the cloudmesh database!") return "" # Create a security-group elif arguments["create"]: # if no arguments read default label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return # Create returns uuid of created sec-group uuid = SecGroup.create(label, cloud) if uuid: Console.ok( "Created a new security group [{}] with UUID [{}]".format( label, uuid)) else: Console.error("Exiting!") return "" # Delete a security-group elif arguments["delete"]: # if no arguments read default label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" result = SecGroup.delete_secgroup(label, cloud) if result is not None: Console.ok("Security Group [{}] in cloud [{}] deleted successfully." \ .format(label, cloud)) else: Console.error( "Failed to delete Security Group [{}] in cloud [{}]". format(label, cloud)) return "" # Delete security group rule elif arguments["rules-delete"]: # if no arguments read default cloud = arguments["--cloud"] or Default.get_cloud() label = arguments["LABEL"] from_port = arguments["FROMPORT"] to_port = arguments["TOPORT"] protocol = arguments["PROTOCOL"] cidr = arguments["CIDR"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" # Get the security group sec_group = SecGroup.get(label, cloud) if sec_group: # delete all rules for secgroup if arguments["--all"]: SecGroup.delete_all_rules(secgroup=sec_group) return "" # Get the rules result = SecGroup.delete_rule(cloud=cloud, secgroup=sec_group, from_port=from_port, to_port=to_port, protocol=protocol, cidr=cidr) if result: Console.ok(result) else: Console.error( "Rule [{} | {} | {} | {}] could not be deleted".format( from_port, to_port, protocol, cidr)) return "" # list security group rules elif arguments["rules-list"]: # if no arguments read default label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" # Get the security group sec_group = SecGroup.get(label, cloud) if sec_group: # Get the rules result = SecGroup.get_rules(sec_group.uuid) print(result) else: Console.error( "Security Group with label [{}] in cloud [{}] not found!". format(label, cloud)) return "" # add rule to security group elif arguments["rules-add"]: label = arguments["LABEL"] from_port = arguments["FROMPORT"] to_port = arguments["TOPORT"] protocol = arguments["PROTOCOL"] cidr = arguments["CIDR"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" # Get the security group sec_group = SecGroup.get(label, cloud) if sec_group: # Add rules to the security group SecGroup.add_rule(cloud=cloud, secgroup=sec_group, from_port=from_port, to_port=to_port, protocol=protocol, cidr=cidr) else: Console.error( "Security Group with label [{}] in cloud [{}] not found!". format(label, cloud)) return "" # TODO: Add Implementation elif arguments["--version"]: Console.ok('Version: ') return ""
def do_sync(self, args, arguments): """ :: Usage: sync put [--cloud=CLOUD] LOCALDIR [REMOTEDIR] sync get [--cloud=CLOUD] REMOTEDIR LOCALDIR A simple wrapper for the openstack nova command Arguments: LOCALDIR A directory on local machine REMOTEDIR A directory on remote machine Options: --cloud=CLOUD Sync with cloud """ cloudname = arguments["--cloud"] or Default.get_cloud() if cloudname is None: Console.error("Default cloud has not been set!" "Please use the following to set it:\n" "cm default cloud=CLOUDNAME\n" "or provide it via the --cloud=CLOUDNAME argument.") return # Get the arguments # group = arguments["--group"] or Default.get("group", cloudname) localdir = arguments["LOCALDIR"] remotedir = arguments["REMOTEDIR"] if arguments["put"]: # validate local directory exists if localdir is None: Console.error("Please provide the [LOCALDIR] argument.") return "" result = Sync.sync(cloudname=cloudname, localdir=localdir, remotedir=remotedir, operation="put") if result is not None: Console.ok("Successuly synced local and remote directories.") elif arguments["get"]: # validate local directory exists if localdir is None: Console.error("Please provide the [LOCALDIR] argument.") return "" result = Sync.sync(cloudname=cloudname, localdir=localdir, remotedir=remotedir, operation="get") if result is not None: Console.ok("Successuly synced local and remote directories.") return ""
def do_select(self, args, arguments): """ :: Usage: select image [CLOUD] [--refresh] select flavor [CLOUD] [--refresh] select cloud [CLOUD] select key [CLOUD] selects interactively the default values Arguments: CLOUD the name of the cloud Options: --refresh refreshes the data before displaying it from the cloud """ # pprint(arguments) cloud = arguments["CLOUD"] or Default.get_cloud() if arguments["image"]: try: refresh = arguments['--refresh'] or Default.refresh() if refresh: Image.refresh(cloud) image_dict = Image.list(cloud, format="dict") image_names = list() for image in image_dict.values(): image_names.append(image["name"]) number = menu_return_num(title="Select an Image", menu_list=image_names, tries=10, with_display=True) if number == "q": pass else: image = image_names[number] print("Selected image " + image) Default.set("image", image, category=cloud) except: print("ERROR: could not set image.") elif arguments["flavor"]: try: refresh = arguments['--refresh'] or Default.refresh() if refresh: Flavor.refresh(cloud) flavor_dict = Flavor.list(cloud, format="dict") flavor_names = list() for flavor in flavor_dict.values(): flavor_names.append(flavor["name"]) number = menu_return_num(title="Select a Flavor", menu_list=flavor_names, tries=10, with_display=True) if number == "q": pass else: flavor = flavor_names[number] print("Selected flavor " + flavor) Default.set("flavor", flavor, category=cloud) except: print("ERROR: could not set flavor.") elif arguments["cloud"]: try: config = ConfigDict("cloudmesh.yaml") clouds = config["cloudmesh"]["clouds"] for key in clouds.keys(): Console.ok(" " + key) number = menu_return_num(title="Select a cloud", menu_list=clouds.keys(), tries=10, with_display=True) if number == "q": pass else: cloud = clouds.keys()[number] print("Selected cloud " + cloud) Default.set("cloud", cloud, "general") except: print("ERROR: could not set cloud.") elif arguments["key"]: try: db = SSHKeyDBManager() key_dict = db.table_dict() key_names = list() for key in key_dict.values(): key_names.append(key["name"]) number = menu_return_num(title="Select a Key", menu_list=key_names, tries=10, with_display=True) if number == "q": pass else: key = key_names[number] print("Selected key " + key) # TODO Fix default key setting in key DB # db.set_default(key) Default.set("key", key, category=cloud) except: print("ERROR: could not set key") return ""
def do_flavor(self, args, arguments): """ :: Usage: flavor refresh [--cloud=CLOUD] [-v] flavor list [ID] [--cloud=CLOUD] [--format=FORMAT] [--refresh] [-v] This lists out the flavors present for a cloud Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --refresh refreshes the data before displaying it from the cloud Examples: cm flavor refresh cm flavor list cm flavor list --format=csv cm flavor show 58c9552c-8d93-42c0-9dea-5f48d90a3188 --refresh """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") return if arguments["-v"]: print("Cloud: {}".format(cloud)) if arguments["refresh"] or Default.refresh(): msg = "Refresh flavor for cloud {:}.".format(cloud) if Flavor.refresh(cloud): Console.ok("{:} ok".format(msg)) else: Console.error("{:} failed".format(msg)) return "" if arguments["list"]: id = arguments['ID'] live = arguments['--refresh'] output_format = arguments["--format"] counter = 0 result = None while counter < 2: if id is None: result = Flavor.list(cloud, output_format) else: result = Flavor.details(cloud, id, live, output_format) if counter == 0 and result is None: if not Flavor.refresh(cloud): msg = "Refresh flavor for cloud {:}.".format(cloud) Console.error("{:} failed.".format(msg)) counter += 1 if result is None: Console.error("No image(s) found. Failed.") else: print(result) return ""
def do_network(self, args, arguments): """ :: Usage: network get fixed [ip] [--cloud=CLOUD] FIXED_IP network get floating [ip] [--cloud=CLOUD] FLOATING_IP_ID network reserve fixed [ip] [--cloud=CLOUD] FIXED_IP network unreserve fixed [ip] [--cloud=CLOUD] FIXED_IP network associate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network disassociate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network create floating [ip] [--cloud=CLOUD] [--pool=FLOATING_IP_POOL] network delete floating [ip] [--cloud=CLOUD] FLOATING_IP... network list floating pool [--cloud=CLOUD] network list floating [ip] [--cloud=CLOUD] [--instance=INS_ID_OR_NAME] [IP_OR_ID] network create cluster --group=demo_group network -h | --help Options: -h help message --cloud=CLOUD Name of the IaaS cloud e.g. india_openstack_grizzly. --group=GROUP Name of the group in Cloudmesh --pool=FLOATING_IP_POOL Name of Floating IP Pool --instance=INS_ID_OR_NAME ID or Name of the vm instance Arguments: IP_OR_ID IP Address or ID of IP Address FIXED_IP Fixed IP Address, e.g. 10.1.5.2 FLOATING_IP Floating IP Address, e.g. 192.1.66.8 FLOATING_IP_ID ID associated with Floating IP, e.g. 185c5195-e824-4e7b-8581-703abec4bc01 Examples: network get fixed ip --cloud=india 10.1.2.5 network get fixed --cloud=india 10.1.2.5 network get floating ip --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 network get floating --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 network reserve fixed ip --cloud=india 10.1.2.5 network reserve fixed --cloud=india 10.1.2.5 network unreserve fixed ip --cloud=india 10.1.2.5 network unreserve fixed --cloud=india 10.1.2.5 network associate floating ip --cloud=india --instance=albert-001 192.1.66.8 network associate floating --cloud=india --instance=albert-001 network associate floating --cloud=india --group=albert_group network disassociate floating ip --cloud=india --instance=albert-001 192.1.66.8 network disassociate floating --cloud=india --instance=albert-001 192.1.66.8 network create floating ip --cloud=india --pool=albert-f01 network create floating --cloud=india --pool=albert-f01 network delete floating ip --cloud=india 192.1.66.8 192.1.66.9 network delete floating --cloud=india 192.1.66.8 192.1.66.9 network list floating ip --cloud=india network list floating --cloud=india network list floating --cloud=india 192.1.66.8 network list floating --cloud=india --instance=323c5195-7yy34-4e7b-8581-703abec4b network list floating pool --cloud=india network create cluster --group=demo_group """ # pprint(arguments) # Get the cloud parameter OR read default cloudname = arguments["--cloud"] or Default.get_cloud() if cloudname is None: Console.error("Default cloud has not been set!" "Please use the following to set it:\n" "cm default cloud=CLOUDNAME\n" "or provide it via the --cloud=CLOUDNAME argument.") return "" # Fixed IP info if arguments["get"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.get_fixed_ip(cloudname, fixed_ip_addr=fixed_ip) Console.msg(result) # Floating IP info elif arguments["get"] \ and arguments["floating"]: floating_ip_id = arguments["FLOATING_IP_ID"] result = Network.get_floating_ip(cloudname, floating_ip_or_id=floating_ip_id) Console.msg(result) # Reserve a fixed ip elif arguments["reserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.reserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok("Reserve fixed ip address [{}] complete.".format(fixed_ip)) # Un-Reserve a fixed ip elif arguments["unreserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.unreserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok("Un-Reserve fixed ip address [{}] complete.".format(fixed_ip)) # Associate floating IP elif arguments["associate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] print(floating_ip) # group supplied if group_name is not None: """ Group name has been provided. Assign floating IPs to all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, category=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict 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 "" # Get the instance name instance_name = instance_dict["name"] floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Refresh VM in db self.refresh_vm(cloudname) else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" # floating-ip not supplied, instance-id supplied elif len(floating_ip) == 0 and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Generate one from the pool, and assign to vm and return """ 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"] floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Associate the IP to the instance and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) floating_ip = floating_ip[0] # 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)) # Invalid parameters else: Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) elif arguments["disassociate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] # group supplied if group_name is not None: """ Group name has been provided. Remove floating IPs of all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, category=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict 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 "" # Get the instance name instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error("Instance[{}] does not have a floating_ip." .format(instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" # floating-ip not supplied, instance-id supplied elif len(floating_ip) == 0 and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Remove floating ip allocated to vm and return """ 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"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error("Instance[{}] does not have a floating_ip." .format(instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Remove the IP from the instance and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) floating_ip = floating_ip[0] # 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"] _floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if _floating_ip != floating_ip: Console.error("Invalid floating_ip [{}] for instance [{}]." .format(floating_ip, instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) # Invalid parameters else: Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) # Create new floating ip under floating pool elif arguments["create"] \ and arguments["floating"]: floating_pool = arguments["--pool"] result = Network.create_floating_ip(cloudname=cloudname, floating_pool=floating_pool) if result is not None: Console.ok("Created new floating IP [{}]".format(result)) else: Console.error("Failed to create floating IP! Please check arguments.") # Delete a floating ip address elif arguments["delete"] \ and arguments["floating"]: floating_ips = arguments["FLOATING_IP"] for floating_ip in floating_ips: result = Network.delete_floating_ip(cloudname=cloudname, floating_ip_or_id=floating_ip) if result is not None: Console.ok(result) else: Console.error("Failed to delete floating IP address!") # Floating IP Pool List elif arguments["list"] \ and arguments["floating"] \ and arguments["pool"]: result = Network.list_floating_ip_pool(cloudname) Console.msg(result) # Floating IP list [or info] elif arguments["list"] \ and arguments["floating"]: ip_or_id = arguments["IP_OR_ID"] instance_id = arguments["--instance"] # Refresh VM in db self.refresh_vm(cloudname) # If instance id is supplied if instance_id is not None: 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 "" # Read the floating_ip from the dict ip_or_id = instance_dict["floating_ip"] if ip_or_id is None: Console.error("Instance with ID [{}] does not have a floating IP address!" .format(instance_id)) return "" # If the floating ip or associated ID is supplied if ip_or_id is not None: result = Network.get_floating_ip(cloudname, floating_ip_or_id=ip_or_id) if result is not None: Console.msg(result) else: Console.error("Floating IP not found! Please check your arguments.") return "" # Retrieve the full list else: result = Network.list_floating_ip(cloudname) Console.msg(result) # Create a virtual cluster elif arguments["cluster"] and \ arguments["create"]: group_name = arguments["--group"] or \ Default.get("group", category=cloudname) # Get the group information group = Group.get_info(name=group_name, category=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # var contains pub key of all vms public_keys = "" login_users = [] login_ips = [] # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict 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 "" # Get the instance name instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # If vm does not have floating ip, then create if floating_ip is None: floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Refresh VM in db self.refresh_vm(cloudname) # Get the login user for this machine user = raw_input("Enter the login user for VM {} : ".format(instance_name)) passphrase = getpass.getpass("Enter the passphrase key on VM {} : ".format(instance_name)) # create list for second iteration login_users.append(user) login_ips.append(floating_ip) login_args = [ user + "@" + floating_ip, ] keygen_args = [ "ssh-keygen -t rsa -f ~/.ssh/id_rsa -N " + passphrase ] cat_pubkey_args = [ "cat ~/.ssh/id_rsa.pub" ] generate_keypair = login_args + keygen_args result = Shell.ssh(*generate_keypair) # print("***** Keygen *****") # print(result) cat_public_key = login_args + cat_pubkey_args result = Shell.ssh(*cat_public_key) public_keys += "\n" + result # print("***** id_rsa.pub *****") # print(result) # print("***** public keys *****") # print(public_keys) for user, ip in zip(login_users, login_ips): arguments = [ user + "@" + ip, "echo '" + public_keys + "' >> ~/.ssh/authorized_keys" ] # copy the public key contents to auth_keys result = Shell.ssh(*arguments) Console.ok("Virtual cluster creation successfull.") else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" return ""
def cloudmesh_clouds(request): config = ConfigDict(filename="cloudmesh.yaml") clouds = config["cloudmesh.clouds"] active = config["cloudmesh.active"] default = Default.get_cloud() data = {} attributes = ['cm_label', 'cm_host', 'cm_heading', 'cm_type', 'cm_type_version'] for cloud in clouds: name = {'cloud': cloud} data[cloud] = {} for attribute in attributes: data[cloud][attribute] = clouds[cloud][attribute] print clouds[cloud]['cm_type'] if clouds[cloud]['cm_type'] == "ec2": data[cloud]['username'] = clouds[cloud]['credentials']['userid'] elif clouds[cloud]['cm_type'] == "azure": data[cloud]['username'] = '******' elif clouds[cloud]['cm_type'] == "openstack": data[cloud]['username'] = clouds[cloud]['credentials'][ 'OS_USERNAME'] if cloud in active: data[cloud]['active'] = 'yes' else: data[cloud]['active'] = 'no' if cloud in [default]: data[cloud]['default'] = 'yes' else: data[cloud]['default'] = 'no' data[cloud]['info'] = ", ".join([ url('d', '/cm/cloud/{cloud}/'.format(**name)), url('i', '/cm/image/{cloud}/'.format(**name)), url('f', '/cm/flavor/{cloud}/'.format(**name)), url('v', '/cm/vm/{cloud}/'.format(**name))]) order = [ 'default', 'active', 'cm_label', 'info', 'username', 'cm_host', 'cm_heading', 'cm_type', 'cm_type_version' ] header = [ 'Default', 'Active', 'Label', 'Info', 'Username', 'Host', 'Description', 'Type', 'Version' ] pprint(data) context = { 'data': data, 'title': "Cloud List", 'order': order, 'header': header, } return render(request, 'cloudmesh_portal/dict_table.jinja', context)
def do_group(self, args, arguments): """ :: Usage: group add NAME [--type=TYPE] [--category=CLOUD] --id=IDs group list [--category=CLOUD] [--format=FORMAT] [NAME] group delete NAME [--category=CLOUD] group remove [--category=CLOUD] --name=NAME --id=ID group copy FROM TO group merge GROUPA GROUPB MERGEDGROUP manage the groups Arguments: NAME name of a group FROM name of a group TO name of a group GROUPA name of a group GROUPB name of a group MERGEDGROUP name of a group Options: --category=CLOUD the name of the category --format=FORMAT the output format --type=TYPE the resource type --name=NAME the name of the group --id=IDS the ID(s) to add to the group Description: Todo: design parameters that are useful and match description Todo: discuss and propose command cloudmesh can manage groups of resources and category related objects. As it would be cumbersome to for example delete many virtual machines or delete VMs that are in the same group, but are running in different clouds. Hence it is possible to add a virtual machine to a specific group. The group name to be added to can be set as a default. This way all subsequent commands use this default group. It can also be set via a command parameter. Another convenience function is that the group command can use the last used virtual machine. If a vm is started it will be automatically added to the default group if it is set. The delete command has an optional category parameter so that deletion of vms of a partial group by cloud can be achieved. If finer grained deletion is needed, it can be achieved with the delete command that supports deletion by name It is also possible to remove a VM from the group using the remove command, by supplying the ID Example: default group mygroup group add --type=vm --id=albert-[001-003] adds the vms with teh given name using the Parameter see base group add --type=vm adds the last vm to the group group delete --name=mygroup deletes all objects in the group """ # pprint(arguments) category = arguments["--category"] or Default.get_cloud() if arguments["list"]: output = arguments["--format"] or Default.get("format", category) or "table" name = arguments["NAME"] if name is None: result = Group.list(format=output, category=category) if result: print(result) else: print("There are no groups in the cloudmesh database!") else: result = Group.get_info(name=name, category=category, output=output) if result: print(result) else: msg_a = ("No group found with name `{name}` found in the " "category `{category}`.".format(**locals())) # find alternate result = Group.get(name=name) msg_b = "" if result is not None: msg_b = " However we found such a variable in " \ "category `{category}`. Please consider " \ "using --category={category}".format(**result) Console.error(msg_a + msg_b) return elif arguments["add"]: type = arguments["--type"] or Default.get("type", category) category_id = arguments["--id"] or Default.get("id", category) data = { "name": arguments["NAME"], "type": type, "category": category, "id": category_id } Group.add(**data) return elif arguments["delete"]: data = { "name": arguments["NAME"], "category": category, } result = Group.delete(**data) if result: Console.ok("Deletion completed. ok.") else: Console.error( "No group with name `{name}` found".format(**data)) return elif arguments["remove"]: name = arguments["--name"] category_id = arguments["--id"] if not category: Console.error("Default category not set!") return result = Group.remove(name, category_id, category) if result: Console.ok(result) else: Console.error( "Failed to delete ID [{}] from group [{}] in the database!" .format(category_id, name)) return elif arguments["copy"]: _from = arguments["FROM"] _to = arguments["TO"] Group.copy(_from, _to) return elif arguments["merge"]: _groupA = arguments["GROUPA"] _groupB = arguments["GROUPB"] _mergedGroup = arguments["MERGEDGROUP"] Group.merge(_groupA, _groupB, _mergedGroup) return
def do_vm(self, args, arguments): """ :: Usage: vm default [--cloud=CLOUD][--format=FORMAT] vm refresh [--cloud=CLOUD] vm boot [--name=NAME] [--cloud=CLOUD] [--image=IMAGE_OR_ID] [--flavor=FLAVOR_OR_ID] [--group=GROUP] [--secgroup=SECGROUP] [--key=KEY] [--dryrun] vm start [NAME]... [--group=GROUP] [--cloud=CLOUD] [--force] vm stop [NAME]... [--group=GROUP] [--cloud=CLOUD] [--force] vm delete [NAME]... [--group=GROUP] [--cloud=CLOUD] [--force] vm ip assign [NAME]... [--cloud=CLOUD] vm ip show [NAME]... [--group=GROUP] [--cloud=CLOUD] [--format=FORMAT] [--refresh] vm login [NAME] [--user=USER] [--ip=IP] [--cloud=CLOUD] [--key=KEY] [--command=COMMAND] vm rename [NAME]... [--new=NEWNAME] [--cloud=CLOUD] vm list [NAME_OR_ID] [--cloud=CLOUD|--all] [--group=GROUP] [--format=FORMAT] [--refresh] vm status [--cloud=CLOUD] vm info [--cloud=CLOUD] [--format=FORMAT] Arguments: COMMAND positional arguments, the commands you want to execute on the server(e.g. ls -a) separated by ';', you will get a return of executing result instead of login to the server, note that type in -- is suggested before you input the commands NAME server name. By default it is set to the name of last vm from database. NAME_OR_ID server name or ID KEYPAIR_NAME Name of the openstack keypair to be used to create VM. Note this is not a path to key. NEWNAME New name of the VM while renaming. Options: --ip=IP give the public ip of the server --cloud=CLOUD give a cloud to work on, if not given, selected or default cloud will be used --count=COUNT give the number of servers to start --detail for table print format, a brief version is used as default, use this flag to print detailed table --flavor=FLAVOR_OR_ID give the name or id of the flavor --group=GROUP give the group name of server --secgroup=SECGROUP security group name for the server --image=IMAGE_OR_ID give the name or id of the image --key=KEY specify a key to use, input a string which is the full path to the private key file --keypair_name=KEYPAIR_NAME Name of the openstack keypair to be used to create VM. Note this is not a path to key. --user=USER give the user name of the server that you want to use to login --name=NAME give the name of the virtual machine --force delete vms without user's confirmation --command=COMMAND specify the commands to be executed --new=NEWNAME Specify the new name for a VM while renaming. By default, this will be set to <username>-<count> format. Description: commands used to boot, start or delete servers of a cloud vm default [options...] Displays default parameters that are set for VM boot. vm boot [options...] Boots servers on a cloud, user may specify flavor, image .etc, otherwise default values will be used, see how to set default values of a cloud: cloud help vm start [options...] Starts a suspended or stopped vm instance. vm stop [options...] Stops a vm instance . vm delete [options...] delete servers of a cloud, user may delete a server by its name or id, delete servers of a group or servers of a cloud, give prefix and/or range to find servers by their names. Or user may specify more options to narrow the search vm floating_ip_assign [options...] assign a public ip to a VM of a cloud vm ip show [options...] show the ips of VMs vm login [options...] login to a server or execute commands on it vm list [options...] same as command "list vm", please refer to it vm status [options...] Retrieves status of last VM booted on cloud and displays it. Tip: give the VM name, but in a hostlist style, which is very convenient when you need a range of VMs e.g. sample[1-3] => ['sample1', 'sample2', 'sample3'] sample[1-3,18] => ['sample1', 'sample2', 'sample3', 'sample18'] """ def _print_dict(d, header=None, format='table'): if format == "json": return json.dumps(d, indent=4) elif format == "yaml": return pyaml.dump(d) elif format == "table": return dict_printer(d, order=["id", "name", "status"], output="table", sort_keys=True) else: return d def _print_dict_ip(d, header=None, format='table'): if format == "json": return json.dumps(d, indent=4) elif format == "yaml": return pyaml.dump(d) elif format == "table": return dict_printer(d, order=["network", "version", "addr"], output="table", sort_keys=True) else: return d """ def list_vms_on_cloud(cloud="kilo", group=None, format="table"): Utility reusable function to list vms on the cloud. :param cloud: :param group: :param format: :return: _cloud = cloud _group = group _format = format cloud_provider = CloudProvider(_cloud).provider servers = cloud_provider.list_vm(_cloud) server_list = {} index = 0 # TODO: Improve the implementation to display more fields if required. for server in servers: server_list[index] = {} server_list[index]["name"] = server.name server_list[index]["id"] = server.id server_list[index]["status"] = server.status index += 1 # TODO: Get this printed in a table print("Print table") dict_printer(servers, output=_format) """ # pprint(arguments) def _refresh(): try: msg = "Refresh VMs for cloud {:}.".format(cloud) if Vm.refresh(cloud=cloud): Console.ok("{:} OK.".format(msg)) else: Console.error("{:} failed".format(msg)) except Exception as e: Error.traceback(e) Console.error("Problem running VM refresh") cloud = arguments["--cloud"] or Default.get_cloud() if arguments["boot"]: name = None try: name = arguments["--name"] is_name_provided = True if name is None: is_name_provided = False count = Counter.get() prefix = Username() if prefix is None or count is None: Console.error( "Prefix and Count could not be retrieved correctly." ) return # BUG THE Z FILL SHOULD BE detected from yaml file name = prefix + "-" + str(count).zfill(3) # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" image = arguments["--image"] or Default.get("image", category=cloud) # if default image not set, return error if not image: Console.error("Default image not set.") return "" flavor = arguments["--flavor"] or Default.get("flavor", category=cloud) # if default flavor not set, return error if not flavor: Console.error("Default flavor not set.") return "" group = arguments["--group"] or Default.get_group() # if default group not set, return error if not group: group = "default" Default.set_group(group) secgroup = arguments["--secgroup"] or Default.get( "secgroup", category=cloud) # print("SecurityGrp : {:}".format(secgroup)) secgroup_list = ["default"] if secgroup is not None: secgroup_list.append(secgroup) key_name = arguments["--key"] or Default.get_key() # if default keypair not set, return error if not key_name: Console.error("Default key not set.") return "" if arguments["--dryrun"]: data = { "cloud": cloud, "name": name, "image": image, "flavor": flavor, "key_name": key_name, "secgroup_list": secgroup_list, "group": group } print(attribute_printer(data, output="table")) msg = "dryrun info. OK." Console.ok(msg) else: vm_id = Vm.boot(cloud=cloud, name=name, image=image, flavor=flavor, key_name=key_name, secgroup_list=secgroup_list) Default.set("last_vm_id", vm_id) Default.set("last_vm_name", name) # SHOULD WE NOT DO THIS BY DEFAULT EVEN IF WE SPECIFY THE NAME? if is_name_provided is False: # Incrementing count Counter.incr() # Add to group if vm_id is not None: Group.add(name=group, type="vm", id=name, category=cloud) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem booting instance {:}".format(name)) elif arguments["default"]: try: count = Counter.get() prefix = Username() if prefix is None or count is None: Console.error( "Prefix and Count could not be retrieved correctly.") return vm_name = prefix + "-" + str(count).zfill(3) data = { "name": vm_name, "cloud": arguments["--cloud"] or Default.get_cloud() } for attribute in [ "image", "flavor", "key", "login_key", "group", "secgroup" ]: data[attribute] = Default.get(attribute, category=cloud) output_format = arguments["--format"] or "table" print(attribute_printer(data, output=output_format)) msg = "info. OK." Console.ok(msg) ValueError( "default command not implemented properly. Upon " "first install the defaults should be read from yaml.") except Exception as e: Error.traceback(e) Console.error("Problem listing defaults") elif arguments["status"]: try: cloud_provider = CloudProvider(cloud).provider vm_list = cloud_provider.list_vm(cloud) print("Status of VM {} is {}".format(vm_list[0]["name"], vm_list[0]["status"])) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem retrieving status of the VM") elif arguments["info"]: try: cloud_provider = CloudProvider(cloud).provider vms = cloud_provider.list_vm(cloud) vm = vms[0] output_format = arguments["--format"] or "table" print(attribute_printer(vm, output=output_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem retrieving status of the VM") elif arguments["start"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error( "No VM records in database. Please run vm refresh." ) return "" name = last_vm["name"] # print(name) servers = list() servers.append(name) group = arguments["--group"] force = arguments["--force"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" Vm.start(cloud=cloud, servers=servers) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem starting instances") elif arguments["stop"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error( "No VM records in database. Please run vm refresh." ) return "" name = last_vm["name"] # print(name) servers = list() servers.append(name) group = arguments["--group"] force = arguments["--force"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" Vm.stop(cloud=cloud, servers=servers) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem stopping instances") elif arguments["refresh"]: _refresh() elif arguments["delete"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error( "No VM records in database. Please run vm refresh." ) return "" name = last_vm["name"] servers = list() servers.append(name) group = arguments["--group"] force = arguments["--force"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" Vm.delete(cloud=cloud, servers=servers) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem deleting instances") elif arguments["ip"] and arguments["assign"]: vmids = arguments["NAME"] # If names not provided, take the last vm from DB. if vmids is None or len(vmids) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error( "No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] vmids = list() vmids.append(name) # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" try: cloud_provider = CloudProvider(cloud).provider for sname in vmids: floating_ip = cloud_provider.create_assign_floating_ip( sname) if floating_ip is not None: print( "Floating IP assigned to {:} successfully and it is: {:}" .format(sname, floating_ip)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem assigning floating ips.") elif arguments["ip"] and arguments["show"]: vmids = arguments["NAME"] # If names not provided, take the last vm from DB. if vmids is None or len(vmids) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error( "No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] vmids = list() vmids.append(name) group = arguments["--group"] output_format = arguments["--format"] or "table" refresh = arguments["--refresh"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" try: cloud_provider = CloudProvider(cloud).provider for server in vmids: ip_addr = cloud_provider.get_ips(server) ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud) print( "IP Addresses of instance {:} are as follows:-".format( server)) print(_print_dict_ip(ipaddr_dict, format=output_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Problem getting ip addresses for instance {:}".format(id)) elif arguments["login"]: vm_names = arguments["NAME"] # If names not provided, take the last vm from DB. if vm_names is None or len(vm_names) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error( "No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] else: name = vm_names[0] print("Logging in into {:} machine...".format(name)) user = arguments["--user"] # Get user if user argument not specified. if user is None: user_from_db = Vm.get_vm_login_user(name, cloud) user_suggest = user_from_db or getpass.getuser() user = input("Enter the user to login (Default: {}):".format( user_suggest)) or user_suggest Vm.set_vm_login_user(name, cloud, user) ip = arguments["--ip"] commands = arguments["--command"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" key = arguments["--key"] or Default.get("login_key", category=cloud) if not key: Console.error("Default login_key not set.") return "" cloud_provider = CloudProvider(cloud).provider # print("Name : {:}".format(name)) ip_addr = cloud_provider.get_ips(name) ip_addresses = [] ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud) for entry in ipaddr_dict: ip_addresses.append(ipaddr_dict[entry]["addr"]) if ip is not None: if ip not in ip_addresses: print( "ERROR: IP Address specified does not match with the host." ) return "" else: print("Determining IP Address to use with a ping test.") # This part assumes that the ping is allowed to the machine. for ipadd in ip_addresses: print("Checking {:}...".format(ipadd)) try: socket.gethostbyaddr(ipadd) # ip will be set if above command is successful. ip = ipadd except socket.herror: print("Cannot reach {:}.".format(ipadd)) if ip is None: print("SORRY. Unable to connect to the machine") return "" else: print("IP to be used is: {:}".format(ip)) SecGroup.enable_ssh(cloud=cloud) # print("COMMANDS : {:}".format(commands)) # Constructing the ssh command to connect to the machine. sshcommand = "ssh" if key is not None: sshcommand += " -i {:}".format(key) sshcommand += " -o StrictHostKeyChecking=no" sshcommand += " {:}@{:}".format(user, ip) if commands is not None: sshcommand += " \"{:}\"".format(commands) # print(sshcommand) os.system(sshcommand) elif arguments["list"]: if arguments["--all"]: try: _format = arguments["--format"] or "table" d = ConfigDict("cloudmesh.yaml") for cloud in d["cloudmesh"]["clouds"]: if arguments["--refresh"] or Default.refresh(): _refresh() print("Listing VMs on Cloud: {:}".format(cloud)) result = Vm.list(cloud=cloud, output_format=_format) if result is not None: print(result) else: print( "Sorry. No data found with requested parameters in DB." ) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem listing all instances") else: # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" try: name_or_id = arguments["NAME_OR_ID"] group = arguments["--group"] _format = arguments["--format"] or "table" # list_vms_on_cloud(cloud, group, _format) if arguments["--refresh"] or Default.refresh(): _refresh() result = Vm.list(name_or_id=name_or_id, cloud=cloud, output_format=_format) if result is not None: print(result) else: print("No data found with the requested parameters.") msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Problem listing instances on cloud {:}".format(cloud)) elif arguments["rename"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error( "No VM records in database. Please run vm refresh." ) return "" name = last_vm["name"] servers = list() servers.append(name) # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" new_name = arguments["--new"] is_name_provided = True # If the new name is not provided, make the new new name in format username-count. if new_name is None or len(new_name) == 0: is_name_provided = False count = Counter.get() prefix = Username() if prefix is None or count is None: Console.error( "Prefix and Count could not be retrieved correctly." ) return # BUG THE Z FILL SHOULD BE detected from yaml file new_name = prefix + "-" + str(count).zfill(3) Vm.rename(cloud=cloud, servers=servers, new_name=new_name) if is_name_provided is False: # Incrementing count Counter.incr() msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem deleting instances") return ""
def do_cloud(self, args, arguments): """ :: Usage: cloud list [--cloud=CLOUD] [--format=FORMAT] cloud logon CLOUD cloud logout CLOUD 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 --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 deactivate 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) cloudname = arguments["--cloud"] or Default.get_cloud() if arguments["logon"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.logon(cloudname) Console.ok("Logged into cloud: " + cloudname) elif arguments["logout"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.logout(cloudname) Console.ok("Logged out of cloud: " + cloudname) elif arguments["activate"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.activate(cloudname) Console.ok("Activated cloud: " + cloudname) elif arguments["deactivate"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.deactivate(cloudname) Console.ok("Deactivated cloud: " + cloudname) elif arguments["list"]: provider = CloudProvider(cloudname).provider clouds = provider.list_clouds() (order, header) = CloudProvider(cloudname).get_attributes("clouds") Console.msg(dict_printer(clouds, order=order, header=header)) pass
def do_secgroup(self, args, arguments): """ :: Usage: secgroup list [--cloud=CLOUD] secgroup create [--cloud=CLOUD] LABEL secgroup delete [--cloud=CLOUD] LABEL secgroup rules-list [--cloud=CLOUD] LABEL secgroup rules-add [--cloud=CLOUD] LABEL FROMPORT TOPORT PROTOCOL CIDR secgroup rules-delete [--cloud=CLOUD] [--all] LABEL [FROMPORT] [TOPORT] [PROTOCOL] [CIDR] secgroup refresh [--cloud=CLOUD] secgroup -h | --help secgroup --version Options: -h help message --cloud=CLOUD Name of the IaaS cloud e.g. india_openstack_grizzly. Arguments: LABEL The label/name of the security group FROMPORT Staring port of the rule, e.g. 22 TOPORT Ending port of the rule, e.g. 22 PROTOCOL Protocol applied, e.g. TCP,UDP,ICMP CIDR IP address range in CIDR format, e.g., 129.79.0.0/16 Description: security_group command provides list/add/delete security_groups for a tenant of a cloud, as well as list/add/delete of rules for a security group from a specified cloud and tenant. Examples: secgroup list --cloud india secgroup rules-list --cloud=kilo default secgroup create --cloud=kilo webservice secgroup rules-add --cloud=kilo webservice 8080 8088 TCP 129.79.0.0/16 secgroup rules-delete --cloud=kilo webservice 8080 8088 TCP 129.79.0.0/16 secgroup rules-delete --all """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() # if refresh ON, pull data from cloud to db if arguments["refresh"] or \ Default.refresh(): msg = "Refresh secgroup for cloud {:}.".format(cloud) if SecGroup.refresh(cloud): Console.ok("{:} ok".format(msg)) else: Console.error("{:} failed".format(msg)) # list all security-groups in cloud if arguments["list"]: # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return result = SecGroup.list(cloud=cloud) if result: print(result) else: Console.error( "No Security Groups found in the cloudmesh database!") return "" # Create a security-group elif arguments["create"]: # if no arguments read default label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return # Create returns uuid of created sec-group uuid = SecGroup.create(label, cloud) if uuid: Console.ok("Created a new security group [{}] with UUID [{}]" .format(label, uuid)) else: Console.error("Exiting!") return "" # Delete a security-group elif arguments["delete"]: # if no arguments read default label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" result = SecGroup.delete_secgroup(label, cloud) if result is not None: Console.ok("Security Group [{}] in cloud [{}] deleted successfully." \ .format(label, cloud)) else: Console.error("Failed to delete Security Group [{}] in cloud [{}]" .format(label, cloud)) return "" # Delete security group rule elif arguments["rules-delete"]: # if no arguments read default cloud = arguments["--cloud"] or Default.get_cloud() label = arguments["LABEL"] from_port = arguments["FROMPORT"] to_port = arguments["TOPORT"] protocol = arguments["PROTOCOL"] cidr = arguments["CIDR"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" # Get the security group sec_group = SecGroup.get(label, cloud) if sec_group: # delete all rules for secgroup if arguments["--all"]: SecGroup.delete_all_rules(secgroup=sec_group) return "" # Get the rules result = SecGroup.delete_rule(cloud=cloud, secgroup=sec_group, from_port=from_port, to_port=to_port, protocol=protocol, cidr=cidr) if result: Console.ok(result) else: Console.error( "Rule [{} | {} | {} | {}] could not be deleted" .format(from_port, to_port, protocol, cidr)) return "" # list security group rules elif arguments["rules-list"]: # if no arguments read default label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" # Get the security group sec_group = SecGroup.get(label, cloud) if sec_group: # Get the rules result = SecGroup.get_rules(sec_group.uuid) print(result) else: Console.error( "Security Group with label [{}] in cloud [{}] not found!" .format(label, cloud)) return "" # add rule to security group elif arguments["rules-add"]: label = arguments["LABEL"] from_port = arguments["FROMPORT"] to_port = arguments["TOPORT"] protocol = arguments["PROTOCOL"] cidr = arguments["CIDR"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" # Get the security group sec_group = SecGroup.get(label, cloud) if sec_group: # Add rules to the security group SecGroup.add_rule(cloud=cloud, secgroup=sec_group, from_port=from_port, to_port=to_port, protocol=protocol, cidr=cidr) else: Console.error( "Security Group with label [{}] in cloud [{}] not found!".format(label, cloud)) return "" # TODO: Add Implementation elif arguments["--version"]: Console.ok('Version: ') return ""
def do_vm(self, args, arguments): """ :: Usage: vm default [--cloud=CLOUD][--format=FORMAT] vm refresh [--cloud=CLOUD] vm boot [--name=NAME] [--cloud=CLOUD] [--image=IMAGE_OR_ID] [--flavor=FLAVOR_OR_ID] [--group=GROUP] [--secgroup=SECGROUP] [--key=KEY] [--dryrun] vm start [NAME]... [--group=GROUP] [--cloud=CLOUD] [--force] vm stop [NAME]... [--group=GROUP] [--cloud=CLOUD] [--force] vm delete [NAME]... [--group=GROUP] [--cloud=CLOUD] [--force] vm ip assign [NAME]... [--cloud=CLOUD] vm ip show [NAME]... [--group=GROUP] [--cloud=CLOUD] [--format=FORMAT] [--refresh] vm login [NAME] [--user=USER] [--ip=IP] [--cloud=CLOUD] [--key=KEY] [--command=COMMAND] vm rename [NAME]... [--new=NEWNAME] [--cloud=CLOUD] vm list [NAME_OR_ID] [--cloud=CLOUD|--all] [--group=GROUP] [--format=FORMAT] [--refresh] vm status [--cloud=CLOUD] vm info [--cloud=CLOUD] [--format=FORMAT] Arguments: COMMAND positional arguments, the commands you want to execute on the server(e.g. ls -a) separated by ';', you will get a return of executing result instead of login to the server, note that type in -- is suggested before you input the commands NAME server name. By default it is set to the name of last vm from database. NAME_OR_ID server name or ID KEYPAIR_NAME Name of the openstack keypair to be used to create VM. Note this is not a path to key. NEWNAME New name of the VM while renaming. Options: --ip=IP give the public ip of the server --cloud=CLOUD give a cloud to work on, if not given, selected or default cloud will be used --count=COUNT give the number of servers to start --detail for table print format, a brief version is used as default, use this flag to print detailed table --flavor=FLAVOR_OR_ID give the name or id of the flavor --group=GROUP give the group name of server --secgroup=SECGROUP security group name for the server --image=IMAGE_OR_ID give the name or id of the image --key=KEY specify a key to use, input a string which is the full path to the private key file --keypair_name=KEYPAIR_NAME Name of the openstack keypair to be used to create VM. Note this is not a path to key. --user=USER give the user name of the server that you want to use to login --name=NAME give the name of the virtual machine --force delete vms without user's confirmation --command=COMMAND specify the commands to be executed --new=NEWNAME Specify the new name for a VM while renaming. By default, this will be set to <username>-<count> format. Description: commands used to boot, start or delete servers of a cloud vm default [options...] Displays default parameters that are set for VM boot. vm boot [options...] Boots servers on a cloud, user may specify flavor, image .etc, otherwise default values will be used, see how to set default values of a cloud: cloud help vm start [options...] Starts a suspended or stopped vm instance. vm stop [options...] Stops a vm instance . vm delete [options...] delete servers of a cloud, user may delete a server by its name or id, delete servers of a group or servers of a cloud, give prefix and/or range to find servers by their names. Or user may specify more options to narrow the search vm floating_ip_assign [options...] assign a public ip to a VM of a cloud vm ip show [options...] show the ips of VMs vm login [options...] login to a server or execute commands on it vm list [options...] same as command "list vm", please refer to it vm status [options...] Retrieves status of last VM booted on cloud and displays it. Tip: give the VM name, but in a hostlist style, which is very convenient when you need a range of VMs e.g. sample[1-3] => ['sample1', 'sample2', 'sample3'] sample[1-3,18] => ['sample1', 'sample2', 'sample3', 'sample18'] """ def _print_dict(d, header=None, format='table'): if format == "json": return json.dumps(d, indent=4) elif format == "yaml": return pyaml.dump(d) elif format == "table": return dict_printer(d, order=["id", "name", "status"], output="table", sort_keys=True) else: return d def _print_dict_ip(d, header=None, format='table'): if format == "json": return json.dumps(d, indent=4) elif format == "yaml": return pyaml.dump(d) elif format == "table": return dict_printer(d, order=["network", "version", "addr"], output="table", sort_keys=True) else: return d """ def list_vms_on_cloud(cloud="kilo", group=None, format="table"): Utility reusable function to list vms on the cloud. :param cloud: :param group: :param format: :return: _cloud = cloud _group = group _format = format cloud_provider = CloudProvider(_cloud).provider servers = cloud_provider.list_vm(_cloud) server_list = {} index = 0 # TODO: Improve the implementation to display more fields if required. for server in servers: server_list[index] = {} server_list[index]["name"] = server.name server_list[index]["id"] = server.id server_list[index]["status"] = server.status index += 1 # TODO: Get this printed in a table print("Print table") dict_printer(servers, output=_format) """ # pprint(arguments) def _refresh(): try: msg = "Refresh VMs for cloud {:}.".format(cloud) if Vm.refresh(cloud=cloud): Console.ok("{:} OK.".format(msg)) else: Console.error("{:} failed".format(msg)) except Exception as e: Error.traceback(e) Console.error("Problem running VM refresh") cloud = arguments["--cloud"] or Default.get_cloud() if arguments["boot"]: name = None try: name = arguments["--name"] is_name_provided = True if name is None: is_name_provided = False count = Counter.get() prefix = Username() if prefix is None or count is None: Console.error("Prefix and Count could not be retrieved correctly.") return # BUG THE Z FILL SHOULD BE detected from yaml file name = prefix + "-" + str(count).zfill(3) # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" image = arguments["--image"] or Default.get("image", category=cloud) # if default image not set, return error if not image: Console.error("Default image not set.") return "" flavor = arguments["--flavor"] or Default.get("flavor", category=cloud) # if default flavor not set, return error if not flavor: Console.error("Default flavor not set.") return "" group = arguments["--group"] or Default.get_group() # if default group not set, return error if not group: group = "default" Default.set_group(group) secgroup = arguments["--secgroup"] or Default.get( "secgroup", category=cloud) # print("SecurityGrp : {:}".format(secgroup)) secgroup_list = ["default"] if secgroup is not None: secgroup_list.append(secgroup) key_name = arguments["--key"] or Default.get_key() # if default keypair not set, return error if not key_name: Console.error("Default key not set.") return "" if arguments["--dryrun"]: data = { "cloud": cloud, "name": name, "image": image, "flavor": flavor, "key_name": key_name, "secgroup_list": secgroup_list, "group": group } print (attribute_printer(data, output="table")) msg = "dryrun info. OK." Console.ok(msg) else: vm_id = Vm.boot(cloud=cloud, name=name, image=image, flavor=flavor, key_name=key_name, secgroup_list=secgroup_list) Default.set("last_vm_id", vm_id) Default.set("last_vm_name", name) # SHOULD WE NOT DO THIS BY DEFAULT EVEN IF WE SPECIFY THE NAME? if is_name_provided is False: # Incrementing count Counter.incr() # Add to group if vm_id is not None: Group.add(name=group, type="vm", id=name, category=cloud) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem booting instance {:}".format(name)) elif arguments["default"]: try: count = Counter.get() prefix = Username() if prefix is None or count is None: Console.error("Prefix and Count could not be retrieved correctly.") return vm_name = prefix + "-" + str(count).zfill(3) data = {"name": vm_name, "cloud": arguments["--cloud"] or Default.get_cloud()} for attribute in ["image", "flavor", "key", "login_key", "group", "secgroup"]: data[attribute] = Default.get(attribute, category=cloud) output_format = arguments["--format"] or "table" print (attribute_printer(data, output=output_format)) msg = "info. OK." Console.ok(msg) ValueError("default command not implemented properly. Upon " "first install the defaults should be read from yaml.") except Exception as e: Error.traceback(e) Console.error("Problem listing defaults") elif arguments["status"]: try: cloud_provider = CloudProvider(cloud).provider vm_list = cloud_provider.list_vm(cloud) print("Status of VM {} is {}".format(vm_list[0]["name"], vm_list[0]["status"])) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem retrieving status of the VM") elif arguments["info"]: try: cloud_provider = CloudProvider(cloud).provider vms = cloud_provider.list_vm(cloud) vm = vms[0] output_format = arguments["--format"] or "table" print (attribute_printer(vm, output=output_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem retrieving status of the VM") elif arguments["start"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error("No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] # print(name) servers = list() servers.append(name) group = arguments["--group"] force = arguments["--force"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" Vm.start(cloud=cloud, servers=servers) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem starting instances") elif arguments["stop"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error("No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] # print(name) servers = list() servers.append(name) group = arguments["--group"] force = arguments["--force"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" Vm.stop(cloud=cloud, servers=servers) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem stopping instances") elif arguments["refresh"]: _refresh() elif arguments["delete"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error("No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] servers = list() servers.append(name) group = arguments["--group"] force = arguments["--force"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" Vm.delete(cloud=cloud, servers=servers) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem deleting instances") elif arguments["ip"] and arguments["assign"]: vmids = arguments["NAME"] # If names not provided, take the last vm from DB. if vmids is None or len(vmids) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error("No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] vmids = list() vmids.append(name) # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" try: cloud_provider = CloudProvider(cloud).provider for sname in vmids: floating_ip = cloud_provider.create_assign_floating_ip( sname) if floating_ip is not None: print( "Floating IP assigned to {:} successfully and it is: {:}".format( sname, floating_ip)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem assigning floating ips.") elif arguments["ip"] and arguments["show"]: vmids = arguments["NAME"] # If names not provided, take the last vm from DB. if vmids is None or len(vmids) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error("No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] vmids = list() vmids.append(name) group = arguments["--group"] output_format = arguments["--format"] or "table" refresh = arguments["--refresh"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" try: cloud_provider = CloudProvider(cloud).provider for server in vmids: ip_addr = cloud_provider.get_ips(server) ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud) print( "IP Addresses of instance {:} are as follows:-".format( server)) print(_print_dict_ip(ipaddr_dict, format=output_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Problem getting ip addresses for instance {:}".format(id)) elif arguments["login"]: vm_names = arguments["NAME"] # If names not provided, take the last vm from DB. if vm_names is None or len(vm_names) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error("No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] else: name = vm_names[0] print("Logging in into {:} machine...".format(name)) user = arguments["--user"] # Get user if user argument not specified. if user is None: user_from_db = Vm.get_vm_login_user(name, cloud) user_suggest = user_from_db or getpass.getuser() user = input("Enter the user to login (Default: {}):".format(user_suggest)) or user_suggest Vm.set_vm_login_user(name, cloud, user) ip = arguments["--ip"] commands = arguments["--command"] # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" key = arguments["--key"] or Default.get("login_key", category=cloud) if not key: Console.error("Default login_key not set.") return "" cloud_provider = CloudProvider(cloud).provider # print("Name : {:}".format(name)) ip_addr = cloud_provider.get_ips(name) ip_addresses = [] ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud) for entry in ipaddr_dict: ip_addresses.append(ipaddr_dict[entry]["addr"]) if ip is not None: if ip not in ip_addresses: print( "ERROR: IP Address specified does not match with the host.") return "" else: print("Determining IP Address to use with a ping test.") # This part assumes that the ping is allowed to the machine. for ipadd in ip_addresses: print("Checking {:}...".format(ipadd)) try: socket.gethostbyaddr(ipadd) # ip will be set if above command is successful. ip = ipadd except socket.herror: print("Cannot reach {:}.".format(ipadd)) if ip is None: print("SORRY. Unable to connect to the machine") return "" else: print("IP to be used is: {:}".format(ip)) SecGroup.enable_ssh(cloud=cloud) # print("COMMANDS : {:}".format(commands)) # Constructing the ssh command to connect to the machine. sshcommand = "ssh" if key is not None: sshcommand += " -i {:}".format(key) sshcommand += " -o StrictHostKeyChecking=no" sshcommand += " {:}@{:}".format(user, ip) if commands is not None: sshcommand += " \"{:}\"".format(commands) # print(sshcommand) os.system(sshcommand) elif arguments["list"]: if arguments["--all"]: try: _format = arguments["--format"] or "table" d = ConfigDict("cloudmesh.yaml") for cloud in d["cloudmesh"]["clouds"]: if arguments["--refresh"] or Default.refresh(): _refresh() print("Listing VMs on Cloud: {:}".format(cloud)) result = Vm.list(cloud=cloud, output_format=_format) if result is not None: print(result) else: print("Sorry. No data found with requested parameters in DB.") msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem listing all instances") else: # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" try: name_or_id = arguments["NAME_OR_ID"] group = arguments["--group"] _format = arguments["--format"] or "table" # list_vms_on_cloud(cloud, group, _format) if arguments["--refresh"] or Default.refresh(): _refresh() result = Vm.list(name_or_id=name_or_id, cloud=cloud, output_format=_format) if result is not None: print(result) else: print("No data found with the requested parameters.") msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Problem listing instances on cloud {:}".format(cloud)) elif arguments["rename"]: try: servers = arguments["NAME"] # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Vm.get_last_vm(cloud=cloud) if last_vm is None: Console.error("No VM records in database. Please run vm refresh.") return "" name = last_vm["name"] servers = list() servers.append(name) # if default cloud not set, return error if not cloud: Console.error("Default cloud not set.") return "" new_name = arguments["--new"] is_name_provided = True # If the new name is not provided, make the new new name in format username-count. if new_name is None or len(new_name) == 0: is_name_provided = False count = Counter.get() prefix = Username() if prefix is None or count is None: Console.error("Prefix and Count could not be retrieved correctly.") return # BUG THE Z FILL SHOULD BE detected from yaml file new_name = prefix + "-" + str(count).zfill(3) Vm.rename(cloud=cloud, servers=servers, new_name=new_name) if is_name_provided is False: # Incrementing count Counter.incr() msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem deleting instances") return ""
def do_nova(self, args, arguments): """ :: Usage: nova set CLOUD nova info [CLOUD] [--password] nova help nova [--group=GROUP] ARGUMENTS... A simple wrapper for the openstack nova command Arguments: GROUP The group to add vms to ARGUMENTS The arguments passed to nova help Prints the nova manual set reads the information from the current cloud and updates the environment variables if the cloud is an openstack cloud info the environment values for OS Options: --group=GROUP Add VM to GROUP group --password Prints the password -v verbose mode """ # pprint(arguments) cloud = arguments['CLOUD'] or Default.get_cloud() if not cloud: Console.error("Default cloud not set!") return "" group = arguments["--group"] or Default.get("group", category=cloud) if not group: Console.error("Default group not set!") return "" if arguments["help"]: os.system("nova help") return "" elif arguments["info"]: set_os_environ(cloud) d = {} # # TODO: this naturally does not work as clouds will have # different parameters. ALos it does not unset previous # parameters from other clouds. See register # for attribute in ['OS_USERNAME', 'OS_TENANT_NAME', 'OS_AUTH_URL', 'OS_CACERT', 'OS_PASSWORD', 'OS_REGION']: try: d[attribute] = os.environ[attribute] except: Console.warning("OS environment variable {:} not found" .format(attribute)) d[attribute] = None if not arguments["--password"]: d['OS_PASSWORD'] = "******" print(row_table(d, order=None, labels=["Variable", "Value"])) msg = "info. OK." Console.ok(msg) return "" elif arguments["set"]: if cloud: set_os_environ(cloud) msg = "{0} is set".format(cloud) Console.ok(msg) else: Console.error("CLOUD is required") else: # nova ARGUMENTS... print("Cloud = {0}".format(cloud)) try: set_os_environ(cloud) args = arguments["ARGUMENTS"] # arguments may contain multiple optional arguments if len(args) == 1: args = args[0].split() result = Shell.execute("nova", args) print(Nova.remove_subjectAltName_warning(result)) """ If request for nova boot, add the vm to group specified, or else add to default group """ if "boot" in args: # Logic to find ID of VM in the result fields = [] for field in result.split("|"): fields.append(field.strip()) index = fields.index('id') + 1 vm_id = fields[index] # Add to group Group.add(name=group, type="vm", id=vm_id, category=cloud) except Exception as ex: Console.error("Error executing Nova command: {}".format(ex)) return ""
def do_select(self, args, arguments): """ :: Usage: select image [CLOUD] [--refresh] select flavor [CLOUD] [--refresh] select cloud [CLOUD] select key [CLOUD] selects interactively the default values Arguments: CLOUD the name of the cloud Options: --refresh refreshes the data before displaying it from the cloud """ # pprint(arguments) cloud = arguments["CLOUD"] or Default.get_cloud() if arguments["image"]: try: refresh = arguments['--refresh'] or Default.refresh() if refresh: Image.refresh(cloud) image_dict = Image.list(cloud, format="dict") image_names = list() for image in list(image_dict.values()): image_names.append(image["name"]) number = menu_return_num(title="Select an Image", menu_list=image_names, tries=10, with_display=True) if number == "q": pass else: image = image_names[number] print("Selected image " + image) Default.set("image", image, category=cloud) except: print("ERROR: could not set image.") elif arguments["flavor"]: try: refresh = arguments['--refresh'] or Default.refresh() if refresh: Flavor.refresh(cloud) flavor_dict = Flavor.list(cloud, format="dict") flavor_names = list() for flavor in list(flavor_dict.values()): flavor_names.append(flavor["name"]) number = menu_return_num(title="Select a Flavor", menu_list=flavor_names, tries=10, with_display=True) if number == "q": pass else: flavor = flavor_names[number] print("Selected flavor " + flavor) Default.set("flavor", flavor, category=cloud) except: print("ERROR: could not set flavor.") elif arguments["cloud"]: try: config = ConfigDict("cloudmesh.yaml") clouds = config["cloudmesh"]["clouds"] for key in clouds: Console.ok(" " + key) number = menu_return_num(title="Select a cloud", menu_list=list(clouds), tries=10, with_display=True) if number == "q": pass else: cloud = list(clouds)[number] print("Selected cloud " + cloud) Default.set("cloud", cloud, "general") except: print("ERROR: could not set cloud.") elif arguments["key"]: try: db = SSHKeyDBManager() key_dict = db.table_dict() key_names = list() for key in key_dict.values(): key_names.append(key["name"]) number = menu_return_num(title="Select a Key", menu_list=key_names, tries=10, with_display=True) if number == "q": pass else: key = key_names[number] print("Selected key " + key) # TODO Fix default key setting in key DB # db.set_default(key) Default.set("key", key, category=cloud) except: print("ERROR: could not set key") return ""
def do_network(self, args, arguments): """ :: Usage: network get fixed [ip] [--cloud=CLOUD] FIXED_IP network get floating [ip] [--cloud=CLOUD] FLOATING_IP_ID network reserve fixed [ip] [--cloud=CLOUD] FIXED_IP network unreserve fixed [ip] [--cloud=CLOUD] FIXED_IP network associate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network disassociate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network create floating [ip] [--cloud=CLOUD] [--pool=FLOATING_IP_POOL] network delete floating [ip] [--cloud=CLOUD] FLOATING_IP... network list floating pool [--cloud=CLOUD] network list floating [ip] [--cloud=CLOUD] [--instance=INS_ID_OR_NAME] [IP_OR_ID] network create cluster --group=demo_group network -h | --help Options: -h help message --cloud=CLOUD Name of the IaaS cloud e.g. india_openstack_grizzly. --group=GROUP Name of the group in Cloudmesh --pool=FLOATING_IP_POOL Name of Floating IP Pool --instance=INS_ID_OR_NAME ID or Name of the vm instance Arguments: IP_OR_ID IP Address or ID of IP Address FIXED_IP Fixed IP Address, e.g. 10.1.5.2 FLOATING_IP Floating IP Address, e.g. 192.1.66.8 FLOATING_IP_ID ID associated with Floating IP, e.g. 185c5195-e824-4e7b-8581-703abec4bc01 Examples: network get fixed ip --cloud=india 10.1.2.5 network get fixed --cloud=india 10.1.2.5 network get floating ip --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 network get floating --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 network reserve fixed ip --cloud=india 10.1.2.5 network reserve fixed --cloud=india 10.1.2.5 network unreserve fixed ip --cloud=india 10.1.2.5 network unreserve fixed --cloud=india 10.1.2.5 network associate floating ip --cloud=india --instance=albert-001 192.1.66.8 network associate floating --cloud=india --instance=albert-001 network associate floating --cloud=india --group=albert_group network disassociate floating ip --cloud=india --instance=albert-001 192.1.66.8 network disassociate floating --cloud=india --instance=albert-001 192.1.66.8 network create floating ip --cloud=india --pool=albert-f01 network create floating --cloud=india --pool=albert-f01 network delete floating ip --cloud=india 192.1.66.8 192.1.66.9 network delete floating --cloud=india 192.1.66.8 192.1.66.9 network list floating ip --cloud=india network list floating --cloud=india network list floating --cloud=india 192.1.66.8 network list floating --cloud=india --instance=323c5195-7yy34-4e7b-8581-703abec4b network list floating pool --cloud=india network create cluster --group=demo_group """ # pprint(arguments) # Get the cloud parameter OR read default cloudname = arguments["--cloud"] or Default.get_cloud() if cloudname is None: Console.error("Default cloud has not been set!" "Please use the following to set it:\n" "cm default cloud=CLOUDNAME\n" "or provide it via the --cloud=CLOUDNAME argument.") return "" # Fixed IP info if arguments["get"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.get_fixed_ip(cloudname, fixed_ip_addr=fixed_ip) Console.msg(result) # Floating IP info elif arguments["get"] \ and arguments["floating"]: floating_ip_id = arguments["FLOATING_IP_ID"] result = Network.get_floating_ip(cloudname, floating_ip_or_id=floating_ip_id) Console.msg(result) # Reserve a fixed ip elif arguments["reserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.reserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok( "Reserve fixed ip address [{}] complete.".format(fixed_ip)) # Un-Reserve a fixed ip elif arguments["unreserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.unreserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok("Un-Reserve fixed ip address [{}] complete.".format( fixed_ip)) # Associate floating IP elif arguments["associate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] print(floating_ip) # group supplied if group_name is not None: """ Group name has been provided. Assign floating IPs to all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, category=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict 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 "" # Get the instance name instance_name = instance_dict["name"] floating_ip = Network.create_assign_floating_ip( cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok( "Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Refresh VM in db self.refresh_vm(cloudname) else: Console.error( "No group [{}] in the Cloudmesh database.".format( group_name)) return "" # floating-ip not supplied, instance-id supplied elif len(floating_ip) == 0 and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Generate one from the pool, and assign to vm and return """ 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"] floating_ip = Network.create_assign_floating_ip( cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok( "Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Associate the IP to the instance and return """ instance_dict = Network.get_instance_dict( cloudname=cloudname, instance_id=instance_id) floating_ip = floating_ip[0] # 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)) # Invalid parameters else: Console.error( "Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) elif arguments["disassociate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] # group supplied if group_name is not None: """ Group name has been provided. Remove floating IPs of all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, category=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict 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 "" # Get the instance name instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error( "Instance[{}] does not have a floating_ip.". format(instance_name)) return "" result = Network.disassociate_floating_ip( cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok( "Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) else: Console.error( "No group [{}] in the Cloudmesh database.".format( group_name)) return "" # floating-ip not supplied, instance-id supplied elif len(floating_ip) == 0 and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Remove floating ip allocated to vm and return """ 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"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error( "Instance[{}] does not have a floating_ip.".format( instance_name)) return "" result = Network.disassociate_floating_ip( cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok( "Disassociated Floating IP [{}] from instance [{}].". format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Remove the IP from the instance and return """ instance_dict = Network.get_instance_dict( cloudname=cloudname, instance_id=instance_id) floating_ip = floating_ip[0] # 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"] _floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if _floating_ip != floating_ip: Console.error( "Invalid floating_ip [{}] for instance [{}].".format( floating_ip, instance_name)) return "" result = Network.disassociate_floating_ip( cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok( "Disassociated Floating IP [{}] from instance [{}].". format(floating_ip, instance_name)) # Invalid parameters else: Console.error( "Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) # Create new floating ip under floating pool elif arguments["create"] \ and arguments["floating"]: floating_pool = arguments["--pool"] result = Network.create_floating_ip(cloudname=cloudname, floating_pool=floating_pool) if result is not None: Console.ok("Created new floating IP [{}]".format(result)) else: Console.error( "Failed to create floating IP! Please check arguments.") # Delete a floating ip address elif arguments["delete"] \ and arguments["floating"]: floating_ips = arguments["FLOATING_IP"] for floating_ip in floating_ips: result = Network.delete_floating_ip( cloudname=cloudname, floating_ip_or_id=floating_ip) if result is not None: Console.ok(result) else: Console.error("Failed to delete floating IP address!") # Floating IP Pool List elif arguments["list"] \ and arguments["floating"] \ and arguments["pool"]: result = Network.list_floating_ip_pool(cloudname) Console.msg(result) # Floating IP list [or info] elif arguments["list"] \ and arguments["floating"]: ip_or_id = arguments["IP_OR_ID"] instance_id = arguments["--instance"] # Refresh VM in db self.refresh_vm(cloudname) # If instance id is supplied if instance_id is not None: 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 "" # Read the floating_ip from the dict ip_or_id = instance_dict["floating_ip"] if ip_or_id is None: Console.error( "Instance with ID [{}] does not have a floating IP address!" .format(instance_id)) return "" # If the floating ip or associated ID is supplied if ip_or_id is not None: result = Network.get_floating_ip(cloudname, floating_ip_or_id=ip_or_id) if result is not None: Console.msg(result) else: Console.error( "Floating IP not found! Please check your arguments.") return "" # Retrieve the full list else: result = Network.list_floating_ip(cloudname) Console.msg(result) # Create a virtual cluster elif arguments["cluster"] and \ arguments["create"]: group_name = arguments["--group"] or \ Default.get("group", category=cloudname) # Get the group information group = Group.get_info(name=group_name, category=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # var contains pub key of all vms public_keys = "" login_users = [] login_ips = [] # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict 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 "" # Get the instance name instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # If vm does not have floating ip, then create if floating_ip is None: floating_ip = Network.create_assign_floating_ip( cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok( "Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Refresh VM in db self.refresh_vm(cloudname) # Get the login user for this machine user = input("Enter the login user for VM {} : ".format( instance_name)) passphrase = getpass.getpass( "Enter the passphrase key on VM {} : ".format( instance_name)) # create list for second iteration login_users.append(user) login_ips.append(floating_ip) login_args = [ user + "@" + floating_ip, ] keygen_args = [ "ssh-keygen -t rsa -f ~/.ssh/id_rsa -N " + passphrase ] cat_pubkey_args = ["cat ~/.ssh/id_rsa.pub"] generate_keypair = login_args + keygen_args result = Shell.ssh(*generate_keypair) # print("***** Keygen *****") # print(result) cat_public_key = login_args + cat_pubkey_args result = Shell.ssh(*cat_public_key) public_keys += "\n" + result # print("***** id_rsa.pub *****") # print(result) # print("***** public keys *****") # print(public_keys) for user, ip in zip(login_users, login_ips): arguments = [ user + "@" + ip, "echo '" + public_keys + "' >> ~/.ssh/authorized_keys" ] # copy the public key contents to auth_keys result = Shell.ssh(*arguments) Console.ok("Virtual cluster creation successfull.") else: Console.error( "No group [{}] in the Cloudmesh database.".format( group_name)) return "" return ""
def do_group(self, args, arguments): """ :: Usage: group add NAME [--type=TYPE] [--category=CLOUD] --id=IDs group list [--category=CLOUD] [--format=FORMAT] [NAME] group delete NAME [--category=CLOUD] group remove [--category=CLOUD] --name=NAME --id=ID group copy FROM TO group merge GROUPA GROUPB MERGEDGROUP manage the groups Arguments: NAME name of a group FROM name of a group TO name of a group GROUPA name of a group GROUPB name of a group MERGEDGROUP name of a group Options: --category=CLOUD the name of the category --format=FORMAT the output format --type=TYPE the resource type --name=NAME the name of the group --id=IDS the ID(s) to add to the group Description: Todo: design parameters that are useful and match description Todo: discuss and propose command cloudmesh can manage groups of resources and category related objects. As it would be cumbersome to for example delete many virtual machines or delete VMs that are in the same group, but are running in different clouds. Hence it is possible to add a virtual machine to a specific group. The group name to be added to can be set as a default. This way all subsequent commands use this default group. It can also be set via a command parameter. Another convenience function is that the group command can use the last used virtual machine. If a vm is started it will be automatically added to the default group if it is set. The delete command has an optional category parameter so that deletion of vms of a partial group by cloud can be achieved. If finer grained deletion is needed, it can be achieved with the delete command that supports deletion by name It is also possible to remove a VM from the group using the remove command, by supplying the ID Example: default group mygroup group add --type=vm --id=albert-[001-003] adds the vms with teh given name using the Parameter see base group add --type=vm adds the last vm to the group group delete --name=mygroup deletes all objects in the group """ # pprint(arguments) category = arguments["--category"] or Default.get_cloud() if arguments["list"]: output = arguments["--format"] or Default.get("format", category) or "table" name = arguments["NAME"] if name is None: result = Group.list(format=output, category=category) if result: print(result) else: print("There are no groups in the cloudmesh database!") else: result = Group.get_info(name=name, category=category, output=output) if result: print(result) else: msg_a = ("No group found with name `{name}` found in the " "category `{category}`.".format(**locals())) # find alternate result = Group.get(name=name) msg_b = "" if result is not None: msg_b = " However we found such a variable in " \ "category `{category}`. Please consider " \ "using --category={category}".format(**result) Console.error(msg_a + msg_b) return elif arguments["add"]: type = arguments["--type"] or Default.get("type", category) category_id = arguments["--id"] or Default.get("id", category) data = { "name": arguments["NAME"], "type": type, "category": category, "id": category_id } Group.add(**data) return elif arguments["delete"]: data = { "name": arguments["NAME"], "category": category, } result = Group.delete(**data) if result: Console.ok("Deletion completed. ok.") else: Console.error( "No group with name `{name}` found".format(**data)) return elif arguments["remove"]: name = arguments["--name"] category_id = arguments["--id"] if not category: Console.error("Default category not set!") return result = Group.remove(name, category_id, category) if result: Console.ok(result) else: Console.error( "Failed to delete ID [{}] from group [{}] in the database!".format( category_id, name)) return elif arguments["copy"]: _from = arguments["FROM"] _to = arguments["TO"] Group.copy(_from, _to) return elif arguments["merge"]: _groupA = arguments["GROUPA"] _groupB = arguments["GROUPB"] _mergedGroup = arguments["MERGEDGROUP"] Group.merge(_groupA, _groupB, _mergedGroup) return
def do_list(self, args, arguments): """ :: Usage: list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] default list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] vm list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] flavor list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] image List the items stored in the database Options: --cloud=CLOUD the name of the cloud --format=FORMAT the output format --tenant=TENANT Name of the tenant, e.g. fg82. Description: List command prints the values stored in the database for [default/vm/flavor/image]. Result can be filtered based on the cloud, user & tenant arguments. If these arguments are not specified, it reads the default Examples: $ list --cloud india default $ list --cloud india --format table flavor $ list --cloud india --user albert --tenant fg82 flavor """ # pprint(arguments) # Method to get the kind from args # # TODO: the kind are defined in the provider, # TODO: keep the kind lower case # why is there a reason to make the gind upper case def get_kind(): for k in ["vm", "image", "flavor", "default"]: if arguments[k]: # kinds are all uppercase in model.py return k.upper() return "help" # Read commandline arguments output_format = arguments['--format'] cloud = arguments['--cloud'] or Default.get_cloud() user = arguments['--user'] tenant = arguments['--tenant'] # If format is not specified, read default if output_format is None: output_format = Default.get("format") or "table" # If cloud is not specified, get default if cloud is None: cloud = Default.get("cloud") or "kilo" # If user is not specified, get default if user is None: user = Default.get("user") # If tenant is not specified, get default if tenant is None: tenant = Default.get("tenant") # Get the kind kind = get_kind() header = None order = None # print help message if kind == 'help': Console.ok("Print help!") return "" # Prepare the order & header based on kind # TODO: use lower case so we have a convention thats easy to follow # TODO: add quota # TODO: add limits # TODO: add usage if kind == 'FLAVOR': order = [ 'cm_cloud', 'disk', 'ephemeral_disk', 'id', 'name', 'ram', 'vcpus' ] elif kind == 'DEFAULT': order = ['user', 'cloud', 'name', 'value', 'created_at', 'updated_at' ] elif kind == 'IMAGE': order = [ 'cm_cloud', 'cm_user', 'instance_type_ephemeral_gb', 'instance_type_flavorid', 'instance_type_id', 'instance_type_memory_mb', 'instance_type_name', 'instance_type_root_gb', 'instance_type_rxtx_factor', 'instance_type_swap', 'instance_type_vcpus', 'minDisk', 'minRam', 'name', ] header = [ 'cloud', 'user', 'ephemeral_gb', 'flavorid', 'id', 'memory_mb', 'flavor', 'root_gb', 'rxtx_factor', 'swap', 'vcpus', 'minDisk', 'minRam', 'name', ] # Get the result & print it result = List.list(kind, cloud, user, tenant, order, header, output_format) if result: print(result) else: Console.error("No {}s found in the database." .format(kind.lower())) return ""
def do_launcher(self, args, arguments): """ :: Usage: launcher list [--cloud=CLOUD] [--format=FORMAT] [--all] launcher delete KEY [--cloud=CLOUD] launcher run launcher resume launcher suspend launcher details launcher clear launcher refresh Arguments: KEY the name of the launcher Options: --cloud=CLOUD the name of the cloud --format=FORMAT the output format [launcher: table] --all lists all the launcher values Description: Launcher is a command line tool to test the portal launch functionalities through command The current launcher values can by listed with --all option:( if you have a launcher cloud specified. You can also add a cloud parameter to apply the command to a specific cloud) launcher list A launcher can be deleted with launcher delete KEY Examples: launcher list --all launcher list --cloud=general launcher delete <KEY> """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() launcher = Launcher(kind=None) if cloud is None: Console.error("Default cloud not set") return if arguments["list"]: result = launcher.list() print(result) elif arguments["delete"]: result = launcher.delete() print(result) elif arguments["run"]: result = launcher.run() print(result) elif arguments["resume"]: result = launcher.resume() print(result) elif arguments["suspend"]: result = launcher.suspend() print(result) elif arguments["details"]: result = launcher.details() print(result) elif arguments["clear"]: result = launcher.clear() print(result) elif arguments["refresh"]: result = launcher.refresh() print(result)
def do_key(self, args, arguments): """ :: Usage: key -h | --help key list [--source=db] [--format=FORMAT] key list --source=cloudmesh [--format=FORMAT] key list --source=ssh [--dir=DIR] [--format=FORMAT] key load [--format=FORMAT] key list --source=git [--format=FORMAT] [--username=USERNAME] key add --git [--name=KEYNAME] FILENAME key add --ssh [--name=KEYNAME] key add [--name=KEYNAME] FILENAME key get NAME key default [KEYNAME | --select] key delete (KEYNAME | --select | --all) [--force] key upload [KEYNAME] [--cloud=CLOUD] key map [--cloud=CLOUD] Manages the keys Arguments: SOURCE db, ssh, all KEYNAME The name of a key. For key upload it defaults to the default key name. FORMAT The format of the output (table, json, yaml) FILENAME The filename with full path in which the key is located NAME_ON_CLOUD Typically the name of the keypair on the cloud. Options: --dir=DIR the directory with keys [default: ~/.ssh] --format=FORMAT the format of the output [default: table] --source=SOURCE the source for the keys [default: db] --username=USERNAME the source for the keys [default: none] --name=KEYNAME The name of a key --all delete all keys --force delete the key form the cloud --name_on_cloud=NAME_ON_CLOUD Typically the name of the keypair on the cloud. Description: 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] [--format=FORMAT] lists all keys in the directory. If the directory is not specified the default will be ~/.ssh key list --source=cloudmesh [--dir=DIR] [--format=FORMAT] lists all keys in cloudmesh.yaml file in the specified directory. dir is by default ~/.cloudmesh key list [--format=FORMAT] list the keys in teh giiven format: json, yaml, table. table is default key list Prints list of keys. NAME of the key can be specified key add [--name=keyname] FILENAME adds the key specifid by the filename to the key database key get NAME Retrieves the key indicated by the NAME parameter from database and prints its fingerprint. key default [NAME] Used to set a key from the key-list as the default key if NAME is given. Otherwise print the current default key key delete NAME deletes a key. In yaml mode it can delete only key that are not saved in the database key rename NAME NEW renames the key from NAME to NEW. """ # pprint(arguments) def _print_dict(d, header=None, format='table'): if format == "json": return json.dumps(d, indent=4) elif format == "yaml": return yaml.dump(d, default_flow_style=False) elif format == "table": return dict_printer( d, order=["name", "comment", "uri", "fingerprint", "source"], output="table", sort_keys=True) else: return d # return dict_printer(d,order=['cm_id, name, fingerprint']) directory = Config.path_expand(arguments["--dir"]) if arguments['list']: _format = arguments['--format'] _source = arguments['--source'] _dir = arguments['--dir'] if arguments['--source'] == 'ssh': try: sshm = SSHKeyManager() sshm.get_from_dir(directory) d = dict(sshm.__keys__) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem listing keys from ssh") elif arguments['--source'] in ['cm', 'cloudmesh']: try: sshm = SSHKeyManager() m = sshm.get_from_yaml(load_order=directory) d = dict(m.__keys__) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem listing keys from `{:}`".format( arguments['--source'])) elif arguments['--source'] in ['git']: username = arguments["--username"] # print(username) if username == 'none': conf = ConfigDict("cloudmesh.yaml") username = conf["cloudmesh.github.username"] sshm = SSHKeyManager() try: sshm.get_from_git(username) d = dict(sshm.__keys__) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem listing git keys from database") return "" elif arguments['--source'] == 'db': try: sshdb = SSHKeyDBManager() d = sshdb.table_dict() if d != {}: print(_print_dict(d, format=arguments['--format'])) msg = "info. OK." Console.ok(msg) else: Console.error("No keys in the database") except Exception as e: Error.traceback(e) Console.error("Problem listing keys from database") elif arguments['load']: _format = arguments['--format'] _dir = arguments['--dir'] try: sshm = SSHKeyManager() m = sshm.get_from_yaml(load_order=directory) d = dict(m.__keys__) sshdb = SSHKeyDBManager() for keyname in m.__keys__: filename = m[keyname]["path"] try: sshdb.add(filename, keyname, source="yaml", uri="file://" + filename) except Exception as e: Console.error("problem adding key {}:{}".format( keyname, filename)) print(_print_dict(d, format=_format)) msg = "info. OK." Console.ok(msg) except Exception as e: Console.error("Problem adding keys from yaml file") elif arguments['get']: try: name = arguments['NAME'] sshdb = SSHKeyDBManager() d = sshdb.table_dict() for i in d: if d[i]["name"] == name: key = d[i] print("{:}: {:}".format(key['name'], key['fingerprint'])) msg = "info. OK." Console.ok(msg) return "" else: pass Console.error("The key is not in the database") except Exception as e: Error.traceback(e) Console.error("The key is not in the database") # key add --git KEYNAME # key add --ssh KEYNAME # key add [--path=PATH] KEYNAME elif arguments['add'] and arguments["--git"]: print('git add') sshdb = SSHKeyDBManager() keyname = arguments['--name'] gitkeyname = arguments['NAME'] filename = arguments['FILENAME'] # Are we adding to the database as well? # sshdb.add(filename, keyname, source="ssh", uri="file://"+filename) username = arguments["--username"] if username == 'none': conf = ConfigDict("cloudmesh.yaml") username = conf["cloudmesh.github.username"] print(username) sshm = SSHKeyManager() try: sshm.get_from_git(username) d = dict(sshm.__keys__) print(d) except Exception as e: Error.traceback(e) Console.error("Problem adding keys to git for user: "******"" try: # FIXME: correct code to add to git d[gitkeyname]['keyname'] = keyname d[gitkeyname]['user'] = None d[gitkeyname]['source'] = 'git' # sshdb.add_from_dict(d[gitkeyname]) except Exception as e: Console.error("The key already exists") elif arguments['add'] and arguments["--ssh"]: # print('ssh add') sshdb = SSHKeyDBManager() keyname = arguments['--name'] filename = Config.path_expand("~/.ssh/id_rsa.pub") try: sshdb.add(filename, keyname, source="ssh", uri="file://" + filename) print("Key {:} successfully added to the database".format( keyname or "")) msg = "info. OK." Console.ok(msg) except Exception as e: """ Error.traceback(e) print (keyname) print (filename) """ Console.error( "Problem adding the key `{}` from file `{}`".format( keyname, filename)) elif arguments['add'] and not arguments["--git"]: # print('ssh add') sshdb = SSHKeyDBManager() keyname = arguments['--name'] filename = arguments['FILENAME'] try: sshdb.add(filename, keyname, source="ssh", uri="file://" + filename) print("Key {:} successfully added to the database".format( keyname or "")) msg = "info. OK." Console.ok(msg) except ValueError as e: Console.error("The key `{}` already exists".format(keyname), traceflag=False) """ except Exception as e: Error.traceback(e) print (keyname) print (filename) Console.error("Problem adding the key `{}` from file `{}`".format(keyname, filename)) """ return "" elif arguments['default']: # print("default") if arguments['KEYNAME']: keyname = None try: keyname = arguments['KEYNAME'] sshdb = SSHKeyDBManager() sshdb.set_default(keyname) Default.set_key(keyname) print("Key {:} set as default".format(keyname)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Setting default for key {:} failed.".format(keyname)) elif arguments['--select']: keyname = None try: sshdb = SSHKeyDBManager() select = sshdb.select() if select != 'q': keyname = select.split(':')[0] print("Setting key: {:} as default.".format(keyname)) sshdb.set_default(keyname) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Setting default for selected key {:} failed.".format( keyname)) else: try: sshdb = SSHKeyDBManager() d = sshdb.table_dict() for i in d: if d[i]["is_default"] == "True": key = d[i] print("{:}: {:}".format(key['name'], key['fingerprint'])) msg = "info. OK." Console.ok(msg) return "" else: pass Console.error("The key is not in the database") except Exception as e: Error.traceback(e) Console.error("Problem retrieving default key.") elif arguments['delete']: delete_on_cloud = arguments["--force"] or False # print ("DDD", delete_on_cloud) if arguments['--all']: try: sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud) sshm.delete_all_keys() print("All keys from the database deleted successfully.") msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem deleting keys") elif arguments['--select']: keyname = None sshdb = SSHKeyDBManager() select = sshdb.select() if select != 'q': try: keyname = select.split(':')[0] print("Deleting key: {:}...".format(keyname)) sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud) sshm.delete_key(keyname) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Problem deleting the key `{:}`".format(keyname)) else: keyname = None try: keyname = arguments['KEYNAME'] sshm = SSHKeyManager(delete_on_cloud=delete_on_cloud) sshm.delete_key(keyname) print("Key {:} deleted successfully from database.".format( keyname)) msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error( "Problem deleting the key `{:}`".format(keyname)) elif arguments['upload']: try: # # get username # conf = ConfigDict("cloudmesh.yaml") username = conf["cloudmesh"]["profile"]["username"] if username in ['None', 'TBD']: username = None # # get cloudnames # clouds = [] cloud = arguments["--cloud"] or Default.get_cloud() if cloud == "all": config = ConfigDict("cloudmesh.yaml") clouds = config["cloudmesh"]["clouds"] else: clouds.append(cloud) # # get keyname # for cloud in clouds: status = 0 sshdb = SSHKeyDBManager() sshm = SSHKeyManager() keys = sshdb.find_all() for keyid in keys: key = keys[keyid] print("upload key {} -> {}".format(key["name"], cloud)) try: status = sshm.add_key_to_cloud( username, key["name"], cloud, key["name"]) except Exception as e: print(e) if "already exists" in str(e): print("key already exists. Skipping " "upload. ok.") if status == 1: print("Problem uploading key. failed.") msg = "info. OK." Console.ok(msg) except Exception as e: Error.traceback(e) Console.error("Problem adding key to cloud") elif arguments['map']: try: cloud = arguments["--cloud"] or Default.get_cloud() sshm = SSHKeyManager() map_dict = sshm.get_key_cloud_maps(cloud) print( dict_printer(map_dict, order=[ "user", "key_name", "cloud_name", "key_name_on_cloud" ])) except Exception as e: Error.traceback(e) Console.error("Problem adding key to cloud")
def do_flavor(self, args, arguments): """ :: Usage: flavor refresh [--cloud=CLOUD] [-v] flavor list [ID] [--cloud=CLOUD] [--format=FORMAT] [--refresh] [-v] This lists out the flavors present for a cloud Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --refresh refreshes the data before displaying it from the cloud Examples: cm flavor refresh cm flavor list cm flavor list --format=csv cm flavor show 58c9552c-8d93-42c0-9dea-5f48d90a3188 --refresh """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") return if arguments["-v"]: print ("Cloud: {}".format(cloud)) if arguments["refresh"] or Default.refresh(): msg = "Refresh flavor for cloud {:}.".format(cloud) if Flavor.refresh(cloud): Console.ok("{:} ok".format(msg)) else: Console.error("{:} failed".format(msg)) return "" if arguments["list"]: id = arguments['ID'] live = arguments['--refresh'] output_format = arguments["--format"] counter = 0 result = None while counter < 2: if id is None: result = Flavor.list(cloud, output_format) else: result = Flavor.details(cloud, id, live, output_format) if counter == 0 and result is None: if not Flavor.refresh(cloud): msg = "Refresh flavor for cloud {:}.".format(cloud) Console.error("{:} failed.".format(msg)) counter += 1 if result is None: Console.error("No image(s) found. Failed.") else: print(result) return ""