Skip to content

Commit

Permalink
Issue 12 (#16)
Browse files Browse the repository at this point in the history
This PR is a follow up of #15 
- It updates the handlers processing the `AggregationSourceDiscovered`
and `ResourceCreated` events. At the reception of the
`AggregationSourceDiscovered` event the handler adds a UUID as `Context`
to the Subscription. The Agent will have to add such `Context` to the
following Events issued to the Sunfish server.
- It adds a Makefile simplifying the steps to build the `whl`
  • Loading branch information
christian-pinto authored Feb 28, 2024
2 parents 97717e2 + c99040d commit 963736e
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 72 deletions.
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright IBM Corp. 2023
# This software is available to you under a BSD 3-Clause License.
# The full license terms are available here: https://github.com/OpenFabrics/sunfish_library_reference/blob/main/LICENSE

all: build

build:
poetry build

test:
python3 -m pytest tests/test_sunfishcore_library.py -vvvv

clean:
rm -r dist


20 changes: 8 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,29 @@ The library requires:
- Python (version>=3.9)
- Poetry

## To generate the installation file
From the directory ```sunfish_library_reference``` execute the following command:
```
poetry build #This command will create the .whl file
```

## Installation

We suggest using a Python virtual environment.
We suggest using a Python virtual environment.
To install the project requirements:
```
pip install -r requirements.txt
```
To install sunfish you need to use the file .whl:
```
pip3 install dist/sunfish-0.1.0-py3-none-any.whl

## To generate the installation file
From the directory ```sunfish_library_reference``` execute the following command:
```
make build
```


## Tests
To test this Library you need ```pytest``` to be installed.
To run the tests run the command
```
python3 -m pytest test_sunfishcore_library.py -vvvv
make test
```


## Usage
To use sunfishcorelib you need to specify the **configuration parameters** into the conf.json file, an example could be:
```
Expand Down
79 changes: 31 additions & 48 deletions sunfish/events/redfish_event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self, core):
self.backend = core.storage_backend

def new_event(self, payload):
"""Compares event's informations with the subsribtions data structure to find the Ids of the subscribers for that event.
"""Compares event's information with the subsribtions data structure to find the Ids of the subscribers for that event.
Args:
payload (dict): event received.
Expand Down Expand Up @@ -139,7 +139,7 @@ def check_subdirs(self, origin):

return to_forward

def AggregationSourceDiscovered(self, event):
def AggregationSourceDiscovered(self, event, context):
###
# Fabric Agents are modelled as AggregationSource objects (RedFish v2023.1 at the time of writing this comment)
# Registration will happen with the OFMF receiving a and event with MessageId: AggregationSourceDiscovered
Expand Down Expand Up @@ -179,56 +179,35 @@ def AggregationSourceDiscovered(self, event):
}
}

try:
resp_post = self.create_object(os.path.join(self.conf["redfish_root"], "AggregationService/AggregationSources"), connection_method_template)
except Exception:
raise Exception()

# Update Name and ResourcesAccessed
path = hostname + os.path.join(self.conf["redfish_root"], "Fabrics")
response = requests.get(path)
if response.status_code != 200:
raise Exception("Cannot find Fabrics")
response = response.json()
resp_post = self.create_object(os.path.join(self.conf["redfish_root"], "AggregationService/AggregationSources"), connection_method_template)

update_template = {
"@odata.type": "#AggregationSource.v1_2_"+resp_post["Id"]+".AggregationSource",
"@odata.id": resp_post["@odata.id"],
"Name": "Agent "+resp_post["Id"],
"Links": {
"ConnectionMethod": {
"@odata.id": connectionMethodId
},
"ResourcesAccessed": [
member['@odata.id'] for member in response['Members']
]
}
}
aggregation_source_id = resp_post['@odata.id']
agent_subscription_context = {"Context": aggregation_source_id.split('/')[-1]}

resp_patch = requests.patch(f"{hostname}/redfish/v1/EventService/Subscriptions/SunfishServer",
json=agent_subscription_context)

try:
resp_patch = self.patch_object(update_template)
except Exception:
raise Exception

return resp_patch

def ResourceCreated(self, event):
def ResourceCreated(self, event, context):
logging.info("New resource created")

