feat: kubesphere 4.0 (#6115)

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

* feat: kubesphere 4.0

Signed-off-by: ci-bot <ci-bot@kubesphere.io>

---------

Signed-off-by: ci-bot <ci-bot@kubesphere.io>
Co-authored-by: ks-ci-bot <ks-ci-bot@example.com>
Co-authored-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
KubeSphere CI Bot
2024-09-06 11:05:52 +08:00
committed by GitHub
parent b5015ec7b9
commit 447a51f08b
8557 changed files with 546695 additions and 1146174 deletions

View File

@@ -19,11 +19,12 @@ limitations under the License.
//
// The markers take the form:
//
// +kubebuilder:webhook:webhookVersions=<[]string>,failurePolicy=<string>,matchPolicy=<string>,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=<string>,path=<string>,mutating=<bool>,sideEffects=<string>,admissionReviewVersions=<[]string>,reinvocationPolicy=<string>
// +kubebuilder:webhook:webhookVersions=<[]string>,failurePolicy=<string>,matchPolicy=<string>,groups=<[]string>,resources=<[]string>,verbs=<[]string>,versions=<[]string>,name=<string>,path=<string>,mutating=<bool>,sideEffects=<string>,timeoutSeconds=<int>,admissionReviewVersions=<[]string>,reinvocationPolicy=<string>
package webhook
import (
"fmt"
"sort"
"strings"
admissionregv1 "k8s.io/api/admissionregistration/v1"
@@ -80,6 +81,11 @@ type Config struct {
// If the value is "NoneOnDryRun", then the webhook is responsible for inspecting the "dryRun" property of the
// AdmissionReview sent in the request, and avoiding side effects if that value is "true."
SideEffects string `marker:",optional"`
// TimeoutSeconds allows configuring how long the API server should wait for a webhook to respond before treating the call as a failure.
// If the timeout expires before the webhook responds, the webhook call will be ignored or the API call will be rejected based on the failure policy.
// The timeout value must be between 1 and 30 seconds.
// The timeout for an admission webhook defaults to 10 seconds.
TimeoutSeconds int `marker:",optional"`
// Groups specifies the API groups that this webhook receives requests for.
Groups []string
@@ -102,7 +108,7 @@ type Config struct {
// are substituted for hyphens. For example, a validating webhook path for type
// batch.tutorial.kubebuilder.io/v1,Kind=CronJob would be
// /validate-batch-tutorial-kubebuilder-io-v1-cronjob
Path string
Path string `marker:"path,optional"`
// WebhookVersions specifies the target API versions of the {Mutating,Validating}WebhookConfiguration objects
// itself to generate. The only supported value is v1. Defaults to v1.
@@ -119,6 +125,14 @@ type Config struct {
// an object, and mutating webhooks can specify a reinvocationPolicy to control
// whether they are reinvoked as well.
ReinvocationPolicy string `marker:"reinvocationPolicy,optional"`
// URL allows mutating webhooks configuration to specify an external URL when generating
// the manifests, instead of using the internal service communication. Should be in format of
// https://address:port/path
// When this option is specified, the serviceConfig.Service is removed from webhook the manifest.
// The URL configuration should be between quotes.
// `url` cannot be specified when `path` is specified.
URL string `marker:"url,optional"`
}
// verbToAPIVariant converts a marker's verb to the proper value for the API.
@@ -151,13 +165,19 @@ func (c Config) ToMutatingWebhook() (admissionregv1.MutatingWebhook, error) {
return admissionregv1.MutatingWebhook{}, err
}
clientConfig, err := c.clientConfig()
if err != nil {
return admissionregv1.MutatingWebhook{}, err
}
return admissionregv1.MutatingWebhook{
Name: c.Name,
Rules: c.rules(),
FailurePolicy: c.failurePolicy(),
MatchPolicy: matchPolicy,
ClientConfig: c.clientConfig(),
ClientConfig: clientConfig,
SideEffects: c.sideEffects(),
TimeoutSeconds: c.timeoutSeconds(),
AdmissionReviewVersions: c.AdmissionReviewVersions,
ReinvocationPolicy: c.reinvocationPolicy(),
}, nil
@@ -174,13 +194,19 @@ func (c Config) ToValidatingWebhook() (admissionregv1.ValidatingWebhook, error)
return admissionregv1.ValidatingWebhook{}, err
}
clientConfig, err := c.clientConfig()
if err != nil {
return admissionregv1.ValidatingWebhook{}, err
}
return admissionregv1.ValidatingWebhook{
Name: c.Name,
Rules: c.rules(),
FailurePolicy: c.failurePolicy(),
MatchPolicy: matchPolicy,
ClientConfig: c.clientConfig(),
ClientConfig: clientConfig,
SideEffects: c.sideEffects(),
TimeoutSeconds: c.timeoutSeconds(),
AdmissionReviewVersions: c.AdmissionReviewVersions,
}, nil
}
@@ -243,15 +269,27 @@ func (c Config) matchPolicy() (*admissionregv1.MatchPolicyType, error) {
}
// clientConfig returns the client config for a webhook.
func (c Config) clientConfig() admissionregv1.WebhookClientConfig {
path := c.Path
return admissionregv1.WebhookClientConfig{
Service: &admissionregv1.ServiceReference{
Name: "webhook-service",
Namespace: "system",
Path: &path,
},
func (c Config) clientConfig() (admissionregv1.WebhookClientConfig, error) {
if (c.Path != "" && c.URL != "") || (c.Path == "" && c.URL == "") {
return admissionregv1.WebhookClientConfig{}, fmt.Errorf("`url` or `path` markers are required and mutually exclusive")
}
path := c.Path
if path != "" {
return admissionregv1.WebhookClientConfig{
Service: &admissionregv1.ServiceReference{
Name: "webhook-service",
Namespace: "system",
Path: &path,
},
}, nil
}
url := c.URL
return admissionregv1.WebhookClientConfig{
URL: &url,
}, nil
}
// sideEffects returns the sideEffects config for a webhook.
@@ -272,6 +310,15 @@ func (c Config) sideEffects() *admissionregv1.SideEffectClass {
return &sideEffects
}
// timeoutSeconds returns the timeoutSeconds config for a webhook.
func (c Config) timeoutSeconds() *int32 {
if c.TimeoutSeconds != 0 {
timeoutSeconds := int32(c.TimeoutSeconds)
return &timeoutSeconds
}
return nil
}
// reinvocationPolicy returns the reinvocationPolicy config for a mutating webhook.
func (c Config) reinvocationPolicy() *admissionregv1.ReinvocationPolicyType {
var reinvocationPolicy admissionregv1.ReinvocationPolicyType
@@ -304,7 +351,13 @@ func (c Config) webhookVersions() ([]string, error) {
// +controllertools:marker:generateHelp
// Generator generates (partial) {Mutating,Validating}WebhookConfiguration objects.
type Generator struct{}
type Generator struct {
// HeaderFile specifies the header text (e.g. license) to prepend to generated files.
HeaderFile string `marker:",optional"`
// Year specifies the year to substitute for " YEAR" in the header file.
Year string `marker:",optional"`
}
func (Generator) RegisterMarkers(into *markers.Registry) error {
if err := into.Register(ConfigDefinition); err != nil {
@@ -314,7 +367,7 @@ func (Generator) RegisterMarkers(into *markers.Registry) error {
return nil
}
func (Generator) Generate(ctx *genall.GenerationContext) error {
func (g Generator) Generate(ctx *genall.GenerationContext) error {
supportedWebhookVersions := supportedWebhookVersions()
mutatingCfgs := make(map[string][]admissionregv1.MutatingWebhook, len(supportedWebhookVersions))
validatingCfgs := make(map[string][]admissionregv1.ValidatingWebhook, len(supportedWebhookVersions))
@@ -324,7 +377,12 @@ func (Generator) Generate(ctx *genall.GenerationContext) error {
root.AddError(err)
}
for _, cfg := range markerSet[ConfigDefinition.Name] {
cfgs := markerSet[ConfigDefinition.Name]
sort.SliceStable(cfgs, func(i, j int) bool {
return cfgs[i].(Config).Name < cfgs[j].(Config).Name
})
for _, cfg := range cfgs {
cfg := cfg.(Config)
webhookVersions, err := cfg.webhookVersions()
if err != nil {
@@ -369,6 +427,11 @@ func (Generator) Generate(ctx *genall.GenerationContext) error {
if err := checkSideEffectsForV1(objRaw.Webhooks[i].SideEffects); err != nil {
return err
}
// TimeoutSeconds must be nil or between 1 and 30 seconds, otherwise,
// return an error
if err := checkTimeoutSeconds(objRaw.Webhooks[i].TimeoutSeconds); err != nil {
return err
}
// AdmissionReviewVersions is required in admissionregistration/v1, if this is not set,
// return an error
if len(objRaw.Webhooks[i].AdmissionReviewVersions) == 0 {
@@ -395,6 +458,11 @@ func (Generator) Generate(ctx *genall.GenerationContext) error {
if err := checkSideEffectsForV1(objRaw.Webhooks[i].SideEffects); err != nil {
return err
}
// TimeoutSeconds must be nil or between 1 and 30 seconds, otherwise,
// return an error
if err := checkTimeoutSeconds(objRaw.Webhooks[i].TimeoutSeconds); err != nil {
return err
}
// AdmissionReviewVersions is required in admissionregistration/v1, if this is not set,
// return an error
if len(objRaw.Webhooks[i].AdmissionReviewVersions) == 0 {
@@ -405,6 +473,16 @@ func (Generator) Generate(ctx *genall.GenerationContext) error {
}
}
var headerText string
if g.HeaderFile != "" {
headerBytes, err := ctx.ReadFile(g.HeaderFile)
if err != nil {
return err
}
headerText = string(headerBytes)
}
headerText = strings.ReplaceAll(headerText, " YEAR", " "+g.Year)
for k, v := range versionedWebhooks {
var fileName string
if k == defaultWebhookVersion {
@@ -412,7 +490,7 @@ func (Generator) Generate(ctx *genall.GenerationContext) error {
} else {
fileName = fmt.Sprintf("manifests.%s.yaml", k)
}
if err := ctx.WriteYAML(fileName, v); err != nil {
if err := ctx.WriteYAML(fileName, headerText, v, genall.WithTransform(genall.TransformRemoveCreationTimestamp)); err != nil {
return err
}
}
@@ -429,3 +507,10 @@ func checkSideEffectsForV1(sideEffects *admissionregv1.SideEffectClass) error {
}
return nil
}
func checkTimeoutSeconds(timeoutSeconds *int32) error {
if timeoutSeconds != nil && (*timeoutSeconds < 1 || *timeoutSeconds > 30) {
return fmt.Errorf("TimeoutSeconds must be between 1 and 30 seconds")
}
return nil
}

View File

@@ -1,5 +1,4 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright2019 The Kubernetes Authors.
@@ -49,6 +48,10 @@ func (Config) Help() *markers.DefinitionHelp {
Summary: "specify whether calling the webhook will have side effects. This has an impact on dry runs and `kubectl diff`: if the sideEffect is \"Unknown\" (the default) or \"Some\", then the API server will not call the webhook on a dry-run request and fails instead. If the value is \"None\", then the webhook has no side effects and the API server will call it on dry-run. If the value is \"NoneOnDryRun\", then the webhook is responsible for inspecting the \"dryRun\" property of the AdmissionReview sent in the request, and avoiding side effects if that value is \"true.\"",
Details: "",
},
"TimeoutSeconds": {
Summary: "allows configuring how long the API server should wait for a webhook to respond before treating the call as a failure. If the timeout expires before the webhook responds, the webhook call will be ignored or the API call will be rejected based on the failure policy. The timeout value must be between 1 and 30 seconds. The timeout for an admission webhook defaults to 10 seconds.",
Details: "",
},
"Groups": {
Summary: "specifies the API groups that this webhook receives requests for.",
Details: "",
@@ -96,6 +99,15 @@ func (Generator) Help() *markers.DefinitionHelp {
Summary: "generates (partial) {Mutating,Validating}WebhookConfiguration objects.",
Details: "",
},
FieldHelp: map[string]markers.DetailedHelp{},
FieldHelp: map[string]markers.DetailedHelp{
"HeaderFile": {
Summary: "specifies the header text (e.g. license) to prepend to generated files.",
Details: "",
},
"Year": {
Summary: "specifies the year to substitute for \" YEAR\" in the header file.",
Details: "",
},
},
}
}