Skip to content

Commit

Permalink
Tolerations support in otelcol CRD (open-telemetry#302)
Browse files Browse the repository at this point in the history
Signed-off-by: Vineeth Pothulapati <[email protected]>
  • Loading branch information
VineethReddy02 authored Jun 7, 2021
1 parent 28ea4f2 commit 5423a71
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 12 deletions.
6 changes: 6 additions & 0 deletions api/v1alpha1/opentelemetrycollector_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ type OpenTelemetryCollectorSpec struct {
// +optional
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true
Resources v1.ResourceRequirements `json:"resources,omitempty"`

// Toleration to schedule OpenTelemetry Collector pods.
// This is only relevant to daemonsets, statefulsets and deployments
// +optional
// +operator-sdk:gen-csv:customresourcedefinitions.specDescriptors=true
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
}

// OpenTelemetryCollectorStatus defines the observed state of OpenTelemetryCollector.
Expand Down
31 changes: 22 additions & 9 deletions api/v1alpha1/opentelemetrycollector_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package v1alpha1

import (
"errors"
"fmt"

"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -59,23 +59,36 @@ var _ webhook.Validator = &OpenTelemetryCollector{}
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
func (r *OpenTelemetryCollector) ValidateCreate() error {
opentelemetrycollectorlog.Info("validate create", "name", r.Name)
if r.Spec.Mode != ModeStatefulSet && len(r.Spec.VolumeClaimTemplates) > 0 {
return errors.New("Can only specify VolumeClaimTemplates for statefulsets")
}
return nil
return r.validateCRDSpec()
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
func (r *OpenTelemetryCollector) ValidateUpdate(old runtime.Object) error {
opentelemetrycollectorlog.Info("validate update", "name", r.Name)
if r.Spec.Mode != ModeStatefulSet && len(r.Spec.VolumeClaimTemplates) > 0 {
return errors.New("Can only specify VolumeClaimTemplates for statefulsets")
}
return nil
return r.validateCRDSpec()
}

// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
func (r *OpenTelemetryCollector) ValidateDelete() error {
opentelemetrycollectorlog.Info("validate delete", "name", r.Name)
return nil
}

func (r *OpenTelemetryCollector) validateCRDSpec() error {
// validate volumeClaimTemplates
if r.Spec.Mode != ModeStatefulSet && len(r.Spec.VolumeClaimTemplates) > 0 {
return fmt.Errorf("the OpenTelemetry Collector mode is set to %s, which does not support the attribute 'volumeClaimTemplates'", r.Spec.Mode)
}

// validate replicas
if (r.Spec.Mode == ModeSidecar || r.Spec.Mode == ModeDaemonSet) && r.Spec.Replicas != nil {
return fmt.Errorf("the OpenTelemetry Collector mode is set to %s, which does not support the attribute 'replicas'", r.Spec.Mode)
}

// validate tolerations
if r.Spec.Mode == ModeSidecar && len(r.Spec.Tolerations) > 0 {
return fmt.Errorf("the OpenTelemetry Collector mode is set to %s, which does not support the attribute 'tolerations'", r.Spec.Mode)
}

return nil
}
7 changes: 7 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

40 changes: 40 additions & 0 deletions config/crd/bases/opentelemetry.io_opentelemetrycollectors.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,46 @@ spec:
description: ServiceAccount indicates the name of an existing service
account to use with this instance.
type: string
tolerations:
description: Toleration to schedule OpenTelemetry Collector pods.
items:
description: The pod this Toleration is attached to tolerates any
taint that matches the triple <key,value,effect> using the matching
operator <operator>.
properties:
effect:
description: Effect indicates the taint effect to match. Empty
means match all taint effects. When specified, allowed values
are NoSchedule, PreferNoSchedule and NoExecute.
type: string
key:
description: Key is the taint key that the toleration applies
to. Empty means match all taint keys. If the key is empty,
operator must be Exists; this combination means to match all
values and all keys.
type: string
operator:
description: Operator represents a key's relationship to the
value. Valid operators are Exists and Equal. Defaults to Equal.
Exists is equivalent to wildcard for value, so that a pod
can tolerate all taints of a particular category.
type: string
tolerationSeconds:
description: TolerationSeconds represents the period of time
the toleration (which must be of effect NoExecute, otherwise
this field is ignored) tolerates the taint. By default, it
is not set, which means tolerate the taint forever (do not
evict). Zero and negative values will be treated as 0 (evict
immediately) by the system.
format: int64
type: integer
value:
description: Value is the taint value the toleration matches
to. If the operator is Exists, the value should be empty,
otherwise just a regular string.
type: string
type: object
type: array
volumeClaimTemplates:
description: VolumeClaimTemplates will provide stable storage using
PersistentVolumes. Only available when the mode=statefulset.
Expand Down
1 change: 1 addition & 0 deletions pkg/collector/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func DaemonSet(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelem
ServiceAccountName: ServiceAccountName(otelcol),
Containers: []corev1.Container{Container(cfg, logger, otelcol)},
Volumes: Volumes(cfg, otelcol),
Tolerations: otelcol.Spec.Tolerations,
},
},
},
Expand Down
4 changes: 4 additions & 0 deletions pkg/collector/daemonset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ func TestDaemonSetNewDefault(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
},
Spec: v1alpha1.OpenTelemetryCollectorSpec{
Tolerations: testTolerationValues,
},
}
cfg := config.New()

