Initial Commit
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

This commit is contained in:
2024-08-18 20:49:30 +02:00
commit f79b20e8a4
24 changed files with 1921 additions and 0 deletions

20
cmd/healarr/LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2024 Markus Pesch
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

37
cmd/healarr/Makefile Normal file
View File

@ -0,0 +1,37 @@
VERSION?=$(shell git describe --abbrev=0)+hash.$(shell git rev-parse --short HEAD)
# CONTAINER_RUNTIME
# The CONTAINER_RUNTIME variable will be used to specified the path to a
# container runtime. This is needed to start and run a container image.
CONTAINER_RUNTIME?=$(shell which podman)
# BIN
# ==============================================================================
healarr:
CGO_ENABLED=0 \
go build -ldflags "-X 'main.version=${VERSION}'" -o ${@} main.go
# CLEAN
# ==============================================================================
PHONY+=clean
clean:
rm --force --recursive healarr
# INSTALL
# ==============================================================================
PHONY+=install
install: healarr
install --directory ${DESTDIR}/etc/bash_completion.d
./healarr completion bash > ${DESTDIR}/etc/bash_completion.d/healarr
install --directory ${DESTDIR}${PREFIX}/bin
install --mode 0755 healarr ${DESTDIR}${PREFIX}/bin/healarr
install --directory ${DESTDIR}${PREFIX}/share/licenses/healarr
install --mode 0644 LICENSE ${DESTDIR}${PREFIX}/share/licenses/healarr/LICENSE
# PHONY
# ==============================================================================
# Declare the contents of the PHONY variable as phony. We keep that information
# in a variable so we can use it in if_changed.
.PHONY: ${PHONY}

182
cmd/healarr/main.go Normal file
View File

@ -0,0 +1,182 @@
package main
import (
"context"
"fmt"
"time"
"git.cryptic.systems/volker.raschek/tarr/pkg/config"
"git.cryptic.systems/volker.raschek/tarr/pkg/domain"
"git.cryptic.systems/volker.raschek/tarr/pkg/health"
"github.com/spf13/cobra"
)
var version string
func main() {
bazarrCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Example: `healarr bazarr https://bazarr.example.com:8443 --config /etc/bazarr/config.yaml
healarr bazarr https://bazarr.example.com:8443 --api-token my-token`,
RunE: runBazarrE,
Short: "Check if a bazarr instance is healthy",
Use: `bazarr`,
}
lidarrCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Example: `healarr lidarr https://lidarr.example.com:8443 --config /etc/lidarr/config.xml
healarr lidarr https://lidarr.example.com:8443 --api-token my-token`,
RunE: runLidarrE,
Short: "Check if a lidarr instance is healthy",
Use: `lidarr`,
}
prowlarrCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Example: `healarr prowlarr https://prowlarr.example.com:8443 --config /etc/prowlarr/config.xml
healarr prowlarr https://prowlarr.example.com:8443 --api-token my-token`,
RunE: runProwlarrE,
Short: "Check if a prowlarr instance is healthy",
Use: `prowlarr`,
}
radarrCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Example: `healarr radarr https://radarr.example.com:8443 --config /etc/radarr/config.xml
healarr radarr https://radarr.example.com:8443 --api-token my-token`,
RunE: runRadarrE,
Short: "Check if a radarr instance is healthy",
Use: `radarr`,
}
readarrCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Example: `healarr readarr https://readarr.example.com:8443 --config /etc/readarr/config.xml
healarr readarr https://readarr.example.com:8443 --api-token my-token`,
RunE: runReadarrrE,
Short: "Check if a readarr instance is healthy",
Use: `readarr`,
}
sabnzbdCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Example: `healarr sabnzbd https://sabnzbd.example.com:8443 --config /etc/sabnzbd/config.xml
healarr sabnzbd https://sabnzbd.example.com:8443 --api-token my-token`,
RunE: runSabNZBdE,
Short: "Check if a sabnzbd instance is healthy",
Use: `sabnzbd`,
}
sonarrCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Example: `healarr sonarr https://sonarr.example.com:8443 --config /etc/sonarr/config.xml
healarr sonarr https://sonarr.example.com:8443 --api-token my-token`,
RunE: runSonarr,
Short: "Check if a sonarr instance is healthy",
Use: `sonarr`,
}
rootCmd := &cobra.Command{
Args: cobra.ExactArgs(1),
Long: `healarr exits with a non zero exit code, when the *arr application is not healthy`,
Version: version,
Use: "healarr",
}
rootCmd.AddCommand(bazarrCmd)
rootCmd.AddCommand(lidarrCmd)
rootCmd.AddCommand(prowlarrCmd)
rootCmd.AddCommand(radarrCmd)
rootCmd.AddCommand(readarrCmd)
rootCmd.AddCommand(sabnzbdCmd)
rootCmd.AddCommand(sonarrCmd)
rootCmd.PersistentFlags().String("api-token", "", "Token to access the *arr application")
rootCmd.PersistentFlags().String("config", "", "Path to an XML or YAML config file")
rootCmd.PersistentFlags().Bool("insecure", false, "Trust insecure TLS certificates")
rootCmd.PersistentFlags().Duration("timeout", time.Minute, "Timeout")
rootCmd.Execute()
}
func runBazarrE(cmd *cobra.Command, args []string) error {
return runE(cmd, args, domain.BazarrAPIQueryKeyAPIToken)
}
func runLidarrE(cmd *cobra.Command, args []string) error {
return runE(cmd, args, domain.LidarrAPIQueryKeyAPIToken)
}
func runProwlarrE(cmd *cobra.Command, args []string) error {
return runE(cmd, args, domain.ProwlarrAPIQueryKeyAPIToken)
}
func runRadarrE(cmd *cobra.Command, args []string) error {
return runE(cmd, args, domain.RadarrAPIQueryKeyAPIToken)
}
func runReadarrrE(cmd *cobra.Command, args []string) error {
return runE(cmd, args, domain.ReadarrAPIQueryKeyAPIToken)
}
func runSabNZBdE(cmd *cobra.Command, args []string) error {
return runE(cmd, args, domain.SabNZBdAPIQueryKeyAPIToken)
}
func runSonarr(cmd *cobra.Command, args []string) error {
return runE(cmd, args, domain.SonarrAPIQueryKeyAPIToken)
}
func runE(cmd *cobra.Command, args []string, queryKey string) error {
apiToken, err := cmd.Flags().GetString("api-token")
if err != nil {
return err
}
configPath, err := cmd.Flags().GetString("config")
if err != nil {
return err
}
insecure, err := cmd.Flags().GetBool("insecure")
if err != nil {
return err
}
timeout, err := cmd.Flags().GetDuration("timeout")
if err != nil {
return err
}
readinessProbeCtx, cancel := context.WithTimeout(cmd.Context(), timeout)
defer func() { cancel() }()
switch {
case len(apiToken) <= 0 && len(configPath) <= 0:
return fmt.Errorf("At least --api-token oder --config must be defined")
case len(apiToken) > 0 && len(configPath) <= 0:
err = health.NewReadinessProbe(args[0]).
QueryAdd(queryKey, apiToken).
Insecure(insecure).
Run(readinessProbeCtx)
if err != nil {
return err
}
case len(apiToken) <= 0 && len(configPath) > 0:
config, err := config.ReadConfig(configPath)
if err != nil {
return err
}
err = health.NewReadinessProbe(args[0]).
QueryAdd(queryKey, config.API.Token).
Insecure(insecure).
Run(readinessProbeCtx)
if err != nil {
return err
}
default:
return fmt.Errorf("Neither --api-token nor --config can be used at the same time.")
}
return nil
}