コード例 #1
0
    def __init__(self, provider, args, render_args, log):
        self.args = args
        self.log = log

        if 'render' in self.args:

            num_warnings = 0

            for src_dir in self.args.src_dirs:

                src_dir = os.path.realpath(src_dir)
                name = self.args.deployment_name or os.path.basename(src_dir)
                build_dir = Path(self.args.build_dir).joinpath(self.args.provider)

                if not os.path.isdir(src_dir):
                    self.log.warning(colors.orange(f'"{src_dir}" is not a directory, skip'))
                    num_warnings += 1
                    continue

                try:
                    renderer = provider.renderer(
                        name=name,
                        src_dir=src_dir,
                        build_dir=build_dir,
                        namespaces_dir=self.args.namespaces_dir,
                        defaults_path=self.args.defaults_path,
                        args=self.args,
                        log=self.log,
                        **vars(provider.renderer.get_parser().parse_args(render_args)))

                    self.log.info(
                        colors.green_bold('Rendering ') + colors.bold(src_dir) + ' in ' +
                        colors.bold(self.args.build_dir) + ' using the provider ' +
                        colors.bold(self.args.provider)
                    )

                    renderer.run()

                    # Clean and store secret info in build dir.
                    # Note that this affects only secrets that have been registered in the previous
                    # rendering. Secrets from deployments excluded by user filters are not stored and existing secrets
                    # won't be removed. So any testing/deployment should also explicitly respect the user filters to
                    # exclude secrets as well.
                    Secret.clean_build_secrets(build_dir)
                    for secret in Secret.get_registered():
                        secret.store(build_dir)

                except RenderError as e:
                    self.log.error(colors.red(f'Render error in source directory "{src_dir}":'))
                    self.log.error(colors.red_bold(str(e)))
                    sys.exit(1)

            if num_warnings > 0:
                self.log.warning(colors.orange(f'Rendering finished with {num_warnings} warnings'))
            else:
                self.log.info(colors.green_bold(f'Rendering finished'))

            sys.exit(0)
コード例 #2
0
ファイル: logging.py プロジェクト: awesome-it/adeploy
def get_log_format(args, loglevel):

    if args.logfile:
        return '%(asctime)s %(levelname)-8s %(name)s %(message)s'

    if loglevel == logging.DEBUG:
        return '%(levelname)-8s ' + colors.bold('%(name)s') + ' %(message)s'

    return colors.bold('%(name)s') + ' %(message)s'
コード例 #3
0
ファイル: deploy.py プロジェクト: awesome-it/adeploy
    def __init__(self, provider, args, deploy_args, log):
        self.args = args
        self.log = log

        if 'deploy' in self.args:

            num_warnings = 0

            for src_dir in self.args.src_dirs:

                src_dir = os.path.realpath(src_dir)
                name = self.args.deployment_name or os.path.basename(src_dir)
                build_dir = Path(self.args.build_dir).joinpath(self.args.provider)

                if not os.path.isdir(src_dir):
                    self.log.warning(colors.orange(f'"{src_dir}" is not a directory, skip'))
                    num_warnings += 1
                    continue

                try:
                    deployer = provider.deployer(
                        name=name,
                        src_dir=src_dir,
                        build_dir=build_dir,
                        namespaces_dir=self.args.namespaces_dir,
                        defaults_path=self.args.defaults_path,
                        args=self.args,
                        log=self.log,
                        **vars(provider.deployer.get_parser().parse_args(deploy_args)))

                    self.log.info(
                        colors.green_bold('Deploying ') + colors.bold(src_dir) + ' in ' +
                        colors.bold(self.args.build_dir) + ' using the provider ' +
                        colors.bold(self.args.provider)
                    )

                    # Create secrets
                    secrets = [] # Respect user filters
                    for secret in Secret.get_stored(build_dir, name):

                        deployment = secret.deployment
                        if deployment.skipped(self.args):
                            self.log.info(f'... Secret "{colors.blue(secret.name)}" for '
                                          f'deployment "{colors.blue(deployment)}" skipped by user filter.')
                            continue

                        secrets.append(secret)
                        secret.deploy(self.log, self.args.recreate_secrets)

                    # Remove unused secrets
                    Secret.clean_all(secrets, self.log, dry_run=False)

                    # Do the deployments
                    deployer.run()

                except DeployError as e:
                    self.log.error(colors.red(f'Deployment failed in source directory "{src_dir}":'))
                    self.log.error(colors.red_bold(str(e)))
                    sys.exit(1)

            if num_warnings > 0:
                self.log.warning(colors.orange(f'Deployment finished with {num_warnings} warnings'))
            else:
                self.log.info(colors.green_bold(f'Deployment finished'))

            sys.exit(0)
