Вступление от HP: эта публикация написана одним из наших заказчиков, который по долгу службы пожелал остаться анонимным. Все совпадения имён и айпишников считать случайными. Попробовать сделать то же самое можно в любое время в нашем демо-центре в Москве — желающих просим писать в комментарии.
Приветствую. Меня зовут Эдуард, и я системный администратор в небольшой компании, которая аутсорсит администрирование ИТ-инфраструктуры. Кхм… Уже похоже на клуб анонимных кого-то с проблемами? Ну да ладно, одна интересная проблема у нас действительно была, а сегодня мы расскажем, как мы с ней столкнулись, и как случайно её решили.
![](https://habrastorage.org/r/w780q1/files/bc3/6eb/d98/bc36ebd9807b4d1392760060973d6daf.jpg)
Для начала немного предыстории. Все же помнят, как весело было админить удалённое железо раньше, лет 5-8 назад? Пишем заявку инженерам в ДЦ, ждём, когда они подключат KVM, настраиваем BIOS/CMOS, выставляем загрузку по сети, ставим систему (это хорошо, если кто-то добрый уже написал генератор preseed/kickstart-файлов, и в ДЦ есть DHCP/PXE сервер). А потом у нас на всех серверах появился ipmi (ну со временем). Ох, как мы радовались первое время!
И сервер уже вроде бы ставит ОС. Остаётся только наблюдать за этим в консоли, если скучно. Огорчало только то, что BIOS всё равно приходилось обновлять руками и настраивать (ну там HT/VT-d включить, хотя бы). В итоге все серверы были настроены по-разному, в зависимости от того, в каком квартале их ставили. Ну вы же понимаете, что серверы всегда ставил самый младший админ.
Когда мы находили что-то критичное – мы шли и руками переключали настройки. Бардак, да и только. Но вообще всё это нас устраивало до того, как с нами случилась история, о которой я сегодня и буду рассказывать.
Стоит упомянуть, что часть клиентов мы размещаем прямо на своём железе (точнее на виртуалках на этом железе, которое рулится через <зачеркнуто печатью с большими буквами NDA>). Ну чтобы вам было легче представить – наша система сильно похожа на OpenStack. И вот, в один прекрасный день, к нам пришел заказчик и попросил «на его железе сделать систему для управления виртуальными машинами в приватном облаке». Мы обрадовались, начали ему показывать своё решение (уже после подписания контракта и ТЗ), ему всё понравилось. Всё понравилось, менеджеры уже открывают шампанское (а надо сказать, что контракт по нашим меркам был очень неплохой). И тут клиент показывает пальцем в пункт ТЗ и спрашивает – «а с этим как?». Сидят админы и недоуменно смотрят в этот пункт – «новые серверы должны автоматически добавляться в облако после инвентаризации, установки в стойку и подключения сети-питания». Мы начали показывать – вот смотрите, мы записываем сервер сюда (1c), добавляем его mac-адрес вот сюда (самописная web-морда для управления dhcp-сервером и pxe), запускаем скрипт, сервер загружается по сети, система ставится (мы с облегчением выдохнули, поняв, что хотя бы система ставится сама), потом мы ловим сервер при перезагрузке, усиленно жмем клавишу Del… В общем, представитель клиента посмотрел на это, почесал затылок, походил по переговорке, собрался с мыслями и произнес: «Да где ж тут автоматически? Вот давайте выкинем всё, кроме 1С, всё равно туда бухгалтеры сервер вносить будут, а не я, и того места, куда вы mac-адрес записывали». Ну и вскоре после этого ушел, добавив, что надеется на то, что задачу мы всё же решим.
Потом мы, как обычно, ТЗ решили прочитать. Нашли там всякие интересные пункты, которые мы (ну те, кто делал задачу, а не те, кто ТЗ подписывал и пересказывал его нам) увидели впервые. Например, мониторинг температуры в обход ОС, мониторинг потребления электричества, автоматическая настройка BIOS… Начали размышлять. Сначала склонялись к мысли, что ipmitool всё это может. Потом представили, как всё это будет выглядеть. Подумали про то, как обновлять настройки, про мониторинг датчиков… В общем, разошлись на выходные с задачей «изучить весь гугл на предмет альтернатив ipmi, которые могут».
Приходим в понедельник, все грустные, злые. А один админ сидит и улыбается. Логичным было пристать к нему с расспросами на тему того, зачем он читает ithappens, когда у нас такая беда. Как оказалось, радовался он по поводу того, что читал не ithappens, а Redfish server management spec v 1.0 (читать здесь). Почитали все вместе вслух, злиться перестали. Redfish оказался именно тем, что нам нужно. Взяли менеджера, заставили его обзванивать всех производителей серверов, чтобы найти железку, в которой Redfish реализован. Приходят через час и смеется, показывает пальцем на коробку у входа и говорит «всё, я нашел». Собственно, коробка оказалась коробкой от HP Proliant Gen9. Сервер мы нашли, вернули в лабораторию (и кто вообще догадался новенький неизученный сервер сразу в ДЦ везти…) и приступили к знакомству с HP REST API (которая и является реализацией Redfish в серверах HP).
Так как мы админы (это потом уже нам дали питониста и он нам всё написал и сделал красивый web-интерфейс), то первым делом мы сели писать sh-ники, которые будут делать то, что нам нужно. Конечно, мы бы не советовали ходить в Rest API консольным curl-ом и генерировать JSON через echo (ну или хотя бы потом не показывайте никому это), но вот поделиться примерами взаимодействия с HP ProLiant REST API будем рады (тем более, что сами представители HP нас об этом и попросили).
Возможностей там полно на самом деле, в документации 2 сотни страниц списка объектов и краткого их описания. Мы первым делом пытались выполнить свои основные задачи, как proof-of-concept. Конечно, часть из них можно делать и через IPMI, но мы решили использовать один инструмент, именно API.
Первым делом (ну хорошо, вторым, после подключения сервера в стойке и после того, как HP iLO получит IP-адрес), прописываем все настройки BIOS:
Научимся управлять питанием. Ребут «по кнопке»:
«Выдёргиваем кабель из розетки»:
Включаем сервер:
Отправляем инженера «нажать кнопку питания»:
Спросим у сервера, кто он такой:
PATCH-запросом в эту же ручку можно изменить информацию о сервере внутри iLo.
Спросим MAC-адреса у сервера (да, в итоге мы пошли дальше и DHCP-сервер сам проводил инвентаризацию новых серверов, если находил незнакомый iLO в отдельном VLAN-е – для iLO мы выдавали динамические адрес, а потом уже заводили записи о статических адресах для сетевых карт сервера и интерфейса iLo):
Из предыдущего JSON-а мы вытаскивали также и количество памяти с моделью CPU, потом разработчики сделали интеграцию с 1С, сервер отправлял данные о себе и туда. Здесь же мы определяли и версию BIOS, чтобы ругаться об устаревших (или просто отличающихся по кластеру) версиях.
Ещё через REST API можно снять показания метрик питания (к сожалению, не во всех «уровнях» лицензии iLO):
Ещё мы нашли какую-то жуткую ручку, которая описывает состояние сервера – обороты вентилятора, температуру, состояние разных железок внутри сервера.
А ещё нашли объект, который говорит о состоянии сервера в целом (ОК/fail) и чем он сейчас занимается (в нашем примере он загружался):
В общем, sh-ник мы в итоге написали и отдали его разработчику. Он над нами посмеялся, мы его за это поругали, пригрозили рута отобрать… Но зато он потом написал модуль в наше облачко, который умеет добавлять и управлять серверами через Redfish (и HP REST API, соответственно). Ну а заказ мы в итоге выполнили.
Наверное, пора закругляться. Расскажем про тех, кто играл главные роли во всей это истории.
Спасибо за внимание!
Приветствую. Меня зовут Эдуард, и я системный администратор в небольшой компании, которая аутсорсит администрирование ИТ-инфраструктуры. Кхм… Уже похоже на клуб анонимных кого-то с проблемами? Ну да ладно, одна интересная проблема у нас действительно была, а сегодня мы расскажем, как мы с ней столкнулись, и как случайно её решили.
![](https://habrastorage.org/files/bc3/6eb/d98/bc36ebd9807b4d1392760060973d6daf.jpg)
Для начала немного предыстории. Все же помнят, как весело было админить удалённое железо раньше, лет 5-8 назад? Пишем заявку инженерам в ДЦ, ждём, когда они подключат KVM, настраиваем BIOS/CMOS, выставляем загрузку по сети, ставим систему (это хорошо, если кто-то добрый уже написал генератор preseed/kickstart-файлов, и в ДЦ есть DHCP/PXE сервер). А потом у нас на всех серверах появился ipmi (ну со временем). Ох, как мы радовались первое время!
ipmitool -U user -P password power up -H XXX
ipmitool -U user -P password password bootdev pxe -H XXX
ipmitool -U user -P password power reset -H XXX
И сервер уже вроде бы ставит ОС. Остаётся только наблюдать за этим в консоли, если скучно. Огорчало только то, что BIOS всё равно приходилось обновлять руками и настраивать (ну там HT/VT-d включить, хотя бы). В итоге все серверы были настроены по-разному, в зависимости от того, в каком квартале их ставили. Ну вы же понимаете, что серверы всегда ставил самый младший админ.
Когда мы находили что-то критичное – мы шли и руками переключали настройки. Бардак, да и только. Но вообще всё это нас устраивало до того, как с нами случилась история, о которой я сегодня и буду рассказывать.
Стоит упомянуть, что часть клиентов мы размещаем прямо на своём железе (точнее на виртуалках на этом железе, которое рулится через <зачеркнуто печатью с большими буквами NDA>). Ну чтобы вам было легче представить – наша система сильно похожа на OpenStack. И вот, в один прекрасный день, к нам пришел заказчик и попросил «на его железе сделать систему для управления виртуальными машинами в приватном облаке». Мы обрадовались, начали ему показывать своё решение (уже после подписания контракта и ТЗ), ему всё понравилось. Всё понравилось, менеджеры уже открывают шампанское (а надо сказать, что контракт по нашим меркам был очень неплохой). И тут клиент показывает пальцем в пункт ТЗ и спрашивает – «а с этим как?». Сидят админы и недоуменно смотрят в этот пункт – «новые серверы должны автоматически добавляться в облако после инвентаризации, установки в стойку и подключения сети-питания». Мы начали показывать – вот смотрите, мы записываем сервер сюда (1c), добавляем его mac-адрес вот сюда (самописная web-морда для управления dhcp-сервером и pxe), запускаем скрипт, сервер загружается по сети, система ставится (мы с облегчением выдохнули, поняв, что хотя бы система ставится сама), потом мы ловим сервер при перезагрузке, усиленно жмем клавишу Del… В общем, представитель клиента посмотрел на это, почесал затылок, походил по переговорке, собрался с мыслями и произнес: «Да где ж тут автоматически? Вот давайте выкинем всё, кроме 1С, всё равно туда бухгалтеры сервер вносить будут, а не я, и того места, куда вы mac-адрес записывали». Ну и вскоре после этого ушел, добавив, что надеется на то, что задачу мы всё же решим.
Потом мы, как обычно, ТЗ решили прочитать. Нашли там всякие интересные пункты, которые мы (ну те, кто делал задачу, а не те, кто ТЗ подписывал и пересказывал его нам) увидели впервые. Например, мониторинг температуры в обход ОС, мониторинг потребления электричества, автоматическая настройка BIOS… Начали размышлять. Сначала склонялись к мысли, что ipmitool всё это может. Потом представили, как всё это будет выглядеть. Подумали про то, как обновлять настройки, про мониторинг датчиков… В общем, разошлись на выходные с задачей «изучить весь гугл на предмет альтернатив ipmi, которые могут».
Приходим в понедельник, все грустные, злые. А один админ сидит и улыбается. Логичным было пристать к нему с расспросами на тему того, зачем он читает ithappens, когда у нас такая беда. Как оказалось, радовался он по поводу того, что читал не ithappens, а Redfish server management spec v 1.0 (читать здесь). Почитали все вместе вслух, злиться перестали. Redfish оказался именно тем, что нам нужно. Взяли менеджера, заставили его обзванивать всех производителей серверов, чтобы найти железку, в которой Redfish реализован. Приходят через час и смеется, показывает пальцем на коробку у входа и говорит «всё, я нашел». Собственно, коробка оказалась коробкой от HP Proliant Gen9. Сервер мы нашли, вернули в лабораторию (и кто вообще догадался новенький неизученный сервер сразу в ДЦ везти…) и приступили к знакомству с HP REST API (которая и является реализацией Redfish в серверах HP).
Так как мы админы (это потом уже нам дали питониста и он нам всё написал и сделал красивый web-интерфейс), то первым делом мы сели писать sh-ники, которые будут делать то, что нам нужно. Конечно, мы бы не советовали ходить в Rest API консольным curl-ом и генерировать JSON через echo (ну или хотя бы потом не показывайте никому это), но вот поделиться примерами взаимодействия с HP ProLiant REST API будем рады (тем более, что сами представители HP нас об этом и попросили).
Возможностей там полно на самом деле, в документации 2 сотни страниц списка объектов и краткого их описания. Мы первым делом пытались выполнить свои основные задачи, как proof-of-concept. Конечно, часть из них можно делать и через IPMI, но мы решили использовать один инструмент, именно API.
Первым делом (ну хорошо, вторым, после подключения сервера в стойке и после того, как HP iLO получит IP-адрес), прописываем все настройки BIOS:
# echo '{"AcpiRootBridgePxm":"Enabled","AcpiRtcSupport":"Disabled","AcpiSlit":"Enabled","AdjSecPrefetch":"Enabled","AdminEmail":"","AdminName":"","AdminOtherInfo":"","AdminPassword":"","AdminPhone":"","AdvancedMemProtection":"AdvancedEcc","AsrStatus":"Enabled","AsrTimeoutMinutes":"10","AssetTagProtection":"Unlocked","AttributeRegistry":"HpBiosAttributeRegistryP86.1.1.0","AutoPowerOn":"RestoreLastState","BootMode":"LegacyBios","BootOrderPolicy":"RetryIndefinitely","ChannelInterleaving":"Enabled","CollabPowerControl":"Enabled","ConsistentDevNaming":"LomsOnly","CustomPostMessage":"","DcuIpPrefetcher":"Enabled","DcuStreamPrefetcher":"Enabled","Description":"This is the Platform/BIOS Configuration (RBSU) Current Settings","Dhcpv4":"Enabled","DynamicPowerCapping":"Auto","DynamicPowerResponse":"Fast","EmbNicEnable":"Enabled","EmbSata1Enable":"Enabled","EmbSata2Enable":"Enabled","EmbVideoConnection":"Auto","EmbeddedDiagnostics":"Enabled","EmbeddedDiagsMode":"Auto","EmbeddedSata":"Raid","EmbeddedUefiShell":"Enabled","EmsConsole":"Disabled","EnergyPerfBias":"BalancedPerf","EraseUserDefaults":"No","ExtendedAmbientTemp":"Disabled","ExtendedMemTest":"Disabled","F11BootMenu":"Enabled","FanFailPolicy":"Shutdown","FanInstallReq":"EnableMessaging","HwPrefetcher":"Enabled","IntelDmiLinkFreq":"Auto","IntelPerfMonitoring":"Disabled","IntelProcVtd":"Enabled","IntelQpiFreq":"Auto","IntelQpiPowerManagement":"Enabled","IntelTxt":"Disabled","IntelligentProvisioning":"Enabled","Ipv4Address":"0.0.0.0","Ipv4Gateway":"0.0.0.0","Ipv4PrimaryDNS":"0.0.0.0","Ipv4SecondaryDNS":"0.0.0.0","Ipv4SubnetMask":"0.0.0.0","MaxMemBusFreqMHz":"Auto","MaxPcieSpeed":"MaxSupported","MemFastTraining":"Enabled","MinProcIdlePkgState":"C6Retention","MinProcIdlePower":"C6","MixedPowerSupplyReportngi":"Enabled","Modified":"2015-02-12T20:16:59+00:00","Name":"BIOS Current Settings","NetworkBootRetry":"Enabled","NicBoot1":"NetworkBoot","NicBoot2":"Disabled","NmiDebugButton":"Enabled","NodeInterleaving":"Disabled","OldAdminPassword":"","OldPowerOnPassword":"","PciBusPadding":"Enabled","PostF1Prompt":"Delayed20Sec","PowerButton":"Enabled","PowerOnDelay":"None","PowerOnLogo":"Enabled","PowerOnPassword":"","PowerProfile":"BalancedPowerPerf","PowerRegulator":"DynamicPowerSavings","PreBootNetwork":"EmbNic","ProcCoreDisable":0,"ProcHyperthreading":"Enabled","ProcNoExecute":"Enabled","ProcTurbo":"Enabled","ProcVirtualization":"Disabled","ProcX2Apic":"Enabled","ProductId":"777424-AA1","QpiBandwidthOpt":"Balanced","QpiSnoopConfig":"Standard","RedundantPowerSupply":"BalancedMode","RemovableFlashBootSeq":"ExternalKeysFirst","RestoreDefaults":"No","RestoreManufacturingDefaults":"No","RomSelection":"CurrentRom","SataSecureErase":"Disabled","SaveUserDefaults":"No","SecureBoot":"Disabled","SerialConsoleBaudRate":"115200","SerialConsoleEmulation":"Vt100Plus","SerialConsolePort":"Auto","SerialNumber":"8CW4340081","ServerAssetTag":"","ServerName":"","ServerOtherInfo":"","ServerPrimaryOs":"","ServiceEmail":"","ServiceName":"","ServiceOtherInfo":"","ServicePhone":"","SettingsResult":{"ETag":"","Messages":[{"MessageArgs":[],"MessageID":"Base.1.0:Success"}],"Time":""},"Sriov":"Enabled","ThermalConfig":"OptimalCooling","ThermalShutdown":"Enabled","TimeZone":"Utc0","TpmBinding":"Disabled","TpmOperation":"Disable","TpmState":"NotPresent","TpmType":"NoTpm","TpmVisibility":"Visible","Type":"HpBios.1.0.0","UefiOptimizedBoot":"Enabled","UefiPxeBoot":"Auto","UefiShellBootOrder":"Disabled","UefiShellStartup":"Disabled","UefiShellStartupLocation":"AttachedMedia","UefiShellStartupUri":"","UrlBootFile":"","Usb3Mode":"Auto","UsbBoot":"Enabled","UsbControl":"UsbEnabled","UtilityLang":"English","VideoOptions":"BothVideoEnabled","VirtualInstallDisk":"Disabled","VirtualSerialPort":"Com2Irq3","WakeOnLan":"Enabled","links":{"BaseConfigs":{"href":"/rest/v1/systems/1/bios/BaseConfigs"},"Boot":{"href":"/rest/v1/systems/1/bios/Boot"},"Mappings":{"href":"/rest/v1/systems/1/bios/Mappings"},"Settings":{"href":"/rest/v1/systems/1/bios/Settings"}}}' | curl -v -k -X PATCH https://Administrator:Password@192.168.2.250/rest/v1/systems/1/Bios/Settings -H "Content-Type: application/json" --data-binary @- ; echo
Научимся управлять питанием. Ребут «по кнопке»:
# echo '{"Action":"Reset","ResetType":"ForceRestart"}' | curl -v -k -X POST https://Administrator:Password@192.168.2.250/rest/v1/systems/1 -H "Content-Type: application/json" --data-binary @- ; echo
«Выдёргиваем кабель из розетки»:
# echo '{"Action":"Reset","ResetType":"ForceOff"}' | curl -v -k -X POST https://Administrator:Password@192.168.2.250/rest/v1/systems/1 -H "Content-Type: application/json" --data-binary @- ; echo
Включаем сервер:
# echo '{"Action":"Reset","ResetType":"On"}' | curl -v -k -X POST https://Administrator:Password@192.168.2.250/rest/v1/systems/1 -H "Content-Type: application/json" --data-binary @- ; echo
Отправляем инженера «нажать кнопку питания»:
# echo '{"Action":"Reset","ResetType":"PushPowerButton"}' | curl -v -k -X POST https://Administrator:D3BFF4AE@192.168.2.250/rest/v1/systems/1 -H "Content-Type: application/json" --data-binary @- ; echo
Спросим у сервера, кто он такой:
# curl -v -k -X GET https://Administrator:Password@192.168.2.250/rest/v1 -H "Content-Type: application/json"
{"Name":"HP RESTful Root Service","Oem":{"Hp":{"Manager":[{"DefaultLanguage":"en","FQDN":"ILO8CW4340081.","HostName":"ILO8CW4340081","Languages":[{"Language":"en","TranslationName":"English","Version":"2.02"}],"ManagerFirmwareVersion":"2.02","ManagerType":"iLO 4"}],"Sessions":{"CertCommonName":"ILO8CW4340081","KerberosEnabled":false,"LDAPAuthLicenced":false,"LDAPEnabled":false,"LocalLoginEnabled":true,"LoginFailureDelay":0,"LoginHint":{"Hint":"POST to /Sessions to login using the following JSON object:","HintPOSTData":{"Password":"password","UserName":"username"}},"SecurityOverride":true,"ServerName":""},"Type":"HpiLOServiceExt.0.9.5","links":{"Providers":{"href":"/rest/v1/Providers"}}}},"ServiceVersion":"0.9.5","Time":"2015-05-06T18:01:55Z","Type":"ServiceRoot.0.9.5","links":{"AccountService":{"href":"/rest/v1/AccountService"},"Chassis":{"href":"/rest/v1/Chassis"},"Managers":{"href":"/rest/v1/Managers"},"Registries":{"href":"/rest/v1/Registries"},"Schemas":{"href":"/rest/v1/Schemas"},"Sessions":{"href":"/rest/v1/Sessions"},"Systems":{"href":"/rest/v1/Systems"},"self":{"href":"/rest/v1/root"}}}
PATCH-запросом в эту же ручку можно изменить информацию о сервере внутри iLo.
Спросим MAC-адреса у сервера (да, в итоге мы пошли дальше и DHCP-сервер сам проводил инвентаризацию новых серверов, если находил незнакомый iLO в отдельном VLAN-е – для iLO мы выдавали динамические адрес, а потом уже заводили записи о статических адресах для сетевых карт сервера и интерфейса iLo):
# curl -v -k -X GET https://Administrator:Password@192.168.2.250/rest/v1/systems/1 -H "Content-Type: application/json"
{"AvailableActions":[{"Action":"Reset","Capabilities":[{"AllowableValues":["On","ForceOff","ForceRestart","Nmi","PushPowerButton"],"PropertyName":"ResetType"}]}],"Bios":{"Current":{"VersionString":"P86 v1.30 (09/04/2014)"}},"Boot":{"BootSourceOverrideEnabled":"Disabled","BootSourceOverrideSupported":["None","Floppy","Cd","Hdd","Usb","Utilities","Diags","BiosSetup","Pxe","UefiShell","UefiTarget"],"BootSourceOverrideTarget":"None","UefiTargetBootSourceOverride":"None","UefiTargetBootSourceOverrideSupported":["NIC.LOM.1.1.IPv4","NIC.LOM.1.1.IPv6"]},"Description":"Computer System View","HostCorrelation":{"HostMACAddress":["14:58:d0:d3:20:8e","14:58:d0:d3:20:8f"],"HostName":"","IPAddress":[""]},"IndicatorLED":"Off","Manufacturer":"HP","Memory":{"TotalSystemMemoryGB":32},"Model":"ProLiant DL120 Gen9","Name":"Computer System","Oem":{"Hp":{"AvailableActions":[{"Action":"PowerButton","Capabilities":[{"AllowableValues":["Press","PressAndHold"],"PropertyName":"PushType"},{"AllowableValues":["/Oem/Hp"],"PropertyName":"Target"}]}],"Bios":{"Backup":{"Date":"v1.30 (09/04/2014)","Family":"P86","VersionString":"P86 v1.30 (09/04/2014)"},"Bootblock":{"Date":"","Family":"P86","VersionString":"P86 "},"Current":{"Date":"09/04/2014","Family":"P86","VersionString":"P86 v1.30 (09/04/2014)"},"UefiClass":2},"PowerAllocationLimit":900,"PowerAutoOn":"Restore","PowerOnDelay":"Minimum","PowerRegulatorMode":"Dynamic","PowerRegulatorModesSupported":["OSControl","Dynamic","Max","Min"],"Type":"HpComputerSystemExt.0.10.0","VirtualUUID":null,"links":{"BIOS":{"href":"/rest/v1/systems/1/bios"},"PCIDevices":{"href":"/rest/v1/Systems/1/PCIDevices"},"PCISlots":{"href":"/rest/v1/Systems/1/PCISlots"},"SecureBoot":{"href":"/rest/v1/Systems/1/SecureBoot"}}}},"Power":"Off","Processors":{"Count":1,"ProcessorFamily":"Intel(R) Xeon(R) CPU E5-2660 v3 @ 2.60GHz"},"SKU":"777424-AA1","SerialNumber":"8CW4340081","Status":{"Health":"OK","State":"Disabled"},"SystemType":"Physical","Type":"ComputerSystem.0.9.5","UUID":"34373737-3432-4338-5734-333430303831","links":{"Chassis":[{"href":"/rest/v1/Chassis/1"}],"Manager":[{"href":"/rest/v1/Managers/1"}],"self":{"href":"/rest/v1/Systems/1"}}}
Из предыдущего JSON-а мы вытаскивали также и количество памяти с моделью CPU, потом разработчики сделали интеграцию с 1С, сервер отправлял данные о себе и туда. Здесь же мы определяли и версию BIOS, чтобы ругаться об устаревших (или просто отличающихся по кластеру) версиях.
Ещё через REST API можно снять показания метрик питания (к сожалению, не во всех «уровнях» лицензии iLO):
# curl -v -k -X GET https://Administrator:Password@192.168.2.250/rest/v1/chassis/1/PowerMetrics -H "Content-Type: application/json"
Ещё мы нашли какую-то жуткую ручку, которая описывает состояние сервера – обороты вентилятора, температуру, состояние разных железок внутри сервера.
# curl -v -k -X GET https://Administrator:Password@192.168.1.235/rest/v1/Chassis/1/ThermalMetrics -H "Content-Type: application/json"
{"Fans":[{"CurrentReading":33,"FanName":"Fan 1","Oem":{"Hp":{"Location":"System","Type":"HpServerFan.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Percent"},{"CurrentReading":33,"FanName":"Fan 2","Oem":{"Hp":{"Location":"System","Type":"HpServerFan.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Percent"},{"CurrentReading":33,"FanName":"Fan 3","Oem":{"Hp":{"Location":"System","Type":"HpServerFan.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Percent"},{"CurrentReading":33,"FanName":"Fan 4","Oem":{"Hp":{"Location":"System","Type":"HpServerFan.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Percent"},{"CurrentReading":33,"FanName":"Fan 5","Oem":{"Hp":{"Location":"System","Type":"HpServerFan.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Percent"},{"CurrentReading":33,"FanName":"Fan 6","Oem":{"Hp":{"Location":"System","Type":"HpServerFan.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Percent"}],"Name":"ThermalMetrics","Temperatures":[{"Context":"Ambient","CurrentReading":21,"LowerThresholdCritical":46,"LowerThresholdNonCritical":42,"Name":"01-Inlet Ambient","Oem":{"Hp":{"LocationXmm":11,"LocationYmm":0,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"CPU","CurrentReading":40,"LowerThresholdCritical":0,"LowerThresholdNonCritical":70,"Name":"02-CPU 1","Oem":{"Hp":{"LocationXmm":7,"LocationYmm":9,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"CPU","CurrentReading":40,"LowerThresholdCritical":0,"LowerThresholdNonCritical":70,"Name":"03-CPU 2","Oem":{"Hp":{"LocationXmm":12,"LocationYmm":9,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"GPU","CurrentReading":27,"LowerThresholdCritical":0,"LowerThresholdNonCritical":87,"Name":"04-P1 DIMM 1-2","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":10,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"GPU","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":87,"Name":"05-P1 DIMM 3-4","Oem":{"Hp":{"LocationXmm":5,"LocationYmm":10,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"GPU","CurrentReading":28,"LowerThresholdCritical":0,"LowerThresholdNonCritical":87,"Name":"06-P2 DIMM 1-2","Oem":{"Hp":{"LocationXmm":14,"LocationYmm":10,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"GPU","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":87,"Name":"07-P2 DIMM 3-4","Oem":{"Hp":{"LocationXmm":11,"LocationYmm":10,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":60,"Name":"08-HD Max","Oem":{"Hp":{"LocationXmm":4,"LocationYmm":2,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":41,"LowerThresholdCritical":0,"LowerThresholdNonCritical":105,"Name":"09-Chipset","Oem":{"Hp":{"LocationXmm":7,"LocationYmm":13,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":40,"LowerThresholdCritical":0,"LowerThresholdNonCritical":0,"Name":"10-P/S 1","Oem":{"Hp":{"LocationXmm":1,"LocationYmm":14,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":0,"Name":"11-P/S 2","Oem":{"Hp":{"LocationXmm":2,"LocationYmm":14,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":30,"LowerThresholdCritical":120,"LowerThresholdNonCritical":115,"Name":"12-VR P1","Oem":{"Hp":{"LocationXmm":7,"LocationYmm":8,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":30,"LowerThresholdCritical":120,"LowerThresholdNonCritical":115,"Name":"13-VR P2","Oem":{"Hp":{"LocationXmm":12,"LocationYmm":8,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":26,"LowerThresholdCritical":120,"LowerThresholdNonCritical":115,"Name":"14-VR P1 Zone","Oem":{"Hp":{"LocationXmm":7,"LocationYmm":7,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":25,"LowerThresholdCritical":120,"LowerThresholdNonCritical":115,"Name":"15-VR P2 Zone","Oem":{"Hp":{"LocationXmm":12,"LocationYmm":7,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":26,"LowerThresholdCritical":120,"LowerThresholdNonCritical":115,"Name":"16-VR P1 Mem","Oem":{"Hp":{"LocationXmm":8,"LocationYmm":7,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":26,"LowerThresholdCritical":120,"LowerThresholdNonCritical":115,"Name":"17-VR P2 Mem","Oem":{"Hp":{"LocationXmm":13,"LocationYmm":7,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":60,"Name":"18-Storage Batt","Oem":{"Hp":{"LocationXmm":0,"LocationYmm":7,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":30,"LowerThresholdCritical":85,"LowerThresholdNonCritical":80,"Name":"19-iLO Zone","Oem":{"Hp":{"LocationXmm":12,"LocationYmm":13,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":30,"LowerThresholdCritical":105,"LowerThresholdNonCritical":100,"Name":"20-System Board","Oem":{"Hp":{"LocationXmm":7,"LocationYmm":14,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":28,"LowerThresholdCritical":105,"LowerThresholdNonCritical":100,"Name":"21-System Board","Oem":{"Hp":{"LocationXmm":11,"LocationYmm":13,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":24,"LowerThresholdCritical":127,"LowerThresholdNonCritical":126,"Name":"22-P/S Zone","Oem":{"Hp":{"LocationXmm":4,"LocationYmm":9,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":28,"LowerThresholdCritical":0,"LowerThresholdNonCritical":126,"Name":"23-System Board","Oem":{"Hp":{"LocationXmm":4,"LocationYmm":15,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":29,"LowerThresholdCritical":0,"LowerThresholdNonCritical":126,"Name":"24-System Board","Oem":{"Hp":{"LocationXmm":9,"LocationYmm":15,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":29,"LowerThresholdCritical":0,"LowerThresholdNonCritical":126,"Name":"25-System Board","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":15,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":100,"Name":"26-PCI 1","Oem":{"Hp":{"LocationXmm":4,"LocationYmm":13,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":100,"Name":"27-PCI 2","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":13,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":100,"Name":"28-PCI 3","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":13,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":26,"LowerThresholdCritical":0,"LowerThresholdNonCritical":126,"Name":"29-PCI 1 Zone","Oem":{"Hp":{"LocationXmm":4,"LocationYmm":15,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":24,"LowerThresholdCritical":0,"LowerThresholdNonCritical":126,"Name":"30-PCI 2 Zone","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":15,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":25,"LowerThresholdCritical":0,"LowerThresholdNonCritical":126,"Name":"31-PCI 3 Zone","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":15,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"Health":"OK","State":"Enabled"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":100,"Name":"32-LOM Card","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":13,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"Expansion Bay","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":126,"Name":"33-I/O Board","Oem":{"Hp":{"LocationXmm":10,"LocationYmm":15,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"},{"Context":"System Board","CurrentReading":0,"LowerThresholdCritical":0,"LowerThresholdNonCritical":100,"Name":"34-LOM","Oem":{"Hp":{"LocationXmm":6,"LocationYmm":14,"Type":"HpSeaOfSensors.0.9.5"}},"Status":{"State":"Absent"},"Units":"Celsius"}],"Type":"ThermalMetrics.0.9.5","links":{"self":{"href":"/rest/v1/Chassis/1/ThermalMetrics"}}}
А ещё нашли объект, который говорит о состоянии сервера в целом (ОК/fail) и чем он сейчас занимается (в нашем примере он загружался):
# curl -v -k -X GET https://Administrator:Password@192.168.1.235/rest/v1/Chassis/1 -H "Content-Type: application/json"
...
"Status":{"Health":"OK","State":"Starting"}
...
В общем, sh-ник мы в итоге написали и отдали его разработчику. Он над нами посмеялся, мы его за это поругали, пригрозили рута отобрать… Но зато он потом написал модуль в наше облачко, который умеет добавлять и управлять серверами через Redfish (и HP REST API, соответственно). Ну а заказ мы в итоге выполнили.
Наверное, пора закругляться. Расскажем про тех, кто играл главные роли во всей это истории.
- Конечно же, самую главную роль мы отведём серверу ProLiant DL60 Gen9;
- Ещё хотелось бы сказать спасибо утилите hprest, strace-дамп которой помог понять нам, с какой стороны вообще к этой коробке подступиться из консоли;
- Документация по HP Restfull API;
- Python-ProLiant-SDK, который мы сразу не нашли, но который помог сделать production-решение поверх REST API;
- Описание спецификации DMTF.org Redfish — как утверждает HP, во многом основанной на разработках собственных REST API для HP ProLiant
- И, конечно же, компания HP, которая первой запустила в продажу серверы, поддерживающие Redfish, за что мы им и благодарны.
Спасибо за внимание!