Skip to content

Commit

Permalink
Merge pull request #3668 from cyclinder/spidercliamparameter/webhook
Browse files Browse the repository at this point in the history
spiderclaimparameter: add webhook to verify the create and update
  • Loading branch information
weizhoublue authored Jun 27, 2024
2 parents 5566f50 + 15af7ad commit 5ff6c82
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ spec:
type: boolean
staticNics:
items:
type: string
properties:
multusConfigName:
type: string
namespace:
type: string
required:
- multusConfigName
- namespace
type: object
type: array
type: object
type: object
Expand Down
28 changes: 28 additions & 0 deletions charts/spiderpool/templates/tls.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,34 @@ webhooks:
- spidermultusconfigs
sideEffects: None
{{- end }}
{{- if .Values.dra.enabled }}
- admissionReviewVersions:
- v1
clientConfig:
service:
name: {{ .Values.spiderpoolController.name | trunc 63 | trimSuffix "-" }}
namespace: {{ .Release.Namespace }}
path: /validate-spiderpool-spidernet-io-v2beta1-spiderclaimparameter
port: {{ .Values.spiderpoolController.webhookPort }}
{{- if (eq .Values.spiderpoolController.tls.method "provided") }}
caBundle: {{ .Values.spiderpoolController.tls.provided.tlsCa | required "missing spiderpoolController.tls.provided.tlsCa" }}
{{- else if (eq .Values.spiderpoolController.tls.method "auto") }}
caBundle: {{ .ca.Cert | b64enc }}
{{- end }}
failurePolicy: Fail
name: spiderclaimparameter.spiderpool.spidernet.io
rules:
- apiGroups:
- spiderpool.spidernet.io
apiVersions:
- v2beta1
operations:
- CREATE
- UPDATE
resources:
- spiderclaimparameters
sideEffects: None
{{- end }}

{{- if eq .Values.spiderpoolController.tls.method "certmanager" -}}
---
Expand Down
9 changes: 9 additions & 0 deletions cmd/spiderpool-controller/cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
crdclientset "github.com/spidernet-io/spiderpool/pkg/k8s/client/clientset/versioned"
"github.com/spidernet-io/spiderpool/pkg/kubevirtmanager"
"github.com/spidernet-io/spiderpool/pkg/logutils"
"github.com/spidernet-io/spiderpool/pkg/manager/spidercliamparameter"
"github.com/spidernet-io/spiderpool/pkg/multuscniconfig"
"github.com/spidernet-io/spiderpool/pkg/namespacemanager"
"github.com/spidernet-io/spiderpool/pkg/nodemanager"
Expand Down Expand Up @@ -345,6 +346,14 @@ func initControllerServiceManagers(ctx context.Context) {
}
}

if controllerContext.Cfg.DraEnabled {
logger.Debug("Begin to setup SpiderClaimParameter webhook")
if err = spidercliamparameter.New(controllerContext.CRDManager.GetClient(),
controllerContext.CRDManager.GetAPIReader(), controllerContext.CRDManager); err != nil {
logger.Fatal(err.Error())
}
}

if controllerContext.Cfg.EnableSpiderSubnet {
logger.Debug("Begin to initialize Subnet manager")
subnetManager, err := subnetmanager.NewSubnetManager(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ type ClaimParameterSpec struct {
RdmaAcc bool `json:"rdmaAcc,omitempty"`

// +kubebuilder:validation:Optional
StaticNics []string `json:"staticNics,omitempty"`
StaticNics []StaticNic `json:"staticNics,omitempty"`
}

type StaticNic struct {
// +kubebuilder:validation:Required
MultusConfigName string `json:"multusConfigName"`
// +kubebuilder:validation:Required
Namespace string `json:"namespace"`
}

// +kubebuilder:resource:categories={spiderpool},path="spiderclaimparameters",scope="Namespaced",shortName={scp},singular="spiderclaimparameter"
Expand Down

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

128 changes: 128 additions & 0 deletions pkg/manager/spidercliamparameter/spidercliamparameter_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright 2022 Authors of spidernet-io
// SPDX-License-Identifier: Apache-2.0

package spidercliamparameter

import (
"context"
"fmt"

"go.uber.org/zap"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

"github.com/spidernet-io/spiderpool/pkg/constant"
spiderpoolv2beta1 "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1"
"github.com/spidernet-io/spiderpool/pkg/logutils"
)

var logger *zap.Logger

type SpiderClaimParameterManager interface {
admission.CustomDefaulter
admission.CustomValidator
}

type spiderClaimParameterWebhook struct {
Client client.Client
APIReader client.Reader
}

func New(client client.Client, apiReader client.Reader, mgr ctrl.Manager) error {
if logger == nil {
logger = logutils.Logger.Named("SpiderClaimParameter-Webhook")
}

scpm := &spiderClaimParameterWebhook{
Client: client,
APIReader: apiReader,
}

return ctrl.NewWebhookManagedBy(mgr).
For(&spiderpoolv2beta1.SpiderClaimParameter{}).
WithDefaulter(scpm).
WithValidator(scpm).
Complete()
}

var _ webhook.CustomValidator = &spiderClaimParameterWebhook{}

// Default implements admission.CustomDefaulter.
func (*spiderClaimParameterWebhook) Default(ctx context.Context, obj runtime.Object) error {
return nil
}

func (scpm *spiderClaimParameterWebhook) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
scp := obj.(*spiderpoolv2beta1.SpiderClaimParameter)

log := logger.Named("Validating").With(
zap.String("SpiderClaimParameter", fmt.Sprintf("%s/%s", scp.Namespace, scp.Name)),
zap.String("Operation", "CREATE"),
)
log.Sugar().Debugf("Request SpiderClaimParameter: %+v", *scp)

err := scpm.validate(scp)
if err != nil {
log.Error(err.Error())
return nil, apierrors.NewInvalid(
spiderpoolv2beta1.SchemeGroupVersion.WithKind(constant.KindSpiderClaimParameter).GroupKind(),
scp.Name,
field.ErrorList{err},
)
}

return nil, nil
}

func (scpm *spiderClaimParameterWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
new := newObj.(*spiderpoolv2beta1.SpiderClaimParameter)

log := logger.Named("Validating").With(
zap.String("SpiderClaimParameter", fmt.Sprintf("%s/%s", new.Namespace, new.Name)),
zap.String("Operation", "UPDATE"),
)
log.Sugar().Debugf("Request new SpiderClaimParameter: %+v", *new)

err := scpm.validate(new)
if err != nil {
log.Error(err.Error())
return nil, apierrors.NewInvalid(
spiderpoolv2beta1.SchemeGroupVersion.WithKind(constant.KindSpiderClaimParameter).GroupKind(),
new.Name,
field.ErrorList{err},
)
}

return nil, nil
}

// ValidateDelete will implement something just like kubernetes Foreground cascade deletion to delete the MultusConfig corresponding net-attach-def firstly
// Since the MultusConf doesn't have Finalizer, you could delete it as soon as possible and we can't filter it to delete the net-attach-def at first.
func (scpm *spiderClaimParameterWebhook) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
return nil, nil
}

