- 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.