예제 #1
0
def test_render_json_template_require_float_requires_float(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"muffin_count": {{ MUFFIN_COUNT|require_float }}}',
    )

    with pytest.raises(FloatRequired):
        render_json_template(template_path, template_name, **{"MUFFIN_COUNT": "one muffin"})
예제 #2
0
def test_render_json_template_missing_value_raises(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"type_of_muffin": "{{ MUFFIN_TYPE }}"}',
    )

    with pytest.raises(UndefinedError):
        render_json_template(template_path, template_name, **{})
예제 #3
0
def test_render_json_template_require_float_max_constraint_raises(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"muffin_count": {{ MUFFIN_COUNT|require_float(max=50) }}}',
    )

    with pytest.raises(FloatTooLarge):
        render_json_template(template_path, template_name, **{"MUFFIN_COUNT": "60"})
예제 #4
0
def test_render_json_template_invalid_json_missing_value(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"type_of_muffin": {{ MUFFIN_TYPE }}}',
    )

    with pytest.raises(InvalidJSONError):
        render_json_template(template_path, template_name, **{"MUFFIN_TYPE": ""})
예제 #5
0
def test_render_json_template_require_int_min_constraint_raises(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"muffin_count": {{ MUFFIN_COUNT|require_int(min=50) }}}',
    )

    with pytest.raises(IntegerTooSmall):
        render_json_template(template_path, template_name, **{"MUFFIN_COUNT": "40"})
예제 #6
0
def test_render_json_template_with_inheritance_no_parent(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '''
        {% extends "bases/base.json" %}
        {% block MUFFIN_TYPE_PLACEHOLDER %}{{ ALT_MUFFIN_TYPE }}{% endblock %}
        ''',
    )

    with pytest.raises(MissingTemplateError):
        render_json_template(template_path, template_name, **{})
예제 #7
0
def deploy(marathon_client, marathon_lb_client, deployment_strategy, timeout,
           env_prefix, template_path, template_names, force, env_pairs, **kw):
    """Deploy one or more applications to Marathon.
    """
    # select the appropriate deployment strategy
    strategy = STRATEGIES[deployment_strategy]

    # use the default template if none was specified
    if not template_names:
        template_names = [strategy["default_template"]]

    # read and render deploy template using values from the environment
    values = load_values_from_environment(prefix=env_prefix, overrides=env_pairs)
    rendered_templates = []
    for template_name in template_names:
        rendered_templates.append(render_json_template(template_path, template_name, **values))

    # perform some extra pre-flight validation if required, and execute the
    # deployment, blocking until complete.
    deployment_params = {"marathon_client": marathon_client,
                         "marathon_lb_client": marathon_lb_client,
                         "timeout": timeout,
                         "app_definitions": rendered_templates}
    strategy["validator"](**deployment_params)
    strategy["executor"](**deployment_params).execute(force)
예제 #8
0
def test_render_json_template_require_int(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"muffin_count": {{ MUFFIN_COUNT|require_int }}}',
    )

    rendered_template = render_json_template(template_path, template_name, **{"MUFFIN_COUNT": "1"})
    assert rendered_template['muffin_count'] == 1
예제 #9
0
def test_render_json_template_require_float_max_constraint(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"muffin_count": {{ MUFFIN_COUNT|require_float(max=50) }}}',
    )

    rendered_template = render_json_template(template_path, template_name, **{"MUFFIN_COUNT": "-60"})
    assert rendered_template['muffin_count'] == -60
예제 #10
0
def test_render_json_template_valid(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '{"type_of_muffin": "{{ MUFFIN_TYPE }}"}',
    )

    rendered_template = render_json_template(template_path, template_name, **{"MUFFIN_TYPE": "banana"})
    assert "type_of_muffin" in rendered_template
    assert rendered_template["type_of_muffin"] == "banana"
예제 #11
0
파일: cmd_cron.py 프로젝트: shopkeep/shpkpr
def set(chronos_client, template_path, template_names, env_prefix, env_pairs):
    """Add or Update a job in chronos.
    """
    values = load_values_from_environment(prefix=env_prefix, overrides=env_pairs)
    current_jobs = chronos_client.list()

    for template_name in template_names:
        rendered_template = render_json_template(template_path, template_name, **values)
        if _find_job(current_jobs, rendered_template['name']):
            chronos_client.update(rendered_template)
        else:
            chronos_client.add(rendered_template)
예제 #12
0
def cli(logger, marathon_client, env_prefix, template_path, template_names, dry_run, force, env_pairs):
    """Deploy application from template.
    """
    # set dry_run param if the user has requested it. This happens in the
    # command callback as it only applies to the deploy command and doesn't make
    # sense anywhere else.
    marathon_client.dry_run = dry_run
    # read and render deploy template using values from the environment
    values = load_values_from_environment(prefix=env_prefix, overrides=env_pairs)
    rendered_templates = []
    for template_name in template_names:
        rendered_templates.append(render_json_template(template_path, template_name, **values))

    marathon_client.deploy(rendered_templates, force=force).wait()
