Skip to content

Commit

Permalink
Merge pull request #1 from QualiSystems/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
nahumtimerman authored Oct 5, 2016
2 parents 1306526 + ee7821d commit 25477ab
Show file tree
Hide file tree
Showing 21 changed files with 307 additions and 1,178 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ var/
.installed.cfg
*.egg

# Archives
*.zip
spike.bat
.idea/workspace.xml

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
Expand Down
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1,050 changes: 0 additions & 1,050 deletions .idea/workspace.xml

This file was deleted.

23 changes: 18 additions & 5 deletions cloudshell/power/pdu/raritan/device/raritan_rpcapi_pdu_factory.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from raritan import rpc
from raritan.rpc import pdumodel
from raritan.rpc import pdumodel, HttpException

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

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

def get_outlets(self):
return [RPCAPIOutlet(x) for x in self._pdu_handler.getOutlets()]
handler = self._get_handler()
return [RPCAPIOutlet(x) for x in handler.getOutlets()]

def _get_handler(self):
agent = rpc.Agent("https", self._context.host, self._context.user, self._context.password)
return pdumodel.Pdu('model/pdu/0', agent)

def get_inventory(self):
metadata = self._pdu_handler.getMetaData()
handler = self._get_handler()
try:
metadata = handler.getMetaData()
except HttpException as e:
if 'unauthorized' in e.message.lower():
error_msg = 'User is unauthorized to access PDU. Check if username and or password valid'
else:
error_msg = 'Unable to access PDU. Check if PDU address is valid.'
raise Exception(error_msg)

