<filename>otter/integration/lib/mimic.py
"""Contains reusable classes relating to mimic."""

from __future__ import print_function

import json

from characteristic import Attribute, attributes

import treq

from twisted.internet.defer import inlineCallbacks, returnValue

from otter.integration.lib.utils import diagnose

from otter.util.http import check_success


@inlineCallbacks
def _sequenced_behaviors(test_case, pool, endpoint, criteria, behaviors,
                         _treq):
    """
    Cause an endpoint fail sometimes or all the time, with a pre-determined
    sequence of successes and/or failures.

    :param str endpoint: The endpoint for the mimic behavior to POST to
    :param pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :param list criteria: The criteria that the event should apply for the
        behavior to work
    :param list behaviors:  A list of dictionaries containing the names of
        behaviors parameters.
    :param _treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.

    :return: the ID of the created behavior
    :rtype: `str`
    """
    body = yield _treq.post(
        endpoint,
        json.dumps({
            "criteria": criteria,
            "name": "sequence",
            "parameters": {
                "behaviors": behaviors
            }
        }),
        pool=pool
    ).addCallback(check_success, [201]).addCallback(_treq.json_content)

    behavior_id = body['id']

    if test_case is not None:
        test_case.addCleanup(
            _delete_behavior, pool, endpoint, behavior_id, _treq)

    returnValue(behavior_id)


@diagnose("mimic", "Deleting behavior")
def _delete_behavior(pool, endpoint, behavior_id, _treq):
    """
    Given a behavior ID, delete it from mimic.

    :param str endpoint: The endpoint for the mimic behavior to POST to
    :param pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :param str behavior_id: The ID of the behavior to delete.
    :param _treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    d = _treq.delete("{0}/{1}".format(endpoint, behavior_id), pool=pool)
    d.addCallback(check_success, [204, 404])
    d.addCallback(_treq.content)
    return d


@attributes(["pool",
             Attribute("test_case", default_value=None),
             Attribute("treq", default_value=treq)])
class MimicNova(object):
    """
    Class that handles HTTP requests to the mimic nova control plane.

    Please see the mimic control plane API
    (:class:`mimic.rest.nova_api.NovaControlAPIRegion`) in the mimic
    codebase for more information.

    :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not
        None, will be used to clean up added behaviors.
    :ivar treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    @diagnose("mimic", "Changing a server's status")
    def change_server_statuses(self, rcs, ids_to_status):
        """
        Change the statuses of the given server IDs.  Changing the statuses of
        servers does not require any cleanup, because this is not creating a
        persistent behavior in mimic.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param dict ids_to_status: A mapping of server IDs to the string status
            to which they should be changed.  (see
            https://docs.rackspace.com/servers/api/v2/cs-devguide/content/
            List_Servers_Server_Statuses-d1e2078.html for a list of statuses)

        :return: A deferred that fires with the content of the response, which
            is probably the empty string.
        """
        return self.treq.post(
            "{0}/attributes".format(rcs.endpoints["mimic_nova"]),
            json.dumps({"status": ids_to_status}),
            pool=self.pool
        ).addCallback(check_success, [201]).addCallback(self.treq.content)

    @diagnose("mimic", "Injecting create server behavior")
    def sequenced_behaviors(self, rcs, criteria, behaviors,
                            event_description="creation"):
        """
        Cause Nova to fail sometimes or all the time, with a pre-determined
        sequence of successes and/or failures.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param list criteria: The criteria for the servers that should exhibit
            this behavior.  See, in mimic the control plane API,
            :func:`register_creation_behavior`, for more information.
        :param list behaviors:  A list of dictionaries containing the names of
            creation behaviors parameters.
            See, in the mimic codebase,
            :func:`mimic.model.nova_objects.sequence` for more information.
        :param str event_description: Which event this sequence of behaviors
            should apply to - the default event is server creation.

        :return: the ID of the created behavior
        :rtype: `str`
        """
        return _sequenced_behaviors(
            self.test_case, self.pool,
            "{0}/behaviors/{1}".format(rcs.endpoints['mimic_nova'],
                                       event_description),
            criteria, behaviors, self.treq)

    @diagnose("mimic", "Deleting create server behavior")
    def delete_behavior(self, rcs, behavior_id, event_description="creation"):
        """
        Given a behavior ID, delete it from mimic.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param str behavior_id: The ID of the behavior to delete.
        :param event_description: What type of event this is that should be
            deleted.
        """
        return _delete_behavior(
            self.pool, "{0}/behaviors/{1}".format(rcs.endpoints['mimic_nova'],
                                                  event_description),
            behavior_id, self.treq)