id = event['OriginOfCondition']['@odata.id'] # /redfish/v1/Fabrics/CXL
aggregation_source = RedfishEventHandler.get_aggregation_source(self, id)
aggregation_source = self.get_object(
os.path.join(self.conf["redfish_root"], "AggregationService", "AggregationSources", context))
hostname = aggregation_source["HostName"]

response = requests.get(f"{hostname}/{id}")
if response.status_code != 200:
raise Exception("Cannot find ConnectionMethod")
response = response.json()
object = response.json()
add_aggregation_source_reference(object, aggregation_source)

self.create_object(id, response)
self.create_object(id, object)

RedfishEventHandler.bfsInspection(self, response, aggregation_source)
RedfishEventHandler.bfsInspection(self, object, aggregation_source)

self.patch_object(aggregation_source)
self.patch_object(id, aggregation_source)

def bfsInspection(self, node, aggregation_source):
queue = []
Expand Down Expand Up @@ -335,14 +314,18 @@ def createInspectedObject(self,redfish_obj, aggregation_source):
elif self.get_object(file_path) != redfish_obj:
warnings.warn('Resource state changed')
except ResourceNotFound:
oem = {
"@odata.type": "#SunfishExtensions.v1_0_0.ResourceExtensions",
"ManagingAgent": {
"@odata.id": aggregation_source["@odata.id"]
}
}
if "Oem" not in redfish_obj:
redfish_obj["Oem"] = {}
if "Sunfish_RM" not in redfish_obj["Oem"]:
redfish_obj["Oem"]["Sunfish_RM"] = oem
self.create_object(file_path, redfish_obj)
add_aggregation_source_reference(redfish_obj, aggregation_source)
self.create_object(file_path, redfish_obj)


def add_aggregation_source_reference(redfish_obj, aggregation_source):
if "Oem" not in redfish_obj:
redfish_obj["Oem"] = {}
if "Sunfish_RM" not in redfish_obj["Oem"]:
oem = {
"@odata.type": "#SunfishExtensions.v1_0_0.ResourceExtensions",
"ManagingAgent": {
"@odata.id": aggregation_source["@odata.id"]
}
}
redfish_obj["Oem"]["Sunfish_RM"] = oem
2 changes: 1 addition & 1 deletion sunfish/events/redfish_subscription_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def new_subscription(self, payload:dict):

if "OriginResources" in payload:
for prefix in payload["OriginResources"]:
origin = payload["OriginResources"][prefix]
origin = prefix["@odata.id"]
if "SubordinateResources" in payload and payload["SubordinateResources"]:
origin = os.path.join(origin, '*')
if origin in subscribtions["OriginResources"]:
Expand Down
6 changes: 5 additions & 1 deletion sunfish/lib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,14 @@ def delete_object(self, path):
return self.storage_backend.remove(path)

def handle_event(self, payload):
if "Context" in payload:
context = payload["Context"]
else:
context = ""
for event in payload["Events"]:
try:
handlerfunc = getattr(RedfishEventHandler, event['MessageId'].split(".")[-1])
handlerfunc(self, event)
handlerfunc(self, event, context)
except AttributeError:
pass
return self.event_handler.new_event(payload)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_sunfishcore_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_put(self):
# Exception put element that doesnt exists
def test_put_exception(self):
payload = tests_template.test_update_exception
with pytest.raises(ResourceNotFound):
with pytest.raises(PropertyNotFound):
self.core.replace_object(payload)

# Patch
Expand Down
11 changes: 2 additions & 9 deletions tests/tests_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,6 @@

test_update_exception = {
"@odata.id": "/redfish/v1/Systems/-1",
"@odata.type": "#ComputerSystem.1.00.0.ComputerSystem",
"Id": "1234",
"Name": "Compute Node 1234",
"SystemType": "Physical",
"Manufacturer": "Manufacturer Name",
"Model": "Model Name",
"SKU": "",
"Memory": {
"TotalSystemMemoryGB": 12,
"Status": {
Expand Down Expand Up @@ -240,9 +233,9 @@
"ResourceTypes": [
"ComputerSystem"
],
"OriginResources": {
"OriginResources": [{
"@odata.id": "/redfish/v1/Systems/1"
},
}],
"SubordinateResources": "True"
}

Expand Down

0 comments on commit 963736e

Please sign in to comment.