Skip to main content

Environment

Struct Environment 

Source
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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<ConfigureFailed> into type-erased AnyEnvironmentState

Source§

impl Environment<Configured>

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Configured> into type-erased AnyEnvironmentState

Source§

impl Environment<Configuring>

Source

pub fn configured(self) -> Environment<Configured>

Transitions from Configuring to Configured state

This method indicates that application configuration completed successfully.

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Configuring> into type-erased AnyEnvironmentState

Source§

impl Environment<Created>

Source

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.

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Created> into type-erased AnyEnvironmentState

Source§

impl Environment<DestroyFailed>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<DestroyFailed> into type-erased AnyEnvironmentState

Source§

impl Environment<Destroyed>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Destroyed> into type-erased AnyEnvironmentState

Source§

impl Environment<Destroying>

Source

pub fn destroyed(self) -> Environment<Destroyed>

Transitions from Destroying to Destroyed state

This method indicates that infrastructure destruction completed successfully.

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Destroying> into type-erased AnyEnvironmentState

Source§

impl Environment<ProvisionFailed>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<ProvisionFailed> into type-erased AnyEnvironmentState

Source§

impl Environment<Provisioned>

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Provisioned> into type-erased AnyEnvironmentState

Source§

impl Environment<Provisioning>

Source

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 instance
  • provision_method - How the instance was provisioned (always Provisioned for this transition)
§Returns

Returns the environment in Provisioned state with instance IP and provision method set

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Provisioning> into type-erased AnyEnvironmentState

Source§

impl Environment<ReleaseFailed>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<ReleaseFailed> into type-erased AnyEnvironmentState

Source§

impl Environment<Released>

Source

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
Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Released> into type-erased AnyEnvironmentState

Source§

impl Environment<Releasing>

Source

pub fn released(self) -> Environment<Released>

Transitions from Releasing to Released state

This method indicates that release preparation completed successfully.

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Releasing> into type-erased AnyEnvironmentState

Source§

impl Environment<RunFailed>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<RunFailed> into type-erased AnyEnvironmentState

Source§

impl Environment<Running>

Source

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>

Source

pub fn into_any(self) -> AnyEnvironmentState

Converts typed Environment<Running> into type-erased AnyEnvironmentState

Source§

impl Environment

Source

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 name
  • provider_config - Provider-specific configuration (LXD, Hetzner, etc.)
  • ssh_credentials - SSH credentials for connecting to instances
  • ssh_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.

Source

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 directories
  • created_at - Timestamp for environment creation
§Errors

Returns UserInputsError if the cross-service configuration is invalid:

  • GrafanaRequiresPrometheus: Grafana is configured but Prometheus is not
  • HttpsSectionWithoutTlsServices: HTTPS section exists but no service uses TLS
  • TlsServicesWithoutHttpsSection: Service has TLS but HTTPS section is missing
Source§

impl<S> Environment<S>

Source

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.

Source

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>

Source

pub fn context(&self) -> &EnvironmentContext

Get a reference to the environment context

Provides access to all state-independent environment data.

Source

pub fn state(&self) -> &S

Returns a reference to the current state

Source

pub fn name(&self) -> &EnvironmentName

Returns the environment name

Source

pub fn instance_name(&self) -> &InstanceName

Returns the instance name for this environment

Source

pub fn provider_config(&self) -> &ProviderConfig

Returns the provider configuration for this environment

Source

pub fn ssh_credentials(&self) -> &SshCredentials

Returns the SSH credentials for this environment

Source

pub fn ssh_port(&self) -> u16

Returns the SSH port for this environment

Source

pub fn database_config(&self) -> &DatabaseConfig

Returns the database configuration for this environment

Source

pub fn tracker_config(&self) -> &TrackerConfig

Returns the tracker configuration for this environment

Source

pub fn admin_token(&self) -> &str

Returns the admin token for the HTTP API

Source

pub fn prometheus_config(&self) -> Option<&PrometheusConfig>

Returns the Prometheus configuration if enabled

Source

pub fn grafana_config(&self) -> Option<&GrafanaConfig>

Returns the Grafana configuration if enabled

Source

pub fn backup_config(&self) -> Option<&BackupConfig>

Returns the Backup configuration if enabled

Source

pub fn ssh_username(&self) -> &Username

Returns the SSH username for this environment

Source

pub fn ssh_private_key_path(&self) -> &PathBuf

Returns the SSH private key path for this environment

Source

pub fn ssh_public_key_path(&self) -> &PathBuf

Returns the SSH public key path for this environment

Source

pub fn build_dir(&self) -> &PathBuf

Returns the build directory for this environment

Source

pub fn data_dir(&self) -> &PathBuf

Returns the data directory for this environment

Source

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 provisioned
  • None if 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));
Source

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.

Source

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 via provision command using OpenTofu
  • Some(Registered): Connected to existing infrastructure via register command
  • None: Unknown or legacy state (before this field was added)
§Returns

The provision method, if set.

Source

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 register command
  • 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());
Source

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));
Source

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 via provision command using OpenTofu
  • Registered: Connected to existing infrastructure via register command
§Arguments
  • method - The provision method to set
§Returns

Returns the environment with the provision method set.

Source

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")
);
Source

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")
);
Source

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")
);
Source

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")
);
Source

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")
);
Source

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>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<S: Debug> Debug for Environment<S>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

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>,

Deserialize this value from the given Serde deserializer. Read more
Source§

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 From trait
Source§

fn from(env: &Environment<Configured>) -> Self

Converts to this type from the input type.
Source§

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

Converts to this type from the input type.
Source§

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 From trait
Source§

fn from(provisioned: &Environment<Provisioned>) -> Self

Converts to this type from the input type.
Source§

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 From trait
Source§

fn from(environment: &Environment<Provisioned>) -> Self

Converts to this type from the input type.
Source§

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 From trait
Source§

fn from(env: &Environment<Released>) -> Self

Converts to this type from the input type.
Source§

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 From trait
Source§

fn from(environment: &Environment<Created>) -> Self

Converts to this type from the input type.
Source§

impl<S> Serialize for Environment<S>
where S: Serialize,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> IntoResult<T> for T

Source§

type Err = !

Source§

fn into_result(self) -> Result<T, <T as IntoResult<T>>::Err>

Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more