diff --git a/tools/python_utils/__pycache__/app.cpython-312.pyc b/tools/python_utils/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000..72dd69d Binary files /dev/null and b/tools/python_utils/__pycache__/app.cpython-312.pyc differ diff --git a/tools/python_utils/app.py b/tools/python_utils/app.py new file mode 100644 index 0000000..28e3174 --- /dev/null +++ b/tools/python_utils/app.py @@ -0,0 +1,51 @@ +from flask import Flask, send_from_directory, abort, request +import json +import requests +import os +app = Flask(__name__) + +def pretty_print_POST(req): + """ + At this point it is completely built and ready + to be fired; it is "prepared". + + However pay attention at the formatting used in + this function because it is programmed to be pretty + printed and may differ from the actual request. + """ + print('{}\n{}\r\n{}\r\n\r\n{}'.format( + '-----------START-----------', + req.method + ' ' + req.url, + '\r\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()), + req.body, + )) + +FILES_DIR = os.path.join(os.path.dirname(__file__), "files") +@app.route('/snipe_api') +def home(): + return "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiMmU3YmJhZTEwZjM1NThhNTQ2MzZmNTRiYjhiNzQ1NmRhNDRiZDAyNWJlZTNmZjFkZTAxZTI3NzZiNjEwODQ5MDRkNGRkYjE3Njg5ZDYyMjYiLCJpYXQiOjE3MzA1NTQxMzguMTAwMzAyLCJuYmYiOjE3MzA1NTQxMzguMTAwMzE0LCJleHAiOjIzNjE3MDYxMzcuOTkwMzQ0LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.rFVnJo5E-UHW-Z4fQ639xBXq9zroAGmPQSkm1Z6iVir-8NAm-AJy-_UZLH32IG9_aT9CGJZc6_hyCRisEhm2PIAvQ0ejUzZb8atNfD3bhMEp4DwjNZtsonO6xP8Mi4YXuscWuyxNAlg7svm53bAl3mop_S2jeOEQ5DM_RhjpYxy1VMvs3diiN7W6U-WDgznMl9FLQ7TFHQ8w8g3zCbIrI5PEeKn05525sQcvgonlo1hjEe5L2gcUCV5dvXnZHnyCaZcrCcuhmZM0Xy4_ZiK5EtFvKKm4BFprnis1pT9xEdv5QzRk-IJYrFkIcAZzha7sVGShln8HzyhTE27oq1wsUgBKY4J_VQhyc4343_n3eofAOrTSRbnsMNjZE0Vy7wUVw8snOVoz56T_AYa7IKtBuv0CBGS2XLVNERer-rkJtPLTVGPC9Ck0vKfO202klRlkPgfl_HeYMIDxBwDwY6dZSoNPPG1hPSTFFv74zkSz3AsxyKmD5QOp90tuclvpINTxghRhbpHSBl1TV4XRY9rbmQ9Wo40A7XRsSUGrh-SDErLp6J5Taa9rXrxaIVs5oFZA8ehaRcZlZRm-uiJXbgd7gHhWSNdqnZ1kbPGJwsXvGI8JTAL04LSd3moWyx3TCoP2yCLAdAqPoOe35RK76IWSpZ1Et-yKzYwPMHlsKiYLjCA" + +@app.route('/download_late_command') +def download_file(): + try: + return send_from_directory(FILES_DIR, "late_command.sh", as_attachment=True) + except FileNotFoundError: + abort(404, description="File not found") + +@app.route('/preseed.cfg') +def download_pre(): + try: + return send_from_directory(FILES_DIR, "preseed.cfg", as_attachment=True) + except FileNotFoundError: + abort(404, description="File not found") + +@app.route('/print', methods=['POST']) +def print_label(): + url = "http://10.200.4.12:8000/label" + data = request.get_json() + label = requests.post(url,data=json.dumps(data)).content + print(label) + return "{Success}" + +if __name__ == '__main__': + app.run(debug=True) diff --git a/tools/python_utils/files/check_result.json b/tools/python_utils/files/check_result.json new file mode 100644 index 0000000..09fd90a --- /dev/null +++ b/tools/python_utils/files/check_result.json @@ -0,0 +1 @@ +{"error":"Unauthorized or unauthenticated."} \ No newline at end of file diff --git a/tools/python_utils/files/late_command.sh b/tools/python_utils/files/late_command.sh new file mode 100644 index 0000000..2464883 --- /dev/null +++ b/tools/python_utils/files/late_command.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +api_key=$(curl -s http://localhost:5000/snipe_api) + +# CPU Model +category=`hostnamectl | grep Chassis | cut -c 21-` +cpu_model=`cat /proc/cpuinfo | grep 'model name' | uniq | cut -c14-39 | sed -e 's/([^()]*)//g' | tr -d ' ' | cut -c -12` +# OS Distribution and Version +if [ -f /etc/os-release ]; then + . /etc/os-release + os_distro="$NAME" + os_version="$VERSION" +else + os_distro="Unknown" + os_version="Unknown" +fi + +# Total RAM +total_ram=$(free -h | awk '/^Mem:/ { print $2 }') + +# Free space on root (/) +free_space=$(df -h / | awk 'NR==2 { print $4 }') + +if [[ $category = "laptop" || $category = "notebook" ]]; then + model=2 + battery=`acpi -V | grep '^Battery.*%$' | tail -c 4` + display=`xrandr | awk '/ connected/{print sqrt( ($(NF-2)/10)^2 + ($NF/10)^2 )/2.54}' | cut -c -2 | head -n 1` + else + model=1 +fi +# You can now use these variables as needed +# For example, to print them later: + +if [[ $(lsblk | grep sr0) ]]; then + odd=ja +else + odd=nein +fi + +mac=`ip link | sed -n "/BROADCAST.*state UP/{n;p}" | tail -1 | tr -s " " | cut -d" " -f3` +serialno=`sudo dmidecode -s system-serial-number` +name=`echo $os_distro/$os_version/$cpu/$total_ram/$free_space` + +echo $name +post_data() { + cat << EOF +{ + "status_id": "2", + "name": "$name", + "model_id": "$model", + "serial": "$serialno", + "_snipeit_mac_address_1": "$mac", + "_snipeit_betriebssystem_2": "$os_distro $os_version", + "_snipeit_festplatte_4": "$free_space", + "_snipeit_prozessor_5": "$cpu_model", + "_snipeit_arbeitsspeicher_6": "$total_ram", + "_snipeit_optisches_laufwerk_7": "$odd", + "_snipeit_display_8": "$display", + "_snipeit_akku_9": "$battery", + "_snipeit_anydeskid_10": "$anydeskid" +} +EOF +} + +curl --request GET \ + --url 'https://computer.z31.it/api/v1/hardware?limit=5&search='$mac'' \ + --header 'accept: application/json' \ + --header 'authorization: Bearer '$api_key'' \ + --header 'content-type: application/x-www-form-urlencoded' > ./check_result.json + +asset_tag=$(jq -j .rows[].asset_tag ./check_result.json) + +if [ ! -z ${asset_tag} ] +then + zenity --info --text "Der Rechner ist ist bereits eingetragen RE${asset_tag}" --width=500 --height=200 + #echo " Der Rechner ist bereits eingetragen RE${asset_tag}" + exit 0 +fi + +curl --request POST \ + --url https://orga.z31.it/api/v1/hardware \ + --header 'accept: application/json' \ + --header 'authorization: Bearer '$api_key'' \ + --header 'Content-Type: application/json' \ + --data "$(post_data)" > ./result.json + + +# get missing information from payload +asset_tag=$(cat ./result.json | jq -r '.payload.asset_tag') +result_jq=$(cat ./result.json | jq -r '.status') +erstellt_am=$(cat ./result.json | jq -r '.payload.created_at') + + +print_data() { + cat << EOF +{ + "id": "$asset_tag", + "distribution": "$os_distro", + "version": "$os_version", + "cpu": "$cpu_model", + "memory": "$total_ram", + "disk": "$free_space" +} +EOF +} + +echo $print_data +curl --request POST -d "$(print_data)" http://10.200.4.12:8000/label | lpr -H 10.200.4.12:631 -P DYMO -o landscape - diff --git a/tools/python_utils/files/preseed.cfg b/tools/python_utils/files/preseed.cfg new file mode 100755 index 0000000..a653b24 --- /dev/null +++ b/tools/python_utils/files/preseed.cfg @@ -0,0 +1,103 @@ + + +### Allgemeines +# Verhindert weniger wichtige Nachfragen +# https://www.debian.org/releases/sarge/s390/ch05s02.html.en +# https://preseed.debian.net/debian-preseed/bullseye/amd64-main-full.txt +d-i debconf/priority string critical +# Deaktiviert die Meldung am Ende, dass die Installation abgeschlossen wurde und man neu starten kann +d-i finish-install/reboot_in_progress note + +# Gibt an, ob Infos zum Nutzungsverhalten (installierte/verwendete Software) an Debian gesendet werden +popularity-contest popularity-contest/participate boolean false +# Proprietaere Firmware laden (falls es zu Hardwareproblemen kommt) +#d-i hw-detect/load_firmware boolean true + +### Lokalisierung +d-i debian-installer/locale string de_DE +# Keymap setzen reicht nicht, layout/variantcode hilft ebenfalls nicht: https://groups.google.com/g/linux.debian.bugs.dist/c/XYcrRjLwpQM +d-i keyboard-configuration/variant select Deutschland +d-i keyboard-configuration/xkb-keymap select de + +d-i clock-setup/utc boolean true +d-i tzdata/Areas select Europe +tzdata/Zones/Europe select Berlin +d-i time/zone string Europe/Berlin + +### Partitionierung +# Grub wird automatisch auf den MBR installiert, wenn kein anderes OS vorhanden ist (sicher) +d-i grub-installer/only_debian boolean true +# MBR installation ebenfalls wenn andere OS vorhanden sind (koennte dazu fuehren, dass diese nicht mehr booten) +#d-i grub-installer/with_other_os boolean true +# Verhindert, dass grub alternativ fragt, wo er installiert werden soll +d-i grub-installer/bootdev string /dev/sda +# Fuer die vollautomatische Partitionierung (falls unten aktiv) - Beispiel Lenovo Tiny mit NVMe-SSD +# VirtualBox -> /dev/sda, KVM -> /dev/vda +#d-i partman-auto/disk string /dev/nvme0n1 + +# Fuer lvm 'lvmcfg/vgdelete_confirm', 'partman-lvm/confirm' und 'partman-lvm/confirm_nooverwrite' setzen +# Siehe https://www.debian.org/releases/stable/s390x/apbs04.de.html Abschnitt B.4.7.1. + d-i partman-auto/method string regular +# Alle Daten auf einer Partition (mit 'home' wird das Home-Verzeichnis auf eine eigene Partition gelegt) + d-i partman-auto/choose_recipe select atomic + +# Komplett automatisiert ohne Bestaetigung fuer alle Partitionierungsmethoden (Mit Vorsicht verwenden!) +d-i partman/choose_partition select finish +d-i partman/confirm boolean true +d-i partman/confirm_nooverwrite boolean true +d-i partman-partitioning/confirm_write_new_label boolean true +d-i partman-md/confirm boolean true +d-i partman-md/deleteverify boolean true +d-i lvmcfg/vgdelete_confirm boolean true +d-i partman-lvm/vgdelete_confirm boolean true +d-i partman-lvm/device_remove_lvm boolean true +d-i partman-lvm/confirm boolean true +d-i partman-lvm/confirm_nooverwrite boolean true + +### Software +d-i mirror/country string manual +d-i mirror/http/hostname string ftp2.de.debian.org +d-i mirror/http/directory string /debian +d-i mirror/http/proxy string + +# Aktiviert Spiegelserver abseits der Sicherheitsupdates per Netzwerk statt Image +d-i apt-setup/use_mirror boolean true +d-i apt-setup/disable-cdrom-entries boolean true +# Aktiviert offizielle, aber unfreie Repositorys: https://wiki.debian.org/SourcesList +#d-i apt-setup/non-free boolean true +#d-i apt-setup/contrib boolean true + +# Vorinstallierte Software +# Programmgruppe kann festlegen, ob z.B. Headless oder eine bestimmte Desktopumgebung (xfce-desktop, kde-desktop usw) vorinstalliert werden soll (siehe B.4.10) +tasksel tasksel/first multiselect standard, cinnamon-desktop + +d-i pkgsel/install-language-support boolean true +d-i pkgsel/update-policy select Install security updates automatically +# Alle Pakete automatisch aktualisieren +d-i pkgsel/upgrade select full-upgrade +d-i pkgsel/include string git vim htop curl jq + +# Stdout Weiterleitungen funktionieren in in-target nicht ohne --pass-stdout +# Siehe https://askubuntu.com/a/1248987/650986 und https://serverfault.com/questions/390122/how-do-i-pipe-commands-together-in-a-debian-preseed-file + +### Benutzerkonten +d-i passwd/username string computerspende +d-i passwd/user-fullname string computerspende +d-i passwd/user-uid string 1000 +d-i passwd/user-password password csw +d-i passwd/user-password-again password csw +# root +d-i passwd/root-password password csw +d-i passwd/root-password-again password csw + +# Fuer Testsysteme kann die Policy strikter PWs abgeschaltet werden +d-i user-setup/allow-password-weak boolean true +d-i user-setup/encrypt-home boolean false +d-i user-setup/enable sudo boolean true +### Netzwerk +d-i netcfg/enable boolean true +d-i netcfg/choose_interface select auto +d-i netcfg/hostname string computerspende + +d-i preseed/late_command string \ + in-target --pass-stdout bash -c "echo 'computerspende ALL=NOPASSWD:ALL' > /etc/sudoers.d/computerspende"; diff --git a/tools/python_utils/files/result.json b/tools/python_utils/files/result.json new file mode 100644 index 0000000..e69de29 diff --git a/tools/python_utils/python.sh b/tools/python_utils/python.sh new file mode 100644 index 0000000..cfb9450 --- /dev/null +++ b/tools/python_utils/python.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +print_data() { + cat << EOF +{ + "id": "00000", + "distribution": "Debian", + "version": "12", + "cpu": "i7 0000", + "memory": "128", + "disk": "125" +} +EOF +} + +curl -X POST http://localhost:5000/print \ + -H "Content-Type: application/json" \ + -d "$(print_data)" diff --git a/tools/python_utils/shell.nix b/tools/python_utils/shell.nix new file mode 100644 index 0000000..c2e9605 --- /dev/null +++ b/tools/python_utils/shell.nix @@ -0,0 +1,15 @@ +{ pkgs ? import {} }: + +pkgs.mkShell { + buildInputs = [ + pkgs.python3 + (pkgs.python3.withPackages (ps: with ps; [ + flask + requests + ])) + ]; + + shellHook = '' + echo "Python + Flask dev environment is ready!" + ''; +}