@attributes(["pool",
             Attribute("test_case", default_value=None),
             Attribute("treq", default_value=treq)])
class MimicIdentity(object):
    """
    Class that handles HTTP requests to the Mimic Identity control plane.

    Please see the Mimic generic control plane (:mod:`mimic.model.behaviors`)
    and specific auth failure behaviors (:class:`mimic.rest.auth_api`) in the
    mimic codebase for more information.

    :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not
        None, will be used to clean up added behaviors.
    :ivar treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    @diagnose("mimic", "Injecting auth behavior")
    def sequenced_behaviors(self, identity_endpoint, criteria, behaviors,
                            event_description="auth"):
        """
        Cause Identity to fail sometimes or all the time, with a pre-determined
        sequence of successes and/or failures.

        :param identity_endpoint: The endpoint with which to auth against
            identity - the mimic identity control endpoint is hardcoded, so
            this can tell us what the control endpoint is.
        :param list criteria: The criteria for the servers that should exhibit
            this behavior.  See, in mimic the control plane API,
            :func:`register_creation_behavior`, for more information.
        :param list behaviors:  A list of dictionaries containing the names of
            creation behaviors parameters.
            See, in the mimic codebase,
            :func:`mimic.model.nova_objects.sequence` for more information.
        :param str event_description: Which event this sequence of behaviors
            should apply to - the default event is authentication.

        :return: the ID of the created behavior
        :rtype: `str`
        """
        endpoint = identity_endpoint.replace(
            "/identity/v2.0",
            "/mimic/v1.1/IdentityControlAPI/behaviors/{0}".format(
                event_description))
        return _sequenced_behaviors(self.test_case, self.pool, endpoint,
                                    criteria, behaviors, self.treq)


@attributes(["pool",
             Attribute("test_case", default_value=None),
             Attribute("treq", default_value=treq)])
class MimicCLB(object):
    """
    Class that handles HTTP requests to the mimic Cloud Load Blancer
    control plane.

    Please see the mimic control plane API
    (:class:`mimic.rest.loadbalancer_api.LoadBalancerControlRegion`) in the
    mimic codebase for more information.

    :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not
        None, will be used to clean up added behaviors.
    :ivar treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    @diagnose("mimic", "Setting CLB status")
    def set_clb_attributes(self, rcs, clb_id, kvpairs):
        """
        Update the attributes of a clould load balancer based on the provided
        key, value pairs.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param clb_id: The ID of the load balancer to be altered
        :param dict kvpairs: A dictionary of key value pairs. The keys
        correspond to attributes in the load balancer details and the value is
        what the attribute will be replaced with.
        See the `mimic.model.RegionalCLBCollection.set_attribue` function
        for the supported attributes.
        :return: A deferred that fires with the content of the response, which
            is probably the empty string.
        """
        return self.treq.patch(
            "{0}/loadbalancer/{1}/attributes".format(
                rcs.endpoints["mimic_clb"], clb_id),
            json.dumps(kvpairs),
            pool=self.pool
        ).addCallback(check_success, [204]).addCallback(self.treq.content)

    @diagnose("mimic", "Updating CLB node status")
    def update_clb_node_status(self, rcs, clb_id, node_id, status):
        """
        Update CLB node's status field

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param int clb_id: The ID of the load balancer whose node's status
            is to be updated
        :param int node_id: ID of updating node
        :param str status: status to update. One of "ONLINE" or "OFFLINE"
        :return: A deferred that fires with the content of the response, which
            is probably the empty string.
        """
        return self.treq.put(
            "{0}/loadbalancers/{1}/nodes/{2}/status".format(
                rcs.endpoints["mimic_clb"], clb_id, node_id),
            json.dumps({"status": status}),
            pool=self.pool
        ).addCallback(check_success, [200]).addCallback(self.treq.content)

<filename>otter/integration/lib/mimic.py
"""Contains reusable classes relating to mimic."""

from __future__ import print_function

import json

from characteristic import Attribute, attributes

import treq

from twisted.internet.defer import inlineCallbacks, returnValue

from otter.integration.lib.utils import diagnose

from otter.util.http import check_success


