Skip to content
This repository has been archived by the owner on May 17, 2024. It is now read-only.

added ability to stop an instance pool as an experiment #19

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
83 changes: 83 additions & 0 deletions chaosoci/core/computemanagement/actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

__all__ = ["stop_instance_pool_by_id", "stop_instance_pool_by_filters"]

from random import choice
from typing import Any, Dict, List

from chaoslib.exceptions import ActivityFailed
from chaoslib.types import Configuration, Secrets

from chaosoci import oci_client
from chaosoci.types import OCIResponse
from chaosoci.util.constants import FILTER_ERR

from logzero import logger

from oci.config import from_file
from oci.core import ComputeManagementClient

from .common import (get_instance_pools)

from .filters import (filter_instance_pools)


def stop_instance_pool_by_id(instance_pool_id: str, force: bool = False,
configuration: Configuration = None,
secrets: Secrets = None) -> OCIResponse:
"""
Stops an instance pool using the instance pool id.

Parameters:
Required:
- instance_pool_id: the id of the route table
"""

client = oci_client(ComputeManagementClient, configuration, secrets,
skip_deserialization=True)
if not instance_pool_id:
raise ActivityFailed('An instance pool id is required.')

ret = client.stop_instance_pool(instance_pool_id=instance_pool_id).data
logger.debug("Instance pool %s stopped", instance_pool_id)
return ret


def stop_instance_pool_by_filters(compartment_id: str,
filters: Dict[str, Any], force: bool = False,
configuration: Configuration = None,
secrets: Secrets = None) -> OCIResponse:
"""
Search for an instance pool using the specified filters and
then stops it.

Parameters:
Required:
- compartment_id: the compartment id of the instance pool
- filters: the set of filters for the route table.
Please refer to
https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/api/core/models/oci.core.models.InstancePool.html#oci.core.models.InstancePool
for the route table filters.
"""

client = oci_client(ComputeManagementClient, configuration, secrets,
skip_deserialization=False)

if compartment_id is None:
raise ActivityFailed('A compartment id is required.')
else:
unfiltered = get_instance_pools(client, compartment_id)

if filters is None:
raise ActivityFailed(FILTER_ERR)
else:
filtered = filter_instance_pools(unfiltered, filters)

if (len(filtered) == 0):
raise ActivityFailed(FILTER_ERR)
else:
ret = client.stop_instance_pool(filtered[0].id).data
logger.debug("Instance pool %s stopped",
filtered[0].display_name)
return ret
33 changes: 33 additions & 0 deletions chaosoci/core/computemanagement/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

__all__ = ["get_instance_pools"]

from typing import Any, Dict, List

from chaoslib.exceptions import ActivityFailed

from logzero import logger

from oci.core import ComputeManagementClient
from oci.core.models import (InstancePool)


def get_instance_pools(client: ComputeManagementClient = None,
compartment_id: str = None) -> List[InstancePool]:
"""
Returns a complete, unfiltered list of instance pools in the
compartment.
"""

instance_pools = []
instance_pools_raw = client.list_instance_pools(
compartment_id=compartment_id)
instance_pools.extend(instance_pools_raw.data)
while instance_pools_raw.has_next_page:
instance_pools_raw = client.list_instance_pools(
compartment_id=compartment_id,
page=instance_pools_raw.next_page)
instance_pools.extend(instance_pools_raw.data)

return instance_pools
48 changes: 48 additions & 0 deletions chaosoci/core/computemanagement/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

__all__ = ["filter_instance_pools"]

from typing import Any, Dict, List

from chaoslib.exceptions import ActivityFailed
from chaosoci.util.constants import FILTER_ERR

from logzero import logger

from oci.core import ComputeManagementClient
from oci.core.models import (InstancePool)


def filter_instance_pools(instance_pools: List[InstancePool] = None,
filters: Dict[str, Any] = None
) -> List[InstancePool]:
"""
Return only those instance pools that match the filters provided.
"""
instance_pools = instance_pools or None

if instance_pools is None:
raise ActivityFailed('No instance pools were found.')

filters_set = {x for x in filters}

available_filters_set = {x for x in instance_pools[0].attribute_map}

# Partial filtering may return instance pools we do not want. We avoid it.
if not filters_set.issubset(available_filters_set):
raise ActivityFailed(FILTER_ERR)

# Walk the instance pools and find those that match the given filters.
filtered = []
for instance_pool in instance_pools:
sentinel = True
for attr, val in filters.items():
if val != getattr(instance_pool, attr, None):
sentinel = False
break

if sentinel:
filtered.append(instance_pool)

return filtered
48 changes: 48 additions & 0 deletions chaosoci/core/computemanagement/probes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

__all__ = ['count_instance_pools']

from typing import Any, Dict, List

from chaoslib.exceptions import ActivityFailed
from chaoslib.types import Configuration, Secrets

from chaosoci import oci_client

from logzero import logger

from oci.config import from_file
from oci.core import ComputeManagementClient

from .common import (get_instance_pools)

from .filters import (filter_instance_pools)


def count_instance_pools(filters: List[Dict[str, Any]],
compartment_id: str = None,
configuration: Configuration = None,
secrets: Secrets = None) -> int:
"""
Returns the number of Instance Pools in the compartment 'compartment_id'
and according to the given filters.

Please refer to:https://oracle-cloud-infrastructure-python-sdk.readthedocs.io/en/latest/api/core/models/oci.core.models.InstancePool.html#oci.core.models.InstancePool

for details on the available filters under the 'parameters' section.
""" # noqa: E501
compartment_id = compartment_id or from_file().get('compartment')

