Enjoin Plugins¶
Enjoin plugins apply system state configuration based on HERY entity declarations. Each plugin is a fat plugin — it contains multiple OS-aware backends and selects the right one at runtime based on the OS/Preference entity or auto-detection.
Plugin Inventory¶
| Plugin | Manages | Backends | Entity |
|---|---|---|---|
enjoin-user |
Users, groups, sudoers | useradd, groupadd | User |
enjoin-service |
System services | systemctl, init.d, rc-service | Service |
enjoin-firewall |
Firewall rules | ufw, iptables, nftables, firewalld | Security/Firewall |
enjoin-cron |
Scheduled tasks | crontab, systemd timers | Cron |
enjoin-network |
Network config | ip, nmcli, netplan, ifupdown | System/Network |
enjoin-filesystem |
Mounts, fstab | mount, fstab, tmpfs | System/Filesystem |
enjoin-certificate |
TLS certificates | certbot, openssl, mkcert | Security/Certificate |
enjoin-selinux |
SELinux policies | semanage, setsebool, restorecon | — |
enjoin-apparmor |
AppArmor profiles | aa-enforce, aa-complain | — |
enjoin-sysctl |
Kernel parameters | sysctl.conf | — |
Protocol¶
Enjoin plugins follow the standard Plugin Protocol:
# Plugin metadata — declares which entity types are supported
enjoin-user info
# {"name": "enjoin-user", "version": "1.0.0", "supports": ["amadla.org/entity/user@^v1.0.0"], ...}
# Apply system state (file or stdin)
enjoin-user apply -f users.yaml
# {"success": true, "status": "applied", "changes": [...]}
# Dry-run validation
enjoin-user validate -f users.yaml
# {"success": true, "status": "valid", "changes": [...]}
# Exit codes: 0 = success, 1 = failure, 2 = usage error
Backend Selection¶
Each fat plugin selects its backend at runtime:
- OS/Preference entity — explicit declaration (e.g.,
firewall: firewalld) - Runtime detection — probes PATH for available tools (fallback if no OS entity)
- Mismatch warning — if entity declares firewalld but system has ufw, warn/error
Example: enjoin-service detects:
systemctlon PATH → systemd backendrc-serviceon PATH → OpenRC backend- Neither → SysV init backend (
service,update-rc.d)
Go Framework (Optional)¶
LibraryEnjoinFramework provides convenience wrappers for Go plugin authors:
- Standard
apply/validatesubcommands with entity input handling - JSON result output with status and change details
-o table|json|yamldisplay formatting- UNIX exit code protocol
Plugins can also be written in any language — just implement the protocol.
Active Plugins¶
enjoin-user¶
Manages system users and groups.
- Repo: AmadlaOrg/enjoin-user
- Entity: User
- Backends:
useradd/usermod/userdel,groupadd/groupmod/groupdel - Features: UID/GID assignment, supplementary groups, shell, home directory, system accounts, sudoers
# Example input
users:
- name: deploy
shell: /bin/bash
groups: [docker, sudo]
sudoer: true
groups:
- name: deploy
enjoin-service¶
Manages system services (start, stop, enable, disable, restart).
- Repo: AmadlaOrg/enjoin-service
- Entity: Service
- Backends: systemd (
systemctl), SysV (service/update-rc.d), OpenRC (rc-service/rc-update) - Features: State management (started/stopped/restarted), enable/disable at boot
# Example input
services:
- name: nginx
state: started
enabled: true
- name: apache2
state: stopped
enabled: false
enjoin-firewall¶
Manages firewall rules and default policies.
- Repo: AmadlaOrg/enjoin-firewall
- Entity: Security/Firewall
- Backends: ufw, firewalld (
firewall-cmd), nftables (nft), iptables - Features: Default policy (allow/deny), per-rule action/direction/protocol/port, source/destination filtering
# Example input
default_policy: deny
rules:
- action: allow
direction: in
protocol: tcp
port: "443"
comment: "HTTPS"
- action: allow
direction: in
protocol: tcp
port: "22"
from: "10.0.0.0/8"
comment: "SSH from internal"