示例#1
0
def test_when_set_for_labelling(owner):
    obj = {}
    kopf.label(obj)
    assert obj['metadata']['labels'] == {
        'label-1': 'value-1',
        'label-2': 'value-2'
    }
示例#2
0
def test_adding_to_pykube_object(pykube_object):
    del pykube_object.obj['metadata']
    kopf.label(pykube_object, {'label-1': 'value-1', 'label-2': 'value-2'})
    assert len(pykube_object.labels) == 2
    assert 'label-1' in pykube_object.labels
    assert 'label-2' in pykube_object.labels
    assert pykube_object.labels['label-1'] == 'value-1'
    assert pykube_object.labels['label-2'] == 'value-2'
示例#3
0
def test_adding_to_kubernetes_model(kubernetes_model):
    kubernetes_model.metadata = None
    kopf.label(kubernetes_model, {'label-1': 'value-1', 'label-2': 'value-2'})
    assert len(kubernetes_model.metadata.labels) == 2
    assert 'label-1' in kubernetes_model.metadata.labels
    assert 'label-2' in kubernetes_model.metadata.labels
    assert kubernetes_model.metadata.labels['label-1'] == 'value-1'
    assert kubernetes_model.metadata.labels['label-2'] == 'value-2'
示例#4
0
def test_nested_with_forced_true_to_kubernetes_model(nested, kubernetes_model):
    kubernetes_model.metadata.labels = {'label': 'old-value'}
    kopf.label(kubernetes_model, {'label': 'new-value'},
               nested=nested,
               forced=True)
    assert kubernetes_model.metadata.labels['label'] == 'new-value'
    assert kubernetes_model.spec.job_template.metadata.labels[
        'label'] == 'new-value'
    assert not hasattr(kubernetes_model.spec, 'unexistent')
示例#5
0
def test_nested_with_forced_false_to_pykube_object(nested, pykube_object):
    pykube_object.labels.update({'label': 'old-value'})
    pykube_object.obj.update({'spec': {'jobTemplate': {}}})
    kopf.label(pykube_object, {'label': 'new-value'},
               nested=nested,
               forced=False)
    assert pykube_object.labels['label'] == 'old-value'
    assert pykube_object.obj['spec']['jobTemplate']['metadata']['labels'][
        'label'] == 'new-value'
    assert 'unexistent' not in pykube_object.obj['spec']
示例#6
0
def test_adding_to_dict():
    obj = {}
    kopf.label(obj, {'label-1': 'value-1', 'label-2': 'value-2'})
    assert 'metadata' in obj
    assert 'labels' in obj['metadata']
    assert isinstance(obj['metadata']['labels'], dict)
    assert len(obj['metadata']['labels']) == 2
    assert 'label-1' in obj['metadata']['labels']
    assert 'label-2' in obj['metadata']['labels']
    assert obj['metadata']['labels']['label-1'] == 'value-1'
    assert obj['metadata']['labels']['label-2'] == 'value-2'
示例#7
0
def test_nested_with_forced_false_to_dict(nested):
    obj = {
        'metadata': {
            'labels': {
                'label': 'old-value'
            }
        },
        'spec': {
            'jobTemplate': {}
        }
    }
    kopf.label(obj, {'label': 'new-value'}, nested=nested, forced=False)
    assert obj['metadata']['labels']['label'] == 'old-value'
    assert obj['spec']['jobTemplate']['metadata']['labels'][
        'label'] == 'new-value'
    assert 'unexistent' not in obj['spec']
示例#8
0
def test_nested_with_forced_false():
    obj = {
        'metadata': {
            'labels': {
                'label': 'old-value'
            }
        },
        'spec': {
            'template': {}
        }
    }
    kopf.label(obj, {'label': 'new-value'},
               nested=['spec.template'],
               force=False)
    assert obj['metadata']['labels']['label'] == 'old-value'
    assert obj['spec']['template']['metadata']['labels'][
        'label'] == 'new-value'
示例#9
0
def test_adding_to_dicts(multicls):
    obj1 = {}
    obj2 = {}
    objs = multicls([obj1, obj2])
    kopf.label(objs, {'label-1': 'value-1', 'label-2': 'value-2'})
    assert isinstance(obj1['metadata']['labels'], dict)
    assert len(obj1['metadata']['labels']) == 2
    assert 'label-1' in obj1['metadata']['labels']
    assert 'label-2' in obj1['metadata']['labels']
    assert obj1['metadata']['labels']['label-1'] == 'value-1'
    assert obj1['metadata']['labels']['label-2'] == 'value-2'

    assert isinstance(obj2['metadata']['labels'], dict)
    assert len(obj2['metadata']['labels']) == 2
    assert 'label-1' in obj2['metadata']['labels']
    assert 'label-2' in obj2['metadata']['labels']
    assert obj2['metadata']['labels']['label-1'] == 'value-1'
    assert obj2['metadata']['labels']['label-2'] == 'value-2'
