pub trait Transform: Send + Sync {
// Provided methods
fn transform_host(
&self,
host: &Host,
_options: Option<&TransformFunctionOptions>,
) -> Host { ... }
fn transform_group(
&self,
group: &Group,
_options: Option<&TransformFunctionOptions>,
) -> Group { ... }
fn transform_defaults(
&self,
defaults: &Defaults,
_options: Option<&TransformFunctionOptions>,
) -> Defaults { ... }
}Expand description
A trait for implementing custom transformation logic on inventory entities.
The Transform trait provides a flexible mechanism to modify hosts, groups, and defaults
in an inventory based on custom logic, external configuration, or runtime conditions.
Implementations of this trait can be wrapped in a TransformFunction and applied to an
inventory to dynamically alter entity properties without modifying the underlying data.
All methods in this trait have default implementations that return clones of the input entities unchanged. Implementors only need to override the methods for entity types they wish to transform.
§Thread Safety
Implementations must be Send + Sync to allow safe sharing across threads. The inventory
system uses Arc internally to share transform functions, so all transform logic must be
thread-safe.
§Transform Methods
The trait provides three transformation methods, one for each inventory entity type:
transform_host- Transforms individual host configurationstransform_group- Transforms group configurationstransform_defaults- Transforms inventory-wide defaults
Each method receives a reference to the entity being transformed and optional configuration
through TransformFunctionOptions. The methods should return a new instance of the entity
with the desired modifications applied.
§When Transforms Are Applied
Transforms are applied lazily when accessing inventory entities:
- When calling
Inventory::hosts()and accessing individual hosts - When calling
Inventory::groups()and accessing individual groups - When calling
Inventory::defaults() - During host resolution via
Inventory::resolve_host()
Results are cached for hosts and groups to improve performance on subsequent
accesses. Resolved hosts and connection parameters are also cached by
Inventory. Defaults are transformed lazily on each Inventory::defaults()
call and are not stored in a dedicated cache.
§Transform Options
The optional TransformFunctionOptions parameter provides a way to pass configuration
data to the transform function at runtime. This allows for flexible, data-driven
transformations without hardcoding values in the transform implementation.
Options are stored as JSON values and can contain any structured data needed by the
transform logic. Access the options using the get() method and JSON value accessors.
§Examples
§Basic Host Transform
struct PortTransform {
default_port: u16,
}
impl Transform for PortTransform {
fn transform_host(&self, host: &Host, _options: Option<&TransformFunctionOptions>) -> Host {
// Apply default port if host doesn't have one
if host.port().is_none() {
host.to_builder()
.port(self.default_port)
.build()
} else {
host.clone()
}
}
}
let transform = TransformFunction::new_full(PortTransform { default_port: 2222 });§Transform Using Options
struct PrefixTransform;
impl Transform for PrefixTransform {
fn transform_host(&self, host: &Host, options: Option<&TransformFunctionOptions>) -> Host {
// Get prefix from options
let prefix = options
.and_then(|opts| opts.get("hostname_prefix"))
.and_then(|v| v.as_str())
.unwrap_or("");
if !prefix.is_empty() {
if let Some(hostname) = host.hostname() {
return host.to_builder()
.hostname(format!("{}{}", prefix, hostname))
.build();
}
}
host.clone()
}
}
let transform = TransformFunction::new_full(PrefixTransform);
let options = TransformFunctionOptions::new(
serde_json::json!({"hostname_prefix": "prod-"})
);§Multi-Entity Transform
struct EnvironmentTransform {
environment: String,
}
impl Transform for EnvironmentTransform {
fn transform_host(&self, host: &Host, _options: Option<&TransformFunctionOptions>) -> Host {
// Add environment tag to hostname
if let Some(hostname) = host.hostname() {
host.to_builder()
.hostname(format!("{}.{}", hostname, self.environment))
.build()
} else {
host.clone()
}
}
fn transform_group(&self, group: &Group, _options: Option<&TransformFunctionOptions>) -> Group {
// Apply environment-specific group settings
if self.environment == "prod" {
// Production groups might need different settings
group.to_builder()
.port(443)
.build()
} else {
group.clone()
}
}
fn transform_defaults(&self, defaults: &Defaults, _options: Option<&TransformFunctionOptions>) -> Defaults {
// Apply environment-specific defaults
defaults.to_builder()
.username(format!("{}-user", self.environment))
.build()
}
}
let transform = TransformFunction::new_full(EnvironmentTransform {
environment: "prod".to_string(),
});§IP Address Mapping Transform
struct IpMappingTransform;
impl Transform for IpMappingTransform {
fn transform_host(&self, host: &Host, options: Option<&TransformFunctionOptions>) -> Host {
// Get IP mapping from options
let mapping = options
.and_then(|opts| opts.get("ip_map"))
.and_then(|v| v.as_object());
let Some(mapping) = mapping else {
return host.clone();
};
let mut builder = host.to_builder();
// Map hostname if it exists in the mapping
if let Some(hostname) = host.hostname() {
if let Some(mapped) = mapping.get(hostname).and_then(|v| v.as_str()) {
builder = builder.hostname(mapped);
}
}
builder.build()
}
}
let transform = TransformFunction::new_full(IpMappingTransform);
let options = TransformFunctionOptions::new(serde_json::json!({
"ip_map": {
"10-0-0-1": "10.0.0.1",
"10-0-0-2": "10.0.0.2"
}
}));Provided Methods§
Sourcefn transform_host(
&self,
host: &Host,
_options: Option<&TransformFunctionOptions>,
) -> Host
fn transform_host( &self, host: &Host, _options: Option<&TransformFunctionOptions>, ) -> Host
Transforms a host entity.
This method is called when a host is accessed through the inventory’s host view or during host resolution. The default implementation returns a clone of the input host unchanged.
§Parameters
host- A reference to the host being transformed_options- Optional configuration data for the transform
§Returns
Returns a new Host instance with the desired transformations applied.
Sourcefn transform_group(
&self,
group: &Group,
_options: Option<&TransformFunctionOptions>,
) -> Group
fn transform_group( &self, group: &Group, _options: Option<&TransformFunctionOptions>, ) -> Group
Transforms a group entity.
This method is called when a group is accessed through the inventory’s group view. The default implementation returns a clone of the input group unchanged.
§Parameters
group- A reference to the group being transformed_options- Optional configuration data for the transform
§Returns
Returns a new Group instance with the desired transformations applied.
Sourcefn transform_defaults(
&self,
defaults: &Defaults,
_options: Option<&TransformFunctionOptions>,
) -> Defaults
fn transform_defaults( &self, defaults: &Defaults, _options: Option<&TransformFunctionOptions>, ) -> Defaults
Transforms the inventory defaults.
This method is called when defaults are accessed through Inventory::defaults().
The default implementation returns a clone of the input defaults unchanged.
§Parameters
defaults- A reference to the defaults being transformed_options- Optional configuration data for the transform
§Returns
Returns a new Defaults instance with the desired transformations applied.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".