From 85521e8c8f4e467a0fa73fedf414530539cb8be9 Mon Sep 17 00:00:00 2001 From: Blake Harnden <32446120+bharnden@users.noreply.github.com> Date: Fri, 13 Dec 2019 18:17:42 -0800 Subject: [PATCH] added grpc to get current service configurations, fixed bug for core daemon not using custom service configs --- coretk/coretk/coreclient.py | 32 ++++++--------- coretk/coretk/dialogs/serviceconfiguration.py | 2 +- daemon/core/api/grpc/client.py | 12 ++++++ daemon/core/api/grpc/grpcutils.py | 22 +++++++++++ daemon/core/api/grpc/server.py | 39 +++++++++++++------ daemon/core/services/coreservices.py | 7 +++- daemon/proto/core/api/grpc/core.proto | 16 ++++++++ daemon/tests/test_grpc.py | 18 +++++++++ 8 files changed, 112 insertions(+), 36 deletions(-) diff --git a/coretk/coretk/coreclient.py b/coretk/coretk/coreclient.py index bff47501..776e1750 100644 --- a/coretk/coretk/coreclient.py +++ b/coretk/coretk/coreclient.py @@ -242,27 +242,17 @@ class CoreClient: mapped_config = response.configs[_id] self.wlan_configs[_id] = mapped_config.config - # save and retrieve data, needed for session nodes - for node in session.nodes: - # get node service config and file config - # retrieve service configurations data for default nodes - if node.type == core_pb2.NodeType.DEFAULT: - for service in node.services: - response = self.client.get_node_service( - self.session_id, node.id, service - ) - if node.id not in self.service_configs: - self.service_configs[node.id] = {} - self.service_configs[node.id][service] = response.service - for file in response.service.configs: - response = self.client.get_node_service_file( - self.session_id, node.id, service, file - ) - if node.id not in self.file_configs: - self.file_configs[node.id] = {} - if service not in self.file_configs[node.id]: - self.file_configs[node.id][service] = {} - self.file_configs[node.id][service][file] = response.data + # get service configurations + response = self.client.get_node_service_configs(self.session_id) + for config in response.configs: + service_configs = self.service_configs.setdefault(config.node_id, {}) + service_configs[config.service] = config.data + logging.info("service file configs: %s", config.files) + for file_name in config.files: + file_configs = self.file_configs.setdefault(config.node_id, {}) + files = file_configs.setdefault(config.service, {}) + data = config.files[file_name] + files[file_name] = data # draw session self.app.canvas.reset_and_redraw(session) diff --git a/coretk/coretk/dialogs/serviceconfiguration.py b/coretk/coretk/dialogs/serviceconfiguration.py index 03c74ab2..a53c2aa1 100644 --- a/coretk/coretk/dialogs/serviceconfiguration.py +++ b/coretk/coretk/dialogs/serviceconfiguration.py @@ -323,7 +323,7 @@ class ServiceConfiguration(Dialog): button = ttk.Button(frame, text="Apply", command=self.click_apply) button.grid(row=0, column=0, sticky="ew", padx=PADX) button = ttk.Button( - frame, text="Dafults", command=self.click_defaults, state="disabled" + frame, text="Defaults", command=self.click_defaults, state="disabled" ) button.grid(row=0, column=1, sticky="ew", padx=PADX) button = ttk.Button( diff --git a/daemon/core/api/grpc/client.py b/daemon/core/api/grpc/client.py index ae193909..fbafbb44 100644 --- a/daemon/core/api/grpc/client.py +++ b/daemon/core/api/grpc/client.py @@ -731,6 +731,18 @@ class CoreGrpcClient: ) return self.stub.SetServiceDefaults(request) + def get_node_service_configs(self, session_id): + """ + Get service data for a node. + + :param int session_id: session id + :return: response with all node service configs + :rtype: core_pb2.GetNodeServiceConfigsResponse + :raises grpc.RpcError: when session doesn't exist + """ + request = core_pb2.GetNodeServiceConfigsRequest(session_id=session_id) + return self.stub.GetNodeServiceConfigs(request) + def get_node_service(self, session_id, node_id, service): """ Get service data for a node. diff --git a/daemon/core/api/grpc/grpcutils.py b/daemon/core/api/grpc/grpcutils.py index 7df86a18..4ea752fd 100644 --- a/daemon/core/api/grpc/grpcutils.py +++ b/daemon/core/api/grpc/grpcutils.py @@ -352,3 +352,25 @@ def service_configuration(session, config): service.startup = tuple(config.startup) service.validate = tuple(config.validate) service.shutdown = tuple(config.shutdown) + + +def get_service_configuration(service): + """ + Convenience for converting a service to service data proto. + + :param service: service to get proto data for + :return: service proto data + :rtype: core.api.grpc.core_pb2.NodeServiceData + """ + return core_pb2.NodeServiceData( + executables=service.executables, + dependencies=service.dependencies, + dirs=service.dirs, + configs=service.configs, + startup=service.startup, + validate=service.validate, + validation_mode=service.validation_mode.value, + validation_timer=service.validation_timer, + shutdown=service.shutdown, + meta=service.meta, + ) diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index 75ce23ba..1ada5267 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -917,6 +917,32 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ] = service_defaults.services return core_pb2.SetServiceDefaultsResponse(result=True) + def GetNodeServiceConfigs(self, request, context): + """ + Retrieve all node service configurations. + + :param core.api.grpc.core_pb2.GetNodeServiceConfigsRequest request: + get-node-service request + :param grpc.ServicerContext context: context object + :return: all node service configs response + :rtype: core.api.grpc.core_pb2.GetNodeServiceConfigsResponse + """ + logging.debug("get node service configs: %s", request) + session = self.get_session(request.session_id, context) + configs = [] + for node_id, service_configs in session.services.custom_services.items(): + for name in service_configs: + service = session.services.get_service(node_id, name) + service_proto = grpcutils.get_service_configuration(service) + config = core_pb2.GetNodeServiceConfigsResponse.ServiceConfig( + node_id=node_id, + service=name, + data=service_proto, + files=service.config_data, + ) + configs.append(config) + return core_pb2.GetNodeServiceConfigsResponse(configs=configs) + def GetNodeService(self, request, context): """ Retrieve a requested service from a node @@ -932,18 +958,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): service = session.services.get_service( request.node_id, request.service, default_service=True ) - service_proto = core_pb2.NodeServiceData( - executables=service.executables, - dependencies=service.dependencies, - dirs=service.dirs, - configs=service.configs, - startup=service.startup, - validate=service.validate, - validation_mode=service.validation_mode.value, - validation_timer=service.validation_timer, - shutdown=service.shutdown, - meta=service.meta, - ) + service_proto = grpcutils.get_service_configuration(service) return core_pb2.GetNodeServiceResponse(service=service_proto) def GetNodeServiceFile(self, request, context): diff --git a/daemon/core/services/coreservices.py b/daemon/core/services/coreservices.py index b51eb715..684ccbb9 100644 --- a/daemon/core/services/coreservices.py +++ b/daemon/core/services/coreservices.py @@ -461,8 +461,8 @@ class CoreServices: :param core.netns.vnode.LxcNode node: node to start services on :return: nothing """ - funcs = [] boot_paths = ServiceDependencies(node.services).boot_paths() + funcs = [] for boot_path in boot_paths: args = (node, boot_path) funcs.append((self._start_boot_paths, args, {})) @@ -484,6 +484,7 @@ class CoreServices: " -> ".join([x.name for x in boot_path]), ) for service in boot_path: + service = self.get_service(node.id, service.name, default_service=True) try: self.boot_service(node, service) except Exception: @@ -744,7 +745,9 @@ class CoreServices: config_files = service.get_configs(node) for file_name in config_files: - logging.debug("generating service config: %s", file_name) + logging.debug( + "generating service config custom(%s): %s", service.custom, file_name + ) if service.custom: cfg = service.config_data.get(file_name) if cfg is None: diff --git a/daemon/proto/core/api/grpc/core.proto b/daemon/proto/core/api/grpc/core.proto index 55ed272e..b0a6c0d6 100644 --- a/daemon/proto/core/api/grpc/core.proto +++ b/daemon/proto/core/api/grpc/core.proto @@ -89,6 +89,8 @@ service CoreApi { } rpc SetServiceDefaults (SetServiceDefaultsRequest) returns (SetServiceDefaultsResponse) { } + rpc GetNodeServiceConfigs (GetNodeServiceConfigsRequest) returns (GetNodeServiceConfigsResponse) { + } rpc GetNodeService (GetNodeServiceRequest) returns (GetNodeServiceResponse) { } rpc GetNodeServiceFile (GetNodeServiceFileRequest) returns (GetNodeServiceFileResponse) { @@ -538,6 +540,20 @@ message SetServiceDefaultsResponse { bool result = 1; } +message GetNodeServiceConfigsRequest { + int32 session_id = 1; +} + +message GetNodeServiceConfigsResponse { + message ServiceConfig { + int32 node_id = 1; + string service = 2; + NodeServiceData data = 3; + map files = 4; + } + repeated ServiceConfig configs = 1; +} + message GetNodeServiceRequest { int32 session_id = 1; int32 node_id = 2; diff --git a/daemon/tests/test_grpc.py b/daemon/tests/test_grpc.py index d4df63d7..796febf7 100644 --- a/daemon/tests/test_grpc.py +++ b/daemon/tests/test_grpc.py @@ -878,6 +878,24 @@ class TestGrpc: assert response.result is True assert session.services.default_services[node_type] == services + def test_get_node_service_configs(self, grpc_server): + # given + client = CoreGrpcClient() + session = grpc_server.coreemu.create_session() + node = session.add_node() + service_name = "DefaultRoute" + session.services.set_service(node.id, service_name) + + # then + with client.context_connect(): + response = client.get_node_service_configs(session.id) + + # then + assert len(response.configs) == 1 + service_config = response.configs[0] + assert service_config.node_id == node.id + assert service_config.service == service_name + def test_get_node_service(self, grpc_server): # given client = CoreGrpcClient()