[+] yml executor

This commit is contained in:
2024-07-22 02:34:10 +03:00
parent 0ed1516b9f
commit 2a9655efbb

View File

@@ -66,6 +66,7 @@ class VMKer:
self.config = None self.config = None
self.vm_list = set() self.vm_list = set()
self.template = None self.template = None
self.cmds = {}
@staticmethod @staticmethod
def generate_key_from_password(password: str, salt: bytes) -> bytes: def generate_key_from_password(password: str, salt: bytes) -> bytes:
@@ -143,7 +144,7 @@ class VMKer:
logger.error(f"TimeoutError: {e}") logger.error(f"TimeoutError: {e}")
return False return False
def _edit(self, _first_init=False): def _console(self, _first_init=False):
self._load_config() self._load_config()
logger.info("Entered to configuration mode.") logger.info("Entered to configuration mode.")
@@ -250,6 +251,7 @@ class VMKer:
print("Incorrect syntax.") print("Incorrect syntax.")
print("Usage: edit [server|port|password|ssl|datacenter|datastore|respool] <new value>") print("Usage: edit [server|port|password|ssl|datacenter|datastore|respool] <new value>")
case "test": case "test":
self._load_yml(True)
try: try:
self._connect() self._connect()
except Exception as e: except Exception as e:
@@ -276,8 +278,62 @@ class VMKer:
ipv6.append(ip.ipAddress) ipv6.append(ip.ipAddress)
return ipv4, ipv6 return ipv4, ipv6
def _parse_yml(self, ssh): def _load_yml(self, test=False):
pass _f = args.get("f")
if not _f:
return
for f in _f:
try:
f = Path(f)
if not f.exists():
return logger.error(f"[YML] File not exist: {f}")
if f.is_dir():
return logger.error(f"[YML] Not a file: {f}")
if f.suffix != ".yml":
return logger.error(f"[YML] File not YAML: {f}")
y = yaml.load(f)
self.cmds[f] = y
if test:
s = f"{f}:"
br = y.get("before-reboot")
if br:
s += "\n Before-Reboot:"
for n, c in br.items():
s += f"\n {n}:"
for _c in c:
s += f"\n {_c}"
ar = y.get("after-reboot")
if ar:
s += "\n After-Reboot:"
for n, c in ar.items():
s += f"\n {n}:"
for _c in c:
s += f"\n {_c}"
logger.debug(s)
print(s)
except Exception as e:
logger.exception(e)
def _execute_yml(self, name, ssh, _pre=True):
for p, f in self.cmds.items():
try:
if _pre:
y = f.get('before-reboot')
logger.info(f"[{name}] [YML] Executing {f.name}..")
if not y:
return logger.debug(f"[{name}] [YML] Block 'before-reboot' not found. Skipping..")
for n, c in y.items():
logger.info(f"[{name}] [YML] {n}. Steps: {len(c)}.")
for cmd, i in enumerate(c, 1):
logger.debug(f"executing: {cmd}")
logger.debug(ssh.send_command(cmd))
logger.info(f"[{name}] [YML] {n}: {i}/{len(c)}")
else:
y = f.get('after-reboot')
if not y:
return logger.debug(f"[{name}] [YML] Block 'after-reboot' not found. Skipping..")
except Exception as e:
logger.exception(e)
def _clone(self, new_name, destfolder, clone_spec): def _clone(self, new_name, destfolder, clone_spec):
logger.info(f"[{new_name}] Cloning from {self.template.name!r}") logger.info(f"[{new_name}] Cloning from {self.template.name!r}")
@@ -322,14 +378,13 @@ class VMKer:
try: try:
ssh = ConnectHandler(**_ssh_connect) ssh = ConnectHandler(**_ssh_connect)
logger.success(f"[{_name}] [SSH] Connected to {ipv4[0]} as {user} ({key_file=})") logger.success(f"[{_name}] [SSH] Connected to {ipv4[0]} as {user} ({key_file=})")
# TODO: length
_pwd = ''.join(random.choice(chars) for _ in range(12)) _pwd = ''.join(random.choice(chars) for _ in range(12))
ssh.send_command(f"echo '{user}:{_pwd}' | chpasswd") ssh.send_command(f"echo '{user}:{_pwd}' | chpasswd")
logger.info(f"[{_name}] Password for root: {_pwd}") logger.info(f"[{_name}] Password for root: {_pwd}")
ssh.send_command(f'echo {_name} > /etc/hostname') ssh.send_command(f'echo {_name} > /etc/hostname')
# TODO: yml logger.info(f"[{_name}] [YML] After-Reboot.")
logger.info(f"[{_name}] [YML] Executing %.yml") self._execute_yml(_name, ssh)
ssh.disconnect() ssh.disconnect()
vm.RebootGuest() vm.RebootGuest()
@@ -348,7 +403,8 @@ class VMKer:
logger.success(f"[{_name}] [SSH] Connected to {ipv4[0]} as {user}") logger.success(f"[{_name}] [SSH] Connected to {ipv4[0]} as {user}")
logger.debug(f'[{_name}] uname {ssh.send_command("uname -a")}') logger.debug(f'[{_name}] uname {ssh.send_command("uname -a")}')
logger.info(f"[{_name}] [YML] Checks %.yml") logger.info(f"[{_name}] [YML] Before-Reboot.")
self._execute_yml(_name, ssh, False)
except NetmikoAuthenticationException as e: except NetmikoAuthenticationException as e:
return logger.error(f"[{_name}] [SSH] Error: Authentication. ({e})") return logger.error(f"[{_name}] [SSH] Error: Authentication. ({e})")
@@ -387,6 +443,7 @@ class VMKer:
return return
logger.info("Loading...") logger.info("Loading...")
self._load_yml()
datacenter = [dc for dc in self.content.rootFolder.childEntity if dc.name == self.config['datacenter']] datacenter = [dc for dc in self.content.rootFolder.childEntity if dc.name == self.config['datacenter']]
if not datacenter: if not datacenter:
return logger.error(f"Datacenter not found: {self.config['datacenter']}") return logger.error(f"Datacenter not found: {self.config['datacenter']}")
@@ -451,9 +508,9 @@ class VMKer:
if len(sys.argv) > 1: if len(sys.argv) > 1:
match sys.argv[1]: match sys.argv[1]:
case "init": case "init":
self._edit(True) self._console(True)
case "edit": case "console":
self._edit() self._console()
case "create": case "create":
self._create() self._create()
case _: case _: