Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to rename binding to annotation #12

Merged
merged 4 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
include ./VERSION
include ./src/generated/*.proto
include ./src/generated/*.pyi
include ./keysight_chakra/protos/*.proto
include ./keysight_chakra/generated/*.pyi
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ env: ## install env requirements
.PHONY: build
GENERATED_DIR := ./keysight_chakra/generated
build: ## compile all .proto files and generate artifacts
curl -L -o ./protos/et_def.proto https://raw.githubusercontent.com/mlcommons/chakra/main/schema/protobuf/et_def.proto
curl -L -o ./keysight_chakra/protos/et_def.proto https://raw.githubusercontent.com/mlcommons/chakra/main/schema/protobuf/et_def.proto
rm -rf $(GENERATED_DIR) || true
mkdir -p $(GENERATED_DIR)
python3 -m grpc_tools.protoc \
--proto_path=./protos \
--proto_path=./keysight_chakra/protos \
--python_out=$(GENERATED_DIR) \
--pyi_out=$(GENERATED_DIR) \
--grpc_python_out=$(GENERATED_DIR) \
et_def.proto infra.proto bind.proto service.proto
et_def.proto infra.proto annotate.proto service.proto
python3 -m pip uninstall -y keysight-chakra
python3 setup.py bdist_wheel
python3 -m pip install --no-cache .
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.1
1.1.0
57 changes: 26 additions & 31 deletions protos/bind.proto → keysight_chakra/protos/annotate.proto
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// bind.proto
// annotate.proto
//
// A data model to describe binding infrastructure paths to external
// A data model to annotate infrastructure paths with external
// application information.
//
// Some examples of binding third party information to infrastructure paths:
// Thesea are some examples of annotating infrastructure paths:
//
// binding = Binding(
// annotation = Annotation(
// device_instance="pod_switch.0",
// data=Data(
// name="routing",
// value="routing configuration information in a third party format"))
//
// binding = Binding(
// annotation = Annotation(
// device_instance_index_component_index="host.0.nic.0",
// data=Data(
// name="mellanox_config",
// value="additional nic configuration information in a third party format"))
//
// binding = Binding(
// annotation = Annotation(
// infrastructure="ranks",
// data=Data(
// name="rank_to_host_map",
Expand All @@ -26,12 +26,12 @@

syntax = "proto3";

package bind;
package annotate;

import "google/protobuf/any.proto";

// Data message allows a user to provide data outside of the scope of the
// infrastructure graph.
// Data message allows a user to provide data that is outside of the scope of
// the infrastructure graph.
message Data {
// Use this field to provide descriptive information about the message
// that is packed into the value field.
Expand Down Expand Up @@ -59,45 +59,45 @@ message Data {
google.protobuf.Any value = 2;
}

// The BindTarget message
message BindTarget {
// The location of infrastructure that matches the binding type format
// The Target message
message Target {
// The location of infrastructure that is associated with the annotation data
oneof infrastructure_path {
// the binding is global to the infrastructure and the value provided here
// is for informational purposes only
// the annotation is global to the infrastructure and the value provided
// here is for informational purposes only
string infrastructure = 1;

// binding is specific to an Infrastructure.inventory.device.name
// the annotation is specific to an Infrastructure.inventory.device.name
// example: dgx
string device = 2;

// binding is specific to an Infrastructure.inventory.device.name
// the annotation is specific to an Infrastructure.inventory.device.name
// example: dgx.npu
string device_component = 3;

// binding is specific to an Infrastructure.inventory.device.name
// the annotation is specific to an Infrastructure.inventory.device.name
// example: dgx.npu.0
string device_component_index = 4;

// binding is specific to an instance of
// the annotation is specific to an instance of
// Infrastructure.device_instances.name
// example: host
string device_instance = 5;

// binding is specific to an instance of
// the annotation is specific to an instance of
// Infrastructure.device_instances.name
// and an index < Infrastructure.device_instances.count
// example: host.1
string device_instance_index = 6;

// binding is specific to an instance of
// the annotation is specific to an instance of
// Infrastructure.device_instances.name
// and an index < Infrastructure.device_instances.count
// and an Infrastructure.inventory.device.component.name
// example: host.1.npu
string device_instance_index_component = 7;

// binding is specific to an instance of
// the annotation is specific to an instance of
// Infrastructure.device_instances.name
// and an index < Infrastructure.device_instances.count
// and an Infrastructure.inventory.device.component.name
Expand All @@ -107,22 +107,17 @@ message BindTarget {
}
}

// The Binding message offers the option of binding different types of logical
// Infrastructure endpoints to any type of user defined data.
// The Annotation message allows for associating different types of
// logical Infrastructure endpoints to any type of user defined data.
//
// The format allows for data to be applied at a macro level such as
// all devices or at a micro level such as an individual component in a
// specific device instance.
message Binding {
// targets is a list of BindTarget messages that share the same
message Annotation {
// targets is a list of Target messages that share the same
// user defined information stored in the data field
repeated BindTarget targets = 1;
repeated Target targets = 1;

// the data field accomodates any type of user defined information
Data data = 100;
}

message Bindings {
// A list of user defined information for specific endpoints
repeated Binding bindings = 1;
}
File renamed without changes.
File renamed without changes.
14 changes: 7 additions & 7 deletions protos/service.proto → keysight_chakra/protos/service.proto
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// service.proto
//
// Service and rpcs for infrastructure and bindings
// Service and rpcs for infrastructure and annotations

syntax = "proto3";

package service;

import "infra.proto";
import "bind.proto";
import "annotate.proto";

message ValidationRequest {
infra.Infrastructure infrastructure = 1;
bind.Bindings bindings = 2;
repeated annotate.Annotation annotations = 2;
}

message ValidationError {
Expand All @@ -29,9 +29,9 @@ message ValidationError {
// the following cases fall under this type:
// connection structure is incorrectly formatted
// connection pieces are not present in the inventory or device instances
// binding infrastructure path is incorrectly formatted
// binding infrastructure path pieces are not present in the infrastructure
// inventory
// annotation infrastructure path is incorrectly formatted
// annotation infrastructure path pieces are not present in the
// infrastructure inventory
string referential_integrity = 4;

// scale up / scale out count
Expand All @@ -46,6 +46,6 @@ message ValidationResponse {
}

service InfraService {
// Validate rpc validates both infra and binding messages
// Validate rpc validates both infra and annotation messages
rpc Validate(ValidationRequest) returns (ValidationResponse);
}
62 changes: 62 additions & 0 deletions keysight_chakra/tests/test_serialization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import pytest
from google.protobuf.json_format import MessageToJson, Parse
from google.protobuf.any_pb2 import Any
from google.protobuf.wrappers_pb2 import StringValue
from keysight_chakra.generated.annotate_pb2 import Annotation, Target, Data


class AnyString:
"""Wrapper class for StringValue and Any"""

TYPE = "type.googleapis.com/google.protobuf.StringValue"

@staticmethod
def get_any(value: str) -> Any:
"""Returns an Any message with the string encapsulated using StringValue"""
assert isinstance(value, str)
any: Any = Any()
any.Pack(StringValue(value=value))
return any

def get_str(any: Any) -> str:
"""Returns a str from an Any message"""
assert isinstance(any, Any)
assert any.type_url == AnyString.TYPE
string_value = StringValue()
any.Unpack(string_value)
return string_value.value


def test_string_serialization():
"""Test serialization of Any string values in protobuf messages to json
and from json.
"""
annotation_value = "3 Tier Clos Fabric Infrastructure"

annotation1 = Annotation(
targets=[Target(infrastructure="Infrastructure Description")],
data=Data(
name="Description",
value=AnyString.get_any(annotation_value),
),
)

# serialization to json string
serialized_json = MessageToJson(annotation1)

# deserialize json string to protobuf message
annotation2 = Annotation()
Parse(serialized_json, annotation2)

# validate that the original message is the same as the serialized
# to deserialized message
for target1, target2 in zip(annotation1.targets, annotation2.targets):
assert target1.infrastructure == target2.infrastructure

annotation1_value = AnyString.get_str(annotation1.data.value)
annotation2_value = AnyString.get_str(annotation2.data.value)
assert annotation1_value == annotation2_value == annotation_value


if __name__ == "__main__":
pytest.main(["-s", "-o", "log_cli=True", "-o", "log_cli_level=INFO", __file__])
12 changes: 6 additions & 6 deletions keysight_chakra/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from google.protobuf.message import Message
from generated.service_pb2 import ValidationRequest, ValidationError, ValidationResponse
from generated.infra_pb2 import Device
from generated.bind_pb2 import Binding
from generated.annotate_pb2 import Annotation


class Validation:
Expand Down Expand Up @@ -86,7 +86,7 @@ def _validate_device_exists(self, name: str):
def _validate_device_connection(self, connection: str):
pass

def _validate_binding_infrastructure_path(self, binding: Binding):
def _validate_target_path(self, annotation: Annotation):
pass

def _validate_count(self, object: Message):
Expand Down Expand Up @@ -141,8 +141,8 @@ def validate(self, request: ValidationRequest):
self._validate_device_exists(device_instance.device)
for connection in request.infrastructure.connections:
self._validate_device_connection(connection)
if request.bindings is not None:
for binding in request.bindings.bindings:
self._validate_oneof(binding, "infrastructure_path")
self._validate_binding_infrastructure_path(binding)
if request.annotations is not None:
for annotation in request.annotations:
self._validate_oneof(annotation, "infrastructure_path")
self._validate_target_path(annotation)
return self._validation_response
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
python_requires=">=3.8",
author="Keysight",
author_email=f"[email protected]",
url="https://keysight.com",
url="https://github.com/Keysight/infrastructure",
packages=set(package_dir_map.keys()),
package_dir=package_dir_map,
include_package_data=True,
Expand Down