diff --git a/daemon/core/api/grpc/grpcutils.py b/daemon/core/api/grpc/grpcutils.py index d54cba27..f7e80fc1 100644 --- a/daemon/core/api/grpc/grpcutils.py +++ b/daemon/core/api/grpc/grpcutils.py @@ -3,7 +3,7 @@ import time from typing import Any, Dict, List, Tuple, Type from core import utils -from core.api.grpc import core_pb2 +from core.api.grpc import common_pb2, core_pb2 from core.config import ConfigurableOptions from core.emulator.data import LinkData from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions @@ -190,7 +190,7 @@ def convert_value(value: Any) -> str: def get_config_options( config: Dict[str, str], configurable_options: Type[ConfigurableOptions] -) -> Dict[str, core_pb2.ConfigOption]: +) -> Dict[str, common_pb2.ConfigOption]: """ Retrieve configuration options in a form that is used by the grpc server. @@ -201,7 +201,7 @@ def get_config_options( results = {} for configuration in configurable_options.configurations(): value = config[configuration.id] - config_option = core_pb2.ConfigOption( + config_option = common_pb2.ConfigOption( label=configuration.label, name=configuration.id, value=value, diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index b0a7609b..df6178b9 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -10,7 +10,7 @@ from typing import Type import grpc from grpc import ServicerContext -from core.api.grpc import core_pb2, core_pb2_grpc, grpcutils +from core.api.grpc import common_pb2, core_pb2, core_pb2_grpc, grpcutils from core.api.grpc.configservices_pb2 import ( ConfigService, GetConfigServiceDefaultsRequest, @@ -1494,7 +1494,17 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): service_class = self.validate_service(request.name, context) service = service_class(None) templates = service.get_templates() - config = service.render_config() + config = {} + for configuration in service.default_configs: + config_option = common_pb2.ConfigOption( + label=configuration.label, + name=configuration.id, + value=configuration.default, + type=configuration.type.value, + select=configuration.options, + group="Settings", + ) + config[configuration.id] = config_option return GetConfigServiceDefaultsResponse(templates=templates, config=config) def GetNodeConfigServices( diff --git a/daemon/core/gui/coreclient.py b/daemon/core/gui/coreclient.py index b9522730..216a50a9 100644 --- a/daemon/core/gui/coreclient.py +++ b/daemon/core/gui/coreclient.py @@ -9,7 +9,7 @@ from typing import TYPE_CHECKING, Dict, List import grpc -from core.api.grpc import client, core_pb2 +from core.api.grpc import client, common_pb2, core_pb2 from core.gui import appconfig from core.gui.dialogs.mobilityplayer import MobilityPlayer from core.gui.dialogs.sessions import SessionsDialog @@ -875,14 +875,14 @@ class CoreClient: logging.info("running node(%s) cmd: %s", node_id, self.observer) return self.client.node_command(self.session_id, node_id, self.observer).output - def get_wlan_config(self, node_id: int) -> Dict[str, core_pb2.ConfigOption]: + def get_wlan_config(self, node_id: int) -> Dict[str, common_pb2.ConfigOption]: config = self.wlan_configs.get(node_id) if not config: response = self.client.get_wlan_config(self.session_id, node_id) config = response.config return config - def get_mobility_config(self, node_id: int) -> Dict[str, core_pb2.ConfigOption]: + def get_mobility_config(self, node_id: int) -> Dict[str, common_pb2.ConfigOption]: config = self.mobility_configs.get(node_id) if not config: response = self.client.get_mobility_config(self.session_id, node_id) @@ -891,7 +891,7 @@ class CoreClient: def get_emane_model_config( self, node_id: int, model: str, interface: int = None - ) -> Dict[str, core_pb2.ConfigOption]: + ) -> Dict[str, common_pb2.ConfigOption]: logging.info("getting emane model config: %s %s %s", node_id, model, interface) config = self.emane_model_configs.get((node_id, model, interface)) if not config: @@ -907,7 +907,7 @@ class CoreClient: self, node_id: int, model: str, - config: Dict[str, core_pb2.ConfigOption], + config: Dict[str, common_pb2.ConfigOption], interface: int = None, ): logging.info("setting emane model config: %s %s %s", node_id, model, interface) diff --git a/daemon/core/gui/dialogs/configserviceconfig.py b/daemon/core/gui/dialogs/configserviceconfig.py index ea5a025a..94556a3c 100644 --- a/daemon/core/gui/dialogs/configserviceconfig.py +++ b/daemon/core/gui/dialogs/configserviceconfig.py @@ -1,6 +1,7 @@ """ Service configuration dialog """ +import logging import tkinter as tk from tkinter import ttk from typing import TYPE_CHECKING, Any, List @@ -13,7 +14,7 @@ from core.gui.dialogs.dialog import Dialog from core.gui.errors import show_grpc_error from core.gui.images import ImageEnum, Images from core.gui.themes import FRAME_PAD, PADX, PADY -from core.gui.widgets import CodeText, ListboxScroll +from core.gui.widgets import CodeText, ConfigFrame, ListboxScroll if TYPE_CHECKING: from core.gui.app import Application @@ -61,6 +62,8 @@ class ConfigServiceConfigDialog(Dialog): self.original_service_files = {} self.temp_service_files = {} self.modified_files = set() + self.config_frame = None + self.config = None self.load() self.draw() @@ -81,6 +84,7 @@ class ConfigServiceConfigDialog(Dialog): response = self.core.client.get_config_service_defaults(self.service_name) self.original_service_files = response.templates self.temp_service_files = dict(self.original_service_files) + self.config = response.config node_configs = self.service_configs.get(self.node_id, {}) service_config = node_configs.get(self.service_name, {}) @@ -98,9 +102,10 @@ class ConfigServiceConfigDialog(Dialog): self.notebook = ttk.Notebook(self.top) self.notebook.grid(sticky="nsew", pady=PADY) self.draw_tab_files() + self.draw_tab_config() self.draw_tab_directories() self.draw_tab_startstop() - self.draw_tab_configuration() + self.draw_tab_validation() self.draw_buttons() @@ -184,6 +189,16 @@ class ConfigServiceConfigDialog(Dialog): "", self.update_temp_service_file_data ) + def draw_tab_config(self): + tab = ttk.Frame(self.notebook, padding=FRAME_PAD) + tab.grid(sticky="nsew") + tab.columnconfigure(0, weight=1) + self.notebook.add(tab, text="Configuration") + logging.info("config service config: %s", self.config) + self.config_frame = ConfigFrame(tab, self.app, self.config) + self.config_frame.draw_config() + self.config_frame.grid(sticky="nsew", pady=PADY) + def draw_tab_directories(self): tab = ttk.Frame(self.notebook, padding=FRAME_PAD) tab.grid(sticky="nsew") @@ -250,7 +265,7 @@ class ConfigServiceConfigDialog(Dialog): elif i == 2: self.validate_commands_listbox = listbox_scroll.listbox - def draw_tab_configuration(self): + def draw_tab_validation(self): tab = ttk.Frame(self.notebook, padding=FRAME_PAD) tab.grid(sticky="nsew") tab.columnconfigure(0, weight=1) diff --git a/daemon/core/gui/widgets.py b/daemon/core/gui/widgets.py index 8dc163ab..e6d2e940 100644 --- a/daemon/core/gui/widgets.py +++ b/daemon/core/gui/widgets.py @@ -5,7 +5,7 @@ from pathlib import PosixPath from tkinter import filedialog, font, ttk from typing import TYPE_CHECKING, Dict -from core.api.grpc import core_pb2 +from core.api.grpc import common_pb2, core_pb2 from core.gui import themes from core.gui.themes import FRAME_PAD, PADX, PADY @@ -74,7 +74,7 @@ class ConfigFrame(ttk.Notebook): self, master: tk.Widget, app: "Application", - config: Dict[str, core_pb2.ConfigOption], + config: Dict[str, common_pb2.ConfigOption], **kw ): super().__init__(master, **kw) diff --git a/daemon/proto/Makefile.am b/daemon/proto/Makefile.am index e63179ca..af535c1e 100644 --- a/daemon/proto/Makefile.am +++ b/daemon/proto/Makefile.am @@ -1,5 +1,6 @@ all: - $(PYTHON) -m grpc_tools.protoc -I . --python_out=.. --grpc_python_out=.. core/api/grpc/*.proto + $(PYTHON) -m grpc_tools.protoc -I . --python_out=.. core/api/grpc/*.proto + $(PYTHON) -m grpc_tools.protoc -I . --grpc_python_out=.. core/api/grpc/core.proto clean: -rm -f ../core/api/grpc/*_pb2* diff --git a/daemon/proto/core/api/grpc/common.proto b/daemon/proto/core/api/grpc/common.proto new file mode 100644 index 00000000..590e2262 --- /dev/null +++ b/daemon/proto/core/api/grpc/common.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +package common; + +message ConfigOption { + string label = 1; + string name = 2; + string value = 3; + int32 type = 4; + repeated string select = 5; + string group = 6; +} diff --git a/daemon/proto/core/api/grpc/configservices.proto b/daemon/proto/core/api/grpc/configservices.proto index e52bd1a0..156bad6b 100644 --- a/daemon/proto/core/api/grpc/configservices.proto +++ b/daemon/proto/core/api/grpc/configservices.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package configservices; +import "core/api/grpc/common.proto"; + message ConfigServiceValidationMode { enum Enum { BLOCKING = 0; @@ -39,7 +41,7 @@ message GetConfigServiceDefaultsRequest { message GetConfigServiceDefaultsResponse { map templates = 1; - map config = 2; + map config = 2; } message GetNodeConfigServiceRequest { diff --git a/daemon/proto/core/api/grpc/core.proto b/daemon/proto/core/api/grpc/core.proto index 4cea4143..82c26b2a 100644 --- a/daemon/proto/core/api/grpc/core.proto +++ b/daemon/proto/core/api/grpc/core.proto @@ -6,6 +6,7 @@ option java_package = "com.core.client.grpc"; option java_outer_classname = "CoreProto"; import "core/api/grpc/configservices.proto"; +import "core/api/grpc/common.proto"; service CoreApi { // session rpc @@ -217,7 +218,7 @@ message GetSessionOptionsRequest { } message GetSessionOptionsResponse { - map config = 2; + map config = 2; } message SetSessionOptionsRequest { @@ -508,7 +509,7 @@ message GetMobilityConfigRequest { } message GetMobilityConfigResponse { - map config = 1; + map config = 1; } message SetMobilityConfigRequest { @@ -633,7 +634,7 @@ message GetWlanConfigRequest { } message GetWlanConfigResponse { - map config = 1; + map config = 1; } message SetWlanConfigRequest { @@ -650,7 +651,7 @@ message GetEmaneConfigRequest { } message GetEmaneConfigResponse { - map config = 1; + map config = 1; } message SetEmaneConfigRequest { @@ -678,7 +679,7 @@ message GetEmaneModelConfigRequest { } message GetEmaneModelConfigResponse { - map config = 1; + map config = 1; } message SetEmaneModelConfigRequest { @@ -699,7 +700,7 @@ message GetEmaneModelConfigsResponse { int32 node_id = 1; string model = 2; int32 interface = 3; - map config = 4; + map config = 4; } repeated ModelConfig configs = 1; } @@ -917,16 +918,7 @@ message NodeServiceData { } message MappedConfig { - map config = 1; -} - -message ConfigOption { - string label = 1; - string name = 2; - string value = 3; - int32 type = 4; - repeated string select = 5; - string group = 6; + map config = 1; } message Session {