@inlineCallbacks
def _sequenced_behaviors(test_case, pool, endpoint, criteria, behaviors,
                         _treq):
    """
    Cause an endpoint fail sometimes or all the time, with a pre-determined
    sequence of successes and/or failures.

    :param str endpoint: The endpoint for the mimic behavior to POST to
    :param pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :param list criteria: The criteria that the event should apply for the
        behavior to work
    :param list behaviors:  A list of dictionaries containing the names of
        behaviors parameters.
    :param _treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.

    :return: the ID of the created behavior
    :rtype: `str`
    """
    body = yield _treq.post(
        endpoint,
        json.dumps({
            "criteria": criteria,
            "name": "sequence",
            "parameters": {
                "behaviors": behaviors
            }
        }),
        pool=pool
    ).addCallback(check_success, [201]).addCallback(_treq.json_content)

    behavior_id = body['id']

    if test_case is not None:
        test_case.addCleanup(
            _delete_behavior, pool, endpoint, behavior_id, _treq)

    returnValue(behavior_id)


@diagnose("mimic", "Deleting behavior")
def _delete_behavior(pool, endpoint, behavior_id, _treq):
    """
    Given a behavior ID, delete it from mimic.

    :param str endpoint: The endpoint for the mimic behavior to POST to
    :param pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :param str behavior_id: The ID of the behavior to delete.
    :param _treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    d = _treq.delete("{0}/{1}".format(endpoint, behavior_id), pool=pool)
    d.addCallback(check_success, [204, 404])
    d.addCallback(_treq.content)
    return d


@attributes(["pool",
             Attribute("test_case", default_value=None),
             Attribute("treq", default_value=treq)])
class MimicNova(object):
    """
    Class that handles HTTP requests to the mimic nova control plane.

    Please see the mimic control plane API
    (:class:`mimic.rest.nova_api.NovaControlAPIRegion`) in the mimic
    codebase for more information.

    :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not
        None, will be used to clean up added behaviors.
    :ivar treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    @diagnose("mimic", "Changing a server's status")
    def change_server_statuses(self, rcs, ids_to_status):
        """
        Change the statuses of the given server IDs.  Changing the statuses of
        servers does not require any cleanup, because this is not creating a
        persistent behavior in mimic.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param dict ids_to_status: A mapping of server IDs to the string status
            to which they should be changed.  (see
            https://docs.rackspace.com/servers/api/v2/cs-devguide/content/
            List_Servers_Server_Statuses-d1e2078.html for a list of statuses)

        :return: A deferred that fires with the content of the response, which
            is probably the empty string.
        """
        return self.treq.post(
            "{0}/attributes".format(rcs.endpoints["mimic_nova"]),
            json.dumps({"status": ids_to_status}),
            pool=self.pool
        ).addCallback(check_success, [201]).addCallback(self.treq.content)

    @diagnose("mimic", "Injecting create server behavior")
    def sequenced_behaviors(self, rcs, criteria, behaviors,
                            event_description="creation"):
        """
        Cause Nova to fail sometimes or all the time, with a pre-determined
        sequence of successes and/or failures.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param list criteria: The criteria for the servers that should exhibit
            this behavior.  See, in mimic the control plane API,
            :func:`register_creation_behavior`, for more information.
        :param list behaviors:  A list of dictionaries containing the names of
            creation behaviors parameters.
            See, in the mimic codebase,
            :func:`mimic.model.nova_objects.sequence` for more information.
        :param str event_description: Which event this sequence of behaviors
            should apply to - the default event is server creation.

        :return: the ID of the created behavior
        :rtype: `str`
        """
        return _sequenced_behaviors(
            self.test_case, self.pool,
            "{0}/behaviors/{1}".format(rcs.endpoints['mimic_nova'],
                                       event_description),
            criteria, behaviors, self.treq)

    @diagnose("mimic", "Deleting create server behavior")
    def delete_behavior(self, rcs, behavior_id, event_description="creation"):
        """
        Given a behavior ID, delete it from mimic.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param str behavior_id: The ID of the behavior to delete.
        :param event_description: What type of event this is that should be
            deleted.
        """
        return _delete_behavior(
            self.pool, "{0}/behaviors/{1}".format(rcs.endpoints['mimic_nova'],
                                                  event_description),
            behavior_id, self.treq)


@attributes(["pool",
             Attribute("test_case", default_value=None),
             Attribute("treq", default_value=treq)])
