def test_mirror_pod_cannot_be_drained(cl, client, has_conf): has_conf.return_value = False v1 = MagicMock() client.CoreV1Api.return_value = v1 node = MagicMock() node.metadata.name = "mynode" result = MagicMock() result.items = [node] v1.list_node.return_value = result owner = MagicMock() owner.controller = True owner.kind = "ReplicationSet" pod = MagicMock() pod.metadata.uid = "1" pod.metadata.name = "apod" pod.metadata.namespace = "default" pod.metadata.owner_references = [owner] pod.metadata.annotations = {"kubernetes.io/config.mirror": "..."} pods = MagicMock() pods.items = [pod] v1.list_pod_for_all_namespaces.return_value = pods drain_nodes(name="mynode") v1.read_namespaced_pod.assert_not_called() v1.create_namespaced_pod_eviction.assert_not_called()
def test_pod_with_local_volume_cannot_be_drained(cl, client, has_conf): has_conf.return_value = False v1 = MagicMock() client.CoreV1Api.return_value = v1 node = MagicMock() node.metadata.name = "mynode" result = MagicMock() result.items = [node] v1.list_node.return_value = result owner = MagicMock() owner.controller = True owner.kind = "ReplicationSet" pod = MagicMock() pod.metadata.uid = "1" pod.metadata.name = "apod" pod.metadata.namespace = "default" pod.metadata.owner_references = [owner] volume = MagicMock() volume.empty_dir = True pod.spec.volumes = [volume] pods = MagicMock() pods.items = [pod] v1.list_pod_for_all_namespaces.return_value = pods drain_nodes(name="mynode") v1.read_namespaced_pod.assert_not_called() v1.create_namespaced_pod_eviction.assert_not_called()
def test_pod_with_local_volume_cannot_be_drained_unless_forced( cl, client, has_conf): has_conf.return_value = False client.V1beta1Eviction = MagicMock() client.V1ObjectMeta = MagicMock() client.V1DeleteOptions = MagicMock() v1 = MagicMock() client.CoreV1Api.return_value = v1 node = MagicMock() node.metadata.name = "mynode" result = MagicMock() result.items = [node] v1.list_node.return_value = result owner = MagicMock() owner.controller = True owner.kind = "ReplicationSet" pod = MagicMock() pod.metadata.uid = "1" pod.metadata.name = "apod" pod.metadata.namespace = "default" pod.metadata.owner_references = [owner] pods = MagicMock() pods.items = [pod] v1.list_pod_for_all_namespaces.return_value = pods new_pod = MagicMock() new_pod.metadata.uid = "2" new_pod.metadata.name = "apod" new_pod.metadata.namespace = "default" v1.read_namespaced_pod.side_effect = [pod, new_pod] drain_nodes(name="mynode", delete_pods_with_local_storage=True) v1.create_namespaced_pod_eviction.assert_called_with("apod", "default", body=ANY)
def test_drain_nodes_by_name(cl, client, has_conf): has_conf.return_value = False v1 = MagicMock() client.CoreV1Api.return_value = v1 node = MagicMock() node.metadata.name = "mynode" result = MagicMock() result.items = [node] v1.list_node.return_value = result owner = MagicMock() owner.controller = True owner.kind = "ReplicationSet" pod = MagicMock() pod.metadata.uid = "1" pod.metadata.name = "apod" pod.metadata.namespace = "default" pod.metadata.owner_references = [owner] pods = MagicMock() pods.items = [pod] v1.list_pod_for_all_namespaces.return_value = pods new_pod = MagicMock() new_pod.metadata.uid = "2" new_pod.metadata.name = "apod" new_pod.metadata.namespace = "default" v1.read_namespaced_pod.side_effect = [ pod, new_pod ] drain_nodes(name="mynode") v1.create_namespaced_pod_eviction.assert_called_with( "apod", "default", body=ANY)
def swap_nodepool(old_node_pool_id: str, new_nodepool_body: Dict[str, Any], wait_until_complete: bool = True, delete_old_node_pool: bool = False, drain_timeout: int = 120, configuration: Configuration = None, secrets: Secrets = None) -> Dict[str, Any]: """ Create a new nodepool, drain the old one so pods can be rescheduled on the new pool. Delete the old nodepool only `delete_old_node_pool` is set to `True`, which is not the default. Otherwise, leave the old node pool cordonned so it cannot be scheduled any longer. Please ensure to provide the Kubernetes secrets as well when calling this action. See https://github.com/chaostoolkit/chaostoolkit-kubernetes#configuration """ new_nodepool_response = create_new_nodepool( body=new_nodepool_body, wait_until_complete=wait_until_complete, configuration=configuration, secrets=secrets) logger.debug("New nodepool '{}' created".format(new_nodepool_response)) drain_nodes( timeout=drain_timeout, delete_pods_with_local_storage=False, secrets=secrets, label_selector="cloud.google.com/gke-nodepool={}".format( old_node_pool_id)) logger.debug("Old nodepool '{}' drained".format(old_node_pool_id)) if delete_old_node_pool: logger.debug("Deleting now nodepool '{}'".format(old_node_pool_id)) delete_nodepool( node_pool_id=old_node_pool_id, wait_until_complete=wait_until_complete, configuration=configuration, secrets=secrets) return new_nodepool_response