Commits (15)
......@@ -36,7 +36,7 @@ spec:
- containerPort: 9192
env:
- name: LOG_LEVEL
value: "INFO"
value: "DEBUG"
readinessProbe:
exec:
command: ["/bin/grpc_health_probe", "-addr=:2020"]
......
......@@ -36,7 +36,7 @@ spec:
- containerPort: 9192
env:
- name: LOG_LEVEL
value: "INFO"
value: "DEBUG"
envFrom:
- secretRef:
name: qdb-data
......
......@@ -58,7 +58,7 @@ export CRDB_DATABASE="tfs"
export CRDB_DEPLOY_MODE="single"
# Disable flag for dropping database, if exists.
export CRDB_DROP_DATABASE_IF_EXISTS=""
export CRDB_DROP_DATABASE_IF_EXISTS="YES"
# Disable flag for re-deploying CockroachDB from scratch.
export CRDB_REDEPLOY=""
......@@ -88,7 +88,7 @@ export QDB_PASSWORD="quest"
export QDB_TABLE="tfs_monitoring"
## If not already set, disable flag for dropping table if exists.
#export QDB_DROP_TABLE_IF_EXISTS=""
export QDB_DROP_TABLE_IF_EXISTS=""
# If not already set, disable flag for re-deploying QuestDB from scratch.
export QDB_REDEPLOY=""
export QDB_REDEPLOY="YES"
......@@ -83,7 +83,6 @@ DEFAULT_SERVICE_HTTP_PORTS = {
# Default HTTP/REST-API service base URLs
DEFAULT_SERVICE_HTTP_BASEURLS = {
ServiceNameEnum.CONTEXT .value : '/api',
ServiceNameEnum.COMPUTE .value : '/restconf/data',
ServiceNameEnum.COMPUTE .value : '/restconf',
ServiceNameEnum.WEBUI .value : None,
}
......@@ -31,8 +31,8 @@
# for message,level in compose_notifications(results):
# loggers.get(level)(message)
import json
from typing import Dict, List, Optional, Tuple, Union
import concurrent.futures, json, logging, operator
from typing import Any, Dict, List, Optional, Tuple, Union
from common.proto.context_pb2 import Connection, Context, Device, Link, Service, Slice, Topology
from context.client.ContextClient import ContextClient
from device.client.DeviceClient import DeviceClient
......@@ -43,6 +43,8 @@ from .Tools import (
get_descriptors_add_contexts, get_descriptors_add_services, get_descriptors_add_slices,
get_descriptors_add_topologies, split_devices_by_rules)
LOGGER = logging.getLogger(__name__)
ENTITY_TO_TEXT = {
# name => singular, plural
'context' : ('Context', 'Contexts' ),
......@@ -79,7 +81,7 @@ def compose_notifications(results : TypeResults) -> TypeNotificationList:
class DescriptorLoader:
def __init__(
self, descriptors : Union[str, Dict],
self, descriptors : Union[str, Dict], num_workers : int = 1,
context_client : Optional[ContextClient] = None, device_client : Optional[DeviceClient] = None,
service_client : Optional[ServiceClient] = None, slice_client : Optional[SliceClient] = None
) -> None:
......@@ -93,6 +95,8 @@ class DescriptorLoader:
self.__slices = self.__descriptors.get('slices' , [])
self.__connections = self.__descriptors.get('connections', [])
self.__num_workers = num_workers
self.__contexts_add = None
self.__topologies_add = None
self.__devices_add = None
......@@ -242,12 +246,26 @@ class DescriptorLoader:
#self.__dev_cli.close()
#self.__ctx_cli.close()
@staticmethod
def worker(grpc_method, grpc_class, entity) -> Any:
return grpc_method(grpc_class(**entity))
def _process_descr(self, entity_name, action_name, grpc_method, grpc_class, entities) -> None:
num_ok, error_list = 0, []
for entity in entities:
try:
grpc_method(grpc_class(**entity))
num_ok += 1
except Exception as e: # pylint: disable=broad-except
error_list.append(f'{str(entity)}: {str(e)}')
with concurrent.futures.ThreadPoolExecutor(max_workers=self.__num_workers) as executor:
future_to_entity = {
executor.submit(DescriptorLoader.worker, grpc_method, grpc_class, entity): (i, entity)
for i,entity in enumerate(entities)
}
for future in concurrent.futures.as_completed(future_to_entity):
i, entity = future_to_entity[future]
try:
_ = future.result()
num_ok += 1
except Exception as e: # pylint: disable=broad-except
error_list.append((i, f'{str(entity)}: {str(e)}'))
error_list = [str_error for _,str_error in sorted(error_list, key=operator.itemgetter(0))]
self.__results.append((entity_name, action_name, num_ok, error_list))
......@@ -26,7 +26,7 @@ from .rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn
terminate = threading.Event()
LOGGER = None
def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
def signal_handler(signal, frame): # pylint: disable=redefined-outer-name, unused-argument
LOGGER.warning('Terminate signal received')
terminate.set()
......
......@@ -12,48 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from flask.json import jsonify
from flask_restful import Resource
from common.proto.context_pb2 import ConnectionId, ContextId, DeviceId, Empty, LinkId, ServiceId, SliceId, TopologyId
from common.proto.policy_pb2 import PolicyRuleId
from common.tools.grpc.Tools import grpc_message_to_json
from common.tools.object_factory.Connection import json_connection_id
from common.tools.object_factory.Context import json_context_id
from common.tools.object_factory.Device import json_device_id
from common.tools.object_factory.Link import json_link_id
from common.tools.object_factory.PolicyRule import json_policyrule_id
from common.tools.object_factory.Service import json_service_id
from common.tools.object_factory.Slice import json_slice_id
from common.tools.object_factory.Topology import json_topology_id
from common.proto.context_pb2 import Empty
from context.client.ContextClient import ContextClient
def format_grpc_to_json(grpc_reply):
return jsonify(grpc_message_to_json(grpc_reply))
def grpc_connection_id(connection_uuid):
return ConnectionId(**json_connection_id(connection_uuid))
def grpc_context_id(context_uuid):
return ContextId(**json_context_id(context_uuid))
def grpc_device_id(device_uuid):
return DeviceId(**json_device_id(device_uuid))
def grpc_link_id(link_uuid):
return LinkId(**json_link_id(link_uuid))
def grpc_service_id(context_uuid, service_uuid):
return ServiceId(**json_service_id(service_uuid, context_id=json_context_id(context_uuid)))
def grpc_slice_id(context_uuid, slice_uuid):
return SliceId(**json_slice_id(slice_uuid, context_id=json_context_id(context_uuid)))
def grpc_topology_id(context_uuid, topology_uuid):
return TopologyId(**json_topology_id(topology_uuid, context_id=json_context_id(context_uuid)))
def grpc_policy_rule_id(policy_rule_uuid):
return PolicyRuleId(**json_policyrule_id(policy_rule_uuid))
from .Tools import (
format_grpc_to_json, grpc_connection_id, grpc_context_id, grpc_device_id, grpc_link_id, grpc_policy_rule_id,
grpc_service_id, grpc_slice_id, grpc_topology_id)
class _Resource(Resource):
......
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (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 flask.json import jsonify
from common.proto.context_pb2 import ConnectionId, ContextId, DeviceId, LinkId, ServiceId, SliceId, TopologyId
from common.proto.policy_pb2 import PolicyRuleId
from common.tools.grpc.Tools import grpc_message_to_json
from common.tools.object_factory.Connection import json_connection_id
from common.tools.object_factory.Context import json_context_id
from common.tools.object_factory.Device import json_device_id
from common.tools.object_factory.Link import json_link_id
from common.tools.object_factory.PolicyRule import json_policyrule_id
from common.tools.object_factory.Service import json_service_id
from common.tools.object_factory.Slice import json_slice_id
from common.tools.object_factory.Topology import json_topology_id
def format_grpc_to_json(grpc_reply):
return jsonify(grpc_message_to_json(grpc_reply))
def grpc_connection_id(connection_uuid):
return ConnectionId(**json_connection_id(connection_uuid))
def grpc_context_id(context_uuid):
return ContextId(**json_context_id(context_uuid))
def grpc_device_id(device_uuid):
return DeviceId(**json_device_id(device_uuid))
def grpc_link_id(link_uuid):
return LinkId(**json_link_id(link_uuid))
def grpc_service_id(context_uuid, service_uuid):
return ServiceId(**json_service_id(service_uuid, context_id=json_context_id(context_uuid)))
def grpc_slice_id(context_uuid, slice_uuid):
return SliceId(**json_slice_id(slice_uuid, context_id=json_context_id(context_uuid)))
def grpc_topology_id(context_uuid, topology_uuid):
return TopologyId(**json_topology_id(topology_uuid, context_id=json_context_id(context_uuid)))
def grpc_policy_rule_id(policy_rule_uuid):
return PolicyRuleId(**json_policyrule_id(policy_rule_uuid))
......@@ -12,52 +12,48 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# RFC 8466 - L2VPN Service Model (L2SM)
# Ref: https://datatracker.ietf.org/doc/html/rfc8466
from compute.service.rest_server.RestServer import RestServer
from .Resources import (
Connection, ConnectionIds, Connections, Context, ContextIds, Contexts, Device, DeviceIds, Devices, Link, LinkIds,
Links, PolicyRule, PolicyRuleIds, PolicyRules, Service, ServiceIds, Services, Slice, SliceIds, Slices, Topologies,
Topology, TopologyIds)
URL_PREFIX = '/api'
URL_PREFIX = '/debug-api'
# Use 'path' type in Service and Sink because service_uuid and link_uuid might contain char '/' and Flask is unable to
# recognize them in 'string' type.
# Use 'path' type since some identifiers might contain char '/' and Flask is unable to recognize them in 'string' type.
RESOURCES = [
# (endpoint_name, resource_class, resource_url)
('api.context_ids', ContextIds, '/context_ids'),
('api.contexts', Contexts, '/contexts'),
('api.context', Context, '/context/<string:context_uuid>'),
('api.context', Context, '/context/<path:context_uuid>'),
('api.topology_ids', TopologyIds, '/context/<string:context_uuid>/topology_ids'),
('api.topologies', Topologies, '/context/<string:context_uuid>/topologies'),
('api.topology', Topology, '/context/<string:context_uuid>/topology/<string:topology_uuid>'),
('api.topology_ids', TopologyIds, '/context/<path:context_uuid>/topology_ids'),
('api.topologies', Topologies, '/context/<path:context_uuid>/topologies'),
('api.topology', Topology, '/context/<path:context_uuid>/topology/<path:topology_uuid>'),
('api.service_ids', ServiceIds, '/context/<string:context_uuid>/service_ids'),
('api.services', Services, '/context/<string:context_uuid>/services'),
('api.service', Service, '/context/<string:context_uuid>/service/<path:service_uuid>'),
('api.service_ids', ServiceIds, '/context/<path:context_uuid>/service_ids'),
('api.services', Services, '/context/<path:context_uuid>/services'),
('api.service', Service, '/context/<path:context_uuid>/service/<path:service_uuid>'),
('api.slice_ids', SliceIds, '/context/<string:context_uuid>/slice_ids'),
('api.slices', Slices, '/context/<string:context_uuid>/slices'),
('api.slice', Slice, '/context/<string:context_uuid>/slice/<path:slice_uuid>'),
('api.slice_ids', SliceIds, '/context/<path:context_uuid>/slice_ids'),
('api.slices', Slices, '/context/<path:context_uuid>/slices'),
('api.slice', Slice, '/context/<path:context_uuid>/slice/<path:slice_uuid>'),
('api.device_ids', DeviceIds, '/device_ids'),
('api.devices', Devices, '/devices'),
('api.device', Device, '/device/<string:device_uuid>'),
('api.device', Device, '/device/<path:device_uuid>'),
('api.link_ids', LinkIds, '/link_ids'),
('api.links', Links, '/links'),
('api.link', Link, '/link/<path:link_uuid>'),
('api.connection_ids', ConnectionIds, '/context/<string:context_uuid>/service/<path:service_uuid>/connection_ids'),
('api.connections', Connections, '/context/<string:context_uuid>/service/<path:service_uuid>/connections'),
('api.connection_ids', ConnectionIds, '/context/<path:context_uuid>/service/<path:service_uuid>/connection_ids'),
('api.connections', Connections, '/context/<path:context_uuid>/service/<path:service_uuid>/connections'),
('api.connection', Connection, '/connection/<path:connection_uuid>'),
('api.policyrule_ids', PolicyRuleIds, '/policyrule_ids'),
('api.policyrules', PolicyRules, '/policyrules'),
('api.policyrule', PolicyRule, '/policyrule/<string:policyrule_uuid>'),
('api.policyrule', PolicyRule, '/policyrule/<path:policyrule_uuid>'),
]
def register_debug_api(rest_server : RestServer):
......
......@@ -21,7 +21,7 @@ from .L2VPN_Services import L2VPN_Services
from .L2VPN_Service import L2VPN_Service
from .L2VPN_SiteNetworkAccesses import L2VPN_SiteNetworkAccesses
URL_PREFIX = '/ietf-l2vpn-svc:l2vpn-svc'
URL_PREFIX = '/data/ietf-l2vpn-svc:l2vpn-svc'
def _add_resource(rest_server : RestServer, resource : Resource, *urls, **kwargs):
urls = [(URL_PREFIX + url) for url in urls]
......
This diff is collapsed.
syntax = "proto3";
// Package gnmi_ext defines a set of extensions messages which can be optionally
// included with the request and response messages of gNMI RPCs. A set of
// well-known extensions are defined within this file, along with a registry for
// extensions defined outside of this package.
package gnmi_ext;
option go_package = "github.com/openconfig/gnmi/proto/gnmi_ext";
// The Extension message contains a single gNMI extension.
message Extension {
oneof ext {
RegisteredExtension registered_ext = 1; // A registered extension.
// Well known extensions.
MasterArbitration master_arbitration = 2; // Master arbitration extension.
History history = 3; // History extension.
}
}
// The RegisteredExtension message defines an extension which is defined outside
// of this file.
message RegisteredExtension {
ExtensionID id = 1; // The unique ID assigned to this extension.
bytes msg = 2; // The binary-marshalled protobuf extension payload.
}
// RegisteredExtension is an enumeration acting as a registry for extensions
// defined by external sources.
enum ExtensionID {
EID_UNSET = 0;
// New extensions are to be defined within this enumeration - their definition
// MUST link to a reference describing their implementation.
// An experimental extension that may be used during prototyping of a new
// extension.
EID_EXPERIMENTAL = 999;
}
// MasterArbitration is used to select the master among multiple gNMI clients
// with the same Roles. The client with the largest election_id is honored as
// the master.
// The document about gNMI master arbitration can be found at
// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-master-arbitration.md
message MasterArbitration {
Role role = 1;
Uint128 election_id = 2;
}
// Representation of unsigned 128-bit integer.
message Uint128 {
uint64 high = 1;
uint64 low = 2;
}
// There can be one master for each role. The role is identified by its id.
message Role {
string id = 1;
// More fields can be added if needed, for example, to specify what paths the
// role can read/write.
}
// The History extension allows clients to request historical data. Its
// spec can be found at
// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-history.md
message History {
oneof request {
int64 snapshot_time = 1; // Nanoseconds since the epoch
TimeRange range = 2;
}
}
message TimeRange {
int64 start = 1; // Nanoseconds since the epoch
int64 end = 2; // Nanoseconds since the epoch
}
\ No newline at end of file
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: gnmi.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ngnmi.proto\x12\x04gnmi\x1a\x19google/protobuf/any.proto\x1a google/protobuf/descriptor.proto\"\xa0\x01\n\tExtension\x12\x33\n\x0eregistered_ext\x18\x01 \x01(\x0b\x32\x19.gnmi.RegisteredExtensionH\x00\x12\x35\n\x12master_arbitration\x18\x02 \x01(\x0b\x32\x17.gnmi.MasterArbitrationH\x00\x12 \n\x07history\x18\x03 \x01(\x0b\x32\r.gnmi.HistoryH\x00\x42\x05\n\x03\x65xt\"A\n\x13RegisteredExtension\x12\x1d\n\x02id\x18\x01 \x01(\x0e\x32\x11.gnmi.ExtensionID\x12\x0b\n\x03msg\x18\x02 \x01(\x0c\"Q\n\x11MasterArbitration\x12\x18\n\x04role\x18\x01 \x01(\x0b\x32\n.gnmi.Role\x12\"\n\x0b\x65lection_id\x18\x02 \x01(\x0b\x32\r.gnmi.Uint128\"$\n\x07Uint128\x12\x0c\n\x04high\x18\x01 \x01(\x04\x12\x0b\n\x03low\x18\x02 \x01(\x04\"\x12\n\x04Role\x12\n\n\x02id\x18\x01 \x01(\t\"O\n\x07History\x12\x17\n\rsnapshot_time\x18\x01 \x01(\x03H\x00\x12 \n\x05range\x18\x02 \x01(\x0b\x32\x0f.gnmi.TimeRangeH\x00\x42\t\n\x07request\"\'\n\tTimeRange\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\"\x94\x01\n\x0cNotification\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12\x1a\n\x06prefix\x18\x02 \x01(\x0b\x32\n.gnmi.Path\x12\x1c\n\x06update\x18\x04 \x03(\x0b\x32\x0c.gnmi.Update\x12\x1a\n\x06\x64\x65lete\x18\x05 \x03(\x0b\x32\n.gnmi.Path\x12\x0e\n\x06\x61tomic\x18\x06 \x01(\x08J\x04\x08\x03\x10\x04R\x05\x61lias\"u\n\x06Update\x12\x18\n\x04path\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0b.gnmi.ValueB\x02\x18\x01\x12\x1d\n\x03val\x18\x03 \x01(\x0b\x32\x10.gnmi.TypedValue\x12\x12\n\nduplicates\x18\x04 \x01(\r\"\x83\x03\n\nTypedValue\x12\x14\n\nstring_val\x18\x01 \x01(\tH\x00\x12\x11\n\x07int_val\x18\x02 \x01(\x03H\x00\x12\x12\n\x08uint_val\x18\x03 \x01(\x04H\x00\x12\x12\n\x08\x62ool_val\x18\x04 \x01(\x08H\x00\x12\x13\n\tbytes_val\x18\x05 \x01(\x0cH\x00\x12\x17\n\tfloat_val\x18\x06 \x01(\x02\x42\x02\x18\x01H\x00\x12\x14\n\ndouble_val\x18\x0e \x01(\x01H\x00\x12*\n\x0b\x64\x65\x63imal_val\x18\x07 \x01(\x0b\x32\x0f.gnmi.Decimal64B\x02\x18\x01H\x00\x12)\n\x0cleaflist_val\x18\x08 \x01(\x0b\x32\x11.gnmi.ScalarArrayH\x00\x12\'\n\x07\x61ny_val\x18\t \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x12\x12\n\x08json_val\x18\n \x01(\x0cH\x00\x12\x17\n\rjson_ietf_val\x18\x0b \x01(\x0cH\x00\x12\x13\n\tascii_val\x18\x0c \x01(\tH\x00\x12\x15\n\x0bproto_bytes\x18\r \x01(\x0cH\x00\x42\x07\n\x05value\"Y\n\x04Path\x12\x13\n\x07\x65lement\x18\x01 \x03(\tB\x02\x18\x01\x12\x0e\n\x06origin\x18\x02 \x01(\t\x12\x1c\n\x04\x65lem\x18\x03 \x03(\x0b\x32\x0e.gnmi.PathElem\x12\x0e\n\x06target\x18\x04 \x01(\t\"j\n\x08PathElem\x12\x0c\n\x04name\x18\x01 \x01(\t\x12$\n\x03key\x18\x02 \x03(\x0b\x32\x17.gnmi.PathElem.KeyEntry\x1a*\n\x08KeyEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"8\n\x05Value\x12\r\n\x05value\x18\x01 \x01(\x0c\x12\x1c\n\x04type\x18\x02 \x01(\x0e\x32\x0e.gnmi.Encoding:\x02\x18\x01\"N\n\x05\x45rror\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\"\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any:\x02\x18\x01\"2\n\tDecimal64\x12\x0e\n\x06\x64igits\x18\x01 \x01(\x03\x12\x11\n\tprecision\x18\x02 \x01(\r:\x02\x18\x01\"0\n\x0bScalarArray\x12!\n\x07\x65lement\x18\x01 \x03(\x0b\x32\x10.gnmi.TypedValue\"\x99\x01\n\x10SubscribeRequest\x12+\n\tsubscribe\x18\x01 \x01(\x0b\x32\x16.gnmi.SubscriptionListH\x00\x12\x1a\n\x04poll\x18\x03 \x01(\x0b\x32\n.gnmi.PollH\x00\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.ExtensionB\t\n\x07requestJ\x04\x08\x04\x10\x05R\x07\x61liases\"\x06\n\x04Poll\"\xa4\x01\n\x11SubscribeResponse\x12$\n\x06update\x18\x01 \x01(\x0b\x32\x12.gnmi.NotificationH\x00\x12\x17\n\rsync_response\x18\x03 \x01(\x08H\x00\x12 \n\x05\x65rror\x18\x04 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01H\x00\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.ExtensionB\n\n\x08response\"\xd5\x02\n\x10SubscriptionList\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12(\n\x0csubscription\x18\x02 \x03(\x0b\x32\x12.gnmi.Subscription\x12\x1d\n\x03qos\x18\x04 \x01(\x0b\x32\x10.gnmi.QOSMarking\x12)\n\x04mode\x18\x05 \x01(\x0e\x32\x1b.gnmi.SubscriptionList.Mode\x12\x19\n\x11\x61llow_aggregation\x18\x06 \x01(\x08\x12#\n\nuse_models\x18\x07 \x03(\x0b\x32\x0f.gnmi.ModelData\x12 \n\x08\x65ncoding\x18\x08 \x01(\x0e\x32\x0e.gnmi.Encoding\x12\x14\n\x0cupdates_only\x18\t \x01(\x08\"&\n\x04Mode\x12\n\n\x06STREAM\x10\x00\x12\x08\n\x04ONCE\x10\x01\x12\x08\n\x04POLL\x10\x02J\x04\x08\x03\x10\x04R\x0buse_aliases\"\x9f\x01\n\x0cSubscription\x12\x18\n\x04path\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12$\n\x04mode\x18\x02 \x01(\x0e\x32\x16.gnmi.SubscriptionMode\x12\x17\n\x0fsample_interval\x18\x03 \x01(\x04\x12\x1a\n\x12suppress_redundant\x18\x04 \x01(\x08\x12\x1a\n\x12heartbeat_interval\x18\x05 \x01(\x04\"\x1d\n\nQOSMarking\x12\x0f\n\x07marking\x18\x01 \x01(\r\"\xa5\x01\n\nSetRequest\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x1a\n\x06\x64\x65lete\x18\x02 \x03(\x0b\x32\n.gnmi.Path\x12\x1d\n\x07replace\x18\x03 \x03(\x0b\x32\x0c.gnmi.Update\x12\x1c\n\x06update\x18\x04 \x03(\x0b\x32\x0c.gnmi.Update\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.Extension\"\xa8\x01\n\x0bSetResponse\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12$\n\x08response\x18\x02 \x03(\x0b\x32\x12.gnmi.UpdateResult\x12 \n\x07message\x18\x03 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12\x11\n\ttimestamp\x18\x04 \x01(\x03\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.Extension\"\xca\x01\n\x0cUpdateResult\x12\x15\n\ttimestamp\x18\x01 \x01(\x03\x42\x02\x18\x01\x12\x18\n\x04path\x18\x02 \x01(\x0b\x32\n.gnmi.Path\x12 \n\x07message\x18\x03 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12(\n\x02op\x18\x04 \x01(\x0e\x32\x1c.gnmi.UpdateResult.Operation\"=\n\tOperation\x12\x0b\n\x07INVALID\x10\x00\x12\n\n\x06\x44\x45LETE\x10\x01\x12\x0b\n\x07REPLACE\x10\x02\x12\n\n\x06UPDATE\x10\x03\"\x93\x02\n\nGetRequest\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x18\n\x04path\x18\x02 \x03(\x0b\x32\n.gnmi.Path\x12\'\n\x04type\x18\x03 \x01(\x0e\x32\x19.gnmi.GetRequest.DataType\x12 \n\x08\x65ncoding\x18\x05 \x01(\x0e\x32\x0e.gnmi.Encoding\x12#\n\nuse_models\x18\x06 \x03(\x0b\x32\x0f.gnmi.ModelData\x12\"\n\textension\x18\x07 \x03(\x0b\x32\x0f.gnmi.Extension\";\n\x08\x44\x61taType\x12\x07\n\x03\x41LL\x10\x00\x12\n\n\x06\x43ONFIG\x10\x01\x12\t\n\x05STATE\x10\x02\x12\x0f\n\x0bOPERATIONAL\x10\x03\"{\n\x0bGetResponse\x12(\n\x0cnotification\x18\x01 \x03(\x0b\x32\x12.gnmi.Notification\x12\x1e\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12\"\n\textension\x18\x03 \x03(\x0b\x32\x0f.gnmi.Extension\"7\n\x11\x43\x61pabilityRequest\x12\"\n\textension\x18\x01 \x03(\x0b\x32\x0f.gnmi.Extension\"\xa6\x01\n\x12\x43\x61pabilityResponse\x12)\n\x10supported_models\x18\x01 \x03(\x0b\x32\x0f.gnmi.ModelData\x12+\n\x13supported_encodings\x18\x02 \x03(\x0e\x32\x0e.gnmi.Encoding\x12\x14\n\x0cgNMI_version\x18\x03 \x01(\t\x12\"\n\textension\x18\x04 \x03(\x0b\x32\x0f.gnmi.Extension\"@\n\tModelData\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\x0corganization\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t*3\n\x0b\x45xtensionID\x12\r\n\tEID_UNSET\x10\x00\x12\x15\n\x10\x45ID_EXPERIMENTAL\x10\xe7\x07*D\n\x08\x45ncoding\x12\x08\n\x04JSON\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\t\n\x05\x41SCII\x10\x03\x12\r\n\tJSON_IETF\x10\x04*A\n\x10SubscriptionMode\x12\x12\n\x0eTARGET_DEFINED\x10\x00\x12\r\n\tON_CHANGE\x10\x01\x12\n\n\x06SAMPLE\x10\x02\x32\xe3\x01\n\x04gNMI\x12\x41\n\x0c\x43\x61pabilities\x12\x17.gnmi.CapabilityRequest\x1a\x18.gnmi.CapabilityResponse\x12*\n\x03Get\x12\x10.gnmi.GetRequest\x1a\x11.gnmi.GetResponse\x12*\n\x03Set\x12\x10.gnmi.SetRequest\x1a\x11.gnmi.SetResponse\x12@\n\tSubscribe\x12\x16.gnmi.SubscribeRequest\x1a\x17.gnmi.SubscribeResponse(\x01\x30\x01:3\n\x0cgnmi_service\x12\x1c.google.protobuf.FileOptions\x18\xe9\x07 \x01(\tBS\n\x15\x63om.github.gnmi.protoB\tGnmiProtoP\x01Z%github.com/openconfig/gnmi/proto/gnmi\xca>\x05\x30.8.0b\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'gnmi_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(gnmi_service)
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\025com.github.gnmi.protoB\tGnmiProtoP\001Z%github.com/openconfig/gnmi/proto/gnmi\312>\0050.8.0'
_UPDATE.fields_by_name['value']._options = None
_UPDATE.fields_by_name['value']._serialized_options = b'\030\001'
_TYPEDVALUE.fields_by_name['float_val']._options = None
_TYPEDVALUE.fields_by_name['float_val']._serialized_options = b'\030\001'
_TYPEDVALUE.fields_by_name['decimal_val']._options = None
_TYPEDVALUE.fields_by_name['decimal_val']._serialized_options = b'\030\001'
_PATH.fields_by_name['element']._options = None
_PATH.fields_by_name['element']._serialized_options = b'\030\001'
_PATHELEM_KEYENTRY._options = None
_PATHELEM_KEYENTRY._serialized_options = b'8\001'
_VALUE._options = None
_VALUE._serialized_options = b'\030\001'
_ERROR._options = None
_ERROR._serialized_options = b'\030\001'
_DECIMAL64._options = None
_DECIMAL64._serialized_options = b'\030\001'
_SUBSCRIBERESPONSE.fields_by_name['error']._options = None
_SUBSCRIBERESPONSE.fields_by_name['error']._serialized_options = b'\030\001'
_SETRESPONSE.fields_by_name['message']._options = None
_SETRESPONSE.fields_by_name['message']._serialized_options = b'\030\001'
_UPDATERESULT.fields_by_name['timestamp']._options = None
_UPDATERESULT.fields_by_name['timestamp']._serialized_options = b'\030\001'
_UPDATERESULT.fields_by_name['message']._options = None
_UPDATERESULT.fields_by_name['message']._serialized_options = b'\030\001'
_GETRESPONSE.fields_by_name['error']._options = None
_GETRESPONSE.fields_by_name['error']._serialized_options = b'\030\001'
_EXTENSIONID._serialized_start=3780
_EXTENSIONID._serialized_end=3831
_ENCODING._serialized_start=3833
_ENCODING._serialized_end=3901
_SUBSCRIPTIONMODE._serialized_start=3903
_SUBSCRIPTIONMODE._serialized_end=3968
_EXTENSION._serialized_start=82
_EXTENSION._serialized_end=242
_REGISTEREDEXTENSION._serialized_start=244
_REGISTEREDEXTENSION._serialized_end=309
_MASTERARBITRATION._serialized_start=311
_MASTERARBITRATION._serialized_end=392
_UINT128._serialized_start=394
_UINT128._serialized_end=430
_ROLE._serialized_start=432
_ROLE._serialized_end=450
_HISTORY._serialized_start=452
_HISTORY._serialized_end=531
_TIMERANGE._serialized_start=533
_TIMERANGE._serialized_end=572
_NOTIFICATION._serialized_start=575
_NOTIFICATION._serialized_end=723
_UPDATE._serialized_start=725
_UPDATE._serialized_end=842
_TYPEDVALUE._serialized_start=845
_TYPEDVALUE._serialized_end=1232
_PATH._serialized_start=1234
_PATH._serialized_end=1323
_PATHELEM._serialized_start=1325
_PATHELEM._serialized_end=1431
_PATHELEM_KEYENTRY._serialized_start=1389
_PATHELEM_KEYENTRY._serialized_end=1431
_VALUE._serialized_start=1433
_VALUE._serialized_end=1489
_ERROR._serialized_start=1491
_ERROR._serialized_end=1569
_DECIMAL64._serialized_start=1571
_DECIMAL64._serialized_end=1621
_SCALARARRAY._serialized_start=1623
_SCALARARRAY._serialized_end=1671
_SUBSCRIBEREQUEST._serialized_start=1674
_SUBSCRIBEREQUEST._serialized_end=1827
_POLL._serialized_start=1829
_POLL._serialized_end=1835
_SUBSCRIBERESPONSE._serialized_start=1838
_SUBSCRIBERESPONSE._serialized_end=2002
_SUBSCRIPTIONLIST._serialized_start=2005
_SUBSCRIPTIONLIST._serialized_end=2346
_SUBSCRIPTIONLIST_MODE._serialized_start=2289
_SUBSCRIPTIONLIST_MODE._serialized_end=2327
_SUBSCRIPTION._serialized_start=2349
_SUBSCRIPTION._serialized_end=2508
_QOSMARKING._serialized_start=2510
_QOSMARKING._serialized_end=2539
_SETREQUEST._serialized_start=2542
_SETREQUEST._serialized_end=2707
_SETRESPONSE._serialized_start=2710
_SETRESPONSE._serialized_end=2878
_UPDATERESULT._serialized_start=2881
_UPDATERESULT._serialized_end=3083
_UPDATERESULT_OPERATION._serialized_start=3022
_UPDATERESULT_OPERATION._serialized_end=3083
_GETREQUEST._serialized_start=3086
_GETREQUEST._serialized_end=3361
_GETREQUEST_DATATYPE._serialized_start=3302
_GETREQUEST_DATATYPE._serialized_end=3361
_GETRESPONSE._serialized_start=3363
_GETRESPONSE._serialized_end=3486
_CAPABILITYREQUEST._serialized_start=3488
_CAPABILITYREQUEST._serialized_end=3543
_CAPABILITYRESPONSE._serialized_start=3546
_CAPABILITYRESPONSE._serialized_end=3712
_MODELDATA._serialized_start=3714
_MODELDATA._serialized_end=3778
_GNMI._serialized_start=3971
_GNMI._serialized_end=4198
# @@protoc_insertion_point(module_scope)
This diff is collapsed.
from google.protobuf import any_pb2 as _any_pb2
from google.protobuf import descriptor_pb2 as _descriptor_pb2
from google.protobuf.internal import containers as _containers
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
ASCII: Encoding
BYTES: Encoding
DESCRIPTOR: _descriptor.FileDescriptor
EID_EXPERIMENTAL: ExtensionID
EID_UNSET: ExtensionID
GNMI_SERVICE_FIELD_NUMBER: _ClassVar[int]
JSON: Encoding
JSON_IETF: Encoding
ON_CHANGE: SubscriptionMode
PROTO: Encoding
SAMPLE: SubscriptionMode
TARGET_DEFINED: SubscriptionMode
gnmi_service: _descriptor.FieldDescriptor
class CapabilityRequest(_message.Message):
__slots__ = ["extension"]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
extension: _containers.RepeatedCompositeFieldContainer[Extension]
def __init__(self, extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class CapabilityResponse(_message.Message):
__slots__ = ["extension", "gNMI_version", "supported_encodings", "supported_models"]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
GNMI_VERSION_FIELD_NUMBER: _ClassVar[int]
SUPPORTED_ENCODINGS_FIELD_NUMBER: _ClassVar[int]
SUPPORTED_MODELS_FIELD_NUMBER: _ClassVar[int]
extension: _containers.RepeatedCompositeFieldContainer[Extension]
gNMI_version: str
supported_encodings: _containers.RepeatedScalarFieldContainer[Encoding]
supported_models: _containers.RepeatedCompositeFieldContainer[ModelData]
def __init__(self, supported_models: _Optional[_Iterable[_Union[ModelData, _Mapping]]] = ..., supported_encodings: _Optional[_Iterable[_Union[Encoding, str]]] = ..., gNMI_version: _Optional[str] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class Decimal64(_message.Message):
__slots__ = ["digits", "precision"]
DIGITS_FIELD_NUMBER: _ClassVar[int]
PRECISION_FIELD_NUMBER: _ClassVar[int]
digits: int
precision: int
def __init__(self, digits: _Optional[int] = ..., precision: _Optional[int] = ...) -> None: ...
class Error(_message.Message):
__slots__ = ["code", "data", "message"]
CODE_FIELD_NUMBER: _ClassVar[int]
DATA_FIELD_NUMBER: _ClassVar[int]
MESSAGE_FIELD_NUMBER: _ClassVar[int]
code: int
data: _any_pb2.Any
message: str
def __init__(self, code: _Optional[int] = ..., message: _Optional[str] = ..., data: _Optional[_Union[_any_pb2.Any, _Mapping]] = ...) -> None: ...
class Extension(_message.Message):
__slots__ = ["history", "master_arbitration", "registered_ext"]
HISTORY_FIELD_NUMBER: _ClassVar[int]
MASTER_ARBITRATION_FIELD_NUMBER: _ClassVar[int]
REGISTERED_EXT_FIELD_NUMBER: _ClassVar[int]
history: History
master_arbitration: MasterArbitration
registered_ext: RegisteredExtension
def __init__(self, registered_ext: _Optional[_Union[RegisteredExtension, _Mapping]] = ..., master_arbitration: _Optional[_Union[MasterArbitration, _Mapping]] = ..., history: _Optional[_Union[History, _Mapping]] = ...) -> None: ...
class GetRequest(_message.Message):
__slots__ = ["encoding", "extension", "path", "prefix", "type", "use_models"]
class DataType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = []
ALL: GetRequest.DataType
CONFIG: GetRequest.DataType
ENCODING_FIELD_NUMBER: _ClassVar[int]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
OPERATIONAL: GetRequest.DataType
PATH_FIELD_NUMBER: _ClassVar[int]
PREFIX_FIELD_NUMBER: _ClassVar[int]
STATE: GetRequest.DataType
TYPE_FIELD_NUMBER: _ClassVar[int]
USE_MODELS_FIELD_NUMBER: _ClassVar[int]
encoding: Encoding
extension: _containers.RepeatedCompositeFieldContainer[Extension]
path: _containers.RepeatedCompositeFieldContainer[Path]
prefix: Path
type: GetRequest.DataType
use_models: _containers.RepeatedCompositeFieldContainer[ModelData]
def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., path: _Optional[_Iterable[_Union[Path, _Mapping]]] = ..., type: _Optional[_Union[GetRequest.DataType, str]] = ..., encoding: _Optional[_Union[Encoding, str]] = ..., use_models: _Optional[_Iterable[_Union[ModelData, _Mapping]]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class GetResponse(_message.Message):
__slots__ = ["error", "extension", "notification"]
ERROR_FIELD_NUMBER: _ClassVar[int]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
NOTIFICATION_FIELD_NUMBER: _ClassVar[int]
error: Error
extension: _containers.RepeatedCompositeFieldContainer[Extension]
notification: _containers.RepeatedCompositeFieldContainer[Notification]
def __init__(self, notification: _Optional[_Iterable[_Union[Notification, _Mapping]]] = ..., error: _Optional[_Union[Error, _Mapping]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class History(_message.Message):
__slots__ = ["range", "snapshot_time"]
RANGE_FIELD_NUMBER: _ClassVar[int]
SNAPSHOT_TIME_FIELD_NUMBER: _ClassVar[int]
range: TimeRange
snapshot_time: int
def __init__(self, snapshot_time: _Optional[int] = ..., range: _Optional[_Union[TimeRange, _Mapping]] = ...) -> None: ...
class MasterArbitration(_message.Message):
__slots__ = ["election_id", "role"]
ELECTION_ID_FIELD_NUMBER: _ClassVar[int]
ROLE_FIELD_NUMBER: _ClassVar[int]
election_id: Uint128
role: Role
def __init__(self, role: _Optional[_Union[Role, _Mapping]] = ..., election_id: _Optional[_Union[Uint128, _Mapping]] = ...) -> None: ...
class ModelData(_message.Message):
__slots__ = ["name", "organization", "version"]
NAME_FIELD_NUMBER: _ClassVar[int]
ORGANIZATION_FIELD_NUMBER: _ClassVar[int]
VERSION_FIELD_NUMBER: _ClassVar[int]
name: str
organization: str
version: str
def __init__(self, name: _Optional[str] = ..., organization: _Optional[str] = ..., version: _Optional[str] = ...) -> None: ...
class Notification(_message.Message):
__slots__ = ["atomic", "delete", "prefix", "timestamp", "update"]
ATOMIC_FIELD_NUMBER: _ClassVar[int]
DELETE_FIELD_NUMBER: _ClassVar[int]
PREFIX_FIELD_NUMBER: _ClassVar[int]
TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
UPDATE_FIELD_NUMBER: _ClassVar[int]
atomic: bool
delete: _containers.RepeatedCompositeFieldContainer[Path]
prefix: Path
timestamp: int
update: _containers.RepeatedCompositeFieldContainer[Update]
def __init__(self, timestamp: _Optional[int] = ..., prefix: _Optional[_Union[Path, _Mapping]] = ..., update: _Optional[_Iterable[_Union[Update, _Mapping]]] = ..., delete: _Optional[_Iterable[_Union[Path, _Mapping]]] = ..., atomic: bool = ...) -> None: ...
class Path(_message.Message):
__slots__ = ["elem", "element", "origin", "target"]
ELEMENT_FIELD_NUMBER: _ClassVar[int]
ELEM_FIELD_NUMBER: _ClassVar[int]
ORIGIN_FIELD_NUMBER: _ClassVar[int]
TARGET_FIELD_NUMBER: _ClassVar[int]
elem: _containers.RepeatedCompositeFieldContainer[PathElem]
element: _containers.RepeatedScalarFieldContainer[str]
origin: str
target: str
def __init__(self, element: _Optional[_Iterable[str]] = ..., origin: _Optional[str] = ..., elem: _Optional[_Iterable[_Union[PathElem, _Mapping]]] = ..., target: _Optional[str] = ...) -> None: ...
class PathElem(_message.Message):
__slots__ = ["key", "name"]
class KeyEntry(_message.Message):
__slots__ = ["key", "value"]
KEY_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
key: str
value: str
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
KEY_FIELD_NUMBER: _ClassVar[int]
NAME_FIELD_NUMBER: _ClassVar[int]
key: _containers.ScalarMap[str, str]
name: str
def __init__(self, name: _Optional[str] = ..., key: _Optional[_Mapping[str, str]] = ...) -> None: ...
class Poll(_message.Message):
__slots__ = []
def __init__(self) -> None: ...
class QOSMarking(_message.Message):
__slots__ = ["marking"]
MARKING_FIELD_NUMBER: _ClassVar[int]
marking: int
def __init__(self, marking: _Optional[int] = ...) -> None: ...
class RegisteredExtension(_message.Message):
__slots__ = ["id", "msg"]
ID_FIELD_NUMBER: _ClassVar[int]
MSG_FIELD_NUMBER: _ClassVar[int]
id: ExtensionID
msg: bytes
def __init__(self, id: _Optional[_Union[ExtensionID, str]] = ..., msg: _Optional[bytes] = ...) -> None: ...
class Role(_message.Message):
__slots__ = ["id"]
ID_FIELD_NUMBER: _ClassVar[int]
id: str
def __init__(self, id: _Optional[str] = ...) -> None: ...
class ScalarArray(_message.Message):
__slots__ = ["element"]
ELEMENT_FIELD_NUMBER: _ClassVar[int]
element: _containers.RepeatedCompositeFieldContainer[TypedValue]
def __init__(self, element: _Optional[_Iterable[_Union[TypedValue, _Mapping]]] = ...) -> None: ...
class SetRequest(_message.Message):
__slots__ = ["delete", "extension", "prefix", "replace", "update"]
DELETE_FIELD_NUMBER: _ClassVar[int]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
PREFIX_FIELD_NUMBER: _ClassVar[int]
REPLACE_FIELD_NUMBER: _ClassVar[int]
UPDATE_FIELD_NUMBER: _ClassVar[int]
delete: _containers.RepeatedCompositeFieldContainer[Path]
extension: _containers.RepeatedCompositeFieldContainer[Extension]
prefix: Path
replace: _containers.RepeatedCompositeFieldContainer[Update]
update: _containers.RepeatedCompositeFieldContainer[Update]
def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., delete: _Optional[_Iterable[_Union[Path, _Mapping]]] = ..., replace: _Optional[_Iterable[_Union[Update, _Mapping]]] = ..., update: _Optional[_Iterable[_Union[Update, _Mapping]]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class SetResponse(_message.Message):
__slots__ = ["extension", "message", "prefix", "response", "timestamp"]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
MESSAGE_FIELD_NUMBER: _ClassVar[int]
PREFIX_FIELD_NUMBER: _ClassVar[int]
RESPONSE_FIELD_NUMBER: _ClassVar[int]
TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
extension: _containers.RepeatedCompositeFieldContainer[Extension]
message: Error
prefix: Path
response: _containers.RepeatedCompositeFieldContainer[UpdateResult]
timestamp: int
def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., response: _Optional[_Iterable[_Union[UpdateResult, _Mapping]]] = ..., message: _Optional[_Union[Error, _Mapping]] = ..., timestamp: _Optional[int] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class SubscribeRequest(_message.Message):
__slots__ = ["extension", "poll", "subscribe"]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
POLL_FIELD_NUMBER: _ClassVar[int]
SUBSCRIBE_FIELD_NUMBER: _ClassVar[int]
extension: _containers.RepeatedCompositeFieldContainer[Extension]
poll: Poll
subscribe: SubscriptionList
def __init__(self, subscribe: _Optional[_Union[SubscriptionList, _Mapping]] = ..., poll: _Optional[_Union[Poll, _Mapping]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class SubscribeResponse(_message.Message):
__slots__ = ["error", "extension", "sync_response", "update"]
ERROR_FIELD_NUMBER: _ClassVar[int]
EXTENSION_FIELD_NUMBER: _ClassVar[int]
SYNC_RESPONSE_FIELD_NUMBER: _ClassVar[int]
UPDATE_FIELD_NUMBER: _ClassVar[int]
error: Error
extension: _containers.RepeatedCompositeFieldContainer[Extension]
sync_response: bool
update: Notification
def __init__(self, update: _Optional[_Union[Notification, _Mapping]] = ..., sync_response: bool = ..., error: _Optional[_Union[Error, _Mapping]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
class Subscription(_message.Message):
__slots__ = ["heartbeat_interval", "mode", "path", "sample_interval", "suppress_redundant"]
HEARTBEAT_INTERVAL_FIELD_NUMBER: _ClassVar[int]
MODE_FIELD_NUMBER: _ClassVar[int]
PATH_FIELD_NUMBER: _ClassVar[int]
SAMPLE_INTERVAL_FIELD_NUMBER: _ClassVar[int]
SUPPRESS_REDUNDANT_FIELD_NUMBER: _ClassVar[int]
heartbeat_interval: int
mode: SubscriptionMode
path: Path
sample_interval: int
suppress_redundant: bool
def __init__(self, path: _Optional[_Union[Path, _Mapping]] = ..., mode: _Optional[_Union[SubscriptionMode, str]] = ..., sample_interval: _Optional[int] = ..., suppress_redundant: bool = ..., heartbeat_interval: _Optional[int] = ...) -> None: ...
class SubscriptionList(_message.Message):
__slots__ = ["allow_aggregation", "encoding", "mode", "prefix", "qos", "subscription", "updates_only", "use_models"]
class Mode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = []
ALLOW_AGGREGATION_FIELD_NUMBER: _ClassVar[int]
ENCODING_FIELD_NUMBER: _ClassVar[int]
MODE_FIELD_NUMBER: _ClassVar[int]
ONCE: SubscriptionList.Mode
POLL: SubscriptionList.Mode
PREFIX_FIELD_NUMBER: _ClassVar[int]
QOS_FIELD_NUMBER: _ClassVar[int]
STREAM: SubscriptionList.Mode
SUBSCRIPTION_FIELD_NUMBER: _ClassVar[int]
UPDATES_ONLY_FIELD_NUMBER: _ClassVar[int]
USE_MODELS_FIELD_NUMBER: _ClassVar[int]
allow_aggregation: bool
encoding: Encoding
mode: SubscriptionList.Mode
prefix: Path
qos: QOSMarking
subscription: _containers.RepeatedCompositeFieldContainer[Subscription]
updates_only: bool
use_models: _containers.RepeatedCompositeFieldContainer[ModelData]
def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., subscription: _Optional[_Iterable[_Union[Subscription, _Mapping]]] = ..., qos: _Optional[_Union[QOSMarking, _Mapping]] = ..., mode: _Optional[_Union[SubscriptionList.Mode, str]] = ..., allow_aggregation: bool = ..., use_models: _Optional[_Iterable[_Union[ModelData, _Mapping]]] = ..., encoding: _Optional[_Union[Encoding, str]] = ..., updates_only: bool = ...) -> None: ...
class TimeRange(_message.Message):
__slots__ = ["end", "start"]
END_FIELD_NUMBER: _ClassVar[int]
START_FIELD_NUMBER: _ClassVar[int]
end: int
start: int
def __init__(self, start: _Optional[int] = ..., end: _Optional[int] = ...) -> None: ...
class TypedValue(_message.Message):
__slots__ = ["any_val", "ascii_val", "bool_val", "bytes_val", "decimal_val", "double_val", "float_val", "int_val", "json_ietf_val", "json_val", "leaflist_val", "proto_bytes", "string_val", "uint_val"]
ANY_VAL_FIELD_NUMBER: _ClassVar[int]
ASCII_VAL_FIELD_NUMBER: _ClassVar[int]
BOOL_VAL_FIELD_NUMBER: _ClassVar[int]
BYTES_VAL_FIELD_NUMBER: _ClassVar[int]
DECIMAL_VAL_FIELD_NUMBER: _ClassVar[int]
DOUBLE_VAL_FIELD_NUMBER: _ClassVar[int]
FLOAT_VAL_FIELD_NUMBER: _ClassVar[int]
INT_VAL_FIELD_NUMBER: _ClassVar[int]
JSON_IETF_VAL_FIELD_NUMBER: _ClassVar[int]
JSON_VAL_FIELD_NUMBER: _ClassVar[int]
LEAFLIST_VAL_FIELD_NUMBER: _ClassVar[int]
PROTO_BYTES_FIELD_NUMBER: _ClassVar[int]
STRING_VAL_FIELD_NUMBER: _ClassVar[int]
UINT_VAL_FIELD_NUMBER: _ClassVar[int]
any_val: _any_pb2.Any
ascii_val: str
bool_val: bool
bytes_val: bytes
decimal_val: Decimal64
double_val: float
float_val: float
int_val: int
json_ietf_val: bytes
json_val: bytes
leaflist_val: ScalarArray
proto_bytes: bytes
string_val: str
uint_val: int
def __init__(self, string_val: _Optional[str] = ..., int_val: _Optional[int] = ..., uint_val: _Optional[int] = ..., bool_val: bool = ..., bytes_val: _Optional[bytes] = ..., float_val: _Optional[float] = ..., double_val: _Optional[float] = ..., decimal_val: _Optional[_Union[Decimal64, _Mapping]] = ..., leaflist_val: _Optional[_Union[ScalarArray, _Mapping]] = ..., any_val: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., json_val: _Optional[bytes] = ..., json_ietf_val: _Optional[bytes] = ..., ascii_val: _Optional[str] = ..., proto_bytes: _Optional[bytes] = ...) -> None: ...
class Uint128(_message.Message):
__slots__ = ["high", "low"]
HIGH_FIELD_NUMBER: _ClassVar[int]
LOW_FIELD_NUMBER: _ClassVar[int]
high: int
low: int
def __init__(self, high: _Optional[int] = ..., low: _Optional[int] = ...) -> None: ...
class Update(_message.Message):
__slots__ = ["duplicates", "path", "val", "value"]
DUPLICATES_FIELD_NUMBER: _ClassVar[int]
PATH_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
VAL_FIELD_NUMBER: _ClassVar[int]
duplicates: int
path: Path
val: TypedValue
value: Value
def __init__(self, path: _Optional[_Union[Path, _Mapping]] = ..., value: _Optional[_Union[Value, _Mapping]] = ..., val: _Optional[_Union[TypedValue, _Mapping]] = ..., duplicates: _Optional[int] = ...) -> None: ...
class UpdateResult(_message.Message):
__slots__ = ["message", "op", "path", "timestamp"]
class Operation(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = []
DELETE: UpdateResult.Operation
INVALID: UpdateResult.Operation
MESSAGE_FIELD_NUMBER: _ClassVar[int]
OP_FIELD_NUMBER: _ClassVar[int]
PATH_FIELD_NUMBER: _ClassVar[int]
REPLACE: UpdateResult.Operation
TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
UPDATE: UpdateResult.Operation
message: Error
op: UpdateResult.Operation
path: Path
timestamp: int
def __init__(self, timestamp: _Optional[int] = ..., path: _Optional[_Union[Path, _Mapping]] = ..., message: _Optional[_Union[Error, _Mapping]] = ..., op: _Optional[_Union[UpdateResult.Operation, str]] = ...) -> None: ...
class Value(_message.Message):
__slots__ = ["type", "value"]
TYPE_FIELD_NUMBER: _ClassVar[int]
VALUE_FIELD_NUMBER: _ClassVar[int]
type: Encoding
value: bytes
def __init__(self, value: _Optional[bytes] = ..., type: _Optional[_Union[Encoding, str]] = ...) -> None: ...
class ExtensionID(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = []
class Encoding(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = []
class SubscriptionMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = []
\ No newline at end of file
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import gnmi_pb2 as gnmi__pb2
class gNMIStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Capabilities = channel.unary_unary(
'/gnmi.gNMI/Capabilities',
request_serializer=gnmi__pb2.CapabilityRequest.SerializeToString,
response_deserializer=gnmi__pb2.CapabilityResponse.FromString,
)
self.Get = channel.unary_unary(
'/gnmi.gNMI/Get',
request_serializer=gnmi__pb2.GetRequest.SerializeToString,
response_deserializer=gnmi__pb2.GetResponse.FromString,
)
self.Set = channel.unary_unary(
'/gnmi.gNMI/Set',
request_serializer=gnmi__pb2.SetRequest.SerializeToString,
response_deserializer=gnmi__pb2.SetResponse.FromString,
)
self.Subscribe = channel.stream_stream(
'/gnmi.gNMI/Subscribe',
request_serializer=gnmi__pb2.SubscribeRequest.SerializeToString,
response_deserializer=gnmi__pb2.SubscribeResponse.FromString,
)
class gNMIServicer(object):
"""Missing associated documentation comment in .proto file."""
def Capabilities(self, request, context):
"""Capabilities allows the client to retrieve the set of capabilities that
is supported by the target. This allows the target to validate the
service version that is implemented and retrieve the set of models that
the target supports. The models can then be specified in subsequent RPCs
to restrict the set of data that is utilized.
Reference: gNMI Specification Section 3.2
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Get(self, request, context):
"""Retrieve a snapshot of data from the target. A Get RPC requests that the
target snapshots a subset of the data tree as specified by the paths
included in the message and serializes this to be returned to the
client using the specified encoding.
Reference: gNMI Specification Section 3.3
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Set(self, request, context):
"""Set allows the client to modify the state of data on the target. The
paths to modified along with the new values that the client wishes
to set the value to.
Reference: gNMI Specification Section 3.4
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Subscribe(self, request_iterator, context):
"""Subscribe allows a client to request the target to send it values
of particular paths within the data tree. These values may be streamed
at a particular cadence (STREAM), sent one off on a long-lived channel
(POLL), or sent as a one-off retrieval (ONCE).
Reference: gNMI Specification Section 3.5
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_gNMIServicer_to_server(servicer, server):
rpc_method_handlers = {
'Capabilities': grpc.unary_unary_rpc_method_handler(
servicer.Capabilities,
request_deserializer=gnmi__pb2.CapabilityRequest.FromString,
response_serializer=gnmi__pb2.CapabilityResponse.SerializeToString,
),
'Get': grpc.unary_unary_rpc_method_handler(
servicer.Get,
request_deserializer=gnmi__pb2.GetRequest.FromString,
response_serializer=gnmi__pb2.GetResponse.SerializeToString,
),
'Set': grpc.unary_unary_rpc_method_handler(
servicer.Set,
request_deserializer=gnmi__pb2.SetRequest.FromString,
response_serializer=gnmi__pb2.SetResponse.SerializeToString,
),
'Subscribe': grpc.stream_stream_rpc_method_handler(
servicer.Subscribe,
request_deserializer=gnmi__pb2.SubscribeRequest.FromString,
response_serializer=gnmi__pb2.SubscribeResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'gnmi.gNMI', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
# This class is part of an EXPERIMENTAL API.
class gNMI(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def Capabilities(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/gnmi.gNMI/Capabilities',
gnmi__pb2.CapabilityRequest.SerializeToString,
gnmi__pb2.CapabilityResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def Get(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/gnmi.gNMI/Get',
gnmi__pb2.GetRequest.SerializeToString,
gnmi__pb2.GetResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def Set(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(request, target, '/gnmi.gNMI/Set',
gnmi__pb2.SetRequest.SerializeToString,
gnmi__pb2.SetResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@staticmethod
def Subscribe(request_iterator,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.stream_stream(request_iterator, target, '/gnmi.gNMI/Subscribe',
gnmi__pb2.SubscribeRequest.SerializeToString,
gnmi__pb2.SubscribeResponse.FromString,
options, channel_credentials,
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
......@@ -69,6 +69,8 @@ def main():
wait_for_environment_variables([
get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST ),
get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_HOST ),
get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
])
signal.signal(signal.SIGINT, signal_handler)
......
......@@ -47,7 +47,7 @@ def create_rule_set(endpoint_a, endpoint_b):
}
]
}
)
)
def create_rule_del(endpoint_a, endpoint_b):
return json_config_rule_delete(
......@@ -68,7 +68,17 @@ def create_rule_del(endpoint_a, endpoint_b):
}
]
}
)
)
def find_names(uuid_a, uuid_b, device_endpoints):
endpoint_a, endpoint_b = None, None
for endpoint in device_endpoints:
if endpoint.endpoint_id.endpoint_uuid.uuid == uuid_a:
endpoint_a = endpoint.name
elif endpoint.endpoint_id.endpoint_uuid.uuid == uuid_b:
endpoint_b = endpoint.name
return (endpoint_a, endpoint_b)
class P4ServiceHandler(_ServiceHandler):
def __init__(self,
......@@ -127,12 +137,21 @@ class P4ServiceHandler(_ServiceHandler):
device = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
del device.device_config.config_rules[:]
# Find names from uuids
(endpoint_a, endpoint_b) = find_names(matched_endpoint_uuid, endpoint_uuid, device.device_endpoints)
if endpoint_a is None:
LOGGER.exception('Unable to find name of endpoint({:s})'.format(str(matched_endpoint_uuid)))
raise Exception('Unable to find name of endpoint({:s})'.format(str(matched_endpoint_uuid)))
if endpoint_b is None:
LOGGER.exception('Unable to find name of endpoint({:s})'.format(str(endpoint_uuid)))
raise Exception('Unable to find name of endpoint({:s})'.format(str(endpoint_uuid)))
# One way
rule = create_rule_set(matched_endpoint_uuid, endpoint_uuid)
rule = create_rule_set(endpoint_a, endpoint_b)
device.device_config.config_rules.append(ConfigRule(**rule))
# The other way
rule = create_rule_set(endpoint_uuid, matched_endpoint_uuid)
rule = create_rule_set(endpoint_b, endpoint_a)
device.device_config.config_rules.append(ConfigRule(**rule))
self.__task_executor.configure_device(device)
......@@ -189,11 +208,20 @@ class P4ServiceHandler(_ServiceHandler):
del device.device_config.config_rules[:]
# Find names from uuids
(endpoint_a, endpoint_b) = find_names(matched_endpoint_uuid, endpoint_uuid, device.device_endpoints)
if endpoint_a is None:
LOGGER.exception('Unable to find name of endpoint({:s})'.format(str(matched_endpoint_uuid)))
raise Exception('Unable to find name of endpoint({:s})'.format(str(matched_endpoint_uuid)))
if endpoint_b is None:
LOGGER.exception('Unable to find name of endpoint({:s})'.format(str(endpoint_uuid)))
raise Exception('Unable to find name of endpoint({:s})'.format(str(endpoint_uuid)))
# One way
rule = create_rule_del(matched_endpoint_uuid, endpoint_uuid)
rule = create_rule_del(endpoint_a, endpoint_b)
device.device_config.config_rules.append(ConfigRule(**rule))
# The other way
rule = create_rule_del(endpoint_uuid, matched_endpoint_uuid)
rule = create_rule_del(endpoint_b, endpoint_a)
device.device_config.config_rules.append(ConfigRule(**rule))
self.__task_executor.configure_device(device)
......
......@@ -25,6 +25,10 @@ from common.proto.context_pb2 import ConfigActionEnum, Context, ContextId, Devic
from device.client.DeviceClient import DeviceClient
from .Objects import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
from common.tools.object_factory.ConfigRule import (
json_config_rule_set, json_config_rule_delete)
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.DEBUG)
......@@ -48,15 +52,18 @@ def test_prepare_scenario(context_client : ContextClient): # pylint: disable=re
context_uuid = context['context_id']['context_uuid']['uuid']
LOGGER.info('Adding Context {:s}'.format(context_uuid))
response = context_client.SetContext(Context(**context))
assert response.context_uuid.uuid == context_uuid
context_data = context_client.GetContext(response)
assert context_data.name == context_uuid
for topology in TOPOLOGIES:
context_uuid = topology['topology_id']['context_id']['context_uuid']['uuid']
topology_uuid = topology['topology_id']['topology_uuid']['uuid']
LOGGER.info('Adding Topology {:s}/{:s}'.format(context_uuid, topology_uuid))
response = context_client.SetTopology(Topology(**topology))
assert response.context_id.context_uuid.uuid == context_uuid
assert response.topology_uuid.uuid == topology_uuid
# assert response.context_id.context_uuid.uuid == context_uuid
topology_data = context_client.GetTopology(response)
assert topology_data.name == topology_uuid
context_id = json_context_id(context_uuid)
......@@ -81,19 +88,24 @@ def test_devices_bootstraping(
device_p4_with_connect_rules = copy.deepcopy(device)
device_p4_with_connect_rules['device_config']['config_rules'].extend(connect_rules)
device_p4_with_connect_rules['device_operational_status'] = \
DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
response = device_client.AddDevice(Device(**device_p4_with_connect_rules))
assert response.device_uuid.uuid == device_uuid
LOGGER.info('Adding Device {:s}'.format(device_uuid))
device_p4_with_endpoints = copy.deepcopy(device)
device_p4_with_endpoints['device_id']['device_uuid']['uuid'] = response.device_uuid.uuid
device_p4_with_endpoints['device_endpoints'].extend(endpoints)
for i in device_p4_with_endpoints['device_endpoints']:
i['endpoint_id']['device_id']['device_uuid']['uuid'] = response.device_uuid.uuid
LOGGER.info('Adding Endpoints {:s}'.format(device_uuid))
device_client.ConfigureDevice(Device(**device_p4_with_endpoints))
for link in LINKS:
link_uuid = link['link_id']['link_uuid']['uuid']
LOGGER.info('Adding Link {:s}'.format(link_uuid))
response = context_client.SetLink(Link(**link))
assert response.link_uuid.uuid == link_uuid
context_client.SetLink(Link(**link))
def test_devices_bootstrapped(context_client : ContextClient): # pylint: disable=redefined-outer-name
# ----- List entities - Ensure bevices are created -----------------------------------------------------------------
......