class MimicIdentity(object):
    """
    Class that handles HTTP requests to the Mimic Identity control plane.

    Please see the Mimic generic control plane (:mod:`mimic.model.behaviors`)
    and specific auth failure behaviors (:class:`mimic.rest.auth_api`) in the
    mimic codebase for more information.

    :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not
        None, will be used to clean up added behaviors.
    :ivar treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    @diagnose("mimic", "Injecting auth behavior")
    def sequenced_behaviors(self, identity_endpoint, criteria, behaviors,
                            event_description="auth"):
        """
        Cause Identity to fail sometimes or all the time, with a pre-determined
        sequence of successes and/or failures.

        :param identity_endpoint: The endpoint with which to auth against
            identity - the mimic identity control endpoint is hardcoded, so
            this can tell us what the control endpoint is.
        :param list criteria: The criteria for the servers that should exhibit
            this behavior.  See, in mimic the control plane API,
            :func:`register_creation_behavior`, for more information.
        :param list behaviors:  A list of dictionaries containing the names of
            creation behaviors parameters.
            See, in the mimic codebase,
            :func:`mimic.model.nova_objects.sequence` for more information.
        :param str event_description: Which event this sequence of behaviors
            should apply to - the default event is authentication.

        :return: the ID of the created behavior
        :rtype: `str`
        """
        endpoint = identity_endpoint.replace(
            "/identity/v2.0",
            "/mimic/v1.1/IdentityControlAPI/behaviors/{0}".format(
                event_description))
        return _sequenced_behaviors(self.test_case, self.pool, endpoint,
                                    criteria, behaviors, self.treq)


@attributes(["pool",
             Attribute("test_case", default_value=None),
             Attribute("treq", default_value=treq)])
class MimicCLB(object):
    """
    Class that handles HTTP requests to the mimic Cloud Load Blancer
    control plane.

    Please see the mimic control plane API
    (:class:`mimic.rest.loadbalancer_api.LoadBalancerControlRegion`) in the
    mimic codebase for more information.

    :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to
        all treq requests
    :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not
        None, will be used to clean up added behaviors.
    :ivar treq: the treq module to use for making requests - if not provided,
        the default library :mod:`treq` will be used.  Mainly to be used for
        injecting stubs during tests.
    """
    @diagnose("mimic", "Setting CLB status")
    def set_clb_attributes(self, rcs, clb_id, kvpairs):
        """
        Update the attributes of a clould load balancer based on the provided
        key, value pairs.

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param clb_id: The ID of the load balancer to be altered
        :param dict kvpairs: A dictionary of key value pairs. The keys
        correspond to attributes in the load balancer details and the value is
        what the attribute will be replaced with.
        See the `mimic.model.RegionalCLBCollection.set_attribue` function
        for the supported attributes.
        :return: A deferred that fires with the content of the response, which
            is probably the empty string.
        """
        return self.treq.patch(
            "{0}/loadbalancer/{1}/attributes".format(
                rcs.endpoints["mimic_clb"], clb_id),
            json.dumps(kvpairs),
            pool=self.pool
        ).addCallback(check_success, [204]).addCallback(self.treq.content)

    @diagnose("mimic", "Updating CLB node status")
    def update_clb_node_status(self, rcs, clb_id, node_id, status):
        """
        Update CLB node's status field

        :param rcs: A :class:`otter.integration.lib.resources.TestResources`
            instance.
        :param int clb_id: The ID of the load balancer whose node's status
            is to be updated
        :param int node_id: ID of updating node
        :param str status: status to update. One of "ONLINE" or "OFFLINE"
        :return: A deferred that fires with the content of the response, which
            is probably the empty string.
        """
        return self.treq.put(
            "{0}/loadbalancers/{1}/nodes/{2}/status".format(
                rcs.endpoints["mimic_clb"], clb_id, node_id),
            json.dumps({"status": status}),
            pool=self.pool
        ).addCallback(check_success, [200]).addCallback(self.treq.content)

Contains reusable classes relating to mimic. Cause an endpoint fail sometimes or all the time, with a pre-determined     sequence of successes and/or failures.      :param str endpoint: The endpoint for the mimic behavior to POST to     :param pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to         all treq requests     :param list criteria: The criteria that the event should apply for the         behavior to work     :param list behaviors:  A list of dictionaries containing the names of         behaviors parameters.     :param _treq: the treq module to use for making requests - if not provided,         the default library :mod:`treq` will be used.  Mainly to be used for         injecting stubs during tests.      :return: the ID of the created behavior     :rtype: `str` Given a behavior ID, delete it from mimic.      :param str endpoint: The endpoint for the mimic behavior to POST to     :param pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to         all treq requests     :param str behavior_id: The ID of the behavior to delete.     :param _treq: the treq module to use for making requests - if not provided,         the default library :mod:`treq` will be used.  Mainly to be used for         injecting stubs during tests. Class that handles HTTP requests to the mimic nova control plane.      Please see the mimic control plane API     (:class:`mimic.rest.nova_api.NovaControlAPIRegion`) in the mimic     codebase for more information.      :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to         all treq requests     :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not         None, will be used to clean up added behaviors.     :ivar treq: the treq module to use for making requests - if not provided,         the default library :mod:`treq` will be used.  Mainly to be used for         injecting stubs during tests. Change the statuses of the given server IDs.  Changing the statuses of         servers does not require any cleanup, because this is not creating a         persistent behavior in mimic.          :param rcs: A :class:`otter.integration.lib.resources.TestResources`             instance.         :param dict ids_to_status: A mapping of server IDs to the string status             to which they should be changed.  (see             https://docs.rackspace.com/servers/api/v2/cs-devguide/content/             List_Servers_Server_Statuses-d1e2078.html for a list of statuses)          :return: A deferred that fires with the content of the response, which             is probably the empty string. Cause Nova to fail sometimes or all the time, with a pre-determined         sequence of successes and/or failures.          :param rcs: A :class:`otter.integration.lib.resources.TestResources`             instance.         :param list criteria: The criteria for the servers that should exhibit             this behavior.  See, in mimic the control plane API,             :func:`register_creation_behavior`, for more information.         :param list behaviors:  A list of dictionaries containing the names of             creation behaviors parameters.             See, in the mimic codebase,             :func:`mimic.model.nova_objects.sequence` for more information.         :param str event_description: Which event this sequence of behaviors             should apply to - the default event is server creation.          :return: the ID of the created behavior         :rtype: `str` Given a behavior ID, delete it from mimic.          :param rcs: A :class:`otter.integration.lib.resources.TestResources`             instance.         :param str behavior_id: The ID of the behavior to delete.         :param event_description: What type of event this is that should be             deleted. Class that handles HTTP requests to the Mimic Identity control plane.      Please see the Mimic generic control plane (:mod:`mimic.model.behaviors`)     and specific auth failure behaviors (:class:`mimic.rest.auth_api`) in the     mimic codebase for more information.      :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to         all treq requests     :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not         None, will be used to clean up added behaviors.     :ivar treq: the treq module to use for making requests - if not provided,         the default library :mod:`treq` will be used.  Mainly to be used for         injecting stubs during tests. Cause Identity to fail sometimes or all the time, with a pre-determined         sequence of successes and/or failures.          :param identity_endpoint: The endpoint with which to auth against             identity - the mimic identity control endpoint is hardcoded, so             this can tell us what the control endpoint is.         :param list criteria: The criteria for the servers that should exhibit             this behavior.  See, in mimic the control plane API,             :func:`register_creation_behavior`, for more information.         :param list behaviors:  A list of dictionaries containing the names of             creation behaviors parameters.             See, in the mimic codebase,             :func:`mimic.model.nova_objects.sequence` for more information.         :param str event_description: Which event this sequence of behaviors             should apply to - the default event is authentication.          :return: the ID of the created behavior         :rtype: `str` Class that handles HTTP requests to the mimic Cloud Load Blancer     control plane.      Please see the mimic control plane API     (:class:`mimic.rest.loadbalancer_api.LoadBalancerControlRegion`) in the     mimic codebase for more information.      :ivar pool: a :class:`twisted.web.client.HTTPConnectionPool` to pass to         all treq requests     :ivar test_case: a :class:`twisted.trial.unittest.TestCase`, which if not         None, will be used to clean up added behaviors.     :ivar treq: the treq module to use for making requests - if not provided,         the default library :mod:`treq` will be used.  Mainly to be used for         injecting stubs during tests. Update the attributes of a clould load balancer based on the provided         key, value pairs.          :param rcs: A :class:`otter.integration.lib.resources.TestResources`             instance.         :param clb_id: The ID of the load balancer to be altered         :param dict kvpairs: A dictionary of key value pairs. The keys         correspond to attributes in the load balancer details and the value is         what the attribute will be replaced with.         See the `mimic.model.RegionalCLBCollection.set_attribue` function         for the supported attributes.         :return: A deferred that fires with the content of the response, which             is probably the empty string. Update CLB node's status field          :param rcs: A :class:`otter.integration.lib.resources.TestResources`             instance.         :param int clb_id: The ID of the load balancer whose node's status             is to be updated         :param int node_id: ID of updating node         :param str status: status to update. One of "ONLINE" or "OFFLINE"         :return: A deferred that fires with the content of the response, which             is probably the empty string.