added docs
This commit is contained in:
+286
@@ -0,0 +1,286 @@
|
||||
# AIM Installation Guide
|
||||
|
||||
This guide installs AIM with `/etc/ansible/scripts` as the project root.
|
||||
|
||||
## Layout
|
||||
|
||||
``` text
|
||||
/etc/ansible/scripts/
|
||||
├── pyproject.toml
|
||||
└── src/
|
||||
└── aim/
|
||||
|
||||
/etc/ansible/.venv/
|
||||
/usr/local/bin/aim -> /etc/ansible/.venv/bin/aim
|
||||
```
|
||||
|
||||
The virtual environment is intentionally not stored in Git.
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
On Debian/Ubuntu:
|
||||
|
||||
``` bash
|
||||
sudo apt update
|
||||
sudo apt install -y python3 python3-venv python3-pip
|
||||
```
|
||||
|
||||
## 2. Rebuild the virtual environment
|
||||
|
||||
``` bash
|
||||
sudo rm -rf /etc/ansible/.venv
|
||||
sudo python3 -m venv /etc/ansible/.venv
|
||||
sudo /etc/ansible/.venv/bin/python -m pip install --upgrade pip setuptools wheel
|
||||
```
|
||||
|
||||
## 3. Install AIM
|
||||
|
||||
``` bash
|
||||
sudo /etc/ansible/.venv/bin/python -m pip install -e /etc/ansible/scripts
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
``` bash
|
||||
ls -l /etc/ansible/.venv/bin/aim
|
||||
/etc/ansible/.venv/bin/python -m pip check
|
||||
```
|
||||
|
||||
## 4. Restore the system-wide command
|
||||
|
||||
``` bash
|
||||
sudo ln -sfn /etc/ansible/.venv/bin/aim /usr/local/bin/aim
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
``` bash
|
||||
ls -l /usr/local/bin/aim
|
||||
aim --version
|
||||
```
|
||||
|
||||
## 5. Authorization group / using another GID
|
||||
|
||||
AIM authorization is group-based rather than root-based. The default
|
||||
required group is:
|
||||
|
||||
``` text
|
||||
srv_debsansible01_admins@bitformer.lan
|
||||
```
|
||||
|
||||
AIM resolves the configured **group name** through the operating
|
||||
system's NSS layer (for example local groups, SSSD or winbind). The
|
||||
operator must have that group active as a primary or supplementary
|
||||
group.
|
||||
|
||||
Do not hard-code a numeric GID into AIM merely because a particular
|
||||
server uses a different GID. Numeric GIDs can differ between systems;
|
||||
configure the appropriate group name and let NSS resolve its GID.
|
||||
|
||||
Inspect the default group and its resolved GID:
|
||||
|
||||
``` bash
|
||||
getent group 'srv_debsansible01_admins@bitformer.lan'
|
||||
```
|
||||
|
||||
Check the current user's active groups/GIDs:
|
||||
|
||||
``` bash
|
||||
id
|
||||
id -G
|
||||
id -Gn
|
||||
```
|
||||
|
||||
If another authorization group should be used, change AIM's **Required
|
||||
Group** through:
|
||||
|
||||
``` text
|
||||
Global Config
|
||||
└── Required Group
|
||||
```
|
||||
|
||||
For example, if the local/AD-backed group is:
|
||||
|
||||
``` text
|
||||
ansible_operators
|
||||
```
|
||||
|
||||
verify it first:
|
||||
|
||||
``` bash
|
||||
getent group ansible_operators
|
||||
```
|
||||
|
||||
Then configure `ansible_operators` as AIM's Required Group. AIM will use
|
||||
the GID returned by NSS for that group.
|
||||
|
||||
After adding a user to a group, the login session may need to be renewed
|
||||
before the supplementary group becomes active. Verify with `id` before
|
||||
troubleshooting AIM authorization.
|
||||
|
||||
### Same group name, different GID
|
||||
|
||||
This is supported. For example, one server may resolve:
|
||||
|
||||
``` text
|
||||
ansible_operators:x:1200:...
|
||||
```
|
||||
|
||||
and another may resolve:
|
||||
|
||||
``` text
|
||||
ansible_operators:x:48001:...
|
||||
```
|
||||
|
||||
AIM should be configured with `ansible_operators`, not `1200` or
|
||||
`48001`.
|
||||
|
||||
### Different group name
|
||||
|
||||
Configure the alternative group name in AIM Global Config and confirm:
|
||||
|
||||
``` bash
|
||||
getent group '<group-name>'
|
||||
id
|
||||
```
|
||||
|
||||
If `getent` cannot resolve the group, fix NSS/SSSD/winbind/local group
|
||||
resolution first.
|
||||
|
||||
## 6. Git-ignored runtime data
|
||||
|
||||
Important ignored data includes:
|
||||
|
||||
``` gitignore
|
||||
.vscode/*
|
||||
.venv/*
|
||||
.ansible/*
|
||||
secure/*
|
||||
secure/keys/*
|
||||
vault.yml
|
||||
.ssh
|
||||
*.msi
|
||||
*.deb
|
||||
*.rpm
|
||||
**/.hosts.tsv
|
||||
**/hosts.yml.aim-session.bak
|
||||
**/hosts.aim-session.bak.yml
|
||||
*.bak
|
||||
```
|
||||
|
||||
For AIM inventory recovery, the critical persistent data is `vault.yml`
|
||||
and inventory `.ssh/` content. Do not restore `.venv`; rebuild it.
|
||||
|
||||
## 7. Recover missing Vaults and SSH keys
|
||||
|
||||
Example restored backup:
|
||||
|
||||
``` text
|
||||
/etc/ansible/inventories_RESTORED_20260915_152127
|
||||
```
|
||||
|
||||
Active inventories:
|
||||
|
||||
``` text
|
||||
/etc/ansible/inventories
|
||||
```
|
||||
|
||||
### Dry run
|
||||
|
||||
``` bash
|
||||
BACKUP="/etc/ansible/inventories_RESTORED_20260915_152127"
|
||||
TARGET="/etc/ansible/inventories"
|
||||
|
||||
echo "=== vault.yml ==="
|
||||
sudo find "$BACKUP" -type f -name 'vault.yml' -print0 |
|
||||
while IFS= read -r -d '' src; do
|
||||
rel="${src#"$BACKUP"/}"
|
||||
dst="$TARGET/$rel"
|
||||
if [ -e "$dst" ]; then
|
||||
echo "KEEP $dst"
|
||||
else
|
||||
echo "RESTORE $src -> $dst"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "=== .ssh files ==="
|
||||
sudo find "$BACKUP" -path '*/.ssh/*' -type f -print0 |
|
||||
while IFS= read -r -d '' src; do
|
||||
rel="${src#"$BACKUP"/}"
|
||||
dst="$TARGET/$rel"
|
||||
if [ -e "$dst" ]; then
|
||||
echo "KEEP $dst"
|
||||
else
|
||||
echo "RESTORE $src -> $dst"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### Restore
|
||||
|
||||
``` bash
|
||||
BACKUP="/etc/ansible/inventories_RESTORED_20260915_152127"
|
||||
TARGET="/etc/ansible/inventories"
|
||||
|
||||
sudo find "$BACKUP" -type f -name 'vault.yml' -print0 |
|
||||
while IFS= read -r -d '' src; do
|
||||
rel="${src#"$BACKUP"/}"
|
||||
dst="$TARGET/$rel"
|
||||
if [ -e "$dst" ]; then
|
||||
echo "KEEP $dst"
|
||||
continue
|
||||
fi
|
||||
sudo mkdir -p "$(dirname "$dst")"
|
||||
sudo cp -a "$src" "$dst"
|
||||
echo "RESTORED $dst"
|
||||
done
|
||||
|
||||
sudo find "$BACKUP" -path '*/.ssh/*' -type f -print0 |
|
||||
while IFS= read -r -d '' src; do
|
||||
rel="${src#"$BACKUP"/}"
|
||||
dst="$TARGET/$rel"
|
||||
if [ -e "$dst" ]; then
|
||||
echo "KEEP $dst"
|
||||
continue
|
||||
fi
|
||||
sudo mkdir -p "$(dirname "$dst")"
|
||||
sudo cp -a "$src" "$dst"
|
||||
echo "RESTORED $dst"
|
||||
done
|
||||
```
|
||||
|
||||
`cp -a` preserves ownership, permissions and timestamps. Existing active
|
||||
files are never overwritten.
|
||||
|
||||
Verify:
|
||||
|
||||
``` bash
|
||||
sudo find /etc/ansible/inventories -type f -name 'vault.yml' -print | sort
|
||||
sudo find /etc/ansible/inventories -path '*/.ssh/*' -type f -print | sort
|
||||
sudo find /etc/ansible/inventories -path '*/.ssh/*' -type f -exec ls -l {} \;
|
||||
```
|
||||
|
||||
Keep the restored backup until Vault and SSH access have been tested.
|
||||
|
||||
## 8. Final verification
|
||||
|
||||
``` bash
|
||||
aim --version
|
||||
/etc/ansible/.venv/bin/python -m pip check
|
||||
aim
|
||||
```
|
||||
|
||||
## Updating AIM
|
||||
|
||||
AIM is installed editable from `/etc/ansible/scripts`.
|
||||
|
||||
If its entry point needs recreation:
|
||||
|
||||
``` bash
|
||||
sudo /etc/ansible/.venv/bin/python -m pip install -e /etc/ansible/scripts
|
||||
sudo ln -sfn /etc/ansible/.venv/bin/aim /usr/local/bin/aim
|
||||
```
|
||||
|
||||
Customer data under `/etc/ansible/inventories` is separate from the AIM
|
||||
source installation.
|
||||
Reference in New Issue
Block a user