├── LICENSE.md ├── README.md ├── backups ├── README.md ├── backup.sh ├── backups.sh ├── gotify-notify.conf ├── snapshot.sh └── snapshots.sh ├── docker ├── README.md ├── gotify-notify.conf └── update_dc_containers.sh ├── gohugo-cwebp ├── README.md └── hugowebpconvert.sh ├── home-assistant ├── send-temp-sensor-to-ha │ ├── README.md │ ├── my_send_temp_sensor_to_ha.conf │ └── my_send_temp_sensor_to_ha.sh └── update-in-venv │ ├── README.md │ ├── update_gotify.sh │ ├── update_gotifyfull.png │ ├── update_telegram.png │ └── update_telegram.sh ├── nagios-plugins ├── README.md ├── check_hostsonnetwork │ ├── README.md │ └── my_check_hostsonnetwork.sh ├── check_json_output │ ├── README.md │ └── my_check_json_output.sh ├── check_sensors │ ├── README.md │ └── my_check_sensors.sh ├── check_uptime │ ├── README.md │ └── my_check_uptime.sh ├── check_wifichannels │ ├── README.md │ └── my_check_wifichannels.sh └── gotify_nagios │ ├── README.md │ ├── example_result.png │ └── gotify_nagios.sh ├── octolapse-local-rendering ├── README.md └── timelapse.sh ├── power-notify ├── README.md ├── gotify-notify.conf ├── power-notify.service └── power-notify.sh └── update-notifier ├── README.md ├── gotify-notify.conf └── my-unattended-upgrades-notify.sh /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Anup 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## My Scripts 2 | 3 | My personnal collection of scripts. 4 | 5 | Some of them got a related article in my website 6 | [Scrample](https://www.scrample.xyz) (in french). 7 | 8 | I will try to put a README file in all scripts but 9 | some time I may be too lazy to do so. -------------------------------------------------------------------------------- /backups/README.md: -------------------------------------------------------------------------------- 1 | ## Backup scripts 2 | 3 | This series of scripts are made to Rsync specified 4 | folder with Rsync. It send notification using 5 | [Gotify](https://gotify.net) with cURL. 6 | 7 | In scripts whose names are singular, 8 | don't forget to update thoses variables : 9 | 10 | * `GOTIFY_URL` (unnecessary if using configuration file : see below) 11 | * `GOTIFY_TOKEN` (unnecessary if using configuration file : see below) 12 | 13 | I run those scripts with scheduled tasks on my 14 | Synology NAS. This is why you can see some weird stuff 15 | like `export LANG=en_US.UTF-8` (to send emojis correctly) 16 | and the path `/volume1` 17 | Since it's in Bash, it should work on Linux (tested also on Ubuntu). 18 | 19 | In my implementation, I run `backups.sh` one day of the week 20 | and `snapshots.sh` the next day. 21 | 22 | Further explanation 23 | [here](https://www.scrample.xyz/sauvegarde-avec-rsync/) 24 | (but in french) with the original Telegram based notifications scripts. 25 | 26 | 27 | ### Configuration file (optional) 28 | 29 | Copy `gotify-notify.conf` to the `/etc/` folder or be lazy : 30 | ``` 31 | wget https://raw.githubusercontent.com/anup92k/scripts/master/backups/gotify-notify.conf -O /etc/gotify-notify.conf 32 | ``` 33 | 34 | Don't forget to update it with your personnal credentials ! 35 | 36 | 37 | ### Rsync 38 | 39 | The `backup.sh` script is called trough `backups.sh`. 40 | Every backups result in a text log file which need to be kept 41 | in order to do the snapshot. 42 | 43 | 44 | ### Snapshot 45 | 46 | Making a snapshot is implemented by just doing a 47 | tarball of the "rsynced" folder. 48 | 49 | The `snapshot.sh` script is called trough `snapshots.sh`. 50 | 51 | *This script also remove Snapshots which are more than 90 days old.* -------------------------------------------------------------------------------- /backups/backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export LANG=en_US.UTF-8 3 | 4 | # Gotify parameters 5 | GOTIFY_URL="https://gotify.blablabla.mu" 6 | GOTIFY_TOKEN="Az3rTy" # Your token here 7 | 8 | # Configuration file 9 | FILE_CONF="/etc/gotify-notify.conf" 10 | 11 | # Handling configuration file (if present) 12 | if [[ -f "${FILE_CONF}" ]]; then 13 | GOTIFY_URL=$(grep "server-url=" $FILE_CONF | cut -d'=' -f2) 14 | GOTIFY_TOKEN=$(grep "access-token=" $FILE_CONF | cut -d'=' -f2) 15 | fi 16 | 17 | # Handling options 18 | while getopts "S:H:b:d:h" option 19 | do 20 | case $option in 21 | S) 22 | serverName=$OPTARG 23 | ;; 24 | H) 25 | serverIP=$OPTARG 26 | ;; 27 | b) 28 | backupStorage=$OPTARG 29 | ;; 30 | d) 31 | serverDirectory=$OPTARG 32 | ;; 33 | h) 34 | echo "Usage :" 35 | echo -n "$(basename $0) " 36 | echo -n "-S [Server Name] " 37 | echo -n "-H [Hostname or IP address] " 38 | echo -n "-b [Backup Storage] " 39 | echo -n "-d [Directories to Save] " 40 | echo "" 41 | exit 0 42 | ;; 43 | :) 44 | echo "Argument needed for $OPTARG" 45 | exit 2 46 | ;; 47 | \?) 48 | echo "$OPTARG : invalid option" 49 | exit 3 50 | ;; 51 | esac 52 | done 53 | 54 | # Testing correct number of argument 55 | if [ $# -ne 8 ]; then 56 | echo "Not right number of argument" 57 | echo "Use option '-h' for help" 58 | exit 1 59 | fi 60 | 61 | # Gotify Checks 62 | ## Do you have cURL ? 63 | if [[ $(command -v curl >/dev/null 2>&1) ]]; then 64 | echo "FATAL ERROR: This script require cURL !" 65 | exit 2 66 | fi 67 | # Test Gotify server connexion (health check) 68 | curlHttpResult=$(curl "${GOTIFY_URL}/health?token=${GOTIFY_TOKEN}" --output /dev/null --silent --write-out %{http_code}) 69 | if [[ $? -ne 0 ]]; then 70 | echo "FATAL ERROR: cURL health check command failed !" 71 | exit 3 72 | fi 73 | # Check HTTP return code ("200" is OK) 74 | if [[ $curlHttpResult -ne 200 ]]; then 75 | echo -e "FATAL ERROR: API call failed ! Return code is $curlHttpResult instead of 200." 76 | exit 4 77 | fi 78 | 79 | 80 | # Gotify messages title 81 | GOTIFY_TITLE="🔄 $serverName Rsync" 82 | 83 | 84 | currentDate=$(date +%F) 85 | backupDirectory="$backupStorage/$serverName/backup" 86 | 87 | mkdir -p $backupDirectory 88 | if [ $? -ne 0 ]; then 89 | message="Error making backup." 90 | message+="Cannot create directory $backupDirectory" 91 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 92 | -F "title=${GOTIFY_TITLE}" \ 93 | -F "message=${message}" \ 94 | -F "priority=8" \ 95 | --output /dev/null --silent 96 | exit 5 97 | fi 98 | 99 | 100 | # Remove old backup log 101 | rm -f $backupDirectory/backup-*.txt 102 | 103 | # Notify Rsync start 104 | message="▶️ Started" 105 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 106 | -F "title=${GOTIFY_TITLE}" \ 107 | -F "message=${message}" \ 108 | -F "priority=8" \ 109 | --output /dev/null --silent 110 | 111 | 112 | # Rsync (¬‿¬ ) 113 | rsync --archive --stats --human-readable --exclude /var/lib/docker/overlay2/ --relative --delete -e ssh \ 114 | root@$serverIP:{$serverDirectory} $backupDirectory | tee $backupDirectory/backup-$currentDate.txt 115 | 116 | 117 | # Notify finished with Rsync log 118 | message="$(echo "☑️ Finished"; tail -n 14 $backupDirectory/backup-$currentDate.txt)" 119 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 120 | -F "title=${GOTIFY_TITLE}" \ 121 | -F "message=${message}" \ 122 | -F "priority=8" \ 123 | --output /dev/null --silent 124 | 125 | 126 | exit 0 127 | -------------------------------------------------------------------------------- /backups/backups.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Server "Tapion" backup 4 | /volume1/BackupStorage/backup.sh \ 5 | -S Tapion \ 6 | -H tapion.konatz.dbz \ 7 | -b "/volume1/BackupStorage" \ 8 | -d "/etc,/home/nagios,/opt,/root,/usr/lib,/usr/local,/var/lib,/var/log,/var/www" 9 | 10 | # Server "Bubbles" backup 11 | /volume1/BackupStorage/backup.sh \ 12 | -S Bubbles \ 13 | -H 192.168.92.17 \ 14 | -b "/volume1/BackupStorage" \ 15 | -d "/etc,/home/homeassistant,/home/nagios,/opt,/root,/srv/esphome/config,/usr/lib,/usr/local,/var/lib,/var/log,/var/www" 16 | -------------------------------------------------------------------------------- /backups/gotify-notify.conf: -------------------------------------------------------------------------------- 1 | #-------------------------------# 2 | # /etc/gotify-notify.conf # 3 | #-------------------------------# 4 | 5 | [general] 6 | server-url=https://YourGotifyServer.url 7 | access-token=YourTokenHere 8 | -------------------------------------------------------------------------------- /backups/snapshot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export LANG=en_US.UTF-8 3 | 4 | # Gotify parameters 5 | GOTIFY_URL="https://gotify.blablabla.mu" 6 | GOTIFY_TOKEN="Az3rTy" # Your token here 7 | 8 | # Handling options 9 | while getopts "S:b:h" option 10 | do 11 | case $option in 12 | S) 13 | serverName=$OPTARG 14 | ;; 15 | b) 16 | backupStorage=$OPTARG 17 | ;; 18 | h) 19 | echo "Usage :" 20 | echo -n "$(basename $0) " 21 | echo -n "-S [Server Name] " 22 | echo -n "-b [Backup Storage] " 23 | echo "" 24 | exit 0 25 | ;; 26 | :) 27 | echo "Argument needed for $OPTARG" 28 | exit 2 29 | ;; 30 | \?) 31 | echo "$OPTARG : invalid option" 32 | exit 3 33 | ;; 34 | esac 35 | done 36 | 37 | 38 | backupDirectory="$backupStorage/$serverName/backup" 39 | snapshotDirectory="$backupStorage/$serverName/snapshot" 40 | 41 | # Testing correct number of argument 42 | if [ $# -ne 4 ]; then 43 | echo "Not right number of argument" 44 | echo "Use option '-h' for help" 45 | exit 1 46 | fi 47 | 48 | 49 | # Gotify Checks 50 | ## Do you have cURL ? 51 | if [[ $(command -v curl >/dev/null 2>&1) ]]; then 52 | echo "FATAL ERROR: This script require cURL !" 53 | exit 2 54 | fi 55 | # Test Gotify server connexion (health check) 56 | curlHttpResult=$(curl "${GOTIFY_URL}/health?token=${GOTIFY_TOKEN}" --output /dev/null --silent --write-out %{http_code}) 57 | if [[ $? -ne 0 ]]; then 58 | echo "FATAL ERROR: cURL health check command failed !" 59 | exit 3 60 | fi 61 | # Check HTTP return code ("200" is OK) 62 | if [[ $curlHttpResult -ne 200 ]]; then 63 | echo -e "FATAL ERROR: API call failed ! Return code is $curlHttpResult instead of 200." 64 | exit 4 65 | fi 66 | 67 | # Gotify messages title 68 | GOTIFY_TITLE="💾 $serverName Snapshot" 69 | 70 | # Test if the backup directory exist 71 | if [ ! -d $backupDirectory ]; then 72 | message="❌ Directory $backupDirectory does not exist" 73 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 74 | -F "title=${GOTIFY_TITLE}" \ 75 | -F "message=${message}" \ 76 | -F "priority=8" \ 77 | --output /dev/null --silent 78 | exit 4 79 | fi 80 | 81 | # Find backup stats file (stop at first result : should be only one) 82 | backupFile=$(find $backupDirectory -type f -name backup-*.txt -print -quit) 83 | 84 | # Test if the backup file exist 85 | if [ -z "$backupFile" ]; then 86 | message="❌ Backup file in $backupDirectory does not exist" 87 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 88 | -F "title=${GOTIFY_TITLE}" \ 89 | -F "message=${message}" \ 90 | -F "priority=8" \ 91 | --output /dev/null --silent 92 | exit 5 93 | fi 94 | 95 | # Get the date of the backup (written in the file name) 96 | backupDate=$(basename $backupFile | cut -d'-' -f2- | cut -d'.' -f1) 97 | 98 | # Notify snapshot start 99 | message="▶️ Making snapshot of $backupDate backup" 100 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 101 | -F "title=${GOTIFY_TITLE}" \ 102 | -F "message=${message}" \ 103 | -F "priority=8" \ 104 | --output /dev/null --silent 105 | 106 | # Making snapshot 107 | mkdir -p $snapshotDirectory 108 | cd $backupDirectory 109 | tar --warning='no-file-ignored' -czf $snapshotDirectory/snapshot-$backupDate.tgz * 110 | if [ $? -ne 0 ]; then 111 | message="❌ Tar task for $backupDirectory of $backupDate failed" 112 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 113 | -F "title=${GOTIFY_TITLE}" \ 114 | -F "message=${message}" \ 115 | -F "priority=8" \ 116 | --output /dev/null --silent 117 | exit 6 118 | fi 119 | 120 | tarFileSize=$(du -h $snapshotDirectory/snapshot-$backupDate.tgz | awk '{print $1}') 121 | 122 | # Gotify finished notification with rsync stats as attachement 123 | message="☑️ Finished snapshot of $backupDate with a file of $tarFileSize" 124 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 125 | -F "title=${GOTIFY_TITLE}" \ 126 | -F "message=${message}" \ 127 | -F "priority=8" \ 128 | --output /dev/null --silent 129 | 130 | # Delete backup older than 3 months 131 | find $snapshotDirectory -mtime +90 -type f -exec rm -f '{}' \; 132 | 133 | -------------------------------------------------------------------------------- /backups/snapshots.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Tapion snapshot 4 | /volume1/BackupStorage/snapshot.sh \ 5 | -S Tapion \ 6 | -b "/volume1/BackupStorage" 7 | 8 | 9 | # Bubbles snapshot 10 | /volume1/BackupStorage/snapshot.sh \ 11 | -S Bubbles \ 12 | -b "/volume1/BackupStorage" 13 | 14 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | ## Docker related scripts 2 | ### Updates Docker Compose container 3 | 4 | Basically, this script found all Docker Compose files, 5 | pulls images based on them and re-run the containers. 6 | 7 | Because I may wanna cron this script, 8 | I added Gotify notifications to this. 9 | 10 | If you just want a simple script : 11 | ```bash 12 | #!/usr/bin/env bash 13 | 14 | composeConfig=$(find . -type f -name "docker-compose.yml" -o -name "docker-compose.yaml" | xargs echo) 15 | 16 | for i in $composeConfig; do 17 | cd $(dirname -- $i) 18 | docker compose pull --quiet 19 | docker compose up --detach --remove-orphans --quiet-pull 20 | done 21 | 22 | docker image prune --force 23 | ``` 24 | 25 | If you use `update_dc_containers.sh`, 26 | don't forget to update thoses variables in the script : 27 | 28 | * `DC_FOLDERS` 29 | * `GOTIFY_URL` (unnecessary if using configuration file : see below) 30 | * `GOTIFY_TOKEN` (unnecessary if using configuration file : see below) 31 | 32 | And optionally : 33 | 34 | * `GOTIFY_TITLE` 35 | 36 | Update (2021-12-28) : 37 | If you run this script using any argument 38 | (ex : `update_dc_containers.sh lol`), 39 | it will only work on the current directory 40 | 41 | Update (2023-02-18) : 42 | Make it work in directory so file like `docker-compose.override.yml` 43 | will be processed too. 44 | 45 | Update (2023-05-04) : 46 | Update to Compose V2. 47 | 48 | 49 | ### Configuration file (optional) 50 | 51 | Copy `gotify-notify.conf` to the `/etc/` folder or be lazy : 52 | ``` 53 | wget https://raw.githubusercontent.com/anup92k/scripts/master/docker/gotify-notify.conf -O /etc/gotify-notify.conf 54 | ``` 55 | 56 | Don't forget to update it with your personnal credentials ! 57 | -------------------------------------------------------------------------------- /docker/gotify-notify.conf: -------------------------------------------------------------------------------- 1 | #-------------------------------# 2 | # /etc/gotify-notify.conf # 3 | #-------------------------------# 4 | 5 | [general] 6 | server-url=https://YourGotifyServer.url 7 | access-token=YourTokenHere 8 | -------------------------------------------------------------------------------- /docker/update_dc_containers.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Pull new images based on Docker Compose files 3 | 4 | # Directory containing folders of all Docker Compose files 5 | DC_FOLDERS="/root/docker" 6 | # Gotify parameters 7 | GOTIFY_URL="https://gotify.blablabla.mu" 8 | GOTIFY_TOKEN="Az3rTy" # Your token here 9 | # Gotify messages title 10 | GOTIFY_TITLE="🐳 Updates" 11 | 12 | # Configuration file 13 | FILE_CONF="/etc/gotify-notify.conf" 14 | 15 | # Handling configuration file (if present) 16 | if [[ -f "${FILE_CONF}" ]]; then 17 | GOTIFY_URL=$(grep "server-url=" $FILE_CONF | cut -d'=' -f2) 18 | GOTIFY_TOKEN=$(grep "access-token=" $FILE_CONF | cut -d'=' -f2) 19 | fi 20 | 21 | # Gotify Checks 22 | ## Do you have cURL ? 23 | if [[ $(command -v curl >/dev/null 2>&1) ]]; then 24 | echo "FATAL ERROR: This script require cURL !" 25 | exit 1 26 | fi 27 | # Test Gotify server connexion (health check) 28 | curlHttpResult=$(curl "${GOTIFY_URL}/health?token=${GOTIFY_TOKEN}" --output /dev/null --silent --write-out %{http_code}) 29 | if [[ $? -ne 0 ]]; then 30 | echo "FATAL ERROR: cURL health check command failed !" 31 | exit 2 32 | fi 33 | # Check HTTP return code ("200" is OK) 34 | if [[ $curlHttpResult -ne 200 ]]; then 35 | echo -e "FATAL ERROR: API call failed ! Return code is $curlHttpResult instead of 200." 36 | exit 3 37 | fi 38 | 39 | 40 | # Temp out file 41 | outputFile="$(mktemp)" 42 | 43 | # Allow working only into the current folder 44 | # if any argument is used to run the script 45 | if [[ $# -ne 0 ]]; then 46 | DC_FOLDERS="." 47 | fi 48 | 49 | # Find Docker Compose files 50 | composeConfig=$(find $DC_FOLDERS -type f \ 51 | -name "docker-compose.yml" -o \ 52 | -name "docker-compose.yaml" -o \ 53 | -name "compose.yml" -o \ 54 | -name "compose.yaml" | xargs echo) 55 | if [[ -z "$composeConfig" ]]; then 56 | message="No Docker Compose files found in $DC_FOLDERS" 57 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 58 | -F "title=${GOTIFY_TITLE}" \ 59 | -F "message=${message}" \ 60 | -F "priority=8" \ 61 | --output /dev/null --silent 62 | exit 4 63 | fi 64 | 65 | 66 | # Processing updates 67 | message="▶️ Starting" 68 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 69 | -F "title=${GOTIFY_TITLE}" \ 70 | -F "message=${message}" \ 71 | -F "priority=8" \ 72 | --output /dev/null --silent 73 | 74 | for i in $composeConfig; do 75 | # Go to folder location 76 | cd $(dirname -- $i) 77 | # Pull current Docker Compose images 78 | docker compose pull --quiet 79 | # Builds, (re)creates, starts containers 80 | ## Run containers in the background 81 | ## Remove containers for services not defined in the Compose file. 82 | ## Pull without printing progress information 83 | docker compose up --detach --remove-orphans --quiet-pull 84 | done 85 | 86 | # Remove all dangling images 87 | ## Do not prompt for confirmation 88 | docker image prune --force | grep untagged | tee $outputFile 89 | 90 | # Sending result to Gotify 91 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 92 | -F "title=${GOTIFY_TITLE}" \ 93 | -F "message=$(cat $outputFile)" \ 94 | -F "priority=8" \ 95 | --output /dev/null --silent 96 | 97 | rm $outputFile -------------------------------------------------------------------------------- /gohugo-cwebp/README.md: -------------------------------------------------------------------------------- 1 | ## Hugo related scripts 2 | ### Convert images to WebP 3 | #### Purpose 4 | 5 | As [v0.83.0](https://github.com/gohugoio/hugo/releases/tag/v0.83.0) 6 | of [Hugo](https://gohugo.io/) framework bring support to WebP format, 7 | I scripted a tool to automatically convert images and update posts. 8 | 9 | 10 | #### Prerequisite 11 | 12 | Without modification, this script will only work if your content 13 | are in the `content` folder and your images in the static folder. 14 | 15 | In order to use this, you'll need `webp` installed. 16 | ```bash 17 | sudo apt install webp 18 | ``` 19 | *The script will use `gif2webp` for GIF file and 20 | `cwebp` for the others.* 21 | 22 | 23 | You also need a file (in the same folder as the script) named `list.txt` 24 | containing the image path as it is specified in the post preceded by the 25 | post path. 26 | 27 | For exemple : 28 | `content/posts/2021/05-05-my-awsome-post/index.en.md` contain : 29 | ``` 30 | {{< image src="/path/to/images/un.png" caption="Azerty" title=" " >}} 31 | {{< image src="/path/to/images/one.jpg" caption="Qwerty" title=" " >}} 32 | ``` 33 | 34 | and 35 | `content/posts/2020/04-17-hello/index.en.md` contain : 36 | ``` 37 | {{< image src="/2020/04-17/hello/1.gif" caption="Hi" title=" " >}} 38 | {{< image src="/2020/04-17/hello/2.gif" caption="Hello" title=" " >}} 39 | ``` 40 | 41 | This means the images paths are : 42 | ``` 43 | static/path/to/images/un.png 44 | static/path/to/images/one.jpg 45 | static/2020/04-17/hello/1.gif 46 | static/2020/04-17/hello/2.gif 47 | ``` 48 | 49 | My `list.txt` file must contain thoses lines : 50 | ``` 51 | content/posts/2021/05-05-my-awsome-post/index.en.md /path/to/images/un.png 52 | content/posts/2021/05-05-my-awsome-post/index.en.md /path/to/images/one.jpg 53 | content/posts/2020/04-17-hello/index.en.md /2020/04-17/hello/1.gif 54 | content/posts/2020/04-17-hello/index.en.md /2020/04-17/hello/2.gif 55 | ``` 56 | 57 | Here is my dirty command to achieve that : 58 | ``` 59 | find content -type f -name "*.md" -print | xargs grep "image src" | sed 's/{{< image src="//g' | awk '{print $1}' | tr -d '"' | sed 's/:/ /g' | grep -e ".jpg" -e ".png" -e ".gif" | sort -u > list.txt 60 | ``` 61 | If this command work for you, dont forget to manually remove external images links. 62 | 63 | 64 | #### Using the script 65 | 66 | Update the variable `HUGO_ROOT` on line 12 to hugo site folder 67 | (ex : `HUGO_ROOT="/home/anup92k/git/HugoBlog"`). 68 | *With so, you don't need to place the script inside the Hugo folder.* 69 | 70 | You may also want to change the conversion parameters (see line 15). 71 | Make sure to specify something that will work with `cwebp` and `gif2webp`. 72 | 73 | 74 | Run the script ! 75 | 76 | `error.txt` file will contain paths of non found images. 77 | `failed.txt` file will contain a list of non converted file. 78 | `toberemove.txt` file will contain the list of the removed images. 79 | Keep in mind that thoses files are cleared on every run. 80 | -------------------------------------------------------------------------------- /gohugo-cwebp/hugowebpconvert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Created by : Anup92k 4 | # Date (YYYY-MM-DD) : 2021-05-04 5 | # Last update : 2021-05-04 6 | 7 | # Purpose : 8 | ## Convert images used in Hugo posts 9 | ## into WebP format and update thoses contents 10 | 11 | # Hugo root path (where `content` and `static` are) 12 | HUGO_ROOT="/my/root/path/to/hugo" 13 | 14 | # Conversion parameters 15 | CONVERT_PARAM="-m 6 -mt -quiet" 16 | 17 | # Not using temp file because keeping them 18 | # should be usefull 19 | true > failed.txt 20 | true > error.txt 21 | true > toberemove.txt 22 | 23 | while read line 24 | do 25 | POST="${HUGO_ROOT}/$(echo $line | awk '{print $1}')" 26 | IMG="${HUGO_ROOT}/static$(echo $line | awk '{print $2}')" 27 | IMG_POST_LINK="$(echo $line | awk '{print $2}')" 28 | 29 | # Test if post really exist 30 | if [[ (-f "${POST}") ]]; then 31 | echo "ok" > /dev/null 32 | 33 | IMG_WEBP="${IMG%.*}.webp" 34 | 35 | # If webp file does not already exist 36 | # (case of same images used multiple time) 37 | if [[ ! -f "$IMG_WEBP" ]]; then 38 | CONVERT_PROGRAM="cwebp" 39 | ## GIF file should be converted using gif2webp 40 | if [ "$(file $IMG | cut -d':' -f2- | grep -c 'GIF')" -ne 0 ]; then 41 | CONVERT_PROGRAM="gif2webp" 42 | fi 43 | # Converting image to webp format 44 | $CONVERT_PROGRAM $CONVERT_PARAM $IMG -o $IMG_WEBP 45 | fi 46 | 47 | # Test if converted file exist 48 | if [[ -f $IMG_WEBP ]]; then 49 | # Store post webp content link 50 | IMG_WEBP_POST_LINK="${IMG_POST_LINK%.*}.webp" 51 | 52 | # Replace content 53 | sed -i "s@$IMG_POST_LINK@$IMG_WEBP_POST_LINK@g" $POST 54 | 55 | # Add link to remove old image 56 | echo $IMG >> toberemove.txt 57 | else 58 | echo "ERROR : cwebp for $IMG" 59 | echo -e "\t $IMG_WEBP unreachable" 60 | echo "$IMG" >> failed.txt 61 | fi 62 | 63 | else 64 | echo "ERROR : $POST or $IMG does not exist !" 65 | echo "$POST $IMG" >> error.txt 66 | fi 67 | 68 | done < list.txt 69 | 70 | 71 | # Remove old file 72 | for oldfile in $(cat toberemove.txt | sort -u); do 73 | rm $oldfile 74 | done 75 | 76 | echo "#######################" 77 | echo "# ERROR testing files #" 78 | echo "" 79 | cat error.txt 80 | echo "#######################" 81 | echo "" 82 | 83 | echo "#######################" 84 | echo "# FAIL convert files #" 85 | echo "" 86 | cat failed.txt 87 | echo "#######################" 88 | echo "" -------------------------------------------------------------------------------- /home-assistant/send-temp-sensor-to-ha/README.md: -------------------------------------------------------------------------------- 1 | ## Send temperature sensor to HA 2 | 3 | ### Purpose 4 | 5 | This script is made to send `sensors` data to Home Assistant 6 | 7 | My goal is to buil a virtual thermostat in HA in order to cool my server using 8 | an external fan plugged into a USB relay. 9 | 10 | It use my [Nagios script](https://github.com/anup92k/scripts/tree/master/nagios-plugins/check_sensors) 11 | 12 | ### Usage 13 | 14 | - Edit and put `my_send_temp_sensor_to_ha.conf` into `/etc/my_send_temp_sensor_to_ha.conf` 15 | - Copy the script and try to run it manually 16 | 17 | - Cron this script ! -------------------------------------------------------------------------------- /home-assistant/send-temp-sensor-to-ha/my_send_temp_sensor_to_ha.conf: -------------------------------------------------------------------------------- 1 | # ------------------------------------------------------------------------------ 2 | # /etc/my_mb_temp_to_ha.conf 3 | # ------------------------------------------------------------------------------ 4 | 5 | HA_BASE_URL="http://192.168.0.17" 6 | HA_TOKEN="Az3rty" 7 | 8 | CHECK_SENSORS_SCRIPT="/usr/lib/nagios/plugins/my_check_sensors.sh" 9 | CHECK_SENSORS_ARGS="temp1 2 2 50 70" 10 | 11 | SENSOR_NAME="my_temp" 12 | -------------------------------------------------------------------------------- /home-assistant/send-temp-sensor-to-ha/my_send_temp_sensor_to_ha.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # ------------------------------------------------------------------------------ 4 | # Script to send MotherBoard temp data to HomeAssistant 5 | # ------------------------------------------------------------------------------ 6 | 7 | # This script is using 8 | # https://github.com/anup92k/scripts/tree/master/nagios-plugins/check_sensors 9 | # to get the datas 10 | 11 | # Configuration file 12 | MY_CONFIG_FILE="/etc/my_send_temp_sensor_to_ha.conf" 13 | 14 | HA_API_SUBPATH="api/states" 15 | 16 | # Handling configuration file (must be present) 17 | if [[ -f "${MY_CONFIG_FILE}" ]]; then 18 | # Load config file 19 | . ${MY_CONFIG_FILE} 20 | else 21 | echo "Cannot access config file on : ${MY_CONFIG_FILE}" 22 | exit 1 23 | fi 24 | 25 | # Get sensor value 26 | sensorValue="0" 27 | checkReturnValue="3" 28 | tempValue="none" 29 | 30 | sensorValue=$($CHECK_SENSORS_SCRIPT $CHECK_SENSORS_ARGS) 31 | checkReturnValue=$? 32 | 33 | # If return value is not 3, get correct result 34 | if [[ $checkReturnValue -ne "3" ]]; then 35 | # Get result from perfdata 36 | tempValue=$(echo $sensorValue | cut -d '|' -f2 | cut -d '=' -f2 | tr -d '°C') 37 | fi 38 | 39 | # Send data to HA 40 | curl -s -H "Authorization: Bearer ${HA_TOKEN}" -X POST ${HA_BASE_URL}/${HA_API_SUBPATH}/sensor.${SENSOR_NAME} -d \ 41 | "{\"state\": \"${tempValue}\", \"attributes\": {\"device_class\":\"temperature\",\"unit_of_measurement\": \"°C\"}}" 42 | curlReturnValue=$? 43 | 44 | if [[ $curlReturnValue -ne "0" ]]; then 45 | echo "cURL failed : code $curlReturnValue" 46 | exit 2 47 | fi 48 | 49 | exit 0 50 | -------------------------------------------------------------------------------- /home-assistant/update-in-venv/README.md: -------------------------------------------------------------------------------- 1 | ## Update 2 | 3 | Bash scripts to update my HA instance with notification. 4 | It output a log file in the `$HADIR` in a `$(date +%F_%H-%M)-update-log.txt` format 5 | (old one is removed when re-running this script). 6 | 7 | My HA is installed in a Python virtual environment (venv) following 8 | [this article](https://www.home-assistant.io/docs/installation/raspberry-pi/). 9 | 10 | [Mon article sur l'installation](https://www.scrample.xyz/installation-de-home-assistant-sous-ubuntu-18-04/) 11 | [Et la suite](https://www.scrample.xyz/maj-python-pour-home-assistant/) 12 | 13 | I run this script using 14 | [Shell Command integration](https://www.home-assistant.io/integrations/shell_command/). 15 | 16 | 17 | ### Gotify notifications 18 | 19 | The notification are send using cURL commands. 20 | To use this one, it require to set the URL and the token in the script. 21 | Please also check the HA directory and it's virtual environnement location. 22 | 23 | ```bash 24 | HADIR="/home/homeassistant/.homeassistant" 25 | HAVENV="/srv/homeassistant/bin/activate" 26 | GOTIFYURL="https://gotify.blablabla.mu" 27 | GOTIFYTOKEN="Az3rTy" # Your token here 28 | ``` 29 | ![](update_gotifyfull.png) 30 | 31 | [Mon article sur Gotify](https://www.scrample.xyz/gotify-service-de-notifications/) 32 | 33 | 34 | ### Telegram notifications 35 | 36 | The notifications are send using 37 | [telegram-notify](https://github.com/NicolasBernaerts/debian-scripts/tree/master/telegram) 38 | with a custom config file located in `$HADIR/.telegram-notify.conf`. 39 | ![](update_telegram.png) 40 | 41 | -------------------------------------------------------------------------------- /home-assistant/update-in-venv/update_gotify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 1. Upgrade HA 4 | # 2. Check HA config 5 | # 3. Restart HA 6 | 7 | 8 | HADIR="/home/homeassistant/.homeassistant" 9 | HAVENV="/srv/homeassistant/bin/activate" 10 | GOTIFYURL="https://gotify.blablabla.mu" 11 | GOTIFYTOKEN="Az3rTy" # Your token here 12 | 13 | TITLE="HA Update" 14 | 15 | DATE=$(date +%F_%H-%M) 16 | source $HAVENV 17 | 18 | # Do you have cURL ? 19 | if [[ $(command -v curl >/dev/null 2>&1) ]]; then 20 | echo "FATAL ERROR: This script require cURL !" 21 | exit 1 22 | fi 23 | 24 | # Do you have jq ? 25 | if [[ $(command -v jq >/dev/null 2>&1) ]]; then 26 | echo "FATAL ERROR: This script require jQuery (jq) !" 27 | exit 1 28 | fi 29 | 30 | # Test Gotify server connexion (health check) 31 | curl_http_result=$(curl "${GOTIFYURL}/health?token=${GOTIFYTOKEN}" --output /dev/null --silent --write-out %{http_code}) 32 | if [[ $? -ne 0 ]]; then 33 | echo "FATAL ERROR: cURL health check command failed !" 34 | exit 2 35 | fi 36 | # Check HTTP return code ("200" is OK) 37 | if [[ $curl_http_result -ne 200 ]]; then 38 | echo -e "FATAL ERROR: API call failed ! Return code is $curl_http_result instead of 200." 39 | exit 3 40 | fi 41 | 42 | 43 | # Remove old update log file 44 | find $HADIR -type f -name "*-update-log.txt" -exec rm -f '{}' \; 45 | 46 | 47 | # 1. Upgrade HA 48 | 49 | MESSAGE="▶️ Started from $(hass --version) to $(curl --silent -L https://pypi.python.org/pypi/homeassistant/json | jq .info.version | sed 's/\"//g')" 50 | curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=8" 51 | 52 | echo "----------------- HA Update -----------------" | tee $HADIR/$DATE-update-log.txt 53 | 54 | set -o pipefail # Get non-zero status of the pipeline if it append 55 | pip3 install --upgrade homeassistant | tee --append $HADIR/$DATE-update-log.txt 56 | if [ $? -ne 0 ]; then 57 | MESSAGE="❌ Failed ! Please refer back to log file $DATE-update-log.txt" 58 | curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=10" 59 | exit 4 60 | fi 61 | set +o pipefail 62 | 63 | 64 | MESSAGE="✅ Finished" 65 | curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=8" 66 | 67 | 68 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 69 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 70 | 71 | 72 | # 2. Check HA config 73 | 74 | set -o pipefail 75 | hass --script check_config | tee --append $HADIR/$DATE-update-log.txt 76 | if [ $? -ne 0 ]; then 77 | MESSAGE="❌ Checking configuration failed ! Please refer back to log file $DATE-update-log.txt" 78 | curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=10" 79 | exit 5 80 | fi 81 | set +o pipefail 82 | 83 | MESSAGE="✅ Checking config OK" 84 | curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=8" 85 | 86 | 87 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 88 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 89 | 90 | 91 | # 3. Restart HA 92 | 93 | MESSAGE="🔄 Restarting Home Assistant" 94 | curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=8" 95 | 96 | 97 | 98 | set -o pipefail 99 | sudo systemctl restart home-assistant@homeassistant.service | tee --append $HADIR/$DATE-update-log.txt 100 | if [ $? -ne 0 ]; then 101 | MESSAGE="❌ Errors while restarting ! Please refer back to log file $DATE-update-log.txt" 102 | curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=10" 103 | exit 6 104 | fi 105 | set +o pipefail 106 | 107 | # Not needed since I have an HA automation that already notified when HA (re)start : 108 | #MESSAGE="☑️ Finished update to $(hass --version)" 109 | #curl "${GOTIFYURL}/message?token=${GOTIFYTOKEN}" -F "title=${TITLE}" -F "message=${MESSAGE}" -F "priority=8" 110 | -------------------------------------------------------------------------------- /home-assistant/update-in-venv/update_gotifyfull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anup92k/scripts/ea89c154c1c720c5b51f7e85c4c4eb6e9bc40d50/home-assistant/update-in-venv/update_gotifyfull.png -------------------------------------------------------------------------------- /home-assistant/update-in-venv/update_telegram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anup92k/scripts/ea89c154c1c720c5b51f7e85c4c4eb6e9bc40d50/home-assistant/update-in-venv/update_telegram.png -------------------------------------------------------------------------------- /home-assistant/update-in-venv/update_telegram.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 1. Upgrade HA 4 | # 2. Check HA config 5 | # 3. Restart HA 6 | 7 | 8 | DATE=$(date +%F_%H-%M) 9 | HADIR="/home/homeassistant/.homeassistant" 10 | NOTIFY=$(which telegram-notify) 11 | source /srv/homeassistant/bin/activate 12 | 13 | 14 | # Do you have jq ? 15 | if [[ $(command -v jq >/dev/null 2>&1) ]]; then 16 | echo "FATAL ERROR: This script require jQuery (jq) !" 17 | exit 1 18 | fi 19 | 20 | if [[ -z $NOTIFY ]]; then 21 | echo "Telegram Notification (telegram-notify) not available" 22 | exit 1 23 | fi 24 | 25 | # Make telegram notification on the HA group 26 | NOTIFY="$NOTIFY --config $HADIR/.telegram-notify.conf" 27 | 28 | # Remove old update log file 29 | find $HADIR -type f -name "*-update-log.txt" -exec rm -f '{}' \; 30 | 31 | 32 | # 1. Upgrade HA 33 | 34 | $NOTIFY --icon 25B6 --text "Update started from $(hass --version) to $(curl --silent -L https://pypi.python.org/pypi/homeassistant/json | jq .info.version | sed 's/\"//g')" 35 | echo "----------------- HA Update -----------------" | tee $HADIR/$DATE-update-log.txt 36 | 37 | set -o pipefail # Get non-zero status of the pipeline if it append 38 | pip3 install --upgrade homeassistant | tee --append $HADIR/$DATE-update-log.txt 39 | if [ $? -ne 0 ]; then 40 | $NOTIFY --error --title "Update failed !" --text "Please refer back to log file" --document "$HADIR/$DATE-update-log.txt" 41 | exit 2 42 | fi 43 | set +o pipefail 44 | 45 | $NOTIFY --success --text "Update finished" 46 | 47 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 48 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 49 | 50 | 51 | # 2. Check HA config 52 | 53 | set -o pipefail 54 | hass --script check_config | tee --append $HADIR/$DATE-update-log.txt 55 | if [ $? -ne 0 ]; then 56 | $NOTIFY --error --title "Checking configuration failed !" --text "Please refer back to log file" --document "$HADIR/$DATE-update-log.txt" 57 | exit 3 58 | fi 59 | set +o pipefail 60 | 61 | $NOTIFY --success --text "Checking config OK" 62 | 63 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 64 | echo "---------------------------------------------" | tee --append $HADIR/$DATE-update-log.txt 65 | 66 | 67 | # 3. Restart HA 68 | 69 | $NOTIFY --icon 1F504 --text "Restarting Home Assistant" 70 | set -o pipefail 71 | sudo systemctl restart home-assistant@homeassistant.service | tee --append $HADIR/$DATE-update-log.txt 72 | if [ $? -ne 0 ]; then 73 | $NOTIFY --error --title "Errors while restarting !" --text "Please refer back to log file" --document "$HADIR/$DATE-update-log.txt" 74 | exit 3 75 | fi 76 | set +o pipefail 77 | 78 | # Not needed since an HA automation already notified HA (re)start 79 | # $NOTIFY --success --text "Update to $(hass --version) finished" --document "$HADIR/$DATE-update-log.txt" 80 | 81 | -------------------------------------------------------------------------------- /nagios-plugins/README.md: -------------------------------------------------------------------------------- 1 | ## Nagios plugins 2 | 3 | Nagios plugins I made for my personnal use 4 | 5 | I made them mostly for these reasons : 6 | 7 | * Because of the lack of plugins with performance data 8 | *My Nagios data are transmitted to an InfluxDB and displayed in Grafana* 9 | * Because I can't find plugins that do what I'm looking for 10 | * Combination of reasons above -------------------------------------------------------------------------------- /nagios-plugins/check_hostsonnetwork/README.md: -------------------------------------------------------------------------------- 1 | ## Check Wi-Fi channel 2 | ### Description 3 | 4 | This plugin was made in order to to display 5 | how many equipements are connected 6 | to my network. 7 | 8 | This script requiere the nagios user to be 9 | able to run `nmap`. 10 | 11 | ### Output 12 | #### Nagios Web Interface 13 | 14 | This is a exemple of the output of this script : 15 | > 17 hosts on 192.168.92.0/24 16 | 17 | 18 | #### Performance data 19 | 20 | * `hosts` : available hosts 21 | * `scantime` : NMAP scan time 22 | 23 | Exemple : 24 | > hosts=17 scantime=7.91s 25 | 26 | ### Configuration 27 | #### Command 28 | 29 | My command is defined as below : 30 | ``` 31 | define command { 32 | command_name check_hostsonnetwork 33 | command_line $USER1$/my_check_hostsonnetwork.sh $ARG1$ 34 | } 35 | ``` 36 | 37 | #### Service 38 | 39 | The service is defined with the network as an argument. 40 | ``` 41 | define service { 42 | use generic-service-with-perf 43 | host_name Namek 44 | service_description Hosts on network 45 | check_period 24x7 46 | check_interval 60 47 | max_check_attempts 3 48 | retry_interval 1 49 | notifications_enabled 1 50 | notification_options w,u,c,r 51 | notification_interval 0 52 | notification_period 24x7 53 | check_command check_hostsonnetwork!192.168.92.0/24 54 | icon_image network.png 55 | } 56 | 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /nagios-plugins/check_hostsonnetwork/my_check_hostsonnetwork.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # NMAP scanning in order to display 4 | # how many equipements are connected 5 | # to the network 6 | 7 | # Limitations : 8 | # The regex does not validate 9 | # completely the IP address format 10 | # IP address such as 333.444.555.666 11 | # will be accepted but CIDR mask must 12 | # stay beetween 0 and 32 13 | 14 | function call_for_help { 15 | echo -e "usage:\t $(basename $0)\t " 16 | echo -e "exemple: $(basename $0) 192.168.1.0/24" 17 | exit 0 18 | } 19 | 20 | function nmap_check { 21 | # Call : nmap network 22 | # This function only return result (last line) 23 | functioncommand=$($1 -sP -n $2 | tail -n 1) 24 | 25 | # if command failed, exit with 1 26 | if [ $? -ne 0 ] ; then 27 | exit 1 28 | fi 29 | 30 | echo $functioncommand 31 | exit 0 32 | } 33 | 34 | 35 | NMAP=$(which nmap) 36 | 37 | # Continue if only one argument is provided 38 | if [ $# -ne 1 ] ; then 39 | call_for_help 40 | exit 4 41 | fi 42 | 43 | # Check 44 | if [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\/([0-9]|[1-2][0-9]|3[0-2])$ ]]; then 45 | NETWORK_TESTED=$1 46 | else 47 | call_for_help 48 | exit 4 49 | fi 50 | 51 | # Call Nmap 52 | NMAP_RESULT=$(nmap_check $NMAP $NETWORK_TESTED) 53 | 54 | if [ $? -ne 0 ] ; then 55 | echo "NMAP Failed" 56 | exit 3 57 | fi 58 | 59 | ## Debug output 60 | #echo $NMAP_RESULT 61 | 62 | # Parsing info 63 | # hosts up 64 | 65 | HOST_UP=$(echo $NMAP_RESULT | cut -d'(' -f2 | cut -d')' -f1 | awk {'print $1'}) 66 | NMAP_DURATION=$(echo $NMAP_RESULT | rev | awk {'print $1" "$2'} | rev | awk {'print $1'}) 67 | 68 | ## Debug output 69 | #echo $HOST_UP 70 | ## Debug output 71 | #echo $NMAP_DURATION 72 | 73 | 74 | echo -n "$HOST_UP hosts on $NETWORK_TESTED" 75 | echo -n "|" 76 | echo "hosts=${HOST_UP} scantime=${NMAP_DURATION}s" 77 | 78 | exit 0 79 | -------------------------------------------------------------------------------- /nagios-plugins/check_json_output/README.md: -------------------------------------------------------------------------------- 1 | ## Check JSON output 2 | 3 | This plugin is made to check the value 4 | of a JSON file using `jq`. 5 | 6 | The argument needed are : 7 | 8 | 1. JSON file 9 | 2. `jq` filter 10 | 3. Expected value 11 | -------------------------------------------------------------------------------- /nagios-plugins/check_json_output/my_check_json_output.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Stock arguments 4 | file_to_check=$1 5 | json_filter=$2 6 | expected_value=$3 7 | 8 | # Nagios output 9 | OK=0 10 | WARN=1 11 | CRIT=2 12 | UNK=3 13 | 14 | # <-- Sanity checks 15 | if [[ ! $(which jq) ]]; then 16 | echo "jq not found" 17 | exit $UNK 18 | fi 19 | 20 | if [[ $# -ne 3 ]]; then 21 | echo "3 arguments needed" 22 | exit $UNK 23 | fi 24 | 25 | if [[ ! -f $file_to_check ]]; then 26 | echo "File ${file_to_check} not found" 27 | exit $UNK 28 | fi 29 | # Sanity checks --> 30 | 31 | # Run check 32 | result=$(jq -r "${json_filter}" "${file_to_check}") 33 | 34 | if [[ $result == "null" ]]; then 35 | echo "Filter ${json_filter} is empty" 36 | exit $WARN 37 | fi 38 | 39 | if [[ $result != $expected_value ]]; then 40 | echo "Unexpected value" 41 | exit $CRIT 42 | fi 43 | 44 | echo "OK" 45 | exit $OK -------------------------------------------------------------------------------- /nagios-plugins/check_sensors/README.md: -------------------------------------------------------------------------------- 1 | ## Check sensors 2 | 3 | ### Usage 4 | 5 | This plugin is made to parse the value of the `sensors` command. 6 | 7 | The arguments needed to run this script are : 8 | 9 | 1. Line filter 10 | 2. Matching n's value (when filter got multiple result) 11 | 3. Temperature position on line 12 | 4. Warning level 13 | 5. Critical level 14 | 15 | This can be difficult to understand so look at the exemples below. 16 | 17 | ### Exemples 18 | 19 | So, my `sensors` result look like this : 20 | 21 | ``` 22 | coretemp-isa-0000 23 | Adapter: ISA adapter 24 | Package id 0: +51.0°C (high = +100.0°C, crit = +100.0°C) 25 | Core 0: +47.0°C (high = +100.0°C, crit = +100.0°C) 26 | Core 4: +47.0°C (high = +100.0°C, crit = +100.0°C) 27 | Core 8: +49.0°C (high = +100.0°C, crit = +100.0°C) 28 | Core 12: +47.0°C (high = +100.0°C, crit = +100.0°C) 29 | Core 16: +49.0°C (high = +100.0°C, crit = +100.0°C) 30 | Core 20: +48.0°C (high = +100.0°C, crit = +100.0°C) 31 | Core 28: +50.0°C (high = +100.0°C, crit = +100.0°C) 32 | Core 29: +50.0°C (high = +100.0°C, crit = +100.0°C) 33 | Core 30: +50.0°C (high = +100.0°C, crit = +100.0°C) 34 | Core 31: +50.0°C (high = +100.0°C, crit = +100.0°C) 35 | 36 | acpitz-acpi-0 37 | Adapter: ACPI interface 38 | temp1: +27.8°C 39 | 40 | mt7921_phy0-pci-0400 41 | Adapter: PCI adapter 42 | temp1: +48.0°C 43 | 44 | nvme-pci-0100 45 | Adapter: PCI adapter 46 | Composite: +43.9°C (low = -0.1°C, high = +76.8°C) 47 | (crit = +78.8°C) 48 | ``` 49 | 50 | First, I want the "Package id 0" sensor value. 51 | So my line filter is gonna be `Package`. 52 | As this value is only present one time in the output, the second argument is `1`. 53 | The temperature value is the fourth value of the line (`4`). 54 | I want the warning value to be `60` and `80` for the critical value. 55 | 56 | So, for this sensor, the command will be : 57 | 58 | ```bash 59 | ./my_check_sensors.sh Package 1 4 60 80 60 | ``` 61 | 62 | I also want the motherboard sensors (mt7921_phy0-pci-0400) but the only 63 | filter available is `temp1` wich is present on two lines. 64 | By putting the second argument value to 2, the script will get `temp1` second value ! 65 | 66 | So, for this sensor, the command will be : 67 | 68 | ```bash 69 | ./my_check_sensors.sh temp1 2 2 60 80 70 | ``` 71 | 72 | ### Limitations 73 | 74 | - Value is treated as Celsius 75 | - `sensors` is not tested 76 | -------------------------------------------------------------------------------- /nagios-plugins/check_sensors/my_check_sensors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Author : Anup SUNGUM 4 | 5 | # This script will parse `sensors` command result 6 | # and compare it with the warning and critical value. 7 | # To make is simple, the decimal are truncated ! 8 | 9 | # $1 :: line filter 10 | # $2 :: matching n's value (when filter got multiple result) 11 | # $3 :: arg position on line 12 | # $4 :: Warning level 13 | # $5 :: Critical level 14 | 15 | # Sanity check 16 | if [ "$#" -ne "5" ];then 17 | echo "UNKNOWN - Expected 5 argument but got $#" 18 | exit 3 19 | fi 20 | 21 | # Put args in vars 22 | filter="$1" 23 | matchValue="$2" 24 | argPos="$3" 25 | warnLevel="$4" 26 | critLevel="$5" 27 | 28 | # Get the value 29 | value=$(sensors | grep -m $matchValue $filter | tail -n 1 | awk '{print $"'"$argPos"'"}' | tr -d '+°C' | cut -d '.' -f1) 30 | 31 | # Above critical ? 32 | result=$(echo $value - $critLevel | bc) 33 | if [ "$result" -gt "0" ]; then 34 | echo "CRITICAL - ${value}°C is over ${critLevel}°C|temp=${value}°C" 35 | exit 2 36 | fi 37 | 38 | # Above warning ? 39 | result=$(echo $value - $warnLevel | bc) 40 | if [ "$result" -gt "0" ]; then 41 | echo "WARNING - ${value}°C is over ${warnLevel}°C|temp=${value}°C" 42 | exit 1 43 | fi 44 | 45 | # Not critical or warning => OK 46 | echo "OK - ${value}°C|temp=${value}°C" 47 | exit 0 48 | -------------------------------------------------------------------------------- /nagios-plugins/check_uptime/README.md: -------------------------------------------------------------------------------- 1 | ## Uptime 2 | 3 | This plugin display the Uptime in two differant way : 4 | * Date of last boot 5 | * Uptime in an human readable way 6 | 7 | This is a exemple of the output of this script : 8 | > Server is up for 168 days 22 hours 45 minutes from 2019-09-21 17:43 9 | 10 | The uptime in second is passed to whatever performance data processing it has configured. 11 | 12 | Some improvement can be donne. 13 | Here is my task list : 14 | - [ ] Add help 15 | - [ ] Allow to add warning and critical threshold 16 | -------------------------------------------------------------------------------- /nagios-plugins/check_uptime/my_check_uptime.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | #set -v 3 | 4 | # Last boot time (%Y-%m-%d %H:%M) 5 | BOOTDATE=$(date -r /proc/1 '+%F %R') 6 | if [ $? -ne 0 ]; then 7 | echo "Unable to retrieve boot date" 8 | exit 3 9 | fi 10 | 11 | # Uptime in seconds 12 | UPTIME=$(cat /proc/uptime | awk '{print $1}') 13 | if [ $? -ne 0 ]; then 14 | echo "Unable to retrieve uptime" 15 | exit 3 16 | fi 17 | 18 | # Uptime Human Readable 19 | UPTIMEHR=$(eval "echo $(date -ud "@$UPTIME" +'$((%s/3600/24)) days %H hours %M minutes')") 20 | if [ $? -ne 0 ]; then 21 | echo "Unable to convert uptime" 22 | exit 3 23 | fi 24 | 25 | # Write result 26 | echo "Server is up for $UPTIMEHR from $BOOTDATE|uptime=${UPTIME}s" 27 | exit 0 -------------------------------------------------------------------------------- /nagios-plugins/check_wifichannels/README.md: -------------------------------------------------------------------------------- 1 | ## Check Wi-Fi channel 2 | ### Description 3 | 4 | This plugin was made in order to scan for 5 | the channels used by my SSID. 6 | My Wi-Fi router is provided by my ISP, 7 | I couldn't find a way to get these info from it. 8 | My Nagios server got a none used Wireless card, 9 | so I took advantage of it with this script. 10 | 11 | To make sure this script may work for you, 12 | try manually the `iwlist` command : 13 | ```bash 14 | sudo iwlist scanning essid 15 | ``` 16 | 17 | ### Output 18 | #### Nagios Web Interface 19 | 20 | This is a exemple of the output of this script : 21 | > Channels 11, 56 22 | 23 | 24 | #### Performance data 25 | 26 | The value `CELL24` is for the 2,4 GHz band and 27 | `CELL5` for the 5 GHz band. 28 | > CELL24=11, CELL5=56 29 | 30 | ### Configuration 31 | #### Command 32 | 33 | My command is defined as below : 34 | ``` 35 | define command { 36 | command_name my_check_wifichannels 37 | command_line $USER1$/my_check_wifichannels.sh $ARG1$ $ARG2$ 38 | } 39 | ``` 40 | 41 | #### Service 42 | 43 | The service is defined with `wlan0` as the wireless scanning interface 44 | and `My_SSID` as the SSID I'm scanning (my SSID :wink:). 45 | 46 | ``` 47 | define service { 48 | use generic-service-with-perf 49 | host_name Sadara 50 | service_description Wi-Fi Channels 51 | check_period 24x7 52 | check_interval 60 53 | max_check_attempts 3 54 | retry_interval 1 55 | notifications_enabled 1 56 | notification_options w,u,c,r 57 | notification_interval 0 58 | notification_period 24x7 59 | check_command my_check_wifichannels!wlan0!My_SSID 60 | icon_image wifi.png 61 | } 62 | ``` 63 | 64 | -------------------------------------------------------------------------------- /nagios-plugins/check_wifichannels/my_check_wifichannels.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script use 'iwlist' to scan for 4 | # wireless cells about the provided SSID. 5 | # 6 | # The result is rendered as a list of channels 7 | # and as performance data : 8 | # "CELL24" for a 2,4 GHz cell 9 | # "CELL5" for a 5 GHz cell 10 | # 11 | # Return state : 12 | # OK 13 | # if iwlist run successfully 14 | # UNKNOWN 15 | # if it fail (does not removed temp files) 16 | # check '/tmp/*wifichannel' files 17 | # 18 | # Argument : 19 | # $1 :: Wireless interface 20 | # $2 :: SSID 21 | # exemple : 22 | # my_check_wifichannels.sh wlan0 My_SSID 23 | 24 | 25 | IWLIST=$(which iwlist) 26 | 27 | # Temporary files 28 | IWLIST_RESULT="$(mktemp --suffix="wifichannel")" 29 | PARSING_RESULT="$(mktemp --suffix="wifichannel")" 30 | CHANNEL_LIST="$(mktemp --suffix="wifichannel")" 31 | CHANNEL_PERFDATA="$(mktemp --suffix="wifichannel")" 32 | 33 | function ssid_check { 34 | # $1 :: 'iwlist' command 35 | # $2 :: wireless interface 36 | # $3 :: SSID 37 | # sudo iwlist INTERFACE scanning essid MY_SSID 38 | sudo $1 $2 scanning essid $3 > $IWLIST_RESULT 39 | 40 | # if command failed, exit with 1 41 | if [ $? -ne 0 ] ; then 42 | exit 1 43 | fi 44 | 45 | exit 0 46 | } 47 | 48 | function parsing_data { 49 | # ssid_check result in STDIN 50 | # output format "mac essid frq chn qual lvl enc" 51 | 52 | # Parsing method found on 53 | # https://stackoverflow.com/a/25395290/11699038 54 | # (modified) 55 | while IFS= read -r line; do 56 | ## test line contenst and parse as required 57 | [[ "$line" =~ Cell ]] && { cell=${line##*ll }; cell=${cell%% *}; } 58 | [[ "$line" =~ Address ]] && mac=${line##*ss: } 59 | [[ "$line" =~ \(Channel ]] && { chn=${line##*nel }; chn=${chn:0:$((${#chn}-1))}; } 60 | [[ "$line" =~ Frequen ]] && { frq=${line##*ncy:}; frq=${frq%% *}; } 61 | [[ "$line" =~ Quality ]] && { 62 | qual=${line##*ity=} 63 | qual=${qual%% *} 64 | lvl=${line##*evel=} 65 | lvl=${lvl%% *} 66 | } 67 | [[ "$line" =~ Encrypt ]] && enc=${line##*key:} 68 | [[ "$line" =~ ESSID ]] && { 69 | essid=${line##*ID:} 70 | echo "$cell $mac $essid $frq $chn $qual $lvl $enc" # output after ESSID 71 | } 72 | 73 | done < $1 74 | } 75 | 76 | function extract_data { 77 | # $1 :: parsing_data file 78 | 79 | while IFS= read -r line; do 80 | cell_channel=$(echo $line | awk {'print $5'}) 81 | echo -n $cell_channel", " >> $CHANNEL_LIST 82 | 83 | # 2.4 GHz ( channel ∈ ];15] ) 84 | if [ $cell_channel -le 14 ]; then 85 | channel_group="24" 86 | # 5 GHz ( channel ∈ [32;165] ) 87 | elif [ "$cell_channel" -ge 32 ] && [ "$cell_channel" -le 165 ]; then 88 | channel_group="5" 89 | # error case : return "N-" followed by cell number 90 | else 91 | channel_group="N-$(echo $line | awk {'print $1'})" 92 | fi 93 | echo -n "CELL"$channel_group"="$cell_channel", " >> $CHANNEL_PERFDATA 94 | done < $1 95 | 96 | # Remove last "," 97 | sed -i '$ s/..$//' $CHANNEL_LIST 98 | sed -i '$ s/..$//' $CHANNEL_PERFDATA 99 | 100 | echo "Channels "$(cat $CHANNEL_LIST)"|"$(cat $CHANNEL_PERFDATA) 101 | } 102 | 103 | function remove_temp_files { 104 | for i in $@ ; do 105 | rm $i 106 | done 107 | } 108 | 109 | iwlist_result=$(ssid_check $IWLIST $1 $2) 110 | if [ $? -ne 0 ] ; then 111 | echo "iwlist failed" 112 | exit 3 113 | fi 114 | 115 | parsing_data $IWLIST_RESULT | grep $2 > $PARSING_RESULT 116 | script_result=$(extract_data $PARSING_RESULT) 117 | 118 | remove_temp_files $IWLIST_RESULT $PARSING_RESULT $CHANNEL_LIST $CHANNEL_PERFDATA 119 | 120 | echo $script_result 121 | 122 | exit 0 -------------------------------------------------------------------------------- /nagios-plugins/gotify_nagios/README.md: -------------------------------------------------------------------------------- 1 | ## Gotify Nagios 2 | ### Description 3 | 4 | This plugin was made in order to send Nagios notification 5 | using [Gotify](https://gotify.net) with cURL. 6 | 7 | ``` 8 | Usage: gotify_nagios.sh [-h|--help] [-v|--version] 9 | : Gotify app token 10 | : Gotify URL 11 | : 'Host' or 'Service' 12 | -h, --help: Prints help 13 | -v, --version: Prints version 14 | ``` 15 | 16 | Some testing example : 17 | ```bash 18 | ./gotify_nagios.sh MYTOKEN https://gotify.example.com Host "PROBLEM" "UNREACHABLE" "GoogleDNS" "8.8.8.8" "Host check timed out after 30.04 seconds" 19 | ./gotify_nagios.sh MYTOKEN https://gotify.example.com Service "RECOVERY" "OK" "MyServer" "Wordpress" "HTTP OK: HTTP/1.1 200 OK - 30978 bytes in 0.095 second response time" 20 | ``` 21 | 22 | Which result in : 23 | ![](example_result.png) 24 | 25 | 26 | ### Configuration 27 | #### Contact 28 | 29 | This is my contact definition : 30 | ``` 31 | define contact { 32 | contact_name gotify_group 33 | host_notification_commands notify-host-by-gotify 34 | service_notification_commands notify-service-by-gotify 35 | host_notifications_enabled 1 36 | service_notifications_enabled 1 37 | service_notification_period 24x7 38 | host_notification_period 24x7 39 | service_notification_options w,u,c,r 40 | host_notification_options d,u,r 41 | } 42 | ``` 43 | 44 | Which is part of the default contact group : 45 | ``` 46 | define contactgroup { 47 | contactgroup_name admins 48 | alias Nagios Administrators 49 | members gotify_group 50 | } 51 | ``` 52 | 53 | #### Resource 54 | 55 | I stored my token and my Gotify server's URL in macros 56 | in the resource file `resource.cfg` like this example : 57 | 58 | ``` 59 | # Gotify 60 | ## API token 61 | $USER15$=Az3rtY 62 | ## URL 63 | $USER16$=https://gotify.example.com 64 | ``` 65 | 66 | 67 | #### Command 68 | 69 | My commands are defined as below : 70 | ``` 71 | define command { 72 | command_name notify-host-by-gotify 73 | command_line $USER1$/gotify_nagios.sh $USER15$ $USER16$ Host "$NOTIFICATIONTYPE$" "$HOSTSTATE$" "$HOSTNAME$" "$HOSTADDRESS$" "$HOSTOUTPUT$" 74 | } 75 | 76 | define command { 77 | command_name notify-service-by-gotify 78 | command_line $USER1$/gotify_nagios.sh $USER15$ $USER16$ Service "$NOTIFICATIONTYPE$" "$SERVICESTATE$" "$HOSTNAME$" "$SERVICEDESC$" "$SERVICEOUTPUT$" 79 | } 80 | ``` 81 | 82 | It's important that `Host` and `Service` are exactly written this way 83 | because the script check for one of theses exact value. 84 | *I made it like that because I may build differents notification template 85 | which is not the case by now.* 86 | 87 | 88 | ### Installation 89 | 90 | As you can see from the commands, I stored this script in the Nagios scripts directory. 91 | 92 | So, you may install it this way : 93 | ```bash 94 | wget https://raw.githubusercontent.com/anup92k/nagios-plugins/master/gotify_nagios/gotify_nagios.sh 95 | sudo cp gotify_nagios.sh /usr/local/nagios/libexec 96 | sudo chown nagios:nagios /usr/local/nagios/libexec/gotify_nagios.sh 97 | sudo chmod u+x /usr/local/nagios/libexec/gotify_nagios.sh 98 | ``` 99 | 100 | Don't forget to test it manually with the `nagios` user. 101 | 102 | 103 | ### Customisation 104 | 105 | You may want to change the icons I choose for the notifications. 106 | Do do that, search for "emoji" in the script content and change them ! -------------------------------------------------------------------------------- /nagios-plugins/gotify_nagios/example_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anup92k/scripts/ea89c154c1c720c5b51f7e85c4c4eb6e9bc40d50/nagios-plugins/gotify_nagios/example_result.png -------------------------------------------------------------------------------- /nagios-plugins/gotify_nagios/gotify_nagios.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | version="0.4" 3 | 4 | # -------------------------------------------------------- 5 | # Script to send Nagios notification with Gotify 6 | # -------------------------------------------------------- 7 | 8 | 9 | # Menu generated with https://argbash.io/ and some elbow grease 10 | 11 | # End the process 12 | # Args: 13 | # $1: The exit message (print to stderr) 14 | # $2: The exit code (default is 1) 15 | # if env var _PRINT_HELP is set to 'yes', the usage is print to stderr (prior to $1) 16 | die() 17 | { 18 | local _ret=$2 19 | test -n "$_ret" || _ret=1 20 | test "$_PRINT_HELP" = yes && print_help >&2 21 | echo "$1" >&2 22 | exit ${_ret} 23 | } 24 | 25 | 26 | # Evaluates whether a value passed to it begins by a character 27 | begins_with_short_option() 28 | { 29 | local first_option all_short_options='hv' 30 | first_option="${1:0:1}" 31 | test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0 32 | } 33 | 34 | 35 | # The positional args array has to be reset before the parsing, because it may already be defined 36 | _positionals=() 37 | 38 | # Call for Help ! 39 | print_help() 40 | { 41 | printf '%s\n' "Nagios Gotify help" 42 | printf 'Usage: %s [-h|--help] [-v|--version] \n' "$0" 43 | printf '\t%s\n' ": Gotify app token" 44 | printf '\t%s\n' ": Gotify URL" 45 | printf '\t%s\n' ": 'Host' or 'Service'" 46 | printf '\t%s\n' "-h, --help: Prints help" 47 | printf '\t%s\n' "-v, --version: Prints version" 48 | } 49 | 50 | 51 | # The parsing of the command-line 52 | parse_commandline() 53 | { 54 | _positionals_count=0 55 | while test $# -gt 0 56 | do 57 | _key="$1" 58 | case "$_key" in 59 | # The help argurment doesn't accept a value, 60 | # we expect the --help or -h, so we watch for them. 61 | -h|--help) 62 | print_help 63 | exit 0 64 | ;; 65 | -h*) 66 | print_help 67 | exit 0 68 | ;; 69 | -v|--version) 70 | echo "Nagios Gotify v$version" 71 | exit 0 72 | ;; 73 | -v*) 74 | echo "Nagios Gotify v$version" 75 | exit 0 76 | ;; 77 | *) 78 | _last_positional="$1" 79 | _positionals+=("$_last_positional") 80 | _positionals_count=$((_positionals_count + 1)) 81 | ;; 82 | esac 83 | shift 84 | done 85 | } 86 | 87 | 88 | # Return 0 if everything is OK, 1 if we have too little arguments 89 | # and 2 if we have too much arguments 90 | handle_passed_args_count() 91 | { 92 | local _required_args_string="'token', 'url', 'object_type', 'notification_type', 'state', 'host_name', 'description' and 'output'" 93 | test "${_positionals_count}" -ge 8 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 8 (namely: $_required_args_string), but got only ${_positionals_count}." 1 94 | test "${_positionals_count}" -le 8 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 8 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1 95 | } 96 | 97 | 98 | # Take arguments that we have received, and save them in variables of given names. 99 | # The 'eval' command is needed as the name of target variable is saved into another variable. 100 | assign_positional_args() 101 | { 102 | local _positional_name _shift_for=$1 103 | # We have an array of variables to which we want to save positional args values. 104 | # This array is able to hold array elements as targets. 105 | # As variables don't contain spaces, they may be held in space-separated string. 106 | _positional_names="_arg_token _arg_url _arg_object_type _arg_notification_type _arg_state _arg_host_name _arg_description _arg_output " 107 | 108 | shift "$_shift_for" 109 | for _positional_name in ${_positional_names} 110 | do 111 | test $# -gt 0 || break 112 | eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1 113 | shift 114 | done 115 | } 116 | 117 | # Call all the functions defined above that are needed to get the job done 118 | parse_commandline "$@" 119 | handle_passed_args_count 120 | assign_positional_args 1 "${_positionals[@]}" 121 | 122 | # End of menu 123 | 124 | 125 | # 'object_type' value should be 'host' or 'service' 126 | if [[ !($_arg_object_type = "Host" || $_arg_object_type = "Service") ]]; then 127 | _PRINT_HELP=yes die "FATAL ERROR: Wrong object_type value - we require 'Host' or 'Service', but got ${_arg_object_type}." 3 128 | fi 129 | 130 | 131 | ## At this point, all values are stored in values 132 | ## Uncomments for debug 133 | #echo "token : $_arg_token" 134 | #echo "url : $_arg_url" 135 | #echo "object_type : $_arg_object_type" 136 | #echo "notification_type : $_arg_notification_type" 137 | #echo "state : $_arg_state" 138 | #echo "host_name : $_arg_host_name" 139 | #echo "description : $_arg_description" # host address or service description 140 | #echo "output : $_arg_output" 141 | 142 | 143 | # Do you have cURL ? 144 | if [[ $(command -v curl >/dev/null 2>&1) ]]; then 145 | _PRINT_HELP=no die "FATAL ERROR: This script require cURL !" 4 146 | fi 147 | 148 | 149 | # Argument `state` (`$_arg_state`) made into icons ! 150 | # Icons from https://www.emojicopy.com 151 | case "$_arg_state" in 152 | UP) 153 | _icon="✅" 154 | ;; 155 | DOWN) 156 | _icon="🆘" 157 | ;; 158 | UNREACHABLE) 159 | _icon="💫" 160 | ;; 161 | OK) 162 | _icon="🆗" 163 | ;; 164 | WARNING) 165 | _icon="⚠️" 166 | ;; 167 | CRITICAL) 168 | _icon="❌" 169 | ;; 170 | UNKNOWN) 171 | _icon="❓" 172 | ;; 173 | *) 174 | _icon="" 175 | ;; 176 | esac 177 | 178 | 179 | # Processing notification content 180 | ## Title 181 | _title="$_icon " 182 | _title+="$_arg_object_type " 183 | _title+="$_arg_host_name: " 184 | _title+="$_arg_description - " 185 | _title+="$_arg_state" 186 | ## Message 187 | _message="$_arg_notification_type : " 188 | _message+="$_arg_output" 189 | 190 | 191 | # Finally cURLing ! 192 | curl_http_result=$(curl "${_arg_url}/message?token=${_arg_token}" -F "title=${_title}" -F "message=${_message}" -F "priority=10" --output /dev/null --silent --write-out %{http_code}) 193 | if [[ $? -ne 0 ]]; then 194 | _PRINT_HELP=no die "FATAL ERROR: cURL command failed !" 5 195 | fi 196 | 197 | # Check HTTP return code ("200" is OK) 198 | if [[ $curl_http_result -ne 200 ]]; then 199 | _PRINT_HELP=no die "FATAL ERROR: API call failed ! Return code is $curl_http_result instead of 200." 6 200 | fi 201 | 202 | 203 | exit 0 -------------------------------------------------------------------------------- /octolapse-local-rendering/README.md: -------------------------------------------------------------------------------- 1 | ## Octolapse rendering 2 | ### Purpose 3 | 4 | As I'm using OctoPi on a RPi 3, it takes some time 5 | to render the timelapse (convert photos into a video). 6 | I decided to make the timelapse with my computer so I 7 | can shutdown my printer earlier (my RPi is powered by the printer). 8 | 9 | Even better, I can easly output them using x265 ! 10 | 11 | 12 | ### Explanation 13 | 14 | Basically doing a timelapse with `ffmpeg` is just a simple command : 15 | ```bash 16 | ffmpeg -pattern_type glob -i "*.jpg" -c:v libx265 -crf 18 -vf "format=yuv420p" -tag:v hvc1 my_timelapse.mp4 17 | ``` 18 | 19 | As I want my video to got the same name as the GCODE file, 20 | I find it annoying to specify it on every time I run the command. 21 | 22 | The main part of this script it to deduce the file name based on 23 | the common part of the photos names. 24 | To do so, I use the metadata file to get the files list, get 25 | the common part and trim the remaining "0". 26 | 27 | As I'm using the metadata file, this script also check if all 28 | photos are really here. 29 | 30 | 31 | ### Prerequisite 32 | 33 | In order to use this, you'll need `ffmpeg` installed. 34 | ```bash 35 | sudo apt install ffmpeg 36 | ``` 37 | 38 | ### Using the script 39 | 40 | This script need to be run where the photos are located. 41 | So, unzip the archive and navigate to the directory 42 | where the photos are located and call the script from there. 43 | 44 | *My way of using it by putting the script in `~/bin` 45 | (as this path is in my `PATH`) so I can call it from anywhere.* 46 | -------------------------------------------------------------------------------- /octolapse-local-rendering/timelapse.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Created by : Anup92k 4 | # Date (YYYY-MM-DD) : 2021-05-13 5 | # Last update : 2021-05-15 6 | 7 | # Purpose : 8 | ## Render Octolapse result images locally 9 | ## 10 | ## 11 | 12 | # Metadata file 13 | META_DATA_FILE="metadata.csv" 14 | # Conversion parameters 15 | FFMPEG_PARAM=(-c:v libx265 -crf 18 -vf "format=yuv420p" -tag:v hvc1) 16 | # Change the value to "on" to see the debug 17 | _DEBUG="off" 18 | 19 | 20 | # Debug function 21 | function DEBUG(){ 22 | [ "$_DEBUG" == "on" ] && $@ 23 | } 24 | 25 | # Check if ffmpeg is installed 26 | if [[ $(dpkg-query -W -f='${Status}' ffmpeg 2>/dev/null | grep -c "ok installed") -eq 0 ]]; then 27 | echo "Package ffmpeg not found" 28 | exit 1 29 | fi 30 | 31 | # Check if the metadata file exist 32 | if [[ ! -f "$META_DATA_FILE" ]]; then 33 | echo "No MetaData file found in : $(pwd)" 34 | exit 2 35 | fi 36 | 37 | # Check if the metadata images really exist 38 | IMG_LIST=$(cat $META_DATA_FILE | cut -d',' -f2) 39 | for i in $IMG_LIST; do 40 | DEBUG echo "Testing $i" 41 | if [[ ! -f "$i" ]]; then 42 | echo "File $i provided in the metadata does not exist !" 43 | exit 3 44 | fi 45 | done 46 | 47 | # Store common part of the images names 48 | COMMON_NAME=$(cat $META_DATA_FILE | cut -d',' -f2 | grep -zoP '\A(.*)(?=.*?\n\1)' | tr '\0' '\n') 49 | 50 | DEBUG echo "###############" 51 | DEBUG echo "$IMG_LIST" 52 | DEBUG echo "###############" 53 | DEBUG echo "Common part of file list : $COMMON_NAME" 54 | 55 | # Initialize output name 56 | OUTPUT_NAME=$COMMON_NAME 57 | 58 | # Loop to remove multiple "0" at the end of the common name 59 | while [[ "${OUTPUT_NAME: -1}" = "0" ]]; do 60 | OUTPUT_NAME=${OUTPUT_NAME%?} 61 | DEBUG echo "While loop --> Trimmed OUTPUT_NAME : $OUTPUT_NAME" 62 | done 63 | 64 | DEBUG echo "Trimmed common part of file list : $OUTPUT_NAME" 65 | 66 | echo "#### FMPEG ####" 67 | 68 | # The commented command does not work : process only 10 images on my tests. 69 | # May be related to the max characters for the input list. 70 | # ffmpeg -pattern_type glob -i "${COMMON_NAME}*.jpg" -c:v libx265 -crf 18 -vf "format=yuv420p" -tag:v hvc1 $OUTPUT_NAME 71 | 72 | # Running ffmpeg ! 73 | ffmpeg -pattern_type glob -i "*.jpg" "${FFMPEG_PARAM[@]}" ${OUTPUT_NAME}.mp4 74 | if [[ $? -eq 0 ]]; then 75 | echo "###############" 76 | echo "Timelapse done ! See ${OUTPUT_NAME}.mp4" 77 | fi 78 | 79 | 80 | -------------------------------------------------------------------------------- /power-notify/README.md: -------------------------------------------------------------------------------- 1 | ## Gotify notification at boot and shutdown 2 | 3 | The purpose of this script is to get a notification 4 | at system boot and shutdown using 5 | [Gotify](https://gotify.net) with cURL. 6 | 7 | I'm using `systemd` to get this running as a service. 8 | 9 | 10 | ### Installation 11 | #### Configuration file (optional) 12 | 13 | Copy `gotify-notify.conf` to the `/etc/` folder or be lazy : 14 | ``` 15 | wget https://raw.githubusercontent.com/anup92k/scripts/master/power-notify/gotify-notify.conf -O /etc/gotify-notify.conf 16 | ``` 17 | 18 | Don't forget to update it with your personnal credentials ! 19 | 20 | 21 | #### Script 22 | ``` 23 | wget https://raw.githubusercontent.com/anup92k/scripts/master/power-notify/power-notify.sh -O /usr/local/sbin/power-notify.sh 24 | chmod u+x /usr/local/sbin/power-notify.sh 25 | ``` 26 | 27 | If you are not using the configuration file, 28 | don't forget to update thoses variables : 29 | 30 | * `GOTIFY_URL` 31 | * `GOTIFY_TOKEN` 32 | 33 | 34 | #### Activation 35 | 36 | This service description make the script run at boot 37 | after the server is online. 38 | This way, it's gonna be called before stopping the 39 | network when shuting down. 40 | 41 | ``` 42 | [Unit] 43 | Description=Power Notify 44 | After=network-online.target 45 | 46 | [Service] 47 | Type=oneshot 48 | RemainAfterExit=yes 49 | ExecStart=/usr/local/sbin/power-notify.sh up 50 | ExecStop=/usr/local/sbin/power-notify.sh down 51 | 52 | [Install] 53 | WantedBy=multi-user.target 54 | ``` 55 | 56 | Copy the content above as `/etc/systemd/system/power-notify.service` or : 57 | ``` 58 | wget https://raw.githubusercontent.com/anup92k/scripts/master/power-notify/power-notify.service -O /etc/systemd/system/power-notify.service 59 | ``` 60 | 61 | Then, reload configuration file : 62 | ``` 63 | systemctl daemon-reload 64 | ``` 65 | 66 | Enable the service : 67 | ``` 68 | systemctl enable power-notify.service 69 | ``` 70 | 71 | Start the service to see if it works : 72 | ``` 73 | systemctl start power-notify.service 74 | ``` 75 | 76 | As `RemainAfterExit` is set to yes, 77 | `systemctl status power-notify.service` should 78 | give you an active state. 79 | 80 | 81 | ### Troubleshooting 82 | 83 | Since this script is run as a service, errors 84 | are logged using `logger`. This mean you can check 85 | for failure in your log file (`tail /var/log/syslog`). 86 | 87 | You can change the log tag editing the variable `LOGGER_TITLE` 88 | (set as `power-notify` by default). -------------------------------------------------------------------------------- /power-notify/gotify-notify.conf: -------------------------------------------------------------------------------- 1 | #-------------------------------# 2 | # /etc/gotify-notify.conf # 3 | #-------------------------------# 4 | 5 | [general] 6 | server-url=https://YourGotifyServer.url 7 | access-token=YourTokenHere 8 | -------------------------------------------------------------------------------- /power-notify/power-notify.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Power Notify 3 | After=network-online.target 4 | 5 | [Service] 6 | Type=oneshot 7 | RemainAfterExit=yes 8 | ExecStart=/usr/local/sbin/power-notify.sh up 9 | ExecStop=/usr/local/sbin/power-notify.sh down 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /power-notify/power-notify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Gotify parameters (if not using configuration file) 4 | GOTIFY_URL="https://gotify.blablabla.mu" 5 | GOTIFY_TOKEN="Az3rTy" 6 | # Tag to see in log file 7 | LOGGER_TITLE="power-notify" 8 | 9 | # Configuration file 10 | FILE_CONF="/etc/gotify-notify.conf" 11 | # Get servername 12 | SERVER_NAME=$(uname -n) 13 | 14 | # Handling configuration file (if present) 15 | if [[ -f "${FILE_CONF}" ]]; then 16 | GOTIFY_URL=$(grep "server-url=" $FILE_CONF | cut -d'=' -f2) 17 | GOTIFY_TOKEN=$(grep "access-token=" $FILE_CONF | cut -d'=' -f2) 18 | fi 19 | 20 | # Testing correct number of argument 21 | if [ $# -ne 1 ]; then 22 | echo "Not argument provided, use option '-h' for help" 23 | logger -t $LOGGER_TITLE "Not argument provided" 24 | exit 1 25 | fi 26 | 27 | option=$1 28 | 29 | case $option in 30 | up) 31 | GOTIFY_TITLE="⬆️ $SERVER_NAME started" 32 | GOTIFY_MESSAGE="System just boot up" 33 | ;; 34 | down) 35 | GOTIFY_TITLE="⬇️ $SERVER_NAME is shutting down" 36 | GOTIFY_MESSAGE="System is going to shutdown" 37 | ;; 38 | -h) 39 | echo "Usage :" 40 | echo "$(basename $0) [up|down|-h]" 41 | echo "up : for booting up" 42 | echo "down : for shuting down" 43 | echo "-h : display this help" 44 | echo "" 45 | exit 0 46 | ;; 47 | \?) 48 | echo "invalid $option argument, use option '-h' for help" 49 | logger -t $LOGGER_TITLE "invalid $option argument" 50 | exit 2 51 | ;; 52 | esac 53 | 54 | # Gotify Checks 55 | ## Do you have cURL ? 56 | if [[ $(command -v curl >/dev/null 2>&1) ]]; then 57 | logger -t $LOGGER_TITLE "FATAL ERROR: This script require cURL !" 58 | exit 3 59 | fi 60 | # Test Gotify server connexion (health check) 61 | curlHttpResult=$(curl "${GOTIFY_URL}/health?token=${GOTIFY_TOKEN}" --output /dev/null --silent --write-out %{http_code}) 62 | if [[ $? -ne 0 ]]; then 63 | logger -t $LOGGER_TITLE "FATAL ERROR: cURL health check command failed !" 64 | exit 4 65 | fi 66 | # Check HTTP return code ("200" is OK) 67 | if [[ $curlHttpResult -ne 200 ]]; then 68 | logger -t $LOGGER_TITLE "FATAL ERROR: API call failed ! Return code is $curlHttpResult instead of 200." 69 | exit 5 70 | fi 71 | 72 | 73 | # Notify power state 74 | curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \ 75 | -F "title=${GOTIFY_TITLE}" \ 76 | -F "message=${GOTIFY_MESSAGE}" \ 77 | -F "priority=8" \ 78 | --output /dev/null --silent 79 | 80 | exit 0 81 | -------------------------------------------------------------------------------- /update-notifier/README.md: -------------------------------------------------------------------------------- 1 | ## Gotify notification about updates 2 | 3 | The purpose of this script is to get a notification 4 | about available updates using 5 | [Gotify](https://gotify.net) with cURL. 6 | 7 | Update (2025/04/11) : Notify if reboot is required ! 8 | 9 | 10 | ### Installation 11 | #### Configuration file (optional) 12 | 13 | Copy `gotify-notify.conf` to the `/etc/` folder or be lazy : 14 | ``` 15 | wget https://raw.githubusercontent.com/anup92k/scripts/master/update-notifier/gotify-notify.conf -O /etc/gotify-notify.conf 16 | ``` 17 | 18 | Don't forget to update it with your personnal credentials ! 19 | 20 | 21 | #### Script 22 | ``` 23 | wget https://raw.githubusercontent.com/anup92k/scripts/master/update-notifier/my-unattended-upgrades-notify.sh -O /usr/local/sbin/my-unattended-upgrades-notify.sh 24 | chmod u+x /usr/local/sbin/my-unattended-upgrades-notify.sh 25 | ``` 26 | 27 | If you are not using the configuration file, 28 | don't forget to update thoses variables : 29 | 30 | * `GOTIFY_URL` 31 | * `GOTIFY_TOKEN` 32 | 33 | 34 | #### Cron 35 | 36 | I run this script every day at 8 o'clock on my servers using `cron`. 37 | 38 | Here is my definition : 39 | ``` 40 | 0 8 * * * /usr/local/sbin/my-unattended-upgrades-notify.sh 41 | ``` 42 | -------------------------------------------------------------------------------- /update-notifier/gotify-notify.conf: -------------------------------------------------------------------------------- 1 | #-------------------------------# 2 | # /etc/gotify-notify.conf # 3 | #-------------------------------# 4 | 5 | [general] 6 | server-url=https://YourGotifyServer.url 7 | access-token=YourTokenHere 8 | -------------------------------------------------------------------------------- /update-notifier/my-unattended-upgrades-notify.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Send Gotify notifications about 4 | # ubuntu pending updates 5 | 6 | # Gotify parameters (if not using configuration file) 7 | GOTIFY_URL="https://gotify.blablabla.mu" 8 | GOTIFY_TOKEN="Az3rTy" 9 | # Tag to see in log file 10 | LOGGER_TITLE="my-unattended-upgrades-notify" 11 | 12 | # Configuration file 13 | FILE_CONF="/etc/gotify-notify.conf" 14 | 15 | # Handling configuration file (if present) 16 | if [[ -f "${FILE_CONF}" ]]; then 17 | GOTIFY_URL=$(grep "server-url=" $FILE_CONF | cut -d'=' -f2) 18 | GOTIFY_TOKEN=$(grep "access-token=" $FILE_CONF | cut -d'=' -f2) 19 | fi 20 | 21 | # Server info 22 | server_name=$(uname -n) 23 | updates_available=$(cat /var/lib/update-notifier/updates-available | grep -e ^[0-9]) 24 | release=$(lsb_release -d | cut -d$'\t' -f2) 25 | 26 | 27 | # Handle no updates 28 | if [[ -z "$updates_available" ]]; then 29 | updates_available="No updates available." 30 | fi 31 | 32 | 33 | # Processing notification content 34 | ## Title 35 | title="$server_name ($release)" 36 | 37 | ## Message 38 | message="$updates_available" 39 | 40 | 41 | # Append message if reboot is required 42 | if [ -f /var/run/reboot-required ]; then 43 | message="${message} 44 | $(cat /var/run/reboot-required)" 45 | fi 46 | 47 | 48 | # Finally cURLing ! 49 | curl_http_result=$(curl "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" -F "title=${title}" -F "message=${message}" -F "priority=5" --output /dev/null --silent --write-out %{http_code}) 50 | if [[ $? -ne 0 ]]; then 51 | logger -t $LOGGER_TITLE "FATAL ERROR: cURL command failed !" 52 | exit 1 53 | fi 54 | 55 | # Check HTTP return code ("200" is OK) 56 | if [[ $curl_http_result -ne 200 ]]; then 57 | logger -t $LOGGER_TITLE "FATAL ERROR: API call failed ! Return code is $curl_http_result instead of 200." 58 | exit 2 59 | fi 60 | 61 | logger -t $LOGGER_TITLE "Notification sent" 62 | 63 | exit 0 64 | --------------------------------------------------------------------------------