- 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
Minule jsme si vyzkoušeli Python knihovnu pro OneView v interaktivním režimu a dnes navážeme s tvorbou užitečnějších skriptů. Po stránce funkčnosti to bude totéž, co jsme dělali s PowerShell. Všechny sripty najdete na:
https://github.com/tkubica12/oneview-demo/tree/master/python
Práce s Volume
První skript slouží k vytvoření hned několika Volume ve vaší storage spravované přes OneView v řadě. Podívejme se jak vypadá a pak okomentujeme, co se tam děje.
#!/usr/bin/python
# Script to demonstrate OneView Python interaction
# Creating one or more volumes
# Tomas Kubica
import hpOneView as ov
import argparse
# Let's just parse script inputs
parser = argparse.ArgumentParser(description='Creating storage Volumes via OneView')
parser.add_argument('--ov-server', help='OneView IP address',
dest='oneview_server', default='192.168.89.100')
parser.add_argument('--ov-user', help='OneView username',
dest='oneview_user', default='Administrator')
parser.add_argument('--ov-password', help='OneView password',
dest='oneview_password', default='HPEnet123')
parser.add_argument('--storage-pool', help='Storage pool name',
dest='storage_pool',default='CPG-SSD')
parser.add_argument('--volumes', help='Volumes to be created',
dest='volumes', nargs='+', required=True)
parser.add_argument('--volume-size', help='Volume size',
dest='volume_size', default=2)
parser.add_argument('--volume-sharing', action='store_true',
dest='volume_sharing')
parser.add_argument('--volume-provisioning', help='Volume provisioning',
dest='volume_provisioning', default='Thin')
args = parser.parse_args()
# Get connection and log into OneView
con = ov.connection(args.oneview_server)
login = {'userName':args.oneview_user,'password':args.oneview_password}
con.login(login)
# Get access to storage resources
storage = ov.storage(con)
pools = storage.get_storage_pools()
for pool in pools['members']:
# Find specified storage pool
if pool['name'] == args.storage_pool:
storagePoolUri = pool['uri']
# Loop throw volumes scpecified in input
for vol in args.volumes:
# Create volumes
print 'Adding volume: ', vol
volume = ov.common.make_storage_volume(vol,
int(args.volume_size)*1024*1024*1024,
args.volume_sharing,
storagePoolUri,
'Created via script',
args.volume_provisioning)
result = storage.add_storage_volume(volume)
if 'deviceVolumeName' in result:
print 'Name: ', result['name']
print 'Type: ', result['type']
print 'State: ', result['state']
print 'Allocated Capacity: ', result['allocatedCapacity']
print 'Provisioned Capacity: ', result['provisionedCapacity']
print
else:
print result
V první části definujeme vstupní argumenty tohoto skriptu (samo to za nás udělá zpracování i případný tisk nápovědy). U některých parametrů, typicky údaje pro připojení do OneView appliance, jsou nějaké výchozí hodnoty (abych to nemusel pořád ťukat), ale můžete je přepsat zadáním přímo při spuštění.
Následně si vytvoříme connection objekt a nalogujeme se a také založíme storage objekt. Stáhneme si storage pooly a vyhledáme ten náš. Pak už jen projdeme zadaný seznam názvů volume a postupně je vytvoříme.
Takhle to vypadá, když to spustíme:
C:\git\oneview-demo\python>python ./createVolume.py --volumes pstore1 pstore2 pstore3 --volume-size 1 Adding volume: pstore1 Name: pstore1 Type: StorageVolumeV3 State: Configured Allocated Capacity: 536870912 Provisioned Capacity: 1073741824 Adding volume: pstore2 Name: pstore2 Type: StorageVolumeV3 State: Configured Allocated Capacity: 536870912 Provisioned Capacity: 1073741824 Adding volume: pstore3 Name: pstore3 Type: StorageVolumeV3 State: Configured Allocated Capacity: 536870912 Provisioned Capacity: 1073741824
Najdeme je i v GUI.
Druhým skriptem je můžeme zase smazat. Kód vypadá takhle:
#!/usr/bin/python
# Script to demonstrate OneView Python interaction
# Deleting one or more volumes
# Tomas Kubica
import hpOneView as ov
import argparse
# Let's just parse script inputs
parser = argparse.ArgumentParser(description='Deleting storage Volumes via OneView')
parser.add_argument('--ov-server', help='OneView IP address',
dest='oneview_server', default='192.168.89.100')
parser.add_argument('--ov-user', help='OneView username',
dest='oneview_user', default='Administrator')
parser.add_argument('--ov-password', help='OneView password',
dest='oneview_password', default='HPEnet123')
parser.add_argument('--storage-pool', help='Storage pool name',
dest='storage_pool', default='CPG-SSD')
parser.add_argument('--volumes', help='Volumes to be created',
dest='volumes', nargs='+', required=True)
args = parser.parse_args()
# Get connection and log into OneView
con = ov.connection(args.oneview_server)
login = {'userName':args.oneview_user,'password':args.oneview_password}
con.login(login)
# Get access to storage resources
storage = ov.storage(con)
pools = storage.get_storage_pools()
for pool in pools['members']:
# Find specified storage pool
if pool['name'] == args.storage_pool:
storagePoolUri = pool['uri']
existing_volumes = storage.get_storage_volumes()
# Loop throw volumes specified in input
for vol in args.volumes:
# Loop throw existing volumes
for existing_volume in existing_volumes['members']:
# Is this volume we want to remove?
if existing_volume['name'] == vol:
# Remove volume
print 'Removing Storage Volume: ', existing_volume['name']
storage.remove_storage_volume(existing_volume)
A tohle dělá po spuštění:
C:\git\oneview-demo\python>python ./deleteVolume.py --volumes pstore1 pstore2 pstore3 Removing Storage Volume: pstore1 Removing Storage Volume: pstore2 Removing Storage Volume: pstore3
Vytvoříme si server
Dejme tomu, že potřebujeme skriptem nabootovat hned několik fyzických serverů určitého typu, například blade žiletku BL 460c Gen9. Chceme tedy, aby skript našel nějakou, která není používána (nemá přiřazený profil) a na tu nám profil vytvořil. Aby to mohl udělat, musí být ovšem server vypnutý, takže pokud to tak není, nechť to skript udělá. Server ale také chceme nějak připojený ven, takže skriptu potřebujeme jako parametr předat jméno připraveného napojení směrem ven. Budeme chtít lokální storage a tak by se nám hodilo, abychom mohli skriptu říct, jak má řadič nastavit – zda bez raidu, nebo v raidu 0 či 1. Výsledek bude vypadat nějak takhle:
#!/usr/bin/python
# Script to demonstrate OneView Python interaction
# Creating and booting one or more servers
# Tomas Kubica
import hpOneView as ov
import hpOneView.profile as profile
import argparse
# Let's just parse script inputs
parser = argparse.ArgumentParser(description='Creating servers OneView')
parser.add_argument('--ov-server', help='OneView IP address',
dest='oneview_server', default='192.168.89.100')
parser.add_argument('--ov-user', help='OneView username',
dest='oneview_user', default='Administrator')
parser.add_argument('--ov-password', help='OneView password',
dest='oneview_password', default='HPEnet123')
parser.add_argument('--servers', help='Servers to be created',
dest='servers', nargs='+', required=True)
parser.add_argument('--hardware', help='Hardware type',
dest='hardware', default='BL460c Gen9 1')
parser.add_argument('--connection', help='Network profile',
dest='connection', required=False)
parser.add_argument('--raid', dest='raid', required=False,
choices=['NONE', 'RAID0', 'RAID1'],
help='Choose raid level on local storage')
parser.add_argument('--drives', dest='drives', required=False,
help='Number of local storage disks')
args = parser.parse_args()
# Get connection and log into OneView
con = ov.connection(args.oneview_server)
login = {'userName':args.oneview_user,'password':args.oneview_password}
con.login(login)
# Get access to compute and network resources
compute = ov.servers(con)
net = ov.networking(con)
selectedServer = ''
# We will loop over servers specified in input
print 'Creating servers...'
for server in args.servers:
# Get list of unassigned servers and select first available
unassignedServers = compute.get_available_servers()
for unassignedServer in unassignedServers['targets']:
if unassignedServer['serverHardwareTypeName'] == args.hardware:
selectedServer = unassignedServer
break
# Check whether server is power on and if yes, power off
if selectedServer['powerState'] != 'Off':
print 'Shutting down server', selectedServer['serverHardwareName']
compute.set_server_powerstate(
compute.get_server_by_name(selectedServer['serverHardwareName']),
'Off', force=True, blocking=True)
# Create connection profile
if args.connection:
networks = net.get_enet_networks()
netw = None
for network in networks:
if network['name'] == args.connection:
netw = network
break
connectionProfile = ov.common.make_ProfileConnectionV4(cid=1,
name='My_connection',
networkUri=netw['uri'],
functionType='Ethernet',
profileTemplateConnection=True)
# Create local storage profile
if args.raid:
storageProfile = profile.make_local_storage_dict(sht=con.get(selectedServer['serverHardwareUri']),
raidlevel=args.raid,
lboot=False,
init_storage=True,
num=args.drives,
drive_name='MyDrive')
# Create server profile
print 'Creating profile of server', server
if (args.raid and args.connection):
result = compute.create_server_profile(name=server,
serverHardwareUri=selectedServer['serverHardwareUri'],
localStorageSettingsV3=storageProfile,
profileConnectionV4=[connectionProfile])
elif (args.raid):
result = compute.create_server_profile(name=server,
serverHardwareUri=selectedServer['serverHardwareUri'],
localStorageSettingsV3=storageProfile)
elif (args.connection):
result = compute.create_server_profile(name=server,
serverHardwareUri=selectedServer['serverHardwareUri'],
profileConnectionV4=[connectionProfile])
else:
result = compute.create_server_profile(name=server,
serverHardwareUri=selectedServer['serverHardwareUri'])
print 'Created profile %s on %s' % (server, selectedServer['serverHardwareName'])
# Boot server
print 'Booting server', server
compute.set_server_powerstate(compute.get_server_by_name(selectedServer['serverHardwareName']), 'On')
print
Stejně jako v PowerShellu dělá náš skript víc operací. Pro jednotlivé požadavané servery jistého hardwarového typu nejprve vyhledá první volný server (žiletku bez přiřazeného profilu). Pokud běží, vypne ji, aby mohl aplikovat profil. Pokud je to potřeba vytvoří si objekty reprezentující LAN spojení a také nastavení lokální storage (úroveň RAID, počet fyzických disků v logickém volume). Následně vytvoří profil, sváže ho se serverem a ten nabootuje. Takhle to vypadá:
C:\git\oneview-demo\python>python ./createServer.py --servers srv1 srv2 srv3 --connection PROD_10 --raid RAID1 --drives 2 Creating servers... Shutting down server Encl2, bay 11 Creating profile of server srv1 Created profile srv1 on Encl2, bay 11 Booting server srv1 Shutting down server Encl1, bay 11 Creating profile of server srv2 Created profile srv2 on Encl1, bay 11 Booting server srv2 Shutting down server Encl2, bay 12 Creating profile of server srv3 Created profile srv3 on Encl1, bay 12 Booting server srv3
A v GUI je můžeme najít:
Jakmile doplníte Insight Control Server Provisioning nebo Synergy s komponentou Image Streamer můžete takto ovládat i výsledný image, do kterého vám fyzický server naběhne.


