Exemplo n.º 1
0
def main():
    fields = dict(
        operation=dict(type='str', required=True),
        data=dict(type='dict'),
        query_params=dict(type='dict'),
        path_params=dict(type='dict'),
        register_as=dict(type='str'),
        filters=dict(type='dict')
    )
    module = AnsibleModule(argument_spec=fields,
                           supports_check_mode=True)
    params = module.params

    connection = Connection(module._socket_path)
    resource = BaseConfigurationResource(connection, module.check_mode)
    op_name = params['operation']
    try:
        resp = resource.execute_operation(op_name, params)
        module.exit_json(changed=resource.config_changed, response=resp,
                         ansible_facts=construct_ansible_facts(resp, module.params))
    except FtdInvalidOperationNameError as e:
        module.fail_json(msg='Invalid operation name provided: %s' % e.operation_name)
    except FtdConfigurationError as e:
        module.fail_json(msg='Failed to execute %s operation because of the configuration error: %s' % (op_name, e.msg))
    except FtdServerError as e:
        module.fail_json(msg='Server returned an error trying to execute %s operation. Status code: %s. '
                             'Server response: %s' % (op_name, e.code, e.response))
    except FtdUnexpectedResponse as e:
        module.fail_json(msg=e.args[0])
    except ValidationError as e:
        module.fail_json(msg=e.args[0])
    except CheckModeException:
        module.exit_json(changed=False)
Exemplo n.º 2
0
    def _resource_execute_operation(params, connection):
        resource = BaseConfigurationResource(connection)
        op_name = params['operation']

        resp = resource.execute_operation(op_name, params)

        return resp
 def setUp(self, fetch_system_info_mock):
     self._conn = mock.MagicMock()
     self._resource = BaseConfigurationResource(self._conn)
     fetch_system_info_mock.return_value = {
         'databaseInfo': {
             'buildVersion': '6.3.0'
         }
     }
    def _resource_execute_operation(params, connection):

        with mock.patch.object(BaseConfigurationResource, '_fetch_system_info') as fetch_system_info_mock:
            fetch_system_info_mock.return_value = {
                'databaseInfo': {
                    'buildVersion': '6.3.0'
                }
            }
            resource = BaseConfigurationResource(connection)
            op_name = params['operation']

            resp = resource.execute_operation(op_name, params)

        return resp
Exemplo n.º 5
0
def main():
    fields = dict(device_hostname=dict(type='str', required=True),
                  device_username=dict(type='str',
                                       required=False,
                                       default='admin'),
                  device_password=dict(type='str', required=True, no_log=True),
                  device_sudo_password=dict(type='str',
                                            required=False,
                                            no_log=True),
                  device_new_password=dict(type='str',
                                           required=False,
                                           no_log=True),
                  device_ip=dict(type='str', required=False),
                  device_netmask=dict(type='str', required=False),
                  device_gateway=dict(type='str', required=False),
                  device_model=dict(type='str',
                                    required=False,
                                    choices=[e.value for e in FtdModel]),
                  dns_server=dict(type='str', required=False),
                  search_domains=dict(type='str',
                                      required=False,
                                      default='cisco.com'),
                  console_ip=dict(type='str', required=True),
                  console_port=dict(type='str', required=True),
                  console_username=dict(type='str', required=True),
                  console_password=dict(type='str', required=True,
                                        no_log=True),
                  rommon_file_location=dict(type='str', required=True),
                  image_file_location=dict(type='str', required=True),
                  image_version=dict(type='str', required=True),
                  force_reinstall=dict(type='bool',
                                       required=False,
                                       default=False))
    module = AnsibleModule(argument_spec=fields)
    if not HAS_KICK:
        module.fail_json(
            msg='Kick Python module is required to run this module. '
            'Please, install it with `pip install firepower-kickstart` '
            'command and run the playbook again.')

    use_local_connection = module._socket_path is None
    if use_local_connection:
        check_required_params_for_local_connection(module, module.params)
        platform_model = module.params['device_model']
        check_that_model_is_supported(module, platform_model)
    else:
        connection = Connection(module._socket_path)
        resource = BaseConfigurationResource(connection, module.check_mode)
        system_info = get_system_info(resource)

        platform_model = module.params['device_model'] or system_info[
            'platformModel']
        check_that_model_is_supported(module, platform_model)
        check_that_update_is_needed(module, system_info)
        check_management_and_dns_params(resource, module.params)

    ftd_platform = FtdPlatformFactory.create(platform_model, module.params)
    ftd_platform.install_ftd_image(module.params)

    module.exit_json(
        changed=True,
        msg='Successfully installed FTD image %s on the firewall device.' %
        module.params["image_version"])
