Skip to content

Commit

Permalink
parser for auth params
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Wozniak <[email protected]>
  • Loading branch information
wozniakjan committed May 7, 2024
1 parent 0cf6cd0 commit 6a6c9b0
Show file tree
Hide file tree
Showing 5 changed files with 486 additions and 75 deletions.
84 changes: 84 additions & 0 deletions pkg/scalers/authentication/authentication_types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package authentication

import (
"fmt"
"net/url"
"time"
)
Expand Down Expand Up @@ -31,6 +32,8 @@ const (
FastHTTP // FastHTTP Fast http client.
)

// AuthMeta is the metadata for the authentication types
// DEPRECATED: Use Config instead
type AuthMeta struct {
// bearer auth
EnableBearerAuth bool
Expand Down Expand Up @@ -61,6 +64,87 @@ type AuthMeta struct {
CustomAuthValue string
}

// BasicAuth is a basic authentication type
type BasicAuth struct {
Username string `keda:"name=username, parsingOrder=authParams"`
Password string `keda:"name=password, parsingOrder=authParams, optional=true"`
}

// CertAuth is a client certificate authentication type
type CertAuth struct {
Cert string `keda:"name=cert, parsingOrder=authParams"`
Key string `keda:"name=key, parsingOrder=authParams"`
CA string `keda:"name=ca, parsingOrder=authParams, optional=true"`
}

// OAuth is an oAuth2 authentication type
type OAuth struct {
OauthTokenURI string `keda:"name=oauthTokenURI, parsingOrder=authParams"`
Scopes []string `keda:"name=scopes, parsingOrder=authParams"`
ClientID string `keda:"name=clientID, parsingOrder=authParams"`
ClientSecret string `keda:"name=clientSecret, parsingOrder=authParams"`
EndpointParams url.Values `keda:"name=endpointParams, parsingOrder=authParams"`
}

// CustomAuth is a custom header authentication type
type CustomAuth struct {
CustomAuthHeader string `keda:"name=customAuthHeader, parsingOrder=authParams"` //TODO: check why the code had strings.TrimSuffix(authParams["customAuthHeader"], "\n")
CustomAuthValue string `keda:"name=customAuthValue, parsingOrder=authParams"` //TODO: check why the code had strings.TrimSuffix(authParams["customAuthValue"], "\n")
}

// Config is the configuration for the authentication types
type Config struct {
Modes []string `keda:"name=authModes, parsingOrder=triggerMetadata, enum=apiKey;basic;tls;bearer;custom;oauth, exclusive=bearer;basic;oauth, optional=true"`

//TODO: check why the code had strings.TrimSuffix(authParams["bearerToken"], "\n")
BearerToken string `keda:"name=bearerToken, optional=true"`
BasicAuth `keda:"optional=true"`
CertAuth `keda:"optional=true"`
OAuth `keda:"optional=true"`
CustomAuth `keda:"optional=true"`
}

// Disabled returns true if no auth modes are enabled
func (c *Config) Disabled() bool {
return c == nil || len(c.Modes) == 0
}

// Enabled returns true if given auth mode is enabled
func (c *Config) Enabled(mode Type) bool {
for _, m := range c.Modes {
if m == string(mode) {
return true
}
}
return false
}

// GetBearerToken returns the bearer token with the Bearer prefix
func (c *Config) GetBearerToken() string {
return fmt.Sprintf("Bearer %s", c.BearerToken)
}

// ToAuthMeta converts the Config to deprecated AuthMeta
func (c *Config) ToAuthMeta() *AuthMeta {
if c.Disabled() {
return nil
}
return &AuthMeta{
EnableBearerAuth: c.Enabled(BearerAuthType),
BearerToken: c.BearerToken,
EnableBasicAuth: c.Enabled(BasicAuthType),
Username: c.Username,
Password: c.Password,
EnableTLS: c.Enabled(TLSAuthType),
Cert: c.Cert,
Key: c.Key,
CA: c.CA,
EnableOAuth: c.Enabled(OAuthType),
OauthTokenURI: c.OauthTokenURI,
Scopes: c.Scopes,
}
}

type HTTPTransport struct {
MaxIdleConnDuration time.Duration
ReadTimeout time.Duration
Expand Down
62 changes: 28 additions & 34 deletions pkg/scalers/prometheus_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,21 @@ type prometheusScaler struct {
// change to false/f if can not accept prometheus return null values
// https://github.com/kedacore/keda/issues/3065
type prometheusMetadata struct {
prometheusAuth *authentication.AuthMeta
triggerIndex int

ServerAddress string `keda:"name=serverAddress, parsingOrder=triggerMetadata"`
Query string `keda:"name=query, parsingOrder=triggerMetadata"`
QueryParameters map[string]string `keda:"name=queryParameters, parsingOrder=triggerMetadata, optional"`
Threshold float64 `keda:"name=threshold, parsingOrder=triggerMetadata"`
ActivationThreshold float64 `keda:"name=activationThreshold, parsingOrder=triggerMetadata, optional"`
Namespace string `keda:"name=namespace, parsingOrder=triggerMetadata, optional"`
CustomHeaders map[string]string `keda:"name=customHeaders, parsingOrder=triggerMetadata, optional"`
IgnoreNullValues bool `keda:"name=ignoreNullValues, parsingOrder=triggerMetadata, optional, default=true"`
UnsafeSSL bool `keda:"name=unsafeSsl, parsingOrder=triggerMetadata, optional"`
CortexOrgID string `keda:"name=cortexOrgID, parsingOrder=triggerMetadata, optional, deprecated=use customHeaders instead"`
triggerIndex int

PrometheusAuth *authentication.Config `keda:"optional"`
ServerAddress string `keda:"name=serverAddress, parsingOrder=triggerMetadata"`
Query string `keda:"name=query, parsingOrder=triggerMetadata"`
QueryParameters map[string]string `keda:"name=queryParameters, parsingOrder=triggerMetadata, optional"`
Threshold float64 `keda:"name=threshold, parsingOrder=triggerMetadata"`
ActivationThreshold float64 `keda:"name=activationThreshold, parsingOrder=triggerMetadata, optional"`
Namespace string `keda:"name=namespace, parsingOrder=triggerMetadata, optional"`
CustomHeaders map[string]string `keda:"name=customHeaders, parsingOrder=triggerMetadata, optional"`
IgnoreNullValues bool `keda:"name=ignoreNullValues, parsingOrder=triggerMetadata, optional, default=true"`
UnsafeSSL bool `keda:"name=unsafeSsl, parsingOrder=triggerMetadata, optional"`

// deprecated
CortexOrgID string `keda:"name=cortexOrgID, parsingOrder=triggerMetadata, optional, deprecated=use customHeaders instead"`
}

type promQueryResult struct {
Expand Down Expand Up @@ -93,12 +95,12 @@ func NewPrometheusScaler(config *scalersconfig.ScalerConfig) (Scaler, error) {

httpClient := kedautil.CreateHTTPClient(config.GlobalHTTPTimeout, meta.UnsafeSSL)

if meta.prometheusAuth != nil {
if meta.prometheusAuth.CA != "" || meta.prometheusAuth.EnableTLS {
if meta.PrometheusAuth != nil {
if meta.PrometheusAuth.CA != "" || meta.PrometheusAuth.Enabled(authentication.TLSAuthType) {
// create http.RoundTripper with auth settings from ScalerConfig
transport, err := authentication.CreateHTTPRoundTripper(
authentication.NetHTTP,
meta.prometheusAuth,
meta.PrometheusAuth.ToAuthMeta(),
)
if err != nil {
logger.V(1).Error(err, "init Prometheus client http transport")
Expand Down Expand Up @@ -156,26 +158,18 @@ func parsePrometheusMetadata(config *scalersconfig.ScalerConfig) (meta *promethe
}

meta.triggerIndex = config.TriggerIndex
err = parseAuthConfig(config, meta)
err = checkAuthConfigWithPodIdentity(config, meta)
if err != nil {
return nil, err
}

return meta, nil
}

func parseAuthConfig(config *scalersconfig.ScalerConfig, meta *prometheusMetadata) error {
// parse auth configs from ScalerConfig
auth, err := authentication.GetAuthConfigs(config.TriggerMetadata, config.AuthParams)
if err != nil {
return err
}

if auth != nil && !(config.PodIdentity.Provider == kedav1alpha1.PodIdentityProviderNone || config.PodIdentity.Provider == "") {
func checkAuthConfigWithPodIdentity(config *scalersconfig.ScalerConfig, meta *prometheusMetadata) error {
if meta != nil && !meta.PrometheusAuth.Disabled() && !(config.PodIdentity.Provider == kedav1alpha1.PodIdentityProviderNone || config.PodIdentity.Provider == "") {
return fmt.Errorf("pod identity cannot be enabled with other auth types")
}
meta.prometheusAuth = auth

return nil
}

Expand Down Expand Up @@ -226,14 +220,14 @@ func (s *prometheusScaler) ExecutePromQuery(ctx context.Context) (float64, error
}

switch {
case s.metadata.prometheusAuth == nil:
case s.metadata.PrometheusAuth.Disabled():
break
case s.metadata.prometheusAuth.EnableBearerAuth:
req.Header.Set("Authorization", authentication.GetBearerToken(s.metadata.prometheusAuth))
case s.metadata.prometheusAuth.EnableBasicAuth:
req.SetBasicAuth(s.metadata.prometheusAuth.Username, s.metadata.prometheusAuth.Password)
case s.metadata.prometheusAuth.EnableCustomAuth:
req.Header.Set(s.metadata.prometheusAuth.CustomAuthHeader, s.metadata.prometheusAuth.CustomAuthValue)
case s.metadata.PrometheusAuth.Enabled(authentication.BearerAuthType):
req.Header.Set("Authorization", s.metadata.PrometheusAuth.GetBearerToken())
case s.metadata.PrometheusAuth.Enabled(authentication.BasicAuthType):
req.SetBasicAuth(s.metadata.PrometheusAuth.Username, s.metadata.PrometheusAuth.Password)
case s.metadata.PrometheusAuth.Enabled(authentication.CustomAuthType):
req.Header.Set(s.metadata.PrometheusAuth.CustomAuthHeader, s.metadata.PrometheusAuth.CustomAuthValue)
}

r, err := s.httpClient.Do(req)
Expand Down
11 changes: 6 additions & 5 deletions pkg/scalers/prometheus_scaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"golang.org/x/oauth2"

kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
"github.com/kedacore/keda/v2/pkg/scalers/authentication"
"github.com/kedacore/keda/v2/pkg/scalers/scalersconfig"
)

Expand Down Expand Up @@ -162,11 +163,11 @@ func TestPrometheusScalerAuthParams(t *testing.T) {
}

if err == nil {
if meta.prometheusAuth != nil {
if (meta.prometheusAuth.EnableBearerAuth && !strings.Contains(testData.metadata["authModes"], "bearer")) ||
(meta.prometheusAuth.EnableBasicAuth && !strings.Contains(testData.metadata["authModes"], "basic")) ||
(meta.prometheusAuth.EnableTLS && !strings.Contains(testData.metadata["authModes"], "tls")) ||
(meta.prometheusAuth.EnableCustomAuth && !strings.Contains(testData.metadata["authModes"], "custom")) {
if !meta.PrometheusAuth.Disabled() {
if (meta.PrometheusAuth.Enabled(authentication.BearerAuthType) && !strings.Contains(testData.metadata["authModes"], "bearer")) ||
(meta.PrometheusAuth.Enabled(authentication.BasicAuthType) && !strings.Contains(testData.metadata["authModes"], "basic")) ||
(meta.PrometheusAuth.Enabled(authentication.TLSAuthType) && !strings.Contains(testData.metadata["authModes"], "tls")) ||
(meta.PrometheusAuth.Enabled(authentication.CustomAuthType) && !strings.Contains(testData.metadata["authModes"], "custom")) {
t.Error("wrong auth mode detected")
}
}
Expand Down
Loading

0 comments on commit 6a6c9b0

Please sign in to comment.