Skip to content

Commit

Permalink
fead: Move http scaled object from single host to multi host system
Browse files Browse the repository at this point in the history
Signed-off-by: Somesh Koli <somesh.koli@headout.com>
Signed-off-by: Jocelyn Thode <jocelyn@thode.email>
  • Loading branch information
someshkoli authored and jocelynthode committed May 10, 2023
1 parent c87b1b8 commit 9488dd5
Show file tree
Hide file tree
Showing 18 changed files with 310 additions and 147 deletions.
1 change: 0 additions & 1 deletion .github/workflows/e2e-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ jobs:
- name: Show Kubernetes version
run: |
kubectl version
- name: Run e2e test
run: |
make e2e-test
Expand Down
8 changes: 5 additions & 3 deletions config/crd/bases/http.keda.sh_httpscaledobjects.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ spec:
spec:
description: HTTPScaledObjectSpec defines the desired state of HTTPScaledObject
properties:
host:
hosts:
description: The host to route. All requests with this host in the
"Host" header will be routed to the Service and Port specified in
the scaleTargetRef
type: string
items:
type: string
type: array
replicas:
description: (optional) Replica information
properties:
Expand Down Expand Up @@ -107,7 +109,7 @@ spec:
format: int32
type: integer
required:
- host
- hosts
- scaleTargetRef
type: object
status:
Expand Down
5 changes: 4 additions & 1 deletion examples/xkcd/templates/httpscaledobject.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ apiVersion: http.keda.sh/v1alpha1
metadata:
name: {{ include "xkcd.fullname" . }}
spec:
host: {{ .Values.host }}
{{- with .Values.hosts }}
hosts:
{{- toYaml . | nindent 8 }}
{{- end }}
targetPendingRequests: {{ .Values.targetPendingRequests }}
scaleTargetRef:
deployment: {{ include "xkcd.fullname" . }}
Expand Down
4 changes: 3 additions & 1 deletion examples/xkcd/templates/ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ metadata:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: {{ .Values.host }}
{{- range .Values.hosts }}
- host: {{ . | toString }}
http:
paths:
- path: /
Expand All @@ -18,3 +19,4 @@ spec:
name: keda-add-ons-http-interceptor-proxy
port:
number: 8080
{{- end }}
4 changes: 3 additions & 1 deletion examples/xkcd/values.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
replicaCount: 1
host: myhost.com
hosts:
- "myhost.com"
- "myhost2.com"
targetPendingRequests: 200
# This is the namespace that the ingress should be installed
# into. It should be set to the same namespace as the
Expand Down
4 changes: 2 additions & 2 deletions operator/apis/http/v1alpha1/httpscaledobject_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ type ReplicaStruct struct {

// HTTPScaledObjectSpec defines the desired state of HTTPScaledObject
type HTTPScaledObjectSpec struct {
// The host to route. All requests with this host in the "Host" header will
// The hosts to route. All requests with these hosts in the "Host" header will
// be routed to the Service and Port specified in the scaleTargetRef
Host string `json:"host"`
Hosts []string `json:"hosts"`
// The name of the deployment to route HTTP requests to (and to autoscale).
// Either this or Image must be set
ScaleTargetRef *ScaleTargetRef `json:"scaleTargetRef"`
Expand Down
4 changes: 2 additions & 2 deletions operator/controllers/http/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func removeApplicationResources(
logger,
cl,
routingTable,
httpso.Spec.Host,
httpso.Spec.Hosts,
baseConfig.CurrentNamespace,
); err != nil {
return err
Expand Down Expand Up @@ -149,7 +149,7 @@ func createOrUpdateApplicationResources(
logger,
cl,
routingTable,
httpso.Spec.Host,
httpso.Spec.Hosts,
routing.NewTarget(
httpso.GetNamespace(),
httpso.Spec.ScaleTargetRef.Service,
Expand Down
36 changes: 20 additions & 16 deletions operator/controllers/http/routing_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@ func removeAndUpdateRoutingTable(
lggr logr.Logger,
cl client.Client,
table *routing.Table,
host,
hosts []string,
namespace string,
) error {
lggr = lggr.WithName("removeAndUpdateRoutingTable")
if err := table.RemoveTarget(host); err != nil {
lggr.Error(
err,
"could not remove host from routing table, progressing anyway",
"host",
host,
)
for _, host := range hosts {
if err := table.RemoveTarget(host); err != nil {
lggr.Error(
err,
"could not remove host from routing table, progressing anyway",
"host",
host,
)
}
}

return updateRoutingMap(ctx, lggr, cl, namespace, table)
Expand All @@ -37,18 +39,20 @@ func addAndUpdateRoutingTable(
lggr logr.Logger,
cl client.Client,
table *routing.Table,
host string,
hosts []string,
target routing.Target,
namespace string,
) error {
lggr = lggr.WithName("addAndUpdateRoutingTable")
if err := table.AddTarget(host, target); err != nil {
lggr.Error(
err,
"could not add host to routing table, progressing anyway",
"host",
host,
)
for _, host := range hosts {
if err := table.AddTarget(host, target); err != nil {
lggr.Error(
err,
"could not add host to routing table, progressing anyway",
"host",
host,
)
}
}
return updateRoutingMap(ctx, lggr, cl, namespace, table)
}
Expand Down
24 changes: 16 additions & 8 deletions operator/controllers/http/routing_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,18 @@ import (
"github.com/kedacore/http-add-on/pkg/routing"
)

func getHosts() []string {
return []string{"myhost.com"}
}

func TestRoutingTable(t *testing.T) {
table := routing.NewTable()
const (
host = "myhost.com"
ns = "testns"
svcName = "testsvc"
deplName = "testdepl"
)
hosts := getHosts()
r := require.New(t)
ctx := context.Background()
cl := k8s.NewFakeRuntimeClient()
Expand All @@ -45,7 +49,7 @@ func TestRoutingTable(t *testing.T) {
logr.Discard(),
cl,
table,
host,
hosts,
target,
ns,
))
Expand All @@ -56,16 +60,18 @@ func TestRoutingTable(t *testing.T) {
r.Equal(0, len(cl.FakeRuntimeClientWriter.Updates))
r.Equal(0, len(cl.FakeRuntimeClientWriter.Creates))

retTarget, err := table.Lookup(host)
r.NoError(err)
r.Equal(&target, retTarget)
for _, host := range hosts {
retTarget, err := table.Lookup(host)
r.NoError(err)
r.Equal(target, *retTarget)
}

r.NoError(removeAndUpdateRoutingTable(
ctx,
logr.Discard(),
cl,
table,
host,
hosts,
ns,
))

Expand All @@ -76,6 +82,8 @@ func TestRoutingTable(t *testing.T) {
r.Equal(0, len(cl.FakeRuntimeClientWriter.Updates))
r.Equal(0, len(cl.FakeRuntimeClientWriter.Creates))

_, err = table.Lookup(host)
r.Error(err)
for _, host := range hosts {
_, err := table.Lookup(host)
r.Error(err)
}
}
2 changes: 1 addition & 1 deletion operator/controllers/http/scaled_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func createOrUpdateScaledObject(
fmt.Sprintf("%s-app", httpso.GetName()), // HTTPScaledObject name is the same as the ScaledObject name
httpso.Spec.ScaleTargetRef.Deployment,
externalScalerHostName,
httpso.Spec.Host,
httpso.Spec.Hosts,
minReplicaCount,
maxReplicaCount,
httpso.Spec.CooldownPeriod,
Expand Down
6 changes: 6 additions & 0 deletions operator/controllers/http/scaled_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ func TestCreateOrUpdateScaledObject(t *testing.T) {
spec.MaxReplicaCount,
)

// get hosts from spec and ensure all the hosts are there
r.Equal(
2,
len(testInfra.httpso.Spec.Hosts),
)

// now update the min and max replicas on the httpso
// and call createOrUpdateScaledObject again
if spec := &testInfra.httpso.Spec; spec.Replicas == nil {
Expand Down
1 change: 1 addition & 0 deletions operator/controllers/http/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func newCommonTestInfra(namespace, appName string) *commonTestInfra {
Service: appName,
Port: 8081,
},
Hosts: []string{"myhost1.com", "myhost2.com"},
},
}

Expand Down
8 changes: 5 additions & 3 deletions pkg/k8s/scaledobject.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package k8s

import (
"strings"

kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -12,7 +14,7 @@ const (
soTriggerType = "external-push"

mkScalerAddress = "scalerAddress"
mkHost = "host"
mkHosts = "hosts"
)

// NewScaledObject creates a new ScaledObject in memory
Expand All @@ -21,7 +23,7 @@ func NewScaledObject(
name string,
deploymentName string,
scalerAddress string,
host string,
hosts []string,
minReplicas *int32,
maxReplicas *int32,
cooldownPeriod *int32,
Expand Down Expand Up @@ -54,7 +56,7 @@ func NewScaledObject(
Type: soTriggerType,
Metadata: map[string]string{
mkScalerAddress: scalerAddress,
mkHost: host,
mkHosts: strings.Join(hosts, ","),
},
},
},
Expand Down
24 changes: 24 additions & 0 deletions pkg/k8s/templates/scaledobject.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: {{ .Name }}
namespace: {{ .Namespace }}
labels:
{{- range $key, $val := .Labels }}
{{ $key }}: {{ $val }}
{{- end }}
spec:
minReplicaCount: {{ .MinReplicas }}
maxReplicaCount: {{ .MaxReplicas }}
cooldownPeriod: {{ .CooldownPeriod }}
pollingInterval: 1
scaleTargetRef:
name: {{ .DeploymentName }}
kind: Deployment
triggers:
- type: external-push
metadata:
scalerAddress: {{ $.ScalerAddress }}
hosts: '{{ join "," .Values.Hosts }}'
advanced:
restoreToOriginalReplicaCount: true
Loading

0 comments on commit 9488dd5

Please sign in to comment.