Esempio n. 1
0
def test_get_paasta_native_services_running_here_for_nerve():
    cluster = 'edelweiss'
    soa_dir = 'the_sound_of_music'
    fake_marathon_services = [
        ('no_test', 'left_behind', 1111),
        ('no_docstrings', 'forever_abandoned', 2222),
    ]
    registrations = [
        ['no_docstrings.dos'],
        ['no_test.uno'],
    ]
    nerve_dicts = [
        long_running_service_tools.ServiceNamespaceConfig({
            'binary': 1,
            'proxy_port': 6666
        }),
        long_running_service_tools.ServiceNamespaceConfig({
            'clock': 0,
            'proxy_port': 6666
        }),
    ]
    expected = [
        ('no_test.uno', {
            'clock': 0,
            'port': 1111,
            'proxy_port': 6666
        }),
        ('no_docstrings.dos', {
            'binary': 1,
            'port': 2222,
            'proxy_port': 6666
        }),
    ]
    with mock.patch(
            'paasta_tools.native_mesos_scheduler.paasta_native_services_running_here',
            autospec=True,
            return_value=fake_marathon_services,
    ) as pnsrh_patch, mock.patch(
            'paasta_tools.native_mesos_scheduler.read_all_registrations_for_service_instance',
            autospec=True,
            side_effect=lambda *args, **kwargs: registrations.pop(),
    ) as get_namespace_patch, mock.patch(
            'paasta_tools.native_mesos_scheduler.load_service_namespace_config',
            autospec=True,
            side_effect=lambda *args, **kwargs: nerve_dicts.pop(),
    ) as read_ns_config_patch:
        actual = native_mesos_scheduler.get_paasta_native_services_running_here_for_nerve(
            cluster, soa_dir)
        assert expected == actual
        pnsrh_patch.assert_called_once_with(hostname=None)
        get_namespace_patch.assert_any_call('no_test', 'left_behind', cluster,
                                            soa_dir)
        get_namespace_patch.assert_any_call('no_docstrings',
                                            'forever_abandoned', cluster,
                                            soa_dir)
        assert get_namespace_patch.call_count == 2
        read_ns_config_patch.assert_any_call('no_test', 'uno', soa_dir)
        read_ns_config_patch.assert_any_call('no_docstrings', 'dos', soa_dir)
        assert read_ns_config_patch.call_count == 2
Esempio n. 2
0
def test_get_paasta_native_services_running_here_for_nerve_when_not_in_smartstack():
    cluster = "edelweiss"
    soa_dir = "the_sound_of_music"
    fake_marathon_services = [
        ("no_test", "left_behind", 1111),
        ("no_docstrings", "forever_abandoned", 2222),
    ]
    registrations = [["no_docstrings.dos"], ["no_test.uno"]]
    nerve_dicts = [
        long_running_service_tools.ServiceNamespaceConfig({"binary": 1}),
        long_running_service_tools.ServiceNamespaceConfig(
            {"clock": 0, "proxy_port": 6666}
        ),
    ]
    expected = [("no_test.uno", {"clock": 0, "port": 1111, "proxy_port": 6666})]
    with mock.patch(
        "paasta_tools.native_mesos_scheduler.paasta_native_services_running_here",
        autospec=True,
        return_value=fake_marathon_services,
    ) as pnsrh_patch, mock.patch(
        "paasta_tools.native_mesos_scheduler.load_paasta_native_job_config",
        autospec=True,
    ) as mock_load_paasta_native_job_config, mock.patch(
        "paasta_tools.native_mesos_scheduler.load_service_namespace_config",
        autospec=True,
        side_effect=lambda *args, **kwargs: nerve_dicts.pop(),
    ) as read_ns_config_patch:

        def mock_registrations_side_effect(*args, **kwargs):
            return registrations.pop()

        mock_load_paasta_native_job_config.return_value.get_registrations.side_effect = (
            mock_registrations_side_effect
        )
        actual = (
            native_mesos_scheduler.get_paasta_native_services_running_here_for_nerve(
                cluster, soa_dir
            )
        )
        assert expected == actual
        pnsrh_patch.assert_called_once_with(hostname=None)
        mock_load_paasta_native_job_config.assert_any_call(
            service="no_test",
            instance="left_behind",
            cluster=cluster,
            load_deployments=False,
            soa_dir=soa_dir,
        )
        mock_load_paasta_native_job_config.assert_any_call(
            service="no_docstrings",
            instance="forever_abandoned",
            cluster=cluster,
            load_deployments=False,
            soa_dir=soa_dir,
        )
        assert mock_load_paasta_native_job_config.call_count == 2
        read_ns_config_patch.assert_any_call("no_test", "uno", soa_dir)
        read_ns_config_patch.assert_any_call("no_docstrings", "dos", soa_dir)
        assert read_ns_config_patch.call_count == 2
