Esempio n. 1
0
def main() -> NoReturn:
    arg_parser = argparse.ArgumentParser(
        description=sys.modules[__name__].__doc__)
    arg_parser.add_argument("config_file",
                            type=argparse.FileType("r"),
                            help="path to a configuration file")
    arg_parser.add_argument("--debug",
                            default=False,
                            action="store_true",
                            help="enable debug logging")
    args = arg_parser.parse_args()

    if args.debug:
        level = logging.DEBUG
    else:
        level = logging.INFO
    logging.basicConfig(level=level, format="%(message)s")

    # quiet kazoo's verbose logs a bit
    logging.getLogger("kazoo").setLevel(logging.WARNING)

    parser = configparser.RawConfigParser(
        interpolation=EnvironmentInterpolation())
    parser.read_file(args.config_file)
    watcher_config = dict(parser.items("live-data"))

    cfg = config.parse_config(
        watcher_config,
        {
            "nodes":
            config.DictOf(
                {
                    "source": config.String,
                    "dest": config.String,
                    "owner": config.Optional(config.UnixUser),
                    "group": config.Optional(config.UnixGroup),
                    "mode": config.Optional(config.Integer(base=8),
                                            default=0o400),  # type: ignore
                })
        },
    )
    # pylint: disable=maybe-no-member
    nodes = cfg.nodes.values()

    secrets = secrets_store_from_config(watcher_config, timeout=30)
    zookeeper = zookeeper_client_from_config(secrets,
                                             watcher_config,
                                             read_only=True)
    zookeeper.start()
    try:
        watch_zookeeper_nodes(zookeeper, nodes)
    finally:
        zookeeper.stop()
Esempio n. 2
0
def main() -> None:
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument(
        "config_file", type=argparse.FileType("r"), help="path to a configuration file"
    )
    arg_parser.add_argument(
        "--debug", default=False, action="store_true", help="enable debug logging"
    )
    arg_parser.add_argument(
        "--once",
        default=False,
        action="store_true",
        help="only run the fetcher once rather than as a daemon",
    )
    args = arg_parser.parse_args()

    if args.debug:
        level = logging.DEBUG
    else:
        level = logging.INFO

    logging.basicConfig(format="%(asctime)s:%(levelname)s:%(message)s", level=level)
    parser = configparser.RawConfigParser(interpolation=EnvironmentInterpolation())
    parser.read_file(args.config_file)
    fetcher_config = dict(parser.items("secret-fetcher"))

    cfg = config.parse_config(
        fetcher_config,
        {
            "vault": {
                "url": config.DefaultFromEnv(config.String, "BASEPLATE_DEFAULT_VAULT_URL"),
                "role": config.String,
                "auth_type": config.Optional(
                    config.OneOf(**VaultClientFactory.auth_types()),
                    default=VaultClientFactory.auth_types()["aws"],
                ),
                "mount_point": config.DefaultFromEnv(
                    config.String, "BASEPLATE_VAULT_MOUNT_POINT", fallback="aws-ec2"
                ),
            },
            "output": {
                "path": config.Optional(config.String, default="/var/local/secrets.json"),
                "owner": config.Optional(config.UnixUser, default=0),
                "group": config.Optional(config.UnixGroup, default=0),
                "mode": config.Optional(config.Integer(base=8), default=0o400),  # type: ignore
            },
            "secrets": config.Optional(config.TupleOf(config.String), default=[]),
            "callback": config.Optional(config.String),
        },
    )

    # pylint: disable=maybe-no-member
    client_factory = VaultClientFactory(
        cfg.vault.url, cfg.vault.role, cfg.vault.auth_type, cfg.vault.mount_point
    )

    if args.once:
        logger.info("Running secret fetcher once")
        fetch_secrets(cfg, client_factory)
        trigger_callback(cfg.callback, cfg.output.path)
    else:
        logger.info("Running secret fetcher as a daemon")
        last_proc = None
        while True:
            soonest_expiration = fetch_secrets(cfg, client_factory)
            last_proc = trigger_callback(cfg.callback, cfg.output.path, last_proc)
            time_til_expiration = soonest_expiration - datetime.datetime.utcnow()
            time_to_sleep = time_til_expiration - VAULT_TOKEN_PREFETCH_TIME
            time.sleep(max(int(time_to_sleep.total_seconds()), 1))
Esempio n. 3
0
 def test_non_decimal(self):
     result = config.Integer(base=8)("0600")
     self.assertEqual(result, 384)
Esempio n. 4
0
 def test_parse_integer_actually_float(self):
     with self.assertRaises(ValueError):
         config.Integer("1.2")
Esempio n. 5
0
 def test_parse_integer_invalid(self):
     with self.assertRaises(ValueError):
         config.Integer("")
     with self.assertRaises(ValueError):
         config.Integer("illegal")
Esempio n. 6
0
 def test_parse_integer_valid(self):
     result = config.Integer("337")
     self.assertEqual(result, 337)