Expand All @@ -43,6 +46,7 @@ func TestDaemonSetNewDefault(t *testing.T) {
assert.Equal(t, "true", d.Annotations["prometheus.io/scrape"])
assert.Equal(t, "8888", d.Annotations["prometheus.io/port"])
assert.Equal(t, "/metrics", d.Annotations["prometheus.io/path"])
assert.Equal(t, testTolerationValues, d.Spec.Template.Spec.Tolerations)

assert.Len(t, d.Spec.Template.Spec.Containers, 1)

Expand Down
1 change: 1 addition & 0 deletions pkg/collector/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func Deployment(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTele
ServiceAccountName: ServiceAccountName(otelcol),
Containers: []corev1.Container{Container(cfg, logger, otelcol)},
Volumes: Volumes(cfg, otelcol),
Tolerations: otelcol.Spec.Tolerations,
},
},
},
Expand Down
17 changes: 15 additions & 2 deletions pkg/collector/deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,33 @@ package collector_test
import (
"testing"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/stretchr/testify/assert"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/open-telemetry/opentelemetry-operator/api/v1alpha1"
"github.com/open-telemetry/opentelemetry-operator/internal/config"
. "github.com/open-telemetry/opentelemetry-operator/pkg/collector"
)

var testTolerationValues = []v1.Toleration{
{
Key: "hii",
Value: "greeting",
Effect: "NoSchedule",
},
}

func TestDeploymentNewDefault(t *testing.T) {
// prepare
otelcol := v1alpha1.OpenTelemetryCollector{
ObjectMeta: metav1.ObjectMeta{
Name: "my-instance",
},
Spec: v1alpha1.OpenTelemetryCollectorSpec{
Tolerations: testTolerationValues,
},
}
cfg := config.New()

Expand All @@ -44,6 +56,7 @@ func TestDeploymentNewDefault(t *testing.T) {
assert.Equal(t, "true", d.Annotations["prometheus.io/scrape"])
assert.Equal(t, "8888", d.Annotations["prometheus.io/port"])
assert.Equal(t, "/metrics", d.Annotations["prometheus.io/path"])
assert.Equal(t, testTolerationValues, d.Spec.Template.Spec.Tolerations)

assert.Len(t, d.Spec.Template.Spec.Containers, 1)

Expand Down
1 change: 1 addition & 0 deletions pkg/collector/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func StatefulSet(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTel
ServiceAccountName: ServiceAccountName(otelcol),
Containers: []corev1.Container{Container(cfg, logger, otelcol)},
Volumes: Volumes(cfg, otelcol),
Tolerations: otelcol.Spec.Tolerations,
},
},
Replicas: otelcol.Spec.Replicas,
Expand Down
4 changes: 3 additions & 1 deletion pkg/collector/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ func TestStatefulSetNewDefault(t *testing.T) {
Name: "my-instance",
},
Spec: v1alpha1.OpenTelemetryCollectorSpec{
Mode: "statefulset",
Mode: "statefulset",
Tolerations: testTolerationValues,
},
}
cfg := config.New()
Expand All @@ -49,6 +50,7 @@ func TestStatefulSetNewDefault(t *testing.T) {
assert.Equal(t, "true", ss.Annotations["prometheus.io/scrape"])
assert.Equal(t, "8888", ss.Annotations["prometheus.io/port"])
assert.Equal(t, "/metrics", ss.Annotations["prometheus.io/path"])
assert.Equal(t, testTolerationValues, ss.Spec.Template.Spec.Tolerations)

assert.Len(t, ss.Spec.Template.Spec.Containers, 1)

Expand Down

0 comments on commit 5423a71

Please sign in to comment.