// check the existence of SpiderMultusConfig in the StaticNics
func (scpm *spiderClaimParameterWebhook) validate(scp *spiderpoolv2beta1.SpiderClaimParameter) *field.Error {
if scp == nil {
return field.Required(nil, "SpiderClaimParameter is nil")
}

for idx, nic := range scp.Spec.StaticNics {
if nic.MultusConfigName == "" {
return field.Invalid(field.NewPath("Spec").Child("StaticNics", fmt.Sprintf("[%v].MultusConfigName", idx)), nic, "value should not be empty")
}

var smc spiderpoolv2beta1.SpiderMultusConfig
if err := scpm.APIReader.Get(context.TODO(), client.ObjectKey{Name: nic.MultusConfigName, Namespace: nic.Namespace}, &smc); err != nil {
return field.Invalid(field.NewPath("Spec").Child("StaticNics", fmt.Sprintf("[%v]", idx)), nic, fmt.Sprintf("error get spidermultusconfig %v: %v", nic, err))
}
}

return nil
}
7 changes: 7 additions & 0 deletions test/doc/spidercclaimparameter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# E2E Cases for spiderclaimparameter

| Case ID | Title | Priority | Smoke | Status | Other |
| ------- | ------| -------- | ----- | ------ | ----- |
| Y00001 | test create spiderclaimparameter | p3 | | done |
| Y00002 | test create spiderclaimparameter for empty staticNics | p3 | | done |

16 changes: 6 additions & 10 deletions test/e2e/dra/dra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,19 @@ var _ = Describe("dra", Label("dra"), func() {

DeferCleanup(func() {
GinkgoWriter.Printf("delete spiderMultusConfig %v/%v. \n", namespace, multusNadName)
//Expect(frame.DeleteSpiderMultusInstance(namespace, multusNadName)).NotTo(HaveOccurred())
Expect(frame.DeleteSpiderMultusInstance(namespace, multusNadName)).NotTo(HaveOccurred())

GinkgoWriter.Printf("delete namespace %v. \n", namespace)
//Expect(frame.DeleteNamespace(namespace)).NotTo(HaveOccurred())
Expect(frame.DeleteNamespace(namespace)).NotTo(HaveOccurred())

if frame.Info.IpV4Enabled {
GinkgoWriter.Printf("delete v4 ippool %v. \n", v4PoolName)
//Expect(common.DeleteIPPoolByName(frame, v4PoolName)).NotTo(HaveOccurred())
}
if frame.Info.IpV6Enabled {
GinkgoWriter.Printf("delete v6 ippool %v. \n", v6PoolName)
//Expect(common.DeleteIPPoolByName(frame, v6PoolName)).NotTo(HaveOccurred())
Expect(common.DeleteIPPoolByName(frame, v6PoolName)).NotTo(HaveOccurred())
}

//Expect(
// common.DeleteSpiderClaimParameter(frame, spiderClaimName, namespace),
//).NotTo(HaveOccurred())
Expect(
common.DeleteSpiderClaimParameter(frame, spiderClaimName, namespace),
).NotTo(HaveOccurred())
})
})

Expand Down
35 changes: 35 additions & 0 deletions test/e2e/spiderclaimparameter/spiderclaimparameter_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 Authors of spidernet-io
// SPDX-License-Identifier: Apache-2.0
package spiderclaimparameter_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
e2e "github.com/spidernet-io/e2eframework/framework"
spiderpool "github.com/spidernet-io/spiderpool/pkg/k8s/apis/spiderpool.spidernet.io/v2beta1"
"github.com/spidernet-io/spiderpool/test/e2e/common"
"k8s.io/api/resource/v1alpha2"

"k8s.io/apimachinery/pkg/runtime"
)

func TestSpiderclaimparameter(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Spiderclaimparameter Suite")
}

var frame *e2e.Framework

var _ = BeforeSuite(func() {
if !common.IsDRAEnabled() {
GinkgoWriter.Println("DRA feature is disabled. Skip")
Skip("DRA feature is disabled. Skip")
}

defer GinkgoRecover()
var e error
frame, e = e2e.NewFramework(GinkgoT(), []func(*runtime.Scheme) error{spiderpool.AddToScheme, v1alpha2.AddToScheme})
Expect(e).NotTo(HaveOccurred())
})
Loading

0 comments on commit 5ff6c82

Please sign in to comment.