PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/cloud/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/cloud/libcloudfuncs.py |
""" The generic libcloud template used to create the connections and deploy the cloud virtual machines """ import logging import os import salt.client import salt.config import salt.utils.cloud import salt.utils.data import salt.utils.event from salt.exceptions import SaltCloudNotFound, SaltCloudSystemExit # pylint: disable=W0611 try: import libcloud from libcloud.compute.deployment import MultiStepDeployment, ScriptDeployment from libcloud.compute.providers import get_driver from libcloud.compute.types import NodeState, Provider HAS_LIBCLOUD = True LIBCLOUD_VERSION_INFO = tuple( int(part) for part in libcloud.__version__.replace("-", ".") .replace("rc", ".") .split(".")[:3] ) except ImportError: HAS_LIBCLOUD = False LIBCLOUD_VERSION_INFO = (1000,) # pylint: enable=W0611 log = logging.getLogger(__name__) LIBCLOUD_MINIMAL_VERSION = (1, 5, 0) def check_libcloud_version(reqver=LIBCLOUD_MINIMAL_VERSION, why=None): """ Compare different libcloud versions """ if not HAS_LIBCLOUD: return False if not isinstance(reqver, (list, tuple)): raise RuntimeError( "'reqver' needs to passed as a tuple or list, i.e., (1, 5, 0)" ) if LIBCLOUD_VERSION_INFO >= reqver: return libcloud.__version__ errormsg = ( "Your version of libcloud is {}. salt-cloud requires >= libcloud {}".format( libcloud.__version__, ".".join([str(num) for num in reqver]) ) ) if why: errormsg += f" for {why}" errormsg += ". Please upgrade." raise ImportError(errormsg) def get_node(conn, name): """ Return a libcloud node for the named VM """ nodes = conn.list_nodes() for node in nodes: if node.name == name: __utils__["cloud.cache_node"]( salt.utils.data.simple_types_filter(node.__dict__), __active_provider_name__, __opts__, ) return node def avail_locations(conn=None, call=None): """ Return a dict of all available VM locations on the cloud provider with relevant data """ if call == "action": raise SaltCloudSystemExit( "The avail_locations function must be called with " "-f or --function, or with the --list-locations option" ) if not conn: conn = get_conn() # pylint: disable=E0602 locations = conn.list_locations() ret = {} for img in locations: img_name = str(img.name) ret[img_name] = {} for attr in dir(img): if attr.startswith("_") or attr == "driver": continue attr_value = getattr(img, attr) ret[img_name][attr] = attr_value return ret def avail_images(conn=None, call=None): """ Return a dict of all available VM images on the cloud provider with relevant data """ if call == "action": raise SaltCloudSystemExit( "The avail_images function must be called with " "-f or --function, or with the --list-images option" ) if not conn: conn = get_conn() # pylint: disable=E0602 images = conn.list_images() ret = {} for img in images: img_name = str(img.name) ret[img_name] = {} for attr in dir(img): if attr.startswith("_") or attr in ("driver", "get_uuid"): continue attr_value = getattr(img, attr) ret[img_name][attr] = attr_value return ret def avail_sizes(conn=None, call=None): """ Return a dict of all available VM images on the cloud provider with relevant data """ if call == "action": raise SaltCloudSystemExit( "The avail_sizes function must be called with " "-f or --function, or with the --list-sizes option" ) if not conn: conn = get_conn() # pylint: disable=E0602 sizes = conn.list_sizes() ret = {} for size in sizes: size_name = str(size.name) ret[size_name] = {} for attr in dir(size): if attr.startswith("_") or attr in ("driver", "get_uuid"): continue try: attr_value = getattr(size, attr) except Exception: # pylint: disable=broad-except pass ret[size_name][attr] = attr_value return ret def get_location(conn, vm_): """ Return the location object to use """ locations = conn.list_locations() vm_location = salt.config.get_cloud_config_value("location", vm_, __opts__) for img in locations: img_id = str(img.id) img_name = str(img.name) if vm_location and vm_location in (img_id, img_name): return img raise SaltCloudNotFound( f"The specified location, '{vm_location}', could not be found." ) def get_image(conn, vm_): """ Return the image object to use """ images = conn.list_images() vm_image = salt.config.get_cloud_config_value("image", vm_, __opts__) for img in images: img_id = str(img.id) img_name = str(img.name) if vm_image and vm_image in (img_id, img_name): return img raise SaltCloudNotFound(f"The specified image, '{vm_image}', could not be found.") def get_size(conn, vm_): """ Return the VM's size object """ sizes = conn.list_sizes() vm_size = salt.config.get_cloud_config_value("size", vm_, __opts__) if not vm_size: return sizes[0] for size in sizes: if vm_size and str(vm_size) in ( str(size.id), str(size.name), ): return size raise SaltCloudNotFound(f"The specified size, '{vm_size}', could not be found.") def script(vm_): """ Return the script deployment object """ return ScriptDeployment( salt.utils.cloud.os_script( salt.config.get_cloud_config_value("os", vm_, __opts__), vm_, __opts__, salt.utils.cloud.salt_config_to_yaml( salt.utils.cloud.minion_config(__opts__, vm_) ), ) ) def destroy(name, conn=None, call=None): """ Delete a single VM """ if call == "function": raise SaltCloudSystemExit( "The destroy action must be called with -d, --destroy, -a or --action." ) __utils__["cloud.fire_event"]( "event", "destroying instance", f"salt/cloud/{name}/destroying", args={"name": name}, sock_dir=__opts__["sock_dir"], transport=__opts__["transport"], ) if not conn: conn = get_conn() # pylint: disable=E0602 node = get_node(conn, name) profiles = get_configured_provider()["profiles"] # pylint: disable=E0602 if node is None: log.error("Unable to find the VM %s", name) profile = None if "metadata" in node.extra and "profile" in node.extra["metadata"]: profile = node.extra["metadata"]["profile"] flush_mine_on_destroy = False if profile and profile in profiles and "flush_mine_on_destroy" in profiles[profile]: flush_mine_on_destroy = profiles[profile]["flush_mine_on_destroy"] if flush_mine_on_destroy: log.info("Clearing Salt Mine: %s", name) mopts_ = salt.config.DEFAULT_MINION_OPTS conf_path = "/".join(__opts__["conf_file"].split("/")[:-1]) mopts_.update(salt.config.minion_config(os.path.join(conf_path, "minion"))) with salt.client.get_local_client(mopts=mopts_) as client: minions = client.cmd(name, "mine.flush") log.info("Clearing Salt Mine: %s, %s", name, flush_mine_on_destroy) log.info("Destroying VM: %s", name) ret = conn.destroy_node(node) if ret: log.info("Destroyed VM: %s", name) # Fire destroy action __utils__["cloud.fire_event"]( "event", "destroyed instance", f"salt/cloud/{name}/destroyed", args={"name": name}, sock_dir=__opts__["sock_dir"], transport=__opts__["transport"], ) if __opts__["delete_sshkeys"] is True: public_ips = getattr(node, __opts__.get("ssh_interface", "public_ips")) if public_ips: salt.utils.cloud.remove_sshkey(public_ips[0]) private_ips = getattr(node, __opts__.get("ssh_interface", "private_ips")) if private_ips: salt.utils.cloud.remove_sshkey(private_ips[0]) if __opts__.get("update_cachedir", False) is True: __utils__["cloud.delete_minion_cachedir"]( name, __active_provider_name__.split(":")[0], __opts__ ) return True log.error("Failed to Destroy VM: %s", name) return False def reboot(name, conn=None): """ Reboot a single VM """ if not conn: conn = get_conn() # pylint: disable=E0602 node = get_node(conn, name) if node is None: log.error("Unable to find the VM %s", name) log.info("Rebooting VM: %s", name) ret = conn.reboot_node(node) if ret: log.info("Rebooted VM: %s", name) # Fire reboot action __utils__["cloud.fire_event"]( "event", f"{name} has been rebooted", f"salt/cloud/{name}/rebooting", args={"name": name}, sock_dir=__opts__["sock_dir"], transport=__opts__["transport"], ) return True log.error("Failed to reboot VM: %s", name) return False def list_nodes(conn=None, call=None): """ Return a list of the VMs that are on the provider """ if call == "action": raise SaltCloudSystemExit( "The list_nodes function must be called with -f or --function." ) if not conn: conn = get_conn() # pylint: disable=E0602 nodes = conn.list_nodes() ret = {} for node in nodes: ret[node.name] = { "id": node.id, "image": node.image, "name": node.name, "private_ips": node.private_ips, "public_ips": node.public_ips, "size": node.size, "state": str(node.state).upper(), } return ret def list_nodes_full(conn=None, call=None): """ Return a list of the VMs that are on the provider, with all fields """ if call == "action": raise SaltCloudSystemExit( "The list_nodes_full function must be called with -f or --function." ) if not conn: conn = get_conn() # pylint: disable=E0602 nodes = conn.list_nodes() ret = {} for node in nodes: pairs = {} for key, value in zip(node.__dict__, node.__dict__.values()): pairs[key] = value ret[node.name] = pairs del ret[node.name]["driver"] __utils__["cloud.cache_node_list"]( ret, __active_provider_name__.split(":")[0], __opts__ ) return ret def list_nodes_select(conn=None, call=None): """ Return a list of the VMs that are on the provider, with select fields """ if not conn: conn = get_conn() # pylint: disable=E0602 return salt.utils.cloud.list_nodes_select( list_nodes_full(conn, "function"), __opts__["query.selection"], call, ) def show_instance(name, call=None): """ Show the details from the provider concerning an instance """ if call != "action": raise SaltCloudSystemExit( "The show_instance action must be called with -a or --action." ) nodes = list_nodes_full() __utils__["cloud.cache_node"](nodes[name], __active_provider_name__, __opts__) return nodes[name] def conn_has_method(conn, method_name): """ Find if the provided connection object has a specific method """ if method_name in dir(conn): return True log.error("Method '%s' not yet supported!", method_name) return False