Compare commits
5 Commits
61428cf80a
...
main
Author | SHA1 | Date | |
---|---|---|---|
c81588265b | |||
55a487fed3 | |||
777d0cfbd7 | |||
b546e03e37 | |||
6608e1216b |
6
cli.py
6
cli.py
@ -193,6 +193,10 @@ def recover_env(args: argparse.Namespace):
|
||||
|
||||
|
||||
def create_env(args: argparse.Namespace):
|
||||
"""
|
||||
Managing environments works in a declarative way and thus it can
|
||||
also be used for updating.
|
||||
"""
|
||||
if (args.num_nginx_web + args.num_nginx_lb + args.num_postgres) == 0:
|
||||
raise Exception("At least one item should be deployed")
|
||||
|
||||
@ -306,7 +310,7 @@ def main() -> int:
|
||||
|
||||
# CLI definition for positional arg "create"
|
||||
cenv_parser = sub_parser.add_parser("create",
|
||||
help="create a new environment")
|
||||
help="create/update an environment")
|
||||
cenv_parser.add_argument("customer_name",
|
||||
type=str,
|
||||
help="name of the customer")
|
||||
|
101
service.py
101
service.py
@ -5,6 +5,7 @@ from os import path
|
||||
import subprocess as sub
|
||||
import re
|
||||
from typing import Any, Callable
|
||||
from enum import Enum
|
||||
|
||||
P_BANNER = """
|
||||
██╗ ██╗███████╗██╗ ██╗ ██╗ ██████╗ ███╗ ███╗
|
||||
@ -23,6 +24,13 @@ Opties:
|
||||
3) Recover omgeving(en)
|
||||
4) List omgeving(en)
|
||||
"""
|
||||
class PortalOptions(Enum):
|
||||
EXIT = "0"
|
||||
CREATE = "1"
|
||||
DESTROY = "2"
|
||||
RECOVER = "3"
|
||||
LIST = "4"
|
||||
|
||||
|
||||
RE_TEXT = re.compile(r"^\w+$")
|
||||
RE_NUM = re.compile(r"^\d+$")
|
||||
@ -49,6 +57,11 @@ class Prompter:
|
||||
prompt = self._build_prompt(prompt)
|
||||
return Prompter.input(prompt, lambda x: x in options)
|
||||
|
||||
def take_confirmation(self, prompt: str, default: str = "y") -> bool:
|
||||
prompt = self._build_prompt(prompt)
|
||||
i = Prompter.input(prompt, lambda x: x.lower() in ["y", "n"], default=default)
|
||||
return i == "y"
|
||||
|
||||
@staticmethod
|
||||
def input(prompt: str,
|
||||
validate: Callable[[str], bool],
|
||||
@ -60,7 +73,6 @@ class Prompter:
|
||||
if validate(i):
|
||||
return i
|
||||
|
||||
|
||||
def get_env_list(customer: str) -> list[str]:
|
||||
"""Fetches and parses a list of a customer's environments
|
||||
|
||||
@ -80,6 +92,8 @@ def main() -> int:
|
||||
lambda x: bool(RE_TEXT.match(x)))
|
||||
"""
|
||||
Ensures the necessary customer setup.
|
||||
|
||||
NOTE: The customer and the `envs` directory inside of it never get removed.
|
||||
"""
|
||||
envs_dir = path.join("customers", customer_name, "envs")
|
||||
Path(envs_dir).mkdir(parents=True, exist_ok=True)
|
||||
@ -87,16 +101,16 @@ def main() -> int:
|
||||
p = Prompter(ps1=f"{customer_name} > ")
|
||||
while True:
|
||||
print(P_OPTIONS)
|
||||
c = p.take_input("Keuze: ", RE_ANY)
|
||||
choice = p.take_input("Keuze: ", RE_ANY)
|
||||
print(end="\n")
|
||||
|
||||
if c == "0":
|
||||
if choice == PortalOptions.EXIT.value:
|
||||
"""
|
||||
Used to break out of the loop and exit the portal.
|
||||
"""
|
||||
break
|
||||
|
||||
if c == "1":
|
||||
if choice == PortalOptions.CREATE.value:
|
||||
"""
|
||||
Used to either update or create an environment.
|
||||
"""
|
||||
@ -104,38 +118,57 @@ def main() -> int:
|
||||
print(
|
||||
f"NOTE: Kies een albestaande omgevingen {envs} of iets nieuws..."
|
||||
)
|
||||
fmt = "Omgevingsnaam:"
|
||||
fmt = "Omgevingsnaam: "
|
||||
env_name = p.take_input(fmt, RE_TEXT)
|
||||
|
||||
templates = ["production", "acceptance", "test", "custom"]
|
||||
fmt = f"Het type omgeving {templates}: "
|
||||
template_name = p.take_choice(fmt, templates)
|
||||
# Loop until customer has confirmed their desired combination of machines
|
||||
while True:
|
||||
templates = ["production", "acceptance", "test", "custom"]
|
||||
fmt = f"Het type omgeving {templates}: "
|
||||
template_name = p.take_choice(fmt, templates)
|
||||
if template_name == "custom":
|
||||
"""
|
||||
Asks for all machine's individually
|
||||
"""
|
||||
fmt = "Aantal nginx webservers (default=1): "
|
||||
amnt_nginx_web = p.take_input(fmt, RE_NUM, default="1")
|
||||
|
||||
if template_name == "custom":
|
||||
"""
|
||||
Asks for all machine's individually
|
||||
"""
|
||||
fmt = "Aantal nginx webservers (default=1): "
|
||||
amnt_nginx_web = p.take_input(fmt, RE_NUM, default="1")
|
||||
fmt = "Aantal nginx loadbalancers (default=1): "
|
||||
amnt_nginx_lb = p.take_input(fmt, RE_NUM, default="1")
|
||||
|
||||
fmt = "Aantal nginx loadbalancers (default=1): "
|
||||
amnt_nginx_lb = p.take_input(fmt, RE_NUM, default="1")
|
||||
fmt = "Aantal postgres instances (default=1): "
|
||||
amnt_psql = p.take_input(fmt, RE_NUM, default="1")
|
||||
elif template_name == "production":
|
||||
amnt_nginx_web = "2"
|
||||
amnt_nginx_lb = "1"
|
||||
amnt_psql = "1"
|
||||
|
||||
elif template_name == "acceptance":
|
||||
amnt_nginx_web = "1"
|
||||
amnt_nginx_lb = "0"
|
||||
amnt_psql = "1"
|
||||
# elif template_name == "test":
|
||||
else:
|
||||
amnt_nginx_web = "1"
|
||||
amnt_nginx_lb = "0"
|
||||
amnt_psql = "0"
|
||||
|
||||
# TODO: migrate different machine types to a dict model
|
||||
print(end="\n")
|
||||
print("Deze omgeving bevat:")
|
||||
if amnt_nginx_web > "0":
|
||||
print(f" - {amnt_nginx_web} Nginx webserver(s)")
|
||||
|
||||
if amnt_nginx_lb > "0":
|
||||
print(f" - {amnt_nginx_lb} Nginx loadbalancer(s)")
|
||||
|
||||
if amnt_psql > "0":
|
||||
print(f" - {amnt_psql} Postgres instance(s)")
|
||||
print(end="\n")
|
||||
|
||||
if p.take_confirmation("Bevestig (Y/n): "):
|
||||
break
|
||||
|
||||
fmt = "Aantal postgres instances (default=1): "
|
||||
amnt_psql = p.take_input(fmt, RE_NUM, default="1")
|
||||
elif template_name == "production":
|
||||
amnt_nginx_web = "2"
|
||||
amnt_nginx_lb = "1"
|
||||
amnt_psql = "1"
|
||||
elif template_name == "acceptance":
|
||||
amnt_nginx_web = "1"
|
||||
amnt_nginx_lb = "0"
|
||||
amnt_psql = "1"
|
||||
# elif template_name == "test":
|
||||
else:
|
||||
amnt_nginx_web = "1"
|
||||
amnt_nginx_lb = "0"
|
||||
amnt_psql = "0"
|
||||
"""
|
||||
Define the format for templating ip-addresses.`{}` is required
|
||||
and will be subbed at runtime with the correct octet.
|
||||
@ -157,7 +190,7 @@ def main() -> int:
|
||||
])
|
||||
print(f"Omgeving `{env_name}` successvol gemaakt.")
|
||||
|
||||
if c == "2":
|
||||
if choice == PortalOptions.DESTROY.value:
|
||||
"""
|
||||
Deletes all traces of the chosen environment.
|
||||
"""
|
||||
@ -166,7 +199,7 @@ def main() -> int:
|
||||
env_name = p.take_choice(fmt, envs)
|
||||
sub.call(["python3", "cli.py", "delete", customer_name, env_name])
|
||||
|
||||
if c == "3":
|
||||
if choice == PortalOptions.RECOVER.value:
|
||||
"""
|
||||
Allows the customer to "force" their environment into the desired `up-state`.
|
||||
This `up-state` is a representation of the Vagrantfile, Ansible inventory and
|
||||
@ -179,7 +212,7 @@ def main() -> int:
|
||||
env_name = p.take_choice(fmt, envs)
|
||||
sub.call(["python3", "cli.py", "recover", customer_name, env_name])
|
||||
|
||||
if c == "4":
|
||||
if choice == PortalOptions.LIST.value:
|
||||
"""
|
||||
This branch displays the customer's existing environments
|
||||
"""
|
||||
|
@ -3,3 +3,6 @@ private_key_file = "./.ssh/id_rsa"
|
||||
remote_user = "vagrant"
|
||||
inventory = ./inventory
|
||||
host_key_checking = False
|
||||
|
||||
[ssh_connection]
|
||||
retries=2
|
||||
|
Reference in New Issue
Block a user