Beispiel #1
0
    def test_unbind_agent_not_notified(self):

        # Setup
        self.populate()
        manager = factory.consumer_bind_manager()
        bind = manager.bind(self.CONSUMER_ID, self.REPO_ID, self.DISTRIBUTOR_ID,
                            False, self.BINDING_CONFIG)

        # Test
        options = {}
        itinerary = unbind_itinerary(
            self.CONSUMER_ID,
            self.REPO_ID,
            self.DISTRIBUTOR_ID,
            options)

        call_reports = self.coordinator.execute_multiple_calls(itinerary)

        # Verify
        self.assertEqual(len(call_reports), 1)
        self.assertEqual(call_reports[0].call_request_tags, self.UNBIND_TAGS)
        for call in call_reports:
            self.assertNotEqual(call.state, dispatch_constants.CALL_REJECTED_RESPONSE)

        # run task #1 (actual delete)
        self.run_next()

        # verify bind deleted
        collection = Bind.get_collection()
        bind = collection.find_one(self.QUERY)
        self.assertTrue(bind is None)

        # verify agent notified
        self.assertFalse(mock_agent.Consumer.unbind.called)
Beispiel #2
0
 def DELETE(self, consumer_id, repo_id, distributor_id):
     """
     Delete a bind association between the specified
     consumer and repo-distributor.  Designed to be idempotent.
     @param consumer_id: A consumer ID.
     @type consumer_id: str
     @param repo_id: A repo ID.
     @type repo_id: str
     @param distributor_id: A distributor ID.
     @type distributor_id: str
     @return: The list of call_reports
     @rtype: list
     """
     body = self.params()
     # validate resources
     manager = managers.consumer_bind_manager()
     binding = manager.get_bind(consumer_id, repo_id, distributor_id)
     notify_agent = binding['notify_agent']
     # delete (unbind)
     forced = body.get('force', False)
     options = body.get('options', {})
     if forced or not notify_agent:
         call_requests = forced_unbind_itinerary(consumer_id, repo_id,
                                                 distributor_id, options)
     else:
         call_requests = unbind_itinerary(consumer_id, repo_id,
                                          distributor_id, options)
     execution.execute_multiple(call_requests)
Beispiel #3
0
 def DELETE(self, consumer_id, repo_id, distributor_id):
     """
     Delete a bind association between the specified
     consumer and repo-distributor.  Designed to be idempotent.
     @param consumer_id: A consumer ID.
     @type consumer_id: str
     @param repo_id: A repo ID.
     @type repo_id: str
     @param distributor_id: A distributor ID.
     @type distributor_id: str
     @return: The list of call_reports
     @rtype: list
     """
     body = self.params()
     # validate resources
     manager = managers.consumer_bind_manager()
     binding = manager.get_bind(consumer_id, repo_id, distributor_id)
     notify_agent = binding['notify_agent']
     # delete (unbind)
     forced = body.get('force', False)
     options = body.get('options', {})
     if forced or not notify_agent:
         call_requests = forced_unbind_itinerary(
             consumer_id,
             repo_id,
             distributor_id,
             options)
     else:
         call_requests = unbind_itinerary(
             consumer_id,
             repo_id,
             distributor_id,
             options)
     execution.execute_multiple(call_requests)
Beispiel #4
0
def repo_delete_itinerary(repo_id):
    """
    Get the itinerary for deleting a repository.
      1. Delete the repository on the sever.
      2. Unbind any bound consumers.
    @param repo_id: A repository ID.
    @type repo_id: str
    @return: A list of call_requests known as an itinerary.
    @rtype list
    """

    call_requests = []

    # delete repository

    manager = managers.repo_manager()
    resources = {dispatch_constants.RESOURCE_REPOSITORY_TYPE: {repo_id: dispatch_constants.RESOURCE_DELETE_OPERATION}}

    tags = [resource_tag(dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id), action_tag("delete")]

    delete_request = CallRequest(manager.delete_repo, [repo_id], resources=resources, tags=tags, archive=True)

    call_requests.append(delete_request)

    # append unbind itineraries foreach bound consumer

    options = {}
    manager = managers.consumer_bind_manager()
    for bind in manager.find_by_repo(repo_id):
        unbind_requests = unbind_itinerary(bind["consumer_id"], bind["repo_id"], bind["distributor_id"], options)
        if unbind_requests:
            unbind_requests[0].depends_on(delete_request.id)
            call_requests.extend(unbind_requests)

    return call_requests