resources = self._autoload_resources_by_rpc()
attributes = [AutoLoadAttribute('', 'Firmware Version', metadata.fwRevision),
AutoLoadAttribute('', 'Vendor', metadata.nameplate.manufacturer),
Expand Down
23 changes: 15 additions & 8 deletions cloudshell/power/pdu/raritan/device/rpcapi_outlet.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
from threading import Lock

from raritan.rpc import pdumodel
from cloudshell.power.pdu.device.outlet import Outlet


POWERED_ON = pdumodel.Outlet.PowerState.PS_ON
POWERED_OFF = pdumodel.Outlet.PowerState.PS_OFF


class RPCAPIOutlet(Outlet):
def __init__(self, outlet_handler):
self._handler = outlet_handler
self.lock = Lock()

def power_on(self):
self._handler.setPowerState(POWERED_ON)
if self._handler.getState().powerState != POWERED_ON:
Exception('Ports were not powered on')
with self.lock:
self._handler.setPowerState(POWERED_ON)
if self._handler.getState().powerState != POWERED_ON:
Exception('Ports were not powered on')

def power_off(self):
self._handler.setPowerState(POWERED_OFF)
if self._handler.getState().powerState != POWERED_OFF:
Exception('Ports were not powered off')
with self.lock:
self._handler.setPowerState(POWERED_OFF)
if self._handler.getState().powerState != POWERED_OFF:
Exception('Ports were not powered off')

POWERED_ON = pdumodel.Outlet.PowerState.PS_ON
POWERED_OFF = pdumodel.Outlet.PowerState.PS_OFF
104 changes: 24 additions & 80 deletions cloudshell/power/pdu/raritan/raritan_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from cloudshell.power.pdu.managed_devices.connected_to_pdu_resource import ConnectedToPduResource
from cloudshell.power.pdu.raritan.device.raritan_rpcapi_pdu_factory import RaritanRpcApiPduFactory
from cloudshell.power.pdu.raritan.device.factory_context import FactoryContext
from cloudshell.power.pdu.raritan.helper import get_outlets_by_address
from cloudshell.power.pdu.raritan.shell_helper import get_outlets_by_address


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

@property
def outlets(self):
if not self._outlets:
self._outlets = self.pdu.get_outlets()
return self._outlets
return self.pdu.get_outlets()

def initialize(self, context):
pass

def initialize_pdu(self, context):
factory_context = FactoryContext(context)
self.pdu = self._pdu_factory(factory_context)

def get_inventory(self, context):
self.initialize_pdu(context)
return self.pdu.get_inventory()

def power_on(self, context, ports):
self.initialize_pdu(context)
rr = ConnectedToPduResource(context.remote_endpoints)
for o in get_outlets_by_address(ports):
o.power_on
for o in get_outlets_by_address(self.outlets, ports):
o.power_on()
return rr.online()

def power_off(self, context, ports):
self.initialize_pdu(context)
rr = ConnectedToPduResource(context.remote_endpoints)
for o in get_outlets_by_address(ports):
o.power_off
for o in get_outlets_by_address(self.outlets, ports):
o.power_off()
return rr.offline()

def power_cycle(self, context, ports, delay=0):
if delay < 0:
delay = 0
self.initialize_pdu(context)
self._validate_power_cycle_delay(delay)
self.power_off(context, ports)
time.sleep(delay)
self.power_on(context, ports)
return 'Power cycle complete'
















































# SNMP legacy code
#
# import os
# from cloudshell.configuration.cloudshell_snmp_configuration import SNMP_HANDLER
#
# @property
# def snmp(self):
# if self._snmp is None:
# self._snmp = SNMP_HANDLER()
# path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'mibs'))
# self._snmp.update_mib_sources(path)
# return self._snmp
#
# def _autoload_resources_by_snmp(self):
# outlets = self._get_outlets()
# resources = [AutoLoadResource('Generic Socket',
# 'Socket ' + outlets[outlet]['outletLabel'],
# outlets[outlet]['outletLabel'])
# for outlet in self.outlets]
# return resources
#
# def _get_outlets(self):
# return self.snmp.get_table('PDU2-MIB', 'outletConfigurationTable')
@staticmethod
def _validate_power_cycle_delay(delay):
try:
float(delay)
if delay < 0:
raise ValueError('Must be non negative number')
except ValueError:
raise Exception('Delay represents the seconds between power off and power on. \n'
'You ran the power cycle command with a delay argument of {0}, '
'but acceptable values are 0 or a positive numeric value'.format(delay))



34 changes: 29 additions & 5 deletions cloudshell/power/pdu/raritan/raritan_resource_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,47 @@ def cleanup(self):

@context_from_args
def get_inventory(self, context):
"""
Return device structure with all standard attributes
:return: result
:rtype: string
""" Returns device resource, sub-resources and attributes
:type context: cloudshell.shell.core.driver_context.AutoLoadCommandContext
:rtype: cloudshell.shell.core.driver_context.AutoLoadDetails
"""
return self.handler.get_inventory(context=context)

@context_from_args
def PowerOn(self, context, ports):
return self.handler.power_on(context, ports)
""" Powers on outlets on the managed PDU
:type context: cloudshell.shell.core.driver_context.ResourceRemoteCommandContext
:param ports: full addresses of outlets on PDU, example: ['192.168.30.128/4', '192.168.30.128/6']
:type ports: str
:return: command result message
:rtype: str
"""
return self.handler.power_on(context, ports)

@context_from_args
def PowerOff(self, context, ports):
""" Powers off outlets on the managed PDU
:type context: cloudshell.shell.core.driver_context.ResourceRemoteCommandContext
:param ports: full addresses of outlets on PDU, example: ['192.168.30.128/4', '192.168.30.128/6']
:type ports: str
:return: command result message
:rtype: str
"""
return self.handler.power_off(context, ports)

@context_from_args
def PowerCycle(self, context, ports, delay=0):
""" Powers off outlets, waits during delay, then powers outlets on
:type context: cloudshell.shell.core.driver_context.ResourceRemoteCommandContext
:param ports: full addresses of outlets on PDU, example: ['192.168.30.128/4', '192.168.30.128/6']
:type ports: str
:param delay: seconds to wait after power off
:type delay: int
:return: command result message
:rtype: str
"""
return self.handler.power_cycle(context, ports)
File renamed without changes.
8 changes: 4 additions & 4 deletions raritan_pdu_shell_package/Configuration/shellconfig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ xmlns="http://schemas.qualisystems.com/ResourceManagement/ShellsConfigurationSch
<Description>Discovers the device structure and populate its attributes.</Description>
</AutoLoad>
<Attributes>
<Attribute Name="SNMP Version" Value="" />
<!--<Attribute Name="SNMP Version" Value="" />
<Attribute Name="SNMP Read Community" Value="" />
<Attribute Name="SNMP Write Community" Value="" />
<Attribute Name="SNMP V3 User" Value="" />
<Attribute Name="SNMP V3 Password" Value="" />
<Attribute Name="SNMP V3 Private Key" Value="" />
<Attribute Name="CLI Connection Type" Value="Auto" />
<Attribute Name="CLI Connection Type" Value="Auto" />-->
<Attribute Name="User" Value="" />
<Attribute Name="Password" Value="" />
<Attribute Name="Sessions Concurrency Limit" Value="1" />
<!--<Attribute Name="Sessions Concurrency Limit" Value="1" />
<Attribute Name="Firmware Version" Value=""/>
<Attribute Name="Model" Value="" />
<Attribute Name="Vendor" Value="" />
<Attribute Name="Vendor" Value="" />-->
</Attributes>
</ResourceTemplate>
</ResourceTemplates>
Expand Down
Loading

0 comments on commit 25477ab

Please sign in to comment.