pub struct Environment<S = Created> { /* private fields */ }Expand description
Environment configuration encapsulating all environment-specific settings
This entity represents a complete environment configuration including naming, directory structure, SSH keys, and derived paths. It follows the principle of environment isolation where each environment has its own separate resources.
§Architecture: Context + State Design
The Environment<S> is composed of two distinct parts:
§context: EnvironmentContext - Immutable Identity
Contains all state-independent data that remains constant throughout the
environment’s lifecycle. This includes identity (name, instance_name),
configuration (SSH credentials, port), and paths (build_dir, data_dir).
Accessing context data is efficient and requires no pattern matching on state.
§state: S - Mutable Lifecycle State
Represents the current phase in the deployment lifecycle using type parameters. The type-state pattern ensures that state transitions are validated at compile-time.
§Type-State Pattern
The Environment uses the type-state pattern to enforce valid state transitions
at compile-time. Each state is represented by a distinct type parameter S,
ensuring that operations are only callable on appropriate states.
§Design Principles
- Isolation: Each environment is completely isolated from others
- Compile-time Safety: Invalid state transitions caught during compilation
- Separation of Concerns: Context (identity) vs. State (lifecycle) are distinct
- Consistency: All paths follow the same naming pattern
- Predictability: Paths are derived automatically from environment name
- Traceability: All artifacts are organized by environment for debugging
- Type Safety: Invalid state transitions are prevented at compile-time
§Directory Structure
data/{env_name}/
templates/ # Environment-specific templates
build/{env_name}/ # Environment-specific build artifacts§Instance Naming
Instance names follow the pattern: torrust-tracker-vm-{env_name}
This ensures multiple environments can run concurrently without conflicts.
Implementations§
Source§impl Environment<ConfigureFailed>
impl Environment<ConfigureFailed>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<ConfigureFailed> into type-erased AnyEnvironmentState
Source§impl Environment<Configured>
impl Environment<Configured>
Sourcepub fn start_releasing(self) -> Environment<Releasing>
pub fn start_releasing(self) -> Environment<Releasing>
Transitions from Configured to Releasing state
This method indicates that release preparation has begun.
Source§impl Environment<Configured>
impl Environment<Configured>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Configured> into type-erased AnyEnvironmentState
Source§impl Environment<Configuring>
impl Environment<Configuring>
Sourcepub fn configured(self) -> Environment<Configured>
pub fn configured(self) -> Environment<Configured>
Transitions from Configuring to Configured state
This method indicates that application configuration completed successfully.
Sourcepub fn configure_failed(
self,
context: ConfigureFailureContext,
) -> Environment<ConfigureFailed>
pub fn configure_failed( self, context: ConfigureFailureContext, ) -> Environment<ConfigureFailed>
Transitions from Configuring to ConfigureFailed state
This method indicates that application configuration failed. The context parameter provides structured error information including the failed step, error classification, and trace reference.
Source§impl Environment<Configuring>
impl Environment<Configuring>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Configuring> into type-erased AnyEnvironmentState
Source§impl Environment<Created>
impl Environment<Created>
Sourcepub fn start_provisioning(self) -> Environment<Provisioning>
pub fn start_provisioning(self) -> Environment<Provisioning>
Transitions from Created to Provisioning state
This method consumes the environment and returns a new one in the Provisioning state, indicating that infrastructure provisioning has begun.
Sourcepub fn register(self, instance_ip: IpAddr) -> Environment<Provisioned>
pub fn register(self, instance_ip: IpAddr) -> Environment<Provisioned>
Registers an existing instance and transitions directly to Provisioned state
This is an alternative to start_provisioning() for environments that will
use existing infrastructure instead of provisioning new infrastructure.
The provision method is set to Registered to distinguish from infrastructure
created via OpenTofu.
§Arguments
instance_ip- The IP address of the existing instance
§Returns
Returns the environment in Provisioned state with:
- Instance IP set to the provided address
- Provision method set to
Registered
Source§impl Environment<Created>
impl Environment<Created>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Created> into type-erased AnyEnvironmentState
Source§impl Environment<DestroyFailed>
impl Environment<DestroyFailed>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<DestroyFailed> into type-erased AnyEnvironmentState
Source§impl Environment<Destroyed>
impl Environment<Destroyed>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Destroyed> into type-erased AnyEnvironmentState
Source§impl Environment<Destroying>
impl Environment<Destroying>
Sourcepub fn destroyed(self) -> Environment<Destroyed>
pub fn destroyed(self) -> Environment<Destroyed>
Transitions from Destroying to Destroyed state
This method indicates that infrastructure destruction completed successfully.
Sourcepub fn destroy_failed(
self,
context: DestroyFailureContext,
) -> Environment<DestroyFailed>
pub fn destroy_failed( self, context: DestroyFailureContext, ) -> Environment<DestroyFailed>
Transitions from Destroying to DestroyFailed state
This method indicates that infrastructure destruction failed. The context parameter provides structured error information including the failed step, error classification, and trace reference.
Source§impl Environment<Destroying>
impl Environment<Destroying>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Destroying> into type-erased AnyEnvironmentState
Source§impl Environment<ProvisionFailed>
impl Environment<ProvisionFailed>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<ProvisionFailed> into type-erased AnyEnvironmentState
Source§impl Environment<Provisioned>
impl Environment<Provisioned>
Sourcepub fn start_configuring(self) -> Environment<Configuring>
pub fn start_configuring(self) -> Environment<Configuring>
Transitions from Provisioned to Configuring state
This method indicates that application configuration has begun.
Source§impl Environment<Provisioned>
impl Environment<Provisioned>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Provisioned> into type-erased AnyEnvironmentState
Source§impl Environment<Provisioning>
impl Environment<Provisioning>
Sourcepub fn provisioned(
self,
instance_ip: IpAddr,
provision_method: ProvisionMethod,
) -> Environment<Provisioned>
pub fn provisioned( self, instance_ip: IpAddr, provision_method: ProvisionMethod, ) -> Environment<Provisioned>
Transitions from Provisioning to Provisioned state
This method indicates that infrastructure provisioning completed successfully.
It requires the instance IP address and provision method as proof of successful
provisioning, ensuring that an Environment<Provisioned> always has this data.
§Arguments
instance_ip- The IP address of the provisioned instanceprovision_method- How the instance was provisioned (alwaysProvisionedfor this transition)
§Returns
Returns the environment in Provisioned state with instance IP and provision method set
Sourcepub fn provision_failed(
self,
context: ProvisionFailureContext,
) -> Environment<ProvisionFailed>
pub fn provision_failed( self, context: ProvisionFailureContext, ) -> Environment<ProvisionFailed>
Transitions from Provisioning to ProvisionFailed state
This method indicates that infrastructure provisioning failed. The context parameter provides structured error information including the failed step, error classification, and trace reference.
Source§impl Environment<Provisioning>
impl Environment<Provisioning>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Provisioning> into type-erased AnyEnvironmentState
Source§impl Environment<ReleaseFailed>
impl Environment<ReleaseFailed>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<ReleaseFailed> into type-erased AnyEnvironmentState
Source§impl Environment<Released>
impl Environment<Released>
Sourcepub fn start_running_with_endpoints(
self,
service_endpoints: ServiceEndpoints,
) -> Environment<Running>
pub fn start_running_with_endpoints( self, service_endpoints: ServiceEndpoints, ) -> Environment<Running>
Transitions from Released to Running state with service endpoints
This method indicates that the application has started running and stores the service endpoints for later display.
§Arguments
service_endpoints- The URLs for all running services
Sourcepub fn start_running(self) -> Environment<Running>
pub fn start_running(self) -> Environment<Running>
Transitions from Released to Running state
This method indicates that the application has started running.
Consider using start_running_with_endpoints to also store service URLs.
Source§impl Environment<Released>
impl Environment<Released>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Released> into type-erased AnyEnvironmentState
Source§impl Environment<Releasing>
impl Environment<Releasing>
Sourcepub fn released(self) -> Environment<Released>
pub fn released(self) -> Environment<Released>
Transitions from Releasing to Released state
This method indicates that release preparation completed successfully.
Sourcepub fn release_failed(
self,
context: ReleaseFailureContext,
) -> Environment<ReleaseFailed>
pub fn release_failed( self, context: ReleaseFailureContext, ) -> Environment<ReleaseFailed>
Transitions from Releasing to ReleaseFailed state
This method indicates that release preparation failed at a specific step. The context contains detailed failure information including:
- The step that failed
- Error classification
- Timing and trace information
Source§impl Environment<Releasing>
impl Environment<Releasing>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Releasing> into type-erased AnyEnvironmentState
Source§impl Environment<RunFailed>
impl Environment<RunFailed>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<RunFailed> into type-erased AnyEnvironmentState
Source§impl Environment<Running>
impl Environment<Running>
Sourcepub fn run_failed(self, context: RunFailureContext) -> Environment<RunFailed>
pub fn run_failed(self, context: RunFailureContext) -> Environment<RunFailed>
Transitions from Running to RunFailed state
This method indicates that the application encountered a runtime failure.
§Arguments
context- Structured failure context with step info and error details
Source§impl Environment<Running>
impl Environment<Running>
Sourcepub fn into_any(self) -> AnyEnvironmentState
pub fn into_any(self) -> AnyEnvironmentState
Converts typed Environment<Running> into type-erased AnyEnvironmentState
Source§impl Environment
impl Environment
Sourcepub fn new(
name: EnvironmentName,
provider_config: ProviderConfig,
ssh_credentials: SshCredentials,
ssh_port: u16,
created_at: DateTime<Utc>,
) -> Environment<Created>
pub fn new( name: EnvironmentName, provider_config: ProviderConfig, ssh_credentials: SshCredentials, ssh_port: u16, created_at: DateTime<Utc>, ) -> Environment<Created>
Creates a new Environment with auto-generated paths and instance name
§Arguments
name- The validated environment nameprovider_config- Provider-specific configuration (LXD, Hetzner, etc.)ssh_credentials- SSH credentials for connecting to instancesssh_port- SSH port for connecting to instances
§Returns
A new Environment instance with all paths and instance name automatically generated based on the environment name.
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName, ProfileName};
use torrust_tracker_deployer_lib::domain::provider::{ProviderConfig, LxdConfig};
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("production".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/prod_rsa"),
PathBuf::from("keys/prod_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new("torrust-profile-production".to_string())?,
});
let ssh_port = 22;
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, ssh_port, created_at);
assert_eq!(environment.instance_name().as_str(), "torrust-tracker-vm-production");
assert_eq!(*environment.data_dir(), PathBuf::from("./data/production"));
assert_eq!(*environment.build_dir(), PathBuf::from("./build/production"));
§Panics
This function does not panic. All instance name generation is guaranteed to succeed for valid environment names.
Sourcepub fn create(
params: EnvironmentParams,
working_dir: &Path,
created_at: DateTime<Utc>,
) -> Result<Environment<Created>, UserInputsError>
pub fn create( params: EnvironmentParams, working_dir: &Path, created_at: DateTime<Utc>, ) -> Result<Environment<Created>, UserInputsError>
Creates a new environment in Created state from validated parameters
This is the primary factory method for creating a fully-configured
Environment aggregate. It accepts an EnvironmentParams value object
containing all validated domain inputs.
This creates absolute paths for data and build directories by using the provided working directory as the base.
§Arguments
params- Validated environment parameters (domain value object)working_dir- Base directory for data and build directoriescreated_at- Timestamp for environment creation
§Errors
Returns UserInputsError if the cross-service configuration is invalid:
GrafanaRequiresPrometheus: Grafana is configured but Prometheus is notHttpsSectionWithoutTlsServices: HTTPS section exists but no service uses TLSTlsServicesWithoutHttpsSection: Service has TLS but HTTPS section is missing
Source§impl<S> Environment<S>
impl<S> Environment<S>
Sourcepub fn start_destroying(self) -> Environment<Destroying>
pub fn start_destroying(self) -> Environment<Destroying>
Transitions from any state to Destroying state
This method can be called from any state to begin the environment destruction process. It indicates that the destroy command has started executing.
Sourcepub fn destroy(self) -> Environment<Destroyed>
pub fn destroy(self) -> Environment<Destroyed>
Transitions from any state to Destroyed state
This method can be called from any state to destroy the environment. It indicates that all infrastructure resources have been released.
Source§impl<S> Environment<S>
impl<S> Environment<S>
Sourcepub fn context(&self) -> &EnvironmentContext
pub fn context(&self) -> &EnvironmentContext
Get a reference to the environment context
Provides access to all state-independent environment data.
Sourcepub fn name(&self) -> &EnvironmentName
pub fn name(&self) -> &EnvironmentName
Returns the environment name
Sourcepub fn instance_name(&self) -> &InstanceName
pub fn instance_name(&self) -> &InstanceName
Returns the instance name for this environment
Sourcepub fn provider_config(&self) -> &ProviderConfig
pub fn provider_config(&self) -> &ProviderConfig
Returns the provider configuration for this environment
Sourcepub fn ssh_credentials(&self) -> &SshCredentials
pub fn ssh_credentials(&self) -> &SshCredentials
Returns the SSH credentials for this environment
Sourcepub fn database_config(&self) -> &DatabaseConfig
pub fn database_config(&self) -> &DatabaseConfig
Returns the database configuration for this environment
Sourcepub fn tracker_config(&self) -> &TrackerConfig
pub fn tracker_config(&self) -> &TrackerConfig
Returns the tracker configuration for this environment
Sourcepub fn admin_token(&self) -> &str
pub fn admin_token(&self) -> &str
Returns the admin token for the HTTP API
Sourcepub fn prometheus_config(&self) -> Option<&PrometheusConfig>
pub fn prometheus_config(&self) -> Option<&PrometheusConfig>
Returns the Prometheus configuration if enabled
Sourcepub fn grafana_config(&self) -> Option<&GrafanaConfig>
pub fn grafana_config(&self) -> Option<&GrafanaConfig>
Returns the Grafana configuration if enabled
Sourcepub fn backup_config(&self) -> Option<&BackupConfig>
pub fn backup_config(&self) -> Option<&BackupConfig>
Returns the Backup configuration if enabled
Sourcepub fn ssh_username(&self) -> &Username
pub fn ssh_username(&self) -> &Username
Returns the SSH username for this environment
Sourcepub fn ssh_private_key_path(&self) -> &PathBuf
pub fn ssh_private_key_path(&self) -> &PathBuf
Returns the SSH private key path for this environment
Sourcepub fn ssh_public_key_path(&self) -> &PathBuf
pub fn ssh_public_key_path(&self) -> &PathBuf
Returns the SSH public key path for this environment
Sourcepub fn instance_ip(&self) -> Option<IpAddr>
pub fn instance_ip(&self) -> Option<IpAddr>
Returns the instance IP address if available
The instance IP is populated after successful provisioning and is
None for environments that haven’t been provisioned yet.
§Returns
Some(IpAddr)if the environment has been provisionedNoneif the environment hasn’t been provisioned yet
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use std::net::{IpAddr, Ipv4Addr};
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("test".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/test_rsa"),
PathBuf::from("keys/test_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
// Before provisioning
assert_eq!(environment.instance_ip(), None);
// After provisioning (simulated)
let ip = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100));
let environment = environment.with_instance_ip(ip);
assert_eq!(environment.instance_ip(), Some(ip));
Sourcepub fn created_at(&self) -> DateTime<Utc>
pub fn created_at(&self) -> DateTime<Utc>
Returns when this environment was created
This timestamp is set when the environment is first created using the
create environment command and never changes throughout the
environment’s lifecycle.
§Returns
The UTC timestamp when the environment was created.
Sourcepub fn provision_method(&self) -> Option<ProvisionMethod>
pub fn provision_method(&self) -> Option<ProvisionMethod>
Returns the provision method for this environment
This method indicates how the infrastructure was provisioned:
Some(Provisioned): Created viaprovisioncommand usingOpenTofuSome(Registered): Connected to existing infrastructure viaregistercommandNone: Unknown or legacy state (before this field was added)
§Returns
The provision method, if set.
Sourcepub fn is_infrastructure_managed(&self) -> bool
pub fn is_infrastructure_managed(&self) -> bool
Returns whether this environment’s infrastructure is managed by this tool
Infrastructure is considered “managed” if it was created via the provision command
using OpenTofu. Managed infrastructure can be destroyed using tofu destroy.
Infrastructure is NOT managed if:
- It was registered from existing infrastructure via the
registercommand - The provision method is unknown (legacy state)
§Returns
true if the infrastructure was provisioned by this tool and can be destroyed,
false if the infrastructure is external and should not be touched.
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::environment::runtime_outputs::ProvisionMethod;
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("production".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/prod_rsa"),
PathBuf::from("keys/prod_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
// Provisioned environment - infrastructure is managed
let provisioned_env = Environment::new(env_name.clone(), provider_config.clone(), ssh_credentials.clone(), 22, created_at)
.with_provision_method(ProvisionMethod::Provisioned);
assert!(provisioned_env.is_infrastructure_managed());
// Registered environment - infrastructure is NOT managed
let registered_env = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at)
.with_provision_method(ProvisionMethod::Registered);
assert!(!registered_env.is_infrastructure_managed());
Sourcepub fn with_instance_ip(self, ip: IpAddr) -> Self
pub fn with_instance_ip(self, ip: IpAddr) -> Self
Sets the instance IP address for this environment
This method is typically called by the ProvisionCommandHandler after successfully
provisioning the infrastructure and obtaining the instance’s IP address.
§Arguments
ip- The IP address of the provisioned instance
§Returns
A new Environment instance with the IP address set
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use std::net::{IpAddr, Ipv4Addr};
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("production".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/prod_rsa"),
PathBuf::from("keys/prod_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
// Set IP after provisioning
let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 42));
let environment = environment.with_instance_ip(ip);
assert_eq!(environment.instance_ip(), Some(ip));
Sourcepub fn with_provision_method(self, method: ProvisionMethod) -> Self
pub fn with_provision_method(self, method: ProvisionMethod) -> Self
Sets the provision method and returns a new environment with the method set
This method is used to track how the infrastructure was provisioned:
Provisioned: Created viaprovisioncommand usingOpenTofuRegistered: Connected to existing infrastructure viaregistercommand
§Arguments
method- The provision method to set
§Returns
Returns the environment with the provision method set.
Sourcepub fn templates_dir(&self) -> PathBuf
pub fn templates_dir(&self) -> PathBuf
Returns the templates directory for this environment
The templates directory is located at data/{env_name}/templates/
and contains environment-specific template files.
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("staging".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/staging_rsa"),
PathBuf::from("keys/staging_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
assert_eq!(
environment.templates_dir(),
PathBuf::from("./data/staging/templates")
);
Sourcepub fn traces_dir(&self) -> PathBuf
pub fn traces_dir(&self) -> PathBuf
Returns the traces directory for this environment
The traces directory is located at data/{env_name}/traces/
and contains error trace files for failed operations.
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("production".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/prod_rsa"),
PathBuf::from("keys/prod_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
assert_eq!(
environment.traces_dir(),
PathBuf::from("./data/production/traces")
);
Sourcepub fn ansible_build_dir(&self) -> PathBuf
pub fn ansible_build_dir(&self) -> PathBuf
Returns the ansible build directory for this environment
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("dev".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/dev_rsa"),
PathBuf::from("keys/dev_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
assert_eq!(
environment.ansible_build_dir(),
PathBuf::from("./build/dev/ansible")
);
Sourcepub fn tofu_build_dir(&self) -> PathBuf
pub fn tofu_build_dir(&self) -> PathBuf
Returns the tofu build directory for this environment
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("test".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/test_rsa"),
PathBuf::from("keys/test_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
assert_eq!(
environment.tofu_build_dir(),
PathBuf::from("./build/test/tofu/lxd")
);
Sourcepub fn ansible_templates_dir(&self) -> PathBuf
pub fn ansible_templates_dir(&self) -> PathBuf
Returns the ansible templates directory for this environment
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("integration".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/integration_rsa"),
PathBuf::from("keys/integration_rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
assert_eq!(
environment.ansible_templates_dir(),
PathBuf::from("./data/integration/templates/ansible")
);
Sourcepub fn tofu_templates_dir(&self) -> PathBuf
pub fn tofu_templates_dir(&self) -> PathBuf
Returns the tofu templates directory for this environment
§Examples
use torrust_tracker_deployer_lib::domain::{Environment, EnvironmentName};
use torrust_tracker_deployer_lib::domain::provider::{LxdConfig, ProviderConfig};
use torrust_tracker_deployer_lib::domain::ProfileName;
use torrust_tracker_deployer_lib::shared::Username;
use torrust_tracker_deployer_lib::adapters::ssh::SshCredentials;
use std::path::PathBuf;
use chrono::{TimeZone, Utc};
let env_name = EnvironmentName::new("load-test".to_string())?;
let ssh_username = Username::new("torrust".to_string())?;
let ssh_credentials = SshCredentials::new(
PathBuf::from("keys/load-test-rsa"),
PathBuf::from("keys/load-test-rsa.pub"),
ssh_username,
);
let provider_config = ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new(format!("lxd-{}", env_name.as_str())).unwrap(),
});
let created_at = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let environment = Environment::new(env_name, provider_config, ssh_credentials, 22, created_at);
assert_eq!(
environment.tofu_templates_dir(),
PathBuf::from("./data/load-test/templates/tofu")
);
Trait Implementations§
Source§impl<S: Clone> Clone for Environment<S>
impl<S: Clone> Clone for Environment<S>
Source§impl<S: Debug> Debug for Environment<S>
impl<S: Debug> Debug for Environment<S>
Source§impl<'de, S> Deserialize<'de> for Environment<S>where
S: Deserialize<'de>,
impl<'de, S> Deserialize<'de> for Environment<S>where
S: Deserialize<'de>,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl From<&Environment<Configured>> for ConfigureDetailsData
Conversion from domain model to presentation DTO
impl From<&Environment<Configured>> for ConfigureDetailsData
Conversion from domain model to presentation DTO
This From trait implementation is placed in the presentation layer
(not in the domain layer) to maintain proper DDD layering:
- Domain layer should not depend on presentation layer DTOs
- Presentation layer can depend on domain models (allowed)
- This keeps the domain clean and focused on business logic
Alternative approaches considered:
- Adding method to
Environment<Configured>: Would violate DDD by making domain depend on presentation DTOs - Keeping mapping in controller: Works but less idiomatic than
Fromtrait
Source§fn from(env: &Environment<Configured>) -> Self
fn from(env: &Environment<Configured>) -> Self
Source§impl From<&Environment<Destroyed>> for DestroyDetailsData
Conversion from domain model to presentation DTO
impl From<&Environment<Destroyed>> for DestroyDetailsData
Conversion from domain model to presentation DTO
This From trait implementation is placed in the presentation layer
(not in the domain layer) to maintain proper DDD layering:
- Domain layer should not depend on presentation layer DTOs
- Presentation layer can depend on domain models (allowed)
- This keeps the domain clean and focused on business logic
Source§fn from(env: &Environment<Destroyed>) -> Self
fn from(env: &Environment<Destroyed>) -> Self
Source§impl From<&Environment<Provisioned>> for ConnectionDetailsData
Conversion from domain model to presentation DTO
impl From<&Environment<Provisioned>> for ConnectionDetailsData
Conversion from domain model to presentation DTO
This From trait implementation is placed in the presentation layer
(not in the domain layer) to maintain proper DDD layering:
- Domain layer should not depend on presentation layer DTOs
- Presentation layer can depend on domain models (allowed)
- This keeps the domain clean and focused on business logic
Alternative approaches considered:
- Adding method to
Environment<Provisioned>: Would violate DDD by making domain depend on presentation DTOs - Keeping mapping in controller: Works but less idiomatic than
Fromtrait
Source§fn from(provisioned: &Environment<Provisioned>) -> Self
fn from(provisioned: &Environment<Provisioned>) -> Self
Source§impl From<&Environment<Provisioned>> for ProvisionDetailsData
Conversion from domain model to presentation DTO
impl From<&Environment<Provisioned>> for ProvisionDetailsData
Conversion from domain model to presentation DTO
This From trait implementation is placed in the presentation layer
(not in the domain layer) to maintain proper DDD layering:
- Domain layer should not depend on presentation layer DTOs
- Presentation layer can depend on domain models (allowed)
- This keeps the domain clean and focused on business logic
Alternative approaches considered:
- Adding method to
Environment<Provisioned>: Would violate DDD by making domain depend on presentation DTOs - Keeping mapping in controller: Works but less idiomatic than
Fromtrait
Source§fn from(environment: &Environment<Provisioned>) -> Self
fn from(environment: &Environment<Provisioned>) -> Self
Source§impl From<&Environment<Released>> for ReleaseDetailsData
Conversion from domain model to presentation DTO
impl From<&Environment<Released>> for ReleaseDetailsData
Conversion from domain model to presentation DTO
This From trait implementation is placed in the presentation layer
(not in the domain layer) to maintain proper DDD layering:
- Domain layer should not depend on presentation layer DTOs
- Presentation layer can depend on domain models (allowed)
- This keeps the domain clean and focused on business logic
Alternative approaches considered:
- Adding method to
Environment<Released>: Would violate DDD by making domain depend on presentation DTOs - Keeping mapping in controller: Works but less idiomatic than
Fromtrait
Source§fn from(env: &Environment<Released>) -> Self
fn from(env: &Environment<Released>) -> Self
Source§impl From<&Environment> for EnvironmentDetailsData
Conversion from domain model to presentation DTO
impl From<&Environment> for EnvironmentDetailsData
Conversion from domain model to presentation DTO
This From trait implementation is placed in the presentation layer
(not in the domain layer) to maintain proper DDD layering:
- Domain layer should not depend on presentation layer DTOs
- Presentation layer can depend on domain models (allowed)
- This keeps the domain clean and focused on business logic
Alternative approaches considered:
- Adding method to
Environment<Created>: Would violate DDD by making domain depend on presentation DTOs - Keeping mapping in controller: Works but less idiomatic than
Fromtrait
Source§fn from(environment: &Environment<Created>) -> Self
fn from(environment: &Environment<Created>) -> Self
Auto Trait Implementations§
impl<S> Freeze for Environment<S>where
S: Freeze,
impl<S> RefUnwindSafe for Environment<S>where
S: RefUnwindSafe,
impl<S> Send for Environment<S>where
S: Send,
impl<S> Sync for Environment<S>where
S: Sync,
impl<S> Unpin for Environment<S>where
S: Unpin,
impl<S> UnsafeUnpin for Environment<S>where
S: UnsafeUnpin,
impl<S> UnwindSafe for Environment<S>where
S: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request