示例#10
0
async def _run_pod(action, pod_name, body, namespace):
    # Label the pod for filtering in the on.event handler.
    kopf.label(body, {ACTION_ANNOTATION: action})
    event = asyncio.Event()

    obj = None
    async with kubernetes_asyncio.client.ApiClient() as api:
        v1 = kubernetes_asyncio.client.CoreV1Api(api)
        obj = await v1.create_namespaced_pod(
            body=body,
            namespace=namespace,
        )
        EVENTS[action][obj.metadata.uid] = event

    # TODO: handle timeout and error
    log.debug('waiting for pod_event: %s', pod_name)
    await event.wait()
    log.debug('pod_event has been set: %s', pod_name)
    return obj
示例#11
0
def create_pod(body, **kwargs):

    # Render the pod yaml with some spec fields used in the template.
    pod_data = yaml.safe_load(f"""
        apiVersion: v1
        kind: Pod
        spec:
          containers:
          - name: the-only-one
            image: busybox
            command: ["sh", "-x", "-c", "sleep 1"]
    """)

    # Make it our child: assign the namespace, name, labels, owner references, etc.
    kopf.adopt(pod_data, owner=body)
    kopf.label(pod_data, {'application': 'kopf-example-10'})

    # Actually create an object by requesting the Kubernetes API.
    pod = pykube.Pod(api, pod_data)
    pod.create()
def create_cron_job(api: client.BatchV1beta1Api, configmap: Resource,
                    cro_spec: ResourceChunk, ns: str, name_suffix: str,
                    cro_meta: ResourceChunk, pod_tpl: str):
    logger = logging.getLogger('kopf.objects')

    schedule_spec = cro_spec.get("schedule", {})
    schedule = schedule_spec.get("value")

    tpl = yaml.safe_load(configmap.data['chaostoolkit-cronjob.yaml'])
    set_ns(tpl, ns)
    set_cron_job_name(tpl, name_suffix=name_suffix)
    set_cron_job_schedule(tpl, schedule)
    set_cron_job_template_spec(tpl, pod_tpl.get("spec", {}))

    experiment_labels = cro_meta.get('labels', {})
    kopf.label(tpl, labels=experiment_labels)
    kopf.label(tpl["spec"]["jobTemplate"], labels=experiment_labels)
    kopf.label(tpl["spec"]["jobTemplate"]["spec"]["template"],
               labels=experiment_labels)

    logger.debug(f"Creating cron job with template:\n{tpl}")
    cron = api.create_namespaced_cron_job(body=tpl, namespace=ns)
    logger.info(f"Cron Job '{cron.metadata.self_link}' scheduled with "
                f"pattern '{schedule}' in ns '{ns}'")

    return tpl
示例#13
0
def test_forcing_default_to_pykube_object(pykube_object):
    pykube_object.labels['label'] = 'old-value'
    kopf.label(pykube_object, {'label': 'new-value'})
    assert pykube_object.labels['label'] == 'old-value'
示例#14
0
def test_forcing_false_to_pykube_object(pykube_object):
    pykube_object.labels['label'] = 'old-value'
    kopf.label(pykube_object, {'label': 'new-value'}, forced=False)
    assert pykube_object.labels['label'] == 'old-value'
示例#15
0
def test_forcing_false_to_dict():
    obj = {'metadata': {'labels': {'label': 'old-value'}}}
    kopf.label(obj, {'label': 'new-value'}, forced=False)
    assert obj['metadata']['labels']['label'] == 'old-value'
示例#16
0
def test_forcing_true():
    obj = {'metadata': {'labels': {'label': 'old-value'}}}
    kopf.label(obj, {'label': 'new-value'}, force=True)
    assert obj['metadata']['labels']['label'] == 'new-value'
def test_in_labelling():
    with pytest.raises(TypeError) as e:
        kopf.label(object(), {})
    assert "K8s object class is not supported" in str(e.value)
示例#18
0
def test_forcing_false_warns_on_deprecated_option():
    obj = {'metadata': {'labels': {'label': 'old-value'}}}
    with pytest.deprecated_call(match=r"use forced="):
        kopf.label(obj, {'label': 'new-value'}, force=False)
    assert obj['metadata']['labels']['label'] == 'old-value'
示例#19
0
def test_forcing_false_to_kubernetes_model(kubernetes_model):
    kubernetes_model.metadata.labels = {'label': 'old-value'}
    kopf.label(kubernetes_model, {'label': 'new-value'}, forced=False)
    assert kubernetes_model.metadata.labels['label'] == 'old-value'
