Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow unsafeSsl for artemis connections #4081

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ Here is an overview of all new **experimental** features:

- **General**: Add a warning when KEDA run outside supported k8s versions ([#4130](https://github.com/kedacore/keda/issues/4130))
- **General**: Use (self-signed) certificates for all the communications (internals and externals) ([#3931](https://github.com/kedacore/keda/issues/3931))
- **Artemis Scaler**: Add unsafeSsl option ([#4081](https://github.com/kedacore/keda/pull/4081))
- **Hashicorp Vault**: Add support to secrets backend version 1 ([#2645](https://github.com/kedacore/keda/issues/2645))
- **RabbitMQ Scaler**: Add TLS support ([#967](https://github.com/kedacore/keda/issues/967))
- **RabbitMQ Scaler**: Add TLS support ([#967](https://github.com/kedacore/keda/issues/967))
- **Redis Scalers**: Add support to Redis 7 ([#4052](https://github.com/kedacore/keda/issues/4052))
- **Selenium Grid Scaler**: Add 'platformName' to selenium-grid scaler metadata structure ([#4038](https://github.com/kedacore/keda/issues/4038))

Expand Down Expand Up @@ -212,7 +213,7 @@ Previously announced deprecation(s):
- **General**: Metrics Server: use gRPC connection to get metrics from Operator ([#3920](https://github.com/kedacore/keda/issues/3920))
- **General**: Metrics Server: use OpenAPI definitions served by custom-metrics-apiserver ([#3929](https://github.com/kedacore/keda/issues/3929))
- **Azure EventHub**: Add e2e tests ([#2792](https://github.com/kedacore/keda/issues/2792))
- **Apache Kafka Scaler:** Increase logging V-level ([#3948](https://github.com/kedacore/keda/issues/3948))
- **Apache Kafka Scaler:** Increase logging V-level ([#3948](https://github.com/kedacore/keda/issues/3948))

## v2.8.1

Expand Down Expand Up @@ -351,7 +352,7 @@ None.
- **Datadog Scaler:** Validate query to contain `{` to prevent panic on invalid query ([#2625](https://github.com/kedacore/keda/issues/2625))
- **Datadog Scaler:** Several improvements, including a new optional parameter `metricUnavailableValue` to fill data when no Datadog metric was returned ([#2657](https://github.com/kedacore/keda/issues/2657))
- **Datadog Scaler:** Rely on Datadog API to validate the query ([2761](https://github.com/kedacore/keda/issues/2761))
- **Graphite Scaler** Use the latest non-null datapoint returned by query. ([#2625](https://github.com/kedacore/keda/issues/2944))
- **Graphite Scaler** Use the latest non-null datapoint returned by query. ([#2625](https://github.com/kedacore/keda/issues/2944))
- **Kafka Scaler:** Make "disable" a valid value for tls auth parameter ([#2608](https://github.com/kedacore/keda/issues/2608))
- **Kafka Scaler:** New `scaleToZeroOnInvalidOffset` to control behavior when partitions have an invalid offset ([#2033](https://github.com/kedacore/keda/issues/2033)[#2612](https://github.com/kedacore/keda/issues/2612))
- **Metric API Scaler:** Improve error handling on not-ok response ([#2317](https://github.com/kedacore/keda/issues/2317))
Expand Down Expand Up @@ -498,7 +499,7 @@ None.
- Refactor AWS related scalers to reuse the AWS clients instead of creating a new one for every `GetMetrics` call ([#2255](https://github.com/kedacore/keda/pull/2255))
- Improve context handling in appropriate functionality in which we instantiate scalers ([#2267](https://github.com/kedacore/keda/pull/2267))
- Migrate to Kubebuilder v3 ([#2082](https://github.com/kedacore/keda/pull/2082))
- API path has been changed: `github.com/kedacore/keda/v2/api/v1alpha1` -> `github.com/kedacore/keda/v2/apis/keda/v1alpha1`
- API path has been changed: `github.com/kedacore/keda/v2/api/v1alpha1` -> `github.com/kedacore/keda/v2/apis/keda/v1alpha1`
- Use Patch to set FallbackCondition on ScaledObject.Status ([#2037](https://github.com/kedacore/keda/pull/2037))
- Bump Golang to 1.17.3 ([#2329](https://github.com/kedacore/keda/pull/2329))
- Add Makefile mockgen targets ([#2090](https://github.com/kedacore/keda/issues/2090)|[#2184](https://github.com/kedacore/keda/pull/2184))
Expand Down Expand Up @@ -552,7 +553,7 @@ None.

### Improvements

- Azure Service Bus Scaler: Namespace from `connectionString` parameter is added to `metricName` due to uniqueness violation for clusters having more than one queue with the same name ([#1755](https://github.com/kedacore/keda/issues/1755))
- Azure Service Bus Scaler: Namespace from `connectionString` parameter is added to `metricName` due to uniqueness violation for clusters having more than one queue with the same name ([#1755](https://github.com/kedacore/keda/issues/1755))
- Remove app.kubernetes.io/version label from label selectors ([#1696](https://github.com/kedacore/keda/pull/1696))
- Apache Kafka Scaler: Add `allowIdleConsumers` to the list of trigger parameters ([#1684](https://github.com/kedacore/keda/pull/1684))
- Fixed goroutine leaks in usage of timers ([#1704](https://github.com/kedacore/keda/pull/1704) | [#1739](https://github.com/kedacore/keda/pull/1739))
Expand Down Expand Up @@ -691,6 +692,7 @@ None.
- CRDs are using `apiextensions.k8s.io/v1` apiVersion ([#1202](https://github.com/kedacore/keda/pull/1202))

### Other

- Change API optional structs to pointers to conform with k8s guide ([#1170](https://github.com/kedacore/keda/issues/1170))
- Update Operator SDK and k8s deps ([#1007](https://github.com/kedacore/keda/pull/1007),[#870](https://github.com/kedacore/keda/issues/870),[#1180](https://github.com/kedacore/keda/pull/1180))
- Change Metrics Server image name from `keda-metrics-adapter` to `keda-metrics-apiserver` ([#1105](https://github.com/kedacore/keda/issues/1105))
Expand All @@ -703,13 +705,13 @@ Learn more about our release in [our milestone](https://github.com/kedacore/keda
### New

- **Scalers**
- Introduce Active MQ Artemis scaler ([Docs](https://keda.sh/docs/1.5/scalers/artemis/))
- Introduce Redis Streams scaler ([Docs](https://keda.sh/docs/1.5/scalers/redis-streams/) | [Details](https://github.com/kedacore/keda/issues/746))
- Introduce Cron scaler ([Docs](https://keda.sh/docs/1.5/scalers/cron/) | [Details](https://github.com/kedacore/keda/issues/812))
- Introduce Active MQ Artemis scaler ([Docs](https://keda.sh/docs/1.5/scalers/artemis/))
- Introduce Redis Streams scaler ([Docs](https://keda.sh/docs/1.5/scalers/redis-streams/) | [Details](https://github.com/kedacore/keda/issues/746))
- Introduce Cron scaler ([Docs](https://keda.sh/docs/1.5/scalers/cron/) | [Details](https://github.com/kedacore/keda/issues/812))
- **Secret Providers**
- Introduce HashiCorp Vault secret provider ([Docs](https://keda.sh/docs/1.5/concepts/authentication/#hashicorp-vault-secrets) | [Details](https://github.com/kedacore/keda/issues/673))
- Introduce HashiCorp Vault secret provider ([Docs](https://keda.sh/docs/1.5/concepts/authentication/#hashicorp-vault-secrets) | [Details](https://github.com/kedacore/keda/issues/673))
- **Other**
- Introduction of `nodeSelector` in raw YAML deployment specifications ([Details](https://github.com/kedacore/keda/pull/856))
- Introduction of `nodeSelector` in raw YAML deployment specifications ([Details](https://github.com/kedacore/keda/pull/856))

### Improvements

Expand Down
100 changes: 65 additions & 35 deletions pkg/scalers/artemis_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
v2 "k8s.io/api/autoscaling/v2"
"k8s.io/metrics/pkg/apis/external_metrics"

"github.com/kedacore/keda/v2/pkg/scalers/authentication"
kedautil "github.com/kedacore/keda/v2/pkg/util"
)

Expand All @@ -30,13 +31,13 @@ type artemisMetadata struct {
queueName string
brokerName string
brokerAddress string
username string
password string
artemisAuth *authentication.AuthMeta
restAPITemplate string
queueLength int64
activationQueueLength int64
corsHeader string
scalerIndex int
unsafeSsl bool
}

//revive:enable:var-naming
Expand All @@ -57,11 +58,6 @@ const (

// NewArtemisQueueScaler creates a new artemis queue Scaler
func NewArtemisQueueScaler(config *ScalerConfig) (Scaler, error) {
// do we need to guarantee this timeout for a specific
// reason? if not, we can have buildScaler pass in
// the global client
httpClient := kedautil.CreateHTTPClient(config.GlobalHTTPTimeout, false)

metricType, err := GetMetricTargetType(config)
if err != nil {
return nil, fmt.Errorf("error getting scaler metric type: %w", err)
Expand All @@ -71,6 +67,10 @@ func NewArtemisQueueScaler(config *ScalerConfig) (Scaler, error) {
if err != nil {
return nil, fmt.Errorf("error parsing artemis metadata: %w", err)
}
// do we need to guarantee this timeout for a specific
// reason? if not, we can have buildScaler pass in
// the global client
httpClient := kedautil.CreateHTTPClient(config.GlobalHTTPTimeout, artemisMetadata.unsafeSsl)

return &artemisScaler{
metricType: metricType,
Expand All @@ -83,6 +83,7 @@ func NewArtemisQueueScaler(config *ScalerConfig) (Scaler, error) {
func parseArtemisMetadata(config *ScalerConfig) (*artemisMetadata, error) {
meta := artemisMetadata{}

meta.unsafeSsl = false
meta.queueLength = defaultArtemisQueueLength
meta.activationQueueLength = defaultArtemisActivationQueueLength

Expand Down Expand Up @@ -139,40 +140,24 @@ func parseArtemisMetadata(config *ScalerConfig) (*artemisMetadata, error) {
meta.activationQueueLength = activationQueueLength
}

if val, ok := config.AuthParams["username"]; ok && val != "" {
meta.username = val
} else if val, ok := config.TriggerMetadata["username"]; ok && val != "" {
username := val

if val, ok := config.ResolvedEnv[username]; ok && val != "" {
meta.username = val
} else {
meta.username = username
}
}
meta.scalerIndex = config.ScalerIndex

if meta.username == "" {
return nil, fmt.Errorf("username cannot be empty")
// parse auth configs from ScalerConfig
auth, err := parseArtemisAuth(config)
if err != nil {
return nil, err
}
meta.artemisAuth = auth

if val, ok := config.AuthParams["password"]; ok && val != "" {
meta.password = val
} else if val, ok := config.TriggerMetadata["password"]; ok && val != "" {
password := val

if val, ok := config.ResolvedEnv[password]; ok && val != "" {
meta.password = val
} else {
meta.password = password
if val, ok := config.TriggerMetadata[unsafeSsl]; ok && val != "" {
unsafeSslValue, err := strconv.ParseBool(val)
if err != nil {
return nil, fmt.Errorf("error parsing %s: %w", unsafeSsl, err)
}
}

if meta.password == "" {
return nil, fmt.Errorf("password cannot be empty")
meta.unsafeSsl = unsafeSslValue
}

meta.scalerIndex = config.ScalerIndex

return &meta, nil
}

Expand Down Expand Up @@ -208,6 +193,51 @@ func getAPIParameters(meta artemisMetadata) (artemisMetadata, error) {
return meta, nil
}

func parseArtemisAuth(config *ScalerConfig) (*authentication.AuthMeta, error) {
NoUseFreak marked this conversation as resolved.
Show resolved Hide resolved
if val, ok := config.AuthParams[authentication.AuthModesKey]; ok && val != string(authentication.BasicAuthType) {
return nil, fmt.Errorf("only basic authMode is allowed")
}

auth, err := authentication.GetAuthConfigs(config.TriggerMetadata, config.AuthParams)
if err != nil {
return nil, err
}
if auth == nil {
auth = &authentication.AuthMeta{}
}

// Preserve backward compatibility
if val, ok := config.TriggerMetadata["username"]; ok && val != "" {
username := val

if val, ok := config.ResolvedEnv[username]; ok && val != "" {
auth.Username = val
} else {
auth.Username = username
}
}

if auth.Username == "" {
return nil, fmt.Errorf("username cannot be empty")
}

if val, ok := config.TriggerMetadata["password"]; ok && val != "" {
password := val

if val, ok := config.ResolvedEnv[password]; ok && val != "" {
auth.Password = val
} else {
auth.Password = password
}
}

if auth.Password == "" {
return nil, fmt.Errorf("password cannot be empty")
}

return auth, nil
}

func (s *artemisScaler) getMonitoringEndpoint() string {
replacer := strings.NewReplacer("<<managementEndpoint>>", s.metadata.managementEndpoint,
"<<queueName>>", s.metadata.queueName,
Expand All @@ -230,7 +260,7 @@ func (s *artemisScaler) getQueueMessageCount(ctx context.Context) (int64, error)
if err != nil {
return -1, err
}
req.SetBasicAuth(s.metadata.username, s.metadata.password)
req.SetBasicAuth(s.metadata.artemisAuth.Username, s.metadata.artemisAuth.Password)
req.Header.Set("Origin", s.metadata.corsHeader)

resp, err := client.Do(req)
Expand Down
3 changes: 3 additions & 0 deletions pkg/scalers/artemis_scaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ var testArtemisMetadata = []parseArtemisMetadataTestData{
{map[string]string{"restApiTemplate": "http://localhost:8161/console/jolokia/read/org.apache.activemq.artemis:broker=\"broker-activemq\",component=addresses,address=\"test\",subcomponent=queues,routing-type=\"anycast\",queue=\"queue1\"/MessageCount", "username": "myUserName", "password": "myPassword"}, false},
// Missing brokername , should fail
{map[string]string{"restApiTemplate": "http://localhost:8161/console/jolokia/read/org.apache.activemq.artemis:broker=\"\",component=addresses,address=\"test\",subcomponent=queues,routing-type=\"anycast\",queue=\"queue1\"/MessageCount", "username": "myUserName", "password": "myPassword"}, true},
// Bad unsafeSsl, should fail
{map[string]string{"managementEndpoint": "localhost:8161", "queueName": "queue1", "brokerName": "broker-activemq", "brokerAddress": "test", "username": "myUserName", "password": "myPassword", "unsafeSsl": "bad"}, true},
{map[string]string{"managementEndpoint": "localhost:8161", "queueName": "queue1", "brokerName": "broker-activemq", "brokerAddress": "test", "username": "myUserName", "password": "myPassword", "unsafeSsl": "false"}, false},
}

var artemisMetricIdentifiers = []artemisMetricIdentifier{
Expand Down