web-dev-qa-db-fra.com

Lecture dans une variable environnementale à l'aide de Viper Go

J'essaie de faire lire à Viper mes variables d'environnement, mais cela ne fonctionne pas. Voici ma configuration:

# app.yaml
dsn: RESTFUL_APP_DSN
jwt_verification_key: RESTFUL_APP_JWT_VERIFICATION_KEY
jwt_signing_key: RESTFUL_APP_JWT_SIGNING_KEY
jwt_signing_method: "HS256"

Et mon fichier config.go:

package config

import (
    "fmt"
    "strings"

    "github.com/go-ozzo/ozzo-validation"
    "github.com/spf13/viper"
)

// Config stores the application-wide configurations
var Config appConfig

type appConfig struct {
    // the path to the error message file. Defaults to "config/errors.yaml"
    ErrorFile string `mapstructure:"error_file"`
    // the server port. Defaults to 8080
    ServerPort int `mapstructure:"server_port"`
    // the data source name (DSN) for connecting to the database. required.
    DSN string `mapstructure:"dsn"`
    // the signing method for JWT. Defaults to "HS256"
    JWTSigningMethod string `mapstructure:"jwt_signing_method"`
    // JWT signing key. required.
    JWTSigningKey string `mapstructure:"jwt_signing_key"`
    // JWT verification key. required.
    JWTVerificationKey string `mapstructure:"jwt_verification_key"`
}

func (config appConfig) Validate() error {
    return validation.ValidateStruct(&config,
        validation.Field(&config.DSN, validation.Required),
        validation.Field(&config.JWTSigningKey, validation.Required),
        validation.Field(&config.JWTVerificationKey, validation.Required),
    )
}

func LoadConfig(configpaths ...string) error {
    v := viper.New()
    v.SetConfigName("app")
    v.SetConfigType("yaml")
    v.SetEnvPrefix("restful")
    v.AutomaticEnv()
    v.SetDefault("error_file", "config/errors.yaml")
    v.SetDefault("server_port", 1530)
    v.SetDefault("jwt_signing_method", "HS256")
    v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

    for _, path := range configpaths {
        v.AddConfigPath(path)
    }

    if err := v.ReadInConfig(); err != nil {
        return fmt.Errorf("Failed to read the configuration file: %s", err)
    }

    if err := v.Unmarshal(&Config); err != nil {
        return err
    }

    // Checking with this line. This is what I get:
    // RESTFUL_JWT_SIGNING_KEY
    fmt.Println("Sign Key: ", v.GetString("jwt_signing_key"))

    return Config.Validate()
}

Cette ligne fmt.Println("Sign Key: ", v.GetString("jwt_signing_key")) me donne juste la clé passée dans le fichier yaml RESTFUL_JWT_SIGNING_KEY. Je ne sais pas ce que je fais mal.

Selon le doc:

AutomaticEnv est un assistant puissant, en particulier lorsqu'il est combiné avec SetEnvPrefix. Lorsqu'il est appelé, Viper recherchera une variable d'environnement chaque fois qu'une demande viper.Get est faite. Il appliquera les règles suivantes. Il recherchera une variable d'environnement avec un nom correspondant à la clé en majuscule et préfixé par l'EnvPrefix s'il est défini.

Alors, pourquoi ne lit-il pas les variables d'environnement?

Utilisation de JSON

{
  "dsn": "RESTFUL_APP_DSN",
  "jwt_verification_key": "RESTFUL_APP_JWT_VERIFICATION_KEY",
  "jwt_signing_key": "RESTFUL_APP_JWT_SIGNING_KEY",
  "jwt_signing_method": "HS256"
}

Et mon analyseur ressemble à ceci:

// LoadConfigEnv loads configuration from the given list of paths and populates it into the Config variable.
// Environment variables with the prefix "RESTFUL_" in their names are also read automatically.
func LoadConfigEnv(environment string, configpaths ...string) error {
  v := viper.New()
  v.SetConfigName(environment)
  v.SetConfigType("json")
  v.SetEnvPrefix("restful")
  v.AutomaticEnv()
  v.SetDefault("jwt_signing_method", "HS256")
  v.SetDefault("error_file", "config/errors.yaml")
  v.SetDefault("server_port", 1530)
  v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))

  for _, path := range configpaths {
    v.AddConfigPath(path)
  }

  if err := v.ReadInConfig(); err != nil {
    return fmt.Errorf("Failed to read the configuration file: %s", err)
  }

  if err := v.Unmarshal(&Config); err != nil {
    return err
  }

  return Config.Validate()
}

Dans la fonction Validate, j'ai décidé de vérifier la structure Config, et voici ce que j'ai obtenu:

Config: {config/errors.yaml 1530 RESTFUL_APP_DSN HS256 RESTFUL_APP_JWT_SIGNING_KEY RESTFUL_APP_JWT_VERIFICATION_KEY}

7
Abubakar Oladeji

Le code dans ma question n'a pas réellement montré ce que j'essayais de résoudre. Après avoir compris ce qui n'allait pas, je crois, le code ici aurait fonctionné localement dans mon Environnement de développement.

Selon la documentation de Viper:

AutomaticEnv est un assistant puissant, en particulier lorsqu'il est combiné avec SetEnvPrefix. Lorsqu'il est appelé, Viper recherchera une variable d'environnement chaque fois qu'une demande viper.Get est faite. Il appliquera les règles suivantes. Il recherchera une variable d'environnement avec un nom correspondant à la clé en majuscule et préfixé par l'EnvPrefix s'il est défini.

Cette ligne ici dit tout:

Il recherchera une variable d'environnement avec un nom correspondant à la clé en majuscule et préfixé avec l'EnvPrefix si défini

Le préfixe défini avec v.SetEnvPrefix("restful") attendrait un .yaml avec une valeur clé de:

Exemple app.yaml:

dsn: RESTFUL_DSN

Notez que le DSN étant le Lowercased Key et qu'il est utilisé comme Suffix de RESTFUL_DSN

Dans ma situation, je faisais cela à la place:

Exemple app.yaml:

dsn: RESTFUL_APP_DSN

Donc, il cherchait RESTFUL_DSN dans mon environnement au lieu de RESTFUL_APP_DSN

8
Abubakar Oladeji