Skip to content

Commit

Permalink
Add functionality to INBM Cloudadapter-agent to support OOB AMT RPC c… (
Browse files Browse the repository at this point in the history
#550)

* Add functionality to INBM Cloudadapter-agent to support OOB AMT RPC command requests from INBS
JIRA: 610i [https://jira.devtools.intel.com/browse/NEXMANAGE-610]

Update operations to include new Rpc activate functionality
Write new unit tests

* Unit tests

* update protoc

* regen proto

* fix unit tests

* fix unit tests

---------

Co-authored-by: Gavin Lewis <[email protected]>
  • Loading branch information
tsirlapu and gblewis1 authored Sep 30, 2024
1 parent 9701668 commit 114b6ea
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 187 deletions.
2 changes: 1 addition & 1 deletion inbm-lib/inbm_lib/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
CHROOT_PREFIX = "/usr/sbin/chroot /host "

# XML parse time limit
PARSE_TIME_SECS = 10
PARSE_TIME_SECS = 20

# TRTL install location
TRTL_PATH = get_canonical_representation_of_path('/usr/bin/trtl')
Expand Down
2 changes: 2 additions & 0 deletions inbm/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
### Added
- Updated proto files to add new RPC calls to allow edge node to update
its status with INBS.
- (NEXMANAGE- 610) Add functionality to INBM Cloudadapter-agent to support OOB AMT RPC command requests from INBS


### Fixed
- (NEXMANAGE-746) Add extra sleeptime in INBM tpm script to resolve ARL platform issue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import xml.etree.ElementTree as ET
from google.protobuf.timestamp_pb2 import Timestamp
from cloudadapter.pb.common.v1.common_pb2 import UpdateSystemSoftwareOperation, Operation, Schedule
from cloudadapter.pb.common.v1.common_pb2 import UpdateSystemSoftwareOperation, RpcActivateOperation, Operation, Schedule
from cloudadapter.pb.inbs.v1.inbs_sb_pb2 import UpdateScheduledOperations


Expand Down Expand Up @@ -91,22 +91,57 @@ def convert_updated_scheduled_operations_to_dispatcher_xml(request_id: str, upda
def convert_operation_to_xml_manifests(operation: Operation) -> ET.Element:
"""Converts an Operation message to an XML manifests element containing manifest_xml subelements for dispatcher."""

if not operation.HasField('update_system_software_operation'):
if not (operation.HasField('update_system_software_operation') or operation.HasField('rpc_activate_operation')):
raise ValueError("Operation type not supported")

if len(operation.pre_operations) > 0:
raise ValueError("Pre-operations not supported")

if len(operation.post_operations) > 0:
raise ValueError("Post-operations not supported")

result = create_xml_element("manifests")

manifest = None

if operation.update_system_software_operation is not None:
manifest = convert_system_software_operation_to_xml_manifest(operation.update_system_software_operation)
elif operation.rpc_activate_operation is not None:
manifest = convert_rpc_activate_operation_to_xml_manifest(operation.rpc_activate_operation)
else:
raise ValueError("No valid operation found")

result = create_xml_element('manifests')
for manifest in [convert_system_software_operation_to_xml_manifest(operation.update_system_software_operation)]:
xml_manifest = create_xml_element('manifest_xml', text=manifest)
result.append(xml_manifest)
xml_manifest = create_xml_element('manifest_xml', text=manifest)
result.append(xml_manifest)
return result


def convert_rpc_activate_operation_to_xml_manifest(operation: RpcActivateOperation) -> str:
"""Converts a RpcActivateOperation message to an XML manifest string for Dispatcher."""
# Create the root element
manifest = ET.Element('manifest')
ET.SubElement(manifest, 'type').text = 'cmd'

cmd = ET.SubElement(manifest, 'cmd')
header = ET.SubElement(cmd, 'header')
ET.SubElement(header, 'type').text = 'rpc'

type = ET.SubElement(cmd, 'type')
rpc = ET.SubElement(type, 'rpc')

if operation.url:
ET.SubElement(rpc, 'fetch').text = operation.url

if operation.profile_name:
ET.SubElement(rpc, 'profileName').text = operation.profile_name

# Generate the XML string with declaration
xml_declaration = '<?xml version="1.0" encoding="utf-8"?>'
xml_str = ET.tostring(manifest, encoding='utf-8', method='xml').decode('utf-8')
return xml_declaration + '\n' + xml_str



def convert_system_software_operation_to_xml_manifest(operation: UpdateSystemSoftwareOperation) -> str:
"""Converts a UpdateSystemSoftwareOperation message to an XML manifest string for Dispatcher."""
# Create the root element
Expand Down
46 changes: 24 additions & 22 deletions inbm/cloudadapter-agent/cloudadapter/pb/common/v1/common_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 26 additions & 4 deletions inbm/cloudadapter-agent/cloudadapter/pb/common/v1/common_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class Operation(google.protobuf.message.Message):
SERVICE_TYPE_FIELD_NUMBER: builtins.int
UPDATE_SYSTEM_SOFTWARE_OPERATION_FIELD_NUMBER: builtins.int
SET_POWER_STATE_OPERATION_FIELD_NUMBER: builtins.int
RPC_ACTIVATE_OPERATION_FIELD_NUMBER: builtins.int
service_type: global___Operation.ServiceType.ValueType
@property
def pre_operations(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___PreOperation]: ...
Expand All @@ -212,7 +213,9 @@ class Operation(google.protobuf.message.Message):
@property
def update_system_software_operation(self) -> global___UpdateSystemSoftwareOperation: ...
@property
def set_power_state_operation(self) -> global___SetPowerStateOperation:
def set_power_state_operation(self) -> global___SetPowerStateOperation: ...
@property
def rpc_activate_operation(self) -> global___RpcActivateOperation:
"""and others"""

def __init__(
Expand All @@ -223,13 +226,32 @@ class Operation(google.protobuf.message.Message):
service_type: global___Operation.ServiceType.ValueType = ...,
update_system_software_operation: global___UpdateSystemSoftwareOperation | None = ...,
set_power_state_operation: global___SetPowerStateOperation | None = ...,
rpc_activate_operation: global___RpcActivateOperation | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["operation", b"operation", "set_power_state_operation", b"set_power_state_operation", "update_system_software_operation", b"update_system_software_operation"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["operation", b"operation", "post_operations", b"post_operations", "pre_operations", b"pre_operations", "service_type", b"service_type", "set_power_state_operation", b"set_power_state_operation", "update_system_software_operation", b"update_system_software_operation"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["operation", b"operation"]) -> typing.Literal["update_system_software_operation", "set_power_state_operation"] | None: ...
def HasField(self, field_name: typing.Literal["operation", b"operation", "rpc_activate_operation", b"rpc_activate_operation", "set_power_state_operation", b"set_power_state_operation", "update_system_software_operation", b"update_system_software_operation"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["operation", b"operation", "post_operations", b"post_operations", "pre_operations", b"pre_operations", "rpc_activate_operation", b"rpc_activate_operation", "service_type", b"service_type", "set_power_state_operation", b"set_power_state_operation", "update_system_software_operation", b"update_system_software_operation"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["operation", b"operation"]) -> typing.Literal["update_system_software_operation", "set_power_state_operation", "rpc_activate_operation"] | None: ...

global___Operation = Operation

@typing.final
class RpcActivateOperation(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor

URL_FIELD_NUMBER: builtins.int
PROFILE_NAME_FIELD_NUMBER: builtins.int
url: builtins.str
profile_name: builtins.str
def __init__(
self,
*,
url: builtins.str = ...,
profile_name: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["profile_name", b"profile_name", "url", b"url"]) -> None: ...

global___RpcActivateOperation = RpcActivateOperation

@typing.final
class UpdateSystemSoftwareOperation(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
Expand Down
Loading

0 comments on commit 114b6ea

Please sign in to comment.