Beispiel #5
0
def distributor_delete_itinerary(repo_id, distributor_id):
    """
    Get the itinerary for deleting a repository distributor.
      1. Delete the distributor on the sever.
      2. Unbind any bound consumers.
    @param repo_id: A repository ID.
    @type repo_id: str
    @return: A list of call_requests known as an itinerary.
    @rtype list
    """

    call_requests = []

    # delete distributor

    manager = managers.repo_distributor_manager()
    resources = {
        dispatch_constants.RESOURCE_REPOSITORY_TYPE: {
            repo_id: dispatch_constants.RESOURCE_UPDATE_OPERATION
        },
        dispatch_constants.RESOURCE_REPOSITORY_DISTRIBUTOR_TYPE: {
            distributor_id: dispatch_constants.RESOURCE_DELETE_OPERATION
        }
    }

    tags = [
        resource_tag(dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id),
        resource_tag(dispatch_constants.RESOURCE_REPOSITORY_DISTRIBUTOR_TYPE,
                     distributor_id),
        action_tag('remove_distributor')
    ]

    delete_request = CallRequest(manager.remove_distributor,
                                 [repo_id, distributor_id],
                                 resources=resources,
                                 tags=tags,
                                 archive=True)

    call_requests.append(delete_request)

    # append unbind itineraries foreach bound consumer

    options = {}
    manager = managers.consumer_bind_manager()
    for bind in manager.find_by_distributor(repo_id, distributor_id):
        unbind_requests = unbind_itinerary(bind['consumer_id'],
                                           bind['repo_id'],
                                           bind['distributor_id'], options)
        if unbind_requests:
            unbind_requests[0].depends_on(delete_request.id)
            call_requests.extend(unbind_requests)

    return call_requests
Beispiel #6
0
def distributor_delete_itinerary(repo_id, distributor_id):
    """
    Get the itinerary for deleting a repository distributor.
      1. Delete the distributor on the sever.
      2. Unbind any bound consumers.
    @param repo_id: A repository ID.
    @type repo_id: str
    @return: A list of call_requests known as an itinerary.
    @rtype list
    """

    call_requests = []

    # delete distributor

    manager = managers.repo_distributor_manager()

    tags = [
        resource_tag(dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id),
        resource_tag(dispatch_constants.RESOURCE_REPOSITORY_DISTRIBUTOR_TYPE, distributor_id),
        action_tag('remove_distributor')
    ]

    delete_request = CallRequest(
        manager.remove_distributor,
        [repo_id, distributor_id],
        tags=tags,
        archive=True)

    delete_request.updates_resource(dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id)
    delete_request.deletes_resource(dispatch_constants.RESOURCE_REPOSITORY_DISTRIBUTOR_TYPE, distributor_id)

    call_requests.append(delete_request)

    # append unbind itineraries foreach bound consumer

    options = {}
    manager = managers.consumer_bind_manager()
    for bind in manager.find_by_distributor(repo_id, distributor_id):
        unbind_requests = unbind_itinerary(
            bind['consumer_id'],
            bind['repo_id'],
            bind['distributor_id'],
            options)
        if unbind_requests:
            unbind_requests[0].depends_on(delete_request.id)
            call_requests.extend(unbind_requests)

    return call_requests
Beispiel #7
0
    def test_unbind_failed(self, mock_bind):

        # Setup
        self.populate()
        manager = factory.consumer_bind_manager()

        manager.bind(self.CONSUMER_ID, self.REPO_ID, self.DISTRIBUTOR_ID,
                     self.NOTIFY_AGENT, self.BINDING_CONFIG)

        # Test
        options = {}
        itinerary = unbind_itinerary(
            self.CONSUMER_ID,
            self.REPO_ID,
            self.DISTRIBUTOR_ID,
            options)
        call_reports = self.coordinator.execute_multiple_calls(itinerary)

        # Verify
        self.assertEqual(len(call_reports), 3)
        for call in call_reports:
            self.assertNotEqual(call.state, dispatch_constants.CALL_REJECTED_RESPONSE)

        # run task #1 (actual bind)
        self.run_next()

        # run task #2 (notify consumer)
        self.run_next()

        # verify task #2 skipped
        request_id = call_reports[1].call_request_id
        call_report = self.coordinator.find_call_reports(call_request_id=request_id)[0]
        self.assertEqual(call_report.state, dispatch_constants.CALL_SKIPPED_STATE)

        # verify agent NOT notified
        self.assertFalse(mock_agent.Consumer.bind.called)

        # run task #3 (delete bind)
        self.run_next()

        # verify task #3 was skipped
        request_id = call_reports[2].call_request_id
        call_report = self.coordinator.find_call_reports(call_request_id=request_id)[0]
        self.assertEqual(call_report.state, dispatch_constants.CALL_SKIPPED_STATE)

        # verify bind still exists
        bind = manager.get_bind(self.CONSUMER_ID, self.REPO_ID, self.DISTRIBUTOR_ID)
        self.assertTrue(bind is not None)
