diff options
-rw-r--r-- | common/certificate/src/device_id.rs | 1 | ||||
-rw-r--r-- | tedge/src/cli/connect/bridge_config_azure.rs | 4 | ||||
-rw-r--r-- | tedge/src/cli/connect/command.rs | 44 | ||||
-rw-r--r-- | tedge/src/cli/disconnect/cli.rs | 6 | ||||
-rw-r--r-- | tedge/src/cli/disconnect/disconnect_bridge.rs | 62 | ||||
-rw-r--r-- | tedge/src/services/mod.rs | 3 | ||||
-rw-r--r-- | tedge/src/services/tedge_mapper.rs | 7 | ||||
-rw-r--r-- | tedge/src/services/tedge_mapper_az.rs | 7 | ||||
-rw-r--r-- | tedge/src/services/tedge_mapper_c8y.rs | 7 | ||||
-rw-r--r-- | tedge/tests/os_related/unix.rs | 12 | ||||
-rw-r--r-- | tests/PySys/environments/environment_az.py | 90 | ||||
-rw-r--r-- | tests/PySys/environments/environment_c8y.py | 9 |
12 files changed, 213 insertions, 39 deletions
diff --git a/common/certificate/src/device_id.rs b/common/certificate/src/device_id.rs index d6d45762..51d95037 100644 --- a/common/certificate/src/device_id.rs +++ b/common/certificate/src/device_id.rs @@ -50,7 +50,6 @@ pub enum DeviceIdError { #[cfg(test)] mod test { use super::*; - use anyhow::Result; use assert_matches::*; #[test] diff --git a/tedge/src/cli/connect/bridge_config_azure.rs b/tedge/src/cli/connect/bridge_config_azure.rs index 6aa8e6e6..079cf4bd 100644 --- a/tedge/src/cli/connect/bridge_config_azure.rs +++ b/tedge/src/cli/connect/bridge_config_azure.rs @@ -46,7 +46,7 @@ impl From<BridgeConfigAzureParams> for BridgeConfig { local_clientid: "Azure".into(), bridge_certfile, bridge_keyfile, - use_mapper: false, + use_mapper: true, try_private: false, start_type: "automatic".into(), clean_session: true, @@ -89,7 +89,7 @@ fn test_bridge_config_from_azure_params() -> anyhow::Result<()> { local_clientid: "Azure".into(), bridge_certfile: "./test-certificate.pem".into(), bridge_keyfile: "./test-private-key.pem".into(), - use_mapper: false, + use_mapper: true, topics: vec![ r#"messages/events/ out 1 az/ devices/alpha/"#.into(), r##"messages/devicebound/# out 1 az/ devices/alpha/"##.into(), diff --git a/tedge/src/cli/connect/command.rs b/tedge/src/cli/connect/command.rs index 51cf9922..64f9a27a 100644 --- a/tedge/src/cli/connect/command.rs +++ b/tedge/src/cli/connect/command.rs @@ -1,7 +1,8 @@ use crate::cli::connect::*; use crate::command::{Command, ExecutionContext}; use crate::services::{ - self, mosquitto::MosquittoService, tedge_mapper::TedgeMapperService, SystemdService, + self, mosquitto::MosquittoService, tedge_mapper_az::TedgeMapperAzService, + tedge_mapper_c8y::TedgeMapperC8yService, SystemdService, }; use crate::utils::paths; use crate::ConfigError; @@ -9,7 +10,7 @@ use mqtt_client::{Client, Message, MqttClient, Topic, TopicFilter}; use std::path::Path; use std::time::Duration; use tedge_config::*; -use tedge_users::UserManager; +use tedge_users::{UserManager, ROOT_USER}; use tempfile::NamedTempFile; use tokio::time::timeout; use which::which; @@ -71,6 +72,7 @@ impl Command for ConnectCommand { new_bridge( &bridge_config, + &self.cloud, &self.common_mosquitto_config, &context.user_manager, )?; @@ -267,6 +269,7 @@ async fn check_connection_azure() -> Result<(), ConnectError> { fn new_bridge( bridge_config: &BridgeConfig, + cloud: &Cloud, common_mosquitto_config: &CommonMosquittoConfig, user_manager: &UserManager, ) -> Result<(), ConnectError> { @@ -314,7 +317,14 @@ fn new_bridge( if which("tedge_mapper").is_err() { println!("Warning: tedge_mapper is not installed. We recommend to install it.\n"); } else { - start_and_enable_tedge_mapper(user_manager); + match cloud { + Cloud::Azure => { + start_and_enable_tedge_mapper_az(user_manager); + } + Cloud::C8y => { + start_and_enable_tedge_mapper_c8y(user_manager); + } + } } } @@ -368,17 +378,39 @@ fn get_bridge_config_file_path(bridge_config: &BridgeConfig) -> Result<String, C ])?) } -fn start_and_enable_tedge_mapper(user_manager: &UserManager) { +fn start_and_enable_tedge_mapper_c8y(user_manager: &UserManager) { + let _root_guard = user_manager.become_user(ROOT_USER); + let mut failed = false; + + println!("Starting tedge-mapper service.\n"); + if let Err(err) = TedgeMapperC8yService.restart(user_manager) { + println!("Failed to stop tedge-mapper service: {:?}", err); + failed = true; + } + + println!("Persisting tedge-mapper on reboot.\n"); + if let Err(err) = TedgeMapperC8yService.enable(user_manager) { + println!("Failed to enable tedge-mapper service: {:?}", err); + failed = true; + } + + if !failed { + println!("tedge-mapper service successfully started and enabled!\n"); + } +} + +fn start_and_enable_tedge_mapper_az(user_manager: &UserManager) { + let _root_guard = user_manager.become_user(ROOT_USER); let mut failed = false; println!("Starting tedge-mapper service.\n"); - if let Err(err) = TedgeMapperService.restart(user_manager) { + if let Err(err) = TedgeMapperAzService.restart(user_manager) { println!("Failed to stop tedge-mapper service: {:?}", err); failed = true; } println!("Persisting tedge-mapper on reboot.\n"); - if let Err(err) = TedgeMapperService.enable(user_manager) { + if let Err(err) = TedgeMapperAzService.enable(user_manager) { println!("Failed to enable tedge-mapper service: {:?}", err); failed = true; } diff --git a/tedge/src/cli/disconnect/cli.rs b/tedge/src/cli/disconnect/cli.rs index 6b2acd2f..74c357e0 100644 --- a/tedge/src/cli/disconnect/cli.rs +++ b/tedge/src/cli/disconnect/cli.rs @@ -18,13 +18,13 @@ impl BuildCommand for TEdgeDisconnectBridgeCli { let cmd = match self { TEdgeDisconnectBridgeCli::C8y => DisconnectBridgeCommand { config_file: C8Y_CONFIG_FILENAME.into(), - cloud_name: "Cumulocity".into(), + cloud: Cloud::C8y, use_mapper: true, }, TEdgeDisconnectBridgeCli::Az => DisconnectBridgeCommand { config_file: AZURE_CONFIG_FILENAME.into(), - cloud_name: "Azure".into(), - use_mapper: false, + cloud: Cloud::Azure, + use_mapper: true, }, }; Ok(cmd.into_boxed()) diff --git a/tedge/src/cli/disconnect/disconnect_bridge.rs b/tedge/src/cli/disconnect/disconnect_bridge.rs index d7c889de..4308d7b0 100644 --- a/tedge/src/cli/disconnect/disconnect_bridge.rs +++ b/tedge/src/cli/disconnect/disconnect_bridge.rs @@ -1,7 +1,8 @@ use crate::cli::disconnect::error::*; use crate::command::*; +use crate::services::tedge_mapper_az::TedgeMapperAzService; use crate::services::{ - mosquitto::MosquittoService, tedge_mapper::TedgeMapperService, SystemdService, + mosquitto::MosquittoService, tedge_mapper_c8y::TedgeMapperC8yService, SystemdService, }; use crate::utils::paths; use tedge_users::*; @@ -10,15 +11,30 @@ use which::which; const TEDGE_BRIDGE_CONF_DIR_PATH: &str = "mosquitto-conf"; #[derive(Debug)] +pub enum Cloud { + C8y, + Azure, +} + +impl From<Cloud> for String { + fn from(val: Cloud) -> Self { + match val { + Cloud::C8y => "Cumulocity".into(), + Cloud::Azure => "Azure".into(), + } + } +} + +#[derive(Debug)] pub struct DisconnectBridgeCommand { pub config_file: String, - pub cloud_name: String, + pub cloud: Cloud, pub use_mapper: bool, } impl Command for DisconnectBridgeCommand { fn description(&self) -> String { - format!("remove the bridge to disconnect {} cloud", self.cloud_name) + format!("remove the bridge to disconnect {:?} cloud", self.cloud) } fn execute(&self, context: &ExecutionContext) -> Result<(), anyhow::Error> { @@ -39,7 +55,14 @@ impl DisconnectBridgeCommand { // Only C8Y changes the status of tedge-mapper if self.use_mapper && which("tedge_mapper").is_ok() { - self.stop_and_disable_tedge_mapper(user_manager); + match self.cloud { + Cloud::Azure => { + self.stop_and_disable_tedge_mapper_az(user_manager); + } + Cloud::C8y => { + self.stop_and_disable_tedge_mapper_c8y(user_manager); + } + } } Ok(()) @@ -50,7 +73,7 @@ impl DisconnectBridgeCommand { let bridge_conf_path = paths::build_path_for_sudo_or_user(&[TEDGE_BRIDGE_CONF_DIR_PATH, &self.config_file])?; - println!("Removing {} bridge.\n", self.cloud_name); + println!("Removing {:?} bridge.\n", self.cloud); match std::fs::remove_file(&bridge_conf_path) { // If we find the bridge config file we remove it // and carry on to see if we need to restart mosquitto. @@ -79,23 +102,44 @@ impl DisconnectBridgeCommand { println!("Applying changes to mosquitto.\n"); if MosquittoService.is_active()? { MosquittoService.restart(user_manager)?; - println!("{} Bridge successfully disconnected!\n", self.cloud_name); + println!("{:?} Bridge successfully disconnected!\n", self.cloud); } Ok(()) } - fn stop_and_disable_tedge_mapper(&self, user_manager: &UserManager) { + fn stop_and_disable_tedge_mapper_c8y(&self, user_manager: &UserManager) { + let _root_guard = user_manager.become_user(ROOT_USER); + let mut failed = false; + + println!("Stopping tedge-mapper service.\n"); + if let Err(err) = TedgeMapperC8yService.stop(user_manager) { + println!("Failed to stop tedge-mapper service: {:?}", err); + failed = true; + } + + println!("Disabling tedge-mapper service.\n"); + if let Err(err) = TedgeMapperC8yService.disable(user_manager) { + println!("Failed to disable tedge-mapper service: {:?}", err); + failed = true; + } + + if !failed { + println!("tedge-mapper service successfully stopped and disabled!\n"); + } + } + + fn stop_and_disable_tedge_mapper_az(&self, user_manager: &UserManager) { let _root_guard = user_manager.become_user(ROOT_USER); let mut failed = false; println!("Stopping tedge-mapper service.\n"); - if let Err(err) = TedgeMapperService.stop(user_manager) { + if let Err(err) = TedgeMapperAzService.stop(user_manager) { println!("Failed to stop tedge-mapper service: {:?}", err); failed = true; } println!("Disabling tedge-mapper service.\n"); - if let Err(err) = TedgeMapperService.disable(user_manager) { + if let Err(err) = TedgeMapperAzService.disable(user_manager) { println!("Failed to disable tedge-mapper service: {:?}", err); failed = true; } diff --git a/tedge/src/services/mod.rs b/tedge/src/services/mod.rs index 4130c24d..3abed534 100644 --- a/tedge/src/services/mod.rs +++ b/tedge/src/services/mod.rs @@ -6,7 +6,8 @@ use std::process::ExitStatus; use tedge_users::*; pub mod mosquitto; -pub mod tedge_mapper; +pub mod tedge_mapper_az; +pub mod tedge_mapper_c8y; type ExitCode = i32; diff --git a/tedge/src/services/tedge_mapper.rs b/tedge/src/services/tedge_mapper.rs deleted file mode 100644 index a3dd888a..00000000 --- a/tedge/src/services/tedge_mapper.rs +++ /dev/null @@ -1,7 +0,0 @@ -use super::SystemdService; - -pub struct TedgeMapperService; - -impl SystemdService for TedgeMapperService { - const SERVICE_NAME: &'static str = "tedge-mapper"; -} diff --git a/tedge/src/services/tedge_mapper_az.rs b/tedge/src/services/tedge_mapper_az.rs new file mode 100644 index 00000000..b53c3692 --- /dev/null +++ b/tedge/src/services/tedge_mapper_az.rs @@ -0,0 +1,7 @@ +use super::SystemdService; + +pub struct TedgeMapperAzService; + +impl SystemdService for TedgeMapperAzService { + const SERVICE_NAME: &'static str = "tedge-mapper-az"; +} diff --git a/tedge/src/services/tedge_mapper_c8y.rs b/tedge/src/services/tedge_mapper_c8y.rs new file mode 100644 index 00000000..4eb9122c --- /dev/null +++ b/tedge/src/services/tedge_mapper_c8y.rs @@ -0,0 +1,7 @@ +use super::SystemdService; + +pub struct TedgeMapperC8yService; + +impl SystemdService for TedgeMapperC8yService { + const SERVICE_NAME: &'static str = "tedge-mapper-c8y"; +} diff --git a/tedge/tests/os_related/unix.rs b/tedge/tests/os_related/unix.rs index 2decf8dc..d8bb699d 100644 --- a/tedge/tests/os_related/unix.rs +++ b/tedge/tests/os_related/unix.rs @@ -1,4 +1,4 @@ -fn command_as_root<I, S>( +fn _command_as_root<I, S>( home_dir: &str, args: I, ) -> Result<std::process::Command, Box<dyn std::error::Error>> @@ -36,21 +36,21 @@ fn create_certificate_as_root_should_switch_to_mosquitto() -> Result<(), Box<dyn let tedge = env!("CARGO_BIN_EXE_tedge"); - let mut chown_mosquitto = command_as_root( + let mut chown_mosquitto = _command_as_root( &mosquitto_home, &["chown", "mosquitto:mosquitto", &mosquitto_home], )?; - let mut chown_tedge = command_as_root(&tedge_home, &["chown", "tedge:tedge", &tedge_home])?; - let mut set_cert_path_cmd = command_as_root( + let mut chown_tedge = _command_as_root(&tedge_home, &["chown", "tedge:tedge", &tedge_home])?; + let mut set_cert_path_cmd = _command_as_root( &tedge_home, &[tedge, "config", "set", "device.cert.path", &cert_path], )?; - let mut set_key_path_cmd = command_as_root( + let mut set_key_path_cmd = _command_as_root( &tedge_home, &[tedge, "config", "set", "device.key.path", &key_path], )?; - let mut create_cmd = command_as_root( + let mut create_cmd = _command_as_root( &tedge_home, &[tedge, "cert", "create", "--device-id", device_id], )?; diff --git a/tests/PySys/environments/environment_az.py b/tests/PySys/environments/environment_az.py new file mode 100644 index 00000000..ed2461ed --- /dev/null +++ b/tests/PySys/environments/environment_az.py @@ -0,0 +1,90 @@ +import pysys +from pysys.basetest import BaseTest + +""" +Environment to manage automated connect and disconnect to az + +Tests that derive from class EnvironmentAz use automated connect and +disconnect to Cumulocity. Additional checks are made for the status of +service mosquitto and service tedge-mapper. +""" + + +class EnvironmentAz(BaseTest): + def setup(self): + self.log.debug("EnvironmentAz Setup") + + self.tedge = "/usr/bin/tedge" + self.tedge_mapper_az = "tedge-mapper-az" + self.sudo = "/usr/bin/sudo" + self.systemctl = "/usr/bin/systemctl" + self.log.info("EnvironmentAz Setup") + self.addCleanupFunction(self.myenvcleanup) + + # Check if tedge-mapper is in disabled state + serv_mapper_az = self.startProcess( + command=self.systemctl, + arguments=["status", self.tedge_mapper_az], + stdouterr="serv_mapper1", + expectedExitStatus="==3", # 3: disabled + ) + + + # Connect the bridge + connect = self.startProcess( + command=self.sudo, + arguments=[self.tedge, "connect", "az"], + stdouterr="tedge_connect", + ) + + # Check if mosquitto is running well + serv_mosq = self.startProcess( + command=self.systemctl, + arguments=["status", "mosquitto"], + stdouterr="serv_mosq2", + ) + + # Check if tedge-mapper is active again + serv_mapper = self.startProcess( + command=self.systemctl, + arguments=["status", self.tedge_mapper_az], + stdouterr="serv_mapper3", + ) + + def execute(self): + self.log.debug("EnvironmentAz Execute") + + def validate(self): + self.log.debug("EnvironmentAz Validate") + + # Check if mosquitto is running well + serv_mosq = self.startProcess( + command=self.systemctl, + arguments=["status", "mosquitto"], + stdouterr="serv_mosq", + ) + + # Check if tedge-mapper is active + serv_mapper = self.startProcess( + command=self.systemctl, + arguments=["status", self.tedge_mapper_az], + stdouterr="serv_mapper4", + ) + + def myenvcleanup(self): + self.log.debug("EnvironmentAz Cleanup") + + # Disconnect Bridge + disconnect = self.startProcess( + command=self.sudo, + arguments=[self.tedge, "disconnect", "az"], + stdouterr="tedge_disconnect", + ) + + # Check if tedge-mapper is disabled + serv_mosq = self.startProcess( + command=self.systemctl, + arguments=["status", self.tedge_mapper_az], + stdouterr="serv_mapper5", + expectedExitStatus="==3", + ) diff --git a/tests/PySys/environments/environment_c8y.py b/tests/PySys/environments/environment_c8y.py index ac1c4bb2..9e7f4220 100644 --- a/tests/PySys/environments/environment_c8y.py +++ b/tests/PySys/environments/environment_c8y.py @@ -15,6 +15,7 @@ class EnvironmentC8y(BaseTest): self.log.debug("EnvironmentC8y Setup") self.tedge = "/usr/bin/tedge" + self.tedge_mapper_c8y = "tedge-mapper-c8y" self.sudo = "/usr/bin/sudo" self.systemctl = "/usr/bin/systemctl" self.log.info("EnvironmentC8y Setup") @@ -23,7 +24,7 @@ class EnvironmentC8y(BaseTest): # Check if tedge-mapper is in disabled state serv_mapper = self.startProcess( command=self.systemctl, - arguments=["status", "tedge-mapper"], + arguments=["status", self.tedge_mapper_c8y], stdouterr="serv_mapper1", expectedExitStatus="==3", # 3: disabled ) @@ -45,7 +46,7 @@ class EnvironmentC8y(BaseTest): # Check if tedge-mapper is active again serv_mapper = self.startProcess( command=self.systemctl, - arguments=["status", "tedge-mapper"], + arguments=["status", self.tedge_mapper_c8y], stdouterr="serv_mapper3", ) @@ -65,7 +66,7 @@ class EnvironmentC8y(BaseTest): # Check if tedge-mapper is active serv_mapper = self.startProcess( command=self.systemctl, - arguments=["status", "tedge-mapper"], + arguments=["status", self.tedge_mapper_c8y], stdouterr="serv_mapper4", ) @@ -82,7 +83,7 @@ class EnvironmentC8y(BaseTest): # Check if tedge-mapper is disabled serv_mosq = self.startProcess( command=self.systemctl, - arguments=["status", "tedge-mapper"], + arguments=["status", self.tedge_mapper_c8y], stdouterr="serv_mapper5", expectedExitStatus="==3", ) |