Closes https://git.autonomic.zone/autonomic-cooperative/autonomic/issues/1.master
@ -0,0 +1,71 @@ | |||
"""Initialise the toolbelt.""" | |||
import os | |||
import click | |||
from PyInquirer import prompt | |||
from autonomic import logger | |||
from autonomic.config import add_to_config | |||
from autonomic.infrastructure import get_members | |||
from autonomic.settings import ( | |||
AUTONOMIC_YAML, | |||
CONFIG_PATH, | |||
INFRASTRUCTURE_PATH, | |||
INFRASTRUCTURE_REPOSITORY, | |||
) | |||
from autonomic.system import ensure_installed, run_command | |||
log = logger.get_logger(__name__) | |||
@click.command() | |||
@click.pass_context | |||
def init(ctx): | |||
"""Initialise the toolbelt.""" | |||
create_configuration_directory() | |||
clone_infrastructure_repo() | |||
create_configuration_file() | |||
ask_to_login() | |||
def create_configuration_directory(): | |||
"""Create toolbelt config directory.""" | |||
if not os.path.exists(CONFIG_PATH): | |||
os.mkdir(CONFIG_PATH) | |||
def clone_infrastructure_repo(): | |||
"""Clone the infrastructure repository.""" | |||
if not os.path.exists(INFRASTRUCTURE_PATH): | |||
ensure_installed("git") | |||
run_command( | |||
["git", "clone", INFRASTRUCTURE_REPOSITORY, INFRASTRUCTURE_PATH] | |||
) | |||
else: | |||
os.chdir(INFRASTRUCTURE_PATH) | |||
run_command(["git", "pull", "origin", "master"]) | |||
def ask_to_login(): | |||
"""Log in as your autonomic member username.""" | |||
members = get_members() | |||
choices = [info["username"] for info in members["autonomic_members"]] | |||
question = [ | |||
{ | |||
"type": "list", | |||
"name": "username", | |||
"message": "What is your Autonomic username?", | |||
"choices": choices, | |||
"filter": lambda val: val.lower(), | |||
} | |||
] | |||
answer = prompt(question) | |||
add_to_config(answer) | |||
def create_configuration_file(): | |||
"""Create toolbelt config file.""" | |||
if not os.path.exists(AUTONOMIC_YAML): | |||
with open(AUTONOMIC_YAML, "w") as handle: | |||
handle.write("---") |
@ -0,0 +1,34 @@ | |||
"""Configuration handling module.""" | |||
import os | |||
from autonomic import logger | |||
from autonomic.settings import AUTONOMIC_YAML | |||
from autonomic.system import exit_with_msg | |||
from autonomic.yaml import yaml | |||
log = logger.get_logger(__name__) | |||
def ensure_config(): | |||
"""Ensure the configuration exists.""" | |||
if not os.path.exists(AUTONOMIC_YAML): | |||
msg = "{} is missing, run: autonomic init".format(AUTONOMIC_YAML) | |||
exit_with_msg(msg) | |||
def add_to_config(data): | |||
"""Add values to the autonomic.yml file.""" | |||
ensure_config() | |||
with open(AUTONOMIC_YAML, "r") as handle: | |||
config = yaml.load(handle.read()) | |||
if config is None: | |||
config = {} | |||
for key in data: | |||
config[key] = data[key] | |||
with open(AUTONOMIC_YAML, "w") as handle: | |||
yaml.dump(config, handle) |
@ -0,0 +1,20 @@ | |||
"""Infrastructure handling module.""" | |||
import os | |||
from autonomic.settings import MEMBERS_YAML | |||
from autonomic.system import exit_with_msg | |||
from autonomic.yaml import yaml | |||
def get_members(): | |||
"""Get list of Autonomic members.""" | |||
if not os.path.exists(MEMBERS_YAML): | |||
msg = "{} is missing, run: autonomic init".format(MEMBERS_YAML) | |||
exit_with_msg(msg) | |||
with open(MEMBERS_YAML, "r") as handle: | |||
try: | |||
return yaml.load(handle.read()) | |||
except Exception as exception: | |||
exit_with_msg(str(exception)) |
@ -0,0 +1,142 @@ | |||
"""Logging Module.""" | |||
import logging | |||
import os | |||
import sys | |||
import colorama | |||
def should_do_markup(): | |||
return sys.stdout.isatty() and os.environ.get("TERM") != "dumb" | |||
SUCCESS = 100 | |||
OUT = 101 | |||
class LogFilter(object): | |||
def __init__(self, level): | |||
self.__level = level | |||
def filter(self, logRecord): | |||
return logRecord.levelno <= self.__level | |||
class CustomLogger(logging.getLoggerClass()): | |||
def __init__(self, name, level=logging.NOTSET): | |||
super(logging.getLoggerClass(), self).__init__(name, level) | |||
logging.addLevelName(SUCCESS, "SUCCESS") | |||
logging.addLevelName(OUT, "OUT") | |||
def success(self, msg, *args, **kwargs): | |||
if self.isEnabledFor(SUCCESS): | |||
self._log(SUCCESS, msg, args, **kwargs) | |||
def out(self, msg, *args, **kwargs): | |||
if self.isEnabledFor(OUT): | |||
self._log(OUT, msg, args, **kwargs) | |||
class TrailingNewlineFormatter(logging.Formatter): | |||
def format(self, record): | |||
if record.msg: | |||
record.msg = record.msg.rstrip() | |||
return super(TrailingNewlineFormatter, self).format(record) | |||
def get_logger(name=None): | |||
logging.setLoggerClass(CustomLogger) | |||
logger = logging.getLogger(name) | |||
logger.setLevel(logging.DEBUG) | |||
logger.addHandler(_get_info_handler()) | |||
logger.addHandler(_get_out_handler()) | |||
logger.addHandler(_get_warn_handler()) | |||
logger.addHandler(_get_error_handler()) | |||
logger.addHandler(_get_critical_handler()) | |||
logger.addHandler(_get_success_handler()) | |||
logger.propagate = False | |||
return logger | |||
def _get_info_handler(): | |||
handler = logging.StreamHandler(sys.stdout) | |||
handler.setLevel(logging.INFO) | |||
handler.addFilter(LogFilter(logging.INFO)) | |||
handler.setFormatter( | |||
TrailingNewlineFormatter("--> {}".format(cyan_text("%(message)s"))) | |||
) | |||
return handler | |||
def _get_out_handler(): | |||
handler = logging.StreamHandler(sys.stdout) | |||
handler.setLevel(OUT) | |||
handler.addFilter(LogFilter(OUT)) | |||
handler.setFormatter(TrailingNewlineFormatter(" %(message)s")) | |||
return handler | |||
def _get_warn_handler(): | |||
handler = logging.StreamHandler(sys.stdout) | |||
handler.setLevel(logging.WARN) | |||
handler.addFilter(LogFilter(logging.WARN)) | |||
handler.setFormatter(TrailingNewlineFormatter(yellow_text("%(message)s"))) | |||
return handler | |||
def _get_error_handler(): | |||
handler = logging.StreamHandler(sys.stderr) | |||
handler.setLevel(logging.ERROR) | |||
handler.addFilter(LogFilter(logging.ERROR)) | |||
handler.setFormatter(TrailingNewlineFormatter(red_text("%(message)s"))) | |||
return handler | |||
def _get_critical_handler(): | |||
handler = logging.StreamHandler(sys.stderr) | |||
handler.setLevel(logging.CRITICAL) | |||
handler.addFilter(LogFilter(logging.CRITICAL)) | |||
handler.setFormatter( | |||
TrailingNewlineFormatter(red_text("ERROR: %(message)s")) | |||
) | |||
return handler | |||
def _get_success_handler(): | |||
handler = logging.StreamHandler(sys.stdout) | |||
handler.setLevel(SUCCESS) | |||
handler.addFilter(LogFilter(SUCCESS)) | |||
handler.setFormatter(TrailingNewlineFormatter(green_text("%(message)s"))) | |||
return handler | |||
def red_text(msg): | |||
return color_text(colorama.Fore.RED, msg) | |||
def yellow_text(msg): | |||
return color_text(colorama.Fore.YELLOW, msg) | |||
def green_text(msg): | |||
return color_text(colorama.Fore.GREEN, msg) | |||
def cyan_text(msg): | |||
return color_text(colorama.Fore.CYAN, msg) | |||
def color_text(color, msg): | |||
if should_do_markup(): | |||
return "{}{}{}".format(color, msg, colorama.Style.RESET_ALL) | |||
return msg |
@ -0,0 +1,13 @@ | |||
"""Static settings.""" | |||
import os | |||
USER = os.getlogin() | |||
HOME = "/home/{}".format(USER) | |||
CONFIG_PATH = "{}/.autonomic".format(HOME) | |||
INFRASTRUCTURE_REPOSITORY = ( | |||
"ssh://git@git.autonomic.zone:222/autonomic-cooperative/infrastructure.git" | |||
) | |||
INFRASTRUCTURE_PATH = "{}/infrastructure".format(CONFIG_PATH) | |||
MEMBERS_YAML = "{}/resources/members.yml".format(INFRASTRUCTURE_PATH) | |||
AUTONOMIC_YAML = "{}/autonomic.yml".format(CONFIG_PATH) |
@ -0,0 +1,35 @@ | |||
"""System related functions.""" | |||
import shutil | |||
import subprocess | |||
import sys | |||
from autonomic import logger | |||
log = logger.get_logger(__name__) | |||
def ensure_installed(package): | |||
"""Ensure a system dependency is installed""" | |||
if shutil.which(package) is None: | |||
msg = "{} is not installed?".format(package) | |||
exit_with_msg(msg) | |||
def run_command(command): | |||
"""Run a command.""" | |||
try: | |||
log.info("Running '{}'".format(" ".join(command))) | |||
subprocess.check_output(command) | |||
except subprocess.CalledProcessError as exception: | |||
msg = "{} failed! Saw {}".format(" ".join(command), str(exception)) | |||
exit_with_msg(msg) | |||
def exit(code=1): | |||
sys.exit(code) | |||
def exit_with_msg(msg, code=1): | |||
log.critical(msg) | |||
exit(code) |
@ -0,0 +1,6 @@ | |||
"""YAML initialisation module.""" | |||
from ruamel.yaml import YAML | |||
yaml = YAML() | |||
yaml.explicit_start = True |
@ -0,0 +1,7 @@ | |||
"""YAML initialisation module.""" | |||
from ruamel.yaml import YAML | |||
yaml = YAML() | |||
yaml.explicit_start = True |