コード例 #1
0
ファイル: main.py プロジェクト: groboclown/nightjar-mesh
def main(_args: Sequence[str]) -> int:
    """Main program."""
    config = create_configuration()
    if not config.is_valid():
        warning("Configuration is invalid.  Cannot start.")
        return 1
    generator = create_generator(config)
    envoy = create_envoy_handler(config)

    while True:
        if os.path.exists(config.trigger_stop_file):
            warning("Stopping due to existence of stop trigger file.")
            envoy.stop_envoy()
            return 0
        debug('Generating envoy files.')
        res = generator.generate_file(config.envoy_listen_port,
                                      config.envoy_admin_port)
        if os.path.isfile(config.envoy_config_file):
            debug('Starting envoy.')
            envoy.start_if_not_running()
        if res != 0:
            warning("Envoy configuration generator returned {code}", code=res)
            if config.exit_on_generation_failure:
                warning("Stopping due to exit-on-failure.")
                envoy.stop_envoy()
                return res
            time.sleep(config.failure_sleep)
        else:
            time.sleep(config.refresh_time)
コード例 #2
0
def push_template(config: Config) -> int:
    """Push a piece of the template into the templates document."""
    if not config.purpose:
        log.warning(
            'When pushing a template, the `purpose` argument is required.')
        return 3
    if config.filename == '-':
        source_data = sys.stdin.read()
    elif not config.filename or not os.path.isfile(config.filename):
        log.warning('No such local file `{file}`', file=config.filename)
        return 4
    else:
        with open(config.filename, 'r') as f:
            source_data = f.read()
    log.debug("Pulling current templates")
    templates = pull_document(
        config, TEMPLATES_DOCUMENT) or create_initial_templates_document()
    if config.category == 'gateway':
        update_gateway_template(templates, source_data, config.namespace,
                                config.purpose)
    elif config.category == 'service':
        update_service_template(
            templates,
            source_data,
            config.namespace,
            config.service,
            config.color,
            config.purpose,
        )
    else:
        log.warning('Unknown or unset category `{cat}`', cat=config.category)
        return 5
    push_document(config, TEMPLATES_DOCUMENT, templates)
    return 0
コード例 #3
0
 def get_templates(self) -> Dict[str, str]:
     """Get the right templates for this mode (purpose -> template)."""
     log.debug("Fetching templates")
     all_templates = self._data_store.fetch_document('templates')
     default_templates: Dict[str, str] = {}
     namespace_templates: Dict[str, str] = {}
     for gateway_template in all_templates['gateway-templates']:
         namespace = gateway_template['namespace']
         purpose = gateway_template['purpose']
         if namespace == self._config.namespace:
             namespace_templates[purpose] = gateway_template['template']
         elif namespace == TEMPLATE_DEFAULT:
             default_templates[purpose] = gateway_template['template']
     return namespace_templates or default_templates
コード例 #4
0
ファイル: main.py プロジェクト: groboclown/nightjar-mesh
def main(_args: Sequence[str]) -> int:
    """Main program."""
    config = create_configuration()
    generator = create_generator(config)

    while True:
        if os.path.exists(config.trigger_stop_file):
            warning("Stopping due to existence of stop trigger file.")
            return 0
        debug('Generating new discovery map.')
        res = generator.update_discovery_map()
        if res != 0:
            warning("Envoy configuration generator returned {code}", code=res)
            if config.exit_on_generation_failure:
                warning("Stopping due to exit-on-failure.")
                return res
            time.sleep(config.failure_sleep)
        else:
            time.sleep(config.refresh_time)
コード例 #5
0
def generate_envoy_file(config: Config, file_name: str, contents: str) -> None:
    """Performs the correct construction of the envoy file.  To properly support
    envoy dynamic configurations, the file must be created in a temporary file, then
    replaced via a *move* operation.  Due to potential issues around move, the source
    file must be in the same directory as the target file (due to cross-file system
    move issues)."""

    # Note: this is a bit memory heavy, with the contents of source and target present
    # at the same time.

    out_dir = config.envoy_config_dir
    target_file = os.path.join(out_dir, file_name)

    # First, check if the file needs to be updated.  That means the contents are different.
    if os.path.isfile(target_file):
        with open(target_file, 'r') as f:
            current_contents = f.read()
            if current_contents == contents:
                log.debug(
                    "Contents of {file_name} are the same; not updating.",
                    file_name=file_name)
                return

    gen_fd, gen_filename = tempfile.mkstemp(prefix=file_name,
                                            dir=out_dir,
                                            text=False)
    os.write(gen_fd, contents.encode('utf-8', errors='replace'))
    os.close(gen_fd)
    os.replace(gen_filename, target_file)
    log.log('INFO',
            "Generated configuration file {file_name}",
            file_name=file_name)
    log.debug('. . . . . . . . . . . . . . . . . .')
    log.debug_raw(contents)
    log.debug('. . . . . . . . . . . . . . . . . .')
コード例 #6
0
 def generate_file(self, listen_port: int, admin_port: int) -> int:
     """Runs the generation process."""
     try:
         log.debug("Fetching discovery map")
         discovery_map = self._discovery_map.get_mesh()
         mapping = create_gateway_proxy_input(
             discovery_map,
             self._config.namespace,
             listen_port,
             admin_port,
         )
         if isinstance(mapping, int):
             log.warning("Could not create mapping.")
             return mapping
         for purpose, template in self.get_templates().items():
             log.debug("Rendering template {purpose}", purpose=purpose)
             rendered = pystache.render(template, mapping)
             generate_envoy_file(self._config, purpose, rendered)
         return 0
     except (ExtensionPointRuntimeError,
             ExtensionPointTooManyRetries) as err:
         print("[nightjar-standalone] File construction generated error: " +
               repr(err))
         return 1
コード例 #7
0
ファイル: envoy.py プロジェクト: groboclown/nightjar-mesh
 def start_if_not_running(self) -> None:
     """Start envoy if it is not running."""
     if not self.is_alive():
         debug('Starting {cmd}', cmd=self._config.envoy_cmd)
         self._proc = subprocess.Popen(self._cmd_args())