Beispiel #1
0
def test_brutal_bounce():
    # mock the new client used to brutal bounce in the background using threading.
    mock_cloned_client = mock.MagicMock()

    with mock.patch(
            "paasta_tools.kubernetes.application.controller_wrappers.KubeClient",
            return_value=mock_cloned_client,
            autospec=True,
    ):
        with mock.patch(
                "paasta_tools.kubernetes.application.controller_wrappers.threading.Thread",
                autospec=True,
        ) as mock_deep_delete_and_create:
            mock_client = mock.MagicMock()

            app = mock.MagicMock()
            app.item.metadata.name = "fake_name"
            app.item.metadata.namespace = "faasta"

            # we do NOT call deep_delete_and_create
            app = setup_app({}, True)
            DeploymentWrapper.update(self=app, kube_client=mock_client)

            assert mock_deep_delete_and_create.call_count == 0

            # we call deep_delete_and_create: when bounce_method is brutal
            config_dict = {"instances": 1, "bounce_method": "brutal"}

            app = setup_app(config_dict, True)
            app.update(kube_client=mock_client)

            mock_deep_delete_and_create.assert_called_once_with(
                target=app.deep_delete_and_create, args=[mock_cloned_client])
Beispiel #2
0
def list_namespaced_deployments(kube_client: KubeClient, namespace: str,
                                **kwargs) -> Sequence[DeploymentWrapper]:
    return [
        DeploymentWrapper(deployment)
        for deployment in kube_client.deployments.list_namespaced_deployment(
            namespace, **kwargs).items if is_valid_application(deployment)
    ]
Beispiel #3
0
def setup_app(config_dict, exists_hpa):
    item = mock.MagicMock()
    item.metadata.name = "fake_name"
    item.metadata.namespace = "faasta"

    app = DeploymentWrapper(item=item)
    app.soa_config = KubernetesDeploymentConfig(
        service="service",
        cluster="cluster",
        instance="instance",
        config_dict=config_dict,
        branch_dict=None,
    )

    app.exists_hpa = mock.Mock(return_value=exists_hpa)
    app.delete_horizontal_pod_autoscaler = mock.Mock(return_value=None)
    return app
def create_application_object(
    kube_client: KubeClient, service: str, instance: str, soa_dir: str
) -> Tuple[bool, Optional[Application]]:
    try:
        service_instance_config = load_kubernetes_service_config_no_cache(
            service,
            instance,
            load_system_paasta_config().get_cluster(),
            soa_dir=soa_dir,
        )
    except NoDeploymentsAvailable:
        log.debug(
            "No deployments found for %s.%s in cluster %s. Skipping."
            % (service, instance, load_system_paasta_config().get_cluster())
        )
        return True, None
    except NoConfigurationForServiceError:
        error_msg = (
            "Could not read kubernetes configuration file for %s.%s in cluster %s"
            % (service, instance, load_system_paasta_config().get_cluster())
        )
        log.error(error_msg)
        return False, None
    try:
        formatted_application = service_instance_config.format_kubernetes_app()
    except InvalidKubernetesConfig as e:
        log.error(str(e))
        return False, None

    app = None
    if isinstance(formatted_application, V1Deployment):
        app = DeploymentWrapper(formatted_application)
    elif isinstance(formatted_application, V1StatefulSet):
        app = StatefulSetWrapper(formatted_application)
    else:
        raise Exception("Unknown kubernetes object to update")

    app.load_local_config(soa_dir, load_system_paasta_config())
    return True, app
Beispiel #5
0
def test_cleanup_unused_apps(fake_deployment, fake_stateful_set, invalid_app):
    mock_kube_client = mock.MagicMock()
    with mock.patch(
            "paasta_tools.cleanup_kubernetes_jobs.KubeClient",
            return_value=mock_kube_client,
            autospec=True,
    ), mock.patch(
            "paasta_tools.cleanup_kubernetes_jobs.list_namespaced_applications",
            return_value=[DeploymentWrapper(fake_deployment)],
            autospec=True,
    ), mock.patch(
            "paasta_tools.cleanup_kubernetes_jobs.get_services_for_cluster",
            return_value={},
            autospec=True,
    ), mock.patch("paasta_tools.cleanup_kubernetes_jobs.alert_state_change",
                  autospec=True) as mock_alert_state_change:
        mock_alert_state_change.__enter__ = mock.Mock(
            return_value=(mock.Mock(), None))
        mock_alert_state_change.__exit__ = mock.Mock(return_value=None)
        cleanup_unused_apps("soa_dir", kill_threshold=1, force=False)
        assert mock_kube_client.deployments.delete_namespaced_deployment.call_count == 1
def test_sync_horizontal_pod_autoscaler():
    mock_client = mock.MagicMock()
    app = mock.MagicMock()
    app.item.metadata.name = "fake_name"
    app.item.metadata.namespace = "faasta"

    # helper Functions for mocking
    def setup_app(app, config_dict, exists_hpa):
        app.reset_mock()
        mock_client.reset_mock()
        app.get_soa_config.return_value = config_dict
        app.exists_hpa.return_value = exists_hpa

    # Do nothing
    config_dict = {"instances": 1}
    setup_app(app, config_dict, False)
    DeploymentWrapper.sync_horizontal_pod_autoscaler(self=app,
                                                     kube_client=mock_client)
    assert (mock_client.autoscaling.
            create_namespaced_horizontal_pod_autoscaler.call_count == 0)
    assert (mock_client.autoscaling.patch_namespaced_horizontal_pod_autoscaler.
            call_count == 0)
    assert app.delete_horizontal_pod_autoscaler.call_count == 0

    # old HPA got removed so delete
    config_dict = {"instances": 1}
    setup_app(app, config_dict, True)
    DeploymentWrapper.sync_horizontal_pod_autoscaler(self=app,
                                                     kube_client=mock_client)
    assert (mock_client.autoscaling.
            create_namespaced_horizontal_pod_autoscaler.call_count == 0)
    assert (mock_client.autoscaling.patch_namespaced_horizontal_pod_autoscaler.
            call_count == 0)
    assert app.delete_horizontal_pod_autoscaler.call_count == 1

    # Create
    config_dict = {}
    setup_app(app, config_dict, False)
    DeploymentWrapper.sync_horizontal_pod_autoscaler(self=app,
                                                     kube_client=mock_client)
    assert (mock_client.autoscaling.patch_namespaced_horizontal_pod_autoscaler.
            call_count == 0)
    assert app.delete_horizontal_pod_autoscaler.call_count == 0
    mock_client.autoscaling.create_namespaced_horizontal_pod_autoscaler.assert_called_once_with(
        namespace="faasta",
        body=app.soa_config.get_autoscaling_metric_spec.return_value,
        pretty=True,
    )

    # Update
    config_dict = {}
    setup_app(app, config_dict, True)
    DeploymentWrapper.sync_horizontal_pod_autoscaler(self=app,
                                                     kube_client=mock_client)
    assert (mock_client.autoscaling.
            create_namespaced_horizontal_pod_autoscaler.call_count == 0)
    assert app.delete_horizontal_pod_autoscaler.call_count == 0
    mock_client.autoscaling.patch_namespaced_horizontal_pod_autoscaler.assert_called_once_with(
        namespace="faasta",
        name="fake_name",
        body=app.soa_config.get_autoscaling_metric_spec.return_value,
        pretty=True,
    )