Для ManageIQ есть хорошо написанная документация по работе с REST API. Всё остальное документировано или очень плохо, или совсем никак. Единственным достоверным источником информации остаётся исходный код. Сегодня исследуем конфигурацию сети при создании виртуальных машин: добавление дополнительных интерфейсов и их настройку.
Автоматизация создания виртуальной машины в ManageIQ включает в себя запрос (объект miq_provision_request) и задачу (объект miq_provision). Входные параметры нового развёртывания будут добавлены в объект miq_provision_request в виде хеша options. Далее этот хеш будет передан в объект задачи (или задач) постепенно наполняясь дополнительными параметрами. Хеш options может немного отличаться в зависимости от типа ОС заказанной VM и от целевой платформы виртуализации. В моём случае это будет гостевая ОС семейства Linux на платформе VMware.
Настройка виртуальных машин, не только её сетевых параметров, сводится к наполнению хеша options определёнными элементами – парами <ключ:значение>. Для сетевых настроек используются такие ключи как: :addr_mode, :ip_addr, :gateway, :subnet_mask, :mac_address, :dns_servers, :dns_suffixes, :network_adapters, :networks, :nic_settings, :vlan… Некоторые параметры добавляются автоматически со значением по умолчанию. Перечень параметров, их допустимых значений и значений по умолчанию, можно посмотреть в описаниях диалогов подготовки виртуальных машин: /Automation/Automate/Customization/Provisioning Dialogs/*.
Также у объекта miq_provision есть несколько вспомогательных методов, предназначеных для упрощения процесса настройки: set_vlan, set_dvs, set_network_address_mode, set_network_adapter, set_nic_settings
Дополнительно существуют параметры и методы специфические для облачных провайдеров, например такие как: floating_ip_address, cloud_network, cloud_subnet. В рамках данной статьи работа с облачными провайдерами рассматриваться не будет.
Один сетевой адаптер
Для настройки VM с одним сетевым интерфейсом используются следующие параметры/значения:
- Количество интерфейсов: :network_adapters – уже добавлен и по умолчанию установлен в [1, ‘1’];
- Подключенная сеть: :vlan – имя портгруппы, если портгруппа на DVS, то к имени нужно добавить ‘dvs_*’. Можно использовать методы
miq_request.set_vlan('pg_web_app')
илиmiq_request.set_dvs('pg_web_app')
. - Тип адресации: :addr_mode, ‘dhcp’ (значение по умолчанию) или ‘static’, метод
miq_request.set_network_address_mode('static')
;- Дополнительно при статической адресации нужно будет задать:
- IP адрес: :ip_addr;
- Маску сети: :subnet_mask;
- Шлюз: :gateway;
- DNS серверы: :dns_servers.
- Дополнительно при статической адресации нужно будет задать:
- + Дополнительные сетевые параметры, специфические для конкретной ОС (при необходимости).
miq_request = $evm.root['miq_provision_request']
miq_request.set_option(:vlan, ['pg_web_app', 'pg_web_app'])
# или можно через метод, полностью идентично предыдущей записи:
# miq_request.set_vlan('pg_web_app')
miq_request.set_option(:addr_mode, ['static', 'Static'])
# miq_request.set_network_address_mode('static')
miq_request.set_option(:ip_addr,'192.168.111.7')
miq_request.set_option(:gateway,'192.168.111.1')
miq_request.set_option(:subnet_mask,'255.255.255.0')
miq_request.set_option(:dns_servers,'192.168.101.2, 192.168.102.2')
Прочитать определённое значение из хеша options можно так: miq_request.get_option(:ip_addr)
Несколько сетевых адаптеров
Настройка дополнительных сетевых интерфейсов производится через два специальных параметра: :networks и :nic_settings, принимающих массивы свойств. Два дополнительных метода (на объекте miq_provision): set_network_adapter и set_nic_settings, упрощают их добавление в хеш:
# добавить дополнительный сетевой интерфейс
# подключить его к портгруппе pg_web_app и настроить статический IP
index = 1
miq_provision.set_network_adapter(index,
{
:network => 'pg_web_app',
:devicetype => 'VirtualVmxnet3',
:is_dvs => true
})
miq_provision.set_nic_settings(index,
{
:ip_addr => '192.168.111.7',
:subnet_mask => '255.255.255.0',
:addr_mode => ['static', 'Static']
})
Эти методы можно использовать и для настройки основного сетевого интерфейса, передавая в значение первого атрибута (номер сетевого интерфейса) 0 (ноль). Метод set_nic_settings для интерфейса 0 не добавит в options массив :nic_settings, он последовательно добавит все пары ключ/значение в корневой хеш.
По аналогии с добавлением дисков можно вынести создание сетевых интерфейсов по входным параметрам диалогов в / ManageIQ / Infrastructure / VM / Provisioning / StateMachines / Methods / vmware_PreProvision:
def initialize(handle = $evm)
...
@set_nics = true
end
...
def input_fields_data(prefix)
inputs = prov.options.merge(prov.get_option(:ws_values) || {})
inputs.filter { |key, _value| key.start_with?(prefix) }
.map { |key, value| [key.to_s.scan(/\d+/).first.to_i, value] }
.sort.to_h.values
end
def nic_config(network)
{ network: network,
devicetype: 'VirtualVmxnet3',
is_dvs: true,
connectable: { startconnected: true, allowguestcontrol: true, connected: true } }
end
def set_nics
log(:info, "Processing set_nics...", true)
nics = input_fields_data("add_nic").map { |net| nic_config(net) }
prov.set_option(:networks, nics) if nics.any?
log(:info, "Provisioning object <:networks> updated with <#{nics}>") if nics.any?
log(:info, "Processing set_nics...Complete", true)
end
...
def process_customization
...
set_nics if @set_nics
end
В данном примере происводится поиск всех полей диалогового окна, соответствующих маске ‘add_nicX’. По значениям этих полей формируется массив параметров сетевых интерфейсов nics, который добавляется в хеш options. Настройку адресации можно сделать по аналогии, но правильнее это сделать в процессах интеграции с IPAM.
Интеграция ManageIQ с IPAM
Интеграция процесса создания VM с внешними системами производится очень легко: отдельно создаются классы, методы, инстансы для соединения и обмена данными с внешней системой, и затем добавляется ссылка на инстанс как новый этап в процесс развёртывания:

Внутри выделенного метода PhpIpam_AcquireIPAddress можно прочитать нужные значения из хеша options, найти нужную подсеть, зарезервировать в ней адрес и добавить его в тот же хеш:
...
nic1_options = {
ip_addr: ip_addr1,
subnet_mask: subnet_mask1,
gateway: getFirstAddress(subnet_mask1, ip_addr1),
dns_domain: subnets1[0]["nameservers"]["namesrv1"],
dns_suffixes: subnets1[0]["nameservers"]["description"],
linux_domain_name: subnets1[0]["nameservers"]["description"]
dns_servers: "#{dns1}, #{dns2}"
}
@prov.set_option(:nic_settings, [nic1_options])
Или тоже самое для двух сетевых интерфейсов:
...
nic1_options = {
ip_addr: ip_addr1,
subnet_mask: subnet_mask1,
gateway: getFirstAddress(subnet_mask1, ip_addr1),
dns_domain: subnets1[0]["nameservers"]["namesrv1"],
dns_suffixes: subnets1[0]["nameservers"]["description"],
linux_domain_name: subnets1[0]["nameservers"]["description"]
dns_servers: "#{dns1}, #{dns2}"
}
nic2_options = {
ip_addr: ip_addr2,
subnet_mask: subnet_mask2,
gateway: "0.0.0.0"
}
@prov.set_option(:nic_settings, [nic1_options, nic2_options])