예제 #13
0
def set(chronos_client, vault_client, template_path, template_names, env_prefix, env_pairs, **kw):
    """Add or Update a job in chronos.
    """
    # use the default template if none was specified
    if not template_names:
        template_names = ["chronos/default/job.json.tmpl"]

    values = load_values_from_environment(prefix=env_prefix, overrides=env_pairs)
    current_jobs = chronos_client.list()

    for template_name in template_names:
        rendered_template = render_json_template(template_path, template_name, **values)
        resolved_secrets = resolve_secrets(vault_client, rendered_template)
        rendered_template = _inject_secrets(rendered_template, resolved_secrets)
        if _find_job(current_jobs, rendered_template['name']):
            chronos_client.update(rendered_template)
        else:
            chronos_client.add(rendered_template)
예제 #14
0
def test_render_json_template_with_inheritance_valid(tmpdir):
    _write_template_to_disk(
        tmpdir.mkdir('bases'), 'base.json',
        '{"type_of_muffin": "{% block MUFFIN_TYPE_PLACEHOLDER %}{{ MUFFIN_TYPE }}{% endblock %}"}',
    )
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '''
        {% extends "bases/base.json" %}
        {% block MUFFIN_TYPE_PLACEHOLDER %}{{ ALT_MUFFIN_TYPE }}{% endblock %}
        ''',
    )

    rendered_template = render_json_template(template_path, template_name, **{
        "MUFFIN_TYPE": "banana",
        "ALT_MUFFIN_TYPE": "blueberry",
    })
    assert "type_of_muffin" in rendered_template
    assert rendered_template["type_of_muffin"] == "blueberry"
예제 #15
0
def run(env_prefix, template_path, template_names, vault_client, command, env_pairs, **kw):
    """Run a one-off task in a "production-like" environment.

    Uses the current deployment configuration to start up a container locally
    and run a single command. Environment variables and secrets are extracted
    from the current deployment configuration and injected into the container
    when starting up.
    """
    # use the default template if none was specified. We can just use the
    # standard template here since all we care about are environment variables
    # and secrets.
    if not template_names:
        template_name = STRATEGIES["standard"]["default_template"]
    else:
        template_name = template_names[0]

    # read and render deploy template using values from the environment
    values = load_values_from_environment(prefix=env_prefix, overrides=env_pairs)
    rendered_template = render_json_template(template_path, template_name, **values)

    # extract required configuration from the rendered template
    app_id = rendered_template["id"]
    docker_image = rendered_template["container"]["docker"]["image"]
    environment_variables = rendered_template["env"]
    environment_variables.update(resolve_secrets(vault_client, rendered_template))

    logger.info("Running command for app ({0}): {1}\n".format(app_id, command))

    docker_client = docker.from_env()
    container = docker_client.containers.run(docker_image,
                                             command,
                                             detach=True,
                                             auto_remove=True,
                                             environment=environment_variables)

    # stream logs from the running container to stdout
    for line in container.logs(stream=True):
        logger.info(line.decode('utf-8').rstrip())

    # exit with the container's exit code once it finishes
    sys.exit(container.wait()['StatusCode'])
예제 #16
0
def cli(logger, marathon_client, marathon_lb_url, initial_instances, max_wait,
        step_interval, force, env_prefix, template_path, template_names, env_pairs):
    """Perform a blue/green deploy
    """
    values = load_values_from_environment(prefix=env_prefix, overrides=env_pairs)

    rendered_templates = []
    for template_name in template_names:
        rendered_templates.append(render_json_template(template_path, template_name, **values))

    for app in rendered_templates:
        validate_app(app)

        # fetch all previous deploys from marathon and abort if there is more
        # than one stack currently active.
        previous_deploys = fetch_previous_deploys(marathon_client, app)
        if len(previous_deploys) > 1:
            raise DualStackAlreadyExists("Both blue and green apps detected")
        # transform the app to be deployed to apply the correct labels and
        # ID-change that will allow marathon-lb to cut traffic over as necessary.
        new_app = prepare_deploy(previous_deploys, app, initial_instances)

        logger.log('Final App Definition:')
        logger.log(json.dumps(new_app, indent=4, sort_keys=True))
        if force or click.confirm("Continue with deployment?"):
            try:
                deploy_and_swap(marathon_client,
                                new_app,
                                previous_deploys,
                                logger,
                                force,
                                max_wait,
                                step_interval,
                                initial_instances,
                                marathon_lb_url)
            except (DeploymentFailed, SwapApplicationTimeout):
                remove_new_stack(marathon_client, logger, app['id'], force)
예제 #17
0
def test_render_json_template_all_env(tmpdir):
    template_path, template_name = _write_template_to_disk(
        tmpdir, 'template.json',
        '''
        {
            "types_of_muffin": {
                {% for k, v in _all_env|filter_items("MUFFIN_", True) %}
                "{{ k.lower() }}": {{ v }}{% if loop.last == False %},{% endif %}
                {% endfor %}
            }
        }
        ''',
    )

    rendered_template = render_json_template(template_path, template_name, **{
        "MUFFIN_BLUEBERRY": 4,
        "MUFFIN_BANANA": 7,
        "MUFFIN_CHOCOLATE": 12,
        "DONUT_STRAWBERRY": 9,
    })
    assert "types_of_muffin" in rendered_template
    assert rendered_template["types_of_muffin"]["blueberry"] == 4
    assert rendered_template["types_of_muffin"]["banana"] == 7
    assert rendered_template["types_of_muffin"]["chocolate"] == 12