Esempio n. 3
0
def test_get_paasta_native_services_running_here_for_nerve_when_get_cluster_raises_other_exception(
):
    cluster = None
    soa_dir = 'the_sound_of_music'
    with mock.patch(
            'paasta_tools.native_mesos_scheduler.load_system_paasta_config',
            autospec=True,
    ) as load_system_paasta_config_patch, mock.patch(
            'paasta_tools.native_mesos_scheduler.paasta_native_services_running_here',
            autospec=True,
            return_value=[],
    ):
        load_system_paasta_config_patch.return_value.get_cluster = mock.Mock(
            side_effect=Exception)
        with pytest.raises(Exception):
            native_mesos_scheduler.get_paasta_native_services_running_here_for_nerve(
                cluster, soa_dir)
Esempio n. 4
0
def test_get_paasta_native_services_running_here_for_nerve_when_paasta_not_configured(
):
    cluster = None
    soa_dir = 'the_sound_of_music'
    with mock.patch(
            'paasta_tools.native_mesos_scheduler.load_system_paasta_config',
            autospec=True,
    ) as load_system_paasta_config_patch, mock.patch(
            'paasta_tools.native_mesos_scheduler.paasta_native_services_running_here',
            autospec=True,
            return_value=[],
    ):
        load_system_paasta_config_patch.return_value \
            = mock.Mock(side_effect=native_mesos_scheduler.PaastaNotConfiguredError)
        actual = native_mesos_scheduler.get_paasta_native_services_running_here_for_nerve(
            cluster, soa_dir)
        assert actual == []
def test_get_paasta_native_services_running_here_for_nerve_when_get_cluster_raises_custom_exception():
    cluster = None
    soa_dir = "the_sound_of_music"
    with mock.patch(
        "paasta_tools.native_mesos_scheduler.load_system_paasta_config", autospec=True
    ) as load_system_paasta_config_patch, mock.patch(
        "paasta_tools.native_mesos_scheduler.paasta_native_services_running_here",
        autospec=True,
        return_value=[],
    ):
        load_system_paasta_config_patch.return_value = mock.Mock(
            side_effect=native_mesos_scheduler.PaastaNotConfiguredError
        )
        actual = native_mesos_scheduler.get_paasta_native_services_running_here_for_nerve(
            cluster, soa_dir
        )
        assert actual == []
Esempio n. 6
0
def main() -> None:
    opts = parse_args(sys.argv[1:])
    new_config = generate_configuration(
        paasta_services=(
            get_marathon_services_running_here_for_nerve(  # type: ignore
                cluster=None,
                soa_dir=DEFAULT_SOA_DIR,
            ) + get_paasta_native_services_running_here_for_nerve(
                cluster=None,
                soa_dir=DEFAULT_SOA_DIR,
            ) + get_kubernetes_services_running_here_for_nerve(
                cluster=None,
                soa_dir=DEFAULT_SOA_DIR,
            )),
        puppet_services=get_puppet_services_running_here_for_nerve(
            soa_dir=DEFAULT_SOA_DIR, ),
        heartbeat_path=opts.heartbeat_path,
        hacheck_port=opts.hacheck_port,
        weight=opts.weight,
        zk_topology_dir=opts.zk_topology_dir,
        zk_location_type=opts.zk_location_type,
        zk_cluster_type=opts.zk_cluster_type,
        labels_dir=opts.labels_dir,
        envoy_listeners=get_envoy_listeners(opts.envoy_admin_port),
    )

    # Must use os.rename on files in the same filesystem to ensure that
    # config is swapped atomically, so we need to create the temp file in
    # the same directory as the config file
    new_config_path = '{0}.tmp'.format(opts.nerve_config_path)

    with open(new_config_path, 'w') as fp:
        json.dump(new_config,
                  fp,
                  sort_keys=True,
                  indent=4,
                  separators=(',', ': '))

    # Match the permissions that puppet expects
    os.chmod(new_config_path, 0o644)

    # Restart/reload nerve if the config files differ
    # Always force a restart if the heartbeat file is old
    should_reload = not filecmp.cmp(new_config_path, opts.nerve_config_path)
    should_restart = file_not_modified_since(opts.heartbeat_path,
                                             opts.heartbeat_threshold)

    # Always swap new config file into place, even if we're not going to
    # restart nerve. Our monitoring system checks the opts.nerve_config_path
    # file age to ensure that this script is functioning correctly.
    try:
        # Verify the new config is _valid_
        command = [opts.nerve_executable_path]
        command.extend(['-c', new_config_path, '-k'])
        subprocess.check_call(command)

        # Move the config over
        shutil.move(new_config_path, opts.nerve_config_path)
    except subprocess.CalledProcessError:
        # Nerve config is invalid!, bail out **without restarting**
        # so staleness monitoring can trigger and alert us of a problem
        return

    # If we can reload with SIGHUP, use that, otherwise use the normal
    # graceful method
    if should_reload and opts.reload_with_sighup:
        try:
            with open(opts.nerve_pid_path) as f:
                pid = int(f.read().strip())
            os.kill(pid, signal.SIGHUP)
        except (OSError, ValueError, IOError):
            # invalid pid file, time to restart
            should_restart = True
        else:
            # Always try to stop the backup process
            subprocess.call(opts.nerve_backup_command + ['stop'])
    else:
        should_restart |= should_reload

    if should_restart:
        # Try to do a graceful restart by starting up the backup nerve
        # prior to restarting the main nerve. Then once the main nerve
        # is restarted, stop the backup nerve.
        try:
            subprocess.call(opts.nerve_backup_command + ['start'])
            time.sleep(opts.nerve_registration_delay_s)

            subprocess.check_call(opts.nerve_command + ['stop'])
            subprocess.check_call(opts.nerve_command + ['start'])
            time.sleep(opts.nerve_registration_delay_s)
        finally:
            # Always try to stop the backup process
            subprocess.call(opts.nerve_backup_command + ['stop'])
