diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 19695c25..7576fff2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -151,7 +151,7 @@ follow the instructions in this section. ### Update the version, changelog, and notices 1. Create a new branch for the version bump. 1. Based on the unreleased content, determine the new version number and update - the [version.go](pkg/authenticator/version.go) file. + the [version.go](pkg/authenticator/common/version.go) file. 1. Determine the new version number and update the Helm `Chart.yaml` files in the `helm/conjur-*/` directories. 1. Review the git log and ensure the [changelog](CHANGELOG.md) contains all relevant recent changes with references to GitHub issues or PRs, if possible. diff --git a/bin/build_utils b/bin/build_utils index 7772c7fd..f1e2dc96 100755 --- a/bin/build_utils +++ b/bin/build_utils @@ -6,7 +6,7 @@ set -euo pipefail # Functions to generate version numbers for this project #### -readonly VERSION_GO_FILE="pkg/authenticator/version.go" +readonly VERSION_GO_FILE="pkg/authenticator/common/version.go" function short_version_tag() { grep -v '^//' "${VERSION_GO_FILE}" | grep 'var Version =' | awk -F'= ' '{print $2}' | tr -d '"' diff --git a/cmd/authenticator/main.go b/cmd/authenticator/main.go index 97f4c014..a11a55e4 100644 --- a/cmd/authenticator/main.go +++ b/cmd/authenticator/main.go @@ -7,23 +7,23 @@ import ( "github.com/cenkalti/backoff" - "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator" - authnConfig "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/config" + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common" + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/creators" "github.com/cyberark/conjur-authn-k8s-client/pkg/log" ) func main() { - log.Info(log.CAKC048, authenticator.FullVersionName) + log.Info(log.CAKC048, common.FullVersionName) var err error - config, err := authnConfig.NewFromEnv() + config, err := creators.NewFromEnv() if err != nil { printErrorAndExit(log.CAKC018) } // Create new Authenticator - authn, err := authenticator.New(*config) + authn, err := creators.NewAuthenticator(config) if err != nil { printErrorAndExit(log.CAKC019) } @@ -43,14 +43,14 @@ func main() { return log.RecordedError(log.CAKC016) } - if authn.Config.ContainerMode == "init" { + if config.GetContainerMode() == "init" { os.Exit(0) } - log.Info(log.CAKC047, authn.Config.TokenRefreshTimeout) + log.Info(log.CAKC047, config.GetTokenTimeout()) fmt.Println() - time.Sleep(authn.Config.TokenRefreshTimeout) + time.Sleep(config.GetTokenTimeout()) // Reset exponential backoff expBackoff.Reset() diff --git a/pkg/authenticator/client.go b/pkg/authenticator/common/client.go similarity index 91% rename from pkg/authenticator/client.go rename to pkg/authenticator/common/client.go index 0c66103a..4acae4a6 100644 --- a/pkg/authenticator/client.go +++ b/pkg/authenticator/common/client.go @@ -1,4 +1,4 @@ -package authenticator +package common import ( "crypto/tls" @@ -9,7 +9,7 @@ import ( "github.com/cyberark/conjur-authn-k8s-client/pkg/log" ) -func newHTTPSClient(CACert []byte, certPEMBlock, keyPEMBlock []byte) (*http.Client, error) { +func NewHTTPSClient(CACert []byte, certPEMBlock, keyPEMBlock []byte) (*http.Client, error) { caCertPool := x509.NewCertPool() ok := caCertPool.AppendCertsFromPEM(CACert) if !ok { diff --git a/pkg/authenticator/common/interfaces.go b/pkg/authenticator/common/interfaces.go new file mode 100644 index 00000000..b6851f72 --- /dev/null +++ b/pkg/authenticator/common/interfaces.go @@ -0,0 +1,21 @@ +package common + +import ( + "time" +) + +type AuthnInterface interface { + Init(config *ConfInterface) (AuthnInterface, error) + Authenticate() error +} + +type ConfInterface interface { + LoadConfig(settings map[string]string) + GetAuthenticationType() string + GetEnvVariables() []string + GetRequiredVariables() []string + GetDefaultValues() map[string]string + GetContainerMode() string + GetTokenFilePath() string + GetTokenTimeout() time.Duration +} diff --git a/pkg/authenticator/config/username.go b/pkg/authenticator/common/username.go similarity index 99% rename from pkg/authenticator/config/username.go rename to pkg/authenticator/common/username.go index 7b26927e..e6541461 100644 --- a/pkg/authenticator/config/username.go +++ b/pkg/authenticator/common/username.go @@ -1,4 +1,4 @@ -package config +package common import ( "strings" diff --git a/pkg/authenticator/config/username_test.go b/pkg/authenticator/common/username_test.go similarity index 89% rename from pkg/authenticator/config/username_test.go rename to pkg/authenticator/common/username_test.go index f1abba0e..f990bbdd 100644 --- a/pkg/authenticator/config/username_test.go +++ b/pkg/authenticator/common/username_test.go @@ -1,4 +1,4 @@ -package config +package common import ( "fmt" @@ -19,7 +19,7 @@ func TestNewUsername(t *testing.T) { // ASSERT assert.Equal(t, "host.path.to.policy", usernameStruct.Prefix) - assert.Equal(t, "namespace.resource_type.resource_id", usernameStruct.Suffix) + assert.Equal(t, "namespace.resource_type.resource_id", usernameStruct.Suffix) }) t.Run("shorter than 4 parts", func(t *testing.T) { @@ -31,10 +31,9 @@ func TestNewUsername(t *testing.T) { // ASSERT assert.Equal(t, "host.policy", usernameStruct.Prefix) - assert.Equal(t, "host_id", usernameStruct.Suffix) + assert.Equal(t, "host_id", usernameStruct.Suffix) }) - t.Run("missing host/ prefix", func(t *testing.T) { // SETUP & EXERCISE _, err := NewUsername("namespace/resource_type/resource_id") diff --git a/pkg/authenticator/version.go b/pkg/authenticator/common/version.go similarity index 96% rename from pkg/authenticator/version.go rename to pkg/authenticator/common/version.go index 98fcf301..b8522f43 100644 --- a/pkg/authenticator/version.go +++ b/pkg/authenticator/common/version.go @@ -1,4 +1,4 @@ -package authenticator +package common import "fmt" diff --git a/pkg/authenticator/config/config.go b/pkg/authenticator/config/config.go deleted file mode 100644 index 01f4e2a7..00000000 --- a/pkg/authenticator/config/config.go +++ /dev/null @@ -1,293 +0,0 @@ -package config - -import ( - "errors" - "fmt" - "io/ioutil" - "os" - "strconv" - "time" - - "github.com/cyberark/conjur-authn-k8s-client/pkg/log" -) - -// Config defines the configuration parameters -// for the authentication requests -type Config struct { - Account string - ClientCertPath string - ClientCertRetryCountLimit int - ContainerMode string - ConjurVersion string - InjectCertLogPath string - PodName string - PodNamespace string - SSLCertificate []byte - TokenFilePath string - TokenRefreshTimeout time.Duration - URL string - Username *Username -} - -// AuthnSettings represents a group of authenticator client configuration settings. -type AuthnSettings map[string]string - -// Default settings (this comment added to satisfy linter) -const ( - DefaultClientCertPath = "/etc/conjur/ssl/client.pem" - DefaultInjectCertLogPath = "/tmp/conjur_copy_text_output.log" - DefaultTokenFilePath = "/run/conjur/access-token" - - DefaultConjurVersion = "5" - - // DefaultTokenRefreshTimeout is the default time the system waits to reauthenticate on error - DefaultTokenRefreshTimeout = "6m0s" - - // DefaultClientCertRetryCountLimit is the amount of times we wait after successful - // login for the client certificate file to exist, where each time we wait for a second. - DefaultClientCertRetryCountLimit = "10" -) - -var requiredEnvVariables = []string{ - "CONJUR_AUTHN_URL", - "CONJUR_ACCOUNT", - "CONJUR_AUTHN_LOGIN", - "MY_POD_NAMESPACE", - "MY_POD_NAME", -} - -var envVariables = []string{ - "CONJUR_ACCOUNT", - "CONJUR_AUTHN_LOGIN", - "CONJUR_AUTHN_TOKEN_FILE", - "CONJUR_AUTHN_URL", - "CONJUR_CERT_FILE", - "CONJUR_CLIENT_CERT_PATH", - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT", - "CONJUR_SSL_CERTIFICATE", - "CONJUR_TOKEN_TIMEOUT", - "CONJUR_VERSION", - "CONTAINER_MODE", - "DEBUG", - "MY_POD_NAME", - "MY_POD_NAMESPACE", -} - -var defaultValues = map[string]string{ - "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, - "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, - "CONJUR_VERSION": DefaultConjurVersion, - "CONJUR_TOKEN_TIMEOUT": DefaultTokenRefreshTimeout, - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": DefaultClientCertRetryCountLimit, -} - -func defaultEnv(key string) string { - return defaultValues[key] -} - -// ReadFileFunc defines the interface for reading an SSL Certificate from the env -type ReadFileFunc func(filename string) ([]byte, error) - -// NewFromEnv returns a config FromEnv using the standard file reader for reading certs -func NewFromEnv() (*Config, error) { - return FromEnv(ioutil.ReadFile) -} - -// FromEnv returns a new authenticator configuration object -func FromEnv(readFileFunc ReadFileFunc) (*Config, error) { - envSettings := GatherSettings(os.Getenv) - - errLogs := envSettings.Validate(readFileFunc) - if len(errLogs) > 0 { - logErrors(errLogs) - return nil, errors.New(log.CAKC061) - } - - return envSettings.NewConfig(), nil -} - -// GatherSettings retrieves authenticator client configuration settings from a slice -// of arbitrary `func(key string) string` functions. Values received from 'Getter' functions -// are prioritized in the order that the functions are provided. -func GatherSettings(getters ...func(key string) string) AuthnSettings { - getters = append(getters, defaultEnv) - - getEnv := func(key string) string { - var val string - for _, getter := range getters { - val = getter(key) - if len(val) > 0 { - return val - } - } - return "" - } - - settings := make(AuthnSettings) - - for _, key := range envVariables { - value := getEnv(key) - settings[key] = value - } - - return settings -} - -// Validate confirms that the given AuthnSettings yield a valid authenticator -// client configuration. Returns a list of Error logs. -func (settings AuthnSettings) Validate(readFileFunc ReadFileFunc) []error { - errorLogs := []error{} - - // ensure required values exist - for _, key := range requiredEnvVariables { - if settings[key] == "" { - errorLogs = append(errorLogs, fmt.Errorf(log.CAKC062, key)) - } - } - - // ensure provided values are of the correct type - for _, key := range envVariables { - err := validateSetting(key, settings[key]) - if err != nil { - errorLogs = append(errorLogs, err) - } - } - - // ensure that the certificate settings are valid - cert, err := readSSLCert(settings, readFileFunc) - if err != nil { - errorLogs = append(errorLogs, err) - } else { - if settings["CONJUR_SSL_CERTIFICATE"] == "" { - settings["CONJUR_SSL_CERTIFICATE"] = string(cert) - } - } - - return errorLogs -} - -// NewConfig provides a new authenticator configuration from an AuthnSettings map. -func (settings AuthnSettings) NewConfig() *Config { - configureLogLevel(settings["DEBUG"]) - - config := &Config{} - config.InjectCertLogPath = DefaultInjectCertLogPath - - for key, value := range settings { - switch key { - case "CONJUR_ACCOUNT": - config.Account = value - case "CONJUR_AUTHN_LOGIN": - username, _ := NewUsername(value) - config.Username = username - case "CONJUR_AUTHN_URL": - config.URL = value - case "CONJUR_SSL_CERTIFICATE": - config.SSLCertificate = []byte(value) - case "CONTAINER_MODE": - config.ContainerMode = value - case "MY_POD_NAME": - config.PodName = value - case "MY_POD_NAMESPACE": - config.PodNamespace = value - case "CONJUR_AUTHN_TOKEN_FILE": - config.TokenFilePath = value - case "CONJUR_CLIENT_CERT_PATH": - config.ClientCertPath = value - case "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": - limit, _ := strconv.Atoi(value) - config.ClientCertRetryCountLimit = limit - case "CONJUR_TOKEN_TIMEOUT": - timeout, _ := durationFromString(key, value) - config.TokenRefreshTimeout = timeout - case "CONJUR_VERSION": - config.ConjurVersion = value - } - } - - return config -} - -func configureLogLevel(level string) { - validVal := "true" - if level == validVal { - log.EnableDebugMode() - } else if level != "" { - // In case "DEBUG" is configured with incorrect value - log.Warn(log.CAKC034, level, validVal) - } -} - -func logErrors(errLogs []error) { - for _, err := range errLogs { - log.Error(err.Error()) - } -} - -func validTimeout(key, timeoutStr string) error { - _, err := durationFromString(key, timeoutStr) - return err -} - -func durationFromString(key, value string) (time.Duration, error) { - duration, err := time.ParseDuration(value) - if err != nil { - return 0, fmt.Errorf(log.CAKC060, key, value) - } - return duration, nil -} - -func validInt(key, value string) error { - _, err := strconv.Atoi(value) - if err != nil { - return fmt.Errorf(log.CAKC060, key, value) - } - return nil -} - -func validUsername(key, value string) error { - _, err := NewUsername(value) - return err -} - -func validConjurVersion(key, version string) error { - // Only versions '4' & '5' are allowed, with '5' being used as the default - switch version { - case "4": - break - case "5": - break - default: - return fmt.Errorf(log.CAKC060, key, version) - } - - return nil -} - -func validateSetting(key string, value string) error { - switch key { - case "CONJUR_AUTHN_LOGIN": - return validUsername(key, value) - case "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": - return validInt(key, value) - case "CONJUR_TOKEN_TIMEOUT": - return validTimeout(key, value) - case "CONJUR_VERSION": - return validConjurVersion(key, value) - default: - return nil - } -} - -func readSSLCert(settings map[string]string, readFile ReadFileFunc) ([]byte, error) { - SSLCert := settings["CONJUR_SSL_CERTIFICATE"] - SSLCertPath := settings["CONJUR_CERT_FILE"] - if SSLCert == "" && SSLCertPath == "" { - return nil, errors.New(log.CAKC007) - } - - if SSLCert != "" { - return []byte(SSLCert), nil - } - return readFile(SSLCertPath) -} diff --git a/pkg/authenticator/creators/factories.go b/pkg/authenticator/creators/factories.go new file mode 100644 index 00000000..ef14e3ce --- /dev/null +++ b/pkg/authenticator/creators/factories.go @@ -0,0 +1,97 @@ +package creators + +import ( + "errors" + "fmt" + "io/ioutil" + "os" + "strings" + + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common" + k8sAuthenitcator "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/k8s" + "github.com/cyberark/conjur-authn-k8s-client/pkg/log" +) + +const AuthnURLVarName string = "CONJUR_AUTHN_URL" + +// AuthnSettings represents a group of authenticator client configuration settings. +type AuthnSettings map[string]string + +// ReadFileFunc defines the interface for reading an SSL Certificate from the env +type ReadFileFunc func(filename string) ([]byte, error) + +// NewFromEnv returns a config FromEnv using the standard file reader for reading certs +func NewFromEnv() (common.ConfInterface, error) { + return FromEnv(ioutil.ReadFile) +} + +// FromEnv returns a new authenticator configuration object +func FromEnv(readFileFunc ReadFileFunc) (common.ConfInterface, error) { + authnUrl := os.Getenv(AuthnURLVarName) + conf, error := GetConfiguration(authnUrl) + if error != nil { + return nil, error + } + envSettings := GatherSettings(conf, os.Getenv) + + errLogs := envSettings.Validate(conf, readFileFunc) + if len(errLogs) > 0 { + logErrors(errLogs) + return nil, errors.New(log.CAKC061) + } + + conf.LoadConfig(envSettings) + return conf, nil +} + +func GetConfiguration(url string) (common.ConfInterface, error) { + if strings.Contains(url, k8sAuthenitcator.AuthnType) { + return &k8sAuthenitcator.Config{}, nil + } + return nil, fmt.Errorf(log.CAKC063) +} + +// GatherSettings retrieves authenticator client configuration settings from a slice +// of arbitrary `func(key string) string` functions. Values received from 'Getter' functions +// are prioritized in the order that the functions are provided. +func GatherSettings(conf common.ConfInterface, getters ...func(key string) string) AuthnSettings { + defaultVariables := conf.GetDefaultValues() + + getDefault := func(key string) string { + return defaultVariables[key] + } + + getters = append(getters, getDefault) + settings := make(AuthnSettings) + getEnv := getConfigVariable(getters...) + + for _, key := range conf.GetEnvVariables() { + value := getEnv(key) + settings[key] = value + } + + return settings +} + +func NewAuthenticator(conf common.ConfInterface) (common.AuthnInterface, error) { + var error error + var authn common.AuthnInterface + authn, error = GetAuthenticator(conf) + if error != nil { + return nil, error + } + return authn.Init(&conf) +} + +func GetAuthenticator(conf common.ConfInterface) (common.AuthnInterface, error) { + if strings.Compare(conf.GetAuthenticationType(), k8sAuthenitcator.AuthnType) == 0 { + return &k8sAuthenitcator.Authenticator{}, nil + } + return nil, fmt.Errorf(log.CAKC064) +} + +func logErrors(errLogs []error) { + for _, err := range errLogs { + log.Error(err.Error()) + } +} diff --git a/pkg/authenticator/creators/validations.go b/pkg/authenticator/creators/validations.go new file mode 100644 index 00000000..f90588d8 --- /dev/null +++ b/pkg/authenticator/creators/validations.go @@ -0,0 +1,125 @@ +package creators + +import ( + "errors" + "fmt" + "strconv" + "time" + + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common" + "github.com/cyberark/conjur-authn-k8s-client/pkg/log" +) + +// Validate confirms that the given AuthnSettings yield a valid authenticator +// client configuration. Returns a list of Error logs. +func (settings AuthnSettings) Validate(conf common.ConfInterface, readFileFunc ReadFileFunc) []error { + errorLogs := []error{} + + // ensure required values exist + for _, key := range conf.GetRequiredVariables() { + if settings[key] == "" { + errorLogs = append(errorLogs, fmt.Errorf(log.CAKC062, key)) + } + } + + // ensure provided values are of the correct type + for _, key := range conf.GetEnvVariables() { + err := validateSetting(key, settings[key]) + if err != nil { + errorLogs = append(errorLogs, err) + } + } + + // ensure that the certificate settings are valid + cert, err := readSSLCert(settings, readFileFunc) + if err != nil { + errorLogs = append(errorLogs, err) + } else { + if settings["CONJUR_SSL_CERTIFICATE"] == "" { + settings["CONJUR_SSL_CERTIFICATE"] = string(cert) + } + } + + return errorLogs +} + +func validTimeout(key, timeoutStr string) error { + _, err := durationFromString(key, timeoutStr) + return err +} + +func durationFromString(key, value string) (time.Duration, error) { + duration, err := time.ParseDuration(value) + if err != nil { + return 0, fmt.Errorf(log.CAKC060, key, value) + } + return duration, nil +} + +func validInt(key, value string) error { + _, err := strconv.Atoi(value) + if err != nil { + return fmt.Errorf(log.CAKC060, key, value) + } + return nil +} + +func validUsername(key, value string) error { + _, err := common.NewUsername(value) + return err +} + +func validConjurVersion(key, version string) error { + // Only versions '4' & '5' are allowed, with '5' being used as the default + switch version { + case "4": + break + case "5": + break + default: + return fmt.Errorf(log.CAKC060, key, version) + } + + return nil +} + +func validateSetting(key string, value string) error { + switch key { + case "CONJUR_AUTHN_LOGIN": + return validUsername(key, value) + case "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": + return validInt(key, value) + case "CONJUR_TOKEN_TIMEOUT": + return validTimeout(key, value) + case "CONJUR_VERSION": + return validConjurVersion(key, value) + default: + return nil + } +} + +func readSSLCert(settings map[string]string, readFile ReadFileFunc) ([]byte, error) { + SSLCert := settings["CONJUR_SSL_CERTIFICATE"] + SSLCertPath := settings["CONJUR_CERT_FILE"] + if SSLCert == "" && SSLCertPath == "" { + return nil, errors.New(log.CAKC007) + } + + if SSLCert != "" { + return []byte(SSLCert), nil + } + return readFile(SSLCertPath) +} + +func getConfigVariable(getters ...func(key string) string) func(string) string { + return func(key string) string { + var val string + for _, getter := range getters { + val = getter(key) + if len(val) > 0 { + return val + } + } + return "" + } +} diff --git a/pkg/authenticator/authenticator.go b/pkg/authenticator/k8s/authenticator.go similarity index 92% rename from pkg/authenticator/authenticator.go rename to pkg/authenticator/k8s/authenticator.go index 76c1347d..1118f442 100644 --- a/pkg/authenticator/authenticator.go +++ b/pkg/authenticator/k8s/authenticator.go @@ -1,4 +1,4 @@ -package authenticator +package k8s import ( "crypto" @@ -9,6 +9,7 @@ import ( "encoding/asn1" "encoding/pem" "fmt" + "io/ioutil" "net" "net/http" @@ -20,7 +21,7 @@ import ( "github.com/cyberark/conjur-authn-k8s-client/pkg/access_token" "github.com/cyberark/conjur-authn-k8s-client/pkg/access_token/file" - authnConfig "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/config" + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common" "github.com/cyberark/conjur-authn-k8s-client/pkg/log" "github.com/cyberark/conjur-authn-k8s-client/pkg/utils" ) @@ -34,7 +35,7 @@ type Authenticator struct { client *http.Client privateKey *rsa.PrivateKey AccessToken access_token.AccessToken - Config authnConfig.Config + Config *Config PublicCert *x509.Certificate } @@ -45,9 +46,21 @@ const ( nameTypeIP = 7 ) +// Init the authenticator struct +func (auth *Authenticator) Init(config *common.ConfInterface) (common.AuthnInterface, error) { + log.Debug(log.CAKC058) + var cfg = (*config).(*Config) + authn, err := New(*cfg) + if err != nil { + return nil, fmt.Errorf(log.CAKC019) + } + + return authn, nil +} + // New creates a new authenticator instance from a token file -func New(config authnConfig.Config) (*Authenticator, error) { - accessToken, err := file.NewAccessToken(config.TokenFilePath) +func New(config Config) (*Authenticator, error) { + accessToken, err := file.NewAccessToken(config.GetTokenFilePath()) if err != nil { return nil, log.RecordedError(log.CAKC001) } @@ -56,13 +69,13 @@ func New(config authnConfig.Config) (*Authenticator, error) { } // NewWithAccessToken creates a new authenticator instance from a given access token -func NewWithAccessToken(config authnConfig.Config, accessToken access_token.AccessToken) (*Authenticator, error) { +func NewWithAccessToken(config Config, accessToken access_token.AccessToken) (*Authenticator, error) { signingKey, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { return nil, log.RecordedError(log.CAKC030, err) } - client, err := newHTTPSClient(config.SSLCertificate, nil, nil) + client, err := common.NewHTTPSClient(config.SSLCertificate, nil, nil) if err != nil { return nil, err } @@ -71,7 +84,7 @@ func NewWithAccessToken(config authnConfig.Config, accessToken access_token.Acce client: client, privateKey: signingKey, AccessToken: accessToken, - Config: config, + Config: &config, }, nil } @@ -264,7 +277,7 @@ func (auth *Authenticator) sendAuthenticationRequest() ([]byte, error) { certPEMBlock := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: auth.PublicCert.Raw}) - client, err := newHTTPSClient(auth.Config.SSLCertificate, certPEMBlock, keyPEMBlock) + client, err := common.NewHTTPSClient(auth.Config.SSLCertificate, certPEMBlock, keyPEMBlock) if err != nil { return nil, err } diff --git a/pkg/authenticator/k8s/config.go b/pkg/authenticator/k8s/config.go new file mode 100644 index 00000000..98ca4ca4 --- /dev/null +++ b/pkg/authenticator/k8s/config.go @@ -0,0 +1,160 @@ +package k8s + +import ( + "fmt" + "strconv" + "time" + + configPackage "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common" + "github.com/cyberark/conjur-authn-k8s-client/pkg/log" +) + +// Config defines the configuration parameters +// for the authentication requests +type Config struct { + Account string + ClientCertPath string + ClientCertRetryCountLimit int + ContainerMode string + ConjurVersion string + InjectCertLogPath string + PodName string + PodNamespace string + SSLCertificate []byte + TokenFilePath string + TokenRefreshTimeout time.Duration + URL string + Username *configPackage.Username +} + +// Default settings (this comment added to satisfy linter) +const ( + DefaultClientCertPath = "/etc/conjur/ssl/client.pem" + DefaultInjectCertLogPath = "/tmp/conjur_copy_text_output.log" + DefaultTokenFilePath = "/run/conjur/access-token" + + DefaultConjurVersion = "5" + + // DefaultTokenRefreshTimeout is the default time the system waits to reauthenticate on error + DefaultTokenRefreshTimeout = "6m0s" + + // DefaultClientCertRetryCountLimit is the amount of times we wait after successful + // login for the client certificate file to exist, where each time we wait for a second. + DefaultClientCertRetryCountLimit = "10" + AuthnType = "authn-k8s" +) + +var requiredEnvVariables = []string{ + "CONJUR_AUTHN_URL", + "CONJUR_ACCOUNT", + "CONJUR_AUTHN_LOGIN", + "MY_POD_NAMESPACE", + "MY_POD_NAME", +} + +var envVariables = []string{ + "CONJUR_ACCOUNT", + "CONJUR_AUTHN_LOGIN", + "CONJUR_AUTHN_TOKEN_FILE", + "CONJUR_AUTHN_URL", + "CONJUR_CERT_FILE", + "CONJUR_CLIENT_CERT_PATH", + "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT", + "CONJUR_SSL_CERTIFICATE", + "CONJUR_TOKEN_TIMEOUT", + "CONJUR_VERSION", + "CONTAINER_MODE", + "DEBUG", + "MY_POD_NAME", + "MY_POD_NAMESPACE", +} + +var defaultValues = map[string]string{ + "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, + "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, + "CONJUR_VERSION": DefaultConjurVersion, + "CONJUR_TOKEN_TIMEOUT": DefaultTokenRefreshTimeout, + "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": DefaultClientCertRetryCountLimit, +} + +func durationFromString(key, value string) (time.Duration, error) { + duration, err := time.ParseDuration(value) + if err != nil { + return 0, fmt.Errorf(log.CAKC060, key, value) + } + return duration, nil +} + +func configureLogLevel(level string) { + validVal := "true" + if level == validVal { + log.EnableDebugMode() + } else if level != "" { + // In case "DEBUG" is configured with incorrect value + log.Warn(log.CAKC034, level, validVal) + } +} + +func (config *Config) LoadConfig(settings map[string]string) { + configureLogLevel(settings["DEBUG"]) + + for key, value := range settings { + switch key { + case "CONJUR_ACCOUNT": + config.Account = value + case "CONJUR_AUTHN_LOGIN": + username, _ := configPackage.NewUsername(value) + config.Username = username + case "CONJUR_AUTHN_URL": + config.URL = value + case "CONJUR_SSL_CERTIFICATE": + config.SSLCertificate = []byte(value) + case "CONTAINER_MODE": + config.ContainerMode = value + case "MY_POD_NAME": + config.PodName = value + case "MY_POD_NAMESPACE": + config.PodNamespace = value + case "CONJUR_AUTHN_TOKEN_FILE": + config.TokenFilePath = value + case "CONJUR_CLIENT_CERT_PATH": + config.ClientCertPath = value + case "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": + limit, _ := strconv.Atoi(value) + config.ClientCertRetryCountLimit = limit + case "CONJUR_TOKEN_TIMEOUT": + timeout, _ := durationFromString(key, value) + config.TokenRefreshTimeout = timeout + case "CONJUR_VERSION": + config.ConjurVersion = value + } + } +} + +func (config *Config) GetAuthenticationType() string { + return AuthnType +} + +func (config *Config) GetEnvVariables() []string { + return envVariables +} + +func (config *Config) GetRequiredVariables() []string { + return requiredEnvVariables +} + +func (config *Config) GetDefaultValues() map[string]string { + return defaultValues +} + +func (config *Config) GetContainerMode() string { + return config.ContainerMode +} + +func (config *Config) GetTokenFilePath() string { + return config.TokenFilePath +} + +func (config *Config) GetTokenTimeout() time.Duration { + return config.TokenRefreshTimeout +} diff --git a/pkg/authenticator/requests.go b/pkg/authenticator/k8s/requests.go similarity index 98% rename from pkg/authenticator/requests.go rename to pkg/authenticator/k8s/requests.go index f7f934e3..3869fe1f 100644 --- a/pkg/authenticator/requests.go +++ b/pkg/authenticator/k8s/requests.go @@ -1,4 +1,4 @@ -package authenticator +package k8s import ( "bytes" diff --git a/pkg/authenticator/requests_test.go b/pkg/authenticator/k8s/requests_test.go similarity index 95% rename from pkg/authenticator/requests_test.go rename to pkg/authenticator/k8s/requests_test.go index 0305b3ca..9b594a80 100644 --- a/pkg/authenticator/requests_test.go +++ b/pkg/authenticator/k8s/requests_test.go @@ -1,4 +1,4 @@ -package authenticator +package k8s import ( "testing" diff --git a/pkg/authenticator/authenticator_test.go b/pkg/authenticator/k8s/tests/authenticator_test.go similarity index 86% rename from pkg/authenticator/authenticator_test.go rename to pkg/authenticator/k8s/tests/authenticator_test.go index 3d9786ee..6c6eacf8 100644 --- a/pkg/authenticator/authenticator_test.go +++ b/pkg/authenticator/k8s/tests/authenticator_test.go @@ -1,4 +1,4 @@ -package authenticator +package tests import ( "bytes" @@ -12,12 +12,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/cyberark/conjur-authn-k8s-client/pkg/access_token/memory" - "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/config" + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/common" + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/k8s" "github.com/cyberark/conjur-authn-k8s-client/pkg/log" ) type assertFunc func(t *testing.T, - authn *Authenticator, + authn *k8s.Authenticator, err error, loginCsr *x509.CertificateRequest, loginCsrErr error, @@ -36,7 +37,7 @@ func TestAuthenticator_Authenticate(t *testing.T) { name: "happy path", podName: "testPodName", podNamespace: "testPodNamespace", - assert: func(t *testing.T, authn *Authenticator, err error, loginCsr *x509.CertificateRequest, loginCsrErr error, _ string) { + assert: func(t *testing.T, authn *k8s.Authenticator, err error, loginCsr *x509.CertificateRequest, loginCsrErr error, _ string) { assert.NoError(t, err) // Check the CSR @@ -67,7 +68,7 @@ func TestAuthenticator_Authenticate(t *testing.T) { name: "empty podname", podName: "", podNamespace: "", - assert: func(t *testing.T, authn *Authenticator, err error, loginCsr *x509.CertificateRequest, _ error, _ string) { + assert: func(t *testing.T, authn *k8s.Authenticator, err error, loginCsr *x509.CertificateRequest, _ error, _ string) { assert.NoError(t, err) // Assert empty spiffe @@ -82,7 +83,7 @@ func TestAuthenticator_Authenticate(t *testing.T) { name: "expired cert", podName: "testPodName", podNamespace: "testPodNamespace", - assert: func(t *testing.T, authn *Authenticator, err error, _ *x509.CertificateRequest, _ error, _ string) { + assert: func(t *testing.T, authn *k8s.Authenticator, err error, _ *x509.CertificateRequest, _ error, _ string) { assert.NoError(t, err) // Set the expiration date to now, and try to authenticate again // This will cause the authenticator to try to refresh the cert @@ -99,7 +100,7 @@ func TestAuthenticator_Authenticate(t *testing.T) { podName: "testPodName", podNamespace: "testPodNamespace", skipWritingCSRFile: true, - assert: func(t *testing.T, _ *Authenticator, err error, _ *x509.CertificateRequest, _ error, logTxt string) { + assert: func(t *testing.T, _ *k8s.Authenticator, err error, _ *x509.CertificateRequest, _ error, logTxt string) { assert.Error(t, err) // Check logs for the expected error assert.Contains(t, logTxt, "error writing csr file") @@ -132,9 +133,9 @@ func TestAuthenticator_Authenticate(t *testing.T) { Type: "CERTIFICATE", Bytes: ts.Server.Certificate().Raw, }) - username, _ := config.NewUsername("host/test-user") + username, _ := common.NewUsername("host/test-user") - cfg := config.Config{ + cfg := k8s.Config{ Account: "account", ClientCertPath: clientCertPath, ClientCertRetryCountLimit: 0, @@ -151,7 +152,7 @@ func TestAuthenticator_Authenticate(t *testing.T) { } // EXERCISE - authn, err := NewWithAccessToken(cfg, at) + authn, err := k8s.NewWithAccessToken(cfg, at) if !assert.NoError(t, err) { return } diff --git a/pkg/authenticator/authenticator_test_server.go b/pkg/authenticator/k8s/tests/authenticator_test_server.go similarity index 99% rename from pkg/authenticator/authenticator_test_server.go rename to pkg/authenticator/k8s/tests/authenticator_test_server.go index 9eb0de15..bbe69eeb 100644 --- a/pkg/authenticator/authenticator_test_server.go +++ b/pkg/authenticator/k8s/tests/authenticator_test_server.go @@ -1,4 +1,4 @@ -package authenticator +package tests import ( "crypto/rand" diff --git a/pkg/authenticator/config/config_test.go b/pkg/authenticator/k8s/tests/config_test.go similarity index 57% rename from pkg/authenticator/config/config_test.go rename to pkg/authenticator/k8s/tests/config_test.go index 0de520db..3eeac3fb 100644 --- a/pkg/authenticator/config/config_test.go +++ b/pkg/authenticator/k8s/tests/config_test.go @@ -1,15 +1,17 @@ -package config +package tests import ( - "bytes" "errors" "fmt" - "log" + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/k8s" + "os" "testing" - logger "github.com/cyberark/conjur-authn-k8s-client/pkg/log" "github.com/stretchr/testify/assert" + + "github.com/cyberark/conjur-authn-k8s-client/pkg/authenticator/creators" + logger "github.com/cyberark/conjur-authn-k8s-client/pkg/log" ) var environmentValues = map[string]string{ @@ -35,8 +37,8 @@ var envToAnnot = map[string]string{ "CONTAINER_MODE": "conjur.org/container-mode", } -func assertGoodConfig(expected *Config) func(*testing.T, *Config) { - return func(t *testing.T, result *Config) { +func assertGoodConfig(expected *k8s.Config) func(*testing.T, *k8s.Config) { + return func(t *testing.T, result *k8s.Config) { assert.Equal(t, expected, result) } } @@ -77,12 +79,12 @@ func TestGatherSettings(t *testing.T) { TestCases := []struct { description string annotFunc func(string) string - expected AuthnSettings + expected creators.AuthnSettings }{ { description: "functions are ordered by priority: first function overrides second, which overrides third", annotFunc: fromAnnotations, - expected: AuthnSettings{ + expected: creators.AuthnSettings{ "CONJUR_ACCOUNT": "testAccount", "CONJUR_AUTHN_LOGIN": "host/anotherHost", // provided by annotation "CONJUR_AUTHN_URL": "filepath", @@ -92,17 +94,17 @@ func TestGatherSettings(t *testing.T) { "DEBUG": "true", // provided by annotation "MY_POD_NAME": "testPodName", "MY_POD_NAMESPACE": "testNameSpace", - "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, - "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": DefaultClientCertRetryCountLimit, - "CONJUR_TOKEN_TIMEOUT": DefaultTokenRefreshTimeout, - "CONJUR_VERSION": DefaultConjurVersion, + "CONJUR_AUTHN_TOKEN_FILE": k8s.DefaultTokenFilePath, + "CONJUR_CLIENT_CERT_PATH": k8s.DefaultClientCertPath, + "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": k8s.DefaultClientCertRetryCountLimit, + "CONJUR_TOKEN_TIMEOUT": k8s.DefaultTokenRefreshTimeout, + "CONJUR_VERSION": k8s.DefaultConjurVersion, }, }, { description: "if the first getter function returns empty strings, fallback to the next functions, and eventually an empty string", annotFunc: emptyAnnotations, - expected: AuthnSettings{ + expected: creators.AuthnSettings{ "CONJUR_AUTHN_URL": "filepath", "CONJUR_ACCOUNT": "testAccount", "CONJUR_AUTHN_LOGIN": "host", @@ -112,18 +114,18 @@ func TestGatherSettings(t *testing.T) { "MY_POD_NAME": "testPodName", "DEBUG": "", "CONTAINER_MODE": "", - "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, - "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, - "CONJUR_VERSION": DefaultConjurVersion, - "CONJUR_TOKEN_TIMEOUT": DefaultTokenRefreshTimeout, - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": DefaultClientCertRetryCountLimit, + "CONJUR_CLIENT_CERT_PATH": k8s.DefaultClientCertPath, + "CONJUR_AUTHN_TOKEN_FILE": k8s.DefaultTokenFilePath, + "CONJUR_VERSION": k8s.DefaultConjurVersion, + "CONJUR_TOKEN_TIMEOUT": k8s.DefaultTokenRefreshTimeout, + "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": k8s.DefaultClientCertRetryCountLimit, }, }, } for _, tc := range TestCases { t.Run(tc.description, func(t *testing.T) { - resultMap := GatherSettings(tc.annotFunc, fromEnv) + resultMap := creators.GatherSettings(&k8s.Config{}, tc.annotFunc, fromEnv) assert.Equal(t, tc.expected, resultMap) }) } @@ -132,12 +134,12 @@ func TestGatherSettings(t *testing.T) { func TestValidate(t *testing.T) { TestCases := []struct { description string - settings AuthnSettings + settings creators.AuthnSettings assert errorAssertFunc }{ { description: "happy path", - settings: AuthnSettings{ + settings: creators.AuthnSettings{ // required variables "CONJUR_AUTHN_URL": "filepath", "CONJUR_ACCOUNT": "testAccount", @@ -157,12 +159,12 @@ func TestValidate(t *testing.T) { }, { description: "error raised for missing required setting", - settings: AuthnSettings{}, + settings: creators.AuthnSettings{}, assert: assertErrorInList(fmt.Errorf(logger.CAKC062, "CONJUR_AUTHN_URL")), }, { description: "error raised for invalid username", - settings: AuthnSettings{ + settings: creators.AuthnSettings{ "CONJUR_AUTHN_URL": "filepath", "CONJUR_ACCOUNT": "testAccount", "CONJUR_AUTHN_LOGIN": "bad-username", @@ -173,7 +175,7 @@ func TestValidate(t *testing.T) { }, { description: "error raised for invalid retry count limit", - settings: AuthnSettings{ + settings: creators.AuthnSettings{ "CONJUR_AUTHN_URL": "filepath", "CONJUR_ACCOUNT": "testAccount", "CONJUR_AUTHN_LOGIN": "host", @@ -185,7 +187,7 @@ func TestValidate(t *testing.T) { }, { description: "error raised for invalid timeout", - settings: AuthnSettings{ + settings: creators.AuthnSettings{ "CONJUR_AUTHN_URL": "filepath", "CONJUR_ACCOUNT": "testAccount", "CONJUR_AUTHN_LOGIN": "host", @@ -198,7 +200,7 @@ func TestValidate(t *testing.T) { }, { description: "error raised for invalid certificate", - settings: AuthnSettings{ + settings: creators.AuthnSettings{ "CONJUR_AUTHN_URL": "filepath", "CONJUR_ACCOUNT": "testAccount", "CONJUR_AUTHN_LOGIN": "host", @@ -217,7 +219,7 @@ func TestValidate(t *testing.T) { for _, tc := range TestCases { t.Run(tc.description, func(t *testing.T) { // SETUP & EXERCISE - errLogs := tc.settings.Validate(successfulMockReadFile) + errLogs := tc.settings.Validate(&k8s.Config{}, successfulMockReadFile) // ASSERT tc.assert(t, errLogs) @@ -225,63 +227,6 @@ func TestValidate(t *testing.T) { } } -func TestNewConfig(t *testing.T) { - TestCases := []struct { - description string - settings AuthnSettings - expected *Config - assert func(*testing.T, *Config) - }{ - { - description: "happy path", - settings: AuthnSettings{ - // required variables - "CONJUR_AUTHN_URL": "filepath", - "CONJUR_ACCOUNT": "testAccount", - "CONJUR_AUTHN_LOGIN": "host/test-user", - "MY_POD_NAME": "testPodName", - "MY_POD_NAMESPACE": "testNameSpace", - // correct value types - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": "7", - "CONJUR_TOKEN_TIMEOUT": "6m0s", - "CONTAINER_MODE": "init", - // certificate provided - "CONJUR_SSL_CERTIFICATE": "samplecertificate", - // defaults provided - "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, - "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, - "CONJUR_VERSION": DefaultConjurVersion, - }, - assert: assertGoodConfig(&Config{ - Account: "testAccount", - ClientCertPath: DefaultClientCertPath, - ClientCertRetryCountLimit: 7, - ContainerMode: "init", - ConjurVersion: "5", - InjectCertLogPath: DefaultInjectCertLogPath, - PodName: "testPodName", - PodNamespace: "testNameSpace", - SSLCertificate: []byte("samplecertificate"), - TokenFilePath: DefaultTokenFilePath, - TokenRefreshTimeout: 360000000000, - URL: "filepath", - Username: &Username{ - FullUsername: "host/test-user", - Prefix: "host", - Suffix: "test-user", - }, - }), - }, - } - - for _, tc := range TestCases { - t.Run(tc.description, func(t *testing.T) { - config := tc.settings.NewConfig() - tc.assert(t, config) - }) - } -} - func TestFromEnv(t *testing.T) { TestCases := []struct { description string @@ -291,7 +236,7 @@ func TestFromEnv(t *testing.T) { { description: "happy path", env: map[string]string{ - "CONJUR_AUTHN_URL": "filepath", + "CONJUR_AUTHN_URL": "authn-k8s", "CONJUR_ACCOUNT": "testAccount", "CONJUR_AUTHN_LOGIN": "host/test-user", "MY_POD_NAME": "testPodName", @@ -311,7 +256,7 @@ func TestFromEnv(t *testing.T) { t.Run(tc.description, func(t *testing.T) { // SETUP & EXERCISE setEnv(tc.env) - config, err := FromEnv(successfulMockReadFile) + config, err := creators.FromEnv(successfulMockReadFile) // ASSERT if tc.expectErr { @@ -348,8 +293,8 @@ func TestConjurVersion(t *testing.T) { { description: "Sets the default version for an empty value", version: "", - expVersion: DefaultConjurVersion, - assert: assertErrorNotInList(fmt.Errorf(logger.CAKC060, "CONJUR_VERSION", DefaultConjurVersion)), + expVersion: k8s.DefaultConjurVersion, + assert: assertErrorNotInList(fmt.Errorf(logger.CAKC060, "CONJUR_VERSION", k8s.DefaultConjurVersion)), }, { description: "Returns error if version is invalid", @@ -369,8 +314,8 @@ func TestConjurVersion(t *testing.T) { t.Run(tc.description, func(t *testing.T) { // SETUP & EXERCISE - settings := GatherSettings(provideVersion) - errLogs := settings.Validate(successfulMockReadFile) + settings := creators.GatherSettings(&k8s.Config{}, provideVersion) + errLogs := settings.Validate(&k8s.Config{}, successfulMockReadFile) // ASSERT tc.assert(t, errLogs) @@ -381,108 +326,6 @@ func TestConjurVersion(t *testing.T) { } } -func TestDebugLogging(t *testing.T) { - TestCases := []struct { - description string - debugValue string - settings AuthnSettings - }{ - { - description: "debug logs are enabled", - debugValue: "true", - settings: AuthnSettings{ - // required variables - "CONJUR_AUTHN_URL": "filepath", - "CONJUR_ACCOUNT": "testAccount", - "CONJUR_AUTHN_LOGIN": "host/test-user", - "MY_POD_NAME": "testPodName", - "MY_POD_NAMESPACE": "testNameSpace", - // correct value types - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": "7", - "CONJUR_TOKEN_TIMEOUT": "6m0s", - "CONTAINER_MODE": "init", - // certificate provided - "CONJUR_SSL_CERTIFICATE": "samplecertificate", - // defaults provided - "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, - "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, - "CONJUR_VERSION": DefaultConjurVersion, - // debug setting - "DEBUG": "true", - }, - }, - { - description: "debug logs are disabled", - debugValue: "", - settings: AuthnSettings{ - // required variables - "CONJUR_AUTHN_URL": "filepath", - "CONJUR_ACCOUNT": "testAccount", - "CONJUR_AUTHN_LOGIN": "host/test-user", - "MY_POD_NAME": "testPodName", - "MY_POD_NAMESPACE": "testNameSpace", - // correct value types - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": "7", - "CONJUR_TOKEN_TIMEOUT": "6m0s", - "CONTAINER_MODE": "init", - // certificate provided - "CONJUR_SSL_CERTIFICATE": "samplecertificate", - // defaults provided - "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, - "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, - "CONJUR_VERSION": DefaultConjurVersion, - }, - }, - { - description: "debug logs are given an incorrect value", - debugValue: "garbage", - settings: AuthnSettings{ - // required variables - "CONJUR_AUTHN_URL": "filepath", - "CONJUR_ACCOUNT": "testAccount", - "CONJUR_AUTHN_LOGIN": "host/test-user", - "MY_POD_NAME": "testPodName", - "MY_POD_NAMESPACE": "testNameSpace", - // correct value types - "CONJUR_CLIENT_CERT_RETRY_COUNT_LIMIT": "7", - "CONJUR_TOKEN_TIMEOUT": "6m0s", - "CONTAINER_MODE": "init", - // certificate provided - "CONJUR_SSL_CERTIFICATE": "samplecertificate", - // defaults provided - "CONJUR_AUTHN_TOKEN_FILE": DefaultTokenFilePath, - "CONJUR_CLIENT_CERT_PATH": DefaultClientCertPath, - "CONJUR_VERSION": DefaultConjurVersion, - // debug setting - "DEBUG": "garbage", - }, - }, - } - - for _, tc := range TestCases { - // SETUP - var logBuffer bytes.Buffer - logger.InfoLogger = log.New(&logBuffer, "", 0) - - // EXERCISE - config := tc.settings.NewConfig() - assert.NotNil(t, config) - - // ASSERT - logMessages := logBuffer.String() - if tc.debugValue == "true" { - assert.Contains(t, logMessages, "CAKC052") - assert.NotContains(t, logMessages, "CAKC034") - } else if tc.debugValue == "" { - assert.NotContains(t, logMessages, "CAKC052") - assert.NotContains(t, logMessages, "CAKC034") - } else { - assert.NotContains(t, logMessages, "CAKC052") - assert.Contains(t, logMessages, "CAKC034") - } - } -} - func successfulMockReadFile(filename string) ([]byte, error) { return []byte{}, nil } diff --git a/pkg/log/log_messages.go b/pkg/log/log_messages.go index 10d19ed9..fb5d7b07 100644 --- a/pkg/log/log_messages.go +++ b/pkg/log/log_messages.go @@ -75,3 +75,5 @@ const CAKC059 string = "CAKC059 Path exists but does not contain regular file: % const CAKC060 string = "CAKC060 Setting %s given invalid value %s" const CAKC061 string = "CAKC061 Failed to validate setting for Authenticator configuration" const CAKC062 string = "CAKC062 Required Authenticator setting %s not provided" +const CAKC063 string = "CAKC63 Can't find configuration for this authn URL" +const CAKC064 string = "CAKC64 Can't find Authenticator for this configuration"