Skip to content

Commit 25477ab

Browse files
Merge pull request #1 from QualiSystems/dev
Dev
2 parents 1306526 + ee7821d commit 25477ab

21 files changed

Lines changed: 307 additions & 1178 deletions

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ var/
2424
.installed.cfg
2525
*.egg
2626

27+
# Archives
28+
*.zip
29+
spike.bat
30+
.idea/workspace.xml
31+
2732
# PyInstaller
2833
# Usually these files are written by a python script from a template
2934
# before PyInstaller builds the exe, so as to inject date/other infos into it.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 0 additions & 1050 deletions
This file was deleted.

cloudshell/power/pdu/raritan/device/raritan_rpcapi_pdu_factory.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from raritan import rpc
2-
from raritan.rpc import pdumodel
2+
from raritan.rpc import pdumodel, HttpException
33

44
from cloudshell.shell.core.driver_context import AutoLoadDetails, AutoLoadResource, AutoLoadAttribute
55
from cloudshell.power.pdu.raritan.device.rpcapi_outlet import RPCAPIOutlet
@@ -8,14 +8,27 @@
88

99
class RaritanRpcApiPduFactory(PDUFactory):
1010
def __init__(self, context):
11-
self._agent = rpc.Agent("https", context.host, context.user, context.password)
12-
self._pdu_handler = pdumodel.Pdu('model/pdu/0', self._agent)
11+
self._context = context
1312

1413
def get_outlets(self):
15-
return [RPCAPIOutlet(x) for x in self._pdu_handler.getOutlets()]
14+
handler = self._get_handler()
15+
return [RPCAPIOutlet(x) for x in handler.getOutlets()]
16+
17+
def _get_handler(self):
18+
agent = rpc.Agent("https", self._context.host, self._context.user, self._context.password)
19+
return pdumodel.Pdu('model/pdu/0', agent)
1620

