1
0
mirror of https://github.com/rancher/steve.git synced 2025-05-03 21:46:55 +00:00
steve/pkg/schema/definitions/schema.go
vardhaman22 dae842ea98 updated wrangler from v2 to v3
also updated k8s dependencies to v0.30.1
2024-06-05 22:53:08 +05:30

98 lines
3.4 KiB
Go

package definitions
import (
"context"
"os"
"strconv"
"time"
"github.com/rancher/apiserver/pkg/types"
"github.com/rancher/steve/pkg/debounce"
apiextcontrollerv1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiextensions.k8s.io/v1"
v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/apiregistration.k8s.io/v1"
"github.com/rancher/wrangler/v3/pkg/schemas"
"github.com/sirupsen/logrus"
"k8s.io/client-go/discovery"
)
const (
handlerKey = "schema-definitions"
delayEnvVar = "CATTLE_CRD_REFRESH_DELAY_SECONDS"
defaultDelay = 2
delayUnit = time.Second
refreshEnvVar = "CATTLE_BACKGROUND_REFRESH_MINUTES"
defaultRefresh = 10
refreshUnit = time.Minute
)
type schemaDefinition struct {
DefinitionType string `json:"definitionType"`
Definitions map[string]definition `json:"definitions"`
}
type definition struct {
ResourceFields map[string]definitionField `json:"resourceFields"`
Type string `json:"type"`
Description string `json:"description"`
}
type definitionField struct {
Type string `json:"type"`
SubType string `json:"subtype,omitempty"`
Description string `json:"description,omitempty"`
Required bool `json:"required,omitempty"`
}
// Register registers the schemaDefinition schema.
func Register(ctx context.Context,
baseSchema *types.APISchemas,
client discovery.DiscoveryInterface,
crd apiextcontrollerv1.CustomResourceDefinitionController,
apiService v1.APIServiceController) {
handler := SchemaDefinitionHandler{
baseSchema: baseSchema,
client: client,
}
baseSchema.MustAddSchema(types.APISchema{
Schema: &schemas.Schema{
ID: "schemaDefinition",
PluralName: "schemaDefinitions",
ResourceMethods: []string{"GET"},
},
ByIDHandler: handler.byIDHandler,
})
debounce := debounce.DebounceableRefresher{
Refreshable: &handler,
}
crdDebounce := getDurationEnvVarOrDefault(delayEnvVar, defaultDelay, delayUnit)
refHandler := refreshHandler{
debounceRef: &debounce,
debounceDuration: crdDebounce,
}
crd.OnChange(ctx, handlerKey, refHandler.onChangeCRD)
apiService.OnChange(ctx, handlerKey, refHandler.onChangeAPIService)
refreshFrequency := getDurationEnvVarOrDefault(refreshEnvVar, defaultRefresh, refreshUnit)
// there's a delay between when a CRD is created and when it is available in the openapi/v2 endpoint
// the crd/apiservice controllers use a delay of 2 seconds to account for this, but it's possible that this isn't
// enough in certain environments, so we also use an infrequent background refresh to eventually correct any misses
refHandler.startBackgroundRefresh(ctx, refreshFrequency)
}
// getDurationEnvVarOrDefault gets the duration value for a given envVar. If not found, it returns the provided default.
// unit is the unit of time (time.Second/time.Minute/etc.) that the returned duration should be in
func getDurationEnvVarOrDefault(envVar string, defaultVal int, unit time.Duration) time.Duration {
defaultDuration := time.Duration(defaultVal) * unit
envValue, ok := os.LookupEnv(envVar)
if !ok {
return defaultDuration
}
parsed, err := strconv.Atoi(envValue)
if err != nil {
logrus.Errorf("Env var %s was specified, but could not be converted to an int, default of %d seconds will be used",
envVar, int64(defaultDuration.Seconds()))
return defaultDuration
}
return time.Duration(parsed) * unit
}