コード例 #4
0
def setup_parser():
    parser = argparse.ArgumentParser(description='An awesome universal deployment tool for k8s',
                                     usage=colors.bold(
                                         f'adeploy -p {colors.blue("provider")} {colors.gray("[optional args ...]")} '
                                         f'{colors.blue("build-step")} {colors.gray("[optional build args ...]")} '
                                         f'{colors.blue("src_dir")} [{colors.blue("src_dir")} ...]'))

    parser.add_argument('-l', '--log', dest='logfile', help='Path to logfile')

    parser.add_argument('-d', '--debug', action='store_true')

    parser.add_argument('-s', '--skip-colors', dest='skip_colors', action='store_true')

    parser.add_argument('-p', '--provider', dest='provider',
                        help='The provider to use, type --providers to get a list of supported providers.',
                        required='--providers' not in sys.argv and '--version' not in sys.argv)

    parser.add_argument('--providers', dest='list_providers', action='store_true',
                        help='A list of supported providers')

    parser.add_argument('-n', '--name', dest="deployment_name", default=None,
                        help='Specify a deployment name. This will overwrite deployment name derived from repo dir')

    parser.add_argument('--adeploy-dir', dest='adeploy_dir',
                        help='Configuration directory for adeploy', default=Path.home().joinpath('.adeploy'),
                        metavar='adeploy_dir', type=Path)

    parser.add_argument('--build-dir', dest='build_dir',
                        help='Build directory for output', default='./build', metavar='build_dir')

    parser.add_argument('--defaults', dest='defaults_path', default='defaults.yml',
                        help='YML file or directory containing <deployment_name>.yml with default variables. '
                             'Relative to source dirs.')

    parser.add_argument('--namespaces', dest='namespaces_dir', default='namespaces',
                        help='Directory containing namespaces and variables for deployments')

    parser.add_argument('--recreate-secrets', dest='recreate_secrets', action='store_true',
                        help='Force to re-create secrets. This might invoke a password store to retrieve secrets.')

    parser.add_argument('--filter-namespace', dest='filters_namespace', nargs='+', action='append',
                        help='Only include specified namespace. Argument can be specified multiple times.')

    parser.add_argument('--filter-release', dest='filters_release', nargs='+', action='append',
                        help='Only include specified deployment release i.e. "prod", "testing". '
                             'Argument can be specified multiple times.')

    parser.add_argument('--show-configs', dest='show_configs', action='store_true', default=False,
                        help='Print out rendered namespace configurations and quit.')

    parser.add_argument('--gopass-repo', dest='gopass_repo', nargs='+', action='append',
                        help='Gopass repo names, where the awesome secrets are stored. This argument can be specified '
                             'multiple times for multiple Gpoass repos. This params can also be specified by the env '
                             'var ADEPLOY_GOPASS_REPOS where comma separated list of Gopass repo names is expected. '
                             'If args are specified, these take precedence and the env var is ignored.')

    parser.add_argument('--version', action='store_true', help='Print version and exit')

    subparsers = parser.add_subparsers(title=f'Available build steps', metavar=colors.bold('build-steps'))

    for (module, class_name) in get_submodules(steps):
        module_name = module.__name__
        subparser = subparsers.add_parser(module_name,
                                          help=f'Call module "{module_name}", '
                                               f'type: {sys.argv[0]} {module_name} --help for more options')
        subparser.add_argument("src_dirs",
                               help="Directory containing deployment sources",
                               nargs='*', default='.', metavar='src_dir')

        if module_name == 'config':
            subparser.add_argument("-o,--out", dest='config_out', default="",
                                   help="Filename to store the rendered namespace configurations as JSON.")

        subparser.add_argument(f'--{module_name}', default=True, help=argparse.SUPPRESS)

    return parser