Package: sebastes
o le  o
              /^^^^^7
'  '     ,oO))))))))Oo,
       ,'))))))))))))))), /{
  '  ,'o  ))))))))))))))))={
     >    )))Sebastes)))))={
     `,   ))))))\ \)))))))={
       ',))))))))\/)))))' \{
         '*O))))))))O*'SebastesHey hey people! Sebastes is simple code generator forRedfishcompatible targets (i.e. server, storage systems, network equipment). It recursively scans target Redfish
endpoints and creates organized python modules withPydanticmodels. Forget about spending hours on boilerplate code, just make it within a couple of
minutes!Getting startedConfirmed supportDell:Х2-740ХHuawei:2288H V5YADRO:Vegman N110Prerequisitessebastesrequires python 3.9 or newer versions to run. Currently, only UNIX os is supported.InstallingCloning project from git repositorygitclonehttps://github.com/YADRO-KNS/sebastes.gitInstalling from PyPipip3installsebastesUsageThesebastescommand:usage:sebastes[-h]-aHOSTNAME-uUSERNAME-pPASSWORD-oOUTPUT[-e[ENTRY_POINT]][-m[MAX_MODELS]][-c[MAX_COLLECTION]]optionalarguments:-h,--helpshowthishelpmessageandexit-aHOSTNAMEDNSnameorIPaddressofRedfishtarget-uUSERNAMETargetusername-pPASSWORDTargetpassword-oOUTPUTOutputdirectory-e[ENTRY_POINT]Redfishentrypoint|optionaldefaultis'/redfish/v1/'-m[MAX_MODELS]MaxModelstoscan|optionaldefaultis500-c[MAX_COLLECTION]MaxCollectionelementstosamplefrom|optionaldefaultis50ExampleScanning target# Generate library code from remote server Redfish data.$sebastes-a192.168.1.3-uadmin-ple-pass-o/tmp/output/libGenerated lib structureAfter scanning, Sebastes will create a python module in the output folder with the following structure:.
└── models
    ├── __init__.py
    ├── common.py
    ├── service_root.py
    ├── some_other_resourse.py
    └── ...Working with generated codeInit file will be created automatically. It will contain imports from common script and root models from all of the scanned endpoints.Redfish have a limited list of model types. Matching models will be re-inherited from respective classes defined in common script:Link- the simplest type of model containing a link to some resource.Action- similar to Link but contains URI of some possible action.Resource- main model type, contains a set of mandatory fields defined in parent class, all other fields will be created based on response data. Also for root model resources _url field will be
filled with model location data.Collection- similar to Resource, has a couple of specific fields with links to its members. For root model collections _url field will be filled with model location data.Regardless of what type of data you want to access in Redfish, the first thing you need to do is to create aDataManagerinstance. This class provides methods for interaction with pydantic models.Getting ResourceTo get Resource data you need to call get_resource method of DataManager object and pass required model class to map data into. Models _url field will be used as default data location, you can
manually replace it with your own value.defget_resource(self,resource:typing.Type[T],url:typing.Optional[str]=None)->T:"""Gets resource data from passed model class.:param resource: Model to get data for.:param url: Resource URL | optional:return: resource object"""...from.modelsimportDataManager,ServiceRootif__name__=='__main__':manager=DataManager('192.168.1.3','admin','le-pass')service_root=manager.get_resource(ServiceRoot)print(service_root.host_name)Getting Collection membersTo get a collection you need to provide not only a collection model class but also a model for collection elements. For some root models elements classes will be available via resource class method.defget_collection(self,collection:typing.Type[Collection],resource:typing.Type[T],url:typing.Optional[str]=None)->typing.List[T]:"""Gets collection data from endpoint and returns list of all member resources:param collection: Collection class:param resource: Target resource to map data:param url: collection URL | optional:return: list of resource objects"""...from.modelsimportDataManager,LogServiceEntriesif__name__=='__main__':manager=DataManager('192.168.1.3','admin','le-pass')forloginmanager.get_collection(LogServiceEntries,LogServiceEntries.resource()):print(log.created,log.message,log.severity)And just as with Resource you can provide your own URL value to get data from. For nested collections it is the only way:from.modelsimportDataManager,NetworkInterfaces,NetworkPortsif__name__=='__main__':manager=DataManager('192.168.1.3','admin','le-pass')forinterfaceinmanager.get_collection(NetworkInterfaces,NetworkInterfaces.resource()):url=interface.network_ports.odata_idforportinmanager.get_collection(NetworkPorts,NetworkPorts.resource(),url=url):print(interface.name,port.name,port.mac)Calling Action requestWhen you need to activate some Redfish action all you have to do is pass an Action object. Payload is optional.defaction_post(self,action:Action,payload:typing.Optional[dict]=None)->dict:"""Call action request for specific model.:param action: Model to call:param payload: Calls data.:return: JSON response data"""...from.modelsimportDataManager,ComputerSystemif__name__=='__main__':manager=DataManager('192.168.1.3','admin','le-pass')computer_system=manager.get_resource(ComputerSystem)manager.action_post(computer_system.actions.computer_system_reset,payload={'ResetType':'On'})Patching ResourceSome Redfish endpoints support patching. The link_patch method will call a passed link object and get it’s Etag value (if there is any) and then will perform a patch request with passed payload data.deflink_patch(self,link:Link,payload:typing.Optional[dict]=None,pass_etag:bool=True)->dict:"""Call Patch request on specific link model:param link: Model to patch:param payload: Patch data:param pass_etag: boolean flag, is set as true, will attempt touse resource ETag value in PATCH request.:return: JSON response data"""...from.modelsimportDataManager,Biosif__name__=='__main__':manager=DataManager('192.168.1.3','admin','le-pass')bios=manager.get_resource(Bios)payload={'Attributes':{'BootType':'UEFIBoot'}}manager.link_patch(bios.redfish_settings.settings_object,payload)VersioningWe useSemVerfor versioning.AuthorsSergey ParshinSee also the list ofcontributorswho participated in this project.Acknowledgmentssebastes inspired and based ondatamodel-code-generatorbyKoudai AonoLicenseThe code is available as open source under the terms of theMIT License.