class TestUpsertOperationUnitTests(unittest.TestCase):
    @mock.patch.object(BaseConfigurationResource, '_fetch_system_info')
    def setUp(self, fetch_system_info_mock):
        self._conn = mock.MagicMock()
        self._resource = BaseConfigurationResource(self._conn)
        fetch_system_info_mock.return_value = {
            'databaseInfo': {
                'buildVersion': '6.3.0'
            }
        }

    def test_get_operation_name(self):
        operation_a = mock.MagicMock()
        operation_b = mock.MagicMock()

        def checker_wrapper(expected_object):
            def checker(obj, *args, **kwargs):
                return obj == expected_object

            return checker

        operations = {
            operation_a: "spec",
            operation_b: "spec"
        }

        assert operation_a == self._resource._get_operation_name(checker_wrapper(operation_a), operations)
        assert operation_b == self._resource._get_operation_name(checker_wrapper(operation_b), operations)
        assert self._resource._get_operation_name(checker_wrapper(None), operations) is None

    @mock.patch.object(BaseConfigurationResource, "_get_operation_name")
    @mock.patch.object(BaseConfigurationResource, "add_object")
    def test_add_upserted_object(self, add_object_mock, get_operation_mock):
        model_operations = mock.MagicMock()
        params = mock.MagicMock()
        add_op_name = get_operation_mock.return_value

        assert add_object_mock.return_value == self._resource._add_upserted_object(model_operations, params)

        get_operation_mock.assert_called_once_with(
            self._resource._operation_checker.is_add_operation,
            model_operations)
        add_object_mock.assert_called_once_with(add_op_name, params)

    @mock.patch.object(BaseConfigurationResource, "_get_operation_name")
    @mock.patch.object(BaseConfigurationResource, "add_object")
    def test_add_upserted_object_with_no_add_operation(self, add_object_mock, get_operation_mock):
        model_operations = mock.MagicMock()
        get_operation_mock.return_value = None

        with pytest.raises(FtdConfigurationError) as exc_info:
            self._resource._add_upserted_object(model_operations, mock.MagicMock())
        assert ADD_OPERATION_NOT_SUPPORTED_ERROR in str(exc_info.value)

        get_operation_mock.assert_called_once_with(self._resource._operation_checker.is_add_operation, model_operations)
        add_object_mock.assert_not_called()

    @mock.patch.object(BaseConfigurationResource, "_get_operation_name")
    @mock.patch.object(BaseConfigurationResource, "edit_object")
    @mock.patch("module_utils.configuration.copy_identity_properties")
    @mock.patch("module_utils.configuration._set_default")
    def test_edit_upserted_object(self, _set_default_mock, copy_properties_mock, edit_object_mock, get_operation_mock):
        model_operations = mock.MagicMock()
        existing_object = mock.MagicMock()
        params = {
            'path_params': {},
            'data': {}
        }

        result = self._resource._edit_upserted_object(model_operations, existing_object, params)

        assert result == edit_object_mock.return_value

        _set_default_mock.assert_has_calls([
            mock.call(params, 'path_params', {}),
            mock.call(params, 'data', {})
        ])
        get_operation_mock.assert_called_once_with(
            self._resource._operation_checker.is_edit_operation,
            model_operations
        )
        copy_properties_mock.assert_called_once_with(
            existing_object,
            params['data']
        )
        edit_object_mock.assert_called_once_with(
            get_operation_mock.return_value,
            params
        )

    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    def test_upsert_object_successfully_added(self, edit_mock, add_mock, find_object, get_operation_mock,
                                              is_upsert_supported_mock):
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = True
        find_object.return_value = None

        result = self._resource.upsert_object('upsertFoo', params)

        assert result == add_mock.return_value
        self._conn.get_model_spec.assert_called_once_with('Foo')
        is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value)
        get_operation_mock.assert_called_once_with('Foo')
        find_object.assert_called_once_with('Foo', params)
        add_mock.assert_called_once_with(get_operation_mock.return_value, params)
        edit_mock.assert_not_called()

    @mock.patch("module_utils.configuration.equal_objects")
    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    def test_upsert_object_successfully_edited(self, edit_mock, add_mock, find_object, get_operation_mock,
                                               is_upsert_supported_mock, equal_objects_mock):
        params = mock.MagicMock()
        existing_obj = mock.MagicMock()

        is_upsert_supported_mock.return_value = True
        find_object.return_value = existing_obj
        equal_objects_mock.return_value = False

        result = self._resource.upsert_object('upsertFoo', params)

        assert result == edit_mock.return_value
        self._conn.get_model_spec.assert_called_once_with('Foo')
        get_operation_mock.assert_called_once_with('Foo')
        is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value)
        add_mock.assert_not_called()
        equal_objects_mock.assert_called_once_with(existing_obj, params[ParamName.DATA])
        edit_mock.assert_called_once_with(get_operation_mock.return_value, existing_obj, params)

    @mock.patch("module_utils.configuration.equal_objects")
    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    def test_upsert_object_returned_without_modifications(self, edit_mock, add_mock, find_object, get_operation_mock,
                                                          is_upsert_supported_mock, equal_objects_mock):
        params = mock.MagicMock()
        existing_obj = mock.MagicMock()

        is_upsert_supported_mock.return_value = True
        find_object.return_value = existing_obj
        equal_objects_mock.return_value = True

        result = self._resource.upsert_object('upsertFoo', params)

        assert result == existing_obj
        self._conn.get_model_spec.assert_called_once_with('Foo')
        get_operation_mock.assert_called_once_with('Foo')
        is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value)
        add_mock.assert_not_called()
        equal_objects_mock.assert_called_once_with(existing_obj, params[ParamName.DATA])
        edit_mock.assert_not_called()

    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    def test_upsert_object_not_supported(self, edit_mock, add_mock, find_object, get_operation_mock,
                                         is_upsert_supported_mock):
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = False

        self.assertRaises(
            FtdInvalidOperationNameError,
            self._resource.upsert_object, 'upsertFoo', params
        )

        self._conn.get_model_spec.assert_called_once_with('Foo')
        get_operation_mock.assert_called_once_with('Foo')
        is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value)
        find_object.assert_not_called()
        add_mock.assert_not_called()
        edit_mock.assert_not_called()

    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    def test_upsert_object_when_model_not_supported(self, edit_mock, add_mock, find_object, get_operation_mock,
                                                    is_upsert_supported_mock):
        params = mock.MagicMock()
        self._conn.get_model_spec.return_value = None

        self.assertRaises(
            FtdInvalidOperationNameError,
            self._resource.upsert_object, 'upsertNonExisting', params
        )

        self._conn.get_model_spec.assert_called_once_with('NonExisting')
        get_operation_mock.assert_not_called()
        is_upsert_supported_mock.assert_not_called()
        find_object.assert_not_called()
        add_mock.assert_not_called()
        edit_mock.assert_not_called()

    @mock.patch("module_utils.configuration.equal_objects")
    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    def test_upsert_object_with_fatal_error_during_edit(self, edit_mock, add_mock, find_object, get_operation_mock,
                                                        is_upsert_supported_mock, equal_objects_mock):
        params = mock.MagicMock()
        existing_obj = mock.MagicMock()

        is_upsert_supported_mock.return_value = True
        find_object.return_value = existing_obj
        equal_objects_mock.return_value = False
        edit_mock.side_effect = FtdConfigurationError("Some object edit error")

        self.assertRaises(
            FtdConfigurationError,
            self._resource.upsert_object, 'upsertFoo', params
        )

        is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value)
        self._conn.get_model_spec.assert_called_once_with('Foo')
        get_operation_mock.assert_called_once_with('Foo')
        find_object.assert_called_once_with('Foo', params)
        add_mock.assert_not_called()
        edit_mock.assert_called_once_with(get_operation_mock.return_value, existing_obj, params)

    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_find_object_matching_params")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    def test_upsert_object_with_fatal_error_during_add(self, edit_mock, add_mock, find_object, get_operation_mock,
                                                       is_upsert_supported_mock):
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = True
        find_object.return_value = None

        error = FtdConfigurationError("Obj duplication error")
        add_mock.side_effect = error

        self.assertRaises(
            FtdConfigurationError,
            self._resource.upsert_object, 'upsertFoo', params
        )

        is_upsert_supported_mock.assert_called_once_with(get_operation_mock.return_value)
        self._conn.get_model_spec.assert_called_once_with('Foo')
        get_operation_mock.assert_called_once_with('Foo')
        find_object.assert_called_once_with('Foo', params)
        add_mock.assert_called_once_with(get_operation_mock.return_value, params)
        edit_mock.assert_not_called()
