Skip to content

Commit

Permalink
feat: support TriggerAuthentication properties from ConfigMap (#5111)
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Wozniak <wozniak.jan@gmail.com>
  • Loading branch information
wozniakjan authored Oct 27, 2023
1 parent 567ea55 commit 3435623
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Here is an overview of all new **experimental** features:
### Improvements

- **General**: Add parameter queryParameters to prometheus-scaler ([#4962](https://github.com/kedacore/keda/issues/4962))
- **General**: Support TriggerAuthentication properties from ConfigMap ([#4830](https://github.com/kedacore/keda/issues/4830))
- **General**: TODO ([#XXX](https://github.com/kedacore/keda/issues/XXX))
- **Hashicorp Vault**: Add support to get secret that needs write operation (e.g. pki) ([#5067](https://github.com/kedacore/keda/issues/5067))
- **Kafka Scaler**: Ability to set upper bound to the number of partitions with lag ([#3997](https://github.com/kedacore/keda/issues/3997))
Expand Down
11 changes: 10 additions & 1 deletion apis/keda/v1alpha1/triggerauthentication_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ type TriggerAuthenticationSpec struct {
// +optional
SecretTargetRef []AuthSecretTargetRef `json:"secretTargetRef,omitempty"`

// +optional
ConfigMapTargetRef []AuthConfigMapTargetRef `json:"configMapTargetRef,omitempty"`

// +optional
Env []AuthEnvironment `json:"env,omitempty"`

Expand Down Expand Up @@ -142,8 +145,14 @@ func (a *AuthPodIdentity) GetIdentityID() string {
return *a.IdentityID
}

// AuthConfigMapTargetRef is used to authenticate using a reference to a config map
type AuthConfigMapTargetRef AuthTargetRef

// AuthSecretTargetRef is used to authenticate using a reference to a secret
type AuthSecretTargetRef struct {
type AuthSecretTargetRef AuthTargetRef

// AuthTargetRef is used to authenticate using a reference to a resource
type AuthTargetRef struct {
Parameter string `json:"parameter"`
Name string `json:"name"`
Key string `json:"key"`
Expand Down
35 changes: 35 additions & 0 deletions apis/keda/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions config/crd/bases/keda.sh_clustertriggerauthentications.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,23 @@ spec:
- secrets
- vaultUri
type: object
configMapTargetRef:
items:
description: AuthConfigMapTargetRef is used to authenticate using
a reference to a config map
properties:
key:
type: string
name:
type: string
parameter:
type: string
required:
- key
- name
- parameter
type: object
type: array
env:
items:
description: AuthEnvironment is used to authenticate using environment
Expand Down
17 changes: 17 additions & 0 deletions config/crd/bases/keda.sh_triggerauthentications.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,23 @@ spec:
- secrets
- vaultUri
type: object
configMapTargetRef:
items:
description: AuthConfigMapTargetRef is used to authenticate using
a reference to a config map
properties:
key:
type: string
name:
type: string
parameter:
type: string
required:
- key
- name
- parameter
type: object
type: array
env:
items:
description: AuthEnvironment is used to authenticate using environment
Expand Down
15 changes: 15 additions & 0 deletions pkg/scaling/resolver/scale_resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ func resolveAuthRef(ctx context.Context, client client.Client, logger logr.Logge
}
}
}
if triggerAuthSpec.ConfigMapTargetRef != nil {
for _, e := range triggerAuthSpec.ConfigMapTargetRef {
result[e.Parameter] = resolveAuthConfigMap(ctx, client, logger, e.Name, triggerNamespace, e.Key)
}
}
if triggerAuthSpec.SecretTargetRef != nil {
for _, e := range triggerAuthSpec.SecretTargetRef {
result[e.Parameter] = resolveAuthSecret(ctx, client, logger, e.Name, triggerNamespace, e.Key, secretsLister)
Expand Down Expand Up @@ -503,6 +508,16 @@ func resolveConfigValue(ctx context.Context, client client.Client, configKeyRef
return configMap.Data[keyName], nil
}

func resolveAuthConfigMap(ctx context.Context, client client.Client, logger logr.Logger, name, namespace, key string) string {
ref := &corev1.ConfigMapKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: name}, Key: key}
val, err := resolveConfigValue(ctx, client, ref, key, namespace)
if err != nil {
logger.Error(err, "error trying to get config map from namespace", "ConfigMap.Namespace", namespace, "ConfigMap.Name", name)
return ""
}
return val
}

func resolveAuthSecret(ctx context.Context, client client.Client, logger logr.Logger, name, namespace, key string, secretsLister corev1listers.SecretLister) string {
if name == "" || namespace == "" || key == "" {
logger.Error(fmt.Errorf("error trying to get secret"), "name, namespace and key are required", "Secret.Namespace", namespace, "Secret.Name", name, "key", key)
Expand Down
122 changes: 122 additions & 0 deletions pkg/scaling/resolver/scale_resolvers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ var (
secretName = "supersecret"
secretKey = "mysecretkey"
secretData = "secretDataHere"
cmName = "supercm"
cmKey = "mycmkey"
cmData = "cmDataHere"
trueValue = true
falseValue = false
envKey = "test-env-key"
Expand Down Expand Up @@ -320,6 +323,86 @@ func TestResolveAuthRef(t *testing.T) {
expected: map[string]string{"host": secretData},
expectedPodIdentity: kedav1alpha1.AuthPodIdentity{Provider: kedav1alpha1.PodIdentityProviderNone},
},
{
name: "triggerauth exists and config map",
existing: []runtime.Object{
&kedav1alpha1.TriggerAuthentication{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: triggerAuthenticationName,
},
Spec: kedav1alpha1.TriggerAuthenticationSpec{
PodIdentity: &kedav1alpha1.AuthPodIdentity{
Provider: kedav1alpha1.PodIdentityProviderNone,
},
ConfigMapTargetRef: []kedav1alpha1.AuthConfigMapTargetRef{
{
Parameter: "host",
Name: cmName,
Key: cmKey,
},
},
},
},
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: cmName,
},
Data: map[string]string{cmKey: cmData},
},
},
soar: &kedav1alpha1.AuthenticationRef{Name: triggerAuthenticationName},
expected: map[string]string{"host": cmData},
expectedPodIdentity: kedav1alpha1.AuthPodIdentity{Provider: kedav1alpha1.PodIdentityProviderNone},
},
{
name: "triggerauth exists secret + config map",
existing: []runtime.Object{
&kedav1alpha1.TriggerAuthentication{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: triggerAuthenticationName,
},
Spec: kedav1alpha1.TriggerAuthenticationSpec{
PodIdentity: &kedav1alpha1.AuthPodIdentity{
Provider: kedav1alpha1.PodIdentityProviderNone,
},
SecretTargetRef: []kedav1alpha1.AuthSecretTargetRef{
{
Parameter: "host-secret",
Name: secretName,
Key: secretKey,
},
},
ConfigMapTargetRef: []kedav1alpha1.AuthConfigMapTargetRef{
{
Parameter: "host-configmap",
Name: cmName,
Key: cmKey,
},
},
},
},
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: cmName,
},
Data: map[string]string{cmKey: cmData},
},
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Name: secretName,
},
Data: map[string][]byte{secretKey: []byte(secretData)},
},
},
soar: &kedav1alpha1.AuthenticationRef{Name: triggerAuthenticationName},
expected: map[string]string{"host-secret": secretData, "host-configmap": cmData},
expectedPodIdentity: kedav1alpha1.AuthPodIdentity{Provider: kedav1alpha1.PodIdentityProviderNone},
},
{
name: "clustertriggerauth exists, podidentity nil",
existing: []runtime.Object{
Expand Down Expand Up @@ -372,6 +455,45 @@ func TestResolveAuthRef(t *testing.T) {
expected: map[string]string{"host": secretData},
expectedPodIdentity: kedav1alpha1.AuthPodIdentity{Provider: kedav1alpha1.PodIdentityProviderNone},
},
{
name: "clustertriggerauth exists and secret + config map",
existing: []runtime.Object{
&kedav1alpha1.ClusterTriggerAuthentication{
ObjectMeta: metav1.ObjectMeta{
Name: triggerAuthenticationName,
},
Spec: kedav1alpha1.TriggerAuthenticationSpec{
PodIdentity: &kedav1alpha1.AuthPodIdentity{
Provider: kedav1alpha1.PodIdentityProviderNone,
},
SecretTargetRef: []kedav1alpha1.AuthSecretTargetRef{
{
Parameter: "host",
Name: secretName,
Key: secretKey,
},
},
},
},
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: clusterNamespace,
Name: secretName,
},
Data: map[string][]byte{secretKey: []byte(secretData)},
},
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Namespace: clusterNamespace,
Name: secretName,
},
Data: map[string]string{secretKey: secretData},
},
},
soar: &kedav1alpha1.AuthenticationRef{Name: triggerAuthenticationName, Kind: "ClusterTriggerAuthentication"},
expected: map[string]string{"host": secretData},
expectedPodIdentity: kedav1alpha1.AuthPodIdentity{Provider: kedav1alpha1.PodIdentityProviderNone},
},
{
name: "clustertriggerauth exists and secret in the wrong namespace",
existing: []runtime.Object{
Expand Down

0 comments on commit 3435623

Please sign in to comment.