示例#20
0
def test_forcing_default_to_dict():
    obj = {'metadata': {'labels': {'label': 'old-value'}}}
    kopf.label(obj, {'label': 'new-value'})
    assert obj['metadata']['labels']['label'] == 'old-value'
示例#21
0
def test_forcing_default_to_kubernetes_model(kubernetes_model):
    kubernetes_model.metadata.labels = {'label': 'old-value'}
    kopf.label(kubernetes_model, {'label': 'new-value'})
    assert kubernetes_model.metadata.labels['label'] == 'old-value'
def test_when_unset_for_labelling():
    with pytest.raises(LookupError) as e:
        kopf.label([])
    assert 'Owner must be set explicitly' in str(e.value)
def create_pod(
        api: client.CoreV1Api,
        configmap: Resource,  # noqa: C901
        cro_spec: ResourceChunk,
        ns: str,
        name_suffix: str,
        cro_meta: ResourceChunk,
        *,
        apply: bool = True):
    logger = logging.getLogger('kopf.objects')

    pod_spec = cro_spec.get("pod", {})
    sa_name = cro_spec.get("serviceaccount", {}).get("name")

    # did the user supply their own pod spec?
    tpl = pod_spec.get("template")

    # if not, let's use the default one
    if not tpl:
        tpl = yaml.safe_load(configmap.data['chaostoolkit-pod.yaml'])
        image_name = pod_spec.get("image")
        env_cm_name = pod_spec.get("env", {}).get("configMapName",
                                                  "chaostoolkit-env")
        env_cm_enabled = pod_spec.get("env", {}).get("enabled", True)
        # optional support for loading secret keys as env. variables
        env_secret_name = pod_spec.get("env", {}).get("secretName")
        settings_secret_enabled = pod_spec.get("settings",
                                               {}).get("enabled", False)
        settings_secret_name = pod_spec.get("settings",
                                            {}).get("secretName",
                                                    "chaostoolkit-settings")
        experiment_as_file = pod_spec.get("experiment", {}).get("asFile", True)
        experiment_config_map_name = pod_spec.get("experiment", {}).get(
            "configMapName", "chaostoolkit-experiment")
        experiment_config_map_file_name = pod_spec.get("experiment", {}).get(
            "configMapExperimentFileName", "experiment.json")
        cmd_args = pod_spec.get("chaosArgs", [])

        # if image name is not given in CRO,
        # we keep the one defined by default in pod template from configmap
        if image_name:
            set_image_name(tpl, image_name)

        if not env_cm_enabled:
            logger.info("Removing default env configmap volume")
            remove_env_config_map(tpl)
        elif env_cm_name:
            logger.info(f"Env config map named '{env_cm_name}'")
            set_env_config_map_name(tpl, env_cm_name)

        if env_secret_name and env_cm_enabled:
            logger.info(f"Adding secret '{env_secret_name}' "
                        f"as environment variables")
            add_env_secret(tpl, env_secret_name)

        if not settings_secret_enabled:
            logger.info("Removing default settings secret volume")
            remove_settings_secret(tpl)
        elif settings_secret_name:
            logger.info(
                f"Settings secret volume named '{settings_secret_name}'")
            set_settings_secret_name(tpl, settings_secret_name)

        if experiment_as_file:
            logger.info("Experiment config map named "
                        f"'{experiment_config_map_name}'")
            set_experiment_config_map_name(tpl, experiment_config_map_name,
                                           experiment_config_map_file_name)
        else:
            logger.info("Removing default experiment config map volume")
            remove_experiment_volume(tpl)
            remove_env_path_config_map(tpl)
            set_chaos_cmd_args(tpl, ["run", "$(EXPERIMENT_URL)"])

        if cmd_args:
            # filter out empty values from command line arguments: None, ''
            cmd_args = list(filter(None, cmd_args))
            logger.info(f"Override default chaos command arguments: "
                        f"$ chaos {' '.join([str(arg) for arg in cmd_args])}")
            set_chaos_cmd_args(tpl, cmd_args)

    set_ns(tpl, ns)
    set_pod_name(tpl, name_suffix=name_suffix)
    set_sa_name(tpl, name=sa_name, name_suffix=name_suffix)
    kopf.label(tpl, labels=cro_meta.get('labels', {}))

    if apply:
        logger.debug(f"Creating pod with template:\n{tpl}")
        pod = api.create_namespaced_pod(body=tpl, namespace=ns)
        logger.info(f"Pod {pod.metadata.self_link} created in ns '{ns}'")

    return tpl