Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for timeframe in KeptnMetric #1471

Merged
merged 27 commits into from
Jun 22, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d8f9370
feat: add range.interval and validating webhook
rakshitgondwal May 25, 2023
bcc54a2
add manifests.yaml for webhook
rakshitgondwal May 26, 2023
5d57409
update admissionReviewVersion
rakshitgondwal May 28, 2023
16cd62c
fix after review
rakshitgondwal May 30, 2023
2c71934
minor change
rakshitgondwal May 30, 2023
f65d29f
fix yamllint errors
rakshitgondwal May 30, 2023
35a3138
Merge branch 'keptn:main' into feat/range-interval
rakshitgondwal May 31, 2023
b09e2f2
fix after review
rakshitgondwal May 31, 2023
074eaef
update api version for load test
rakshitgondwal May 31, 2023
bc176af
fix after review
rakshitgondwal Jun 1, 2023
5b56c00
fix validate helm chart err
rakshitgondwal Jun 1, 2023
9272396
add more tests
rakshitgondwal Jun 1, 2023
93037d3
Merge branch 'main' into feat/range-interval
rakshitgondwal Jun 1, 2023
7e0a67c
update go.mod
rakshitgondwal Jun 1, 2023
31e8e58
remove with-no-range test
rakshitgondwal Jun 5, 2023
4c944b7
add integration tests
rakshitgondwal Jun 5, 2023
4e34b4c
fix golangci-lint errors
rakshitgondwal Jun 5, 2023
c23a41d
fix unit test
rakshitgondwal Jun 6, 2023
a4c9e1c
update test to use Validate[Create/Update/Delete]
rakshitgondwal Jun 6, 2023
22f43b9
fix integration test err
rakshitgondwal Jun 6, 2023
b255738
fix typo
rakshitgondwal Jun 6, 2023
e0d26b0
Merge branch 'main' into feat/range-interval
rakshitgondwal Jun 7, 2023
7268581
fix merge conflicts
rakshitgondwal Jun 7, 2023
49a0e20
Merge branch 'keptn:main' into feat/range-interval
rakshitgondwal Jun 12, 2023
cf44799
Merge branch 'keptn:main' into feat/range-interval
rakshitgondwal Jun 20, 2023
661e0db
Merge branch 'main' into feat/range-interval
rakshitgondwal Jun 21, 2023
2beea9c
fix helm-generation check err
rakshitgondwal Jun 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions metrics-operator/PROJECT
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Code generated by tool. DO NOT EDIT.
# This file is used to track the info used to scaffold your project
# and allow the plugins properly work.
# More info: https://book.kubebuilder.io/reference/project-config.html
domain: keptn.sh
layout:
- go.kubebuilder.io/v3
Expand Down Expand Up @@ -41,6 +45,9 @@ resources:
kind: KeptnMetric
path: github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3
version: v1alpha3
webhooks:
validation: true
webhookVersion: v1
- api:
crdVersion: v1
namespaced: true
Expand Down
8 changes: 8 additions & 0 deletions metrics-operator/api/v1alpha3/keptnmetric_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type KeptnMetricSpec struct {
Query string `json:"query"`
// FetchIntervalSeconds represents the update frequency in seconds that is used to update the metric
FetchIntervalSeconds uint `json:"fetchIntervalSeconds"`
// Range represents the time range for which data is to be queried
Range RangeSpec `json:"range,omitempty"`
}

// KeptnMetricStatus defines the observed state of KeptnMetric
Expand All @@ -51,6 +53,12 @@ type ProviderRef struct {
Name string `json:"name"`
}

// RangeSpec defines the time range for which data is to be queried
type RangeSpec struct {
// +kubebuilder:default:="5m"
Interval string `json:"interval,omitempty"`
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
}

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Provider",type=string,JSONPath=`.spec.provider.name`
Expand Down
66 changes: 66 additions & 0 deletions metrics-operator/api/v1alpha3/keptnmetric_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,77 @@ limitations under the License.
package v1alpha3

