Skip to main content

plugin-inventory

A plugin that parses Ansible INI-format inventory files and generates Node objects from plugin-ssh. It provides node group management, variable precedence control, and parallel workflow execution.

3-Level Architecture

LevelClassRole
POJOInventoryParser, NodeGroupInventory parsing and node generation
ActorNodeGroupActorChild actor creation and parallel orchestration
InterpreterNodeGroupInterpreterIntegration with the workflow state machine

Inventory File Format

Uses Ansible-compatible INI format.

# Comments (# or ;)

[all:vars]
ansible_user=admin
ansible_port=22

[webservers:vars]
actoriac_user=deploy

[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11 ansible_port=2222

[dbservers]
db1 ansible_host=192.168.1.20

[local]
localhost ansible_connection=local

Supported Variables

The actoriac_* prefix takes priority, but compatibility with ansible_* is maintained.

actoriac_ansible_Description
actoriac_hostansible_hostActual connection hostname/IP
actoriac_useransible_userSSH username
actoriac_portansible_portSSH port number
actoriac_connectionansible_connectionConnection mode (ssh or local)

Variable Precedence

Variables are applied in order: host-specific > group > global.

[all:vars]
ansible_user=global_user # Priority: low
ansible_port=1111

[web:vars]
ansible_user=group_user # Priority: medium
ansible_port=2222

[web]
server1 ansible_user=host_user # Priority: high

In this example, server1's user is host_user and port is 2222.

When both actoriac_* and ansible_* are defined for the same variable, actoriac_* takes precedence.

Unsupported Features (with warnings)

The parser generates warning messages when it detects the following features.

FeatureWarning
:children groupsNested groups are not supported
Range patterns [01:50]Hostname range expansion is not supported
ansible_becomeRecommend using SUDO_PASSWORD environment variable
ansible_python_interpreterNot needed as it runs without Python
ansible_ssh_*Recommend using ~/.ssh/config

InventoryParser Class

A static class for parsing inventory files.

// Parse inventory from file
try (InputStream is = new FileInputStream("inventory.ini")) {
InventoryParser.ParseResult result = InventoryParser.parse(is);

if (result.hasWarnings()) {
for (String warning : result.getWarnings()) {
System.err.println("WARNING: " + warning);
}
}

InventoryParser.Inventory inv = result.getInventory();

// List hosts in a group
List<String> hosts = inv.getHosts("webservers");

// Get variables
Map<String, String> globalVars = inv.getGlobalVars();
Map<String, String> groupVars = inv.getGroupVars("webservers");
Map<String, String> hostVars = inv.getHostVars("web1");

// All groups
Map<String, List<String>> allGroups = inv.getAllGroups();
}

NodeGroup Class

A POJO that generates Node objects from inventory.

// Builder pattern
NodeGroup ng = new NodeGroup.Builder()
.withInventory(new FileInputStream("inventory.ini"))
.build();

// Generate Node list from group
List<Node> nodes = ng.createNodesForGroup("webservers");

// Node for localhost
List<Node> local = ng.createLocalNode();

// Host limiting
ng.setHostLimit("web1,web2");
List<Node> filtered = ng.createNodesForGroup("webservers");

// Set SSH password (applied to all nodes)
ng.setSshPassword("password");

// Check parse warnings
if (ng.hasParseWarnings()) {
ng.getParseWarnings().forEach(System.err::println);
}

NodeGroupActor @Action Methods

Node Management

ActionArgumentsDescription
createNodeActors["webservers"]Create child NodeActor for each host in the group
createNodeActors["local"]Create a single NodeActor for localhost
hasInventorynoneCheck if inventory is loaded

Parallel Execution

ActionArgumentsDescription
apply{"actor":"node-*", "method":"runWorkflow", "arguments":["deploy.yaml"]}Execute action in parallel on child actors matching the wildcard
executeCommandOnAllNodes["ls -la"]Execute command sequentially on all child nodes

apply uses CompletableFuture for parallel execution and returns combined results from all nodes.

Child Actor Hierarchy

The structure created by createNodeActors is as follows:

nodeGroup (NodeGroupActor)
+-- node-web1 (NodeActor wrapping NodeInterpreter)
+-- node-web2 (NodeActor wrapping NodeInterpreter)
+-- node-db1 (NodeActor wrapping NodeInterpreter)

Each child actor has an independent Node instance and manages its own SSH session.

Workflow Control

ActionArgumentsDescription
readYaml["workflow.yaml"]Load workflow YAML
execCodenoneExecute the current step's code
runUntilEnd[maxIterations]Run workflow to completion
runWorkflow["workflow.yaml", maxIterations]Load and execute

Output and State

ActionArgumentsDescription
hasAccumulatornoneCheck if outputMultiplexer is registered
getAccumulatorSummarynoneGet summary from outputMultiplexer
printSessionSummarynoneDisplay session validation result summary from log store
getSessionIdnoneGet current session ID
printJson / printYamlnoneOutput state as JSON/YAML

NodeGroupInterpreter Features

NodeGroupInterpreter wraps NodeGroup and provides the following additional features:

  • cowsay display: Shows current step with ASCII art during workflow transitions
  • Asynchronous logging: Automatic action result logging to DistributedLogStore
  • verbose mode: Displays full YAML state at each transition
  • Overlay directory: Directory for workflow configuration overrides

Plugin Dependencies

  • plugin-ssh (provided) - Uses Node class
  • plugin-log-db (provided) - Logging functionality
  • plugin-log-output (provided) - Output multiplexer