Skip to content

Commit

Permalink
Move replicas to KubernetesResource from eventlistener spec
Browse files Browse the repository at this point in the history
  • Loading branch information
savitaashture committed Mar 28, 2021
1 parent 571fbb6 commit e4745f2
Show file tree
Hide file tree
Showing 13 changed files with 166 additions and 29 deletions.
10 changes: 10 additions & 0 deletions docs/eventlisteners.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ using [Event Interceptors](#Interceptors).
- [PodTemplate](#podtemplate)
- [Resources](#resources)
- [kubernetesResource](#kubernetesresource)
- [Replicas](#replicas)
- [CustomResource](#customresource)
- [Contract](#contract)
- [Logging](#logging)
Expand Down Expand Up @@ -191,6 +192,8 @@ check out the guide on [exposing EventListeners](./exposing-eventlisteners.md).

### Replicas

The `replicas` field is deprecated as part of eventlistener spec instead its moved to `resources.kubernetesResource`.

The `replicas` field is optional. By default, the number of replicas of EventListener is 1.
If you want to deploy more than one pod, you can specify the number to `replicas` field.

Expand Down Expand Up @@ -263,6 +266,13 @@ spec:

With the help of `kubernetesResource` user can specify [PodTemplateSpec](https://github.com/kubernetes/api/blob/master/core/v1/types.go#L3704).

##### Replicas

The `replicas` field is optional. By default, the number of replicas of EventListener is 1.
If you want to deploy more than one pod, you can specify the number to `replicas` field.

**Note:** If user sets `replicas` field while creating/updating eventlistener yaml then it won't respects replicas values edited by user manually on deployment or through any other mechanism (ex: HPA).

#### CustomResource
A `CustomResource` object has one field that supports dynamic objects.
* runtime.RawExtension
Expand Down
4 changes: 3 additions & 1 deletion examples/eventlisteners/eventlistener-replicas.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ metadata:
name: listener-replicas
spec:
serviceAccountName: tekton-triggers-example-sa
replicas: 3
triggers:
- name: foo-trig
bindings:
- ref: pipeline-binding
- ref: message-binding
template:
ref: pipeline-template
resources:
kubernetesResource:
replicas: 3
30 changes: 28 additions & 2 deletions pkg/apis/triggers/v1alpha1/event_listener_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ package v1alpha1

import (
"context"

"knative.dev/pkg/ptr"
)

// SetDefaults sets the defaults on the object.
func (el *EventListener) SetDefaults(ctx context.Context) {
if IsUpgradeViaDefaulting(ctx) {
// set defaults
if el.Spec.Replicas != nil && *el.Spec.Replicas == 0 {
*el.Spec.Replicas = 1
if el.Spec.Resources.KubernetesResource != nil {
if el.Spec.Resources.KubernetesResource.Replicas != nil && *el.Spec.Resources.KubernetesResource.Replicas == 0 {
*el.Spec.Resources.KubernetesResource.Replicas = 1
}
}

for i, t := range el.Spec.Triggers {
triggerSpecBindingArray(el.Spec.Triggers[i].Bindings).defaultBindings()
for _, ti := range t.Interceptors {
Expand All @@ -37,6 +42,27 @@ func (el *EventListener) SetDefaults(ctx context.Context) {
// To be removed in a later release #904
el.Spec.updatePodTemplate()
el.Spec.updateServiceType()
// To be removed in a later release #1020
el.Spec.updateReplicas()
}
}

// To be Removed in a later release #1020
func (spec *EventListenerSpec) updateReplicas() {
if spec.DeprecatedReplicas != nil {
if *spec.DeprecatedReplicas == 0 {
if spec.Resources.KubernetesResource == nil {
spec.Resources.KubernetesResource = &KubernetesResource{}
}
spec.Resources.KubernetesResource.Replicas = ptr.Int32(1)
spec.DeprecatedReplicas = nil
} else if *spec.DeprecatedReplicas > 0 {
if spec.Resources.KubernetesResource == nil {
spec.Resources.KubernetesResource = &KubernetesResource{}
}
spec.Resources.KubernetesResource.Replicas = spec.DeprecatedReplicas
spec.DeprecatedReplicas = nil
}
}
}

Expand Down
60 changes: 55 additions & 5 deletions pkg/apis/triggers/v1alpha1/event_listener_defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,41 @@ func TestEventListenerSetDefaults(t *testing.T) {
},
},
}, {
name: "set replicas to 1 if provided replicas is 0 as part of eventlistener spec",
name: "set replicas to 1 if provided deprecated replicas is 0 as part of eventlistener spec",
in: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
Replicas: ptr.Int32(0),
DeprecatedReplicas: ptr.Int32(0),
},
},
wc: v1alpha1.WithUpgradeViaDefaulting,
want: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
Replicas: ptr.Int32(1),
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(1),
},
},
},
},
}, {
name: "set replicas to 1 if provided replicas is 0 as part of eventlistener kubernetesResources",
in: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(0),
},
},
},
},
wc: v1alpha1.WithUpgradeViaDefaulting,
want: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(1),
},
},
},
},
}, {
Expand Down Expand Up @@ -153,13 +178,38 @@ func TestEventListenerSetDefaults(t *testing.T) {
name: "different value for replicas other than 0",
in: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
Replicas: ptr.Int32(2),
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(2),
},
},
},
},
wc: v1alpha1.WithUpgradeViaDefaulting,
want: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(2),
},
},
},
},
}, {
name: "different value for deprecated replicas other than 0",
in: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
DeprecatedReplicas: ptr.Int32(2),
},
},
wc: v1alpha1.WithUpgradeViaDefaulting,
want: &v1alpha1.EventListener{
Spec: v1alpha1.EventListenerSpec{
Replicas: ptr.Int32(2),
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(2),
},
},
},
},
}, {
Expand Down
4 changes: 3 additions & 1 deletion pkg/apis/triggers/v1alpha1/event_listener_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ type EventListener struct {
type EventListenerSpec struct {
ServiceAccountName string `json:"serviceAccountName"`
Triggers []EventListenerTrigger `json:"triggers"`
// To be removed in a later release #1020
DeprecatedReplicas *int32 `json:"replicas,omitempty"`
// To be removed in a later release #904
DeprecatedServiceType corev1.ServiceType `json:"serviceType,omitempty"`
Replicas *int32 `json:"replicas,omitempty"`
// To be removed in a later release #904
DeprecatedPodTemplate PodTemplate `json:"podTemplate,omitempty"`
NamespaceSelector NamespaceSelector `json:"namespaceSelector,omitempty"`
Expand All @@ -77,6 +78,7 @@ type CustomResource struct {
}

type KubernetesResource struct {
Replicas *int32 `json:"replicas,omitempty"`
ServiceType corev1.ServiceType `json:"serviceType,omitempty"`
duckv1.WithPodSpec `json:"spec,omitempty"`
}
Expand Down
18 changes: 13 additions & 5 deletions pkg/apis/triggers/v1alpha1/event_listener_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,17 @@ func (e *EventListener) validate(ctx context.Context) (errs *apis.FieldError) {
}

func (s *EventListenerSpec) validate(ctx context.Context) (errs *apis.FieldError) {
if s.Replicas != nil {
if *s.Replicas < 0 {
errs = errs.Also(apis.ErrInvalidValue(*s.Replicas, "spec.replicas"))
}
}
for i, trigger := range s.Triggers {
errs = errs.Also(trigger.validate(ctx).ViaField(fmt.Sprintf("spec.triggers[%d]", i)))
}

// To be removed in a later release #1020
if s.DeprecatedReplicas != nil {
if *s.DeprecatedReplicas < 0 {
errs = errs.Also(apis.ErrInvalidValue(*s.DeprecatedReplicas, "spec.replicas"))
}
}

// Both Kubernetes and Custom resource can't be present at the same time
if s.Resources.KubernetesResource != nil && s.Resources.CustomResource != nil {
return apis.ErrMultipleOneOf("spec.resources.kubernetesResource", "spec.resources.customResource")
Expand Down Expand Up @@ -101,6 +104,11 @@ func validateCustomObject(customData *CustomResource) (errs *apis.FieldError) {
}

func validateKubernetesObject(orig *KubernetesResource) (errs *apis.FieldError) {
if orig.Replicas != nil {
if *orig.Replicas < 0 {
errs = errs.Also(apis.ErrInvalidValue(*orig.Replicas, "spec.replicas"))
}
}
if len(orig.Template.Spec.Containers) > 1 {
errs = errs.Also(apis.ErrMultipleOneOf("containers").ViaField("spec.template.spec"))
}
Expand Down
32 changes: 31 additions & 1 deletion pkg/apis/triggers/v1alpha1/event_listener_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,21 @@ func Test_EventListenerValidate(t *testing.T) {
}),
)),
)),
}, {
name: "Valid Replicas for EventListener",
el: &v1alpha1.EventListener{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "namespace",
},
Spec: v1alpha1.EventListenerSpec{
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(1),
},
},
},
},
}, {
name: "Valid EventListener with env for TLS connection",
el: bldr.EventListener("name", "namespace",
Expand Down Expand Up @@ -514,13 +529,28 @@ func TestEventListenerValidate_error(t *testing.T) {
bldr.EventListenerTriggerName("1234567890123456789012345678901234567890123456789012345678901234"),
))),
}, {
name: "user specify invalid replicas",
name: "user specify invalid deprecated replicas",
el: bldr.EventListener("name", "namespace",
bldr.EventListenerSpec(
bldr.EventListenerReplicas(-1),
bldr.EventListenerTrigger("tt", "v1alpha1",
bldr.EventListenerTriggerBinding("tb", "TriggerBinding", "v1alpha1"),
))),
}, {
name: "user specify invalid replicas",
el: &v1alpha1.EventListener{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "namespace",
},
Spec: v1alpha1.EventListenerSpec{
Resources: v1alpha1.Resources{
KubernetesResource: &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(-1),
},
},
},
},
}, {
name: "user specify multiple containers",
el: bldr.EventListener("name", "namespace",
Expand Down
9 changes: 7 additions & 2 deletions pkg/apis/triggers/v1alpha1/zz_generated.deepcopy.go

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

18 changes: 10 additions & 8 deletions pkg/reconciler/v1alpha1/eventlistener/eventlistener.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,13 @@ func (r *Reconciler) reconcileDeployment(ctx context.Context, logger *zap.Sugare
// Determine if reconciliation has to occur
updated := reconcileObjectMeta(&existingDeployment.ObjectMeta, deployment.ObjectMeta)
if *existingDeployment.Spec.Replicas != *deployment.Spec.Replicas {
if el.Spec.Replicas != nil {
existingDeployment.Spec.Replicas = deployment.Spec.Replicas
updated = true
if el.Spec.Resources.KubernetesResource != nil {
if el.Spec.Resources.KubernetesResource.Replicas != nil {
existingDeployment.Spec.Replicas = deployment.Spec.Replicas
updated = true
}
// if no replicas found as part of el.Spec then replicas from existingDeployment will be considered
}
// if no replicas found as part of el.Spec then replicas from existingDeployment will be considered
}
if existingDeployment.Spec.Selector != deployment.Spec.Selector {
existingDeployment.Spec.Selector = deployment.Spec.Selector
Expand Down Expand Up @@ -611,10 +613,6 @@ func (r *Reconciler) reconcileCustomObject(ctx context.Context, logger *zap.Suga
}

func getDeployment(el *v1alpha1.EventListener, c Config) *appsv1.Deployment {
var replicas = ptr.Int32(1)
if el.Spec.Replicas != nil {
replicas = el.Spec.Replicas
}
var (
tolerations []corev1.Toleration
nodeSelector, annotations, podlabels map[string]string
Expand Down Expand Up @@ -662,7 +660,11 @@ func getDeployment(el *v1alpha1.EventListener, c Config) *appsv1.Deployment {
})
}
}
var replicas = ptr.Int32(1)
if el.Spec.Resources.KubernetesResource != nil {
if el.Spec.Resources.KubernetesResource.Replicas != nil {
replicas = el.Spec.Resources.KubernetesResource.Replicas
}
if len(el.Spec.Resources.KubernetesResource.Template.Spec.Tolerations) != 0 {
tolerations = el.Spec.Resources.KubernetesResource.Template.Spec.Tolerations
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/reconciler/v1alpha1/eventlistener/eventlistener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,9 @@ func TestReconcile(t *testing.T) {
})

elWithReplicas := makeEL(withStatus, func(el *v1alpha1.EventListener) {
el.Spec.Replicas = ptr.Int32(2)
el.Spec.Resources.KubernetesResource = &v1alpha1.KubernetesResource{
Replicas: ptr.Int32(2),
}
})

elWithDeploymentReplicaFailure := makeEL(withStatus, func(el *v1alpha1.EventListener) {
Expand Down
2 changes: 1 addition & 1 deletion test/builder/eventlistener.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func EventListenerServiceAccount(saName string) EventListenerSpecOp {
// EventListenerReplicas sets the specified Replicas of the EventListener.
func EventListenerReplicas(replicas int32) EventListenerSpecOp {
return func(spec *v1alpha1.EventListenerSpec) {
spec.Replicas = &replicas
spec.DeprecatedReplicas = &replicas
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/eventlistener_scale_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ func TestEventListenerScale(t *testing.T) {
},
Spec: triggersv1.EventListenerSpec{
ServiceAccountName: saName,
Replicas: ptr.Int32(3),
Resources: triggersv1.Resources{
KubernetesResource: &triggersv1.KubernetesResource{
Replicas: ptr.Int32(3),
WithPodSpec: duckv1.WithPodSpec{
Template: duckv1.PodSpecable{
Spec: corev1.PodSpec{
Expand Down
2 changes: 1 addition & 1 deletion test/eventlistener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,9 @@ func TestEventListenerCreate(t *testing.T) {
}},
}},
}},
Replicas: ptr.Int32(3),
Resources: triggersv1.Resources{
KubernetesResource: &triggersv1.KubernetesResource{
Replicas: ptr.Int32(3),
WithPodSpec: duckv1.WithPodSpec{
Template: duckv1.PodSpecable{
Spec: corev1.PodSpec{
Expand Down

0 comments on commit e4745f2

Please sign in to comment.