Exemple #1
0
def reconcile_kubernetes_resource(
    kube_client: KubeClient,
    service: str,
    instance_configs: Mapping[str, Any],
    custom_resources: Sequence[KubeCustomResource],
    kind: KubeKind,
    version: str,
    group: str,
) -> bool:

    results = []
    for instance, config in instance_configs.items():
        formatted_resource = format_custom_resource(
            instance_config=config,
            service=service,
            instance=instance,
            kind=kind.singular,
            version=version,
            group=group,
        )
        desired_resource = KubeCustomResource(
            service=service,
            instance=instance,
            config_sha=formatted_resource['metadata']['labels']
            ['yelp.com/paasta_config_sha'],
            kind=kind.singular,
        )

        try:
            if not (service, instance, kind.singular) in [
                (c.service, c.instance, c.kind) for c in custom_resources
            ]:
                log.info(f"{desired_resource} does not exist so creating")
                create_custom_resource(
                    kube_client=kube_client,
                    version=version,
                    kind=kind,
                    formatted_resource=formatted_resource,
                    group=group,
                )
            elif desired_resource not in custom_resources:
                sanitised_service = service.replace('_', '--')
                sanitised_instance = instance.replace('_', '--')
                log.info(
                    f"{desired_resource} exists but config_sha doesn't match")
                update_custom_resource(
                    kube_client=kube_client,
                    name=f'{sanitised_service}-{sanitised_instance}',
                    version=version,
                    kind=kind,
                    formatted_resource=formatted_resource,
                    group=group,
                )
            else:
                log.info(f"{desired_resource} is up to date, no action taken")
        except Exception as e:
            log.error(str(e))
            results.append(False)
        results.append(True)
    return all(results) if results else True
Exemple #2
0
def test_reconcile_kubernetes_resource():
    with mock.patch(
        "paasta_tools.setup_kubernetes_cr.format_custom_resource", autospec=True
    ) as mock_format_custom_resource, mock.patch(
        "paasta_tools.setup_kubernetes_cr.create_custom_resource", autospec=True
    ) as mock_create_custom_resource, mock.patch(
        "paasta_tools.setup_kubernetes_cr.update_custom_resource", autospec=True
    ) as mock_update_custom_resource:
        mock_kind = mock.Mock(singular="flink", plural="flinks")
        mock_custom_resources = [
            KubeCustomResource(
                service="kurupt",
                instance="fm",
                config_sha="conf123",
                kind="flink",
                name="foo",
                namespace="paasta-flinks",
            )
        ]
        mock_client = mock.Mock()
        # no instances, do nothing
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service="mc",
            instance_configs={},
            cluster="mycluster",
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version="v1",
            group="yelp.com",
        )
        assert not mock_create_custom_resource.called
        assert not mock_update_custom_resource.called

        # instance up to date, do nothing
        mock_format_custom_resource.return_value = {
            "metadata": {
                "labels": {
                    "yelp.com/paasta_config_sha": "conf123",
                    "paasta.yelp.com/config_sha": "conf123",
                },
                "name": "foo",
                "namespace": "paasta-flinks",
            }
        }
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service="kurupt",
            instance_configs={"fm": {"some": "config"}},
            cluster="cluster",
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version="v1",
            group="yelp.com",
        )
        assert not mock_create_custom_resource.called
        assert not mock_update_custom_resource.called

        # instance diff config, update
        mock_format_custom_resource.return_value = {
            "metadata": {
                "labels": {"yelp.com/paasta_config_sha": "conf456"},
                "name": "foo",
                "namespace": "paasta-flinks",
            }
        }
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service="kurupt",
            instance_configs={"fm": {"some": "config"}},
            cluster="mycluster",
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version="v1",
            group="yelp.com",
        )
        assert not mock_create_custom_resource.called
        mock_update_custom_resource.assert_called_with(
            kube_client=mock_client,
            name="kurupt-fm",
            version="v1",
            kind=mock_kind,
            formatted_resource=mock_format_custom_resource.return_value,
            group="yelp.com",
        )

        # instance not exist, create
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service="mc",
            instance_configs={"grindah": {"some": "conf"}},
            cluster="mycluster",
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version="v1",
            group="yelp.com",
        )
        mock_create_custom_resource.assert_called_with(
            kube_client=mock_client,
            version="v1",
            kind=mock_kind,
            formatted_resource=mock_format_custom_resource.return_value,
            group="yelp.com",
        )

        # instance not exist, create but error with k8s
        mock_create_custom_resource.side_effect = Exception
        assert not setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service="mc",
            instance_configs={"grindah": {"some": "conf"}},
            cluster="mycluster",
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version="v1",
            group="yelp.com",
        )
        mock_create_custom_resource.assert_called_with(
            kube_client=mock_client,
            version="v1",
            kind=mock_kind,
            formatted_resource=mock_format_custom_resource.return_value,
            group="yelp.com",
        )
