Split per O&M lane work order. Full history: KNEL/PFVCluster. https://projects.knownelement.com/issues/769#note-4152
105 lines
4.6 KiB
Bash
105 lines
4.6 KiB
Bash
#!/bin/bash
|
|
#
|
|
# to-glpi.sh — seed GLPI from the CMDB CSV + create the scoped agent user [#705]
|
|
#
|
|
# Prereqs: ~/.creds/glpi.env with GLPI_URL, GLPI_APP_TOKEN, and a VALID
|
|
# GLPI_USER_TOKEN (glpi admin). Run cmdb/seed/from-inventory.sh first
|
|
# to produce systems.csv.
|
|
#
|
|
# Usage:
|
|
# to-glpi.sh [--dry-run] [systems.csv]
|
|
#
|
|
# What it does:
|
|
# 1. initSession as the admin user token.
|
|
# 2. Creates local user 'cmdb' (Read-Only profile, random password +
|
|
# random api_token) — the scoped agent identity per Charles's ruling.
|
|
# Writes ~/.creds/glpi-agent.env (0600). Skipped if the user exists.
|
|
# 3. Imports systems.csv rows as GLPI Computers (batch; skips names that
|
|
# already exist). comment carries category/specs/ts_ip provenance.
|
|
#
|
|
set -euo pipefail
|
|
|
|
DRY=0
|
|
[ "${1:-}" = "--dry-run" ] && { DRY=1; shift; }
|
|
CSV="${1:-$(dirname "$0")/systems.csv}"
|
|
[ -r "$CSV" ] || { echo "no CSV at $CSV" >&2; exit 2; }
|
|
|
|
CREDS="${HOME}/.creds/glpi.env"
|
|
# shellcheck disable=SC1090
|
|
. "$CREDS"
|
|
: "${GLPI_URL:?}" "${GLPI_APP_TOKEN:?}" "${GLPI_USER_TOKEN:?}"
|
|
API="$GLPI_URL/apirest.php"
|
|
|
|
hdr() { printf 'Content-Type: application/json\nApp-Token: %s\nSession-Token: %s\n' "$GLPI_APP_TOKEN" "$SESSION"; }
|
|
|
|
echo "— initSession"
|
|
SESSION=$(curl -sS --max-time 20 -H "Content-Type: application/json" \
|
|
-H "App-Token: $GLPI_APP_TOKEN" \
|
|
-H "Authorization: user_token $GLPI_USER_TOKEN" \
|
|
"$API/initSession" | jq -re '.session_token')
|
|
echo " session ok (${#SESSION} chars)"
|
|
|
|
# --- 2. scoped agent user -------------------------------------------------
|
|
if curl -sS -H "$(hdr)" "$API/User?searchText%5Bname%5D=cmdb" | jq -e 'if type=="object" then (.totalcount > 0) else (length > 0) end' >/dev/null; then
|
|
echo "— user 'cmdb' already exists (skipping create)"
|
|
else
|
|
AGENT_PASS=$(head -c 24 /dev/urandom | base64 | tr -d '/+=')
|
|
AGENT_TOKEN=$(head -c 24 /dev/urandom | od -An -tx1 | tr -d ' \n')
|
|
if [ "$DRY" = "1" ]; then
|
|
echo "— DRY: would create user cmdb"
|
|
else
|
|
UID_JSON=$(curl -sS -X POST -H "$(hdr)" -d '{"input":{"name":"cmdb","realname":"CMDB agent (core-IT)","password":"'"$AGENT_PASS"'","api_token":"'"$AGENT_TOKEN"'"}}' "$API/User")
|
|
NEWUID=$(echo "$UID_JSON" | jq -r '.id // .users_id // empty')
|
|
echo " created users_id=$NEWUID"
|
|
PROF_ID=$(curl -sS -H "$(hdr)" "$API/Profile?range=0-50" | jq -r '.[] | select(.name=="Read-Only") | .id' | head -1)
|
|
[ -n "$PROF_ID" ] && curl -sS -X POST -H "$(hdr)" \
|
|
-d '{"input":{"users_id":"'"$NEWUID"'","profiles_id":"'"$PROF_ID"'","entities_id":0,"is_recursive":1}}' \
|
|
"$API/Profile_User" > /dev/null && echo " profile Read-Only ($PROF_ID) @ root entity"
|
|
umask 077
|
|
printf 'GLPI_URL=%s\nGLPI_APP_TOKEN=%s\nGLPI_USER_TOKEN=%s\n' \
|
|
"$GLPI_URL" "$GLPI_APP_TOKEN" "$AGENT_TOKEN" > "${HOME}/.creds/glpi-agent.env"
|
|
echo " agent creds written to ~/.creds/glpi-agent.env (0600)"
|
|
fi
|
|
fi
|
|
|
|
# --- 3. seed import -------------------------------------------------------
|
|
echo "— existing Computers"
|
|
EXIST=$(curl -sS -H "$(hdr)" "$API/Computer?range=0-999&is_deleted=0" | jq -r '[.[].name] | join("\n")')
|
|
|
|
# CSV -> JSON objects (pure jq; header names become keys)
|
|
jq -Rn '
|
|
def strip: gsub("^\"";"") | gsub("\"$";"");
|
|
(input | split(",") | map(strip)) as $keys |
|
|
[ inputs | split(",") | map(strip) as $v |
|
|
reduce range(0; ($keys | length)) as $i
|
|
({}; . + {($keys[$i]): ($v[$i] // "")}) ]
|
|
' "$CSV" > /tmp/glpi-rows.json
|
|
|
|
# GLPI Computer input objects; skip names already present
|
|
jq -c --arg existing "$EXIST" '
|
|
[ .[] | select(.ci_name != "") | select(.ci_name as $n | ($existing | split("\n")) | index($n) | not)]
|
|
' /tmp/glpi-rows.json > /tmp/glpi-batch.json
|
|
|
|
# Map to GLPI Computer fields
|
|
jq -c '[ .[] | {name: .ci_name,
|
|
comment: ((.category // "") + " | " + (.specs // "") + " | ts=" + (.ts_ip // "") +
|
|
" | " + (.extra // "") + " | src=" + (.source_section // "") +
|
|
" | status=" + (.status // ""))} ]' /tmp/glpi-batch.json > /tmp/glpi-input.json
|
|
mv /tmp/glpi-input.json /tmp/glpi-batch.json
|
|
|
|
TOTAL=$(jq 'length' /tmp/glpi-batch.json)
|
|
skipped=$(( $(wc -l < "$CSV") - 1 - TOTAL ))
|
|
echo "— import: $TOTAL to create, $skipped already present"
|
|
if [ "$DRY" = "1" ]; then echo "— DRY: no changes made"; exit 0; fi
|
|
|
|
# Batch-create in chunks of 25 (API limits)
|
|
SPLIT=25; i=0
|
|
while [ "$i" -lt "$TOTAL" ]; do
|
|
jq ".[$i:$((i+SPLIT))]" /tmp/glpi-batch.json > /tmp/glpi-chunk.json
|
|
curl -sS -X POST -H "$(hdr)" \
|
|
-d "$(jq -c '{input: .}' /tmp/glpi-chunk.json)" "$API/Computer" \
|
|
| jq -r 'if type=="array" then " +\(length) created" else " ERR: \(tostring)" end'
|
|
i=$((i+SPLIT))
|
|
done
|
|
echo "done — verify count via GET /Computer?range=0-200"
|