Квоты – механизм ограничений необходимый для предотвращения перерасхода ресурсов. Разберёмся как его использовать, и как он функционирует в ManageIQ. Поскольку самый лучший способ изучения – это сделать что-то на практике, мы включим учёт квот для запросов на реконфигурацию сервисов заказа виртуальных машин.
Добавление квот
Для включения квотирования ресурсов в ManageIQ достаточно назначить квоту на тенант или проект. Квоты задаются в Settings → Application Settings → Access Control → Tenants → <tenant_name>. На специальной форме Configuration → Manage Quotas указываются ограничения на использование CPU, RAM, хранилища и на количество виртуальных машин и шаблонов:

mytenant = $evm.root['tenant']
# получить установленные значения лимитов
limits = mytenant.tenant_quotas.map { |q| [q.name.chomp('_allocated'), q.value.to_i] }.to_h
# получить текущие значения утилизации
params = %i[vcpu memory storage]
used = params.map { |p| [p, mytenant.send("allocated_#{p}")] }.to_h
Кроме ограничений для тенантов, есть возможность указать ограничения в экземплярах класса QuotaStateMachine (см. описание далее) или при помощи тегов категорий quota_max_<param> и quota_warn_<param>. Эти способы позволяют назначать квоты на группы пользователей и даже на отдельных пользователей. Квоты для группы, заданные тегами, имеют более высокий приоритет.
$evm.root['quota_source'] = @miq_request.requester.current_group
$evm.root['quota_source_type'] = 'group'
Работа квот в ManageIQ

Процесс проверки квоты включает следующие этапы:
- Событие. Происходит событие “создание нового запроса”, которое обрабатывается в /System/Policy/request_starting. Определяется тип запроса и применяется соответствующая запросу политика: /System/Policy/${#request_type}_starting;
- Политика, например, MiqProvisionRequest_starting. В данной политике определяется процесс – QuotaStateMachine (это не является обязательным, т.к. не все запросы изменяют утилизируемые ресурсы);
- Процесс, по умолчанию это всегда /System/CommonMethods/QuotaStateMachine/quota, выполняет следующие шаги для обработки квоты:
- определение источника/объекта квоты (quota_source);
- определение пределов квоты для данного объекта (limits);
- вычисление объёмов ресурсов, используемых в настоящее время этим объектом (used);
- определение объёмов новых, запрашиваемых ресурсов (requested);
- проверка превышения запросом ресурсной квоты (validate_quota).
- Результат проверки:
- Превышения квоты нет – запуск выполнения запроса;
- Квота превышена – отмена запроса и оповещение пользователя на email.

Квота при реконфигурации сервиса
Что необходимо сделать для включения расчёта квот для какого-то нового типа запроса? Например, есть некоторый сервис, работу которого обеспечивают классы ServiceProvision_Template, ServiceReconfigure и ServiceRetirement:

И Вам нужно, чтобы при создании запроса ServiceReconfigure происходила проверка квоты. Для этого нужно обеспечить работу всех этапов, описанных в предыдущем разделе:
- Обработка запуска нового запроса (/System/Policy/request_starting) выполняется всегда, вне зависимости от типа запроса, ничего делать не нужно;
- Политика. Скопируйте политику /System/Policy/MiqProvisionRequest_starting, для данного примера это будет /System/Policy/ServiceReconfigureRequest_starting;
- Процесс. Методы, вызываемые в /System/CommonMethods/QuotaStateMachine/quota, в основном универсальны. quota_source, limits, used, validate_quota – точно не потребуют никаких изменений, а вот метод requested работает с определёнными типами запросов и названиями полей диалогов. Если Вам потребуются значительные правки в requested, то данный метод лучше полностью заменить своим. Для замены метода:
- Сделайте копию /System/CommonMethods/QuotaStateMachine/quota, в /System/CommonMethods/QuotaStateMachine/ServiceReconfigureQuota;
- Сделайте копию метода requested, в service_reconfigure_requested;
- В /System/CommonMethods/QuotaStateMachine/ServiceReconfigureQuota замените вызов requested на service_reconfigure_requested;
- Отредактируйте service_reconfigure_requested.
- Результат проверки, запуск или отмена запроса: без изменений.
Запрос на реконфигурацию сервиса выбран в качестве примера не случайно. При попытке проверки квоты Вы получите ошибку, что у объекта запроса нет метода check_quota. Базовый функционал ManageIQ не задействует механизм квотирования при изменении параметров сервисов.
Для исправления данной ошибки нужно:
# В файл /var/www/miq/vmdb/app/models/service_reconfigure_request.rb
# добавить в строку 13 (перед первым методом):
include MiqProvisionQuotaMixin
# В файл /opt/manageiq/manageiq-gemset/gems/manageiq-automation_engine-0.1.0/lib/
# miq_automation_engine/service_models/miq_ae_service_service_reconfigure_request.rb
# добавить после строки 3 (перед первым методом):
require_relative "mixins/miq_ae_service_miq_provision_quota_mixin"
include MiqAeServiceMiqProvisionQuotaMixin
Внимание! Внесение изменений в исходном коде потребует перезапуска сервера для их применения, также потребуется вносить эти изменения в код заново после каждого обновления MIQ.