def do_quota(self, args, arguments): """ :: Usage: quota list [--cloud=CLOUD] [--tenant=TENANT] [--format=FORMAT] Prints quota limit on a current project/tenant Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --tenant=TENANT the tenant id Examples: cm quota list cm quota list --cloud=india --format=csv """ if arguments["list"]: cloud = arguments["--cloud"] or Default.get_cloud() if not cloud: Console.error("Default cloud doesn't exist") return tenant = arguments["--tenant"] output_format = arguments["--format"] list_quotas = Quota.list(cloud, tenant, output=output_format) Console.msg(list_quotas) return
def do_check(self, args, arguments): """ :: Usage: check --cloud=CLOUD check checks some elementary setting for cloudmesh Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name Examples: cm check cm check --cloud=kilo """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") print(locals()) Console.ok("{:} ok".format(cloud)) return ""
def do_cloud(self, args, arguments): """ :: Usage: cloud list [--cloud=CLOUD] [--format=FORMAT] cloud activate CLOUD cloud deactivate CLOUD cloud info CLOUD managing the admins test test test test Arguments: KEY the name of the admin VALUE the value to set the key to Options: --cloud=CLOUD the name of the cloud [default: general] --format=FORMAT the output format [default: table] Description: Cloudmesh contains a cloudmesh.yaml file that contains templates for multiple clouds that you may or may not have access to. Hence it is useful to activate and deacivate clouds you like to use in other commands. To activate a cloud a user can simply use the activate command followed by the name of the cloud to be activated. To find out which clouds are available you can use the list command that will provide you with some basic information. As default it will print a table. Thus the commands:: cloud activate india cloud deactivate aws Will result in +----------------------+--------+-------------------+ | Cloud name | Active | Type | +----------------------+--------+-------------------+ | india | True | Openstack | +----------------------+--------+-------------------+ | aws | False | AWS | +----------------------+--------+-------------------+ To get ore information about the cloud you can use the command cloud info CLOUD It will call internally also the command uses in register See also: register """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() output_format = arguments["--format"] Console.error("TODO: Command not yet implemented.") pass
def do_limits(self, args, arguments): """ :: Usage: limits list [--cloud=CLOUD] [--tenant=TENANT] [--format=FORMAT] Current list data with limits on a selected project/tenant. The --tenant option can be used by admin only Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --tenant=TENANT the tenant name Examples: cm limits list cm limits list --cloud=juno --format=csv """ if arguments["list"]: cloud = arguments["--cloud"] or Default.get_cloud() if not cloud: Console.error("cloud doesn't exist") return "" output_format = arguments["--format"] tenant = arguments["--tenant"] result = Limits.list(cloud, output=output_format, tenant=tenant) Console.msg(result) return ""
def do_flavor(self, args, arguments): """ :: Usage: flavor refresh [--cloud=CLOUD] flavor list [ID] [--cloud=CLOUD] [--format=FORMAT] [--refresh] This lists out the flavors present for a cloud Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --refresh refreshes the data before displaying it from the cloud Examples: cm flavor refresh cm flavor list cm flavor list --format=csv cm flavor show 58c9552c-8d93-42c0-9dea-5f48d90a3188 --refresh """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") return if arguments["refresh"]: msg = "Refresh flavor for cloud {:}.".format(cloud) if Flavor.refresh(cloud): Console.ok("{:} ok".format(msg)) else: Console.error("{:} failed".format(msg)) return "" if arguments["list"]: cluster_id = arguments['ID'] refresh = arguments['--refresh'] output_format = arguments["--format"] if cluster_id is None: result = Flavor.list(cloud, output_format) else: result = Flavor.details(cloud, cluster_id, refresh, output_format) if result is None: # # outo refresh # Console.error("No flavor(s) found. Failed") # Flavor.refresh(cloud) # Console.ok("Refreshing flavor(s). ok.") else: print(result) return ""
def test_002(self): """ set default cloud :return: """ HEADING() result = Default.list() print(result) name = "mycloud" Default.set_cloud(name) result = Default.list() print(result) print ("KKK", Default.get_cloud()) assert Default.get_cloud() == name self._check(name)
def do_image(self, args, arguments): """ :: Usage: image refresh [--cloud=CLOUD] image list [ID] [--cloud=CLOUD] [--format=FORMAT] [--refresh] This lists out the images present for a cloud Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --refresh live data taken from the cloud Examples: cm image refresh cm image list cm image list --format=csv cm image list 58c9552c-8d93-42c0-9dea-5f48d90a3188 --refresh """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") return if arguments["refresh"] or Default.refresh(): msg = "Refresh image for cloud {:}.".format(cloud) if Image.refresh(cloud): Console.ok("{:} ok.".format(msg)) else: Console.error("{:} failed.".format(msg)) return "" if arguments["list"]: id = arguments['ID'] live = arguments['--refresh'] output_format = arguments["--format"] if id is None: result = Image.list(cloud, output_format) else: result = Image.details(cloud, id, live, output_format) if result is None: Console.error("No image(s) found. Failed.") # Todo: # if database size = 0: # Console.error("No images in the database, please refresh.") print(result) return ""
def do_sync(self, args, arguments): """ :: Usage: sync put [--cloud=CLOUD] [--group=GROUP] LOCALDIR [REMOTEDIR] sync get [--cloud=CLOUD] [--group=GROUP] REMOTEDIR LOCALDIR sync put [--server=SERVER] [--group=GROUP] LOCALDIR [REMOTEDIR] sync get [--server=SERVER] [--group=GROUP] REMOTEDIR LOCALDIR A simple wrapper for the openstack nova command Arguments: LOCALDIR A directory on local machine REMOTEDIR A directory on remote machine Options: --cloud=CLOUD Sync with cloud """ cloudname = arguments["--cloud"] or Default.get_cloud() if cloudname is None: Console.error("Default cloud has not been set!" "Please use the following to set it:\n" "cm default cloud=CLOUDNAME\n" "or provide it via the --cloud=CLOUDNAME argument.") return # Get the arguments group = arguments["--group"] or Default.get("group", cloudname) localdir = arguments["LOCALDIR"] remotedir = arguments["REMOTEDIR"] if arguments["put"]: # validate local directory exists if localdir is None: Console.error("Please provide the [LOCALDIR] argument.") return "" result = Sync.sync(cloudname=cloudname, localdir=localdir, remotedir=remotedir, operation="put") if result is not None: Console.ok("Successuly synced local and remote directories.") elif arguments["get"]: # validate local directory exists if localdir is None: Console.error("Please provide the [LOCALDIR] argument.") return "" result = Sync.sync(cloudname=cloudname, localdir=localdir, remotedir=remotedir, operation="get") if result is not None: Console.ok("Successuly synced local and remote directories.") return ""
def do_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 ""
print(traceback.format_exc()) print(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, cloud=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, e: import traceback print(traceback.format_exc()) print(e) Console.error("Problem listing defaults") elif arguments["status"]:
def do_select(self, args, arguments): """ :: Usage: select image [CLOUD] select flavor [CLOUD] select cloud [CLOUD] select key [CLOUD] selects interactively the default values Arguments: CLOUD the name of the cloud Options: """ # pprint(arguments) cloud = arguments["CLOUD"] or Default.get_cloud() if arguments["image"]: try: image_dict = Image.list(cloud, format="dict") image_names = list() for image in image_dict.values(): image_names.append(image["name"]) number = menu_return_num(title="Select an Image", menu_list=image_names, tries=10, with_display=True) if number == "q": pass else: image = image_names[number] print("Selected image " + image) Default.set("image", image, cloud=cloud) except: print("ERROR: could not set image.") elif arguments["flavor"]: try: flavor_dict = Flavor.list(cloud, format="dict") flavor_names = list() for flavor in flavor_dict.values(): flavor_names.append(flavor["name"]) number = menu_return_num(title="Select a Flavor", menu_list=flavor_names, tries=10, with_display=True) if number == "q": pass else: flavor = flavor_names[number] print("Selected flavor " + flavor) Default.set("flavor", flavor, cloud=cloud) except: print("ERROR: could not set flavor.") elif arguments["cloud"]: try: config = ConfigDict("cloudmesh.yaml") clouds = config["cloudmesh"]["clouds"] for key in clouds.keys(): Console.ok(" " + key) number = menu_return_num(title="Select a cloud", menu_list=clouds.keys(), tries=10, with_display=True) if number == "q": pass else: cloud = clouds.keys()[number] print("Selected cloud " + cloud) Default.set("cloud", cloud, "general") except: print("ERROR: could not set cloud.") elif arguments["key"]: try: db = SSHKeyDBManager() key_dict = db.table_dict() key_names = list() for key in key_dict.values(): key_names.append(key["name"]) number = menu_return_num(title="Select a Key", menu_list=key_names, tries=10, with_display=True) if number == "q": pass else: key = key_names[number] print("Selected key " + key) # TODO Fix default key setting in key DB # db.set_default(key) Default.set("key", key, cloud=cloud) except: print("ERROR: could not set key") return ""
def do_launcher(self, args, arguments): """ :: Usage: launcher list [--cloud=CLOUD] [--format=FORMAT] [--all] launcher delete KEY [--cloud=CLOUD] launcher run launcher resume launcher suspend launcher details launcher clear launcher refresh Arguments: KEY the name of the launcher Options: --cloud=CLOUD the name of the cloud --format=FORMAT the output format [launcher: table] --all lists all the launcher values Description: Launcher is a command line tool to test the portal launch functionalities through command The current launcher values can by listed with --all option:( if you have a launcher cloud specified. You can also add a cloud parameter to apply the command to a specific cloud) launcher list A launcher can be deleted with launcher delete KEY Examples: launcher list --all launcher list --cloud=general launcher delete <KEY> """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() launcher = Launcher(kind=None) if cloud is None: Console.error("Default cloud not set") return if arguments["list"]: result = launcher.list() print(result) elif arguments["delete"]: result = launcher.delete() print(result) elif arguments["run"]: result = launcher.run() print(result) elif arguments["resume"]: result = launcher.resume() print(result) elif arguments["suspend"]: result = launcher.suspend() print(result) elif arguments["details"]: result = launcher.details() print(result) elif arguments["clear"]: result = launcher.clear() print(result) elif arguments["refresh"]: result = launcher.refresh() print(result)
def do_nova(self, args, arguments): """ :: Usage: nova set CLOUD nova info [CLOUD] [--password] nova help nova [--group=GROUP] ARGUMENTS... A simple wrapper for the openstack nova command Arguments: GROUP The group to add vms to ARGUMENTS The arguments passed to nova help Prints the nova manual set reads the information from the current cloud and updates the environment variables if the cloud is an openstack cloud info the environment values for OS Options: --group=GROUP Add VM to GROUP group --password Prints the password -v verbose mode """ # pprint(arguments) cloud = arguments['CLOUD'] or Default.get_cloud() if not cloud: Console.error("Default cloud not set!") return "" group = arguments["--group"] or Default.get("group", cloud=cloud) if not group: Console.error("Default group not set!") return "" if arguments["help"]: os.system("nova help") return "" elif arguments["info"]: set_os_environ(cloud) d = {} # # TODO: this naturally does not work as clouds will have # different parameters. ALos it does not unset previous # parameters from other clouds. See register # for attribute in ['OS_USERNAME', 'OS_TENANT_NAME', 'OS_AUTH_URL', 'OS_CACERT', 'OS_PASSWORD', 'OS_REGION']: try: d[attribute] = os.environ[attribute] except: Console.warning("OS environment variable {:} not found" .format(attribute)) d[attribute] = None if not arguments["--password"]: d['OS_PASSWORD'] = "******" print(row_table(d, order=None, labels=["Variable", "Value"])) msg = "info. OK." Console.ok(msg) return "" elif arguments["set"]: if cloud: set_os_environ(cloud) msg = "{0} is set".format(cloud) Console.ok(msg) else: Console.error("CLOUD is required") else: # nova ARGUMENTS... print("Cloud = {0}".format(cloud)) try: set_os_environ(cloud) args = arguments["ARGUMENTS"] # arguments may contain multiple optional arguments if len(args) == 1: args = args[0].split() result = Shell.execute("nova", args) print(Nova.remove_subjectAltName_warning(result)) """ If request for nova boot, add the vm to group specified, or else add to default group """ if "boot" in args: # Logic to find ID of VM in the result fields = [] for field in result.split("|"): fields.append(field.strip()) index = fields.index('id') + 1 vm_id = fields[index] # Add to group Group.add(name=group, type="vm", id=vm_id, cloud=cloud) except Exception, ex: Console.error("Error executing Nova command: {}".format(ex)) return ""
def do_network(self, args, arguments): """ :: Usage: network get fixed [ip] [--cloud=CLOUD] FIXED_IP network get floating [ip] [--cloud=CLOUD] FLOATING_IP_ID network reserve fixed [ip] [--cloud=CLOUD] FIXED_IP network unreserve fixed [ip] [--cloud=CLOUD] FIXED_IP network associate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network disassociate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network create floating [ip] [--cloud=CLOUD] [--pool=FLOATING_IP_POOL] network delete floating [ip] [--cloud=CLOUD] FLOATING_IP... network list floating pool [--cloud=CLOUD] network list floating [ip] [--cloud=CLOUD] [--instance=INS_ID_OR_NAME] [IP_OR_ID] network create cluster --group=demo_group network -h | --help Options: -h help message --cloud=CLOUD Name of the IaaS cloud e.g. india_openstack_grizzly. --group=GROUP Name of the group in Cloudmesh --pool=FLOATING_IP_POOL Name of Floating IP Pool --instance=INS_ID_OR_NAME ID or Name of the vm instance Arguments: IP_OR_ID IP Address or ID of IP Address FIXED_IP Fixed IP Address, e.g. 10.1.5.2 FLOATING_IP Floating IP Address, e.g. 192.1.66.8 FLOATING_IP_ID ID associated with Floating IP, e.g. 185c5195-e824-4e7b-8581-703abec4bc01 Examples: $ network get fixed ip --cloud=india 10.1.2.5 $ network get fixed --cloud=india 10.1.2.5 $ network get floating ip --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 $ network get floating --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 $ network reserve fixed ip --cloud=india 10.1.2.5 $ network reserve fixed --cloud=india 10.1.2.5 $ network unreserve fixed ip --cloud=india 10.1.2.5 $ network unreserve fixed --cloud=india 10.1.2.5 $ network associate floating ip --cloud=india --instance=albert-001 192.1.66.8 $ network associate floating --cloud=india --instance=albert-001 $ network associate floating --cloud=india --group=albert_group $ network disassociate floating ip --cloud=india --instance=albert-001 192.1.66.8 $ network disassociate floating --cloud=india --instance=albert-001 192.1.66.8 $ network create floating ip --cloud=india --pool=albert-f01 $ network create floating --cloud=india --pool=albert-f01 $ network delete floating ip --cloud=india 192.1.66.8 192.1.66.9 $ network delete floating --cloud=india 192.1.66.8 192.1.66.9 $ network list floating ip --cloud=india $ network list floating --cloud=india $ network list floating --cloud=india 192.1.66.8 $ network list floating --cloud=india --instance=323c5195-7yy34-4e7b-8581-703abec4b $ network list floating pool --cloud=india $ network create cluster --group=demo_group """ # pprint(arguments) # Get the cloud parameter OR read default cloudname = arguments["--cloud"] or Default.get_cloud() if cloudname is None: Console.error("Default cloud has not been set!" "Please use the following to set it:\n" "cm default cloud=CLOUDNAME\n" "or provide it via the --cloud=CLOUDNAME argument.") return "" # Fixed IP info if arguments["get"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.get_fixed_ip(cloudname, fixed_ip_addr=fixed_ip) Console.msg(result) # Floating IP info elif arguments["get"] \ and arguments["floating"]: floating_ip_id = arguments["FLOATING_IP_ID"] result = Network.get_floating_ip(cloudname, floating_ip_or_id=floating_ip_id) Console.msg(result) # Reserve a fixed ip elif arguments["reserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.reserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok("Reserve fixed ip address [{}] complete.".format(fixed_ip)) # Un-Reserve a fixed ip elif arguments["unreserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.unreserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok("Un-Reserve fixed ip address [{}] complete.".format(fixed_ip)) # Associate floating IP elif arguments["associate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] print(floating_ip) # group supplied if group_name is not None: """ Group name has been provided. Assign floating IPs to all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, cloud=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" # Get the instance name instance_name = instance_dict["name"] floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Refresh VM in db self.refresh_vm(cloudname) else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" # floating-ip not supplied, instance-id supplied elif len(floating_ip)==0 and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Generate one from the pool, and assign to vm and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Associate the IP to the instance and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) floating_ip = floating_ip[0] # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] result = Network.associate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Associated Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Invalid parameters else: Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) elif arguments["disassociate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] # group supplied if group_name is not None: """ Group name has been provided. Remove floating IPs of all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, cloud=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" # Get the instance name instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error("Instance[{}] does not have a floating_ip." .format(instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" # floating-ip not supplied, instance-id supplied elif len(floating_ip)==0 and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Remove floating ip allocated to vm and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error("Instance[{}] does not have a floating_ip." .format(instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Remove the IP from the instance and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) floating_ip = floating_ip[0] # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] _floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if _floating_ip != floating_ip: Console.error("Invalid floating_ip [{}] for instance [{}]." .format(floating_ip, instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) # Invalid parameters else: Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) # Create new floating ip under floating pool elif arguments["create"] \ and arguments["floating"]: floating_pool = arguments["--pool"] result = Network.create_floating_ip(cloudname=cloudname, floating_pool=floating_pool) if result is not None: Console.ok("Created new floating IP [{}]".format(result)) else: Console.error("Failed to create floating IP! Please check arguments.") # Delete a floating ip address elif arguments["delete"] \ and arguments["floating"]: floating_ips = arguments["FLOATING_IP"] for floating_ip in floating_ips: result = Network.delete_floating_ip(cloudname=cloudname, floating_ip_or_id=floating_ip) if result is not None: Console.ok(result) else: Console.error("Failed to delete floating IP address!") # Floating IP Pool List elif arguments["list"] \ and arguments["floating"] \ and arguments["pool"]: result = Network.list_floating_ip_pool(cloudname) Console.msg(result) # Floating IP list [or info] elif arguments["list"] \ and arguments["floating"]: ip_or_id = arguments["IP_OR_ID"] instance_id = arguments["--instance"] # Refresh VM in db self.refresh_vm(cloudname) # If instance id is supplied if instance_id is not None: instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" # Read the floating_ip from the dict ip_or_id = instance_dict["floating_ip"] if ip_or_id is None: Console.error("Instance with ID [{}] does not have a floating IP address!" .format(instance_id)) return "" # If the floating ip or associated ID is supplied if ip_or_id is not None: result = Network.get_floating_ip(cloudname, floating_ip_or_id=ip_or_id) if result is not None: Console.msg(result) else: Console.error("Floating IP not found! Please check your arguments.") return "" # Retrieve the full list else: result = Network.list_floating_ip(cloudname) Console.msg(result) # Create a virtual cluster elif arguments["cluster"] and \ arguments["create"]: group_name = arguments["--group"] or \ Default.get("group", cloud=cloudname) # Get the group information group = Group.get_info(name=group_name, cloud=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # var contains pub key of all vms public_keys = "" login_users = [] login_ips = [] # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" # Get the instance name instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # If vm does not have floating ip, then create if floating_ip is None: floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Refresh VM in db self.refresh_vm(cloudname) # Get the login user for this machine user = raw_input("Enter the login user for VM {} : ".format(instance_name)) passphrase = getpass.getpass("Enter the passphrase key on VM {} : ".format(instance_name)) # create list for second iteration login_users.append(user) login_ips.append(floating_ip) login_args = [ user + "@" + floating_ip, ] keygen_args = [ "ssh-keygen -t rsa -f ~/.ssh/id_rsa -N " + passphrase ] cat_pubkey_args = [ "cat ~/.ssh/id_rsa.pub" ] generate_keypair = login_args + keygen_args result = Shell.ssh(*generate_keypair) #print("***** Keygen *****") #print(result) cat_public_key = login_args + cat_pubkey_args result = Shell.ssh(*cat_public_key) public_keys += "\n" + result #print("***** id_rsa.pub *****") #print(result) #print("***** public keys *****") #print(public_keys) for user, ip in zip(login_users, login_ips): arguments = [ user + "@" + ip, "echo '" + public_keys + "' >> ~/.ssh/authorized_keys" ] # copy the public key contents to auth_keys result = Shell.ssh(*arguments) Console.ok("Virtual cluster creation successfull.") else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" return ""
def do_list(self, args, arguments): """ :: Usage: list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] default list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] vm list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] flavor list [--cloud=CLOUD] [--format=FORMAT] [--user=USER] [--tenant=TENANT] image List the items stored in the database Options: --cloud=CLOUD the name of the cloud --format=FORMAT the output format --tenant=TENANT Name of the tenant, e.g. fg82. Description: List command prints the values stored in the database for [default/vm/flavor/image]. Result can be filtered based on the cloud, user & tenant arguments. If these arguments are not specified, it reads the default Examples: $ list --cloud india default $ list --cloud india --format table flavor $ list --cloud india --user albert --tenant fg82 flavor """ # pprint(arguments) # Method to get the kind from args # # TODO: the kind are defined in the provider, # TODO: keep the kind lower case # why is there a reason to make the gind upper case def get_kind(): for k in ["vm", "image", "flavor", "default"]: if arguments[k]: # kinds are all uppercase in model.py return k.upper() return "help" # Read commandline arguments output_format = arguments['--format'] cloud = arguments['--cloud'] or Default.get_cloud() user = arguments['--user'] tenant = arguments['--tenant'] # If format is not specified, read default if output_format is None: output_format = Default.get("format") or "table" # If cloud is not specified, get default if cloud is None: cloud = Default.get("cloud") or "india" # If user is not specified, get default if user is None: user = Default.get("user") # If tenant is not specified, get default if tenant is None: tenant = Default.get("tenant") # Get the kind kind = get_kind() header = None order = None # print help message if kind == 'help': Console.ok("Print help!") return "" # Prepare the order & header based on kind # TODO: use lower case so we have a convention thats easy to follow # TODO: add quota # TODO: add limits # TODO: add usage if kind == 'FLAVOR': order = [ 'cm_cloud', 'disk', 'ephemeral_disk', 'id', 'name', 'ram', 'vcpus' ] elif kind == 'DEFAULT': order = ['user', 'cloud', 'name', 'value', 'created_at', 'updated_at' ] elif kind == 'IMAGE': order = [ 'cm_cloud', 'cm_user', 'instance_type_ephemeral_gb', 'instance_type_flavorid', 'instance_type_id', 'instance_type_memory_mb', 'instance_type_name', 'instance_type_root_gb', 'instance_type_rxtx_factor', 'instance_type_swap', 'instance_type_vcpus', 'minDisk', 'minRam', 'name', ] header = [ 'cloud', 'user', 'ephemeral_gb', 'flavorid', 'id', 'memory_mb', 'flavor', 'root_gb', 'rxtx_factor', 'swap', 'vcpus', 'minDisk', 'minRam', 'name', ] # Get the result & print it result = List.list(kind, cloud, user, tenant, order, header, output_format) if result: print(result) else: Console.error("No {}s found in the database." .format(kind.lower())) return ""
def do_cloud(self, args, arguments): """ :: Usage: cloud list [--cloud=CLOUD] [--format=FORMAT] cloud logon CLOUD cloud logout CLOUD cloud activate CLOUD cloud deactivate CLOUD cloud info CLOUD managing the admins test test test test Arguments: KEY the name of the admin VALUE the value to set the key to Options: --cloud=CLOUD the name of the cloud --format=FORMAT the output format [default: table] Description: Cloudmesh contains a cloudmesh.yaml file that contains templates for multiple clouds that you may or may not have access to. Hence it is useful to activate and deactivate clouds you like to use in other commands. To activate a cloud a user can simply use the activate command followed by the name of the cloud to be activated. To find out which clouds are available you can use the list command that will provide you with some basic information. As default it will print a table. Thus the commands:: cloud activate india cloud deactivate aws Will result in +----------------------+--------+-------------------+ | Cloud name | Active | Type | +----------------------+--------+-------------------+ | india | True | Openstack | +----------------------+--------+-------------------+ | aws | False | AWS | +----------------------+--------+-------------------+ To get ore information about the cloud you can use the command cloud info CLOUD It will call internally also the command uses in register See also: register """ # pprint(arguments) cloudname = arguments["--cloud"] or Default.get_cloud() if arguments["logon"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.logon(cloudname) Console.ok("Logged into cloud: " + cloudname) elif arguments["logout"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.logout(cloudname) Console.ok("Logged out of cloud: " + cloudname) elif arguments["activate"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.activate(cloudname) Console.ok("Activated cloud: " + cloudname) elif arguments["deactivate"]: cloudname = arguments["CLOUD"] provider = CloudProvider(cloudname).provider provider.deactivate(cloudname) Console.ok("Deactivated cloud: " + cloudname) elif arguments["list"]: provider = CloudProvider(cloudname).provider clouds = provider.list_clouds() (order, header) = CloudProvider(cloudname).get_attributes("clouds") Console.msg(dict_printer(clouds, order=order, header=header)) pass
def do_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] [--keypair_name=KEYPAIR_NAME] 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 floating_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 list [NAME_OR_ID] [--cloud=CLOUD|--all] [--group=GROUP] [--format=FORMAT] vm status [--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 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. 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 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="juno", 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) 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 prefix, count = Counter.get() if prefix is None or count is None: Console.error("Prefix and Count could not be retrieved correctly.") return 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", cloud=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", cloud=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", cloud=cloud) # if default group not set, return error if not group: Console.error("Default group not set.") return "" secgroup = arguments["--secgroup"] or Default.get("secgroup", cloud=cloud) # print("SecurityGrp : {:}".format(secgroup)) secgroup_list = ["default"] if secgroup is not None: secgroup_list.append(secgroup) key_name = arguments["--keypair_name"] or Default.get("keypair", cloud=cloud) # if default keypair not set, return error if not key_name: Console.error("Default keypair not set.") return "" vm_id = Vm.boot(cloud=cloud, name=name, image=image, flavor=flavor, key_name=key_name, secgroup_list=secgroup_list) if is_name_provided is False: # Incrementing count Counter.incr() # Add to group Group.add(name=group, type="vm", id=vm_id, cloud=cloud) msg = "info. OK." Console.ok(msg) except Exception, e: import traceback print(traceback.format_exc()) print(e) Console.error("Problem booting instance {:}".format(name))
print("Key {:} deleted successfully from database.".format(keyname)) msg = "info. OK." Console.ok(msg) except Exception, e: import traceback print(traceback.format_exc()) print (e) Console.error("Problem deleting the key `{:}`".format(keyname)) elif arguments['upload']: try: conf = ConfigDict("cloudmesh.yaml") username = conf["cloudmesh"]["profile"]["username"] keyname = arguments["KEYNAME"] cloud = arguments["--cloud"] or Default.get_cloud() name_on_cloud = arguments["--name"] if name_on_cloud is None: name_on_cloud = username + "-" + cloud + "-" + keyname sshm = SSHKeyManager() sshm.add_key_to_cloud(username, keyname, cloud, name_on_cloud) print("Key {:} added successfully to cloud {:} as {:}.".format(keyname, cloud, name_on_cloud)) msg = "info. OK." Console.ok(msg) except Exception, e: import traceback print(traceback.format_exc())
def do_network(self, args, arguments): """ :: Usage: network get fixed [ip] [--cloud=CLOUD] FIXED_IP network get floating [ip] [--cloud=CLOUD] FLOATING_IP_ID network reserve fixed [ip] [--cloud=CLOUD] FIXED_IP network unreserve fixed [ip] [--cloud=CLOUD] FIXED_IP network associate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network disassociate floating [ip] [--cloud=CLOUD] [--group=GROUP] [--instance=INS_ID_OR_NAME] [FLOATING_IP] network create floating [ip] [--cloud=CLOUD] [--pool=FLOATING_IP_POOL] network delete floating [ip] [--cloud=CLOUD] FLOATING_IP network list floating pool [--cloud=CLOUD] network list floating [ip] [--cloud=CLOUD] [--instance=INS_ID_OR_NAME] [IP_OR_ID] network -h | --help Options: -h help message --cloud=CLOUD Name of the IaaS cloud e.g. india_openstack_grizzly. --group=GROUP Name of the group in Cloudmesh --pool=FLOATING_IP_POOL Name of Floating IP Pool --instance=INS_ID_OR_NAME ID or Name of the vm instance Arguments: IP_OR_ID IP Address or ID of IP Address FIXED_IP Fixed IP Address, e.g. 10.1.5.2 FLOATING_IP Floating IP Address, e.g. 192.1.66.8 FLOATING_IP_ID ID associated with Floating IP, e.g. 185c5195-e824-4e7b-8581-703abec4bc01 Examples: $ network get fixed ip --cloud=india 10.1.2.5 $ network get fixed --cloud=india 10.1.2.5 $ network get floating ip --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 $ network get floating --cloud=india 185c5195-e824-4e7b-8581-703abec4bc01 $ network reserve fixed ip --cloud=india 10.1.2.5 $ network reserve fixed --cloud=india 10.1.2.5 $ network unreserve fixed ip --cloud=india 10.1.2.5 $ network unreserve fixed --cloud=india 10.1.2.5 $ network associate floating ip --cloud=india --instance=albert-001 192.1.66.8 $ network associate floating --cloud=india --instance=albert-001 $ network associate floating --cloud=india --group=albert_group $ network disassociate floating ip --cloud=india --instance=albert-001 192.1.66.8 $ network disassociate floating --cloud=india --instance=albert-001 192.1.66.8 $ network create floating ip --cloud=india --pool=albert-f01 $ network create floating --cloud=india --pool=albert-f01 $ network delete floating ip --cloud=india 192.1.66.8 $ network delete floating --cloud=india 192.1.66.8 $ network list floating ip --cloud=india $ network list floating --cloud=india $ network list floating --cloud=india 192.1.66.8 $ network list floating --cloud=india --instance=323c5195-7yy34-4e7b-8581-703abec4b $ network list floating pool --cloud=india """ # pprint(arguments) # Get the cloud parameter OR read default cloudname = arguments["--cloud"] or Default.get_cloud() if cloudname is None: Console.error("Default cloud has not been set!" "Please use the following to set it:\n" "cm default cloud=CLOUDNAME\n" "or provide it via the --cloud=CLOUDNAME argument.") return "" # Fixed IP info if arguments["get"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.get_fixed_ip(cloudname, fixed_ip_addr=fixed_ip) Console.msg(result) # Floating IP info elif arguments["get"] \ and arguments["floating"]: floating_ip_id = arguments["FLOATING_IP_ID"] result = Network.get_floating_ip(cloudname, floating_ip_or_id=floating_ip_id) Console.msg(result) # Reserve a fixed ip elif arguments["reserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.reserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok("Reserve fixed ip address [{}] complete.".format(fixed_ip)) # Un-Reserve a fixed ip elif arguments["unreserve"] \ and arguments["fixed"]: fixed_ip = arguments["FIXED_IP"] result = Network.unreserve_fixed_ip(cloudname=cloudname, fixed_ip_addr=fixed_ip) if result is not None: Console.ok("Un-Reserve fixed ip address [{}] complete.".format(fixed_ip)) # Associate floating IP elif arguments["associate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] # group supplied if group_name is not None: """ Group name has been provided. Assign floating IPs to all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, cloud=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" # Get the instance name instance_name = instance_dict["name"] floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Refresh VM in db self.refresh_vm(cloudname) else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" # floating-ip not supplied, instance-id supplied elif floating_ip is None and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Generate one from the pool, and assign to vm and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] floating_ip = Network.create_assign_floating_ip(cloudname=cloudname, instance_name=instance_name) if floating_ip is not None: Console.ok("Created and assigned Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Associate the IP to the instance and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] result = Network.associate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Associated Floating IP [{}] to instance [{}]." .format(floating_ip, instance_name)) # Invalid parameters else: Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) elif arguments["disassociate"] \ and arguments["floating"]: # Get all command-line arguments group_name = arguments["--group"] instance_id = arguments["--instance"] floating_ip = arguments["FLOATING_IP"] # group supplied if group_name is not None: """ Group name has been provided. Remove floating IPs of all vms in the group and return """ # Get the group information group = Group.get_info(name=group_name, cloud=cloudname, output="json") if group is not None: # Convert from str to json group = json.loads(group) # For each vm in the group # Create and assign a floating IP for item in group: instance_id = group[item]["value"] # Get the instance dict instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" # Get the instance name instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error("Instance[{}] does not have a floating_ip." .format(instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) else: Console.error("No group [{}] in the Cloudmesh database." .format(group_name)) return "" # floating-ip not supplied, instance-id supplied elif floating_ip is None and instance_id is not None: """ Floating IP has not been provided, instance-id provided. Remove floating ip allocated to vm and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if floating_ip is None: Console.error("Instance[{}] does not have a floating_ip." .format(instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) # instance-id & floating-ip supplied elif instance_id is not None: """ Floating IP & Instance ID have been provided Remove the IP from the instance and return """ instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" instance_name = instance_dict["name"] _floating_ip = instance_dict["floating_ip"] # Floating ip argument invalid if _floating_ip != floating_ip: Console.error("Invalid floating_ip [{}] for instance [{}]." .format(floating_ip, instance_name)) return "" result = Network.disassociate_floating_ip(cloudname=cloudname, instance_name=instance_name, floating_ip=floating_ip) if result is not None: Console.ok("Disassociated Floating IP [{}] from instance [{}]." .format(floating_ip, instance_name)) # Invalid parameters else: Console.error("Please provide at least one of [--group] OR [--instance] parameters.\n" "You can also provide [FLOATING_IP] AND [--instance] parameters.\n" "See 'cm network --help' for more info.") return "" # Refresh VM in db self.refresh_vm(cloudname) # Create new floating ip under floating pool elif arguments["create"] \ and arguments["floating"]: floating_pool = arguments["--pool"] result = Network.create_floating_ip(cloudname=cloudname, floating_pool=floating_pool) if result is not None: Console.ok("Created new floating IP [{}]".format(result)) else: Console.error("Failed to create floating IP! Please check arguments.") # Delete a floating ip address elif arguments["delete"] \ and arguments["floating"]: floating_ip = arguments["FLOATING_IP"] result = Network.delete_floating_ip(cloudname=cloudname, floating_ip_or_id=floating_ip) if result is not None: Console.ok(result) else: Console.error("Failed to delete floating IP address!") # Floating IP Pool List elif arguments["list"] \ and arguments["floating"] \ and arguments["pool"]: result = Network.list_floating_ip_pool(cloudname) Console.msg(result) # Floating IP list [or info] elif arguments["list"] \ and arguments["floating"]: ip_or_id = arguments["IP_OR_ID"] instance_id = arguments["--instance"] # Refresh VM in db self.refresh_vm(cloudname) # If instance id is supplied if instance_id is not None: instance_dict = Network.get_instance_dict(cloudname=cloudname, instance_id=instance_id) # Instance not found if instance_dict is None: Console.error("Instance [{}] not found in the cloudmesh database!" .format(instance_id)) return "" # Read the floating_ip from the dict ip_or_id = instance_dict["floating_ip"] if ip_or_id is None: Console.error("Instance with ID [{}] does not have a floating IP address!" .format(instance_id)) return "" # If the floating ip or associated ID is supplied if ip_or_id is not None: result = Network.get_floating_ip(cloudname, floating_ip_or_id=ip_or_id) if result is not None: Console.msg(result) else: Console.error("Floating IP not found! Please check your arguments.") return "" # Retrieve the full list else: result = Network.list_floating_ip(cloudname) Console.msg(result) return ""
def do_group(self, args, arguments): """ :: Usage: group add NAME [--type=TYPE] [--cloud=CLOUD] [--id=IDs] group list [--cloud=CLOUD] [--format=FORMAT] [NAME] group delete NAME [--cloud=CLOUD] group remove [--cloud=CLOUD] --name=NAME --id=ID group copy FROM TO group merge GROUPA GROUPB MERGEDGROUP manage the groups Arguments: NAME name of a group FROM name of a group TO name of a group GROUPA name of a group GROUPB name of a group MERGEDGROUP name of a group Options: --cloud=CLOUD the name of the cloud --format=FORMAT the output format --type=TYPE the resource type --name=NAME the name of the group Description: Todo: design parameters that are useful and match description Todo: discuss and propose command cloudmesh can manage groups of resources and cloud related objects. As it would be cumbersome to for example delete many virtual machines or delete VMs that are in the same group, but are running in different clouds. Hence it is possible to add a virtual machine to a specific group. The group name to be added to can be set as a default. This way all subsequent commands use this default group. It can also be set via a command parameter. Another convenience function is that the group command can use the last used virtual machine. If a vm is started it will be automatically added to the default group if it is set. The delete command has an optional cloud parameter so that deletion of vms of a partial group by cloud can be achieved. If finer grained deletion is needed, it can be achieved with the delete command that supports deletion by name It is also possible to remove a VM from the group using the remove command, by supplying the ID Example: default group mygroup group add --type=vm --id=albert-[001-003] adds the vms with teh given name using the Parameter see base group add --type=vm adds the last vm to the group group delete --name=mygroup deletes all objects in the group """ # pprint(arguments) cloud = arguments["--cloud"] or Default.get_cloud() if arguments["list"]: output = arguments["--format"] or Default.get("format", cloud) or "table" name = arguments["NAME"] if name is None: result = Group.list(format=output, cloud=cloud) if result: print(result) else: print("There are no groups in the cloudmesh database!") else: result = Group.get_info(name=name, cloud=cloud, output=output) if result: print(result) else: msg_a = ("No group found with name `{name}` found in the " "cloud `{cloud}`.".format(**locals())) # find alternate result = Group.get(name=name) msg_b = "" if result is not None: msg_b = " However we found such a variable in " \ "cloud `{cloud}`. Please consider " \ "using --cloud={cloud}".format(**result) Console.error(msg_a + msg_b) return elif arguments["add"]: type = arguments["--type"] or Default.get("type", cloud) cloud_id = arguments["--id"] or Default.get("id", cloud) or "vm" data = { "name": arguments["NAME"], "type": type, "cloud": cloud, "id": cloud_id } Group.add(**data) return elif arguments["delete"]: data = { "name": arguments["NAME"], "cloud": cloud, } result = Group.delete(**data) if result: Console.ok("Deletion completed. ok.") else: Console.error( "No group with name `{name}` found".format(**data)) return elif arguments["remove"]: name = arguments["--name"] cloud_id = arguments["--id"] if not cloud: Console.error("Default cloud not set!") return result = Group.remove(name, cloud_id, cloud) if result: Console.ok(result) else: Console.error( "Failed to delete ID [{}] from group [{}] in the database!".format( cloud_id, name)) return elif arguments["copy"]: _from = arguments["FROM"] _to = arguments["TO"] Group.copy(_from, _to) return elif arguments["merge"]: _groupA = arguments["GROUPA"] _groupB = arguments["GROUPB"] _mergedGroup = arguments["MERGEDGROUP"] Group.merge(_groupA, _groupB, _mergedGroup) return