Beispiel #8
0
    def test_unbind_failed(self, mock_bind):

        # Setup
        self.populate()
        manager = factory.consumer_bind_manager()

        manager.bind(self.CONSUMER_ID, self.REPO_ID, self.DISTRIBUTOR_ID,
                     self.NOTIFY_AGENT, self.BINDING_CONFIG)

        # Test
        options = {}
        itinerary = unbind_itinerary(
            self.CONSUMER_ID,
            self.REPO_ID,
            self.DISTRIBUTOR_ID,
            options)
        call_reports = self.coordinator.execute_multiple_calls(itinerary)

        # Verify
        self.assertEqual(len(call_reports), 3)
        for call in call_reports:
            self.assertNotEqual(call.state, dispatch_constants.CALL_REJECTED_RESPONSE)

        # run task #1 (actual bind)
        self.run_next()

        # run task #2 (notify consumer)
        self.run_next()

        # verify task #2 skipped
        request_id = call_reports[1].call_request_id
        call_report = self.coordinator.find_call_reports(call_request_id=request_id)[0]
        self.assertEqual(call_report.state, dispatch_constants.CALL_SKIPPED_STATE)

        # verify agent NOT notified
        self.assertFalse(mock_agent.Consumer.bind.called)

        # run task #3 (delete bind)
        self.run_next()

        # verify task #3 was skipped
        request_id = call_reports[2].call_request_id
        call_report = self.coordinator.find_call_reports(call_request_id=request_id)[0]
        self.assertEqual(call_report.state, dispatch_constants.CALL_SKIPPED_STATE)

        # verify bind still exists
        bind = manager.get_bind(self.CONSUMER_ID, self.REPO_ID, self.DISTRIBUTOR_ID)
        self.assertTrue(bind is not None)
Beispiel #9
0
def consumer_group_unbind_itinerary(group_id, repo_id, distributor_id, options):
    """
    Unbind the members of the specified consumer group.
    :param group_id: A consumer group ID.
    :type group_id: str
    :param repo_id: A repository ID.
    :type repo_id: str
    :param distributor_id: A distributor ID.
    :type distributor_id: str
    :param options: Bind options passed to the agent handler.
    :type options: dict
    :return: A list of call_requests.
    :rtype list
    """
    call_requests = []
    manager = managers.consumer_group_query_manager()
    group = manager.get_group(group_id)
    for consumer_id in group["consumer_ids"]:
        itinerary = unbind_itinerary(consumer_id, repo_id, distributor_id, options)
        call_requests.extend(itinerary)
    return call_requests
Beispiel #10
0
def consumer_group_unbind_itinerary(group_id, repo_id, distributor_id,
                                    options):
    """
    Unbind the members of the specified consumer group.
    :param group_id: A consumer group ID.
    :type group_id: str
    :param repo_id: A repository ID.
    :type repo_id: str
    :param distributor_id: A distributor ID.
    :type distributor_id: str
    :param options: Bind options passed to the agent handler.
    :type options: dict
    :return: A list of call_requests.
    :rtype list
    """
    call_requests = []
    manager = managers.consumer_group_query_manager()
    group = manager.get_group(group_id)
    for consumer_id in group['consumer_ids']:
        itinerary = unbind_itinerary(consumer_id, repo_id, distributor_id,
                                     options)
        call_requests.extend(itinerary)
    return call_requests
