From 57bbdeaf76cbdbfe3db539f714114667329c52b6 Mon Sep 17 00:00:00 2001 From: amangalampalli-ks Date: Fri, 6 Mar 2026 12:06:33 +0530 Subject: [PATCH] Add bot port prompt and field --- .../integrations/integration_setup_base.py | 11 ++++-- .../commands/integrations/teams_app_setup.py | 17 +++++++++ .../service/docker/compose_builder.py | 36 ++++++++++--------- keepercommander/service/docker/models.py | 1 + 4 files changed, 46 insertions(+), 19 deletions(-) diff --git a/keepercommander/service/commands/integrations/integration_setup_base.py b/keepercommander/service/commands/integrations/integration_setup_base.py index a9b825eab..290b55bd8 100644 --- a/keepercommander/service/commands/integrations/integration_setup_base.py +++ b/keepercommander/service/commands/integrations/integration_setup_base.py @@ -86,6 +86,10 @@ def get_docker_image(self) -> str: def get_record_env_key(self) -> str: return f'{self.get_integration_name().upper()}_RECORD' + def get_integration_service_ports(self, config) -> List[str]: + """Return host:container port mappings for the integration container. Override if needed.""" + return [] + def get_commander_service_name(self) -> str: return f'commander-{self.get_integration_name().lower()}' @@ -250,7 +254,7 @@ def _run_integration_setup(self, params, setup_result: SetupResult, record_uid = self._create_integration_record(params, record_name, setup_result.folder_uid, custom_fields) DockerSetupPrinter.print_step(2, 2, f"Updating docker-compose.yml with {name} App service...") - self._update_docker_compose(setup_result, service_config, record_uid) + self._update_docker_compose(setup_result, service_config, record_uid, config) return record_uid, config @@ -306,7 +310,7 @@ def _update_record_custom_fields(self, params, record_uid: str, custom_fields: L def _update_docker_compose(self, setup_result: SetupResult, service_config: ServiceConfig, - record_uid: str) -> None: + record_uid: str, config=None) -> None: compose_file = os.path.join(os.getcwd(), 'docker-compose.yml') service_name = self.get_docker_service_name() @@ -329,7 +333,8 @@ def _update_docker_compose(self, setup_result: SetupResult, container_name=self.get_docker_container_name(), image=self.get_docker_image(), record_uid=record_uid, - record_env_key=self.get_record_env_key() + record_env_key=self.get_record_env_key(), + ports=self.get_integration_service_ports(config) ).build() with open(compose_file, 'w') as f: diff --git a/keepercommander/service/commands/integrations/teams_app_setup.py b/keepercommander/service/commands/integrations/teams_app_setup.py index 76a46d6f3..3d3b80aaf 100644 --- a/keepercommander/service/commands/integrations/teams_app_setup.py +++ b/keepercommander/service/commands/integrations/teams_app_setup.py @@ -11,9 +11,12 @@ """Teams App integration setup command.""" +from typing import List + from .... import vault from ....display import bcolors from ...docker import TeamsConfig +from ...config.config_validation import ConfigValidator, ValidationError from .integration_setup_base import IntegrationSetupCommand @@ -66,6 +69,16 @@ def collect_integration_config(self): "Invalid Team ID (must be 32 hex characters in pattern xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)" ) + print(f"\n{bcolors.BOLD}TEAMS_BOT_PORT:{bcolors.ENDC}") + print(f" Port on which the Teams bot will listen for incoming requests") + while True: + bot_port_input = input(f"{bcolors.OKBLUE}Bot Port [Press Enter for 3978]:{bcolors.ENDC} ").strip() or '3978' + try: + bot_port = ConfigValidator.validate_port(bot_port_input) + break + except ValidationError as e: + print(f"{bcolors.FAIL}Error: {str(e)}{bcolors.ENDC}") + pedm_enabled, pedm_interval = self._collect_pedm_config() da_enabled, da_interval = self._collect_device_approval_config() @@ -77,6 +90,7 @@ def collect_integration_config(self): tenant_id=tenant_id, approvals_channel_id=approvals_channel_id, approvals_team_id=approvals_team_id, + bot_port=bot_port, pedm_enabled=pedm_enabled, pedm_polling_interval=pedm_interval, device_approval_enabled=da_enabled, @@ -96,6 +110,9 @@ def build_record_custom_fields(self, config): vault.TypedField.new_field('text', str(config.device_approval_polling_interval), 'device_approval_polling_interval'), ] + def get_integration_service_ports(self, config) -> List[str]: + return [f'{config.bot_port}:{config.bot_port}'] + # ── Display ─────────────────────────────────────────────────── def print_integration_specific_resources(self, config): diff --git a/keepercommander/service/docker/compose_builder.py b/keepercommander/service/docker/compose_builder.py index f4836f143..be3bf5ffa 100644 --- a/keepercommander/service/docker/compose_builder.py +++ b/keepercommander/service/docker/compose_builder.py @@ -37,12 +37,13 @@ def build_dict(self) -> Dict[str, Any]: def add_integration_service(self, service_name: str, container_name: str, image: str, record_uid: str, - record_env_key: str) -> 'DockerComposeBuilder': + record_env_key: str, + ports: List[str] = None) -> 'DockerComposeBuilder': """Add an integration service to the compose file. Returns self.""" if self.commander_service_name not in self._services: self._services[self.commander_service_name] = self._build_commander_service() self._services[service_name] = self._build_integration_service( - container_name, image, record_uid, record_env_key + container_name, image, record_uid, record_env_key, ports or [] ) return self @@ -65,23 +66,26 @@ def _build_commander_service(self) -> Dict[str, Any]: return service def _build_integration_service(self, container_name: str, image: str, - record_uid: str, - record_env_key: str) -> Dict[str, Any]: - return { + record_uid: str, record_env_key: str, + ports: List[str] = None) -> Dict[str, Any]: + service: Dict[str, Any] = { 'container_name': container_name, 'image': image, - 'environment': { - 'KSM_CONFIG': self.setup_result.b64_config, - 'COMMANDER_RECORD': self.setup_result.record_uid, - record_env_key: record_uid - }, - 'depends_on': { - self.commander_service_name: { - 'condition': 'service_healthy' - } - }, - 'restart': 'unless-stopped' } + if ports: + service['ports'] = ports + service['environment'] = { + 'KSM_CONFIG': self.setup_result.b64_config, + 'COMMANDER_RECORD': self.setup_result.record_uid, + record_env_key: record_uid + } + service['depends_on'] = { + self.commander_service_name: { + 'condition': 'service_healthy' + } + } + service['restart'] = 'unless-stopped' + return service def _build_service_command(self) -> None: port = self.config['port'] diff --git a/keepercommander/service/docker/models.py b/keepercommander/service/docker/models.py index 78ad0a6c6..d601c5581 100644 --- a/keepercommander/service/docker/models.py +++ b/keepercommander/service/docker/models.py @@ -96,6 +96,7 @@ class TeamsConfig: tenant_id: str approvals_channel_id: str approvals_team_id: str + bot_port: int = 3978 pedm_enabled: bool = False pedm_polling_interval: int = 120 device_approval_enabled: bool = False