# Duxcore : embed an ansible-like automation engine right in your Rust code
# The goal Instead of having one big configuration management tool trying to handle all scenarios, we prefer to build one flexible automation *engine* (this crate) and make it as easy as possible to embed in a codebase, ready to be adapted to one's specific need. # Documentation A [*book*](https://www.dux-automate.org/book/) has been opened about the Dux project. Especially, modules list and documentation can be found [here](https://www.dux-automate.org/book/modules.html). # Basic example Import the crate ```shell cargo add duxcore ``` Now let's perform the usual example : **setup a webserver** (but, this time, right from your Rust code !) ```rust 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()); } ``` Output ```json { "host": "10.20.0.203", "timestamp_start": "2024-11-15T23:14:09.114229853+00:00", "timestamp_end": "2024-11-15T23:14:09.864756326+00:00", "final_status": "ApplySuccesful", "tasks": [ { "name": "Let's install a web server !", "steps": [ { "name": "First, we test the connectivity and authentication with the host.", "expected_state": { "ping": {} }, "status": "ApplySuccessful" }, { "name": "Then we can install the package...", "expected_state": { "apt": { "state": "present", "package": "apache2" } }, "status": "ApplySuccessful" }, { "name": "... and start & enable the service.", "expected_state": { "service": { "name": "apache2", "state": "started", "enabled": true } }, "status": "ApplySuccessful" }, { "name": "What date is it on this host by the way ?", "expected_state": { "command": { "content": "date +%Y-%m-%d\" \"%Hh%M" } }, "status": "ApplySuccessful" }, { "name": "Let's see...", "expected_state": { "debug": { "msg": "date: 2024-11-16 00h14\n" } }, "status": "ApplySuccessful" } ] } ] } ``` This is the basic workflow of Dux. The *Job* type, around which the whole automation revolves, is serializable/deserializable. It is then up to you to parallelize, distribute the work, display the results in some web interface or send the workload to workers via a message broker... Whatever suits you best ! To handle multiple hosts at once, use a [JobList](https://docs.rs/duxcore/latest/duxcore/job/joblist/struct.JobList.html) instead. # More examples More complex examples of how the Dux crate can be used are being built as separate projects. These are **proofs of concept** and can be used as a starting point for your own implementation. You can also start from scratch. ## Standard implementation > One binary doing everything Dux standard project : [dux-standard](https://gitlab.com/dux-tool/dux-standard)
## Agent implementation > A Dux agent running as a background service, regularly fetching a remote tasklist (http/https, git...) and applying it to itself Dux agent project : [dux-agent](https://gitlab.com/dux-tool/dux-agent)
## Distributed implementation > Workload split between a controller which generates Jobs and workers which actually run them on targetted hosts Dux distributed controller project : [dux-distributed-controller](https://gitlab.com/dux-tool/dux-distributed-controller) Dux distributed worker project : [dux-distributed-worker](https://gitlab.com/dux-tool/dux-distributed-worker)
## Scalable implementation > Workload split between a controller and workers nodes, with a message broker in the middle to allow scaling up and down the number of workers Dux scalable controller project : [dux-scalable-controller](https://gitlab.com/dux-tool/dux-scalable-controller) Dux scalable worker project : [dux-scalable-worker](https://gitlab.com/dux-tool/dux-scalable-worker)
# Contribution Want some help to use this crate for your own situation ? Open to suggestions, feedback, requests and any contribution ! Will gladly exchange ideas and help you build your own implementation right [there](https://discord.com/invite/2gxAW7uzsx) !