Exemple #3
0
def test_reconcile_kubernetes_resource():
    with mock.patch(
            'paasta_tools.setup_kubernetes_cr.format_custom_resource',
            autospec=True,
    ) as mock_format_custom_resource, mock.patch(
            'paasta_tools.setup_kubernetes_cr.create_custom_resource',
            autospec=True,
    ) as mock_create_custom_resource, mock.patch(
            'paasta_tools.setup_kubernetes_cr.update_custom_resource',
            autospec=True,
    ) as mock_update_custom_resource:
        mock_kind = mock.Mock(singular='flinkcluster')
        mock_custom_resources = [
            KubeCustomResource(
                service='kurupt',
                instance='fm',
                config_sha='conf123',
                kind='flinkcluster',
            ),
        ]
        mock_client = mock.Mock()
        # no instances, do nothing
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service='mc',
            instance_configs={},
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version='v1',
            group='yelp.com',
        )
        assert not mock_create_custom_resource.called
        assert not mock_update_custom_resource.called

        # instance up to date, do nothing
        mock_format_custom_resource.return_value = {
            'metadata': {
                'labels': {
                    'yelp.com/paasta_config_sha': 'conf123',
                },
            },
        }
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service='kurupt',
            instance_configs={'fm': {
                'some': 'config'
            }},
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version='v1',
            group='yelp.com',
        )
        assert not mock_create_custom_resource.called
        assert not mock_update_custom_resource.called

        # instance diff config, update
        mock_format_custom_resource.return_value = {
            'metadata': {
                'labels': {
                    'yelp.com/paasta_config_sha': 'conf456',
                },
            },
        }
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service='kurupt',
            instance_configs={'fm': {
                'some': 'config'
            }},
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version='v1',
            group='yelp.com',
        )
        assert not mock_create_custom_resource.called
        mock_update_custom_resource.assert_called_with(
            kube_client=mock_client,
            name='kurupt-fm',
            version='v1',
            kind=mock_kind,
            formatted_resource=mock_format_custom_resource.return_value,
            group='yelp.com',
        )

        # instance not exist, create
        assert setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service='mc',
            instance_configs={'grindah': {
                'some': 'conf'
            }},
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version='v1',
            group='yelp.com',
        )
        mock_create_custom_resource.assert_called_with(
            kube_client=mock_client,
            version='v1',
            kind=mock_kind,
            formatted_resource=mock_format_custom_resource.return_value,
            group='yelp.com',
        )

        # instance not exist, create but error with k8s
        mock_create_custom_resource.side_effect = Exception
        assert not setup_kubernetes_cr.reconcile_kubernetes_resource(
            kube_client=mock_client,
            service='mc',
            instance_configs={'grindah': {
                'some': 'conf'
            }},
            custom_resources=mock_custom_resources,
            kind=mock_kind,
            version='v1',
            group='yelp.com',
        )
        mock_create_custom_resource.assert_called_with(
            kube_client=mock_client,
            version='v1',
            kind=mock_kind,
            formatted_resource=mock_format_custom_resource.return_value,
            group='yelp.com',
        )