import (
"time"

"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
)

// log is for logging in this package.
var keptnmetriclog = logf.Log.WithName("keptnmetric-resource")

func (r *KeptnMetric) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(r).
Complete()
}

//+kubebuilder:webhook:path=/validate-metrics-keptn-sh-v1alpha3-keptnmetric,mutating=false,failurePolicy=fail,sideEffects=None,groups=metrics.keptn.sh,resources=keptnmetrics,verbs=create;update,versions=v1alpha3,name=vkeptnmetric.kb.io,admissionReviewVersions=v1

var _ webhook.Validator = &KeptnMetric{}

// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (r *KeptnMetric) ValidateCreate() error {
keptnmetriclog.Info("validate create", "name", r.Name)

// TODO(user): fill in your validation logic upon object creation.
return r.validateKeptnMetric()
}

// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (r *KeptnMetric) ValidateUpdate(old runtime.Object) error {
keptnmetriclog.Info("validate update", "name", r.Name)

// TODO(user): fill in your validation logic upon object update.
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
return r.validateKeptnMetric()
}

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

return nil
}

func (s *KeptnMetric) validateKeptnMetric() error {
var allErrs field.ErrorList //defined as a list to allow returning multiple validation errors
var err *field.Error
if err = s.validateRangeInterval(); err != nil {
allErrs = append(allErrs, err)
}
if len(allErrs) == 0 {
return nil
}

return apierrors.NewInvalid(
schema.GroupKind{Group: "metrics.keptn.sh", Kind: "KeptnMetric"},
s.Name, allErrs)
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
}

func (s *KeptnMetric) validateRangeInterval() *field.Error {
_, err := time.ParseDuration(s.Spec.Range.Interval)
if err != nil {
return field.Invalid(
field.NewPath("spec").Child("range").Child("interval"),
s.Spec.Range.Interval,
errors.New("Forbidden! The time interval cannot be parsed. Please check for suitable conventions").Error(),
)
}
return nil
}
49 changes: 49 additions & 0 deletions metrics-operator/api/v1alpha3/keptnmetric_webhook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package v1alpha3

import (
"reflect"
"testing"

"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
)

func TestKeptnMetric_validateRangeInterval(t *testing.T) {

tests := []struct {
name string
Spec KeptnMetricSpec
want *field.Error
}{
{
name: "bad-provider",
Spec: KeptnMetricSpec{
Range: RangeSpec{Interval: "5mins"},
},
want: field.Invalid(
field.NewPath("spec").Child("range").Child("interval"),
"5mins",
errors.New("Forbidden! The time interval cannot be parsed. Please check for suitable conventions").Error(),
),
},

rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
{
name: "good-provider",
Spec: KeptnMetricSpec{
Range: RangeSpec{Interval: "5m"},
},
},
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &KeptnMetric{
ObjectMeta: metav1.ObjectMeta{Name: tt.name},
Spec: KeptnMetricSpec{Range: RangeSpec{Interval: tt.Spec.Range.Interval}},
}
if got := s.validateRangeInterval(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("validateRangeInterval() = %v, want %v", got, tt.want)
}
})
}
}

Check failure on line 49 in metrics-operator/api/v1alpha3/keptnmetric_webhook_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint (metrics-operator, metrics-operator/)

File is not `gci`-ed with --skip-generated -s standard,default (gci)
2 changes: 1 addition & 1 deletion metrics-operator/api/v1alpha3/zz_generated.deepcopy.go

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

