Adapt the tool to the job.

Dux is a configuration management tool turned into a library. Flexible and embeddable, it lets developpers build their own ansible-like automation tool and smoothly integrate it in their already-existing infrastructure.

Documentation

Key points.

What do we have in mind while building Dux.

Simplicity for the developper

No internal logger, runtime, multi-threading... Just a simple workflow controlled by the developer. It is then up to him to parallelize, split the work as he sees fit...

Simplicity for the end user

Task lists and Host lists are using the well-known YAML format. Syntax is close to Ansible's and we try to keep it as self-explanatory as possible.

Rust powered

Dux is written in Rust wit no unsafe code, leveraging its type system and performance to be the most efficient possible.

For the developer

Usage

Import the crate

cargo add duxcore

Now let's perform the usual example : turn a host into a webserver (but, this time, right from your Rust code !)

use duxcore::prelude::*;

fn main() {

	// First we need to define what the expected state of the target host is.
	let my_tasklist = r#"---
- name: Let's install a web server !
	steps:
	- name: First, we test the connectivity and authentication with the host.
		ping:
		
	- name: Then we can install the package...
		with_sudo: true
		apt:
		package: '{{ package_name }}'
		state: present
		
	- name: ... and start & enable the service.
		with_sudo: true
		service:
		name: '{{ service_name }}'
		state: started
		enabled: true

	- name: What date is it on this host by the way ?
		register: host_date
		command:
		content: date +%Y-%m-%d" "%Hh%M

	- name: Let's see...
		debug:
		msg: 'date: {{ host_date.output }}'
		"#;

	// Then we create a 'Job'.
	let mut my_job = Job::new();

	// We set who the target host of this Job is, and how to connect to it.
	my_job
		.set_address("10.20.0.203")
		.set_connection(HostConnectionInfo::ssh2_with_key_file("dux", "./controller_key")).unwrap();
	
	// We give it some context and the task list.
	my_job
		.add_var("package_name", "apache2")
		.add_var("service_name", "apache2")
		.set_tasklist_from_str(my_tasklist, TaskListFileType::Yaml).unwrap()
	;
	// We can finally apply the task list to this host.
	my_job.apply();

	// Let's see the result.
	println!("{}", my_job.display_pretty());
}

For the end user

If you build a Dux-based automation tool, your end-users will only have to worry about HostLists and TaskLists. Their syntax is as follows.

Host list

On which hosts shall the automation apply ?

---
vars:
  web_server: apache2

hosts:
  - 10.12.14.18
  - www2.mycompany.com

Task list

What is the expected state of these hosts ?

---
- name: Prerequisites
  steps:
    - name: Connectivity check
        ping:
    - name: Install web server
	  with_sudo: true
        apt:
          package: "{{ web_server }}"
          state: present
    - name: Disable apache service without stopping it
      with_sudo: true
        service:
          name: apache2
          enabled: false

Examples.

The following projects are proofs of concept of how Dux can be implemented in very different scenarios.

Agent

A Dux agent running as a background service, regularly fetching a remote tasklist (http/https, git...) and applying it to itself.

Download

Yours

What situation are you dealing with ? Let's integrate automation in your infrastructure without having to rethink everything.

Let's get in touch !