|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- # imports - standard imports
- import os
- import sys
-
- # imports - third party imports
- import click
-
- # imports - module imports
- from bench.utils import exec_cmd, run_playbook, which
- from bench.utils.cli import SugaredOption
-
-
- @click.group(help="Setup command group for enabling setting up a Xhiveframework environment")
- def setup():
- pass
-
-
- @click.command(
- "sudoers", help="Add commands to sudoers list for execution without password"
- )
- @click.argument("user")
- def setup_sudoers(user):
- from bench.utils.system import setup_sudoers
-
- setup_sudoers(user)
-
-
- @click.command("nginx", help="Generate configuration files for NGINX")
- @click.option(
- "--logging", default="combined", type=click.Choice(["none", "site", "combined"])
- )
- @click.option(
- "--log_format",
- help="Specify the log_format for nginx. Use none or '' to not set a value.",
- only_if_set=["logging"],
- cls=SugaredOption,
- default="main",
- )
- @click.option(
- "--yes", help="Yes to regeneration of nginx config file", default=False, is_flag=True
- )
- def setup_nginx(yes=False, logging="combined", log_format=None):
- from bench.config.nginx import make_nginx_conf
-
- make_nginx_conf(bench_path=".", yes=yes, logging=logging, log_format=log_format)
-
-
- @click.command("reload-nginx", help="Checks NGINX config file and reloads service")
- def reload_nginx():
- from bench.config.production_setup import reload_nginx
-
- reload_nginx()
-
-
- @click.command("supervisor", help="Generate configuration for supervisor")
- @click.option("--user", help="optional user argument")
- @click.option(
- "--yes", help="Yes to regeneration of supervisor config", is_flag=True, default=False
- )
- @click.option(
- "--skip-redis", help="Skip redis configuration", is_flag=True, default=False
- )
- @click.option(
- "--skip-supervisord",
- help="Skip supervisord configuration",
- is_flag=True,
- default=False,
- )
- def setup_supervisor(user=None, yes=False, skip_redis=False, skip_supervisord=False):
- from bench.utils import get_cmd_output
- from bench.config.supervisor import (
- check_supervisord_config,
- generate_supervisor_config,
- )
-
- if which("supervisorctl") is None:
- click.secho("Please install `supervisor` to proceed", fg="red")
- sys.exit(1)
-
- if not skip_supervisord and "Permission denied" in get_cmd_output(
- "supervisorctl status"
- ):
- check_supervisord_config(user=user)
-
- generate_supervisor_config(bench_path=".", user=user, yes=yes, skip_redis=skip_redis)
-
-
- @click.command("redis", help="Generates configuration for Redis")
- def setup_redis():
- from bench.config.redis import generate_config
-
- generate_config(".")
-
-
- @click.command("fonts", help="Add Xhiveframework fonts to system")
- def setup_fonts():
- from bench.utils.system import setup_fonts
-
- setup_fonts()
-
-
- @click.command(
- "production", help="Setup Xhiveframework production environment for specific user"
- )
- @click.argument("user")
- @click.option("--yes", help="Yes to regeneration config", is_flag=True, default=False)
- def setup_production(user, yes=False):
- from bench.config.production_setup import setup_production
-
- setup_production(user=user, yes=yes)
-
-
- @click.command("backups", help="Add cronjob for bench backups")
- def setup_backups():
- from bench.bench import Bench
-
- Bench(".").setup.backups()
-
-
- @click.command("env", help="Setup Python environment for bench")
- @click.option(
- "--python", type=str, default="python3", help="Path to Python Executable."
- )
- def setup_env(python="python3"):
- from bench.bench import Bench
-
- return Bench(".").setup.env(python=python)
-
-
- @click.command("firewall", help="Setup firewall for system")
- @click.option("--ssh_port")
- @click.option("--force")
- def setup_firewall(ssh_port=None, force=False):
- if not force:
- click.confirm(
- f"Setting up the firewall will block all ports except 80, 443 and {ssh_port}\nDo you want to continue?",
- abort=True,
- )
-
- if not ssh_port:
- ssh_port = 22
-
- run_playbook("roles/bench/tasks/setup_firewall.yml", {"ssh_port": ssh_port})
-
-
- @click.command("ssh-port", help="Set SSH Port for system")
- @click.argument("port")
- @click.option("--force")
- def set_ssh_port(port, force=False):
- if not force:
- click.confirm(
- f"This will change your SSH Port to {port}\nDo you want to continue?", abort=True
- )
-
- run_playbook("roles/bench/tasks/change_ssh_port.yml", {"ssh_port": port})
-
-
- @click.command("lets-encrypt", help="Setup lets-encrypt SSL for site")
- @click.argument("site")
- @click.option("--custom-domain")
- @click.option(
- "-n",
- "--non-interactive",
- default=False,
- is_flag=True,
- help="Run command non-interactively. This flag restarts nginx and runs certbot non interactively. Shouldn't be used on 1'st attempt",
- )
- def setup_letsencrypt(site, custom_domain, non_interactive):
- from bench.config.lets_encrypt import setup_letsencrypt
-
- setup_letsencrypt(site, custom_domain, bench_path=".", interactive=not non_interactive)
-
-
- @click.command(
- "wildcard-ssl", help="Setup wildcard SSL certificate for multi-tenant bench"
- )
- @click.argument("domain")
- @click.option("--email")
- @click.option(
- "--exclude-base-domain",
- default=False,
- is_flag=True,
- help="SSL Certificate not applicable for base domain",
- )
- def setup_wildcard_ssl(domain, email, exclude_base_domain):
- from bench.config.lets_encrypt import setup_wildcard_ssl
-
- setup_wildcard_ssl(
- domain, email, bench_path=".", exclude_base_domain=exclude_base_domain
- )
-
-
- @click.command("procfile", help="Generate Procfile for bench start")
- def setup_procfile():
- from bench.config.procfile import setup_procfile
-
- setup_procfile(".")
-
-
- @click.command(
- "socketio", help="[DEPRECATED] Setup node dependencies for socketio server"
- )
- def setup_socketio():
- return
-
-
- @click.command("requirements")
- @click.option("--node", help="Update only Node packages", default=False, is_flag=True)
- @click.option(
- "--python", help="Update only Python packages", default=False, is_flag=True
- )
- @click.option(
- "--dev",
- help="Install optional python development dependencies",
- default=False,
- is_flag=True,
- )
- @click.argument("apps", nargs=-1)
- def setup_requirements(node=False, python=False, dev=False, apps=None):
- """
- Setup Python and Node dependencies.
-
- You can optionally specify one or more apps to setup dependencies for.
- """
- from bench.bench import Bench
-
- bench = Bench(".")
-
- if not (node or python or dev):
- bench.setup.requirements(apps=apps)
-
- elif not node and not dev:
- bench.setup.python(apps=apps)
-
- elif not python and not dev:
- bench.setup.node(apps=apps)
-
- else:
- from bench.utils.bench import install_python_dev_dependencies
-
- install_python_dev_dependencies(apps=apps)
-
- if node:
- click.secho(
- "--dev flag only supports python dependencies. All node development dependencies are installed by default.",
- fg="yellow",
- )
-
-
- @click.command(
- "manager",
- help="Setup bench-manager.local site with the bench_manager app installed on it",
- )
- @click.option(
- "--yes", help="Yes to regeneration of nginx config file", default=False, is_flag=True
- )
- @click.option(
- "--port", help="Port on which you want to run bench manager", default=23624
- )
- @click.option("--domain", help="Domain on which you want to run bench manager")
- def setup_manager(yes=False, port=23624, domain=None):
- from bench.bench import Bench
- from bench.config.nginx import make_bench_manager_nginx_conf
-
- create_new_site = True
-
- if "bench-manager.local" in os.listdir("sites"):
- create_new_site = click.confirm("Site already exists. Overwrite existing site?")
-
- if create_new_site:
- exec_cmd("bench new-site --force bench-manager.local")
-
- if "bench_manager" in os.listdir("apps"):
- print("App already exists. Skipping app download.")
- else:
- exec_cmd("bench get-app bench_manager")
-
- exec_cmd("bench --site bench-manager.local install-app bench_manager")
-
- bench_path = "."
- bench = Bench(bench_path)
-
- if bench.conf.get("restart_supervisor_on_update") or bench.conf.get(
- "restart_systemd_on_update"
- ):
- # implicates a production setup or so I presume
- if not domain:
- print(
- "Please specify the site name on which you want to host bench-manager using the 'domain' flag"
- )
- sys.exit(1)
-
- if domain not in bench.sites:
- raise Exception("No such site")
-
- make_bench_manager_nginx_conf(bench_path, yes=yes, port=port, domain=domain)
-
-
- @click.command("config", help="Generate or over-write sites/common_site_config.json")
- def setup_config():
- from bench.config.common_site_config import setup_config
-
- setup_config(".")
-
-
- @click.command("add-domain", help="Add a custom domain to a particular site")
- @click.argument("domain")
- @click.option("--site", prompt=True)
- @click.option("--ssl-certificate", help="Absolute path to SSL Certificate")
- @click.option("--ssl-certificate-key", help="Absolute path to SSL Certificate Key")
- def add_domain(domain, site=None, ssl_certificate=None, ssl_certificate_key=None):
- """Add custom domain to site"""
- if not site:
- print("Please specify site")
- sys.exit(1)
-
- from bench.config.site_config import add_domain
-
- add_domain(site, domain, ssl_certificate, ssl_certificate_key, bench_path=".")
-
-
- @click.command("remove-domain", help="Remove custom domain from a site")
- @click.argument("domain")
- @click.option("--site", prompt=True)
- def remove_domain(domain, site=None):
- if not site:
- print("Please specify site")
- sys.exit(1)
-
- from bench.config.site_config import remove_domain
-
- remove_domain(site, domain, bench_path=".")
-
-
- @click.command(
- "sync-domains",
- help="Check if there is a change in domains. If yes, updates the domains list.",
- )
- @click.option("--domain", multiple=True)
- @click.option("--site", prompt=True)
- def sync_domains(domain=None, site=None):
- if not site:
- print("Please specify site")
- sys.exit(1)
-
- try:
- domains = list(map(str, domain))
- except Exception:
- print("Domains should be a json list of strings or dictionaries")
- sys.exit(1)
-
- from bench.config.site_config import sync_domains
-
- changed = sync_domains(site, domains, bench_path=".")
-
- # if changed, success, else failure
- sys.exit(0 if changed else 1)
-
-
- @click.command("role", help="Install dependencies via ansible roles")
- @click.argument("role")
- @click.option("--admin_emails", default="")
- @click.option("--mysql_root_password", "--mariadb_root_password")
- @click.option("--container", is_flag=True, default=False)
- def setup_roles(role, **kwargs):
- extra_vars = {"production": True}
- extra_vars.update(kwargs)
-
- if role:
- run_playbook("site.yml", extra_vars=extra_vars, tag=role)
- else:
- run_playbook("site.yml", extra_vars=extra_vars)
-
-
- @click.command(
- "fail2ban",
- help="Setup fail2ban, an intrusion prevention software framework that protects computer servers from brute-force attacks",
- )
- @click.option(
- "--maxretry",
- default=6,
- help="Number of matches (i.e. value of the counter) which triggers ban action on the IP. Default is 6 seconds",
- )
- @click.option(
- "--bantime",
- default=600,
- help="Duration (in seconds) for IP to be banned for. Negative number for 'permanent' ban. Default is 600 seconds",
- )
- @click.option(
- "--findtime",
- default=600,
- help="The counter is set to zero if match found within 'findtime' seconds doesn't exceed 'maxretry'. Default is 600 seconds",
- )
- def setup_nginx_proxy_jail(**kwargs):
- run_playbook("roles/fail2ban/tasks/configure_nginx_jail.yml", extra_vars=kwargs)
-
-
- @click.command("systemd", help="Generate configuration for systemd")
- @click.option("--user", help="Optional user argument")
- @click.option(
- "--yes",
- help="Yes to regeneration of systemd config files",
- is_flag=True,
- default=False,
- )
- @click.option("--stop", help="Stop bench services", is_flag=True, default=False)
- @click.option("--create-symlinks", help="Create Symlinks", is_flag=True, default=False)
- @click.option("--delete-symlinks", help="Delete Symlinks", is_flag=True, default=False)
- def setup_systemd(
- user=None, yes=False, stop=False, create_symlinks=False, delete_symlinks=False
- ):
- from bench.config.systemd import generate_systemd_config
-
- generate_systemd_config(
- bench_path=".",
- user=user,
- yes=yes,
- stop=stop,
- create_symlinks=create_symlinks,
- delete_symlinks=delete_symlinks,
- )
-
-
- setup.add_command(setup_sudoers)
- setup.add_command(setup_nginx)
- setup.add_command(reload_nginx)
- setup.add_command(setup_supervisor)
- setup.add_command(setup_redis)
- setup.add_command(setup_letsencrypt)
- setup.add_command(setup_wildcard_ssl)
- setup.add_command(setup_production)
- setup.add_command(setup_backups)
- setup.add_command(setup_env)
- setup.add_command(setup_procfile)
- setup.add_command(setup_socketio)
- setup.add_command(setup_requirements)
- setup.add_command(setup_manager)
- setup.add_command(setup_config)
- setup.add_command(setup_fonts)
- setup.add_command(add_domain)
- setup.add_command(remove_domain)
- setup.add_command(sync_domains)
- setup.add_command(setup_firewall)
- setup.add_command(set_ssh_port)
- setup.add_command(setup_roles)
- setup.add_command(setup_nginx_proxy_jail)
- setup.add_command(setup_systemd)
|