Loading .gitignore +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ MANIFEST # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest .manifest/ *.spec # Installer logs Loading proto/context.proto +49 −29 Original line number Diff line number Diff line Loading @@ -79,11 +79,17 @@ service ContextService { // ------------------------------ Experimental ----------------------------- rpc GetOpticalConfig (Empty ) returns (OpticalConfigList) {} rpc SetOpticalConfig (OpticalConfig ) returns (OpticalConfigId ) {} rpc UpdateOpticalConfig (OpticalConfig ) returns (OpticalConfigId ) {} rpc SelectOpticalConfig (OpticalConfigId ) returns (OpticalConfig ) {} rpc DeleteOpticalConfig (OpticalConfigId ) returns (Empty ) {} rpc DeleteOpticalChannel (OpticalConfig ) returns (Empty ) {} rpc SetOpticalLink (OpticalLink ) returns (Empty ) {} rpc GetOpticalLink (OpticalLinkId ) returns (OpticalLink ) {} rpc GetFiber (FiberId ) returns (Fiber ) {} rpc GetOpticalLink (LinkId ) returns (OpticalLink ) {} rpc DeleteOpticalLink (LinkId ) returns (Empty ) {} rpc GetOpticalLinkList (Empty ) returns (OpticalLinkList ) {} rpc DeleteServiceConfigRule(ServiceConfigRule) returns (Empty ) {} } // ----- Generic ------------------------------------------------------------------------------------------------------- Loading Loading @@ -148,6 +154,7 @@ message Topology { string name = 2; repeated DeviceId device_ids = 3; repeated LinkId link_ids = 4; repeated LinkId optical_link_ids = 5; } message TopologyDetails { Loading @@ -155,6 +162,7 @@ message TopologyDetails { string name = 2; repeated Device devices = 3; repeated Link links = 4; repeated OpticalLink optical_links = 5; } message TopologyIdList { Loading Loading @@ -653,45 +661,57 @@ message OpticalConfigId { message OpticalConfig { OpticalConfigId opticalconfig_id = 1; string config = 2; DeviceId device_id = 3; } message OpticalConfigList { repeated OpticalConfig opticalconfigs = 1; } message OpticalConfigEvent { Event event = 1; OpticalConfigId opticalconfig_id = 2; } // ---- Optical Link ---- message OpticalLinkId { Uuid optical_link_uuid = 1; message OpticalEndPointId { DeviceId device_id = 2; Uuid endpoint_uuid = 3; } message FiberId { Uuid fiber_uuid = 1; message OpticalLinkList { repeated OpticalLink optical_links = 1; } message Fiber { string ID = 10; string src_port = 1; string dst_port = 2; string local_peer_port = 3; string remote_peer_port = 4; repeated int32 c_slots = 5; repeated int32 l_slots = 6; repeated int32 s_slots = 7; float length = 8; bool used = 9; FiberId fiber_uuid = 11; } message OpticalLinkDetails { float length = 1; string source = 2; string target = 3; repeated Fiber fibers = 4; string src_port = 2; string dst_port = 3; string local_peer_port = 4; string remote_peer_port = 5 ; bool used = 6 ; map<string, int32> c_slots = 7; map<string, int32> l_slots = 8; map<string, int32> s_slots = 9; } message OpticalLink { string name = 1; OpticalLinkDetails details = 2; OpticalLinkId optical_link_uuid = 3; OpticalLinkDetails optical_details = 2; LinkId link_id = 3; repeated EndPointId link_endpoint_ids=4; } ////////////////// Config Rule Delete //////////// message ServiceConfigRule { ServiceId service_id =1; ConfigRule_Custom configrule_custom =2; } proto/openconfig_device.proto→proto/optical_device.proto +5 −3 Original line number Diff line number Diff line Loading @@ -13,11 +13,13 @@ // limitations under the License. syntax = "proto3"; package openconfig_device; package optical_device; import "context.proto"; service OpenConfigService { rpc AddOpenConfigDevice (context.OpticalConfig ) returns (context.OpticalConfigId) {} rpc ConfigureOpticalDevice(context.OpticalConfig ) returns (context.Empty ) {} rpc DisableOpticalDevice (context.OpticalConfig ) returns (context.Empty ) {} rpc GetDeviceConfiguration(context.OpticalConfigList) returns (context.Empty ) {} } src/automation/client/PolicyClient.py +1 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ from common.proto.policy_pb2 import PolicyRuleService, PolicyRuleState from common.proto.policy_pb2_grpc import PolicyServiceStub from common.tools.client.RetryDecorator import retry, delay_exponential from common.tools.grpc.Tools import grpc_message_to_json_string from common.proto.openconfig_device_pb2_grpc import OpenConfigServiceStub LOGGER = logging.getLogger(__name__) MAX_RETRIES = 15 DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0) Loading @@ -40,7 +40,6 @@ class PolicyClient: def connect(self): self.channel = grpc.insecure_channel(self.endpoint) self.stub = PolicyServiceStub(self.channel) self.openconfig_stub=OpenConfigServiceStub(self.channel) def close(self): if self.channel is not None: self.channel.close() Loading src/common/tools/context_queries/OpticalConfig.py 0 → 100644 +66 −0 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from common.method_wrappers.ServiceExceptions import InvalidArgumentsException from typing import Optional, Union from uuid import UUID, uuid4, uuid5 # Generate a UUIDv5-like from the SHA-1 of "TFS" and no namespace to be used as the NAMESPACE for all # the context UUIDs generated. For efficiency purposes, the UUID is hardcoded; however, it is produced # using the following code: # from hashlib import sha1 # from uuid import UUID # hash = sha1(bytes('TFS', 'utf-8')).digest() # NAMESPACE_TFS = UUID(bytes=hash[:16], version=5) NAMESPACE_TFS = UUID('200e3a1f-2223-534f-a100-758e29c37f40') def get_uuid_from_string(str_uuid_or_name : Union[str, UUID], prefix_for_name : Optional[str] = None) -> str: # if UUID given, assume it is already a valid UUID if isinstance(str_uuid_or_name, UUID): return str_uuid_or_name if not isinstance(str_uuid_or_name, str): MSG = 'Parameter({:s}) cannot be used to produce a UUID' raise Exception(MSG.format(str(repr(str_uuid_or_name)))) try: # try to parse as UUID return str(UUID(str_uuid_or_name)) except: # pylint: disable=bare-except # produce a UUID within TFS namespace from parameter if prefix_for_name is not None: str_uuid_or_name = '{:s}/{:s}'.format(prefix_for_name, str_uuid_or_name) return str(uuid5(NAMESPACE_TFS, str_uuid_or_name)) def get_uuid_random() -> str: # Generate random UUID. No need to use namespace since "namespace + random = random". return str(uuid4()) def device_get_uuid (device_name) : if (len(device_name)> 0): return get_uuid_from_string(device_name) raise InvalidArgumentsException([ ('name', device_name), ], extra_details=['Device Name is required to produce Device UUID']) def opticalconfig_get_uuid( device_name : str = '', allow_random : bool = False ) -> str: if len(device_name) > 0: device_uuid= device_get_uuid(device_name=device_name) return get_uuid_from_string(f"{device_uuid}_opticalconfig") if allow_random: return get_uuid_random() raise InvalidArgumentsException([ ('name', device_name), ], extra_details=['At least one is required to produce a OpticalConfig UUID']) Loading
.gitignore +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ MANIFEST # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest .manifest/ *.spec # Installer logs Loading
proto/context.proto +49 −29 Original line number Diff line number Diff line Loading @@ -79,11 +79,17 @@ service ContextService { // ------------------------------ Experimental ----------------------------- rpc GetOpticalConfig (Empty ) returns (OpticalConfigList) {} rpc SetOpticalConfig (OpticalConfig ) returns (OpticalConfigId ) {} rpc UpdateOpticalConfig (OpticalConfig ) returns (OpticalConfigId ) {} rpc SelectOpticalConfig (OpticalConfigId ) returns (OpticalConfig ) {} rpc DeleteOpticalConfig (OpticalConfigId ) returns (Empty ) {} rpc DeleteOpticalChannel (OpticalConfig ) returns (Empty ) {} rpc SetOpticalLink (OpticalLink ) returns (Empty ) {} rpc GetOpticalLink (OpticalLinkId ) returns (OpticalLink ) {} rpc GetFiber (FiberId ) returns (Fiber ) {} rpc GetOpticalLink (LinkId ) returns (OpticalLink ) {} rpc DeleteOpticalLink (LinkId ) returns (Empty ) {} rpc GetOpticalLinkList (Empty ) returns (OpticalLinkList ) {} rpc DeleteServiceConfigRule(ServiceConfigRule) returns (Empty ) {} } // ----- Generic ------------------------------------------------------------------------------------------------------- Loading Loading @@ -148,6 +154,7 @@ message Topology { string name = 2; repeated DeviceId device_ids = 3; repeated LinkId link_ids = 4; repeated LinkId optical_link_ids = 5; } message TopologyDetails { Loading @@ -155,6 +162,7 @@ message TopologyDetails { string name = 2; repeated Device devices = 3; repeated Link links = 4; repeated OpticalLink optical_links = 5; } message TopologyIdList { Loading Loading @@ -653,45 +661,57 @@ message OpticalConfigId { message OpticalConfig { OpticalConfigId opticalconfig_id = 1; string config = 2; DeviceId device_id = 3; } message OpticalConfigList { repeated OpticalConfig opticalconfigs = 1; } message OpticalConfigEvent { Event event = 1; OpticalConfigId opticalconfig_id = 2; } // ---- Optical Link ---- message OpticalLinkId { Uuid optical_link_uuid = 1; message OpticalEndPointId { DeviceId device_id = 2; Uuid endpoint_uuid = 3; } message FiberId { Uuid fiber_uuid = 1; message OpticalLinkList { repeated OpticalLink optical_links = 1; } message Fiber { string ID = 10; string src_port = 1; string dst_port = 2; string local_peer_port = 3; string remote_peer_port = 4; repeated int32 c_slots = 5; repeated int32 l_slots = 6; repeated int32 s_slots = 7; float length = 8; bool used = 9; FiberId fiber_uuid = 11; } message OpticalLinkDetails { float length = 1; string source = 2; string target = 3; repeated Fiber fibers = 4; string src_port = 2; string dst_port = 3; string local_peer_port = 4; string remote_peer_port = 5 ; bool used = 6 ; map<string, int32> c_slots = 7; map<string, int32> l_slots = 8; map<string, int32> s_slots = 9; } message OpticalLink { string name = 1; OpticalLinkDetails details = 2; OpticalLinkId optical_link_uuid = 3; OpticalLinkDetails optical_details = 2; LinkId link_id = 3; repeated EndPointId link_endpoint_ids=4; } ////////////////// Config Rule Delete //////////// message ServiceConfigRule { ServiceId service_id =1; ConfigRule_Custom configrule_custom =2; }
proto/openconfig_device.proto→proto/optical_device.proto +5 −3 Original line number Diff line number Diff line Loading @@ -13,11 +13,13 @@ // limitations under the License. syntax = "proto3"; package openconfig_device; package optical_device; import "context.proto"; service OpenConfigService { rpc AddOpenConfigDevice (context.OpticalConfig ) returns (context.OpticalConfigId) {} rpc ConfigureOpticalDevice(context.OpticalConfig ) returns (context.Empty ) {} rpc DisableOpticalDevice (context.OpticalConfig ) returns (context.Empty ) {} rpc GetDeviceConfiguration(context.OpticalConfigList) returns (context.Empty ) {} }
src/automation/client/PolicyClient.py +1 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ from common.proto.policy_pb2 import PolicyRuleService, PolicyRuleState from common.proto.policy_pb2_grpc import PolicyServiceStub from common.tools.client.RetryDecorator import retry, delay_exponential from common.tools.grpc.Tools import grpc_message_to_json_string from common.proto.openconfig_device_pb2_grpc import OpenConfigServiceStub LOGGER = logging.getLogger(__name__) MAX_RETRIES = 15 DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0) Loading @@ -40,7 +40,6 @@ class PolicyClient: def connect(self): self.channel = grpc.insecure_channel(self.endpoint) self.stub = PolicyServiceStub(self.channel) self.openconfig_stub=OpenConfigServiceStub(self.channel) def close(self): if self.channel is not None: self.channel.close() Loading
src/common/tools/context_queries/OpticalConfig.py 0 → 100644 +66 −0 Original line number Diff line number Diff line # Copyright 2022-2024 ETSI OSG/SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from common.method_wrappers.ServiceExceptions import InvalidArgumentsException from typing import Optional, Union from uuid import UUID, uuid4, uuid5 # Generate a UUIDv5-like from the SHA-1 of "TFS" and no namespace to be used as the NAMESPACE for all # the context UUIDs generated. For efficiency purposes, the UUID is hardcoded; however, it is produced # using the following code: # from hashlib import sha1 # from uuid import UUID # hash = sha1(bytes('TFS', 'utf-8')).digest() # NAMESPACE_TFS = UUID(bytes=hash[:16], version=5) NAMESPACE_TFS = UUID('200e3a1f-2223-534f-a100-758e29c37f40') def get_uuid_from_string(str_uuid_or_name : Union[str, UUID], prefix_for_name : Optional[str] = None) -> str: # if UUID given, assume it is already a valid UUID if isinstance(str_uuid_or_name, UUID): return str_uuid_or_name if not isinstance(str_uuid_or_name, str): MSG = 'Parameter({:s}) cannot be used to produce a UUID' raise Exception(MSG.format(str(repr(str_uuid_or_name)))) try: # try to parse as UUID return str(UUID(str_uuid_or_name)) except: # pylint: disable=bare-except # produce a UUID within TFS namespace from parameter if prefix_for_name is not None: str_uuid_or_name = '{:s}/{:s}'.format(prefix_for_name, str_uuid_or_name) return str(uuid5(NAMESPACE_TFS, str_uuid_or_name)) def get_uuid_random() -> str: # Generate random UUID. No need to use namespace since "namespace + random = random". return str(uuid4()) def device_get_uuid (device_name) : if (len(device_name)> 0): return get_uuid_from_string(device_name) raise InvalidArgumentsException([ ('name', device_name), ], extra_details=['Device Name is required to produce Device UUID']) def opticalconfig_get_uuid( device_name : str = '', allow_random : bool = False ) -> str: if len(device_name) > 0: device_uuid= device_get_uuid(device_name=device_name) return get_uuid_from_string(f"{device_uuid}_opticalconfig") if allow_random: return get_uuid_random() raise InvalidArgumentsException([ ('name', device_name), ], extra_details=['At least one is required to produce a OpticalConfig UUID'])