Exemple #4
0
def reconcile_kubernetes_resource(
    kube_client: KubeClient,
    service: str,
    instance_configs: Mapping[str, Any],
    custom_resources: Sequence[KubeCustomResource],
    kind: KubeKind,
    version: str,
    group: str,
    cluster: str,
    instance: str = None,
) -> bool:

    results = []
    for inst, config in instance_configs.items():
        if instance is not None and instance != inst:
            continue
        formatted_resource = format_custom_resource(
            instance_config=config,
            service=service,
            instance=inst,
            cluster=cluster,
            kind=kind.singular,
            version=version,
            group=group,
            namespace=f"paasta-{kind.plural}",
        )
        desired_resource = KubeCustomResource(
            service=service,
            instance=inst,
            config_sha=formatted_resource["metadata"]["labels"]
            ["paasta.yelp.com/config_sha"],
            kind=kind.singular,
            name=formatted_resource["metadata"]["name"],
            namespace=f"paasta-{kind.plural}",
        )

        try:
            if not (service, inst, kind.singular) in [
                (c.service, c.instance, c.kind) for c in custom_resources
            ]:
                log.info(f"{desired_resource} does not exist so creating")
                create_custom_resource(
                    kube_client=kube_client,
                    version=version,
                    kind=kind,
                    formatted_resource=formatted_resource,
                    group=group,
                )
            elif desired_resource not in custom_resources:
                sanitised_service = sanitise_kubernetes_name(service)
                sanitised_instance = sanitise_kubernetes_name(inst)
                log.info(
                    f"{desired_resource} exists but config_sha doesn't match")
                update_custom_resource(
                    kube_client=kube_client,
                    name=f"{sanitised_service}-{sanitised_instance}",
                    version=version,
                    kind=kind,
                    formatted_resource=formatted_resource,
                    group=group,
                )
            else:
                log.info(f"{desired_resource} is up to date, no action taken")
        except Exception as e:
            log.error(str(e))
            results.append(False)
        results.append(True)
    return all(results) if results else True
def reconcile_kubernetes_resource(
    kube_client: KubeClient,
    service: str,
    instance_configs: Mapping[str, Any],
    custom_resources: Sequence[KubeCustomResource],
    kind: KubeKind,
    version: str,
    group: str,
    crd: CustomResourceDefinition,
    cluster: str,
    instance: str = None,
) -> bool:
    succeeded = True
    config_handler = LONG_RUNNING_INSTANCE_TYPE_HANDLERS[crd.file_prefix]
    for inst, config in instance_configs.items():
        if instance is not None and instance != inst:
            continue
        try:
            soa_config = config_handler.loader(
                service=service,
                instance=inst,
                cluster=cluster,
                load_deployments=True,
                soa_dir=DEFAULT_SOA_DIR,
            )
            git_sha = get_git_sha_from_dockerurl(soa_config.get_docker_url(),
                                                 long=True)
            formatted_resource = format_custom_resource(
                instance_config=config,
                service=service,
                instance=inst,
                cluster=cluster,
                kind=kind.singular,
                version=version,
                group=group,
                namespace=f"paasta-{kind.plural}",
                git_sha=git_sha,
            )
            desired_resource = KubeCustomResource(
                service=service,
                instance=inst,
                config_sha=formatted_resource["metadata"]["labels"][
                    paasta_prefixed("config_sha")],
                git_sha=formatted_resource["metadata"]["labels"].get(
                    paasta_prefixed("git_sha")),
                kind=kind.singular,
                name=formatted_resource["metadata"]["name"],
                namespace=f"paasta-{kind.plural}",
            )
            if not (service, inst, kind.singular) in [
                (c.service, c.instance, c.kind) for c in custom_resources
            ]:
                log.info(f"{desired_resource} does not exist so creating")
                create_custom_resource(
                    kube_client=kube_client,
                    version=version,
                    kind=kind,
                    formatted_resource=formatted_resource,
                    group=group,
                )
            elif desired_resource not in custom_resources:
                sanitised_service = sanitise_kubernetes_name(service)
                sanitised_instance = sanitise_kubernetes_name(inst)
                log.info(
                    f"{desired_resource} exists but config_sha doesn't match")
                update_custom_resource(
                    kube_client=kube_client,
                    name=f"{sanitised_service}-{sanitised_instance}",
                    version=version,
                    kind=kind,
                    formatted_resource=formatted_resource,
                    group=group,
                )
            else:
                log.info(f"{desired_resource} is up to date, no action taken")
        except Exception as e:
            log.error(str(e))
            succeeded = False
    return succeeded