Skip to content

Commit

Permalink
Merge branch 'main' into patch-5
Browse files Browse the repository at this point in the history
  • Loading branch information
StackScribe authored Jun 12, 2023
2 parents 1f8bb56 + 59cdfc8 commit 1348bab
Show file tree
Hide file tree
Showing 17 changed files with 383 additions and 32 deletions.
2 changes: 1 addition & 1 deletion docs/content/en/docs/getting-started/metrics/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ requires that you maintain point-to-point integrations
from Argo Rollouts, Flux, KEDA, and HPA.
Each has plugins but it is difficult to maintain them,
especially if you are using multiple tools,
and multible observability platforms,
and multiple observability platforms,
and multiple instances of some tools or observability platforms.
The Custom Keptn metrics feature unites all these metrics
integrates metrics from all these sources into a single set of metrics.
Expand Down
2 changes: 1 addition & 1 deletion docs/content/en/docs/intro-klt.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ on the production site.
Keptn Lifecycle Toolkit includes multiple features
that can be implemented independently or together.
Different features are at different levels of stability.
See the [Keptn Lifecycle Toolkit README file]
See the [Keptn Lifecycle Toolkit README file](https://github.com/keptn/lifecycle-toolkit/blob/main/README.md)
for a list of the features that have been implemented to date
and their level of stability.

Expand Down
27 changes: 22 additions & 5 deletions operator/apis/lifecycle/v1alpha3/keptntaskdefinition_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,39 @@ func (r *KeptnTaskDefinition) validateKeptnTaskDefinition() error {
allErrs)
}
func (r *KeptnTaskDefinition) validateFields() *field.Error {

if r.Spec.Function == nil && r.Spec.Container == nil {
count := countSpec(r)
if count == 0 {
return field.Invalid(
field.NewPath("spec"),
r.Spec,
errors.New("Forbidden! Either Function or Container field must be defined").Error(),
errors.New("Forbidden! Either Function, Container, Python, or Deno field must be defined").Error(),
)
}

if r.Spec.Function != nil && r.Spec.Container != nil {
if count > 1 {
return field.Invalid(
field.NewPath("spec"),
r.Spec,
errors.New("Forbidden! Both Function and Container fields cannot be defined simultaneously").Error(),
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)
}

return nil
}

func countSpec(r *KeptnTaskDefinition) int {
count := 0
if r.Spec.Function != nil {
count++
}
if r.Spec.Container != nil {
count++
}
if r.Spec.Python != nil {
count++
}
if r.Spec.Deno != nil {
count++
}
return count
}
210 changes: 205 additions & 5 deletions operator/apis/lifecycle/v1alpha3/keptntaskdefinition_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,31 @@ func TestKeptnTaskDefinition_ValidateFields(t *testing.T) {
Container: &ContainerSpec{},
}

specWithFunctionAndPython := KeptnTaskDefinitionSpec{
Function: &RuntimeSpec{},
Python: &RuntimeSpec{},
}

specWithFunctionAndDeno := KeptnTaskDefinitionSpec{
Function: &RuntimeSpec{},
Deno: &RuntimeSpec{},
}

specWithContainerAndPython := KeptnTaskDefinitionSpec{
Container: &ContainerSpec{},
Python: &RuntimeSpec{},
}

specWithContainerAndDeno := KeptnTaskDefinitionSpec{
Container: &ContainerSpec{},
Deno: &RuntimeSpec{},
}

specWithPythonAndDeno := KeptnTaskDefinitionSpec{
Python: &RuntimeSpec{},
Deno: &RuntimeSpec{},
}

emptySpec := KeptnTaskDefinitionSpec{}

tests := []struct {
Expand All @@ -29,15 +54,15 @@ func TestKeptnTaskDefinition_ValidateFields(t *testing.T) {
oldSpec runtime.Object
}{
{
name: "with-no-function-or-container",
name: "with-no-function-or-container-or-python-or-deno",
spec: emptySpec,
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"with-no-function-or-container",
"with-no-function-or-container-or-python-or-deno",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
emptySpec,
errors.New("Forbidden! Either Function or Container field must be defined").Error(),
errors.New("Forbidden! Either Function, Container, Python, or Deno field must be defined").Error(),
)},
),
verb: "create",
Expand All @@ -52,7 +77,7 @@ func TestKeptnTaskDefinition_ValidateFields(t *testing.T) {
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithFunctionAndContainer,
errors.New("Forbidden! Both Function and Container fields cannot be defined simultaneously").Error(),
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
},
Expand All @@ -70,6 +95,21 @@ func TestKeptnTaskDefinition_ValidateFields(t *testing.T) {
},
verb: "create",
},
{
name: "with-python-only",
spec: KeptnTaskDefinitionSpec{
Python: &RuntimeSpec{},
},
verb: "create",
},
{
name: "with-deno-only",
spec: KeptnTaskDefinitionSpec{
Deno: &RuntimeSpec{},
},
verb: "create",
},

{
name: "update-with-both-function-and-container",
spec: specWithFunctionAndContainer,
Expand All @@ -79,14 +119,174 @@ func TestKeptnTaskDefinition_ValidateFields(t *testing.T) {
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithFunctionAndContainer,
errors.New("Forbidden! Both Function and Container fields cannot be defined simultaneously").Error(),
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
oldSpec: &KeptnTaskDefinition{
Spec: KeptnTaskDefinitionSpec{},
},
verb: "update",
},

{
name: "with-both-function-and-python",
spec: specWithFunctionAndPython,
verb: "create",
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"with-both-function-and-python",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithFunctionAndPython,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
},
{
name: "update-with-both-function-and-python",
spec: specWithFunctionAndPython,
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"update-with-both-function-and-python",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithFunctionAndPython,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
oldSpec: &KeptnTaskDefinition{
Spec: KeptnTaskDefinitionSpec{},
},
verb: "update",
},

{
name: "with-both-function-and-deno",
spec: specWithFunctionAndDeno,
verb: "create",
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"with-both-function-and-deno",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithFunctionAndDeno,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
},
{
name: "update-with-both-function-and-deno",
spec: specWithFunctionAndDeno,
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"update-with-both-function-and-deno",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithFunctionAndDeno,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
oldSpec: &KeptnTaskDefinition{
Spec: KeptnTaskDefinitionSpec{},
},
verb: "update",
},

{
name: "with-both-container-and-python",
spec: specWithContainerAndPython,
verb: "create",
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"with-both-container-and-python",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithContainerAndPython,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
},
{
name: "update-with-both-container-and-python",
spec: specWithContainerAndPython,
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"update-with-both-container-and-python",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithContainerAndPython,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
oldSpec: &KeptnTaskDefinition{
Spec: KeptnTaskDefinitionSpec{},
},
verb: "update",
},

{
name: "with-both-container-and-deno",
spec: specWithContainerAndDeno,
verb: "create",
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"with-both-container-and-deno",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithContainerAndDeno,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
},
{
name: "update-with-both-container-and-deno",
spec: specWithContainerAndDeno,
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"update-with-both-container-and-deno",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithContainerAndDeno,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
oldSpec: &KeptnTaskDefinition{
Spec: KeptnTaskDefinitionSpec{},
},
verb: "update",
},
{
name: "with-both-python-and-deno",
spec: specWithPythonAndDeno,
verb: "create",
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"with-both-python-and-deno",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithPythonAndDeno,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
},
{
name: "update-with-both-python-and-deno",
spec: specWithPythonAndDeno,
want: apierrors.NewInvalid(
schema.GroupKind{Group: "lifecycle.keptn.sh", Kind: "KeptnTaskDefinition"},
"update-with-both-python-and-deno",
[]*field.Error{field.Invalid(
field.NewPath("spec"),
specWithPythonAndDeno,
errors.New("Forbidden! Only one of Function, Container, Python, or Deno field can be defined").Error(),
)},
),
oldSpec: &KeptnTaskDefinition{
Spec: KeptnTaskDefinitionSpec{},
},
verb: "update",
},

{
name: "delete",
verb: "delete",
Expand Down
19 changes: 17 additions & 2 deletions test/integration/validate-taskdefinition/00-teststep-install.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
apply:
- goodtaskdefinition.yaml
- td_good_container.yaml
- td_good_function.yaml
- td_good_python.yaml
- td_good_deno.yaml
commands:
- command: kubectl apply -f badtaskdefinition.yaml
- command: kubectl apply -f td_bad_empty.yaml
ignoreFailure: true # we must install ignoring the validating webhook error to proceed with the test
- command: kubectl apply -f td_bad_container_function.yaml
ignoreFailure: true # we must install ignoring the validating webhook error to proceed with the test
- command: kubectl apply -f td_bad_container_python.yaml
ignoreFailure: true # we must install ignoring the validating webhook error to proceed with the test
- command: kubectl apply -f td_bad_container_deno.yaml
ignoreFailure: true # we must install ignoring the validating webhook error to proceed with the test
- command: kubectl apply -f td_bad_function_python.yaml
ignoreFailure: true # we must install ignoring the validating webhook error to proceed with the test
- command: kubectl apply -f td_bad_function_deno.yaml
ignoreFailure: true # we must install ignoring the validating webhook error to proceed with the test
- command: kubectl apply -f td_bad_python_deno.yaml
ignoreFailure: true # we must install ignoring the validating webhook error to proceed with the test
13 changes: 11 additions & 2 deletions test/integration/validate-taskdefinition/01-teststep-assert.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
apiVersion: kuttl.dev/v1beta1
kind: TestStep
error: # this checks that kubectl get resource fails, AKA bad CRD not added
- badtaskdefinition.yaml
- td_bad_empty.yaml
- td_bad_container_function.yaml
- td_bad_container_python.yaml
- td_bad_container_deno.yaml
- td_bad_function_python.yaml
- td_bad_function_deno.yaml
- td_bad_python_deno.yaml
assert: # this checks that kubectl get resource succeeds
- goodtaskdefinition.yaml
- td_good_container.yaml
- td_good_function.yaml
- td_good_python.yaml
- td_good_deno.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
apiVersion: lifecycle.keptn.sh/v1alpha3
kind: KeptnTaskDefinition
metadata:
name: badtaskdefinition1
name: badtaskdefinition4
spec:
container:
name: keptntaskdefinition
Expand All @@ -18,10 +18,7 @@ spec:
volumeMounts:
- mountPath: /cache
name: logger
---
# This TaskDefinition will not be accepted by the validation webhook as it doesn't contain either containerSpec or functionSpec
apiVersion: lifecycle.keptn.sh/v1alpha3
kind: KeptnTaskDefinition
metadata:
name: badtaskdefinition2
spec:
deno:
inline:
code: |
console.log('hello');
Loading

0 comments on commit 1348bab

Please sign in to comment.