- Infrastrukturní DevOps s HPE OneView (1) – Infrastructure as Code
- Infrastrukturní DevOps s HPE OneView (2) – API
- Infrastrukturní DevOps s HPE OneView (3) – Message bus
- Infrastrukturní DevOps s HPE OneView (4) – PowerShell
- Infrastrukturní DevOps s HPE OneView (5) – PowerShell skripty
- Infrastrukturní DevOps s HPE OneView (6) – Python
- Infrastrukturní DevOps s HPE OneView (7) – Python skripty
- Infrastrukturní DevOps s HPE OneView (8) – vaše vlastní aplikace s Grommet
- Infrastrukturní DevOps s HPE OneView (9) – Ansible a infrastruktura
- Infrastrukturní DevOps s HPE OneView (10) – Ansible a Blade networking
- Infrastrukturní DevOps s HPE OneView (11) – Ansible a síťový fabric
- Infrastrukturní DevOps s HPE OneView (12) – Ansible a servery
V minulém díle jsme se seznámili se základním popisem infrastruktury v YAML a ukázali jsme si tři role, které budeme používat. Dnes prozkoumáme detaily první z nich – Blade networking.
Role vs. Playbook/Task vs. Module
Ansible má hierarchii abstrakcí. To co dělat nemusíme je psát modul, to za nás udělali zaměstnanci HPE a stáhneme si to jako open source z GitHub. Jde o vytvoření základních OneView operací. Pro nás to jsou hotové věci, ale pod kapotou je Python kód, který je transformuje do jednotlivých API volání. Tím se ale trápit nemusíme.
V minulém díle jsme viděli top level YAML soubor, kde jsme pouze určili role a přiřadili jim soubor s nastavením infrastruktury. Role jsou vyšší míra abstrakce. Existuje jejich repozitář, můžete je stahovat i sdílet. Pro tuto ukázku jsem si ovšem role připravil sám.
Co role ov-networking dělá a jak
Podívejme se společně do main.yaml v rámci role on-networking/tasks. První krok je tento:
- name: Ensure that Networks exist
oneview_ethernet_network:
config: "{{ oneview_config_file }}"
state: "{{ state }}"
data:
name: "{{ item.name }}"
vlanId: "{{ item.id }}"
smartLink: true
privateNetwork: false
purpose: General
with_items: "{{ vlans }}"
register: networks
Nejprve se tedy potřebujeme ujistit, že sítě, které požadujeme, skutečně ve OneView existují. Používáme OneView příkaz oneview_ethernet_network. Config obsahuje přihlašovací údaje a v state máme ve výchozím stavu present, tedy chceme sítě mít. Pokud nejsou, mají se vytvořit. Pokud dáte stav absent, bude to fungovat opačně.
Ještě než se dostaneme k části data musím zmínit with_items. To je něco, co byste v programování označili jako cyklus typu for each. Příkaz chceme provést pro každou požadovanou VLAN. A kde se tyto berou? No to je z našeho předpisu infrastruktury (config.yaml), který jsme rozebrali minule – konkrétně tato část:
vlans:
- id: 101
name: Prod-101
- id: 102
name: Prod-102
- id: 103
name: Dev-103
Teď se můžeme podívat do části data. Tam jsou parametry pro jednotlivá volání příkazu oneview_ethernet_network. Místo fixních parametrů občas dosazujeme item (což je políčko, na kterém se cyklus zrovna nachází) a za tečkou je klíč, tedy buď id nebo name. Takže při první volání příkazu bude item.id=101 a item.name=Prod-101 a tak postupně dál. Poslední, co musíme okomentovat, je slovíčko register. Jde o to, že každé volání příkazu nám současně vrátilo nějaké informace a některé z nich budeme potřebovat dál. Proto si veškeré výstupy registrujeme do proměnné networks.
Podívejme se na druhý krok.
- name: Store network URIs in list
set_fact:
network_uris: "{{ networks.results | map(attribute='ansible_facts.ethernet_network.uri') | list }}"
Tohle je technikálie. Pro další příkazy potřebuji URI sítí seřazené v seznamu. Výstupy předchozího příkazu obsahují hromadu dalších informací. Zabudovaným Ansible příkazem set_fact přetransformujeme informace z networks do pouhého seznamu URI uloženého v network_uris.
Jdeme dál. Teď potřebujeme tyto sítě přidat na naší skupinu logických interconnectů a tu máme popsanou v našem config-yaml.
- name: Ensure networks are present on Logical interconnect group
oneview_logical_interconnect_group:
config: "{{ oneview_config_file }}"
state: present
data:
type: "logical-interconnect-groupV3"
name: "{{ logical_interconnect_group }}"
internalNetworkUris: "{{ network_uris }}"
Poslední v tomto souboru je rekurzivní příkaz. Chceme vyvolat playbook uplinksets.yaml tak, že pokaždé mu pošleme konkrétní hodnoty ze seznamu connectivity_enclosures.
- name: Ensure UplinkSets are configured
include: uplinksets.yaml
with_items: "{{ connectivity_enclosures }}"
Připomeňme si tuto část našeho config.yaml.
connectivity_enclosures:
- logical_interconnects:
- module: Encl1, interconnect 1
ports:
- X2
- X4
switchports:
- GigabitEthernet 1/0/2
- GigabitEthernet 1/0/3
switch_link_aggregation_group: 1
- module: Encl1, interconnect 2
ports:
- X2
- X4
switchports:
- GigabitEthernet 1/0/4
- GigabitEthernet 1/0/5
switch_link_aggregation_group: 2
- logical_interconnects:
- module: Encl2, interconnect 1
ports:
- X2
- X4
switchports:
- GigabitEthernet 1/0/6
- GigabitEthernet 1/0/7
switch_link_aggregation_group: 3
- module: Encl2, interconnect 2
ports:
- X2
- X4
switchports:
- GigabitEthernet 1/0/8
- GigabitEthernet 1/0/9
V každém volání tedy dostaneme jeden konkrétní modul a seznam jeho portů.
Pro každý modul a seznam portů tedy budeme dělat následující kroky.
Nejprve provedeme řadu přípravných prací. Poskládáme si parametry do správné formy, vytvoříme JSON strukturu s nastavením portu a tak podobně.
- name: Create map with facts about interconnects
oneview_interconnect_facts:
config: "{{ oneview_config_file }}"
name: "{{ item.module }}"
with_items: "{{ item.logical_interconnects }}"
register: interconnects_map
- name: Build port configurations
set_fact:
port_config: '{
"desiredSpeed": "Auto",
"location": {
"locationEntries": [
{
"type": "Port",
"value": "{{ item[1] }}"
},
{{ item[0].ansible_facts.interconnects[0].interconnectLocation.locationEntries[0] }},
{{ item[0].ansible_facts.interconnects[0].interconnectLocation.locationEntries[1] }}
]
}
}'
with_subelements:
- "{{ interconnects_map.results }}"
- "item.ports"
register: port_map
- name: Map port configurations to JSON array
set_fact:
port_configs: "{{ port_map.results | map(attribute='ansible_facts.port_config') | list }}"
- name: Get Logical Interconnect URI
set_fact:
l_interconnect: "{{ interconnects_map.results[0].ansible_facts.interconnects[0].logicalInterconnectUri }}"
Všechno je připraveno, takže můžeme zavolat příkaz oneview_uplink_set. V datové části mu posíláme seznam sítí, které na portech chceme mít a také jednotlivé konfigurace požadovaných portů, které jsme si připravili v předchozím kroku.
- name: Ensure that the Uplink Set with Networks is present
oneview_uplink_set:
config: "{{ oneview_config_file }}"
state: "{{ state }}"
data:
type: "uplink-setV3"
name: "Ansible-uplink{{ interconnects_map.results[0].ansible_facts.interconnects[0].name }}"
status: "OK"
logicalInterconnectUri: "{{ l_interconnect }}"
networkUris: "{{ network_uris }}"
fcNetworkUris: []
fcoeNetworkUris: []
portConfigInfos: "{{ port_configs }}"
connectionMode: "Auto"
networkType: "Ethernet"
manualLoginRedistributionState: "NotSupported"
A máme hotovo ! Sítě ve OneView jsou vytvořené a přiřazené na správné moduly a porty podle toho, co jsme si napsali v config.yaml. Chcete přidat další VLAN? Stačí ji připsat do config.yaml a spustit vše znovu. Ansible ji přidá všude, kde je potřeba. Potřebujete přidat další externí port, kde budou sítě nastavené? Připiště ho do seznamu a spusťte Ansible znova.
Dnes jsme si rozebrali první roli, která nastavuje networking v blade chassis přes OneView. Příště se podíváme na druhou roli, která nastavuje připojený top-of-rack síťový prvek, v našem případě HPE 5900 s Comware.
