Skip to content
Open
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
6 changes: 6 additions & 0 deletions pkg/functions/function.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ type DeploySpec struct {
// Defaults to "knative" for backwards compatibility
Deployer string `yaml:"deployer,omitempty" jsonschema:"enum=knative,enum=raw,enum=keda"`

// ClusterDomain specifies the cluster domain used for building internal service URLs.
// Defaults to "cluster.local" if not specified.
// This is particularly useful for KEDA deployments where the interceptor proxy
// service URL needs to match the cluster's actual domain configuration.
ClusterDomain string `yaml:"clusterDomain,omitempty"`

Subscriptions []KnativeSubscription `yaml:"subscriptions,omitempty"`
}

Expand Down
10 changes: 9 additions & 1 deletion pkg/keda/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ func (d *Deployer) interceptorBridgeServiceName(f fn.Function) string {
}

func (d *Deployer) interceptorBridgeService(f fn.Function, namespace string, deployment *v1.Deployment) *corev1.Service {
// Use configured cluster domain, default to "cluster.local"
clusterDomain := f.Deploy.ClusterDomain
if clusterDomain == "" {
clusterDomain = "cluster.local"
}

externalName := fmt.Sprintf("keda-add-ons-http-interceptor-proxy.keda.svc.%s", clusterDomain)

return &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: d.interceptorBridgeServiceName(f),
Expand All @@ -220,7 +228,7 @@ func (d *Deployer) interceptorBridgeService(f fn.Function, namespace string, dep
},
Spec: corev1.ServiceSpec{
Type: corev1.ServiceTypeExternalName,
ExternalName: "keda-add-ons-http-interceptor-proxy.keda.svc.cluster.local",
ExternalName: externalName,
},
}
}
Expand Down
86 changes: 86 additions & 0 deletions pkg/keda/deployer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package keda

import (
"testing"

v1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fn "knative.dev/func/pkg/functions"
)

func TestDeployer_interceptorBridgeService(t *testing.T) {
tests := []struct {
name string
function fn.Function
expectedExternalName string
}{
{
name: "uses default cluster.local when ClusterDomain is empty",
function: fn.Function{
Name: "test-func",
Deploy: fn.DeploySpec{
ClusterDomain: "",
},
},
expectedExternalName: "keda-add-ons-http-interceptor-proxy.keda.svc.cluster.local",
},
{
name: "uses custom cluster domain when specified",
function: fn.Function{
Name: "test-func",
Deploy: fn.DeploySpec{
ClusterDomain: "custom.domain",
},
},
expectedExternalName: "keda-add-ons-http-interceptor-proxy.keda.svc.custom.domain",
},
{
name: "uses cluster.local explicitly when specified",
function: fn.Function{
Name: "test-func",
Deploy: fn.DeploySpec{
ClusterDomain: "cluster.local",
},
},
expectedExternalName: "keda-add-ons-http-interceptor-proxy.keda.svc.cluster.local",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
d := NewDeployer()
deployment := &v1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: tt.function.Name,
UID: "test-uid",
},
}

service := d.interceptorBridgeService(tt.function, "test-namespace", deployment)

if service.Spec.ExternalName != tt.expectedExternalName {
t.Errorf("interceptorBridgeService() ExternalName = %v, want %v",
service.Spec.ExternalName, tt.expectedExternalName)
}

// Verify service name
expectedServiceName := d.interceptorBridgeServiceName(tt.function)
if service.Name != expectedServiceName {
t.Errorf("interceptorBridgeService() Name = %v, want %v",
service.Name, expectedServiceName)
}

// Verify namespace
if service.Namespace != "test-namespace" {
t.Errorf("interceptorBridgeService() Namespace = %v, want %v",
service.Namespace, "test-namespace")
}

// Verify service type
if service.Spec.Type != "ExternalName" {
t.Errorf("interceptorBridgeService() Type = %v, want %v",
service.Spec.Type, "ExternalName")
}
})
}
}