Beispiel #11
0
    def test_unbind_failed_on_consumer(self):

        # Setup
        self.populate()
        manager = factory.consumer_bind_manager()
        bind = manager.bind(self.CONSUMER_ID, self.REPO_ID, self.DISTRIBUTOR_ID,
                            self.NOTIFY_AGENT, self.BINDING_CONFIG)

        # Test
        options = {}
        itinerary = unbind_itinerary(
            self.CONSUMER_ID,
            self.REPO_ID,
            self.DISTRIBUTOR_ID,
            options)
        call_reports = self.coordinator.execute_multiple_calls(itinerary)

        # Verify
        self.assertEqual(len(call_reports), 3)
        for call in call_reports:
            self.assertNotEqual(call.state, dispatch_constants.CALL_REJECTED_RESPONSE)

        # run task #1 (actual unbind)
        self.run_next()

        # verify bind marked deleted
        collection = Bind.get_collection()
        bind = collection.find_one(self.QUERY)
        self.assertTrue(bind['deleted'])

        # run task #2 (notify consumer)
        self.run_next()

        # verify agent notified
        self.assertTrue(mock_agent.Consumer.unbind.called)

        # verify consumer request (pending)
        request_id = call_reports[1].call_request_id
        collection = Bind.get_collection()
        bind = collection.find_one(self.QUERY)
        self.assertTrue(bind is not None)
        actions = bind['consumer_actions']
        self.assertEqual(len(actions), 1)
        self.assertEqual(actions[0]['id'], request_id)
        self.assertEqual(actions[0]['action'], Bind.Action.UNBIND)
        self.assertEqual(actions[0]['status'], Bind.Status.PENDING)
        self.assertTrue(isinstance(actions[0]['timestamp'], float))

        # simulated asynchronous task result
        report = DispatchReport()
        report.succeeded = False
        self.coordinator.complete_call_success(request_id, report.dict())

        # verify not found (marked deleted)
        binds = manager.find_by_consumer(self.CONSUMER_ID)
        self.assertEquals(len(binds), 0)

        # run task #3 (bind actually deleted)
        self.run_next()

        # verify bind not deleted
        collection = Bind.get_collection()
        bind = collection.find_one(self.QUERY)
        self.assertTrue(bind is not None)
        actions = bind['consumer_actions']
        self.assertEqual(len(actions), 1)
        self.assertEqual(actions[0]['id'], request_id)
        self.assertEqual(actions[0]['action'], Bind.Action.UNBIND)
        self.assertEqual(actions[0]['status'], Bind.Status.FAILED)
        self.assertTrue(isinstance(actions[0]['timestamp'], float))
Beispiel #12
0
    def test_unbind_failed_on_consumer(self):

        # Setup
        self.populate()
        manager = factory.consumer_bind_manager()
        bind = manager.bind(self.CONSUMER_ID, self.REPO_ID, self.DISTRIBUTOR_ID,
                            self.NOTIFY_AGENT, self.BINDING_CONFIG)

        # Test
        options = {}
        itinerary = unbind_itinerary(
            self.CONSUMER_ID,
            self.REPO_ID,
            self.DISTRIBUTOR_ID,
            options)
        call_reports = self.coordinator.execute_multiple_calls(itinerary)

        # Verify
        self.assertEqual(len(call_reports), 3)
        for call in call_reports:
            self.assertNotEqual(call.state, dispatch_constants.CALL_REJECTED_RESPONSE)

        # run task #1 (actual unbind)
        self.run_next()

        # verify bind marked deleted
        collection = Bind.get_collection()
        bind = collection.find_one(self.QUERY)
        self.assertTrue(bind['deleted'])

        # run task #2 (notify consumer)
        self.run_next()

        # verify agent notified
        self.assertTrue(mock_agent.Consumer.unbind.called)

        # verify consumer request (pending)
        request_id = call_reports[1].call_request_id
        collection = Bind.get_collection()
        bind = collection.find_one(self.QUERY)
        self.assertTrue(bind is not None)
        actions = bind['consumer_actions']
        self.assertEqual(len(actions), 1)
        self.assertEqual(actions[0]['id'], request_id)
        self.assertEqual(actions[0]['action'], Bind.Action.UNBIND)
        self.assertEqual(actions[0]['status'], Bind.Status.PENDING)
        self.assertTrue(isinstance(actions[0]['timestamp'], float))

        # simulated asynchronous task result
        report = DispatchReport()
        report.succeeded = False
        self.coordinator.complete_call_success(request_id, report.dict())

        # verify not found (marked deleted)
        binds = manager.find_by_consumer(self.CONSUMER_ID)
        self.assertEquals(len(binds), 0)

        # run task #3 (bind actually deleted)
        self.run_next()

        # verify bind not deleted
        collection = Bind.get_collection()
        bind = collection.find_one(self.QUERY)
        self.assertTrue(bind is not None)
        actions = bind['consumer_actions']
        self.assertEqual(len(actions), 1)
        self.assertEqual(actions[0]['id'], request_id)
        self.assertEqual(actions[0]['action'], Bind.Action.UNBIND)
        self.assertEqual(actions[0]['status'], Bind.Status.FAILED)
        self.assertTrue(isinstance(actions[0]['timestamp'], float))