Skip to content

Commit

Permalink
Use Trigger Authentication for Redis Scaler (#441)
Browse files Browse the repository at this point in the history
* nats streaming support in the list.

* alphabetical oredering of scaler list.

* Use Trigger Authentication for Redis.

* remove password log.
  • Loading branch information
balchua authored and ahmelsayed committed Nov 9, 2019
1 parent ad18ad1 commit 6bd52e0
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 14 deletions.
36 changes: 36 additions & 0 deletions examples/redis_scaledobject_auth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
apiVersion: keda.k8s.io/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-trigger-auth-redis-secret
namespace: my-project
spec:
secretTargetRef: # Optional.
- parameter: password # Required.
name: votes-db-secret # Required.
key: redis_password # Required.

---

apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
name: redis-scaledobject
namespace: my-project
labels:
deploymentName: votes
spec:
pollingInterval: 5 # Optional. Default: 30 seconds
cooldownPeriod: 5 # Optional. Default: 300 seconds
minReplicaCount: 0 # Optional. Default: 0
maxReplicaCount: 30 # Optional. Default: 100
scaleTargetRef:
deploymentName: votes
triggers:
- type: redis
metadata:
address: REDIS_ADDRESS # the environment variable defined in the Pod, the value is in the format host:port
listName: mylist # Required
listLength: "10" # Required
authenticationRef:
name: keda-trigger-auth-redis-secret
2 changes: 1 addition & 1 deletion pkg/handler/scale_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func (h *ScaleHandler) getScaler(name, namespace, triggerType string, resolvedEn
case "prometheus":
return scalers.NewPrometheusScaler(resolvedEnv, triggerMetadata)
case "redis":
return scalers.NewRedisScaler(resolvedEnv, triggerMetadata)
return scalers.NewRedisScaler(resolvedEnv, triggerMetadata, authParams)
case "gcp-pubsub":
return scalers.NewPubSubScaler(resolvedEnv, triggerMetadata)
case "external":
Expand Down
10 changes: 6 additions & 4 deletions pkg/scalers/redis_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type redisMetadata struct {
var redisLog = logf.Log.WithName("redis_scaler")

// NewRedisScaler creates a new redisScaler
func NewRedisScaler(resolvedEnv, metadata map[string]string) (Scaler, error) {
meta, err := parseRedisMetadata(metadata, resolvedEnv)
func NewRedisScaler(resolvedEnv, metadata, authParams map[string]string) (Scaler, error) {
meta, err := parseRedisMetadata(metadata, resolvedEnv, authParams)
if err != nil {
return nil, fmt.Errorf("error parsing redis metadata: %s", err)
}
Expand All @@ -46,7 +46,7 @@ func NewRedisScaler(resolvedEnv, metadata map[string]string) (Scaler, error) {
}, nil
}

func parseRedisMetadata(metadata, resolvedEnv map[string]string) (*redisMetadata, error) {
func parseRedisMetadata(metadata, resolvedEnv, authParams map[string]string) (*redisMetadata, error) {
meta := redisMetadata{}
meta.targetListLength = defaultTargetListLength

Expand Down Expand Up @@ -76,7 +76,9 @@ func parseRedisMetadata(metadata, resolvedEnv map[string]string) (*redisMetadata
}

meta.password = defaultRedisPassword
if val, ok := metadata["password"]; ok && val != "" {
if val, ok := authParams["password"]; ok {
meta.password = val
} else if val, ok := metadata["password"]; ok && val != "" {
if passd, ok := resolvedEnv[val]; ok {
meta.password = passd
}
Expand Down
19 changes: 11 additions & 8 deletions pkg/scalers/redis_scaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,29 @@ var testRedisResolvedEnv = map[string]string{
}

type parseRedisMetadataTestData struct {
metadata map[string]string
isError bool
metadata map[string]string
isError bool
authParams map[string]string
}

var testRedisMetadata = []parseRedisMetadataTestData{
// nothing passed
{map[string]string{}, true},
{map[string]string{}, true, map[string]string{}},
// properly formed listName
{map[string]string{"listName": "mylist", "listLength": "10", "address": "REDIS_HOST", "password": "REDIS_PASSWORD"}, false},
{map[string]string{"listName": "mylist", "listLength": "10", "address": "REDIS_HOST", "password": "REDIS_PASSWORD"}, false, map[string]string{}},
// properly formed listName, empty address
{map[string]string{"listName": "mylist", "listLength": "10", "address": "", "password": ""}, true},
{map[string]string{"listName": "mylist", "listLength": "10", "address": "", "password": ""}, true, map[string]string{}},
// improperly formed listLength
{map[string]string{"listName": "mylist", "listLength": "AA", "address": "REDIS_HOST", "password": ""}, true},
{map[string]string{"listName": "mylist", "listLength": "AA", "address": "REDIS_HOST", "password": ""}, true, map[string]string{}},
// address does not resolve
{map[string]string{"listName": "mylist", "listLength": "0", "address": "REDIS_WRONG", "password": ""}, true},
{map[string]string{"listName": "mylist", "listLength": "0", "address": "REDIS_WRONG", "password": ""}, true, map[string]string{}},
// password is defined in the authParams
{map[string]string{"listName": "mylist", "listLength": "0", "address": "REDIS_WRONG"}, true, map[string]string{"password": ""}},
}

func TestRedisParseMetadata(t *testing.T) {
for _, testData := range testRedisMetadata {
_, err := parseRedisMetadata(testData.metadata, testRedisResolvedEnv)
_, err := parseRedisMetadata(testData.metadata, testRedisResolvedEnv, testData.authParams)
if err != nil && !testData.isError {
t.Error("Expected success but got error", err)
}
Expand Down
65 changes: 64 additions & 1 deletion spec/triggers/redis.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,67 @@ The **listName** parameter in the spec points to the Redis List that you want to
## Example
[`examples/azureeventhub_scaledobject.yaml`](./../../examples/redis_scaledobject.yaml)
[`examples/azureeventhub_scaledobject.yaml`](./../../examples/redis_scaledobject.yaml)

## Using Trigger Authentication CRD

When using the Trigger Authentication CRD `secretTargetRef`, like the example below

```yaml
apiVersion: keda.k8s.io/v1alpha1
kind: TriggerAuthentication
metadata:
name: keda-trigger-auth-redis-secret
namespace: my-project
spec:
secretTargetRef:
- parameter: password
name: votes-db-secret
key: redis_password
```

The `TriggerAuthentication` namespace must be the same as your consumer Pod's namespace.

Where:

* `parameter` value must be the same as the scaler's expecting field. In the case of Redis scaler, the Redis password is expected to be in the field `password`.
* `name` : the name of the kubernetes `Secret` manifest.
* `key`: the Opaque key defined in the `Secret` manifest.

Example below:

```yaml
apiVersion: v1
kind: Secret
metadata:
name: votes-db-secret
namespace: my-project
type: Opaque
data:
redis_password: YWRtaW4=
```

The scaledObject definition must include `TriggerAuthentication` name in the `authenticationRef` as shown below:

```yaml
apiVersion: keda.k8s.io/v1alpha1
kind: ScaledObject
metadata:
name: redis-scaledobject
namespace: my-project
labels:
deploymentName: votes
spec:
scaleTargetRef:
deploymentName: votes
triggers:
- type: redis
metadata:
address: REDIS_ADDRESS # the environment Variable defined in the Pod, the value is in the format host:port
listName: mylist # Required
listLength: "10" # Required
authenticationRef:
name: keda-trigger-auth-redis-secret
```

See example [`examples/redis_scaledobject_auth`](./../../examples/redis_scaledobject_auth.yaml)

0 comments on commit 6bd52e0

Please sign in to comment.