From 9cb87aa02679c147b4cd23b77a2a2bd6f745062e Mon Sep 17 00:00:00 2001 From: anbalogh Date: Tue, 12 Nov 2024 23:04:19 +0000 Subject: [PATCH] additional validation checks --- protos/infra.proto | 6 ++++-- protos/service.proto | 3 +++ src/service.py | 30 ++++++++++++++++++++++++++++++ src/tests/test_service.py | 15 +++++++++++++-- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/protos/infra.proto b/protos/infra.proto index 6d8a791..ca1419a 100644 --- a/protos/infra.proto +++ b/protos/infra.proto @@ -168,6 +168,7 @@ message DeviceInstances { optional string device = 2; // the number of instances of the device in the infrastructure under this name + // must be >= 1 optional uint32 count = 3; } @@ -200,9 +201,10 @@ message Infrastructure { // The inventory of devices and links present in the infrastructure Inventory inventory = 1; - // A list of the device instances that represents the total number of devices + // A map of the device instances that represents the total number of devices // in the infrastructure. - repeated DeviceInstances device_instances = 2; + // Use this to scale out infrastructure + map device_instances = 2; // format: The following pieces of information each separated by a "." // diff --git a/protos/service.proto b/protos/service.proto index f812036..2b49654 100644 --- a/protos/service.proto +++ b/protos/service.proto @@ -33,6 +33,9 @@ message ValidationError { // binding infrastructure path pieces are not present in the infrastructure // inventory string referential_integrity = 4; + + // scale up / scale out count + string count = 5; } } diff --git a/src/service.py b/src/service.py index 7a0e9e1..9ad2aa6 100644 --- a/src/service.py +++ b/src/service.py @@ -76,6 +76,24 @@ def _validate_oneof(self, object, name): ValidationError(oneof=f"{object.DESCRIPTOR.name} oneof:{name} must be set") ) + def _validate_device_exists(self, name): + if name not in self._validation_request.infrastructure.inventory.devices: + self._validation_response.errors.append( + ValidationError(referential_integrity=f"Infrastructure.devices[{name}] does not exist") + ) + + def _validate_infrastructure_connection(self, connection): + pass + + def _validate_binding_infrastructure_path(self, binding): + pass + + def _validate_count(self, count): + if count < 1: + self._validation_response.errors.append( + ValidationError(count=f"Count {count} must be greater than 0") + ) + def validate(self, request: ValidationRequest): """Validate Infrastructure and Bindings. @@ -110,4 +128,16 @@ def validate(self, request: ValidationRequest): self._validate_component_connection(device, connection) for link in device.links.values(): self._validate_oneof(link.bandwidth, "type") + for link in request.infrastructure.inventory.links: + self._validate_presence(link, "name") + self._validate_map(request.infrastructure.device_instances) + for device_instance in request.infrastructure.device_instances.values(): + self._validate_count(device_instance.count) + self._validate_device_exists(device_instance.device) + for connection in request.infrastructure.connections: + self._validate_infrastructure_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) return self._validation_response diff --git a/src/tests/test_service.py b/src/tests/test_service.py index 11111da..e5222cf 100644 --- a/src/tests/test_service.py +++ b/src/tests/test_service.py @@ -1,7 +1,16 @@ import pytest from service import Service from generated.service_pb2 import ValidationRequest -from generated.infra_pb2 import Infrastructure, Inventory, Device, Link, LinkType, Bandwidth, Component +from generated.infra_pb2 import ( + Infrastructure, + Inventory, + Device, + Link, + LinkType, + Bandwidth, + Component, + DeviceInstances, +) def test_valid_device(device): @@ -33,7 +42,7 @@ def test_missing_bandwidth(): def test_referential_integrity(): """Referential integrity tests""" - device = Device(name="host") + device = Device(name="laptop") mii = Link(name="mii", type=LinkType.LINK_CUSTOM, bandwidth=Bandwidth(gbps=100)) device.links[mii.name].CopyFrom(mii) asic = Component(name="asic", count=1) @@ -45,6 +54,8 @@ def test_referential_integrity(): inventory = Inventory() inventory.devices[device.name].CopyFrom(device) infrastructure = Infrastructure(inventory=inventory) + host = DeviceInstances(name="host", device="laptop", count=4) + infrastructure.device_instances[host.name].CopyFrom(host) request = ValidationRequest(infrastructure=infrastructure) response = Service().validate(request=request) print(response)