From 6ffbd4aec8708611696ce1c4160f41e9174cefbc Mon Sep 17 00:00:00 2001
From: Uggla <uggla@free.fr>
Date: Sat, 9 Jan 2016 19:07:51 +0100
Subject: [PATCH] Add manager functions

- Add function get_managed_chassis.
- Add function get_managed_systems.
- Modiy mapping to handle proliant fw 2.40 bugs reporting :
  - links instead of Links.
  - href instead of @odata.id.
- I'll report this bug to redfish folks.
- Various PEP8 cleans.
---
 redfish-client/redfish-client.py |  4 +++
 redfish/main.py                  |  7 ++--
 redfish/mapping.py               | 55 ++++++++++++++++++++++----------
 redfish/types.py                 | 34 +++++++++++++++++++-
 4 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/redfish-client/redfish-client.py b/redfish-client/redfish-client.py
index edfaa15..af2530f 100755
--- a/redfish-client/redfish-client.py
+++ b/redfish-client/redfish-client.py
@@ -263,6 +263,8 @@ if __name__ == '__main__':
             print('Type : {}').format(manager.get_type())
             print('Firmware version : {}').format(manager.get_firmware_version())
             print('State : {}').format(manager.get_status())
+            print manager.get_managed_chassis()
+            print manager.get_managed_systems()
             print('Ethernet interfaces :')
             try :
                 for ethernetinterface_index in sorted(manager.ethernet_interfaces_collection.ethernet_interfaces_dict):
@@ -270,6 +272,8 @@ if __name__ == '__main__':
                     print('\nEthernet Interface id {} :').format(ethernetinterface_index)
                     print(ei.get_name())
                     print(ei.get_parameter('FQDN'))
+                    print ei.get_ipv4()
+                    print ei.get_ipv6()
             except AttributeError:
                 # We don't have ethernet interfaces
                 pass
diff --git a/redfish/main.py b/redfish/main.py
index 838554b..3a28cf0 100644
--- a/redfish/main.py
+++ b/redfish/main.py
@@ -209,9 +209,10 @@ class RedfishConnection(object):
 
         config.logger.info("API Version : %s", self.get_api_version())
         mapping.redfish_version = self.get_api_version()
+        mapping.redfish_root_name = self.Root.get_name()
 
-        # Instanciate a global mapping object to handle Redfish version variation
-        mapping.redfish_mapper = mapping.RedfishVersionMapping(self.get_api_version())
+        # Instantiate a global mapping object to handle Redfish version variation
+        mapping.redfish_mapper = mapping.RedfishVersionMapping(self.get_api_version(), self.Root.get_name())
 
         # Now we need to login otherwise we are not allowed to extract data
         if self.__simulator is False:
@@ -225,7 +226,7 @@ class RedfishConnection(object):
 
 
 
-        # Struture change with mockup 1.0.0, there is no links
+        # Structure change with mockup 1.0.0, there is no links
         # section anymore.
         # ===================================================================
         # TODO : Add a switch to allow the both structure
diff --git a/redfish/mapping.py b/redfish/mapping.py
index 309e23a..f999cd2 100644
--- a/redfish/mapping.py
+++ b/redfish/mapping.py
@@ -2,30 +2,51 @@
 
 redfish_mapper = None
 redfish_version = None
+redfish_root_name = None
 
 class RedfishVersionMapping(object):
-    """Implements basic url path mapping beetween Redfish versions."""
+    '''Implements basic url path mapping beetween Redfish versions.'''
 
-    def __init__(self, version):
+    def __init__(self, version, rootname):
         self.__version = version
+        self.__rootname = rootname
 
     def map_sessionservice(self):
-        if self.__version == "0.95":
-            return "Sessions"
-        return("SessionService")
-        
+        if self.__version == '0.95':
+            return 'Sessions'
+        return 'SessionService'
 
-    def map_links(self):
-        if self.__version == "0.95":
-            return "links"
-        return("Links")  
+    def map_links(self, data_dict=None):
+        if data_dict == None:
+            if self.__version == '0.95':
+                return 'links'
+        else:
+            # Checking if we have Links or links.
+            # This is to deal with proliant firmware 2.40 bug that reports
+            # incorrectly links instead of Links (Redfish standard)
+            try:
+                data_dict.links
+                return 'links'
+            except AttributeError:
+                pass
+        return 'Links'
 
-    def map_links_ref(self):
-        if self.__version == "0.95":
-            return "href"
-        return("@odata.id")
+    def map_links_ref(self, data_dict=None):
+        if data_dict == None:
+            if self.__version == '0.95':
+                return 'href'
+        else:
+            # Checking if we have @odata.id or href.
+            # This is to deal with proliant firmware 2.40 bug that reports
+            # incorrectly href instead of @odata.id (Redfish standard)
+            try:
+                data_dict.href
+                return 'href'
+            except AttributeError:     
+                pass       
+        return '@odata.id'
     
     def map_members(self):
-        if self.__version == "0.95":
-            return "Member"
-        return("Members")
\ No newline at end of file
+        if self.__version == '0.95':
+            return 'Member'
+        return 'Members'
\ No newline at end of file
diff --git a/redfish/types.py b/redfish/types.py
index a4075e6..3a5bac1 100644
--- a/redfish/types.py
+++ b/redfish/types.py
@@ -270,7 +270,39 @@ class Managers(Base):
         except AttributeError:
             return "Not available"
 
+    def get_managed_chassis(self):
+        '''Get managed chassis ids by the manager
 
+        :returns:  list -- chassis ids or "Not available"
+
+        '''
+        chassis_list = []
+        links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
+        
+        try:
+            for chassis in links.ManagerForChassis:
+                result = re.search(r'Chassis/(\w+)', chassis[mapping.redfish_mapper.map_links_ref(chassis)])
+                chassis_list.append(result.group(1))
+            return chassis_list
+        except AttributeError:
+            return "Not available"
+
+    def get_managed_systems(self):
+        '''Get managed systems ids by the manager
+
+        :returns:  list -- chassis ids or "Not available"
+
+        '''
+        systems_list = []
+        links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
+        
+        try:
+            for systems in links.ManagerForServers:
+                result = re.search(r'Systems/(\w+)', systems[mapping.redfish_mapper.map_links_ref(systems)])
+                systems_list.append(result.group(1))           
+            return systems_list
+        except AttributeError:
+            return "Not available"
 
 class ManagersCollection(BaseCollection):
     '''Class to manage redfish ManagersCollection data.'''
@@ -313,7 +345,7 @@ class Systems(Base):
                                      data=action
                                     )
         #TODO : treat response.
-        return response
+        return response  
 
     def get_bios_version(self):
         '''Get bios version of the system.