def get_instance(self, name: str) -> object: log.info(f"Instantiate {name}") try: obj_class: object = self.CLOUD_CLASSES[name] return obj_class() except KeyError as e: raise NotImplementedError(f"{e} not implemented")
def configure(self, configs: dict, dry_run: bool, excludes: dict) -> None: self.configs = configs self.dry_run = dry_run self.excludes = excludes if self.dry_run: log.info(f"Running in dry-run") self._handle_excludes()
def __init__(self) -> None: super().__init__() log.info(f"Proxmox host: {PROXMOX_API_HOST}") log.info(f"Proxmox user: {PROXMOX_API_USER}") self.pve = ProxmoxAPI(host=PROXMOX_API_HOST, user=PROXMOX_API_USER, password=PROXMOX_API_PASSWORD, verify_ssl=PROXMOX_API_VERIFY_SSL)
def run_periodic(interval: int = 1) -> None: log.info(f"Running periodic in intervals of {interval} minute") schedule.every(interval).minutes.do(app) time.sleep(1) schedule.run_all() while True: schedule.run_pending() sys.stdout.write(".") sys.stdout.flush() time.sleep(1)
def _get_namespace(self) -> str: namespaces = [ns['Name'] for ns in self.nomad.list_namespaces()] allowed_ns = self.configs.get('namespace_allowlist') if allowed_ns is not None: namespaces = [ns for ns in namespaces if ns in allowed_ns] denied_ns = self.configs.get('namespace_denylist') if denied_ns is not None: namespaces = [ns for ns in namespaces if ns not in denied_ns] if not namespaces: log.info(f"No namespaces eligible") return namespace = random.choice(namespaces) log.info(f"Selected namespace: {namespace}") return namespace
def main() -> None: parser: ArgumentParser = ArgumentParser() parser.add_argument("--periodic", help="run periodic", action="store_true") parser.add_argument("--interval", help="set interval in minutes", type=int, default=1) parser.add_argument("--version", help="show version", action="store_true") args = parser.parse_args() if args.version: print(f"version {__version__}") sys.exit(0) log.info(f"Starting version {__version__}") if args.periodic: try: run_periodic(args.interval) except KeyboardInterrupt: print("") log.info(f"Stopping...") schedule.clear() log.info(f"done") pass else: app()
def action(self) -> None: namespace = self._get_namespace() if namespace: allocs = self.nomad.list_allocs(namespace=namespace) if allocs: alloc = random.choice(allocs) log.info(f"Selected alloc: {alloc['JobID']} (ID: {alloc['ID']}) on {alloc['NodeName']}") signal = random.choice(self.configs['signals']) log.info(f"Selected signal: {signal}") if not self.dry_run: self.nomad.signal_alloc(alloc_id=alloc['ID'], signal=signal) else: log.info("No allocs found") log.info(f"done")
def action(self) -> None: vms = self.pve.cluster.resources.get(type='vm') denylist = self.configs.get('denylist') or [] vms = [ vm for vm in vms if vm['status'] == "running" and vm['name'] not in denylist ] if vms: vm = random.choice(vms) log.info( f"Choose VM ID={vm['vmid']}, name={vm['name']} on node={vm['node']}" ) min_uptime = self.configs.get('min_uptime') if min_uptime is not None: current = self.pve.nodes(vm['node']).qemu( vm['vmid']).status.current.get() required_uptime = min_uptime * 60 if current['uptime'] < required_uptime: log.info( f"VM {vm['name']} required uptime lower then {min_uptime} min: {current['uptime'] / 60:.2f}, skipping" ) log.info(f"done") return if not self.dry_run: log.info(f"Stopping VM {vm['name']}") self.pve.nodes(vm['node']).qemu( vm['vmid']).status.shutdown.post(forceStop=1) wait_before_restart = int( self.configs.get('wait_before_restart', 60)) log.info(f"Sleeping for {wait_before_restart} seconds") time.sleep(wait_before_restart) log.info(f"Starting VM {vm['name']}") self.pve.nodes(vm['node']).qemu(vm['vmid']).status.start.post() else: log.info("No VMs found") log.info(f"done")
def action(self) -> None: tag = self.configs.get('tag') log.info(f"Querying with tag: {tag}") droplets = self.do.get_all_droplets(tag_name=tag) if droplets: droplet = random.choice(droplets) log.info(f"Choose server {droplet.name}") if not self.dry_run: log.info(f"Stopping server {droplet.name}") droplet.shutdown() wait_before_restart = int(self.configs.get('wait_before_restart', 60)) log.info(f"Sleeping for {wait_before_restart} seconds") time.sleep(wait_before_restart) log.info(f"Starting server {droplet.name}") droplet.power_on() else: log.info("No servers found") log.info(f"done")
def action(self) -> None: tag = self.configs.get('tag') log.info(f"Querying with tag: {tag}") instances = self.vultr.list_instances(tag=tag) if instances: instance = random.choice(instances) log.info(f"Choose server {instance['label']}") if not self.dry_run: log.info(f"Stopping server {instance['label']}") self.vultr.halt_instance(instance['id']) wait_before_restart = int( self.configs.get('wait_before_restart', 60)) log.info(f"Sleeping for {wait_before_restart} seconds") time.sleep(wait_before_restart) log.info(f"Starting server {instance['label']}") self.vultr.start_instance(instance['id']) else: log.info("No servers found") log.info(f"done")
def action(self) -> None: label = self.configs.get('label') log.info(f"Querying with label: {label}") servers = self.hcloud.servers.get_all(label_selector=label) if servers: server = random.choice(servers) log.info(f"Choose server {server.name}") if not self.dry_run: log.info(f"Stopping server {server.name}") self.hcloud.servers.power_off(server) wait_before_restart = int(self.configs.get('wait_before_restart', 60)) log.info(f"Sleeping for {wait_before_restart} seconds") time.sleep(wait_before_restart) log.info(f"Starting server {server.name}") self.hcloud.servers.power_on(server) else: log.info("No servers found") log.info(f"done")
def _handle_excludes(self) -> None: if 'days_of_year' in self.excludes: today = datetime.today().strftime('%b%d') if today in self.excludes['days_of_year']: log.info( f"Today '{today}' in days_of_year excludes, running dry-run" ) self.dry_run = True if 'weekdays' in self.excludes: today = datetime.today().strftime('%a') if today in self.excludes['weekdays']: log.info( f"Today '{today}' in weekday excludes, running dry-run") self.dry_run = True if 'times_of_day' in self.excludes: now = datetime.now().time() for time_range in self.excludes['times_of_day']: start, end = time_range.split('-') start_time = datetime.strptime(start, "%H:%M").time() end_time = datetime.strptime(end, "%H:%M").time() if start_time > end_time: end_of_day = datetime.strptime("23:59", "%H:%M").time() if start_time <= now <= end_of_day: log.info(f"Exclude {start_time}-{end_time}") log.info( f"{now} in time of day excludes, running dry-run") self.dry_run = True start_of_day = datetime.strptime("00:01", "%H:%M").time() if start_of_day <= now <= end_time: log.info(f"Exclude {start_time}-{end_time}") log.info( f"{now} in time of day excludes, running dry-run") self.dry_run = True else: if start_time <= now <= end_time: log.info(f"Exclude {start_time}-{end_time}") log.info( f"{now} in time of day excludes, running dry-run") self.dry_run = True
def action(self) -> None: tag = self.configs.get('tag') log.info(f"Querying with tag: {tag['key']}={tag['value']}") instances = self.cs.listVirtualMachines( tags=[tag], projectid=self.configs.get('projectid'), zoneid=self.configs.get('zoneid'), fetch_list=True, ) if instances: instance = random.choice(instances) log.info(f"Choose server {instance['name']}") if not self.dry_run: log.info(f"Stopping server {instance['name']}") self.cs.stopVirtualMachine(id=instance['id']) wait_before_restart = int( self.configs.get('wait_before_restart', 60)) log.info(f"Sleeping for {wait_before_restart} seconds") time.sleep(wait_before_restart) log.info(f"Starting server {instance['name']}") self.cs.startVirtualMachine(id=instance['id']) else: log.info("No servers found") log.info(f"done")
def action(self) -> None: filter_tag = self.configs.get('filter_tag') log.info(f"Querying with filter_tag: {filter_tag}") servers = self.cloudscale.server.get_all(filter_tag=filter_tag) if servers: server = random.choice(servers) log.info(f"Choose server {server['name']}") if not self.dry_run: log.info(f"Stopping server {server['name']}") self.cloudscale.server.stop(uuid=server['uuid']) wait_before_restart = int(self.configs.get('wait_before_restart', 60)) log.info(f"Sleeping for {wait_before_restart} seconds") time.sleep(wait_before_restart) log.info(f"Starting server {server['name']}") self.cloudscale.server.start(uuid=server['uuid']) else: log.info("No servers found") log.info(f"done")