]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
node-proxy: add type annotation
authorGuillaume Abrioux <gabrioux@ibm.com>
Thu, 8 Jun 2023 16:31:38 +0000 (18:31 +0200)
committerGuillaume Abrioux <gabrioux@ibm.com>
Thu, 25 Jan 2024 14:51:03 +0000 (14:51 +0000)
This commit adds the type annotation in all files.
This was missing since the initial implementation, let's add
it before the project gets bigger.

Signed-off-by: Guillaume Abrioux <gabrioux@ibm.com>
(cherry picked from commit ee8e28baafbe6861a21514c2af05b77a42d6f963)

src/cephadm/node-proxy/redfish_client.py
src/cephadm/node-proxy/redfish_dell.py
src/cephadm/node-proxy/redfish_system.py
src/cephadm/node-proxy/reporter.py
src/cephadm/node-proxy/server-v2.py
src/cephadm/node-proxy/system.py
src/cephadm/node-proxy/util.py

index fdf0106c173bfdab9d6a7670f53931badfe4f132..bfec7d9ad4e9b5a514d4850cc938efdb5a944eab 100644 (file)
@@ -4,6 +4,7 @@ from redfish.rest.v1 import ServerDownOrUnreachableError, \
 import redfish
 import sys
 from util import Logger
+from typing import Dict
 
 log = Logger(__name__)
 
@@ -12,14 +13,17 @@ class RedFishClient:
 
     PREFIX = '/redfish/v1'
 
-    def __init__(self, host, username, password):
+    def __init__(self,
+                 host: str,
+                 username: str,
+                 password: str) -> None:
         log.logger.info("redfish client initialization...")
         self.host = host
         self.username = username
         self.password = password
-        self.redfish_obj = None
+        self.redfish_obj: 'redfish.redfish_client' = None
 