if compartment_id is None:
raise ActivityFailed('A valid compartment id is required.')

client = oci_client(ComputeManagementClient, configuration, secrets,
skip_deserialization=False)

filters = filters or None
instance_pools = get_instance_pools(client, compartment_id)
if filters is not None:
return len(filter_instance_pools(instance_pools, filters=filters))
else:
return len(instance_pools)
22 changes: 22 additions & 0 deletions chaosoci/core/computemanagement/rollbacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

__all__ = ["delete_nat_rollback"]

from random import choice
from typing import Any, Dict, List

from chaoslib.exceptions import ActivityFailed
from chaoslib.types import Configuration, Secrets

from chaosoci import oci_client
from chaosoci.types import OCIResponse

from logzero import logger

from oci.config import from_file
from oci.core import ComputeManagementClient

from .common import (get_instance_pools)

from .filters import (filter_instance_pools)
58 changes: 58 additions & 0 deletions tests/core/computemanagement/test_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

import pytest

from unittest.mock import MagicMock, patch

from chaoslib.exceptions import ActivityFailed

from chaosoci.core.computemanagement.actions import (stop_instance_pool_by_id,
stop_instance_pool_by_filters)
from chaosoci.util.constants import FILTER_ERR

@patch('chaosoci.core.computemanagement.actions.oci_client', autospec=True)
def test_stop_instance_pool_by_id(oci_client):
compute_management_client = MagicMock()
oci_client.return_value = compute_management_client
instance_pool_id = "ocid1.instancepool.oc1.phx.aawnm2cdxq3naniep5dsiixtchqjuypcx7l7"
instance_pool_ids = [instance_pool_id, ""]
for id in instance_pool_ids:
if id == instance_pool_id:
stop_instance_pool_by_id(id)
compute_management_client.stop_instance_pool.assert_called_with(instance_pool_id=id)
else:
with pytest.raises(ActivityFailed) as f:
stop_instance_pool_by_id(id)
assert 'An instance pool id is required.'

@patch('chaosoci.core.computemanagement.actions.filter_instance_pools', autospec=True)
@patch('chaosoci.core.computemanagement.actions.get_instance_pools', autospec=True)
@patch('chaosoci.core.computemanagement.actions.oci_client', autospec=True)
def test_stop_instance_pool_by_filters(oci_client, get_instance_pools,
filter_instance_pools):
compute_management_client = MagicMock()
oci_client.return_value = compute_management_client

c_id = "ocid1.compartment.oc1..oadsocmof6r6ksovxmda44ikwxje7xxu"

c_ids = [c_id, None]
filters = [[{'display_name': 'random_name', 'region': 'uk-london-1'}],
None]

for c in c_ids:
for f in filters:
if c is None :
with pytest.raises(ActivityFailed) as c_failed:
stop_instance_pool_by_filters(c, f)
assert 'A compartment id or vcn id is required.'
elif f is None:
with pytest.raises(ActivityFailed) as f_failed:
stop_instance_pool_by_filters(c, f)
assert FILTER_ERR
else:
with pytest.raises(ActivityFailed) as rt_failed:
stop_instance_pool_by_filters(c, f)
cdcdcompute_management_client.stop_instance_pool.assert_called_with(
filter_instance_pools(route_tables=get_instance_pools(
oci_client, c), filters=f)[0].id)
35 changes: 35 additions & 0 deletions tests/core/computemanagement/test_probes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

import pytest

from unittest import TestCase as T
from unittest.mock import MagicMock, patch

from chaoslib.exceptions import ActivityFailed

from chaosoci.core.computemanagement.probes import (count_instance_pools,
filter_instance_pools)

@patch('chaosoci.core.computemanagement.probes.filter_instance_pools', autospec=True)
@patch('chaosoci.core.computemanagement.probes.get_instance_pools', autospec=True)
@patch('chaosoci.core.computemanagement.probes.oci_client', autospec=True)
def test_count_instance_pools(oci_client, get_instance_pools, filter_instance_pools):
compute_management_client = MagicMock()
oci_client.return_value = compute_management_client

c_id = "ocid1.compartment.oc1..oadsocmof6r6ksovxmda44ikwxje7xxu"
filters = [{'display_name': 'random_name', 'region': 'uk-london-1'}]

c_ids = [c_id]

for id in c_ids:
if id == c_id:
count_instance_pools(filters=filters, compartment_id=id)
filter_instance_pools.assert_called_with(
instance_pools=get_instance_pools(
oci_client, id), filters=filters)
else:
with pytest.raises(ActivityFailed) as f:
count_instance_pools(filters=filters, compartment_id=id)
assert 'A valid compartment id is required.'
10 changes: 10 additions & 0 deletions tests/core/computemanagement/test_rollbacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# coding: utf-8
# Copyright 2020, Oracle Corporation and/or its affiliates.

import pytest

from unittest.mock import MagicMock, patch

from oci.exceptions import ServiceError

from chaoslib.exceptions import ActivityFailed
1 change: 0 additions & 1 deletion tests/core/networking/test_networking_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from chaosoci.core.networking.actions import (delete_route_table_by_id,
delete_route_table_by_filters)
from chaosoci.util.constants import FILTER_ERR
# FILTER_ERR = 'Some of the chosen filters were not found, we cannot continue.'

@patch('chaosoci.core.networking.actions.oci_client', autospec=True)
def test_delete_route_table_by_id(oci_client):
Expand Down