You've already forked tarr
							
							Compare commits
	
		
			2 Commits
		
	
	
		
			43478f233f
			...
			72422e032d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 72422e032d | |||
| 2f17abedb9 | 
| @@ -2,6 +2,7 @@ package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"time" | ||||
| @@ -26,7 +27,9 @@ 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.Execute() | ||||
| 	if err := rootCmd.Execute(); err != nil { | ||||
| 		log.Fatalln(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runE(cmd *cobra.Command, args []string) error { | ||||
| @@ -84,10 +87,16 @@ func runWatch(cmd *cobra.Command, args []string) error { | ||||
| 		select { | ||||
| 		case <-cmd.Context().Done(): | ||||
| 			return nil | ||||
| 		case err := <-errorChannel: | ||||
| 			logrus.WithError(err).Errorln("Received from config watcher") | ||||
| 		case err, open := <-errorChannel: | ||||
| 			if !open { | ||||
| 				return fmt.Errorf("error channel has been closed") | ||||
| 			} | ||||
| 			logrus.WithError(err).Errorln("received from config watcher") | ||||
| 		case <-timer.C: | ||||
| 			writeConfig(cachedConfig, dest) | ||||
| 			err = writeConfig(cachedConfig, dest) | ||||
| 			if err != nil { | ||||
| 				logrus.WithError(err).Errorln("failed to write config") | ||||
| 			} | ||||
| 		case config := <-configChannel: | ||||
| 			cachedConfig = config | ||||
| 			timer.Reset(waitFor) | ||||
| @@ -105,18 +114,23 @@ func writeConfig(config *domain.Config, dest string) error { | ||||
| 	case len(dest) > 0: | ||||
| 		dirname := filepath.Dir(dest) | ||||
|  | ||||
| 		// #nosec G301 | ||||
| 		err := os.MkdirAll(dirname, 0755) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// #nosec G304 | ||||
| 		f, err := os.Create(dest) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		defer func() { _ = f.Close() }() | ||||
|  | ||||
| 		f.WriteString(config.API.Token) | ||||
| 		_, err = f.WriteString(config.API.Token) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package main | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"time" | ||||
|  | ||||
| 	"git.cryptic.systems/volker.raschek/tarr/pkg/config" | ||||
| @@ -95,7 +96,10 @@ healarr sonarr https://sonarr.example.com:8443 --api-token my-token`, | ||||
| 	rootCmd.PersistentFlags().Bool("insecure", false, "Trust insecure TLS certificates") | ||||
| 	rootCmd.PersistentFlags().Duration("timeout", time.Minute, "Timeout") | ||||
|  | ||||
| 	rootCmd.Execute() | ||||
| 	err := rootCmd.Execute() | ||||
| 	if err != nil { | ||||
| 		log.Fatalln(err) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runBazarrE(cmd *cobra.Command, args []string) error { | ||||
| @@ -152,7 +156,7 @@ func runE(cmd *cobra.Command, args []string, queryKey string) error { | ||||
|  | ||||
| 	switch { | ||||
| 	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: | ||||
| 		err = health.NewReadinessProbe(args[0]). | ||||
| 			QueryAdd(queryKey, apiToken). | ||||
| @@ -175,7 +179,7 @@ func runE(cmd *cobra.Command, args []string, queryKey string) error { | ||||
| 			return err | ||||
| 		} | ||||
| 	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 | ||||
|   | ||||
| @@ -46,11 +46,12 @@ type YAMLConfig struct { | ||||
| // Read reads the config struct from a file. The decoding format will be determined by the file extension like | ||||
| // `xml` or `yaml`. | ||||
| func ReadConfig(name string) (*domain.Config, error) { | ||||
| 	// #nosec G304 | ||||
| 	f, err := os.Open(name) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| 	defer func() { _ = f.Close() }() | ||||
|  | ||||
| 	switch { | ||||
| 	case strings.HasSuffix(name, "xml"): | ||||
| @@ -58,7 +59,7 @@ func ReadConfig(name string) (*domain.Config, error) { | ||||
| 	case strings.HasSuffix(name, "yml") || strings.HasSuffix(name, "yaml"): | ||||
| 		return readYAMLConfig(f) | ||||
| 	default: | ||||
| 		return nil, fmt.Errorf("Unsupported file extension") | ||||
| 		return nil, fmt.Errorf("unsupported file extension") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -97,8 +98,8 @@ func readYAMLConfig(r io.Reader) (*domain.Config, error) { | ||||
| } | ||||
|  | ||||
| func WatchConfig(ctx context.Context, name string) (<-chan *domain.Config, <-chan error) { | ||||
| 	configChannel := make(chan *domain.Config, 0) | ||||
| 	errorChannel := make(chan error, 0) | ||||
| 	configChannel := make(chan *domain.Config) | ||||
| 	errorChannel := make(chan error) | ||||
|  | ||||
| 	go func() { | ||||
| 		wait := time.Second * 3 | ||||
| @@ -110,14 +111,18 @@ func WatchConfig(ctx context.Context, name string) (<-chan *domain.Config, <-cha | ||||
| 			errorChannel <- err | ||||
| 			return | ||||
| 		} | ||||
| 		watcher.Add(name) | ||||
| 		err = watcher.Add(name) | ||||
| 		if err != nil { | ||||
| 			errorChannel <- err | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		for { | ||||
| 			select { | ||||
| 			case <-ctx.Done(): | ||||
| 				close(configChannel) | ||||
| 				close(errorChannel) | ||||
| 				break | ||||
| 				return | ||||
| 			case event, open := <-watcher.Events: | ||||
| 				if !open { | ||||
| 					errorChannel <- fmt.Errorf("FSWatcher closed channel: %w", err) | ||||
| @@ -145,11 +150,12 @@ 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 | ||||
| // `xml` or `yaml`. | ||||
| func WriteConfig(name string, config *domain.Config) error { | ||||
| 	// #nosec G304 | ||||
| 	f, err := os.Create(name) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	defer f.Close() | ||||
| 	defer func() { _ = f.Close() }() | ||||
|  | ||||
| 	switch { | ||||
| 	case strings.HasSuffix(name, "xml"): | ||||
| @@ -157,13 +163,13 @@ func WriteConfig(name string, config *domain.Config) error { | ||||
| 	case strings.HasSuffix(name, "yml") || strings.HasSuffix(name, "yaml"): | ||||
| 		return writeYAMLConfig(f, config) | ||||
| 	default: | ||||
| 		return fmt.Errorf("Unsupported file extension") | ||||
| 		return fmt.Errorf("unsupported file extension") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func writeXMLConfig(w io.Writer, config *domain.Config) error { | ||||
| 	xmlEncoder := xml.NewEncoder(w) | ||||
| 	defer xmlEncoder.Close() | ||||
| 	defer func() { _ = xmlEncoder.Close() }() | ||||
|  | ||||
| 	xmlConfig := &XMLConfig{ | ||||
| 		APIToken: config.API.Token, | ||||
| @@ -180,7 +186,7 @@ func writeXMLConfig(w io.Writer, config *domain.Config) error { | ||||
|  | ||||
| func writeYAMLConfig(w io.Writer, config *domain.Config) error { | ||||
| 	yamlEncoder := yaml.NewEncoder(w) | ||||
| 	defer yamlEncoder.Close() | ||||
| 	defer func() { _ = yamlEncoder.Close() }() | ||||
|  | ||||
| 	yamlConfig := &YAMLConfig{ | ||||
| 		Auth: YAMLConfigAuth{ | ||||
|   | ||||
| @@ -24,6 +24,7 @@ func TestReadWriteConfig_XML(t *testing.T) { | ||||
| 	t.Cleanup(func() { _ = os.RemoveAll(tmpDir) }) | ||||
|  | ||||
| 	expectedXMLConfigName := filepath.Join(tmpDir, "expected_config.xml") | ||||
| 	// #nosec G304 | ||||
| 	f, err := os.Create(expectedXMLConfigName) | ||||
| 	require.NoError(err) | ||||
|  | ||||
| @@ -38,6 +39,7 @@ func TestReadWriteConfig_XML(t *testing.T) { | ||||
| 	err = config.WriteConfig(actualXMLConfigName, actualConfig) | ||||
| 	require.NoError(err) | ||||
|  | ||||
| 	// #nosec G304 | ||||
| 	b, err := os.ReadFile(actualXMLConfigName) | ||||
| 	require.NoError(err) | ||||
| 	require.Equal(expectedXMLConfig, string(b)) | ||||
| @@ -51,6 +53,7 @@ func TestReadWriteConfig_YAML(t *testing.T) { | ||||
| 	t.Cleanup(func() { _ = os.RemoveAll(tmpDir) }) | ||||
|  | ||||
| 	expectedYAMLConfigName := filepath.Join(tmpDir, "expected_config.yaml") | ||||
| 	// #nosec G304 | ||||
| 	f, err := os.Create(expectedYAMLConfigName) | ||||
| 	require.NoError(err) | ||||
|  | ||||
| @@ -65,6 +68,7 @@ func TestReadWriteConfig_YAML(t *testing.T) { | ||||
| 	err = config.WriteConfig(actualYAMLConfigName, actualConfig) | ||||
| 	require.NoError(err) | ||||
|  | ||||
| 	// #nosec G304 | ||||
| 	b, err := os.ReadFile(actualYAMLConfigName) | ||||
| 	require.NoError(err) | ||||
| 	require.Equal(expectedYAMLConfig, string(b)) | ||||
|   | ||||
| @@ -9,8 +9,8 @@ import ( | ||||
| 	"net/url" | ||||
| ) | ||||
|  | ||||
| var ErrNoAPIToken error = errors.New("No API token defined") | ||||
| var ErrNoURL 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") | ||||
|  | ||||
| type ReadinessProbe struct { | ||||
| 	additionalQueryValues url.Values | ||||
| @@ -40,6 +40,7 @@ func (rp *ReadinessProbe) Run(ctx context.Context) error { | ||||
| 	httpClient := &http.Client{ | ||||
| 		Transport: &http.Transport{ | ||||
| 			TLSClientConfig: &tls.Config{ | ||||
| 				// #nosec G402 | ||||
| 				InsecureSkipVerify: rp.insecure, | ||||
| 			}, | ||||
| 		}, | ||||
| @@ -64,7 +65,7 @@ func (rp *ReadinessProbe) Run(ctx context.Context) error { | ||||
| 	} | ||||
|  | ||||
| 	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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user