-    def login(self):
+    def login(self) -> 'redfish.redfish_client':
         self.redfish_obj = redfish.redfish_client(base_url=self.host,
                                                   username=self.username,
                                                   password=self.password,
@@ -35,7 +39,7 @@ class RedFishClient:
             log.logger.error(f"Server not reachable or does not support RedFish:\n{e}")
         sys.exit(1)
 
-    def get_path(self, path):
+    def get_path(self, path: str) -> Dict:
         try:
             if self.PREFIX not in path:
                 path = f"{self.PREFIX}{path}"
@@ -47,6 +51,6 @@ class RedFishClient:
             log.logger.error(f"Error detected.\n{e}")
             pass
 
-    def logout(self):
+    def logout(self) -> None:
         log.logger.info('logging out...')
         self.redfish_obj.logout()
index bebce7e2a19b13bf51663a1677215e5441420b12..80e54f1cff3152094472d7a4c55fc14edf09d3f0 100644 (file)
@@ -1,21 +1,22 @@
 from redfish_system import RedfishSystem
 from util import Logger, normalize_dict
+from typing import Dict, Any
 
 log = Logger(__name__)
 
 
 class RedfishDell(RedfishSystem):
-    def __init__(self, **kw):
+    def __init__(self, **kw: Any) -> None:
         if kw.get('system_endpoint') is None:
             kw['system_endpoint'] = '/Systems/System.Embedded.1'
         super().__init__(**kw)
 
-    def _update_network(self):
+    def _update_network(self) -> None:
         net_path = self._system['EthernetInterfaces']['@odata.id']
         log.logger.info("Updating network")
         network_info = self.client.get_path(net_path)
         self._system['network'] = {}
-        result = dict()
+        result: Dict[str, Dict[str, Dict]] = dict()
         for interface in network_info['Members']:
             interface_path = interface['@odata.id']
             interface_info = self.client.get_path(interface_path)
@@ -27,12 +28,12 @@ class RedfishDell(RedfishSystem):
             result[interface_id]['status'] = interface_info['Status']
         self._system['network'] = normalize_dict(result)
 
-    def _update_processors(self):
+    def _update_processors(self) -> None:
         cpus_path = self._system['Processors']['@odata.id']
         log.logger.info("Updating processors")
         cpus_info = self.client.get_path(cpus_path)
         self._system['processors'] = {}
-        result = dict()
+        result: Dict[str, Dict[str, Dict]] = dict()
         for cpu in cpus_info['Members']:
             cpu_path = cpu['@odata.id']
             cpu_info = self.client.get_path(cpu_path)
@@ -47,11 +48,11 @@ class RedfishDell(RedfishSystem):
             result[cpu_id]['manufacturer'] = cpu_info['Manufacturer']
         self._system['processors'] = normalize_dict(result)
 
-    def _update_storage(self):
+    def _update_storage(self) -> None:
         storage_path = self._system['Storage']['@odata.id']
         log.logger.info("Updating storage")
         storage_info = self.client.get_path(storage_path)
-        result = dict()
+        result: Dict[str, Dict[str, Dict]] = dict()
         for storage in storage_info['Members']:
             entity_path = storage['@odata.id']
             entity_info = self.client.get_path(entity_path)
@@ -69,14 +70,14 @@ class RedfishDell(RedfishSystem):
                 result[drive_id]['location'] = drive_info['PhysicalLocation']
         self._system['storage'] = normalize_dict(result)
 
-    def _update_metadata(self):
+    def _update_metadata(self) -> None:
         log.logger.info("Updating metadata")
         pass
 
-    def _update_memory(self):
+    def _update_memory(self) -> None:
         log.logger.info("Updating memory")
         pass
 
-    def _update_power(self):
+    def _update_power(self) -> None:
         log.logger.info("Updating power")
         pass
index 358d03d5bdf8fb7938b10eb04a7f91dd717da567..7b95005b9546e99c886c3c7b81cbe7c5f8f9505d 100644 (file)
@@ -3,34 +3,35 @@ from redfish_client import RedFishClient
 from threading import Thread, Lock
 from time import sleep
 from util import Logger
+from typing import Dict, Any
 
 log = Logger(__name__)
 
 
 class RedfishSystem(System):
-    def __init__(self, **kw):
+    def __init__(self, **kw: Any) -> None:
         super().__init__(**kw)
-        self.host = kw.get('host')
-        self.username = kw.get('username')
-        self.password = kw.get('password')
+        self.host: str = kw['host']
+        self.username: str = kw['username']
+        self.password: str = kw['password']
         self.system_endpoint = kw.get('system_endpoint', '/Systems/1')
         log.logger.info(f"redfish system initialization, host: {self.host}, user: {self.username}")
         self.client = RedFishClient(self.host, self.username, self.password)
 
-        self._system = {}
-        self.run = False
-        self.thread = None
+        self._system: Dict[str, Dict[str, Any]] = {}
+        self.run: bool = False
+        self.thread: Thread
         self.start_client()
-        self.data_ready = False
-        self.previous_data = {}
-        self.lock = Lock()
+        self.data_ready: bool = False
+        self.previous_data: Dict = {}
+        self.lock: Lock = Lock()
 
-    def start_client(self):
+    def start_client(self) -> None:
         log.logger.info(f"redfish system initialization, host: {self.host}, user: {self.username}")
         self.client = RedFishClient(self.host, self.username, self.password)
         self.client.login()
 
-    def get_system(self):
+    def get_system(self) -> Dict[str, Dict[str, Dict]]:
         result = {
             'storage': self.get_storage(),
             'processors': self.get_processors(),
@@ -38,59 +39,59 @@ class RedfishSystem(System):
         }
         return result
 
-    def get_status(self):
+    def get_status(self) -> Dict[str, Dict[str, Dict]]:
         return self._system['status']
 
-    def get_metadata(self):
+    def get_metadata(self) -> Dict[str, Dict[str, Dict]]:
         return self._system['metadata']
 
-    def get_memory(self):
+    def get_memory(self) -> Dict[str, Dict[str, Dict]]:
         return self._system['memory']
 
-    def get_power(self):
+    def get_power(self) -> Dict[str, Dict[str, Dict]]:
         return self._system['power']
 
-    def get_processors(self):
+    def get_processors(self) -> Dict[str, Dict[str, Dict]]:
         return self._system['processors']
 
-    def get_network(self):
+    def get_network(self) -> Dict[str, Dict[str, Dict]]:
         return self._system['network']
 
-    def get_storage(self):
+    def get_storage(self) -> Dict[str, Dict[str, Dict]]:
         return self._system['storage']
 
-    def _update_system(self):
+    def _update_system(self) -> None:
         redfish_system = self.client.get_path(self.system_endpoint)
         self._system = {**redfish_system, **self._system}
 
-    def _update_metadata(self):
+    def _update_metadata(self) -> None:
         raise NotImplementedError()
 
-    def _update_memory(self):
+    def _update_memory(self) -> None:
         raise NotImplementedError()
 
-    def _update_power(self):
+    def _update_power(self) -> None:
         raise NotImplementedError()
 
-    def _update_network(self):
+    def _update_network(self) -> None:
         raise NotImplementedError()
 
-    def _update_processors(self):
+    def _update_processors(self) -> None:
         raise NotImplementedError()
 
-    def _update_storage(self):
+    def _update_storage(self) -> None:
         raise NotImplementedError()
 
-    def start_update_loop(self):
+    def start_update_loop(self) -> None:
         self.run = True
         self.thread = Thread(target=self.update)
         self.thread.start()
 
-    def stop_update_loop(self):
+    def stop_update_loop(self) -> None:
         self.run = False
         self.thread.join()
 
-    def update(self):
+    def update(self) -> None:
         #  this loop can have:
         #  - caching logic
         try:
index 25dde2d85da296edfb3d963d86776252a324fb04..6be8d24c6b0ae696867fbd2f1b7d703d83f1bec2 100644 (file)
@@ -2,25 +2,26 @@ from threading import Thread
 import requests
 import time
 from util import Logger
+from typing import Any
 
 log = Logger(__name__)
 
 
 class Reporter:
-    def __init__(self, system, observer_url):
+    def __init__(self, system: Any, observer_url: str) -> None:
         self.system = system
         self.observer_url = observer_url
         self.finish = False
 
-    def stop(self):
+    def stop(self) -> None:
         self.finish = True
         self.thread.join()
 
-    def run(self):
+    def run(self) -> None:
         self.thread = Thread(target=self.loop)
         self.thread.start()
 
-    def loop(self):
+    def loop(self) -> None:
         while not self.finish:
             # Any logic to avoid sending the all the system
             # information every loop can go here. In a real
index aaf7a75e1c89550b63e18c7cf5534b623c590e1f..d1924629e6bd0ff8e85ef1a73ba21ad904eca5ee 100644 (file)
@@ -2,6 +2,7 @@ import cherrypy
 from redfish_dell import RedfishDell
 from reporter import Reporter
 from util import Config, Logger
+from typing import Dict
 import sys
 
 # for devel purposes
@@ -53,7 +54,7 @@ class Memory:
     exposed = True
 
     @cherrypy.tools.json_out()
-    def GET(self):
+    def GET(self) -> Dict[str, Dict[str, Dict]]:
         return {'memory': system.get_memory()}
 
 
@@ -61,7 +62,7 @@ class Network:
     exposed = True
 
     @cherrypy.tools.json_out()
-    def GET(self):
+    def GET(self) -> Dict[str, Dict[str, Dict]]:
         return {'network': system.get_network()}
 
 
@@ -69,7 +70,7 @@ class Processors:
     exposed = True
 
     @cherrypy.tools.json_out()
-    def GET(self):
+    def GET(self) -> Dict[str, Dict[str, Dict]]:
         return {'processors': system.get_processors()}
 
 
@@ -77,7 +78,7 @@ class Storage:
     exposed = True
 
     @cherrypy.tools.json_out()
-    def GET(self):
+    def GET(self) -> Dict[str, Dict[str, Dict]]:
         return {'storage': system.get_storage()}
 
 
@@ -85,7 +86,7 @@ class Status:
     exposed = True
 
     @cherrypy.tools.json_out()
-    def GET(self):
+    def GET(self) -> Dict[str, Dict[str, Dict]]:
         return {'status': system.get_status()}
 
 
@@ -103,13 +104,13 @@ class System:
 class Shutdown:
     exposed = True
 
-    def POST(self):
+    def POST(self) -> str:
         _stop()
         cherrypy.engine.exit()
         return 'Server shutdown...'
 
 
-def _stop():
+def _stop() -> None:
     system.stop_update_loop()
     system.client.logout()
     reporter_agent.stop()
@@ -118,7 +119,7 @@ def _stop():
 class Start:
     exposed = True
 
-    def POST(self):
+    def POST(self) -> str:
         system.start_client()
         system.start_update_loop()
         reporter_agent.run()
@@ -128,7 +129,7 @@ class Start:
 class Stop:
     exposed = True
 
-    def POST(self):
+    def POST(self) -> str:
         _stop()
         return 'node-proxy daemon stopped'
 
@@ -136,10 +137,10 @@ class Stop:
 class ConfigReload:
     exposed = True
 
-    def __init__(self, config):
+    def __init__(self, config: cherrypy.config) -> None:
         self.config = config
 
-    def POST(self):
+    def POST(self) -> str:
         self.config['node_proxy'].reload()
         return 'node-proxy config reloaded'
 
@@ -153,14 +154,14 @@ class API:
     stop = Stop()
     config_reload = ConfigReload(cherrypy.config)
 
-    def GET(self):
+    def GET(self) -> str:
         return 'use /system'
 
 
 if __name__ == '__main__':
     cherrypy.config.update({
         'node_proxy': config,
-        'server.socket_port': config.server['port']
+        'server.socket_port': config.__dict__['server']['port']
     })
     c = {'/': {
         'request.methods_with_bodies': ('POST', 'PUT', 'PATCH'),
index 4b34001dd817182b6b2cc169fad00069c51523b9..9e8f97ef59d67314b70b66df1c19fc10ad6d958f 100644 (file)
@@ -1,28 +1,32 @@
+from util import Config
+from typing import Dict, Any
+
+
 class System:
-    def __init__(self, **kw):
-        self._system = {}
-        self.config = kw['config']
+    def __init__(self, **kw: Any) -> None:
+        self._system: Dict = {}
+        self.config: Config = kw['config']
 
-    def get_system(self):
+    def get_system(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
 
-    def get_status(self):
+    def get_status(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
 
-    def get_metadata(self):
+    def get_metadata(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
 
-    def get_processors(self):
+    def get_processors(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
 
-    def get_memory(self):
+    def get_memory(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
 
-    def get_power(self):
+    def get_power(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
 
-    def get_network(self):
+    def get_network(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
 
-    def get_storage(self):
+    def get_storage(self) -> Dict[str, Dict[str, Dict]]:
         raise NotImplementedError()
index 27cfffdf3c294b5a8733b0692b09252af23cb670..817583e6ff7f568038abb044a1db762494f5f95d 100644 (file)
@@ -1,9 +1,10 @@
 import logging
 import yaml
 import os
+from typing import Dict, List
 
 
-def normalize_dict(test_dict):
+def normalize_dict(test_dict: Dict) -> Dict:
     res = dict()
     for key in test_dict.keys():
         if isinstance(test_dict[key], dict):
@@ -16,14 +17,14 @@ def normalize_dict(test_dict):
 class Config:
 
     def __init__(self,
-                 config_file='/etc/ceph/node-proxy.yaml',
-                 default_config={}):
+                 config_file: str = '/etc/ceph/node-proxy.yaml',
+                 default_config: Dict[str, Any] = {}) -> None:
         self.config_file = config_file
         self.default_config = default_config
 
         self.load_config()
 
-    def load_config(self):
+    def load_config(self) -> None:
         if os.path.exists(self.config_file):
             with open(self.config_file, 'r') as f:
                 self.config = yaml.safe_load(f)
@@ -39,26 +40,26 @@ class Config:
 
         # TODO: need to be improved
         for _l in Logger._Logger:
-            _l.logger.setLevel(self.logging['level'])
-            _l.logger.handlers[0].setLevel(self.logging['level'])
+            _l.logger.setLevel(self.logging['level'])  # type: ignore
+            _l.logger.handlers[0].setLevel(self.logging['level'])  # type: ignore
 
-    def reload(self, config_file=None):
+    def reload(self, config_file: str = '') -> None:
         if config_file != '':
             self.config_file = config_file
         self.load_config()
 
 
 class Logger:
-    _Logger = []
+    _Logger: List['Logger'] = []
 
-    def __init__(self, name, level=logging.INFO):
+    def __init__(self, name: str, level: int = logging.INFO):
         self.name = name
         self.level = level
 
         Logger._Logger.append(self)
         self.logger = self.get_logger()
 
-    def get_logger(self):
+    def get_logger(self) -> logging.Logger:
         logger = logging.getLogger(self.name)
         logger.setLevel(self.level)
         handler = logging.StreamHandler()