Compare commits

..

1 Commits

Author SHA1 Message Date
43478f233f chore(deps): update docker/login-action action to v3.5.0
Some checks failed
Lint Golang files / Run golang CI linter (stable, ubuntu-latest-amd64) (pull_request) Failing after 28s
Lint Golang files / Run golang CI linter (stable, ubuntu-latest-amd64) (push) Failing after 28s
Lint Markdown files / Run markdown linter (pull_request) Successful in 4s
Lint Golang files / Run golang CI linter (stable, ubuntu-latest-arm64) (pull_request) Failing after 1m34s
Lint Golang files / Run golang CI linter (stable, ubuntu-latest-arm64) (push) Failing after 1m35s
2025-08-12 07:24:20 +00:00
5 changed files with 21 additions and 50 deletions

View File

@ -2,7 +2,6 @@ package main
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
@ -27,9 +26,7 @@ autharr /etc/lidarr/config.xml`,
} }
rootCmd.Flags().Bool("watch", false, "Listens for changes to the configuration and writes the token continuously to the output") rootCmd.Flags().Bool("watch", false, "Listens for changes to the configuration and writes the token continuously to the output")
if err := rootCmd.Execute(); err != nil { rootCmd.Execute()
log.Fatalln(err)
}
} }
func runE(cmd *cobra.Command, args []string) error { func runE(cmd *cobra.Command, args []string) error {
@ -87,16 +84,10 @@ func runWatch(cmd *cobra.Command, args []string) error {
select { select {
case <-cmd.Context().Done(): case <-cmd.Context().Done():
return nil return nil
case err, open := <-errorChannel: case err := <-errorChannel:
if !open { logrus.WithError(err).Errorln("Received from config watcher")
return fmt.Errorf("error channel has been closed")
}
logrus.WithError(err).Errorln("received from config watcher")
case <-timer.C: case <-timer.C:
err = writeConfig(cachedConfig, dest) writeConfig(cachedConfig, dest)
if err != nil {
logrus.WithError(err).Errorln("failed to write config")
}
case config := <-configChannel: case config := <-configChannel:
cachedConfig = config cachedConfig = config
timer.Reset(waitFor) timer.Reset(waitFor)
@ -114,23 +105,18 @@ func writeConfig(config *domain.Config, dest string) error {
case len(dest) > 0: case len(dest) > 0:
dirname := filepath.Dir(dest) dirname := filepath.Dir(dest)
// #nosec G301
err := os.MkdirAll(dirname, 0755) err := os.MkdirAll(dirname, 0755)
if err != nil { if err != nil {
return err return err
} }
// #nosec G304
f, err := os.Create(dest) f, err := os.Create(dest)
if err != nil { if err != nil {
return err return err
} }
defer func() { _ = f.Close() }() defer func() { _ = f.Close() }()
_, err = f.WriteString(config.API.Token) f.WriteString(config.API.Token)
if err != nil {
return err
}
} }
return nil return nil

View File

@ -3,7 +3,6 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"log"
"time" "time"
"git.cryptic.systems/volker.raschek/tarr/pkg/config" "git.cryptic.systems/volker.raschek/tarr/pkg/config"
@ -96,10 +95,7 @@ healarr sonarr https://sonarr.example.com:8443 --api-token my-token`,
rootCmd.PersistentFlags().Bool("insecure", false, "Trust insecure TLS certificates") rootCmd.PersistentFlags().Bool("insecure", false, "Trust insecure TLS certificates")
rootCmd.PersistentFlags().Duration("timeout", time.Minute, "Timeout") rootCmd.PersistentFlags().Duration("timeout", time.Minute, "Timeout")
err := rootCmd.Execute() rootCmd.Execute()
if err != nil {
log.Fatalln(err)
}
} }
func runBazarrE(cmd *cobra.Command, args []string) error { func runBazarrE(cmd *cobra.Command, args []string) error {
@ -156,7 +152,7 @@ func runE(cmd *cobra.Command, args []string, queryKey string) error {
switch { switch {
case len(apiToken) <= 0 && len(configPath) <= 0: case len(apiToken) <= 0 && len(configPath) <= 0:
return fmt.Errorf("at least --api-token oder --config must be defined") return fmt.Errorf("At least --api-token oder --config must be defined")
case len(apiToken) > 0 && len(configPath) <= 0: case len(apiToken) > 0 && len(configPath) <= 0:
err = health.NewReadinessProbe(args[0]). err = health.NewReadinessProbe(args[0]).
QueryAdd(queryKey, apiToken). QueryAdd(queryKey, apiToken).
@ -179,7 +175,7 @@ func runE(cmd *cobra.Command, args []string, queryKey string) error {
return err return err
} }
default: default:
return fmt.Errorf("neither --api-token nor --config can be used at the same time") return fmt.Errorf("Neither --api-token nor --config can be used at the same time.")
} }
return nil return nil

View File

@ -46,12 +46,11 @@ type YAMLConfig struct {
// Read reads the config struct from a file. The decoding format will be determined by the file extension like // Read reads the config struct from a file. The decoding format will be determined by the file extension like
// `xml` or `yaml`. // `xml` or `yaml`.
func ReadConfig(name string) (*domain.Config, error) { func ReadConfig(name string) (*domain.Config, error) {
// #nosec G304
f, err := os.Open(name) f, err := os.Open(name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer func() { _ = f.Close() }() defer f.Close()
switch { switch {
case strings.HasSuffix(name, "xml"): case strings.HasSuffix(name, "xml"):
@ -59,7 +58,7 @@ func ReadConfig(name string) (*domain.Config, error) {
case strings.HasSuffix(name, "yml") || strings.HasSuffix(name, "yaml"): case strings.HasSuffix(name, "yml") || strings.HasSuffix(name, "yaml"):
return readYAMLConfig(f) return readYAMLConfig(f)
default: default:
return nil, fmt.Errorf("unsupported file extension") return nil, fmt.Errorf("Unsupported file extension")
} }
} }
@ -98,8 +97,8 @@ func readYAMLConfig(r io.Reader) (*domain.Config, error) {
} }
func WatchConfig(ctx context.Context, name string) (<-chan *domain.Config, <-chan error) { func WatchConfig(ctx context.Context, name string) (<-chan *domain.Config, <-chan error) {
configChannel := make(chan *domain.Config) configChannel := make(chan *domain.Config, 0)
errorChannel := make(chan error) errorChannel := make(chan error, 0)
go func() { go func() {
wait := time.Second * 3 wait := time.Second * 3
@ -111,18 +110,14 @@ func WatchConfig(ctx context.Context, name string) (<-chan *domain.Config, <-cha
errorChannel <- err errorChannel <- err
return return
} }
err = watcher.Add(name) watcher.Add(name)
if err != nil {
errorChannel <- err
return
}
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
close(configChannel) close(configChannel)
close(errorChannel) close(errorChannel)
return break
case event, open := <-watcher.Events: case event, open := <-watcher.Events:
if !open { if !open {
errorChannel <- fmt.Errorf("FSWatcher closed channel: %w", err) errorChannel <- fmt.Errorf("FSWatcher closed channel: %w", err)
@ -150,12 +145,11 @@ func WatchConfig(ctx context.Context, name string) (<-chan *domain.Config, <-cha
// WriteConfig writes the config struct into the file. The encoding format will be determined by the file extension like // WriteConfig writes the config struct into the file. The encoding format will be determined by the file extension like
// `xml` or `yaml`. // `xml` or `yaml`.
func WriteConfig(name string, config *domain.Config) error { func WriteConfig(name string, config *domain.Config) error {
// #nosec G304
f, err := os.Create(name) f, err := os.Create(name)
if err != nil { if err != nil {
return err return err
} }
defer func() { _ = f.Close() }() defer f.Close()
switch { switch {
case strings.HasSuffix(name, "xml"): case strings.HasSuffix(name, "xml"):
@ -163,13 +157,13 @@ func WriteConfig(name string, config *domain.Config) error {
case strings.HasSuffix(name, "yml") || strings.HasSuffix(name, "yaml"): case strings.HasSuffix(name, "yml") || strings.HasSuffix(name, "yaml"):
return writeYAMLConfig(f, config) return writeYAMLConfig(f, config)
default: default:
return fmt.Errorf("unsupported file extension") return fmt.Errorf("Unsupported file extension")
} }
} }
func writeXMLConfig(w io.Writer, config *domain.Config) error { func writeXMLConfig(w io.Writer, config *domain.Config) error {
xmlEncoder := xml.NewEncoder(w) xmlEncoder := xml.NewEncoder(w)
defer func() { _ = xmlEncoder.Close() }() defer xmlEncoder.Close()
xmlConfig := &XMLConfig{ xmlConfig := &XMLConfig{
APIToken: config.API.Token, APIToken: config.API.Token,
@ -186,7 +180,7 @@ func writeXMLConfig(w io.Writer, config *domain.Config) error {
func writeYAMLConfig(w io.Writer, config *domain.Config) error { func writeYAMLConfig(w io.Writer, config *domain.Config) error {
yamlEncoder := yaml.NewEncoder(w) yamlEncoder := yaml.NewEncoder(w)
defer func() { _ = yamlEncoder.Close() }() defer yamlEncoder.Close()
yamlConfig := &YAMLConfig{ yamlConfig := &YAMLConfig{
Auth: YAMLConfigAuth{ Auth: YAMLConfigAuth{

View File

@ -24,7 +24,6 @@ func TestReadWriteConfig_XML(t *testing.T) {
t.Cleanup(func() { _ = os.RemoveAll(tmpDir) }) t.Cleanup(func() { _ = os.RemoveAll(tmpDir) })
expectedXMLConfigName := filepath.Join(tmpDir, "expected_config.xml") expectedXMLConfigName := filepath.Join(tmpDir, "expected_config.xml")
// #nosec G304
f, err := os.Create(expectedXMLConfigName) f, err := os.Create(expectedXMLConfigName)
require.NoError(err) require.NoError(err)
@ -39,7 +38,6 @@ func TestReadWriteConfig_XML(t *testing.T) {
err = config.WriteConfig(actualXMLConfigName, actualConfig) err = config.WriteConfig(actualXMLConfigName, actualConfig)
require.NoError(err) require.NoError(err)
// #nosec G304
b, err := os.ReadFile(actualXMLConfigName) b, err := os.ReadFile(actualXMLConfigName)
require.NoError(err) require.NoError(err)
require.Equal(expectedXMLConfig, string(b)) require.Equal(expectedXMLConfig, string(b))
@ -53,7 +51,6 @@ func TestReadWriteConfig_YAML(t *testing.T) {
t.Cleanup(func() { _ = os.RemoveAll(tmpDir) }) t.Cleanup(func() { _ = os.RemoveAll(tmpDir) })
expectedYAMLConfigName := filepath.Join(tmpDir, "expected_config.yaml") expectedYAMLConfigName := filepath.Join(tmpDir, "expected_config.yaml")
// #nosec G304
f, err := os.Create(expectedYAMLConfigName) f, err := os.Create(expectedYAMLConfigName)
require.NoError(err) require.NoError(err)
@ -68,7 +65,6 @@ func TestReadWriteConfig_YAML(t *testing.T) {
err = config.WriteConfig(actualYAMLConfigName, actualConfig) err = config.WriteConfig(actualYAMLConfigName, actualConfig)
require.NoError(err) require.NoError(err)
// #nosec G304
b, err := os.ReadFile(actualYAMLConfigName) b, err := os.ReadFile(actualYAMLConfigName)
require.NoError(err) require.NoError(err)
require.Equal(expectedYAMLConfig, string(b)) require.Equal(expectedYAMLConfig, string(b))

View File

@ -9,8 +9,8 @@ import (
"net/url" "net/url"
) )
var ErrNoAPIToken error = errors.New("no API token defined") var ErrNoAPIToken error = errors.New("No API token defined")
var ErrNoURL error = errors.New("no API token defined") var ErrNoURL error = errors.New("No API token defined")
type ReadinessProbe struct { type ReadinessProbe struct {
additionalQueryValues url.Values additionalQueryValues url.Values
@ -40,7 +40,6 @@ func (rp *ReadinessProbe) Run(ctx context.Context) error {
httpClient := &http.Client{ httpClient := &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
// #nosec G402
InsecureSkipVerify: rp.insecure, InsecureSkipVerify: rp.insecure,
}, },
}, },
@ -65,7 +64,7 @@ func (rp *ReadinessProbe) Run(ctx context.Context) error {
} }
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return fmt.Errorf("received unexpected HTTP status code %v", resp.StatusCode) return fmt.Errorf("Received unexpected HTTP status code %v", resp.StatusCode)
} }
return nil return nil