39 changes: 39 additions & 0 deletions metrics-operator/config/certmanager/certificate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# The following manifests contain a self-signed issuer CR and a certificate CR.
# More document can be found at https://docs.cert-manager.io
# WARNING: Targets CertManager v1.0. Check https://cert-manager.io/docs/installation/upgrading/ for breaking changes.
apiVersion: cert-manager.io/v1
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
kind: Issuer
metadata:
labels:
app.kubernetes.io/name: issuer
app.kubernetes.io/instance: selfsigned-issuer
app.kubernetes.io/component: certificate
app.kubernetes.io/created-by: metrics-operator
app.kubernetes.io/part-of: metrics-operator
app.kubernetes.io/managed-by: kustomize
name: selfsigned-issuer
namespace: system
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
labels:
app.kubernetes.io/name: certificate
app.kubernetes.io/instance: serving-cert
app.kubernetes.io/component: certificate
app.kubernetes.io/created-by: metrics-operator
app.kubernetes.io/part-of: metrics-operator
app.kubernetes.io/managed-by: kustomize
name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
namespace: system
spec:
# $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize
dnsNames:
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc
- $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned-issuer
secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize
5 changes: 5 additions & 0 deletions metrics-operator/config/certmanager/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resources:
- certificate.yaml

configurations:
- kustomizeconfig.yaml
16 changes: 16 additions & 0 deletions metrics-operator/config/certmanager/kustomizeconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This configuration is for teaching kustomize how to update name ref and var substitution
nameReference:
- kind: Issuer
group: cert-manager.io
fieldSpecs:
- kind: Certificate
group: cert-manager.io
path: spec/issuerRef/name

varReference:
- kind: Certificate
group: cert-manager.io
path: spec/commonName
- kind: Certificate
group: cert-manager.io
path: spec/dnsNames
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,14 @@ spec:
query:
description: Query represents the query to be run
type: string
range:
description: Range represents the time range for which data is to
be queried
properties:
interval:
default: 5m
type: string
type: object
required:
- fetchIntervalSeconds
- provider
Expand Down
23 changes: 23 additions & 0 deletions metrics-operator/config/default/manager_webhook_patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
ports:
- containerPort: 9443
name: webhook-server
protocol: TCP
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
29 changes: 29 additions & 0 deletions metrics-operator/config/default/webhookcainjection_patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This patch add annotation to admission webhook config and
# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize.
apiVersion: admissionregistration.k8s.io/v1
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
kind: MutatingWebhookConfiguration
metadata:
labels:
app.kubernetes.io/name: mutatingwebhookconfiguration
app.kubernetes.io/instance: mutating-webhook-configuration
app.kubernetes.io/component: webhook
app.kubernetes.io/created-by: metrics-operator
app.kubernetes.io/part-of: metrics-operator
app.kubernetes.io/managed-by: kustomize
name: mutating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
app.kubernetes.io/name: validatingwebhookconfiguration
app.kubernetes.io/instance: validating-webhook-configuration
app.kubernetes.io/component: webhook
app.kubernetes.io/created-by: metrics-operator
app.kubernetes.io/part-of: metrics-operator
app.kubernetes.io/managed-by: kustomize
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
29 changes: 29 additions & 0 deletions metrics-operator/config/webhook/manifests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
creationTimestamp: null
name: metrics-validating-webhook-configuration
labels:
keptn.sh/inject-cert: "true"
webhooks:
- admissionReviewVersions:
- v3
clientConfig:
service:
name: webhook-service
rakshitgondwal marked this conversation as resolved.
Show resolved Hide resolved
namespace: system
path: /validate-metrics-keptn-sh-v1alpha3-keptnmetric
failurePolicy: Fail
name: vkeptnmetric.kb.io
rules:
- apiGroups:
- metrics.keptn.sh
apiVersions:
- v1alpha3
operations:
- CREATE
- UPDATE
resources:
- keptnmetrics
sideEffects: None
4 changes: 2 additions & 2 deletions metrics-operator/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ require (
github.com/gorilla/mux v1.8.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230523133947-65b41399b2e0
github.com/onsi/ginkgo/v2 v2.8.1
github.com/onsi/gomega v1.27.0
github.com/open-feature/go-sdk v1.3.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.15.1
Expand Down Expand Up @@ -67,8 +69,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/ginkgo/v2 v2.8.1 // indirect
github.com/onsi/gomega v1.27.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
Expand Down
Loading