def _delete(self, arg): if arg.cloud is None: Console.ok("Delete secgroup {GROUP}".format(**arg)) SecGroup.delete(group=arg.GROUP) else: Console.ok("Delete secgroup {cloud}:{GROUP}".format(**arg)) result = SecGroup.delete_secgroup(name=arg.GROUP, cloud=arg.cloud) if result is not None: Console.ok("Security Group={GROUP} in cloud={cloud} deleted successfully." .format(**arg)) else: Console.error("Failed to delete Security Group={GROUP} in cloud={cloud}" .format(**arg))
def _delete(self, arg): if arg.cloud is None: Console.ok("Delete secgroup {GROUP}".format(**arg)) SecGroup.delete(group=arg.GROUP) else: Console.ok("Delete secgroup {cloud}:{GROUP}".format(**arg)) result = SecGroup.delete_secgroup(name=arg.GROUP, cloud=arg.cloud) if result is not None: Console.ok( "Security Group={GROUP} in cloud={cloud} deleted successfully." .format(**arg)) else: Console.error( "Failed to delete Security Group={GROUP} in cloud={cloud}". format(**arg))
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 __init__(self, context): cmd.Cmd.__init__(self) self.variables = {} self.command_topics = {} self.register_topics() self.context = context # TODO get loglevel from DB or yaml file, if not defined set to ERROR self.loglevel = "DEBUG" self._hist = [] if self.context.debug: print("init CloudmeshConsole") self.prompt = 'cm> ' self.doc_header = "Documented commands (type help <command>):" self.banner = textwrap.dedent(""" +=======================================================+ . ____ _ _ _ . . / ___| | ___ _ _ __| |_ __ ___ ___ ___| |__ . . | | | |/ _ \| | | |/ _` | '_ ` _ \ / _ \/ __| '_ \ . . | |___| | (_) | |_| | (_| | | | | | | __/\__ \ | | | . . \____|_|\___/ \__,_|\__,_|_| |_| |_|\___||___/_| |_| . +=======================================================+ Cloudmesh Shell """) # KeyCommands.__init__(self, context) # # set default cloud and default group if they do not exist # use the first cloud in cloudmesh.yaml as default # Console.set_debug(Default.debug) filename = path_expand("~/.cloudmesh/cloudmesh.yaml") # moved to import cloudmesh_client # create_cloudmesh_yaml(filename) setup_yaml() # Initialize Logging # LogUtil.initialize_logging() # sys,exit(1) # ################## # DEFAULTS # # # SET DEFAULT CLOUD # value = Default.get(name='cloud', category='general') if value is None: config = ConfigDict(filename=filename)["cloudmesh"] if 'active' in config: cloud = config["active"][0] else: clouds = config["clouds"] cloud = list(clouds.keys())[0] Default.set('cloud', cloud, category='general') # # NOT SURE WHAT THIS IS FOR # value = Default.get(name='default', category='general') if value is None: Default.set('default', 'default', category='general') # # SET DEFAULT CLUSTER # ''' cluster = ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["active"][0] value = Default.get(name='cluster', category='general') if value is None: try: hosts = ssh_config().names() if hosts is not None: cluster = hosts[0] except: pass # use the hardcoded cluster else: cluster = value Default.set('cluster', cluster, category='general') ''' # # SET DEFAULT GROUP # group = Default.group if group is None: Default.set_group("default") # # LOAD DEFAULTS FROM YAML # Default.load("cloudmesh.yaml") try: d = Key.get_from_dir("~/.ssh", store=False) except Exception as e: Console.error(e.message) # # SET DEFAULT TIMER # on = Default.timer # # SET DEFUALT SECGROUP # # # SET DEFAULT REFRESH # # r = Default.refresh # print ("REFRESH", r) # if r is None: # Default.set_refresh("on") # # SET DEFAULT USER # user = Default.user if user is None: user = ConfigDict(filename=filename)["cloudmesh"]["profile"]["user"] Default.set_user(user) r = Default.secgroup if r is None: secgroup = "{}-default".format(Default.user) Default.set_secgroup(secgroup) SecGroup.add_rule_to_db(group=secgroup, name="ssh",from_port="22",to_port="22",protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="http",from_port="80",to_port="80",protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="https", from_port="443", to_port="443", protocol="tcp", cidr="0.0.0.0/0") """ try: sshm = SSHKeyManager() m = sshm.get_from_yaml( load_order="~/.cloudmesh/cloudmesh.yaml") 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: pass except Exception as e: Console.error("Problem adding keys from yaml file") """ for c in CloudmeshConsole.__bases__[1:]: # noinspection PyArgumentList c.__init__(self, context)
def do_vm(self, args, arguments): """ :: Usage: vm default [--cloud=CLOUD][--format=FORMAT] vm refresh [all][--cloud=CLOUD] vm boot [--name=NAME] [--cloud=CLOUD] [--username=USERNAME] [--image=IMAGE] [--flavor=FLAVOR] [--group=GROUP] [--public] [--secgroup=SECGROUP] [--key=KEY] [--dryrun] vm boot [--n=COUNT] [--cloud=CLOUD] [--username=USERNAME] [--image=IMAGE] [--flavor=FLAVOR] [--group=GROUP] [--public] [--secgroup=SECGROUP] [--key=KEY] [--dryrun] vm ping [NAME] [N] vm console [NAME] [--group=GROUP] [--cloud=CLOUD] [--force] vm start [NAMES] [--group=GROUP] [--cloud=CLOUD] [--force] vm stop [NAMES] [--group=GROUP] [--cloud=CLOUD] [--force] vm terminate [NAMES] [--group=GROUP] [--cloud=CLOUD] [--force] vm delete [NAMES] [--group=GROUP] [--cloud=CLOUD] [--keep] [--dryrun] vm ip assign [NAMES] [--cloud=CLOUD] vm ip show [NAMES] [--group=GROUP] [--cloud=CLOUD] [--format=FORMAT] [--refresh] vm ip inventory [NAMES] [--header=HEADER] [--file=FILE] vm ssh [NAME] [--username=USER] [--quiet] [--ip=IP] [--cloud=CLOUD] [--key=KEY] [--command=COMMAND] vm rename [OLDNAMES] [NEWNAMES] [--force] [--dryrun] vm list [NAMES] [--cloud=CLOUDS|--active] [--group=GROUP] [--format=FORMAT] [--refresh] vm status [NAMES] vm wait [--cloud=CLOUD] [--interval=SECONDS] vm info [--cloud=CLOUD] [--format=FORMAT] vm check NAME vm username USERNAME [NAMES] [--cloud=CLOUD] 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. NAMES server name. By default it is set to the name of last vm from database. KEYPAIR_NAME Name of the openstack keypair to be used to create VM. Note this is not a path to key. NEWNAMES New names of the VM while renaming. OLDNAMES Old names of the VM while renaming. Options: --username=USERNAME the username to login into the vm. If not specified it will be guessed from the image name and the cloud --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 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 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 rename/ delete vms without user's confirmation --command=COMMAND specify the commands to be executed Description: commands used to boot, start or delete servers of a cloud vm default [options...] Displays default parameters that are set for vm boot either on the default cloud or the specified cloud. 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 ssh [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'] Quoting commands: cm vm login gvonlasz-004 --command=\"uname -a\" """ """ # terminate # issues a termination to the cloud, keeps vm in database # delete # issues a terminate if not already done # (remember you do not have to go to cloud if state is already terminated) # deletes the vm from database # # bulk rename rename abc[0-1] def[3-4] renames the abc0,abc1 -> def3,def4 if arguments["rename"]: oldnames = Parameter.expand(arguments["OLDNAME"]) newnames = Parameter.expand(arguments["NEWNAME"]) # check if new names ar not already taken # to be implemented if len(oldnames) == len(newnames): for i in range(0, len(oldnames)): oldname = oldnames[i] newname = newnames[i] if newname is None or newname == '': print("New node name cannot be empty") else: print(Cluster.rename_node(clusterid, oldname, newname)) """ cm = CloudmeshDatabase() def _print_dict(d, header=None, output='table'): return Printer.write(d, order=["id", "name", "status"], output=output, sort_keys=True) def _print_dict_ip(d, header=None, output='table'): return Printer.write(d, order=["network", "version", "addr"], output=output, sort_keys=True) def get_vm_name(name=None, offset=0, fill=3): if name is None: count = Default.get_counter(name='name') + offset prefix = Default.user if prefix is None or count is None: Console.error("Prefix and Count could not be retrieved correctly.", traceflag=False) return name = prefix + "-" + str(count).zfill(fill) return name def _refresh_cloud(cloud): try: msg = "Refresh VMs for cloud {:}.".format(cloud) if Vm.refresh(cloud=cloud): Console.ok("{:} OK.".format(msg)) else: Console.error("{:} failed".format(msg), traceflag=False) except Exception as e: Console.error("Problem running VM refresh", traceflag=False) def _get_vm_names(): vm_list = cm.find(kind="vm") vms = [vm["name"] for vm in vm_list] names = pattern = arguments["NAMES"] if pattern is not None: if "*" in pattern: names = search(vms, pattern) else: names = Parameter.expand(names) if names == ['last'] or names is None: names == [Default.vm] return vm_list, names cloud = arguments["--cloud"] or Default.cloud config = ConfigDict("cloudmesh.yaml") active_clouds = config["cloudmesh"]["active"] def _refresh(cloud): all = arguments["all"] or None if all is None: _refresh_cloud(cloud) else: for cloud in active_clouds: _refresh_cloud(cloud) arg = dotdict(arguments) arg.cloud = arguments["--cloud"] or Default.cloud arg.image = arguments["--image"] or Default.get(name="image", category=arg.cloud) arg.flavor = arguments["--flavor"] or Default.get(name="flavor", category=arg.cloud) arg.group = arguments["--group"] or Default.group arg.secgroup = arguments["--secgroup"] or Default.secgroup arg.key = arguments["--key"] or Default.key arg.dryrun = arguments["--dryrun"] arg.name = arguments["--name"] arg.format = arguments["--format"] or 'table' arg.refresh = Default.refresh or arguments["--refresh"] arg.count = int(arguments["--n"] or 1) arg.dryrun = arguments["--dryrun"] arg.verbose = not arguments["--quiet"] # # in many cases use NAMES # if arg.NAMES is not None: # arg.names = Parameter.expand(arg.NAMES) # gvonlasz[001-002] gives ["gvonlasz-001", "gvonlasz-002"] # else: # arg.names = None # if arguments["boot"]: arg.username = arguments["--username"] or Image.guess_username(arg.image) is_name_provided = arg.name is not None arg.user = Default.user for index in range(0, arg.count): vm_details = dotdict({ "cloud": arg.cloud, "name": get_vm_name(arg.name, index), "image": arg.image, "flavor": arg.flavor, "key": arg.key, "secgroup": arg.secgroup, "group": arg.group, "username": arg.username, "user": arg.user }) # correct the username vm_details.username = Image.guess_username_from_category( vm_details.cloud, vm_details.image, username=arg.username) try: if arg.dryrun: print(Printer.attribute(vm_details, output=arg.format)) msg = "dryrun info. OK." Console.ok(msg) else: vm_id = Vm.boot(**vm_details) if vm_id is None: msg = "info. failed." Console.error(msg, traceflag=False) return "" # set name and counter in defaults Default.set_vm(value=vm_details.name) if is_name_provided is False: Default.incr_counter("name") # Add to group if vm_id is not None: Group.add(name=vm_details.group, species="vm", member=vm_details.name, category=vm_details.cloud) msg = "info. OK." Console.ok(msg) except Exception as e: Console.error("Problem booting instance {name}".format(**vm_details), traceflag=False) elif arguments["username"]: arg.username = arguments["--username"] or Image.guess_username(arg.image) cloud = arg.cloud username = arg.USERNAME if arg.NAMES is None: names = [Default.vm] else: names = Parameter.expand(arg.NAMES) if len(names) == 0: return for name in names: arg.name = name Console.ok("Set username for {cloud}:{name} to {USERNAME}".format(**arg)) Vm.set_login_user(name=name, cloud=cloud, username=username) elif arguments["default"]: try: count = Default.get_counter() prefix = Username() if prefix is None or count is None: Console.error("Prefix and Count could not be retrieved correctly.", traceflag=False) return vm_name = prefix + "-" + str(count).zfill(3) arg = { "name": vm_name, "cloud": arguments["--cloud"] or Default.cloud } for attribute in ["image", "flavor"]: arg[attribute] = Default.get(name=attribute, category=cloud) for attribute in ["key", "group", "secgroup"]: arg[attribute] = Default.get(name=attribute, category='general') output = arguments["--format"] or "table" print(Printer.attribute(arg, output=output)) 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", traceflag=False) elif arguments["ping"]: try: if arguments["NAME"] is None and arguments["N"] is None: name = arguments["NAME"] or Default.vm n = arguments["N"] or 1 elif arguments["NAME"].isdigit(): n = arguments["NAME"] name = Default.vm else: name = arguments["NAME"] or Default.vm n = arguments["N"] or 1 print("Ping:", name, str(n)) vm = dotdict(Vm.list(name=name, category=cloud, output="dict")["dict"]) ip = vm.floating_ip result = Shell.ping(host=ip, count=n) print(result) except Exception as e: Console.error(e.message, traceflag=False) elif arguments["console"]: try: name = arguments["NAME"] or Default.vm vm = dotdict(Vm.list(name=name, category=cloud, output="dict")["dict"]) cloud_provider = CloudProvider(cloud).provider vm_list = cloud_provider.list_console(vm.uuid) print(vm_list) msg = "info. OK." Console.ok(msg) except Exception as e: # Error.traceback(e) Console.error("Problem retrieving status of the VM", traceflag=False) elif arguments["status"]: try: cloud_provider = CloudProvider(cloud).provider vm_list = cloud_provider.list_vm(cloud) vms = [vm_list[i]["name"] for i in vm_list ] print ("V", vms) pattern = arguments["NAMES"] if pattern is not None: if "*" in pattern: print ("serach") names = search(vms, pattern) else: names = Parameter.expand() for i in vm_list: if vm_list[i]["name"] in names: print("{} {}".format(vm_list[i]["status"], vm_list[i]["name"])) else: print("{} {}".format(vm_list[0]["status"], vm_list[0]["name"])) except Exception as e: # Error.traceback(e) Console.error("Problem retrieving status of the VM", traceflag=True) elif arguments["wait"]: interval = arguments["--interval"] or 5 try: cloud_provider = CloudProvider(cloud).provider for i in range(1,10): vm_list = cloud_provider.list_vm(cloud) time.sleep(float(1)) d = {} for id in vm_list: vm = vm_list[id] d[vm["name"]] = vm["status"] print (d) print("{} {}".format(vm_list[0]["status"], vm_list[0]["name"])) if vm_list[0]["status"] in ['ACTIVE']: return except Exception as e: # Error.traceback(e) Console.error("Problem retrieving status of the VM", traceflag=True) 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(Printer.attribute(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", traceflag=False) elif arguments["check"]: test = {} try: names = Parameter.expand(arguments["NAME"]) id = 0 for name in names: print("Not implemented: {}".format(name)) # TODO: check the status of the vms status = "active" # TODO: check if they have a floating ip # TODO: get ip floating_ip = "127.0.0.1" ip = True # ping # TODO: ping the machine with the shell command ping = True # check if one can login and run a command check = False try: r = Shell.execute("uname", "-a") # do a real check check = True except: check = False test[name] = { "id": id, "name": name, "status": status, "ip": ip, "ping": ping, "login": check } id += 1 pprint(test) print(Printer.write(test, order=["id", "name", "status", "ip", "ping", "login"], output="table", sort_keys=True)) msg = "not yet implemented. failed." Console.error(msg, traceflag=False) except Exception as e: # Error.traceback(e) Console.error("Problem retrieving status of the VM", traceflag=False) elif arguments["start"]: try: servers = Parameter.expand(arguments["NAMES"]) # If names not provided, take the last vm from DB. if len(servers) == 0: last_vm = Default.vm if last_vm is None: Console.error("No VM records in database. Please run vm refresh.", traceflag=False) 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.", traceflag=False) 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", traceflag=False) elif arguments["stop"]: try: servers = Parameter.expand(arguments["NAMES"]) # If names not provided, take the last vm from DB. if servers is None or len(servers) == 0: last_vm = Default.vm if last_vm is None: Console.error("No VM records in database. Please run vm refresh.", traceflag=False) 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.", traceflag=False) 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", traceflag=False) elif arguments["refresh"]: _refresh(cloud) elif arguments["delete"]: dryrun = arguments["--dryrun"] group = arguments["--group"] force = not arguments["--keep"] cloud = arguments["--cloud"] vms, servers = _get_vm_names() if servers in [None, []]: Console.error("No vms found.", traceflag=False) return "" for server in servers: if dryrun: Console.ok("Dryrun: delete {}".format(server)) else: Vm.delete(servers=[server], force=force) return "" elif arguments["ip"] and arguments["assign"]: if arguments["NAMES"] is None: names = [Default.vm] else: names = Parameter.expand(arguments["NAMES"]) for name in names: # ip = Network.get_floatingip(....) vm = dotdict(Vm.list(name=name, category=cloud, output="dict")["dict"]) if vm.floating_ip is None: Console.ok("Assign IP to {}".format(name)) try: floating_ip = Network.find_assign_floating_ip(cloudname=cloud, instance_id=name) Vm.refresh(cloud=cloud) if floating_ip is not None: print( "Floating IP assigned to {:} is {:}".format( name, floating_ip)) msg = "info. OK." Console.ok(msg) except Exception as e: Console.error("Problem assigning floating ips.", traceflag=False) else: Console.error("VM {} already has a floating ip: {}".format(name, vm.floating_ip), traceflag=False) elif arguments["ip"] and arguments["inventory"]: vms, names = _get_vm_names() if names in [None, []]: if str(Default.vm) in ['None', None]: Console.error("The default vm is not set.", traceflag=False) return "" else: names = [Default.vm] header = arguments["--header"] or "[servers]" filename = arguments["--file"] or "inventory.txt" try: vm_ips = [] for vm in vms: if vm["name"] in names: print (vm["name"]) vm_ips.append(vm["floating_ip"]) result = header + "\n" result += '\n'.join(vm_ips) Console.ok("Creating inventory file: {}".format(filename)) Console.ok(result) with open(filename, 'w') as f: f.write(result) except Exception as e: Console.error("Problem getting ip addresses for instance", traceflag=True) elif arguments["ip"] and arguments["show"]: if arguments["NAMES"] is None: if str(Default.vm) in ['None', None]: Console.error("The default vm is not set.", traceflag=False) return "" else: names = [Default.vm] else: names = Parameter.expand(arguments["NAMES"]) group = arguments["--group"] output_format = arguments["--format"] or "table" refresh = arguments["--refresh"] try: ips = Ip.list(cloud=arg.cloud, output=output_format, names=names) print(ips) except Exception as e: Console.error("Problem getting ip addresses for instance", traceflag=False) elif arguments["ssh"]: def _print(msg): if arg.verbose: Console.msg(msg) chameleon = "chameleon" in ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["clouds"][arg.cloud][ "cm_host"] if chameleon: arg.username = "******" elif arg.cloud == "azure": arg.username = ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["clouds"]["azure"]["default"]["username"] else: if arg.username is None: Console.error("Could not guess the username of the vm", traceflag=False) return arg.username = arguments["--username"] or Image.guess_username(arg.image) arg.command = arguments["--command"] data = dotdict({ 'name': arguments["NAME"] or Default.vm, 'username': arg.username, 'cloud': arg.cloud, 'command': arg.command }) _print("login {cloud}:{username}@{name}".format(**data)) vm = Vm.get(data.name, category=data.cloud) Vm.set_login_user(name=data.name, cloud=data.cloud, username=data.username) data.floating_ip = vm.floating_ip data.key = arguments["--key"] or Default.key _print(Printer.attribute(data)) ''' if vm.username is None: user_from_db = Vm.get_login_user(vm.name, vm.cloud) user_suggest = user_from_db or Default.user username = input("Username (Default: {}):".format(user_suggest)) or user_suggest Vm.set_login_user(name=data.name, cloud=cloud, username=data.username) ''' ip = arguments["--ip"] commands = arguments["--command"] ip_addresses = [] cloud_provider = CloudProvider(cloud).provider ip_addr = cloud_provider.get_ips(vm.name) ipaddr_dict = Vm.construct_ip_dict(ip_addr, cloud) for entry in ipaddr_dict: ip_addresses.append(ipaddr_dict[entry]["addr"]) if len(ip_addresses) > 0: if ip is not None: if ip not in ip_addresses: Console.error("IP Address specified does not match with the host.", traceflag=False) 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: # Evading ping test, as ping is not enabled for VMs on Azure cloud # 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("Unable to connect to the machine") return "" else: _print("IP to be used is: {:}".format(ip)) # # TODO: is this correctly implemented # if not cloud == 'azure': SecGroup.enable_ssh(cloud=cloud) if arg.verbose: Console.info("Connecting to Instance at IP:" + format(ip)) # Constructing the ssh command to connect to the machine. sshcommand = "ssh" if arg.key is not None: sshcommand += " -i {:}".format(arg.key) sshcommand += " -o StrictHostKeyChecking=no" sshcommand += " {:}@{:}".format(data.username, ip) if commands is not None: sshcommand += " \"{:}\"".format(commands) # print(sshcommand) os.system(sshcommand) else: Console.error("No Public IPs found for the instance", traceflag=False) elif arguments["list"]: # groups = Group.list(output="dict") arg = dotdict(arguments) arg.names = arguments["NAMES"] arg.group = arguments["--group"] if arg.group is None: arg.group = [] else: arg.group = Parameter.expand(arguments["--group"]) arg.refresh = arguments["--refresh"] or Default.refresh if arg.NAMES is not None: arg.names = Parameter.expand(arguments["NAMES"]) else: arg.names = ["all"] _format = arguments["--format"] or "table" if arguments["--active"]: clouds = active_clouds else: if arguments["--cloud"]: clouds = Parameter.expand(arguments["--cloud"]) else: clouds = [Default.cloud] try: d = ConfigDict("cloudmesh.yaml") for cloud in clouds: if arg.refresh: _refresh(cloud) Console.ok("Listing VMs on Cloud: {:}".format(cloud)) vms = Vm.list(category=cloud, output="raw") # print ("XXX", type(vms), vms) if vms is None: break result = [] if "all" in arg.names: if result is None: result = [] else: result = vms elif arg.group is not None and len(arg.group) > 0: for vm in vms: if vm["group"] in arg.group: result.append(vm) elif arg.names is not None and len(arg.names) > 0: for vm in vms: if vm["name"] in arg.names: result.append(vm) if len(result) > 0: # print(result) (order, header) = CloudProvider(cloud).get_attributes("vm") print(Printer.write(result, order=order, output=_format) ) else: Console.error("No data found with requested parameters.", traceflag=False) except Exception as e: # Error.traceback(e) Console.error("Problem listing all instances", traceflag=False) elif arguments["rename"]: try: oldnames = Parameter.expand(arguments["OLDNAMES"]) newnames = Parameter.expand(arguments["NEWNAMES"]) force = arguments["--force"] if oldnames is None or newnames is None: Console.error("Wrong VMs specified for rename", traceflag=False) elif len(oldnames) != len(newnames): Console.error("The number of VMs to be renamed is wrong", traceflat=False) else: for i in range(0, len(oldnames)): oldname = oldnames[i] newname = newnames[i] if arguments["--dryrun"]: Console.ok("Rename {} to {}".format(oldname, newname)) else: Vm.rename(cloud=cloud, oldname=oldname, newname=newname, force=force ) msg = "info. OK." Console.ok(msg) except Exception as e: # Error.traceback(e) Console.error("Problem deleting instances", traceflag=False) return ""
def do_secgroup(self, args, arguments): """ :: Usage: secgroup list [--cloud=CLOUD] [--tenant=TENANT] secgroup create [--cloud=CLOUD] [--tenant=TENANT] LABEL secgroup delete [--cloud=CLOUD] [--tenant=TENANT] LABEL secgroup rules-list [--cloud=CLOUD] [--tenant=TENANT] LABEL secgroup rules-add [--cloud=CLOUD] [--tenant=TENANT] LABEL FROMPORT TOPORT PROTOCOL CIDR secgroup rules-delete [--cloud=CLOUD] [--tenant=TENANT] LABEL FROMPORT TOPORT PROTOCOL CIDR secgroup -h | --help secgroup --version Options: -h help message --cloud=CLOUD Name of the IaaS cloud e.g. india_openstack_grizzly. --tenant=TENANT Name of the tenant, e.g. fg82. 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 --tenant fg82 $ secgroup rules-list --cloud india --tenant fg82 default $ secgroup create --cloud india --tenant fg82 webservice $ secgroup rules-add --cloud india --tenant fg82 webservice 8080 8088 TCP "129.79.0.0/16" """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() if arguments["list"]: # if no arguments read default tenant = arguments["--tenant"] or Default.get("tenant") # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return if not tenant: Console.error("Default tenant not set!") return "" result = SecGroup.list(tenant, cloud) if result: print(result) else: Console.error( "No Security Groups found in the cloudmesh database!") return "" elif arguments["create"]: # if no arguments read default tenant = arguments["--tenant"] or Default.get("tenant", cloud) label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return if not tenant: Console.error("Default tenant not set!") return "" # Create returns uuid of created sec-group uuid = SecGroup.create(label, cloud, tenant) if uuid: Console.ok("Created a new security group [{}] with UUID [{}]" .format(label, uuid)) else: Console.error("Exiting!") return "" elif arguments["delete"]: # if no arguments read default tenant = arguments["--tenant"] or Default.get("tenant", cloud) label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" if not tenant: Console.error("Default tenant not set!") return "" result = SecGroup.delete_secgroup(label, cloud, tenant) if result: print(result) else: Console.error("Security Group [{}, {}, {}] could not be " "deleted".format(label, cloud, tenant)) return "" elif arguments["rules-delete"]: # if no arguments read default cloud = arguments["--cloud"] tenant = arguments["--tenant"] or Default.get("tenant", 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 "" if not tenant: Console.error("Default tenant not set!") return "" # Get the security group sec_group = SecGroup.get(label, tenant, cloud) if sec_group: # Get the rules result = SecGroup.delete_rule(sec_group, from_port, to_port, protocol, cidr) if result: print(result) else: Console.error( "Rule [{} | {} | {} | {}] could not be deleted" .format(from_port, to_port, protocol, cidr)) return "" elif arguments["rules-list"]: # if no arguments read default tenant = arguments["--tenant"] or Default.get("tenant", cloud) label = arguments["LABEL"] # If default not set, terminate if not cloud: Console.error("Default cloud not set!") return "" if not tenant: Console.error("Default tenant not set!") return "" # Get the security group sec_group = SecGroup.get(label, tenant, cloud) if sec_group: # Get the rules result = SecGroup.get_rules(sec_group.uuid) print(result) else: Console.error( "Security Group with label [{}], cloud [{}], and " "tenant [{}] not found!" .format(label, cloud, tenant)) return "" elif arguments["rules-add"]: # if no arguments read default tenant = arguments["--tenant"] or Default.get("tenant", 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 "" if not tenant: Console.error("Default tenant not set!") return "" # Get the security group sec_group = SecGroup.get(label, tenant, cloud) if sec_group: # Add rules to the security group SecGroup.add_rule(sec_group, from_port, to_port, protocol, cidr) else: Console.error( "Security Group with label [{}], cloud [{}], and tenant [{" "}] not found!".format(label, cloud, tenant)) 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_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 __init__(self, context): cmd.Cmd.__init__(self) self.variables = {} self.command_topics = {} self.register_topics() self.context = context # TODO get loglevel from DB or yaml file, if not defined set to ERROR self.loglevel = "DEBUG" self._hist = [] if self.context.debug: print("init CloudmeshConsole") self.prompt = 'cm> ' self.doc_header = "Documented commands (type help <command>):" self.banner = textwrap.dedent(""" +=======================================================+ . ____ _ _ _ . . / ___| | ___ _ _ __| |_ __ ___ ___ ___| |__ . . | | | |/ _ \| | | |/ _` | '_ ` _ \ / _ \/ __| '_ \ . . | |___| | (_) | |_| | (_| | | | | | | __/\__ \ | | | . . \____|_|\___/ \__,_|\__,_|_| |_| |_|\___||___/_| |_| . +=======================================================+ Cloudmesh Shell """) # KeyCommands.__init__(self, context) # # set default cloud and default group if they do not exist # use the first cloud in cloudmesh.yaml as default # Console.set_debug(Default.debug) filename = path_expand("~/.cloudmesh/cloudmesh.yaml") # moved to import cloudmesh_client # create_cloudmesh_yaml(filename) setup_yaml() # Initialize Logging # LogUtil.initialize_logging() # sys,exit(1) # ################## # DEFAULTS # # # SET DEFAULT CLOUD # value = Default.get(name='cloud', category='general') if value is None: config = ConfigDict(filename=filename)["cloudmesh"] if 'active' in config: cloud = config["active"][0] else: clouds = config["clouds"] cloud = list(clouds.keys())[0] Default.set('cloud', cloud, category='general') # # NOT SURE WHAT THIS IS FOR # value = Default.get(name='default', category='general') if value is None: Default.set('default', 'default', category='general') # # SET DEFAULT CLUSTER # ''' cluster = ConfigDict(filename="cloudmesh.yaml")["cloudmesh"]["active"][0] value = Default.get(name='cluster', category='general') if value is None: try: hosts = ssh_config().names() if hosts is not None: cluster = hosts[0] except: pass # use the hardcoded cluster else: cluster = value Default.set('cluster', cluster, category='general') ''' # # SET DEFAULT GROUP # group = Default.group if group is None: Default.set_group("default") # # LOAD DEFAULTS FROM YAML # Default.load("cloudmesh.yaml") try: d = Key.get_from_dir("~/.ssh", store=False) except Exception as e: Console.error(e.message) # # SET DEFAULT TIMER # on = Default.timer # # SET DEFUALT SECGROUP # # # SET DEFAULT REFRESH # # r = Default.refresh # print ("REFRESH", r) # if r is None: # Default.set_refresh("on") # # SET DEFAULT USER # user = Default.user if user is None: user = ConfigDict( filename=filename)["cloudmesh"]["profile"]["user"] Default.set_user(user) r = Default.secgroup if r is None: SecGroup.reset_defaults() ''' #secgroup = "{}-default".format(Default.user) secgroup = "default" Default.set_secgroup(secgroup) SecGroup.add_rule_to_db(group=secgroup, name="ssh",from_port="22",to_port="22",protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="http",from_port="80",to_port="80",protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="https", from_port="443", to_port="443", protocol="tcp", cidr="0.0.0.0/0") SecGroup.add_rule_to_db(group=secgroup, name="ping", from_port="0", to_port="0", protocol="icmp", cidr="0.0.0.0/0") ''' """ try: sshm = SSHKeyManager() m = sshm.get_from_yaml( load_order="~/.cloudmesh/cloudmesh.yaml") 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: pass except Exception as e: Console.error("Problem adding keys from yaml file") """ for c in CloudmeshConsole.__bases__[1:]: # noinspection PyArgumentList c.__init__(self, context)
def do_secgroup(self, args, arguments): """ :: Usage: secgroup list [--format=FORMAT] secgroup list --cloud=CLOUD [--format=FORMAT] secgroup list GROUP [--format=FORMAT] secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR secgroup delete GROUP [--cloud=CLOUD] secgroup delete GROUP RULE secgroup upload [GROUP] [--cloud=CLOUD] Options: --format=FORMAT Specify output format, in one of the following: table, csv, json, yaml, dict. The default value is 'table'. --cloud=CLOUD Name of the IaaS cloud e.g. kilo,chameleoon. The clouds are defined in the yaml file. If the name "all" is used for the cloud all clouds will be selected. Arguments: RULE The security group rule name GROUP 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 secgroup list --cloud=kilo secgroup add my_new_group webapp 8080 8080 tcp 0.0.0.0/0 seggroup delete my_group my_rule secgroup delete my_unused_group --cloud=kilo secgroup upload --cloud=kilo Description: Security groups are first assembled in a local database. Once they are defined they can be added to the clouds. secgroup list [--format=FORMAT] lists all security groups and rules in the database secgroup list GROUP [--format=FORMAT] lists a given security group and its rules defined locally in the database secgroup list --cloud=CLOUD [--format=FORMAT] lists the security groups and rules on the specified clouds. secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR adds a security rule with the given group and the details of the security ruls secgroup delete GROUP [--cloud=CLOUD] Deletes a security group from the local database. To make the change on the remote cloud, using the 'upload' command afterwards. If the --cloud parameter is specified, the change would be made directly on the specified cloud secgroup delete GROUP RULE deletes the given rule from the group. To make this change on the remote cloud, using 'upload' command. secgroup upload [GROUP] [--cloud=CLOUD...] uploads a given group to the given cloud. If the cloud is not specified the default cloud is used. If the parameter for cloud is "all" the rules and groups will be uploaded to all active clouds. This will synchronize the changes (add/delete on security groups, rules) made locally to the remote cloud(s). """ arg = dotdict(arguments) if arguments["--cloud"] is not None: is_cloud = True arg.cloud = arguments["--cloud"] or Default.cloud else: is_cloud = False arg.FORMAT = arguments["--format"] or 'table' # list all security-groups in cloud if arguments["list"]: if not is_cloud: if arg.RULE is None: print(SecGroup.list(group=arg.GROUP, name=arg.RULE, output=arg.FORMAT)) else: print(SecGroup.list(group=arg.GROUP, output=arg.FORMAT)) else: print(SecGroup.list(category=arg.cloud, output=arg.FORMAT)) elif arguments["add"]: try: SecGroup.add_rule_to_db( name=arg.RULE, group=arg.GROUP, from_port=arg.FROMPORT, to_port=arg.TOPORT, protocol=arg.PROTOCOL, cidr=arg.CIDR) except: Console.error("Problem adding security group to db") # Delete a security-group elif arguments["delete"]: if arg["RULE"] is not None: SecGroup.delete_rule_from_db(group=arg["GROUP"], name=arg["RULE"]) else: self._delete(arg) elif arguments["upload"]: # rewrite the _delete # # upload does not implicitly deleting a secgroup anymore # instead, it will check and update the rules only # self._delete(arg) SecGroup.upload(cloud=arg.cloud, group=arg.GROUP) return ""
def do_secgroup(self, args, arguments): """ :: Usage: secgroup list [--format=FORMAT] secgroup list --cloud=CLOUD [--format=FORMAT] secgroup list GROUP [--format=FORMAT] secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR secgroup delete GROUP [--cloud=CLOUD] secgroup delete GROUP RULE secgroup upload [GROUP] [--cloud=CLOUD] Options: --format=FORMAT Specify output format, in one of the following: table, csv, json, yaml, dict. The default value is 'table'. --cloud=CLOUD Name of the IaaS cloud e.g. kilo,chameleoon. The clouds are defined in the yaml file. If the name "all" is used for the cloud all clouds will be selected. Arguments: RULE The security group rule name GROUP 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 secgroup list --cloud=kilo secgroup add my_new_group webapp 8080 8080 tcp 0.0.0.0/0 seggroup delete my_group my_rule secgroup delete my_unused_group --cloud=kilo secgroup upload --cloud=kilo Description: Security groups are first assembled in a local database. Once they are defined they can be added to the clouds. secgroup list [--format=FORMAT] lists all security groups and rules in the database secgroup list GROUP [--format=FORMAT] lists a given security group and its rules defined locally in the database secgroup list --cloud=CLOUD [--format=FORMAT] lists the security groups and rules on the specified clouds. secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR adds a security rule with the given group and the details of the security ruls secgroup delete GROUP [--cloud=CLOUD] Deletes a security group from the local database. To make the change on the remote cloud, using the 'upload' command afterwards. If the --cloud parameter is specified, the change would be made directly on the specified cloud secgroup delete GROUP RULE deletes the given rule from the group. To make this change on the remote cloud, using 'upload' command. secgroup upload [GROUP] [--cloud=CLOUD...] uploads a given group to the given cloud. If the cloud is not specified the default cloud is used. If the parameter for cloud is "all" the rules and groups will be uploaded to all active clouds. This will synchronize the changes (add/delete on security groups, rules) made locally to the remote cloud(s). """ arg = dotdict(arguments) if arguments["--cloud"] is not None: is_cloud = True arg.cloud = arguments["--cloud"] or Default.cloud else: is_cloud = False arg.FORMAT = arguments["--format"] or 'table' # list all security-groups in cloud if arguments["list"]: if not is_cloud: if arg.RULE is None: print( SecGroup.list(group=arg.GROUP, name=arg.RULE, output=arg.FORMAT)) else: print(SecGroup.list(group=arg.GROUP, output=arg.FORMAT)) else: print(SecGroup.list(category=arg.cloud, output=arg.FORMAT)) elif arguments["add"]: try: SecGroup.add_rule_to_db(name=arg.RULE, group=arg.GROUP, from_port=arg.FROMPORT, to_port=arg.TOPORT, protocol=arg.PROTOCOL, cidr=arg.CIDR) except: Console.error("Problem adding security group to db") # Delete a security-group elif arguments["delete"]: if arg["RULE"] is not None: SecGroup.delete_rule_from_db(group=arg["GROUP"], name=arg["RULE"]) else: self._delete(arg) elif arguments["upload"]: # rewrite the _delete # # upload does not implicitly deleting a secgroup anymore # instead, it will check and update the rules only # self._delete(arg) SecGroup.upload(cloud=arg.cloud, group=arg.GROUP) return ""
def do_secgroup(self, args, arguments): """ :: Usage: secgroup list secgroup list --cloud=CLOUD [--format=FORMAT] secgroup list GROUP [RULE] [--format=FORMAT] secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR secgroup delete GROUP [--cloud=CLOUD] secgroup upload [GROUP] [--cloud=CLOUD] Options: --cloud=CLOUD Name of the IaaS cloud e.g. kilo, chameleoon. The clouds are defined in the yaml file. If the name "all" is used for the cloud all clouds will be selected. Arguments: RULE The security group rule name GROUP 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 Description: Security groups are first assembled in a local database. Once they are defined they can be added to the clouds. secgroup list lists all security groups and rules in the database secgroup list --cloud=CLOUD... [--format=FORMAT] lists the security groups and rules on the specified clouds. secgroup list GROUP [RULE] [--format=FORMAT] lists a given security group. If in addition the RULE is specified it only lists the RULE secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR adds a security rule with the given group and teh details of the security ruls secgroup delete GROUP deletes all security rules related to the specified group secgroup delete GROUP RULE deletes just the given rule from the group secgroup upload [GROUP] [--cloud=CLOUD...] uploads a given group to the given cloud. if the cloud is not specified the default cloud is used. If the parameter for cloud is "all" the rules and groups will be uploaded to all active clouds. Example: cm secgroup list cm secgroup list --cloud=kilo cm secgroup add cm-gregor-default web 80 80 tcp 0.0.0.0/0 cm secgroup add cm-gregor-default ssh 22 22 tcp 0.0.0.0/0 cm secgroup upload --cloud=kilo """ arg = dotdict(arguments) if arguments["--cloud"] is not None: is_cloud = True arg.cloud = arguments["--cloud"] or Default.cloud else: is_cloud = False arg.FORMAT = arguments["--format"] or 'table' # list all security-groups in cloud if arguments["list"]: if not is_cloud: if arg.RULE is None: print(SecGroup.list(group=arg.GROUP, name=arg.RULE, output=arg.FORMAT)) else: print(SecGroup.list(group=arg.GROUP, output=arg.FORMAT)) else: print(SecGroup.list(category=arg.cloud, output=arg.FORMAT)) elif arguments["add"]: try: SecGroup.add_rule_to_db( name=arg.RULE, group=arg.GROUP, from_port=arg.FROMPORT, to_port=arg.TOPORT, protocol=arg.PROTOCOL, cidr=arg.CIDR) except: Console.error("Problem adding security group to db") # Delete a security-group elif arguments["delete"]: # if no arguments read default # If default not set, terminate if arg.cloud is None: SecGroup.delete(group=arg.GROUP) else: result = SecGroup.delete_secgroup(name=arg.GROUP, cloud=arg.cloud) if result is not None: Console.ok("Security Group={GROUP} in cloud={cloud} deleted successfully." .format(**arg)) else: Console.error("Failed to delete Security Group={GROUP} in cloud={cloud}" .format(**arg)) elif arguments["upload"]: SecGroup.upload(cloud=arg.cloud, group=arg.GROUP) 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 ""
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"]:
def do_secgroup(self, args, arguments): """ :: Usage: secgroup list secgroup list --cloud=CLOUD [--format=FORMAT] secgroup list GROUP [RULE] [--format=FORMAT] secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR secgroup delete GROUP [--cloud=CLOUD] secgroup upload [GROUP] [--cloud=CLOUD] Options: --cloud=CLOUD Name of the IaaS cloud e.g. kilo, chameleoon. The clouds are defined in the yaml file. If the name "all" is used for the cloud all clouds will be selected. Arguments: RULE The security group rule name GROUP 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 Description: Security groups are first assembled in a local database. Once they are defined they can be added to the clouds. secgroup list lists all security groups and rules in the database secgroup list --cloud=CLOUD... [--format=FORMAT] lists the security groups and rules on the specified clouds. secgroup list GROUP [RULE] [--format=FORMAT] lists a given security group. If in addition the RULE is specified it only lists the RULE secgroup add GROUP RULE FROMPORT TOPORT PROTOCOL CIDR adds a security rule with the given group and teh details of the security ruls secgroup delete GROUP deletes all security rules related to the specified group secgroup delete GROUP RULE deletes just the given rule from the group secgroup upload [GROUP] [--cloud=CLOUD...] uploads a given group to the given cloud. if the cloud is not specified the default cloud is used. If the parameter for cloud is "all" the rules and groups will be uploaded to all active clouds. Example: cm secgroup list cm secgroup list --cloud=kilo cm secgroup add cm-gregor-default web 80 80 tcp 0.0.0.0/0 cm secgroup add cm-gregor-default ssh 22 22 tcp 0.0.0.0/0 cm secgroup upload --cloud=kilo """ arg = dotdict(arguments) if arguments["--cloud"] is not None: is_cloud = True arg.cloud = arguments["--cloud"] or Default.cloud else: is_cloud = False arg.FORMAT = arguments["--format"] or 'table' # list all security-groups in cloud if arguments["list"]: if not is_cloud: if arg.RULE is None: print( SecGroup.list(group=arg.GROUP, name=arg.RULE, output=arg.FORMAT)) else: print(SecGroup.list(group=arg.GROUP, output=arg.FORMAT)) else: print(SecGroup.list(category=arg.cloud, output=arg.FORMAT)) elif arguments["add"]: try: SecGroup.add_rule_to_db(name=arg.RULE, group=arg.GROUP, from_port=arg.FROMPORT, to_port=arg.TOPORT, protocol=arg.PROTOCOL, cidr=arg.CIDR) except: Console.error("Problem adding security group to db") # Delete a security-group elif arguments["delete"]: self._delete(arg) elif arguments["upload"]: # rewrite the _delete # # upload does not implicitly deleting a secgroup anymore # instead, it will check and update the rules only # self._delete(arg) SecGroup.upload(cloud=arg.cloud, group=arg.GROUP) return ""