Skip to content

Commit

Permalink
Add support for minimum conduit version required (#29)
Browse files Browse the repository at this point in the history
* Add support for earliest conduit version available
  • Loading branch information
lyuboxa authored Oct 3, 2024
1 parent 6a4058d commit 2321b13
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 117 deletions.
4 changes: 2 additions & 2 deletions api/v1alpha/conduit_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ const (
)

var (
ConduitPipelineFile = path.Join(ConduitPipelinePath, "pipeline.yaml")
ConduitWithProcessorsVersion = "0.9.0"
ConduitPipelineFile = path.Join(ConduitPipelinePath, "pipeline.yaml")
ConduitEarliestAvailable = "v0.11.1"
)

// ConduitSpec defines the desired state of Conduit
Expand Down
29 changes: 29 additions & 0 deletions api/v1alpha/conduit_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"path/filepath"
"strings"

"github.com/Masterminds/semver/v3"
"github.com/hashicorp/go-multierror"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -13,6 +14,18 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

var conduitVerConstraint *semver.Constraints

func init() {
var err error
// validate constraint
sanitized, _ := strings.CutPrefix(ConduitEarliestAvailable, "v")
conduitVerConstraint, err = semver.NewConstraint(fmt.Sprint(">= ", sanitized))
if err != nil {
panic(fmt.Errorf("failed to create version constraint: %w", err))
}
}

func (r *Conduit) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Expand Down Expand Up @@ -103,6 +116,13 @@ var _ webhook.Validator = &Conduit{}
func (r *Conduit) ValidateCreate() (admission.Warnings, error) {
var errs error

if ok := validateConduitVersion(r.Spec.Version); !ok {
errs = multierror.Append(errs, fmt.Errorf("unsupported conduit version %s, minimum required %s",
r.Spec.Version,
ConduitEarliestAvailable,
))
}

if _, err := validateConnectors(r.Spec.Connectors); err != nil {
errs = multierror.Append(errs, err)
}
Expand Down Expand Up @@ -165,3 +185,12 @@ func validateProcessors(pp []*ConduitProcessor) (admission.Warnings, error) {

return nil, errs
}

func validateConduitVersion(ver string) bool {
sanitized, _ := strings.CutPrefix(ver, "v")
v, err := semver.NewVersion(sanitized)
if err != nil {
return false
}
return conduitVerConstraint.Check(v)
}
34 changes: 34 additions & 0 deletions api/v1alpha/conduit_webhook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package v1alpha

import (
"testing"

"github.com/matryer/is"
)

func TestWebhookValidate_ConduitVersion(t *testing.T) {
tests := []struct {
ver string
supported bool
}{
{ver: "v0.11.1", supported: true},
{ver: "v0.12.0", supported: true},
{ver: "v1", supported: true},
{ver: "v0.10", supported: false},
{ver: "v0.9.1", supported: false},
}

testname := func(b bool, ver string) string {
if b {
return "supported " + ver
}
return "unsupported " + ver
}

for _, tc := range tests {
t.Run(testname(tc.supported, tc.ver), func(t *testing.T) {
is := is.New(t)
is.Equal(validateConduitVersion(tc.ver), tc.supported)
})
}
}
29 changes: 29 additions & 0 deletions config/samples/invalid-conduit-version.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: operator.conduit.io/v1alpha
kind: Conduit
metadata:
name: conduit-generator
spec:
running: true
name: generator.log
description: generator pipeline
version: v0.10
connectors:
- name: source-connector
type: source
plugin: builtin:generator
settings:
- name: format.type
value: structured
- name: format.options.id
value: "int"
- name: format.options.name
value: "string"
- name: format.options.company
value: "string"
- name: format.options.trial
value: "bool"
- name: recordCount
value: "3"
- name: destination-connector
type: destination
plugin: builtin:log
5 changes: 1 addition & 4 deletions controllers/conduit_containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,7 @@ func ConduitRuntimeContainer(image, version string, envVars []corev1.EnvVar) cor
"-db.type", "sqlite",
"-db.sqlite.path", v1alpha.ConduitDBPath,
"-pipelines.exit-on-error",
}

if withProcessors(version) {
args = append(args, "-processors.path", v1alpha.ConduitProcessorsPath)
"-processors.path", v1alpha.ConduitProcessorsPath,
}

return corev1.Container{
Expand Down
84 changes: 2 additions & 82 deletions controllers/conduit_containers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,87 +193,7 @@ func Test_ConduitInitContainers(t *testing.T) {
func Test_ConduitRuntimeContainer(t *testing.T) {
want := corev1.Container{
Name: "conduit-server",
Image: "my-image:v0.8.0",
ImagePullPolicy: corev1.PullAlways,
Args: []string{
"/app/conduit",
"-pipelines.path", "/conduit.pipelines/pipeline.yaml",
"-connectors.path", "/conduit.storage/connectors",
"-db.type", "sqlite",
"-db.sqlite.path", "/conduit.storage/db",
"-pipelines.exit-on-error",
},
Ports: []corev1.ContainerPort{
{
Name: "http",
ContainerPort: 8080,
Protocol: corev1.ProtocolTCP,
},
{
Name: "grpc",
ContainerPort: 8084,
Protocol: corev1.ProtocolTCP,
},
},
ReadinessProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/healthz",
Scheme: "HTTP",
Port: intstr.FromString("http"),
},
},
TimeoutSeconds: 1,
PeriodSeconds: 10,
SuccessThreshold: 1,
FailureThreshold: 3,
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "conduit-storage",
MountPath: "/conduit.storage",
},
{
Name: "conduit-pipelines",
MountPath: "/conduit.pipelines",
ReadOnly: true,
},
},
Env: []corev1.EnvVar{
{
Name: "var-1",
Value: "val-1",
},
{
Name: "var-2",
Value: "val-2",
},
},
}

got := ctrls.ConduitRuntimeContainer(
"my-image",
"v0.8.0",
[]corev1.EnvVar{
{
Name: "var-1",
Value: "val-1",
},
{
Name: "var-2",
Value: "val-2",
},
},
)
if diff := cmp.Diff(want, got); diff != "" {
t.Fatalf("container mismatch (-want +got): %v", diff)
}
}

func Test_ConduitRuntimeContainerProcessors(t *testing.T) {
want := corev1.Container{
Name: "conduit-server",
Image: "my-image:v0.9.1",
Image: "my-image:v0.11.1",
ImagePullPolicy: corev1.PullAlways,
Args: []string{
"/app/conduit",
Expand Down Expand Up @@ -335,7 +255,7 @@ func Test_ConduitRuntimeContainerProcessors(t *testing.T) {

got := ctrls.ConduitRuntimeContainer(
"my-image",
"v0.9.1",
"v0.11.1",
[]corev1.EnvVar{
{
Name: "var-1",
Expand Down
29 changes: 0 additions & 29 deletions controllers/conduit_ver.go

This file was deleted.

0 comments on commit 2321b13

Please sign in to comment.