1721
def get_inventory(self):
18-
metadata = self._pdu_handler.getMetaData()
22+
handler = self._get_handler()
23+
try:
24+
metadata = handler.getMetaData()
25+
except HttpException as e:
26+
if 'unauthorized' in e.message.lower():
27+
error_msg = 'User is unauthorized to access PDU. Check if username and or password valid'
28+
else:
29+
error_msg = 'Unable to access PDU. Check if PDU address is valid.'
30+
raise Exception(error_msg)
31+
1932
resources = self._autoload_resources_by_rpc()
2033
attributes = [AutoLoadAttribute('', 'Firmware Version', metadata.fwRevision),
2134
AutoLoadAttribute('', 'Vendor', metadata.nameplate.manufacturer),

cloudshell/power/pdu/raritan/device/rpcapi_outlet.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1+
from threading import Lock
2+
13
from raritan.rpc import pdumodel
24
from cloudshell.power.pdu.device.outlet import Outlet
35

46

7+
POWERED_ON = pdumodel.Outlet.PowerState.PS_ON
8+
POWERED_OFF = pdumodel.Outlet.PowerState.PS_OFF
9+
10+
511
class RPCAPIOutlet(Outlet):
612
def __init__(self, outlet_handler):
713
self._handler = outlet_handler
14+
self.lock = Lock()
815

916
def power_on(self):
10-
self._handler.setPowerState(POWERED_ON)
11-
if self._handler.getState().powerState != POWERED_ON:
12-
Exception('Ports were not powered on')
17+
with self.lock:
18+
self._handler.setPowerState(POWERED_ON)
19+
if self._handler.getState().powerState != POWERED_ON:
20+
Exception('Ports were not powered on')
1321

1422
def power_off(self):
15-
self._handler.setPowerState(POWERED_OFF)
16-
if self._handler.getState().powerState != POWERED_OFF:
17-
Exception('Ports were not powered off')
23+
with self.lock:
24+
self._handler.setPowerState(POWERED_OFF)
25+
if self._handler.getState().powerState != POWERED_OFF:
26+
Exception('Ports were not powered off')
1827

19-
POWERED_ON = pdumodel.Outlet.PowerState.PS_ON
20-
POWERED_OFF = pdumodel.Outlet.PowerState.PS_OFF

cloudshell/power/pdu/raritan/raritan_handler.py

Lines changed: 24 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from cloudshell.power.pdu.managed_devices.connected_to_pdu_resource import ConnectedToPduResource
44
from cloudshell.power.pdu.raritan.device.raritan_rpcapi_pdu_factory import RaritanRpcApiPduFactory
55
from cloudshell.power.pdu.raritan.device.factory_context import FactoryContext
6-
from cloudshell.power.pdu.raritan.helper import get_outlets_by_address
6+
from cloudshell.power.pdu.raritan.shell_helper import get_outlets_by_address
77

88

99
class RaritanHandler:
@@ -14,107 +14,51 @@ def __init__(self, pdu_factory=RaritanRpcApiPduFactory):
1414

1515
@property
1616
def outlets(self):
17-
if not self._outlets:
18-
self._outlets = self.pdu.get_outlets()
19-
return self._outlets
17+
return self.pdu.get_outlets()
2018

2119
def initialize(self, context):
20+
pass
21+
22+
def initialize_pdu(self, context):
2223
factory_context = FactoryContext(context)
2324
self.pdu = self._pdu_factory(factory_context)
2425

2526
def get_inventory(self, context):
27+
self.initialize_pdu(context)
2628
return self.pdu.get_inventory()
2729

2830
def power_on(self, context, ports):
31+
self.initialize_pdu(context)
2932
rr = ConnectedToPduResource(context.remote_endpoints)
30-
for o in get_outlets_by_address(ports):
31-
o.power_on
33+
for o in get_outlets_by_address(self.outlets, ports):
34+
o.power_on()
3235
return rr.online()
3336

3437
def power_off(self, context, ports):
38+
self.initialize_pdu(context)
3539
rr = ConnectedToPduResource(context.remote_endpoints)
36-
for o in get_outlets_by_address(ports):
37-
o.power_off
40+
for o in get_outlets_by_address(self.outlets, ports):
41+
o.power_off()
3842
return rr.offline()
3943

4044
def power_cycle(self, context, ports, delay=0):
41-
if delay < 0:
42-
delay = 0
45+
self.initialize_pdu(context)
46+
self._validate_power_cycle_delay(delay)
4347
self.power_off(context, ports)
4448
time.sleep(delay)
4549
self.power_on(context, ports)
4650
return 'Power cycle complete'
4751

48-
49-
50-
51-
52-
53-
54-
55-
56-
57-
58-
59-
60-
61-
62-
63-
64-
65-
66-
67-
68-
69-
70-
71-
72-
73-
74-
75-
76-
77-
78-
79-
80-
81-
82-
83-
84-
85-
86-
87-
88-
89-
90-
91-
92-
93-
94-
95-
# SNMP legacy code
96-
#
97-
# import os
98-
# from cloudshell.configuration.cloudshell_snmp_configuration import SNMP_HANDLER
99-
#
100-
# @property
101-
# def snmp(self):
102-
# if self._snmp is None:
103-
# self._snmp = SNMP_HANDLER()
104-
# path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'mibs'))
105-
# self._snmp.update_mib_sources(path)
106-
# return self._snmp
107-
#
108-
# def _autoload_resources_by_snmp(self):
109-
# outlets = self._get_outlets()
110-
# resources = [AutoLoadResource('Generic Socket',
111-
# 'Socket ' + outlets[outlet]['outletLabel'],
112-
# outlets[outlet]['outletLabel'])
113-
# for outlet in self.outlets]
114-
# return resources
115-
#
116-
# def _get_outlets(self):
117-
# return self.snmp.get_table('PDU2-MIB', 'outletConfigurationTable')
52+
@staticmethod
53+
def _validate_power_cycle_delay(delay):
54+
try:
55+
float(delay)
56+
if delay < 0:
57+
raise ValueError('Must be non negative number')
58+
except ValueError:
59+
raise Exception('Delay represents the seconds between power off and power on. \n'
60+
'You ran the power cycle command with a delay argument of {0}, '
61+
'but acceptable values are 0 or a positive numeric value'.format(delay))
11862

11963

12064

cloudshell/power/pdu/raritan/raritan_resource_driver.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,47 @@ def cleanup(self):
2626

2727
@context_from_args
2828
def get_inventory(self, context):
29-
"""
30-
Return device structure with all standard attributes
31-
:return: result
32-
:rtype: string
29+
""" Returns device resource, sub-resources and attributes
30+
3331
:type context: cloudshell.shell.core.driver_context.AutoLoadCommandContext
32+
:rtype: cloudshell.shell.core.driver_context.AutoLoadDetails
3433
"""
3534
return self.handler.get_inventory(context=context)
3635

3736
@context_from_args
3837
def PowerOn(self, context, ports):
39-
return self.handler.power_on(context, ports)
38+
""" Powers on outlets on the managed PDU
4039
40+
:type context: cloudshell.shell.core.driver_context.ResourceRemoteCommandContext
41+
:param ports: full addresses of outlets on PDU, example: ['192.168.30.128/4', '192.168.30.128/6']
42+
:type ports: str
43+
:return: command result message
44+
:rtype: str
45+
"""
46+
return self.handler.power_on(context, ports)
4147

4248
@context_from_args
4349
def PowerOff(self, context, ports):
50+
""" Powers off outlets on the managed PDU
51+
52+
:type context: cloudshell.shell.core.driver_context.ResourceRemoteCommandContext
53+
:param ports: full addresses of outlets on PDU, example: ['192.168.30.128/4', '192.168.30.128/6']
54+
:type ports: str
55+
:return: command result message
56+
:rtype: str
57+
"""
4458
return self.handler.power_off(context, ports)
4559

4660
@context_from_args
4761
def PowerCycle(self, context, ports, delay=0):
62+
""" Powers off outlets, waits during delay, then powers outlets on
63+
64+
:type context: cloudshell.shell.core.driver_context.ResourceRemoteCommandContext
65+
:param ports: full addresses of outlets on PDU, example: ['192.168.30.128/4', '192.168.30.128/6']
66+
:type ports: str
67+
:param delay: seconds to wait after power off
68+
:type delay: int
69+
:return: command result message
70+
:rtype: str
71+
"""
4872
return self.handler.power_cycle(context, ports)
File renamed without changes.

raritan_pdu_shell_package/Configuration/shellconfig.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ xmlns="http://schemas.qualisystems.com/ResourceManagement/ShellsConfigurationSch
1010
<Description>Discovers the device structure and populate its attributes.</Description>
1111
</AutoLoad>
1212
<Attributes>
13-
<Attribute Name="SNMP Version" Value="" />
13+
<!--<Attribute Name="SNMP Version" Value="" />
1414
<Attribute Name="SNMP Read Community" Value="" />
1515
<Attribute Name="SNMP Write Community" Value="" />
1616
<Attribute Name="SNMP V3 User" Value="" />
1717
<Attribute Name="SNMP V3 Password" Value="" />
1818
<Attribute Name="SNMP V3 Private Key" Value="" />
19-
<Attribute Name="CLI Connection Type" Value="Auto" />
19+
<Attribute Name="CLI Connection Type" Value="Auto" />-->
2020
<Attribute Name="User" Value="" />
2121
<Attribute Name="Password" Value="" />
22-
<Attribute Name="Sessions Concurrency Limit" Value="1" />
22+
<!--<Attribute Name="Sessions Concurrency Limit" Value="1" />
2323
<Attribute Name="Firmware Version" Value=""/>
2424
<Attribute Name="Model" Value="" />
25-
<Attribute Name="Vendor" Value="" />
25+
<Attribute Name="Vendor" Value="" />-->
2626
</Attributes>
2727
</ResourceTemplate>
2828
</ResourceTemplates>

0 commit comments

Comments
 (0)