Esempio n. 7
0
def test_get_paasta_native_services_running_here_for_nerve_multiple_namespaces(
):
    cluster = 'edelweiss'
    soa_dir = 'the_sound_of_music'
    fake_marathon_services = [
        ('no_test', 'left_behind', 1111),
        ('no_docstrings', 'forever_abandoned', 2222),
    ]
    namespaces = [
        ['no_docstrings.quatro'],
        ['no_test.uno', 'no_test.dos', 'no_test.tres'],
    ]
    nerve_dicts = {
        ('no_test', 'uno'):
        long_running_service_tools.ServiceNamespaceConfig({'proxy_port':
                                                           6666}),
        ('no_test', 'dos'):
        long_running_service_tools.ServiceNamespaceConfig({'proxy_port':
                                                           6667}),
        ('no_test', 'tres'):
        long_running_service_tools.ServiceNamespaceConfig({'proxy_port':
                                                           6668}),
        ('no_docstrings', 'quatro'):
        long_running_service_tools.ServiceNamespaceConfig({'proxy_port':
                                                           6669}),
    }
    expected = [
        ('no_test.uno', {
            'port': 1111,
            'proxy_port': 6666
        }),
        ('no_test.dos', {
            'port': 1111,
            'proxy_port': 6667
        }),
        ('no_test.tres', {
            'port': 1111,
            'proxy_port': 6668
        }),
        ('no_docstrings.quatro', {
            'port': 2222,
            'proxy_port': 6669
        }),
    ]
    with mock.patch(
            'paasta_tools.native_mesos_scheduler.paasta_native_services_running_here',
            autospec=True,
            return_value=fake_marathon_services,
    ) as pnsrh_patch, mock.patch(
            'paasta_tools.native_mesos_scheduler.load_paasta_native_job_config',
            autospec=True,
    ) as mock_load_paasta_native_job_config, mock.patch(
            'paasta_tools.native_mesos_scheduler.load_service_namespace_config',
            autospec=True,
            side_effect=lambda service, namespace, soa_dir: nerve_dicts.pop(
                (service, namespace)),
    ) as read_ns_config_patch:

        def mock_registrations_side_effect(*args, **kwargs):
            return namespaces.pop()

        mock_load_paasta_native_job_config.return_value.get_registrations.side_effect = mock_registrations_side_effect
        actual = native_mesos_scheduler.get_paasta_native_services_running_here_for_nerve(
            cluster, soa_dir)
        assert expected == actual
        pnsrh_patch.assert_called_once_with(hostname=None)
        mock_load_paasta_native_job_config.assert_any_call(
            service='no_test',
            instance='left_behind',
            cluster=cluster,
            load_deployments=False,
            soa_dir=soa_dir,
        )
        mock_load_paasta_native_job_config.assert_any_call(
            service='no_docstrings',
            instance='forever_abandoned',
            cluster=cluster,
            load_deployments=False,
            soa_dir=soa_dir,
        )
        assert mock_load_paasta_native_job_config.call_count == 2
        read_ns_config_patch.assert_any_call('no_test', 'uno', soa_dir)
        read_ns_config_patch.assert_any_call('no_test', 'dos', soa_dir)
        read_ns_config_patch.assert_any_call('no_test', 'tres', soa_dir)
        read_ns_config_patch.assert_any_call('no_docstrings', 'quatro',
                                             soa_dir)
        assert read_ns_config_patch.call_count == 4