From 50f9ed7b081d067edf94d9097d70ac313013d4f5 Mon Sep 17 00:00:00 2001 From: Christian Pinto Date: Thu, 5 Sep 2024 14:58:25 +0100 Subject: [PATCH 1/2] Added description of plugins mechanism in README Signed-off-by: Christian Pinto --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9c6d26d..e31b234 100644 --- a/README.md +++ b/README.md @@ -30,30 +30,89 @@ To run the tests run the command make test ``` +## Plugins -## Usage -To use sunfishcorelib you need to specify the **configuration parameters** into the conf.json file, an example could be: +The Sunfish core library uses a plugin based mechanism for providing custom implementation of: + +- Storage backends: implementation of the Sunfish storage interface used for controlling how RedFish storage are persisted. Plugins in this class must implement the `BackendInterface` class in `storage.backend_interface`. +- Event handlers: Sunfish interactions with hardware agents and clients is implemented through RedFish events. When an event is received, users might want to execute a specific action depending on the specific event. These are provided via this plugin. Plugins in this class must implement the `EventHandlerInterface` class in `events.event_handler_interface`. +- Objects handlers: Whenever a request for an object (get, create, replace, patch, delete) is received on the Sunfish external api the core library checks whether a special handler is to be executed for that specific object. Examples are an object is created and it requires other objects to be created in turn as a result. Plugins in this class must implement the `ObjectHandlerInterface` class in `lib.object_handler_interface`. +- Objects managers: Sunfish keeps all objects in the form of a RedFish tree. Objects belong to a manager (e.g., a Sunfish agent) and this plugin provides the methods for Sungish to interact with the manager. Plugins in this class must implement the `ObjectManagerInterface` class in `lib.object_manager_interface`. + +Plugins are based on python's namespaced packages and are required to be placed in a specific folder at the top of your project. Only the actual plugins have a user defined name. Please see the below example. + +```commandline +─ sunfish_plugins + ├── storage + │ └──my_storage_package <--- User defined + │ ├── __init__.py + │ └── my_storage_backend.py + └── events_handlers + │ └──my_handler_package <--- User defined + │ ├── __init__.py + │ └── my_handler.py + ├── objects_handlers + │ └──my_objects_handler_package <--- User defined + │ ├── __init__.py + │ └── my_objects_handler.py + ├── objects_managers + │ └──my_objects_manager_package <--- User defined + │ ├── __init__.py + │ └── my_objects_manager.py ``` + +Please note no setup.py or project.toml should be placed in any of the plugins folders, including the pre-defined folders (i.e., sunfish_plugins, storage, events_handlers, objects_handlers, objects_managers). Failing to do so will make the plugins impossible to be discovered. + + +When initializing the library, users can specify their implementation of their plugins as part of the sunfish configuration. See the below example. + +```python +sunfish_config = { + +} +``` + +This plugin mechanism allows user to modify the standard behavior of Sunfish without having to modify the core library. Users can place the `sunifsh_plugins` folder at the top of their project that imports the sunfish core library and benefit from the flexibility of a plugin. + +If no plugins are specified in the configuration, the Sunfish library will load the default implementations. See the code for more details. + +## Usage + +When initializing the sunfish core library, users need to specify the **configuration parameters** as a dict to be passed to the `init` function. The below snippet shows all the possible fields : +```json { - "storage_backend": "FS", "redfish_root": "/redfish/v1/", - "backend_conf" : { - "fs_root": "Resources", - "subscribers_root": "EventService/Subscriptions" - }, "handlers": { - "subscription_handler": "redfish", - "event_handler": "redfish" + "subscription_handler": "redfish" + }, + "storage_backend": { + "module_name": "storage.file_system_backend.backend_FS", + "class_name": "BackendFS" + }, + "events_handler": { + "module_name": "events_handlers.redfish.redfish_event_handler", + "class_name": "RedfishEventHandler" + }, + "objects_handler": { + "module_name": "objects_handlers.sunfish_server.redfish_object_handler", + "class_name": "RedfishObjectHandler" + }, + "objects_manager": { + "module_name": "objects_managers.sunfish_agent.sunfish_agent_manager", + "class_name": "SunfishAgentManager" } } ``` -where: -- _storage_backend_ specifies the persistency implementation that you want to use -- _redfish_root_ specifies the Redfish version that must be included in all the requests -- _backend_conf[fs_root]_ specifies the root directory of Redfish objects' file system -- _subscription_handler_ specifies the type of handler implementation that you want to use to handle subscriptions -- _event_handler_ specifies the type of handler implementation that you want to use to handle events +Where: +- `redfish_root`: the root of the RedFish service served by the Sunfish core library. +- `subscripition_hadler`: Identifies how to handle subscriptions to events. At the moment only `redfish` is supported and follows the Redfish standard +- `storage_backend`: specifies the storage plugin to load. +- `events_handler`: specifies the event handling plugin to load. +- `objects_handler`: specifies the object handling plugin to load. +- `objects_manager`: specifies the object manager plugin to load. + +All plugins must specify the module and class name via the `module_name` and `class_name` fields respectively. Sunfish should be installed and imported in an existing Python project. To use it: - instantiate an object Core(conf) From 33b6ecf7864bc95109982447f097739fac89068d Mon Sep 17 00:00:00 2001 From: Christian Pinto Date: Tue, 17 Sep 2024 10:51:20 +0100 Subject: [PATCH 2/2] Added usage instructions to README Signed-off-by: Christian Pinto --- README.md | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e31b234..3b0869a 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Plugins are based on python's namespaced packages and are required to be placed Please note no setup.py or project.toml should be placed in any of the plugins folders, including the pre-defined folders (i.e., sunfish_plugins, storage, events_handlers, objects_handlers, objects_managers). Failing to do so will make the plugins impossible to be discovered. -When initializing the library, users can specify their implementation of their plugins as part of the sunfish configuration. See the below example. +When initializing the library, users can specify their implementation of their plugins as part of the sunfish configuration as described in the [Initialization](https://github.com/OpenFabrics/sunfish_library_reference?tab=readme-ov-file#usage) section. ```python sunfish_config = { @@ -78,9 +78,12 @@ If no plugins are specified in the configuration, the Sunfish library will load ## Usage -When initializing the sunfish core library, users need to specify the **configuration parameters** as a dict to be passed to the `init` function. The below snippet shows all the possible fields : -```json -{ +### Initialization +When initializing the sunfish core library, users need to specify the **configuration parameters** as a dict to be passed to the `init` function. The below snippet shows all the possible fields and how to initialize the library: +```python +from sunfish.lib.core import Core + +config = { "redfish_root": "/redfish/v1/", "handlers": { "subscription_handler": "redfish" @@ -102,6 +105,8 @@ When initializing the sunfish core library, users need to specify the **configur "class_name": "SunfishAgentManager" } } + +sunfish_core = Core(config) ``` Where: @@ -121,5 +126,34 @@ Sunfish should be installed and imported in an existing Python project. To use i **IMPORTANT:** this Library assumes that the .json object are legal and well-formed according to the Redfish specification. +### Interacting with Sunfish + +The Sunfish library is meant to be integrated into another software such as a REST server or similar application providing external access to the library. +Besides the the configuration described above, an application using this library interacts with Sunfish via the below API: + +```python +#get an object from the Sunfish tree +get_object(self, path: string) + +#create a new object in the Sunfish tree +create_object(self, path: string, payload: dict) + +#fully replace an existing object +replace_object(self, path: str, payload: dict) + +#patch an existing object +patch_object(self, path: str, payload: dict) + +#delete an existing object +delete_object(self, path: string) + +#process a Redfish event +handle_event(self, payload) +``` + +THe above API is exposed by the `Core` class. More details on the above api are available [here](https://github.com/OpenFabrics/sunfish_library_reference/blob/main/sunfish/lib/core.py). + +An example REST server, showing how to interact with the Sunfish library is available [here](https://github.com/OpenFabrics/sunfish_server_reference). + ## License and copyright attribution The code in this project is made available via the BSD 3-Clause License. See [LICENSE](https://github.com/OpenFabrics/sunfish_library_reference/blob/main/LICENSE) to access the full license terms. This project adopts the Developer Certificate of Origin (DCO) to certify that each commit was written by the author, or that the author has the rights necessary to contribute the code. All commits must include a DCO which looks like this: Signed-off-by: Joe Smith . Specifically, we utilize the [Developer Certificate of Origin Version 1.1] (https://github.com/OpenFabrics/sunfish_library_reference/blob/main/DCO). The project requires that the name used is your real name. Neither anonymous contributors nor those utilizing pseudonyms will be accepted.