def generate(name, domain, country, state, locale, email, keytype, keylength): """Generate an SSL/TLS certificate.""" if not domain: logger.error( "ctl:info:generate", "Choose a fully-qualified domain name of the " "certificate. Must match a domain present on the system" ) domain = click.prompt("Domain name") if not country: logger.info( "ctl:cert:generate", "Two-character country code (ex.: 'US' or 'CA')" ) country = click.prompt("Country code") if not state: state = click.prompt("State/Province") if not locale: locale = click.prompt("City/Town/Locale") if not email: email = click.prompt("Contact email [optional]") try: cmd = client().certificates.generate job, data = cmd( name, domain, country, state, locale, email, keytype, keylength) handle_job(job) except Exception as e: raise CLIException(str(e))
def revoke(key): """Revoke an API key.""" try: client().apikeys.revoke(key) logger.info('ctl:keys:revoke', 'API key revoked') except Exception as e: raise CLIException(str(e))
def assign(id, type, appid, specialid): """Assign a certificate to an app or website.""" try: client().certificates.assign(id, type, appid, specialid) logger.info('ctl:cert:assign', 'Assigned {0} to {0}'.format(id, appid)) except Exception as e: raise CLIException(str(e))
def _list_backups(bkps): if not bkps: logger.info('ctl:bak:list', 'No backups found') for x in sorted(bkps, key=lambda x: x["time"]): imsg = click.style(" (" + x["type"].capitalize() + ")", fg="yellow") click.echo(click.style(x["pid"], fg="green", bold=True) + imsg) click.echo(click.style(" * Backed up on: ", fg="yellow") + x["time"])
def info(name): """Show information about a particular certificate.""" try: cert = client().certificates.get(name) if not cert: logger.info('ctl:cert:info', 'No certificates found') return click.echo(click.style(cert["id"], fg="white", bold=True)) click.echo( click.style(" * Domain: ", fg="yellow") + cert["domain"] ) click.echo( click.style(" * Type: ", fg="yellow") + "{0}-bit {1}".format(cert["keylength"], cert["keytype"]) ) click.echo( click.style(" * SHA1: ", fg="yellow") + cert["sha1"] ) click.echo( click.style(" * Expires: ", fg="yellow") + cert["expiry"].strftime("%c") ) if cert.assigns: imsg = ", ".join([y["name"] for y in cert["assigns"]]) click.echo(click.style(" * Assigned to: ", fg="yellow") + imsg) except Exception as e: raise CLIException(str(e))
def unassign(id, type, appid, specialid): """Unassign a certificate from an app or website.""" try: client().certificates.unassign(id, type, appid, specialid) logger.info('ctl:cert:unassign', 'Unassigned {0} from {0}'.format(id, appid)) except Exception as e: raise CLIException(str(e))
def assign(id, type, appid, specialid): """Assign a certificate to an app or website.""" try: client().certificates.assign(id, type, appid, specialid) logger.info( 'ctl:cert:assign', 'Assigned {0} to {0}'.format(id, appid) ) except Exception as e: raise CLIException(str(e))
def unassign(id, type, appid, specialid): """Unassign a certificate from an app or website.""" try: client().certificates.unassign(id, type, appid, specialid) logger.info( 'ctl:cert:unassign', 'Unassigned {0} from {0}'.format(id, appid) ) except Exception as e: raise CLIException(str(e))
def _list_backups(bkps): if not bkps: logger.info('ctl:bak:list', 'No backups found') for x in sorted(bkps, key=lambda x: x["time"]): imsg = click.style(" (" + x["type"].capitalize() + ")", fg="yellow") click.echo(click.style(x["pid"], fg="green", bold=True) + imsg) click.echo( click.style(" * Backed up on: ", fg="yellow") + x["time"] )
def add_share(path, expires): """Create a fileshare link.""" try: data = client().files.share(path, expires) logger.success('ctl:links:create', 'Created link') smsg = "Link is your external server address, plus: /shared/{0}" logger.info('ctl:links:create', smsg.format(data["id"])) except Exception as e: raise CLIException(str(e))
def edit(path): """Open a file in your default editor.""" try: data = client().files.get(path, content=True) out = click.edit(data["content"]) if out: client().files.edit(path, out) logger.info('ctl:files:edit', 'File saved to {0}'.format(path)) else: logger.info('ctl:files:edit', 'File not saved') except Exception as e: raise CLIException(str(e))
def _list_applications(apps): if not apps: logger.info('ctl:app:list', 'No apps found') return nlen = len(sorted(apps, key=lambda x: len(x["name"]))[-1]["name"]) vlen = len(sorted(apps, key=lambda x: len(x["version"]))[-1]["version"]) for x in sorted(apps, key=lambda x: x["name"]): click.echo( click.style('{name: <{fill}}'.format(name=x["name"], fill=nlen + 3), fg="white", bold=True) + click.style('{name: <{fill}}'.format(name=x["version"], fill=vlen + 3), fg="green") + " " + x["description"]["short"])
def _list_applications(apps): if not apps: logger.info('ctl:app:list', 'No apps found') return nlen = len(sorted(apps, key=lambda x: len(x["name"]))[-1]["name"]) vlen = len(sorted(apps, key=lambda x: len(x["version"]))[-1]["version"]) for x in sorted(apps, key=lambda x: x["name"]): click.echo( click.style( '{name: <{fill}}'.format(name=x["name"], fill=nlen + 3), fg="white", bold=True) + click.style( '{name: <{fill}}'.format(name=x["version"], fill=vlen + 3), fg="green") + " " + x["description"]["short"] )
def upgrade(yes): """Upgrades all system packages""" try: pkgs = client().packages.get(refresh=False) pkgs = [x["id"] for x in pkgs if x["upgradable"]] if not pkgs: logger.info('ctl:pkg:upgrade', 'System already up-to-date') else: logger.info('ctl:pkg:upgrade', 'The following packages will be upgraded:') click.echo(", ".join(pkgs)) if yes or click.confirm("Are you sure you want to upgrade?"): job = client().packages.install(pkgs) handle_job(job) except Exception as e: raise CLIException(str(e))
def list_dbs(): """List all databases.""" try: dbs = client().databases.get() if not dbs: logger.info('ctl:db:list', 'No databases found') llen = len(sorted(dbs, key=lambda x: len(x["id"]))[-1]["id"]) for x in sorted(dbs, key=lambda x: x["id"]): click.echo( click.style( '{name: <{fill}}'.format(name=x["id"], fill=llen + 3), fg="white", bold=True) + click.style(client().databases.get_types( id=x["database_type"])["name"], fg="yellow")) except Exception as e: raise CLIException(str(e))
def upgrade(yes): """Upgrades all system packages""" try: pkgs = client().packages.get(refresh=False) pkgs = [x["id"] for x in pkgs if x["upgradable"]] if not pkgs: logger.info('ctl:pkg:upgrade', 'System already up-to-date') else: logger.info( 'ctl:pkg:upgrade', 'The following packages will be upgraded:' ) click.echo(", ".join(pkgs)) if yes or click.confirm("Are you sure you want to upgrade?"): job = client().packages.install(pkgs) handle_job(job) except Exception as e: raise CLIException(str(e))
def _list_websites(sites): if not sites: logger.info('ctl:site:list', 'No websites found') for x in sorted(sites, key=lambda x: x["id"]): url = "https://" if x["certificate"] else "http://" url += x["domain"] url += (":{0}".format(x["port"])) if x["port"] not in [80, 443] else "" click.echo(click.style(x["id"], fg="green", bold=True)) click.echo(click.style(" * URL: ", fg="yellow") + url) click.echo(click.style(" * Site Type: ", fg="yellow") + x["app_name"]) click.echo( click.style(" * Uses SSL: ", fg="yellow") + ("Yes" if x["certificate"] else "No")) click.echo( click.style(" * Enabled: ", fg="yellow") + ("Yes" if x["enabled"] else "No")) if x.get("has_update"): click.secho(" * Update available!", fg="green")
def list_certs(): """List all certificates.""" try: certs = client().certificates.get() if not certs: logger.info('ctl:cert:list', 'No certificates found') llen = len(sorted(certs, key=lambda x: len(x["id"]))[-1]["id"]) for x in sorted(certs, key=lambda x: x["id"]): klkt = "{0}-bit {1}".format(x["keylength"], x["keytype"]) click.echo( click.style('{name: <{fill}}'.format(name=x["id"], fill=llen + 3), fg="white", bold=True) + click.style('{name: <15}'.format(name=klkt), fg="green") + click.style(x["domain"], fg="yellow")) except Exception as e: raise CLIException(str(e))
def list_authorities(): """List all certificate authorities (CAs).""" try: certs = client().certificates.get_authorities() if not certs: logger.info('ctl:cert:authorities', 'No certificate authorities found') return llen = len(sorted(certs, key=lambda x: len(x["id"]))[-1]["id"]) for x in sorted(certs, key=lambda x: x["id"]): click.echo( click.style('{name: <{fill}}'.format(name=x["id"], fill=llen + 3), fg="white", bold=True) + "Expires " + click.style(x["expiry"].strftime("%c"), fg="yellow")) except Exception as e: raise CLIException(str(e))
def list_types(): """List all database types and running status.""" try: dbs = client().databases.get_types() if not dbs: logger.info('ctl:db:types', 'No databases found') return llen = len(sorted(dbs, key=lambda x: len(x["name"]))[-1]["name"]) for x in sorted(dbs, key=lambda x: x["id"]): click.echo( click.style('{name: <{fill}}'.format(name=x["name"], fill=llen + 3), fg="white", bold=True) + click.style("Running" if x["state"] else "Stopped", fg="green" if x["state"] else "red")) except Exception as e: raise CLIException(str(e))
def list_dbs(): """List all databases.""" try: dbs = client().databases.get() if not dbs: logger.info('ctl:db:list', 'No databases found') llen = len(sorted(dbs, key=lambda x: len(x["id"]))[-1]["id"]) for x in sorted(dbs, key=lambda x: x["id"]): click.echo( click.style( '{name: <{fill}}'.format(name=x["id"], fill=llen + 3), fg="white", bold=True) + click.style( client().databases.get_types( id=x["database_type"])["name"], fg="yellow") ) except Exception as e: raise CLIException(str(e))
def list_authorities(): """List all certificate authorities (CAs).""" try: certs = client().certificates.get_authorities() if not certs: logger.info( 'ctl:cert:authorities', 'No certificate authorities found' ) return llen = len(sorted(certs, key=lambda x: len(x["id"]))[-1]["id"]) for x in sorted(certs, key=lambda x: x["id"]): click.echo( click.style( '{name: <{fill}}'.format(name=x["id"], fill=llen + 3), fg="white", bold=True) + "Expires " + click.style(x["expiry"].strftime("%c"), fg="yellow") ) except Exception as e: raise CLIException(str(e))
def list_types(): """List all database types and running status.""" try: dbs = client().databases.get_types() if not dbs: logger.info('ctl:db:types', 'No databases found') return llen = len(sorted(dbs, key=lambda x: len(x["name"]))[-1]["name"]) for x in sorted(dbs, key=lambda x: x["id"]): click.echo( click.style( '{name: <{fill}}'.format(name=x["name"], fill=llen + 3), fg="white", bold=True) + click.style( "Running" if x["state"] else "Stopped", fg="green" if x["state"] else "red") ) except Exception as e: raise CLIException(str(e))
def list_keys(): """List all API keys.""" try: keys = client().apikeys.get() if not keys: logger.info('ctl:keys:list', 'No keys found') return llen = len(sorted(keys, key=lambda x: len(x["user"]))[-1].name) for x in keys: click.echo( click.style( '{name: <45}'.format( name=x["key"]), fg="white", bold=True) + click.style('{name: <{fill}}'.format(name=x["user"], fill=llen + 3), fg="green") + " " + click.style(x["comment"], fg="yellow")) except Exception as e: raise CLIException(str(e))
def list_keys(): """List all API keys.""" try: keys = client().apikeys.get() if not keys: logger.info('ctl:keys:list', 'No keys found') return llen = len(sorted(keys, key=lambda x: len(x["user"]))[-1].name) for x in keys: click.echo( click.style( '{name: <45}'.format(name=x["key"]), fg="white", bold=True) + click.style( '{name: <{fill}}'.format(name=x["user"], fill=llen + 3), fg="green") + " " + click.style(x["comment"], fg="yellow") ) except Exception as e: raise CLIException(str(e))
def _list_websites(sites): if not sites: logger.info('ctl:site:list', 'No websites found') for x in sorted(sites, key=lambda x: x["id"]): url = "https://" if x["certificate"] else "http://" url += x["domain"] url += (":{0}".format(x["port"])) if x["port"] not in [80, 443] else "" click.echo(click.style(x["id"], fg="green", bold=True)) click.echo(click.style(" * URL: ", fg="yellow") + url) click.echo(click.style(" * Site Type: ", fg="yellow") + x["app_name"]) click.echo( click.style(" * Uses SSL: ", fg="yellow") + ("Yes" if x["certificate"] else "No") ) click.echo( click.style(" * Enabled: ", fg="yellow") + ("Yes" if x["enabled"] else "No") ) if x.get("has_update"): click.secho(" * Update available!", fg="green")
def list_certs(): """List all certificates.""" try: certs = client().certificates.get() if not certs: logger.info('ctl:cert:list', 'No certificates found') llen = len(sorted(certs, key=lambda x: len(x["id"]))[-1]["id"]) for x in sorted(certs, key=lambda x: x["id"]): klkt = "{0}-bit {1}".format(x["keylength"], x["keytype"]) click.echo( click.style( '{name: <{fill}}'.format(name=x["id"], fill=llen + 3), fg="white", bold=True) + click.style( '{name: <15}'.format(name=klkt), fg="green") + click.style(x["domain"], fg="yellow") ) except Exception as e: raise CLIException(str(e))
def info(name): """Show information about a particular certificate.""" try: cert = client().certificates.get(name) if not cert: logger.info('ctl:cert:info', 'No certificates found') return click.echo(click.style(cert["id"], fg="white", bold=True)) click.echo(click.style(" * Domain: ", fg="yellow") + cert["domain"]) click.echo( click.style(" * Type: ", fg="yellow") + "{0}-bit {1}".format(cert["keylength"], cert["keytype"])) click.echo(click.style(" * SHA1: ", fg="yellow") + cert["sha1"]) click.echo( click.style(" * Expires: ", fg="yellow") + cert["expiry"].strftime("%c")) if cert.assigns: imsg = ", ".join([y["name"] for y in cert["assigns"]]) click.echo(click.style(" * Assigned to: ", fg="yellow") + imsg) except Exception as e: raise CLIException(str(e))
def create(user, comment, save): """Create a new API key.""" try: x = client().apikeys.add(user, comment) key = x["key"] smsg = "Added new API key for {} with comment {}".format(user, comment) logger.success('ctl:keys:create', smsg) logger.info('ctl:keys:create', key) click.echo(click.style("Your new API key is: ", fg="yellow") + key) cmsg = "Do you want to save this key to your .arkosrc?" if save or click.confirm(cmsg): cfg = configparser.SafeConfigParser() rcpath = os.path.join(os.path.expanduser("~"), ".arkosrc") if not os.path.exists(rcpath): with open(rcpath, "w") as f: cfg.add_section("arkosrc") else: cfg.read(rcpath) cfg.set("arkosrc", "apikey", key) with open(rcpath, "w") as f: cfg.write(f) click.secho("API key saved to your .arkosrc config.", bold=True) except Exception as e: raise CLIException(str(e))
def generate(name, domain, country, state, locale, email, keytype, keylength): """Generate an SSL/TLS certificate.""" if not domain: logger.error( "ctl:info:generate", "Choose a fully-qualified domain name of the " "certificate. Must match a domain present on the system") domain = click.prompt("Domain name") if not country: logger.info("ctl:cert:generate", "Two-character country code (ex.: 'US' or 'CA')") country = click.prompt("Country code") if not state: state = click.prompt("State/Province") if not locale: locale = click.prompt("City/Town/Locale") if not email: email = click.prompt("Contact email [optional]") try: cmd = client().certificates.generate job, data = cmd(name, domain, country, state, locale, email, keytype, keylength) handle_job(job) except Exception as e: raise CLIException(str(e))