def boot(self, cloud=None, image=None, flavor=None, key=None, arguments=None): """ Boots the image on a specified cloud :param image: The name of the image :type image: str :param flavor: The name of the flavor :type flavor: str :param key: The name of the key :type key: str :param cloud: The name of the cloud :type cloud: str :param arguments: An array of arguments :type arguments: list of str :return: the id of the vm :rtype: str """ if cloud is None: cloud = Default.get("cloud", "general") print("get default cloud: " + str(cloud)) if image is None: image = Default.get("image", cloud) print("get default image ", str(image)) if flavor is None: flavor = Default.get("flavor", cloud) print("get default flavor ", str(flavor)) if key is None: key = Default.get("key", str(cloud)) print("get default key ", str(key)) # command_key print("boot an image", image, flavor, key, cloud, arguments) pass
def test_001(self): """ delete defaults :return: """ HEADING() Default.clear() assert Default.list() == None
def __init__(self, context): self.context = context if self.context.debug: print("init command refresh") try: value = Default.get_refresh() except: Default.set_refresh("off")
def test_999(self): """ clear the defaults :return: """ HEADING() Default.clear() assert True
def test_005(self): """ set default key :return: """ HEADING() name = "mykey" Default.set_key(name) assert Default.get_key() == name self._check(name)
def test_004(self): """ set default flavor :return: """ HEADING() name = "myflavor" Default.set_flavor(name, "mycloud") assert Default.get_flavor("mycloud") == name self._check(name)
def test_003(self): """ set default image :return: """ HEADING() name = "myimage" Default.set_image(name, "mycloud") assert Default.get_image("mycloud") == name self._check(name)
def test_006(self): """ set default key :return: """ HEADING() name = "mygroup" Default.set_group(name) assert Default.get_group() == name self._check(name)
def test_007(self): """ set default variable :return: """ HEADING() name = "myvar" value = "myvalue" cloud = "mycloud" Default.set(name, value, cloud) assert Default.get(name, cloud) == value self._check(value)
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_check(self, args, arguments): """ :: Usage: check --cloud=CLOUD check checks some elementary setting for cloudmesh Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name Examples: cm check cm check --cloud=kilo """ cloud = arguments["--cloud"] or Default.get_cloud() if cloud is None: Console.error("Default cloud doesn't exist") print(locals()) Console.ok("{:} ok".format(cloud)) return ""
def do_limits(self, args, arguments): """ :: Usage: limits list [--cloud=CLOUD] [--tenant=TENANT] [--format=FORMAT] Current list data with limits on a selected project/tenant. The --tenant option can be used by admin only Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --tenant=TENANT the tenant name Examples: cm limits list cm limits list --cloud=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_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_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 get_info(cls, cloud="kilo", name=None, output="table"): """ Method to get info about a group :param cloud: :param name: :param output: :return: """ try: cloud = cloud or Default.get("cloud") args = { "name": name, "cloud": cloud } # group = cls.get(name=name, cloud=cloud) group = cls.cm.find("group", output="object", **args).first() if group is not None: d = cls.to_dict(group) # Transform the dict to show multiple rows per vm newdict = Group.transform_dict(d) else: return None return dict_printer(newdict, order=cls.order, output=output) except Exception as ex: Console.error(ex.message, ex)
def get(prefix=None, idx=None, user=None): """Return a vm name to use next time. prefix or index can be given to update a vm name (optional) Args: prefix (str, optional): the name of prefix idx (int, str, optional): the index to increment. This can be a digit or arithmetic e.g. +5 or -3 can be used """ user = user or getpass.getuser() prefix = prefix or user if type(idx) is not int: idx = int(idx) Default.set('index', idx) return "%{:}_%{:}".format()
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 do_debug(self, args, arguments): """ :: Usage: debug on debug off debug list switches on and off the debug messages """ if arguments["on"]: Default.set_debug("on") Console.ok("Switch debug on") elif arguments["off"]: Default.set_debug("off") Console.ok("Switch debug off") elif arguments["list"]: debug = Default.debug() Console.ok("Debug is switched {}".format(debug)) return ""
def do_refresh(self, args, arguments): """ :: Usage: refresh on refresh off refresh list switches on and off the refresh for clouds """ if arguments["on"]: Default.set_refresh("on") Console.ok("Switch debug on") elif arguments["off"]: Default.set_refresh("off") Console.ok("Switch debug off") elif arguments["list"]: refresh = Default.get_refresh() Console.ok("Automatic cloud refresh is switched {}".format(refresh)) return ""
def do_usage(self, args, arguments): """ :: Usage: usage list [--cloud=CLOUD] [--start=START] [--end=END] [--tenant=TENANT] [--format=FORMAT] Show usage data. Options: --format=FORMAT the output format [default: table] --cloud=CLOUD the cloud name --tenant=TENANT the tenant name --start=START Usage range start date ex 2012-01-20, default is: 4 weeks ago --end=END Usage range end date, ex 2012-01-20, default is: tomorrow Examples: cm usage list """ if arguments["list"]: cloud = arguments["--cloud"] or Default.get("cloud") if not cloud: Console.error("cloud doesn't exist") return "" output_format = arguments["--format"] start = arguments["--start"] end = arguments["--end"] tenant = arguments["--tenant"] usage = Usage.list(cloud, start=start, end=end, tenant=tenant, format=output_format) Console.msg(usage) return ""
def __init__(self, context): cmd.Cmd.__init__(self) self.command_topics = {} self.register_topics() self.context = context if self.context.debug: print("init CloudmeshConsole") self.prompt = 'ghost> ' self.banner = textwrap.dedent(""" +==========================================================+ . _ .-') ('-. .-') _ . . ( '.( OO )_ _( OO) ( OO) ) . . .-----. .-'),-----. ,--. ,--.)(,------./ '._ . . ' .--./ ( OO' .-. '| `.' | | .---'|'--...__) . . | |('-. / | | | || | | | '--. .--' . . /_) |OO )\_) | |\| || |'.'| | (| '--. | | . . || |`-'| \ | | | || | | | | .--' | | . . (_' '--'\ `' '-' '| | | | | `---. | | . . `-----' `-----' `--' `--' `------' `--' . +==========================================================+ Comet Ghost 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 # value = Default.get('cloud', 'general') if value is None: filename = path_expand("~/.cloudmesh/cloudmesh.yaml") clouds = ConfigDict(filename=filename)["cloudmesh"]["clouds"] cloud = clouds.keys()[0] Default.set('cloud', cloud, 'general') value = Default.get('default', 'general') if value is None: Default.set('default', 'default', 'general') for c in CloudmeshConsole.__bases__[1:]: # noinspection PyArgumentList c.__init__(self, context)
def test_002(self): """ set default cloud :return: """ HEADING() result = Default.list() print(result) name = "mycloud" Default.set_cloud(name) result = Default.list() print(result) print ("KKK", Default.get_cloud()) assert Default.get_cloud() == name self._check(name)
def 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_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 __init__(self, context): cmd.Cmd.__init__(self) self.command_topics = {} self.register_topics() self.context = context if self.context.debug: print("init CloudmeshConsole") self.prompt = 'cm> ' 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 # filename = path_expand("~/.cloudmesh/cloudmesh.yaml") create_cloudmesh_yaml(filename) # sys,exit(1) value = Default.get('cloud', cloud='general') if value is None: clouds = ConfigDict(filename=filename)["cloudmesh"]["clouds"] cloud = clouds.keys()[0] Default.set('cloud', cloud, cloud='general') value = Default.get('default', cloud='general') if value is None: Default.set('default', 'default', cloud='general') cluster = 'india' # hardcode a value if not defined value = Default.get('cluster', cloud='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, cloud='general') # # Read cloud details from yaml file # filename = 'cloudmesh.yaml' config = ConfigDict(filename=filename)["cloudmesh"] clouds = config["clouds"] defaults = {'clouds': {}, 'key': {}} for cloud in clouds: if "default" in config['clouds'][cloud]: defaults['clouds'][cloud] = config["clouds"][cloud]['default'] if "default" in config["keys"]: defaults["keys"] = config["keys"]["default"] else: defaults['key'] = None for cloud in defaults["clouds"]: for default, value in defaults["clouds"][cloud].iteritems(): Default.set(default, value, cloud=cloud) for c in CloudmeshConsole.__bases__[1:]: # noinspection PyArgumentList c.__init__(self, context)
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_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_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_default(self, args, arguments): """ :: Usage: default list [--cloud=CLOUD] [--format=FORMAT] [--all] default delete KEY [--cloud=CLOUD] default KEY [--cloud=CLOUD] default KEY=VALUE [--cloud=CLOUD] Arguments: KEY the name of the default VALUE the value to set the key to Options: --cloud=CLOUD the name of the cloud --format=FORMAT the output format [default: table] --all lists all the default values Description: Cloudmesh has the ability to manage easily multiple clouds. One of the key concepts to make the list of such clouds easier is the introduction of defaults for each cloud or globally. Hence it is possible to set default images, flavors for each cloud, and also the default cloud. The default command is used to set and list the default values. These defaults are used in other commands if they are not overwritten by a command parameter. The current default values can by listed with --all option:( if you have a default cloud specified. You can also add a cloud parameter to apply the command to a specific cloud) default list A default can be set with default KEY=VALUE To look up a default value you can say default KEY A default can be deleted with default delete KEY Examples: default list --all default list --cloud=general default image=xyz default image=abc --cloud=kilo default image default image --cloud=kilo default delete image default delete image --cloud=kilo """ # pprint(arguments) """ For these keys, the 'cloud' column in db will always be 'general'. """ general_keys = ["cloud", "cluster", "queue"] """ If the default cloud has been set (eg. default cloud=xxx), then subsequent defaults for any key (eg. default image=yyy), will have 'cloud' column in db as the default cloud that was set. (eg. image=yyy for cloud=xxx). """ if arguments["KEY"] in general_keys: cloud = "general" else: cloud = arguments["--cloud"] or Default.get("cloud", "general") or "general" if arguments["list"]: output_format = arguments["--format"] if arguments['--all'] or arguments["--cloud"] is None: cloud = None result = Default.list(cloud=cloud, format=output_format) if result is None: Console.error("No default values found") else: print(result) return "" elif arguments["delete"]: key = arguments["KEY"] result = Default.delete(key, cloud) if result is None: Console.error("Key {} not present".format(key)) else: Console.ok("Deleted key {} for cloud {}. ok.".format(key, cloud)) return "" elif "=" in arguments["KEY"]: key, value = arguments["KEY"].split("=") if key in general_keys: cloud = "general" Default.set(key, value, cloud) Console.ok( "set in defaults {}={}. ok.".format(key, value)) return "" elif arguments["KEY"]: key = arguments["KEY"] result = Default.get(key, cloud) if result is None: Console.error("No default values found") else: Console.ok("Default value for {} is {}".format(key, result)) return ""
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 ""