Exemplo n.º 7
0
 def setUp(self):
     conn = mock.MagicMock()
     self._resource = BaseConfigurationResource(conn)
Exemplo n.º 8
0
class TestUpsertOperationUnitTests(unittest.TestCase):
    def setUp(self):
        conn = mock.MagicMock()
        self._resource = BaseConfigurationResource(conn)

    def test_get_operation_name(self):
        operation_a = mock.MagicMock()
        operation_b = mock.MagicMock()

        def checker_wrapper(expected_object):
            def checker(obj, *args, **kwargs):
                return obj == expected_object

            return checker

        operations = {
            operation_a: "spec",
            operation_b: "spec"
        }

        assert operation_a == self._resource._get_operation_name(checker_wrapper(operation_a), operations)
        assert operation_b == self._resource._get_operation_name(checker_wrapper(operation_b), operations)

        self.assertRaises(
            FtdConfigurationError,
            self._resource._get_operation_name, checker_wrapper(None), operations
        )

    @mock.patch.object(BaseConfigurationResource, "_get_operation_name")
    @mock.patch.object(BaseConfigurationResource, "add_object")
    def test_add_upserted_object(self, add_object_mock, get_operation_mock):
        model_operations = mock.MagicMock()
        params = mock.MagicMock()
        add_op_name = get_operation_mock.return_value

        assert add_object_mock.return_value == self._resource._add_upserted_object(model_operations, params)

        get_operation_mock.assert_called_once_with(
            self._resource._operation_checker.is_add_operation,
            model_operations)
        add_object_mock.assert_called_once_with(add_op_name, params)

    @mock.patch.object(BaseConfigurationResource, "_get_operation_name")
    @mock.patch.object(BaseConfigurationResource, "edit_object")
    @mock.patch("module_utils.configuration.copy_identity_properties")
    @mock.patch("module_utils.configuration._set_default")
    def test_edit_upserted_object(self, _set_default_mock, copy_properties_mock, edit_object_mock, get_operation_mock):
        model_operations = mock.MagicMock()
        existing_object = mock.MagicMock()
        params = {
            'path_params': {},
            'data': {}
        }

        result = self._resource._edit_upserted_object(model_operations, existing_object, params)

        assert result == edit_object_mock.return_value

        _set_default_mock.assert_has_calls([
            mock.call(params, 'path_params', {}),
            mock.call(params, 'data', {})
        ])
        get_operation_mock.assert_called_once_with(
            self._resource._operation_checker.is_edit_operation,
            model_operations
        )
        copy_properties_mock.assert_called_once_with(
            existing_object,
            params['data']
        )
        edit_object_mock.assert_called_once_with(
            get_operation_mock.return_value,
            params
        )

    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch("module_utils.configuration.OperationChecker.is_upsert_operation_supported")
    @mock.patch("module_utils.configuration._extract_model_from_upsert_operation")
    def test_is_upsert_operation_supported(self, extract_model_mock, is_upsert_supported_mock, get_operation_spec_mock):
        op_name = mock.MagicMock()

        result = self._resource.is_upsert_operation_supported(op_name)

        assert result == is_upsert_supported_mock.return_value
        extract_model_mock.assert_called_once_with(op_name)
        get_operation_spec_mock.assert_called_once_with(extract_model_mock.return_value)
        is_upsert_supported_mock.assert_called_once_with(get_operation_spec_mock.return_value)

    @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    @mock.patch("module_utils.configuration._extract_model_from_upsert_operation")
    def test_upsert_object_succesfully_added(self, extract_model_mock, edit_mock, add_mock, get_operation_mock,
                                             is_upsert_supported_mock):
        op_name = mock.MagicMock()
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = True

        result = self._resource.upsert_object(op_name, params)

        assert result == add_mock.return_value
        is_upsert_supported_mock.assert_called_once_with(op_name)
        extract_model_mock.assert_called_once_with(op_name)
        get_operation_mock.assert_called_once_with(extract_model_mock.return_value)
        add_mock.assert_called_once_with(get_operation_mock.return_value, params)
        edit_mock.assert_not_called()

    @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    @mock.patch("module_utils.configuration._extract_model_from_upsert_operation")
    def test_upsert_object_succesfully_edited(self, extract_model_mock, edit_mock, add_mock, get_operation_mock,
                                              is_upsert_supported_mock):
        op_name = mock.MagicMock()
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = True
        error = FtdConfigurationError("Obj duplication error")
        error.obj = mock.MagicMock()

        add_mock.side_effect = error

        result = self._resource.upsert_object(op_name, params)

        assert result == edit_mock.return_value
        is_upsert_supported_mock.assert_called_once_with(op_name)
        extract_model_mock.assert_called_once_with(op_name)
        get_operation_mock.assert_called_once_with(extract_model_mock.return_value)
        add_mock.assert_called_once_with(get_operation_mock.return_value, params)
        edit_mock.assert_called_once_with(get_operation_mock.return_value, error.obj, params)

    @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    @mock.patch("module_utils.configuration._extract_model_from_upsert_operation")
    def test_upsert_object_not_supported(self, extract_model_mock, edit_mock, add_mock, get_operation_mock,
                                         is_upsert_supported_mock):
        op_name = mock.MagicMock()
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = False

        self.assertRaises(
            FtdInvalidOperationNameError,
            self._resource.upsert_object, op_name, params
        )

        is_upsert_supported_mock.assert_called_once_with(op_name)
        extract_model_mock.assert_not_called()
        get_operation_mock.assert_not_called()
        add_mock.assert_not_called()
        edit_mock.assert_not_called()

    @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    @mock.patch("module_utils.configuration._extract_model_from_upsert_operation")
    def test_upsert_object_neither_added_nor_edited(self, extract_model_mock, edit_mock, add_mock, get_operation_mock,
                                                    is_upsert_supported_mock):
        op_name = mock.MagicMock()
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = True
        error = FtdConfigurationError("Obj duplication error")
        error.obj = mock.MagicMock()

        add_mock.side_effect = error
        edit_mock.side_effect = FtdConfigurationError("Some object edit error")

        self.assertRaises(
            FtdConfigurationError,
            self._resource.upsert_object, op_name, params
        )

        is_upsert_supported_mock.assert_called_once_with(op_name)
        extract_model_mock.assert_called_once_with(op_name)
        get_operation_mock.assert_called_once_with(extract_model_mock.return_value)
        add_mock.assert_called_once_with(get_operation_mock.return_value, params)
        edit_mock.assert_called_once_with(get_operation_mock.return_value, error.obj, params)

    @mock.patch.object(BaseConfigurationResource, "is_upsert_operation_supported")
    @mock.patch.object(BaseConfigurationResource, "get_operation_specs_by_model_name")
    @mock.patch.object(BaseConfigurationResource, "_add_upserted_object")
    @mock.patch.object(BaseConfigurationResource, "_edit_upserted_object")
    @mock.patch("module_utils.configuration._extract_model_from_upsert_operation")
    def test_upsert_object_with_fatal_error_during_add(self, extract_model_mock, edit_mock, add_mock,
                                                       get_operation_mock, is_upsert_supported_mock):
        op_name = mock.MagicMock()
        params = mock.MagicMock()

        is_upsert_supported_mock.return_value = True

        error = FtdConfigurationError("Obj duplication error")
        add_mock.side_effect = error

        self.assertRaises(
            FtdConfigurationError,
            self._resource.upsert_object, op_name, params
        )

        is_upsert_supported_mock.assert_called_once_with(op_name)
        extract_model_mock.assert_called_once_with(op_name)
        get_operation_mock.assert_called_once_with(extract_model_mock.return_value)
        add_mock.assert_called_once_with(get_operation_mock.return_value, params)
        edit_mock.assert_not_called()