APF: graduate API and types to beta
Signed-off-by: Adhityaa Chandrasekar <adtac@google.com> Kubernetes-commit: 849be447f563fc93a27a0827fb1185b885b57114
This commit is contained in:
parent
13d987893e
commit
a4a3fc9b87
|
|
@ -19,7 +19,7 @@ package bootstrap
|
||||||
import (
|
import (
|
||||||
coordinationv1 "k8s.io/api/coordination/v1"
|
coordinationv1 "k8s.io/api/coordination/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
flowcontrol "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||||
StorageVersionHash: {Default: true, PreRelease: featuregate.Beta},
|
StorageVersionHash: {Default: true, PreRelease: featuregate.Beta},
|
||||||
StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha},
|
StorageVersionAPI: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
WatchBookmark: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||||
APIPriorityAndFairness: {Default: false, PreRelease: featuregate.Alpha},
|
APIPriorityAndFairness: {Default: true, PreRelease: featuregate.Beta},
|
||||||
RemoveSelfLink: {Default: true, PreRelease: featuregate.Beta},
|
RemoveSelfLink: {Default: true, PreRelease: featuregate.Beta},
|
||||||
SelectorIndex: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
SelectorIndex: {Default: true, PreRelease: featuregate.GA, LockToDefault: true},
|
||||||
WarningHeaders: {Default: true, PreRelease: featuregate.Beta},
|
WarningHeaders: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
|
|
||||||
|
|
@ -785,7 +785,7 @@ func installAPI(s *GenericAPIServer, c *Config) {
|
||||||
if c.EnableDiscovery {
|
if c.EnableDiscovery {
|
||||||
s.Handler.GoRestfulContainer.Add(s.DiscoveryGroupManager.WebService())
|
s.Handler.GoRestfulContainer.Add(s.DiscoveryGroupManager.WebService())
|
||||||
}
|
}
|
||||||
if feature.DefaultFeatureGate.Enabled(features.APIPriorityAndFairness) {
|
if c.FlowControl != nil && feature.DefaultFeatureGate.Enabled(features.APIPriorityAndFairness) {
|
||||||
c.FlowControl.Install(s.Handler.NonGoRestfulMux)
|
c.FlowControl.Install(s.Handler.NonGoRestfulMux)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
fcv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
apitypes "k8s.io/apimachinery/pkg/types"
|
apitypes "k8s.io/apimachinery/pkg/types"
|
||||||
epmetrics "k8s.io/apiserver/pkg/endpoints/metrics"
|
epmetrics "k8s.io/apiserver/pkg/endpoints/metrics"
|
||||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
|
|
@ -92,7 +92,7 @@ func WithPriorityAndFairness(
|
||||||
}
|
}
|
||||||
|
|
||||||
var classification *PriorityAndFairnessClassification
|
var classification *PriorityAndFairnessClassification
|
||||||
note := func(fs *fcv1a1.FlowSchema, pl *fcv1a1.PriorityLevelConfiguration) {
|
note := func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration) {
|
||||||
classification = &PriorityAndFairnessClassification{
|
classification = &PriorityAndFairnessClassification{
|
||||||
FlowSchemaName: fs.Name,
|
FlowSchemaName: fs.Name,
|
||||||
FlowSchemaUID: fs.UID,
|
FlowSchemaUID: fs.UID,
|
||||||
|
|
@ -122,8 +122,8 @@ func WithPriorityAndFairness(
|
||||||
served = true
|
served = true
|
||||||
innerCtx := context.WithValue(ctx, priorityAndFairnessKey, classification)
|
innerCtx := context.WithValue(ctx, priorityAndFairnessKey, classification)
|
||||||
innerReq := r.Clone(innerCtx)
|
innerReq := r.Clone(innerCtx)
|
||||||
w.Header().Set(fcv1a1.ResponseHeaderMatchedPriorityLevelConfigurationUID, string(classification.PriorityLevelUID))
|
w.Header().Set(flowcontrol.ResponseHeaderMatchedPriorityLevelConfigurationUID, string(classification.PriorityLevelUID))
|
||||||
w.Header().Set(fcv1a1.ResponseHeaderMatchedFlowSchemaUID, string(classification.FlowSchemaUID))
|
w.Header().Set(flowcontrol.ResponseHeaderMatchedFlowSchemaUID, string(classification.FlowSchemaUID))
|
||||||
handler.ServeHTTP(w, innerReq)
|
handler.ServeHTTP(w, innerReq)
|
||||||
}
|
}
|
||||||
digest := utilflowcontrol.RequestDigest{RequestInfo: requestInfo, User: user}
|
digest := utilflowcontrol.RequestDigest{RequestInfo: requestInfo, User: user}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fctypesv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
|
"k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
|
|
@ -60,7 +60,7 @@ func (t fakeApfFilter) MaintainObservations(stopCh <-chan struct{}) {
|
||||||
|
|
||||||
func (t fakeApfFilter) Handle(ctx context.Context,
|
func (t fakeApfFilter) Handle(ctx context.Context,
|
||||||
requestDigest utilflowcontrol.RequestDigest,
|
requestDigest utilflowcontrol.RequestDigest,
|
||||||
noteFn func(fs *fctypesv1a1.FlowSchema, pl *fctypesv1a1.PriorityLevelConfiguration),
|
noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration),
|
||||||
queueNoteFn fq.QueueNoteFn,
|
queueNoteFn fq.QueueNoteFn,
|
||||||
execFn func(),
|
execFn func(),
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ func (o *RecommendedOptions) ApplyTo(config *server.RecommendedConfig) error {
|
||||||
if feature.DefaultFeatureGate.Enabled(features.APIPriorityAndFairness) {
|
if feature.DefaultFeatureGate.Enabled(features.APIPriorityAndFairness) {
|
||||||
config.FlowControl = utilflowcontrol.New(
|
config.FlowControl = utilflowcontrol.New(
|
||||||
config.SharedInformerFactory,
|
config.SharedInformerFactory,
|
||||||
kubernetes.NewForConfigOrDie(config.ClientConfig).FlowcontrolV1alpha1(),
|
kubernetes.NewForConfigOrDie(config.ClientConfig).FlowcontrolV1beta1(),
|
||||||
config.MaxRequestsInFlight+config.MaxMutatingRequestsInFlight,
|
config.MaxRequestsInFlight+config.MaxMutatingRequestsInFlight,
|
||||||
config.RequestTimeout/4,
|
config.RequestTimeout/4,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ package apihelpers
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
flowcontrol "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetFlowSchemaCondition sets conditions.
|
// SetFlowSchemaCondition sets conditions.
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ import (
|
||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
fctypesv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
fcclientv1a1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1"
|
flowcontrolclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1"
|
||||||
fclistersv1a1 "k8s.io/client-go/listers/flowcontrol/v1alpha1"
|
flowcontrollister "k8s.io/client-go/listers/flowcontrol/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This file contains a simple local (to the apiserver) controller
|
// This file contains a simple local (to the apiserver) controller
|
||||||
|
|
@ -91,13 +91,13 @@ type configController struct {
|
||||||
// objects need to be reprocessed.
|
// objects need to be reprocessed.
|
||||||
configQueue workqueue.RateLimitingInterface
|
configQueue workqueue.RateLimitingInterface
|
||||||
|
|
||||||
plLister fclistersv1a1.PriorityLevelConfigurationLister
|
plLister flowcontrollister.PriorityLevelConfigurationLister
|
||||||
plInformerSynced cache.InformerSynced
|
plInformerSynced cache.InformerSynced
|
||||||
|
|
||||||
fsLister fclistersv1a1.FlowSchemaLister
|
fsLister flowcontrollister.FlowSchemaLister
|
||||||
fsInformerSynced cache.InformerSynced
|
fsInformerSynced cache.InformerSynced
|
||||||
|
|
||||||
flowcontrolClient fcclientv1a1.FlowcontrolV1alpha1Interface
|
flowcontrolClient flowcontrolclient.FlowcontrolV1beta1Interface
|
||||||
|
|
||||||
// serverConcurrencyLimit is the limit on the server's total
|
// serverConcurrencyLimit is the limit on the server's total
|
||||||
// number of non-exempt requests being served at once. This comes
|
// number of non-exempt requests being served at once. This comes
|
||||||
|
|
@ -127,7 +127,7 @@ type configController struct {
|
||||||
type priorityLevelState struct {
|
type priorityLevelState struct {
|
||||||
// the API object or prototype prescribing this level. Nothing
|
// the API object or prototype prescribing this level. Nothing
|
||||||
// reached through this pointer is mutable.
|
// reached through this pointer is mutable.
|
||||||
pl *fctypesv1a1.PriorityLevelConfiguration
|
pl *flowcontrol.PriorityLevelConfiguration
|
||||||
|
|
||||||
// qsCompleter holds the QueueSetCompleter derived from `config`
|
// qsCompleter holds the QueueSetCompleter derived from `config`
|
||||||
// and `queues` if config is not exempt, nil otherwise.
|
// and `queues` if config is not exempt, nil otherwise.
|
||||||
|
|
@ -153,7 +153,7 @@ type priorityLevelState struct {
|
||||||
// NewTestableController is extra flexible to facilitate testing
|
// NewTestableController is extra flexible to facilitate testing
|
||||||
func newTestableController(
|
func newTestableController(
|
||||||
informerFactory kubeinformers.SharedInformerFactory,
|
informerFactory kubeinformers.SharedInformerFactory,
|
||||||
flowcontrolClient fcclientv1a1.FlowcontrolV1alpha1Interface,
|
flowcontrolClient flowcontrolclient.FlowcontrolV1beta1Interface,
|
||||||
serverConcurrencyLimit int,
|
serverConcurrencyLimit int,
|
||||||
requestWaitLimit time.Duration,
|
requestWaitLimit time.Duration,
|
||||||
obsPairGenerator metrics.TimedObserverPairGenerator,
|
obsPairGenerator metrics.TimedObserverPairGenerator,
|
||||||
|
|
@ -178,7 +178,7 @@ func newTestableController(
|
||||||
// config API objects.
|
// config API objects.
|
||||||
func (cfgCtlr *configController) initializeConfigController(informerFactory kubeinformers.SharedInformerFactory) {
|
func (cfgCtlr *configController) initializeConfigController(informerFactory kubeinformers.SharedInformerFactory) {
|
||||||
cfgCtlr.configQueue = workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(200*time.Millisecond, 8*time.Hour), "priority_and_fairness_config_queue")
|
cfgCtlr.configQueue = workqueue.NewNamedRateLimitingQueue(workqueue.NewItemExponentialFailureRateLimiter(200*time.Millisecond, 8*time.Hour), "priority_and_fairness_config_queue")
|
||||||
fci := informerFactory.Flowcontrol().V1alpha1()
|
fci := informerFactory.Flowcontrol().V1beta1()
|
||||||
pli := fci.PriorityLevelConfigurations()
|
pli := fci.PriorityLevelConfigurations()
|
||||||
fsi := fci.FlowSchemas()
|
fsi := fci.FlowSchemas()
|
||||||
cfgCtlr.plLister = pli.Lister()
|
cfgCtlr.plLister = pli.Lister()
|
||||||
|
|
@ -187,13 +187,13 @@ func (cfgCtlr *configController) initializeConfigController(informerFactory kube
|
||||||
cfgCtlr.fsInformerSynced = fsi.Informer().HasSynced
|
cfgCtlr.fsInformerSynced = fsi.Informer().HasSynced
|
||||||
pli.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
pli.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
AddFunc: func(obj interface{}) {
|
AddFunc: func(obj interface{}) {
|
||||||
pl := obj.(*fctypesv1a1.PriorityLevelConfiguration)
|
pl := obj.(*flowcontrol.PriorityLevelConfiguration)
|
||||||
klog.V(7).Infof("Triggered API priority and fairness config reloading due to creation of PLC %s", pl.Name)
|
klog.V(7).Infof("Triggered API priority and fairness config reloading due to creation of PLC %s", pl.Name)
|
||||||
cfgCtlr.configQueue.Add(0)
|
cfgCtlr.configQueue.Add(0)
|
||||||
},
|
},
|
||||||
UpdateFunc: func(oldObj, newObj interface{}) {
|
UpdateFunc: func(oldObj, newObj interface{}) {
|
||||||
newPL := newObj.(*fctypesv1a1.PriorityLevelConfiguration)
|
newPL := newObj.(*flowcontrol.PriorityLevelConfiguration)
|
||||||
oldPL := oldObj.(*fctypesv1a1.PriorityLevelConfiguration)
|
oldPL := oldObj.(*flowcontrol.PriorityLevelConfiguration)
|
||||||
if !apiequality.Semantic.DeepEqual(oldPL.Spec, newPL.Spec) {
|
if !apiequality.Semantic.DeepEqual(oldPL.Spec, newPL.Spec) {
|
||||||
klog.V(7).Infof("Triggered API priority and fairness config reloading due to spec update of PLC %s", newPL.Name)
|
klog.V(7).Infof("Triggered API priority and fairness config reloading due to spec update of PLC %s", newPL.Name)
|
||||||
cfgCtlr.configQueue.Add(0)
|
cfgCtlr.configQueue.Add(0)
|
||||||
|
|
@ -207,13 +207,13 @@ func (cfgCtlr *configController) initializeConfigController(informerFactory kube
|
||||||
}})
|
}})
|
||||||
fsi.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
fsi.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||||
AddFunc: func(obj interface{}) {
|
AddFunc: func(obj interface{}) {
|
||||||
fs := obj.(*fctypesv1a1.FlowSchema)
|
fs := obj.(*flowcontrol.FlowSchema)
|
||||||
klog.V(7).Infof("Triggered API priority and fairness config reloading due to creation of FS %s", fs.Name)
|
klog.V(7).Infof("Triggered API priority and fairness config reloading due to creation of FS %s", fs.Name)
|
||||||
cfgCtlr.configQueue.Add(0)
|
cfgCtlr.configQueue.Add(0)
|
||||||
},
|
},
|
||||||
UpdateFunc: func(oldObj, newObj interface{}) {
|
UpdateFunc: func(oldObj, newObj interface{}) {
|
||||||
newFS := newObj.(*fctypesv1a1.FlowSchema)
|
newFS := newObj.(*flowcontrol.FlowSchema)
|
||||||
oldFS := oldObj.(*fctypesv1a1.FlowSchema)
|
oldFS := oldObj.(*flowcontrol.FlowSchema)
|
||||||
if !apiequality.Semantic.DeepEqual(oldFS.Spec, newFS.Spec) {
|
if !apiequality.Semantic.DeepEqual(oldFS.Spec, newFS.Spec) {
|
||||||
klog.V(7).Infof("Triggered API priority and fairness config reloading due to spec update of FS %s", newFS.Name)
|
klog.V(7).Infof("Triggered API priority and fairness config reloading due to spec update of FS %s", newFS.Name)
|
||||||
cfgCtlr.configQueue.Add(0)
|
cfgCtlr.configQueue.Add(0)
|
||||||
|
|
@ -332,14 +332,14 @@ type cfgMeal struct {
|
||||||
|
|
||||||
// A buffered set of status updates for a FlowSchema
|
// A buffered set of status updates for a FlowSchema
|
||||||
type fsStatusUpdate struct {
|
type fsStatusUpdate struct {
|
||||||
flowSchema *fctypesv1a1.FlowSchema
|
flowSchema *flowcontrol.FlowSchema
|
||||||
condition fctypesv1a1.FlowSchemaCondition
|
condition flowcontrol.FlowSchemaCondition
|
||||||
oldValue fctypesv1a1.FlowSchemaCondition
|
oldValue flowcontrol.FlowSchemaCondition
|
||||||
}
|
}
|
||||||
|
|
||||||
// digestConfigObjects is given all the API objects that configure
|
// digestConfigObjects is given all the API objects that configure
|
||||||
// cfgCtlr and writes its consequent new configState.
|
// cfgCtlr and writes its consequent new configState.
|
||||||
func (cfgCtlr *configController) digestConfigObjects(newPLs []*fctypesv1a1.PriorityLevelConfiguration, newFSs []*fctypesv1a1.FlowSchema) error {
|
func (cfgCtlr *configController) digestConfigObjects(newPLs []*flowcontrol.PriorityLevelConfiguration, newFSs []*flowcontrol.FlowSchema) error {
|
||||||
fsStatusUpdates := cfgCtlr.lockAndDigestConfigObjects(newPLs, newFSs)
|
fsStatusUpdates := cfgCtlr.lockAndDigestConfigObjects(newPLs, newFSs)
|
||||||
var errs []error
|
var errs []error
|
||||||
for _, fsu := range fsStatusUpdates {
|
for _, fsu := range fsStatusUpdates {
|
||||||
|
|
@ -360,7 +360,7 @@ func (cfgCtlr *configController) digestConfigObjects(newPLs []*fctypesv1a1.Prior
|
||||||
return apierrors.NewAggregate(errs)
|
return apierrors.NewAggregate(errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfgCtlr *configController) lockAndDigestConfigObjects(newPLs []*fctypesv1a1.PriorityLevelConfiguration, newFSs []*fctypesv1a1.FlowSchema) []fsStatusUpdate {
|
func (cfgCtlr *configController) lockAndDigestConfigObjects(newPLs []*flowcontrol.PriorityLevelConfiguration, newFSs []*flowcontrol.FlowSchema) []fsStatusUpdate {
|
||||||
cfgCtlr.lock.Lock()
|
cfgCtlr.lock.Lock()
|
||||||
defer cfgCtlr.lock.Unlock()
|
defer cfgCtlr.lock.Unlock()
|
||||||
meal := cfgMeal{
|
meal := cfgMeal{
|
||||||
|
|
@ -390,7 +390,7 @@ func (cfgCtlr *configController) lockAndDigestConfigObjects(newPLs []*fctypesv1a
|
||||||
|
|
||||||
// Digest the new set of PriorityLevelConfiguration objects.
|
// Digest the new set of PriorityLevelConfiguration objects.
|
||||||
// Pretend broken ones do not exist.
|
// Pretend broken ones do not exist.
|
||||||
func (meal *cfgMeal) digestNewPLsLocked(newPLs []*fctypesv1a1.PriorityLevelConfiguration) {
|
func (meal *cfgMeal) digestNewPLsLocked(newPLs []*flowcontrol.PriorityLevelConfiguration) {
|
||||||
for _, pl := range newPLs {
|
for _, pl := range newPLs {
|
||||||
state := meal.cfgCtlr.priorityLevelStates[pl.Name]
|
state := meal.cfgCtlr.priorityLevelStates[pl.Name]
|
||||||
if state == nil {
|
if state == nil {
|
||||||
|
|
@ -411,8 +411,8 @@ func (meal *cfgMeal) digestNewPLsLocked(newPLs []*fctypesv1a1.PriorityLevelConfi
|
||||||
if state.pl.Spec.Limited != nil {
|
if state.pl.Spec.Limited != nil {
|
||||||
meal.shareSum += float64(state.pl.Spec.Limited.AssuredConcurrencyShares)
|
meal.shareSum += float64(state.pl.Spec.Limited.AssuredConcurrencyShares)
|
||||||
}
|
}
|
||||||
meal.haveExemptPL = meal.haveExemptPL || pl.Name == fctypesv1a1.PriorityLevelConfigurationNameExempt
|
meal.haveExemptPL = meal.haveExemptPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameExempt
|
||||||
meal.haveCatchAllPL = meal.haveCatchAllPL || pl.Name == fctypesv1a1.PriorityLevelConfigurationNameCatchAll
|
meal.haveCatchAllPL = meal.haveCatchAllPL || pl.Name == flowcontrol.PriorityLevelConfigurationNameCatchAll
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -423,9 +423,9 @@ func (meal *cfgMeal) digestNewPLsLocked(newPLs []*fctypesv1a1.PriorityLevelConfi
|
||||||
// reflect this. This function also adds any missing mandatory
|
// reflect this. This function also adds any missing mandatory
|
||||||
// FlowSchema objects. The given objects must all have distinct
|
// FlowSchema objects. The given objects must all have distinct
|
||||||
// names.
|
// names.
|
||||||
func (meal *cfgMeal) digestFlowSchemasLocked(newFSs []*fctypesv1a1.FlowSchema) {
|
func (meal *cfgMeal) digestFlowSchemasLocked(newFSs []*flowcontrol.FlowSchema) {
|
||||||
fsSeq := make(apihelpers.FlowSchemaSequence, 0, len(newFSs))
|
fsSeq := make(apihelpers.FlowSchemaSequence, 0, len(newFSs))
|
||||||
fsMap := make(map[string]*fctypesv1a1.FlowSchema, len(newFSs))
|
fsMap := make(map[string]*flowcontrol.FlowSchema, len(newFSs))
|
||||||
var haveExemptFS, haveCatchAllFS bool
|
var haveExemptFS, haveCatchAllFS bool
|
||||||
for i, fs := range newFSs {
|
for i, fs := range newFSs {
|
||||||
otherFS := fsMap[fs.Name]
|
otherFS := fsMap[fs.Name]
|
||||||
|
|
@ -448,8 +448,8 @@ func (meal *cfgMeal) digestFlowSchemasLocked(newFSs []*fctypesv1a1.FlowSchema) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fsSeq = append(fsSeq, newFSs[i])
|
fsSeq = append(fsSeq, newFSs[i])
|
||||||
haveExemptFS = haveExemptFS || fs.Name == fctypesv1a1.FlowSchemaNameExempt
|
haveExemptFS = haveExemptFS || fs.Name == flowcontrol.FlowSchemaNameExempt
|
||||||
haveCatchAllFS = haveCatchAllFS || fs.Name == fctypesv1a1.FlowSchemaNameCatchAll
|
haveCatchAllFS = haveCatchAllFS || fs.Name == flowcontrol.FlowSchemaNameCatchAll
|
||||||
}
|
}
|
||||||
// sort into the order to be used for matching
|
// sort into the order to be used for matching
|
||||||
sort.Sort(fsSeq)
|
sort.Sort(fsSeq)
|
||||||
|
|
@ -481,7 +481,7 @@ func (meal *cfgMeal) processOldPLsLocked() {
|
||||||
// Still desired and already updated
|
// Still desired and already updated
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if plName == fctypesv1a1.PriorityLevelConfigurationNameExempt && !meal.haveExemptPL || plName == fctypesv1a1.PriorityLevelConfigurationNameCatchAll && !meal.haveCatchAllPL {
|
if plName == flowcontrol.PriorityLevelConfigurationNameExempt && !meal.haveExemptPL || plName == flowcontrol.PriorityLevelConfigurationNameCatchAll && !meal.haveCatchAllPL {
|
||||||
// BTW, we know the Spec has not changed because the
|
// BTW, we know the Spec has not changed because the
|
||||||
// mandatory objects have immutable Specs
|
// mandatory objects have immutable Specs
|
||||||
klog.V(3).Infof("Retaining mandatory priority level %q despite lack of API object", plName)
|
klog.V(3).Infof("Retaining mandatory priority level %q despite lack of API object", plName)
|
||||||
|
|
@ -513,8 +513,8 @@ func (meal *cfgMeal) processOldPLsLocked() {
|
||||||
// regular way.
|
// regular way.
|
||||||
meal.shareSum += float64(plState.pl.Spec.Limited.AssuredConcurrencyShares)
|
meal.shareSum += float64(plState.pl.Spec.Limited.AssuredConcurrencyShares)
|
||||||
}
|
}
|
||||||
meal.haveExemptPL = meal.haveExemptPL || plName == fctypesv1a1.PriorityLevelConfigurationNameExempt
|
meal.haveExemptPL = meal.haveExemptPL || plName == flowcontrol.PriorityLevelConfigurationNameExempt
|
||||||
meal.haveCatchAllPL = meal.haveCatchAllPL || plName == fctypesv1a1.PriorityLevelConfigurationNameCatchAll
|
meal.haveCatchAllPL = meal.haveCatchAllPL || plName == flowcontrol.PriorityLevelConfigurationNameCatchAll
|
||||||
meal.newPLStates[plName] = plState
|
meal.newPLStates[plName] = plState
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -548,18 +548,18 @@ func (meal *cfgMeal) finishQueueSetReconfigsLocked() {
|
||||||
// given priority level configuration. Returns nil if that config
|
// given priority level configuration. Returns nil if that config
|
||||||
// does not call for limiting. Returns nil and an error if the given
|
// does not call for limiting. Returns nil and an error if the given
|
||||||
// object is malformed in a way that is a problem for this package.
|
// object is malformed in a way that is a problem for this package.
|
||||||
func queueSetCompleterForPL(qsf fq.QueueSetFactory, queues fq.QueueSet, pl *fctypesv1a1.PriorityLevelConfiguration, requestWaitLimit time.Duration, intPair metrics.TimedObserverPair) (fq.QueueSetCompleter, error) {
|
func queueSetCompleterForPL(qsf fq.QueueSetFactory, queues fq.QueueSet, pl *flowcontrol.PriorityLevelConfiguration, requestWaitLimit time.Duration, intPair metrics.TimedObserverPair) (fq.QueueSetCompleter, error) {
|
||||||
if (pl.Spec.Type == fctypesv1a1.PriorityLevelEnablementExempt) != (pl.Spec.Limited == nil) {
|
if (pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt) != (pl.Spec.Limited == nil) {
|
||||||
return nil, errors.New("broken union structure at the top")
|
return nil, errors.New("broken union structure at the top")
|
||||||
}
|
}
|
||||||
if (pl.Spec.Type == fctypesv1a1.PriorityLevelEnablementExempt) != (pl.Name == fctypesv1a1.PriorityLevelConfigurationNameExempt) {
|
if (pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt) != (pl.Name == flowcontrol.PriorityLevelConfigurationNameExempt) {
|
||||||
// This package does not attempt to cope with a priority level dynamically switching between exempt and not.
|
// This package does not attempt to cope with a priority level dynamically switching between exempt and not.
|
||||||
return nil, errors.New("non-alignment between name and type")
|
return nil, errors.New("non-alignment between name and type")
|
||||||
}
|
}
|
||||||
if pl.Spec.Limited == nil {
|
if pl.Spec.Limited == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
if (pl.Spec.Limited.LimitResponse.Type == fctypesv1a1.LimitResponseTypeReject) != (pl.Spec.Limited.LimitResponse.Queuing == nil) {
|
if (pl.Spec.Limited.LimitResponse.Type == flowcontrol.LimitResponseTypeReject) != (pl.Spec.Limited.LimitResponse.Queuing == nil) {
|
||||||
return nil, errors.New("broken union structure for limit response")
|
return nil, errors.New("broken union structure for limit response")
|
||||||
}
|
}
|
||||||
qcAPI := pl.Spec.Limited.LimitResponse.Queuing
|
qcAPI := pl.Spec.Limited.LimitResponse.Queuing
|
||||||
|
|
@ -585,17 +585,17 @@ func queueSetCompleterForPL(qsf fq.QueueSetFactory, queues fq.QueueSet, pl *fcty
|
||||||
return qsc, err
|
return qsc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (meal *cfgMeal) presyncFlowSchemaStatus(fs *fctypesv1a1.FlowSchema, isDangling bool, plName string) {
|
func (meal *cfgMeal) presyncFlowSchemaStatus(fs *flowcontrol.FlowSchema, isDangling bool, plName string) {
|
||||||
danglingCondition := apihelpers.GetFlowSchemaConditionByType(fs, fctypesv1a1.FlowSchemaConditionDangling)
|
danglingCondition := apihelpers.GetFlowSchemaConditionByType(fs, flowcontrol.FlowSchemaConditionDangling)
|
||||||
if danglingCondition == nil {
|
if danglingCondition == nil {
|
||||||
danglingCondition = &fctypesv1a1.FlowSchemaCondition{
|
danglingCondition = &flowcontrol.FlowSchemaCondition{
|
||||||
Type: fctypesv1a1.FlowSchemaConditionDangling,
|
Type: flowcontrol.FlowSchemaConditionDangling,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
desiredStatus := fctypesv1a1.ConditionFalse
|
desiredStatus := flowcontrol.ConditionFalse
|
||||||
var desiredReason, desiredMessage string
|
var desiredReason, desiredMessage string
|
||||||
if isDangling {
|
if isDangling {
|
||||||
desiredStatus = fctypesv1a1.ConditionTrue
|
desiredStatus = flowcontrol.ConditionTrue
|
||||||
desiredReason = "NotFound"
|
desiredReason = "NotFound"
|
||||||
desiredMessage = fmt.Sprintf("This FlowSchema references the PriorityLevelConfiguration object named %q but there is no such object", plName)
|
desiredMessage = fmt.Sprintf("This FlowSchema references the PriorityLevelConfiguration object named %q but there is no such object", plName)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -607,8 +607,8 @@ func (meal *cfgMeal) presyncFlowSchemaStatus(fs *fctypesv1a1.FlowSchema, isDangl
|
||||||
}
|
}
|
||||||
meal.fsStatusUpdates = append(meal.fsStatusUpdates, fsStatusUpdate{
|
meal.fsStatusUpdates = append(meal.fsStatusUpdates, fsStatusUpdate{
|
||||||
flowSchema: fs,
|
flowSchema: fs,
|
||||||
condition: fctypesv1a1.FlowSchemaCondition{
|
condition: flowcontrol.FlowSchemaCondition{
|
||||||
Type: fctypesv1a1.FlowSchemaConditionDangling,
|
Type: flowcontrol.FlowSchemaConditionDangling,
|
||||||
Status: desiredStatus,
|
Status: desiredStatus,
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
Reason: desiredReason,
|
Reason: desiredReason,
|
||||||
|
|
@ -619,7 +619,7 @@ func (meal *cfgMeal) presyncFlowSchemaStatus(fs *fctypesv1a1.FlowSchema, isDangl
|
||||||
|
|
||||||
// imaginePL adds a priority level based on one of the mandatory ones
|
// imaginePL adds a priority level based on one of the mandatory ones
|
||||||
// that does not actually exist (right now) as a real API object.
|
// that does not actually exist (right now) as a real API object.
|
||||||
func (meal *cfgMeal) imaginePL(proto *fctypesv1a1.PriorityLevelConfiguration, requestWaitLimit time.Duration) {
|
func (meal *cfgMeal) imaginePL(proto *flowcontrol.PriorityLevelConfiguration, requestWaitLimit time.Duration) {
|
||||||
klog.V(3).Infof("No %s PriorityLevelConfiguration found, imagining one", proto.Name)
|
klog.V(3).Infof("No %s PriorityLevelConfiguration found, imagining one", proto.Name)
|
||||||
obsPair := meal.cfgCtlr.obsPairGenerator.Generate(1, 1, []string{proto.Name})
|
obsPair := meal.cfgCtlr.obsPairGenerator.Generate(1, 1, []string{proto.Name})
|
||||||
qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, nil, proto, requestWaitLimit, obsPair)
|
qsCompleter, err := queueSetCompleterForPL(meal.cfgCtlr.queueSetFactory, nil, proto, requestWaitLimit, obsPair)
|
||||||
|
|
@ -651,7 +651,7 @@ func (immediateRequest) Finish(execute func()) bool {
|
||||||
// The returned bool indicates whether the request is exempt from
|
// The returned bool indicates whether the request is exempt from
|
||||||
// limitation. The startWaitingTime is when the request started
|
// limitation. The startWaitingTime is when the request started
|
||||||
// waiting in its queue, or `Time{}` if this did not happen.
|
// waiting in its queue, or `Time{}` if this did not happen.
|
||||||
func (cfgCtlr *configController) startRequest(ctx context.Context, rd RequestDigest, queueNoteFn fq.QueueNoteFn) (fs *fctypesv1a1.FlowSchema, pl *fctypesv1a1.PriorityLevelConfiguration, isExempt bool, req fq.Request, startWaitingTime time.Time) {
|
func (cfgCtlr *configController) startRequest(ctx context.Context, rd RequestDigest, queueNoteFn fq.QueueNoteFn) (fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration, isExempt bool, req fq.Request, startWaitingTime time.Time) {
|
||||||
klog.V(7).Infof("startRequest(%#+v)", rd)
|
klog.V(7).Infof("startRequest(%#+v)", rd)
|
||||||
cfgCtlr.lock.Lock()
|
cfgCtlr.lock.Lock()
|
||||||
defer cfgCtlr.lock.Unlock()
|
defer cfgCtlr.lock.Unlock()
|
||||||
|
|
@ -659,12 +659,12 @@ func (cfgCtlr *configController) startRequest(ctx context.Context, rd RequestDig
|
||||||
if matchesFlowSchema(rd, fs) {
|
if matchesFlowSchema(rd, fs) {
|
||||||
plName := fs.Spec.PriorityLevelConfiguration.Name
|
plName := fs.Spec.PriorityLevelConfiguration.Name
|
||||||
plState := cfgCtlr.priorityLevelStates[plName]
|
plState := cfgCtlr.priorityLevelStates[plName]
|
||||||
if plState.pl.Spec.Type == fctypesv1a1.PriorityLevelEnablementExempt {
|
if plState.pl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt {
|
||||||
klog.V(7).Infof("startRequest(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, immediate", rd, fs.Name, fs.Spec.DistinguisherMethod, plName)
|
klog.V(7).Infof("startRequest(%#+v) => fsName=%q, distMethod=%#+v, plName=%q, immediate", rd, fs.Name, fs.Spec.DistinguisherMethod, plName)
|
||||||
return fs, plState.pl, true, immediateRequest{}, time.Time{}
|
return fs, plState.pl, true, immediateRequest{}, time.Time{}
|
||||||
}
|
}
|
||||||
var numQueues int32
|
var numQueues int32
|
||||||
if plState.pl.Spec.Limited.LimitResponse.Type == fctypesv1a1.LimitResponseTypeQueue {
|
if plState.pl.Spec.Limited.LimitResponse.Type == flowcontrol.LimitResponseTypeQueue {
|
||||||
numQueues = plState.pl.Spec.Limited.LimitResponse.Queuing.Queues
|
numQueues = plState.pl.Spec.Limited.LimitResponse.Queuing.Queues
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -686,9 +686,9 @@ func (cfgCtlr *configController) startRequest(ctx context.Context, rd RequestDig
|
||||||
// This can never happen because every configState has a
|
// This can never happen because every configState has a
|
||||||
// FlowSchema that matches everything. If somehow control reaches
|
// FlowSchema that matches everything. If somehow control reaches
|
||||||
// here, panic with some relevant information.
|
// here, panic with some relevant information.
|
||||||
var catchAll *fctypesv1a1.FlowSchema
|
var catchAll *flowcontrol.FlowSchema
|
||||||
for _, fs := range cfgCtlr.flowSchemas {
|
for _, fs := range cfgCtlr.flowSchemas {
|
||||||
if fs.Name == fctypesv1a1.FlowSchemaNameCatchAll {
|
if fs.Name == flowcontrol.FlowSchemaNameCatchAll {
|
||||||
catchAll = fs
|
catchAll = fs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -726,14 +726,14 @@ func (cfgCtlr *configController) maybeReapLocked(plName string, plState *priorit
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeFlowDistinguisher extracts the flow distinguisher according to the given method
|
// computeFlowDistinguisher extracts the flow distinguisher according to the given method
|
||||||
func computeFlowDistinguisher(rd RequestDigest, method *fctypesv1a1.FlowDistinguisherMethod) string {
|
func computeFlowDistinguisher(rd RequestDigest, method *flowcontrol.FlowDistinguisherMethod) string {
|
||||||
if method == nil {
|
if method == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
switch method.Type {
|
switch method.Type {
|
||||||
case fctypesv1a1.FlowDistinguisherMethodByUserType:
|
case flowcontrol.FlowDistinguisherMethodByUserType:
|
||||||
return rd.User.GetName()
|
return rd.User.GetName()
|
||||||
case fctypesv1a1.FlowDistinguisherMethodByNamespaceType:
|
case flowcontrol.FlowDistinguisherMethodByNamespaceType:
|
||||||
return rd.RequestInfo.Namespace
|
return rd.RequestInfo.Namespace
|
||||||
default:
|
default:
|
||||||
// this line shall never reach
|
// this line shall never reach
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ import (
|
||||||
kubeinformers "k8s.io/client-go/informers"
|
kubeinformers "k8s.io/client-go/informers"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
fctypesv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
fcclientv1a1 "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1"
|
flowcontrolclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Interface defines how the API Priority and Fairness filter interacts with the underlying system.
|
// Interface defines how the API Priority and Fairness filter interacts with the underlying system.
|
||||||
|
|
@ -47,7 +47,7 @@ type Interface interface {
|
||||||
// not be invoked.
|
// not be invoked.
|
||||||
Handle(ctx context.Context,
|
Handle(ctx context.Context,
|
||||||
requestDigest RequestDigest,
|
requestDigest RequestDigest,
|
||||||
noteFn func(fs *fctypesv1a1.FlowSchema, pl *fctypesv1a1.PriorityLevelConfiguration),
|
noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration),
|
||||||
queueNoteFn fq.QueueNoteFn,
|
queueNoteFn fq.QueueNoteFn,
|
||||||
execFn func(),
|
execFn func(),
|
||||||
)
|
)
|
||||||
|
|
@ -69,7 +69,7 @@ type Interface interface {
|
||||||
// New creates a new instance to implement API priority and fairness
|
// New creates a new instance to implement API priority and fairness
|
||||||
func New(
|
func New(
|
||||||
informerFactory kubeinformers.SharedInformerFactory,
|
informerFactory kubeinformers.SharedInformerFactory,
|
||||||
flowcontrolClient fcclientv1a1.FlowcontrolV1alpha1Interface,
|
flowcontrolClient flowcontrolclient.FlowcontrolV1beta1Interface,
|
||||||
serverConcurrencyLimit int,
|
serverConcurrencyLimit int,
|
||||||
requestWaitLimit time.Duration,
|
requestWaitLimit time.Duration,
|
||||||
) Interface {
|
) Interface {
|
||||||
|
|
@ -87,7 +87,7 @@ func New(
|
||||||
// NewTestable is extra flexible to facilitate testing
|
// NewTestable is extra flexible to facilitate testing
|
||||||
func NewTestable(
|
func NewTestable(
|
||||||
informerFactory kubeinformers.SharedInformerFactory,
|
informerFactory kubeinformers.SharedInformerFactory,
|
||||||
flowcontrolClient fcclientv1a1.FlowcontrolV1alpha1Interface,
|
flowcontrolClient flowcontrolclient.FlowcontrolV1beta1Interface,
|
||||||
serverConcurrencyLimit int,
|
serverConcurrencyLimit int,
|
||||||
requestWaitLimit time.Duration,
|
requestWaitLimit time.Duration,
|
||||||
obsPairGenerator metrics.TimedObserverPairGenerator,
|
obsPairGenerator metrics.TimedObserverPairGenerator,
|
||||||
|
|
@ -97,7 +97,7 @@ func NewTestable(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest RequestDigest,
|
func (cfgCtlr *configController) Handle(ctx context.Context, requestDigest RequestDigest,
|
||||||
noteFn func(fs *fctypesv1a1.FlowSchema, pl *fctypesv1a1.PriorityLevelConfiguration),
|
noteFn func(fs *flowcontrol.FlowSchema, pl *flowcontrol.PriorityLevelConfiguration),
|
||||||
queueNoteFn fq.QueueNoteFn,
|
queueNoteFn fq.QueueNoteFn,
|
||||||
execFn func()) {
|
execFn func()) {
|
||||||
fs, pl, isExempt, req, startWaitingTime := cfgCtlr.startRequest(ctx, requestDigest, queueNoteFn)
|
fs, pl, isExempt, req, startWaitingTime := cfgCtlr.startRequest(ctx, requestDigest, queueNoteFn)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fcv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
|
fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
|
||||||
"k8s.io/apiserver/pkg/util/flowcontrol/debug"
|
"k8s.io/apiserver/pkg/util/flowcontrol/debug"
|
||||||
|
|
@ -34,7 +34,7 @@ import (
|
||||||
"k8s.io/apiserver/pkg/util/flowcontrol/metrics"
|
"k8s.io/apiserver/pkg/util/flowcontrol/metrics"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||||
fcclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1alpha1"
|
fcclient "k8s.io/client-go/kubernetes/typed/flowcontrol/v1beta1"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -43,8 +43,8 @@ func TestMain(m *testing.M) {
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|
||||||
var mandPLs = func() map[string]*fcv1a1.PriorityLevelConfiguration {
|
var mandPLs = func() map[string]*flowcontrol.PriorityLevelConfiguration {
|
||||||
ans := make(map[string]*fcv1a1.PriorityLevelConfiguration)
|
ans := make(map[string]*flowcontrol.PriorityLevelConfiguration)
|
||||||
for _, mand := range fcboot.MandatoryPriorityLevelConfigurations {
|
for _, mand := range fcboot.MandatoryPriorityLevelConfigurations {
|
||||||
ans[mand.Name] = mand
|
ans[mand.Name] = mand
|
||||||
}
|
}
|
||||||
|
|
@ -54,9 +54,9 @@ var mandPLs = func() map[string]*fcv1a1.PriorityLevelConfiguration {
|
||||||
type ctlrTestState struct {
|
type ctlrTestState struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
cfgCtlr *configController
|
cfgCtlr *configController
|
||||||
fcIfc fcclient.FlowcontrolV1alpha1Interface
|
fcIfc fcclient.FlowcontrolV1beta1Interface
|
||||||
existingPLs map[string]*fcv1a1.PriorityLevelConfiguration
|
existingPLs map[string]*flowcontrol.PriorityLevelConfiguration
|
||||||
existingFSs map[string]*fcv1a1.FlowSchema
|
existingFSs map[string]*flowcontrol.FlowSchema
|
||||||
heldRequestsMap map[string][]heldRequest
|
heldRequestsMap map[string][]heldRequest
|
||||||
requestWG sync.WaitGroup
|
requestWG sync.WaitGroup
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
|
@ -206,7 +206,7 @@ var mandQueueSetNames, exclQueueSetNames = func() (sets.String, sets.String) {
|
||||||
mandQueueSetNames := sets.NewString()
|
mandQueueSetNames := sets.NewString()
|
||||||
exclQueueSetNames := sets.NewString()
|
exclQueueSetNames := sets.NewString()
|
||||||
for _, mpl := range fcboot.MandatoryPriorityLevelConfigurations {
|
for _, mpl := range fcboot.MandatoryPriorityLevelConfigurations {
|
||||||
if mpl.Spec.Type == fcv1a1.PriorityLevelEnablementExempt {
|
if mpl.Spec.Type == flowcontrol.PriorityLevelEnablementExempt {
|
||||||
exclQueueSetNames.Insert(mpl.Name)
|
exclQueueSetNames.Insert(mpl.Name)
|
||||||
} else {
|
} else {
|
||||||
mandQueueSetNames.Insert(mpl.Name)
|
mandQueueSetNames.Insert(mpl.Name)
|
||||||
|
|
@ -222,11 +222,11 @@ func TestConfigConsumer(t *testing.T) {
|
||||||
t.Run(fmt.Sprintf("trial%d:", i), func(t *testing.T) {
|
t.Run(fmt.Sprintf("trial%d:", i), func(t *testing.T) {
|
||||||
clientset := clientsetfake.NewSimpleClientset()
|
clientset := clientsetfake.NewSimpleClientset()
|
||||||
informerFactory := informers.NewSharedInformerFactory(clientset, 0)
|
informerFactory := informers.NewSharedInformerFactory(clientset, 0)
|
||||||
flowcontrolClient := clientset.FlowcontrolV1alpha1()
|
flowcontrolClient := clientset.FlowcontrolV1beta1()
|
||||||
cts := &ctlrTestState{t: t,
|
cts := &ctlrTestState{t: t,
|
||||||
fcIfc: flowcontrolClient,
|
fcIfc: flowcontrolClient,
|
||||||
existingFSs: map[string]*fcv1a1.FlowSchema{},
|
existingFSs: map[string]*flowcontrol.FlowSchema{},
|
||||||
existingPLs: map[string]*fcv1a1.PriorityLevelConfiguration{},
|
existingPLs: map[string]*flowcontrol.PriorityLevelConfiguration{},
|
||||||
heldRequestsMap: map[string][]heldRequest{},
|
heldRequestsMap: map[string][]heldRequest{},
|
||||||
queues: map[string]*ctlrTestQueueSet{},
|
queues: map[string]*ctlrTestQueueSet{},
|
||||||
}
|
}
|
||||||
|
|
@ -284,8 +284,8 @@ func TestConfigConsumer(t *testing.T) {
|
||||||
|
|
||||||
// Now create a new config and digest it
|
// Now create a new config and digest it
|
||||||
trialStep = fmt.Sprintf("trial%d-%d", i, j)
|
trialStep = fmt.Sprintf("trial%d-%d", i, j)
|
||||||
var newPLs []*fcv1a1.PriorityLevelConfiguration
|
var newPLs []*flowcontrol.PriorityLevelConfiguration
|
||||||
var newFSs []*fcv1a1.FlowSchema
|
var newFSs []*flowcontrol.FlowSchema
|
||||||
newPLs, _, desiredPLNames, newBadPLNames = genPLs(rng, trialStep, persistingPLNames, 1+rng.Intn(4))
|
newPLs, _, desiredPLNames, newBadPLNames = genPLs(rng, trialStep, persistingPLNames, 1+rng.Intn(4))
|
||||||
newFSs, _, newFTRs, newCatchAlls = genFSs(t, rng, trialStep, desiredPLNames, newBadPLNames, 1+rng.Intn(6))
|
newFSs, _, newFTRs, newCatchAlls = genFSs(t, rng, trialStep, desiredPLNames, newBadPLNames, 1+rng.Intn(6))
|
||||||
|
|
||||||
|
|
@ -307,7 +307,7 @@ func TestConfigConsumer(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkNewFS(cts *ctlrTestState, rng *rand.Rand, trialName string, ftr *fsTestingRecord, catchAlls map[bool]*fcv1a1.FlowSchema) {
|
func checkNewFS(cts *ctlrTestState, rng *rand.Rand, trialName string, ftr *fsTestingRecord, catchAlls map[bool]*flowcontrol.FlowSchema) {
|
||||||
t := cts.t
|
t := cts.t
|
||||||
ctlr := cts.cfgCtlr
|
ctlr := cts.cfgCtlr
|
||||||
fs := ftr.fs
|
fs := ftr.fs
|
||||||
|
|
@ -325,8 +325,8 @@ func checkNewFS(cts *ctlrTestState, rng *rand.Rand, trialName string, ftr *fsTes
|
||||||
startWG.Add(1)
|
startWG.Add(1)
|
||||||
go func(matches, isResource bool, rdu RequestDigest) {
|
go func(matches, isResource bool, rdu RequestDigest) {
|
||||||
expectedMatch := matches && ftr.wellFormed && (fsPrecedes(fs, catchAlls[isResource]) || fs.Name == catchAlls[isResource].Name)
|
expectedMatch := matches && ftr.wellFormed && (fsPrecedes(fs, catchAlls[isResource]) || fs.Name == catchAlls[isResource].Name)
|
||||||
ctlr.Handle(ctx, rdu, func(matchFS *fcv1a1.FlowSchema, matchPL *fcv1a1.PriorityLevelConfiguration) {
|
ctlr.Handle(ctx, rdu, func(matchFS *flowcontrol.FlowSchema, matchPL *flowcontrol.PriorityLevelConfiguration) {
|
||||||
matchIsExempt := matchPL.Spec.Type == fcv1a1.PriorityLevelEnablementExempt
|
matchIsExempt := matchPL.Spec.Type == flowcontrol.PriorityLevelEnablementExempt
|
||||||
t.Logf("Considering FlowSchema %s, expectedMatch=%v, isResource=%v: Handle(%#+v) => note(fs=%s, pl=%s, isExempt=%v)", fs.Name, expectedMatch, isResource, rdu, matchFS.Name, matchPL.Name, matchIsExempt)
|
t.Logf("Considering FlowSchema %s, expectedMatch=%v, isResource=%v: Handle(%#+v) => note(fs=%s, pl=%s, isExempt=%v)", fs.Name, expectedMatch, isResource, rdu, matchFS.Name, matchPL.Name, matchIsExempt)
|
||||||
if a := matchFS.Name == fs.Name; expectedMatch != a {
|
if a := matchFS.Name == fs.Name; expectedMatch != a {
|
||||||
t.Errorf("Fail at %s/%s: rd=%#+v, expectedMatch=%v, actualMatch=%v, matchFSName=%q, catchAlls=%#+v", trialName, fs.Name, rdu, expectedMatch, a, matchFS.Name, catchAlls)
|
t.Errorf("Fail at %s/%s: rd=%#+v, expectedMatch=%v, actualMatch=%v, matchFSName=%q, catchAlls=%#+v", trialName, fs.Name, rdu, expectedMatch, a, matchFS.Name, catchAlls)
|
||||||
|
|
@ -355,12 +355,12 @@ func checkNewFS(cts *ctlrTestState, rng *rand.Rand, trialName string, ftr *fsTes
|
||||||
startWG.Wait()
|
startWG.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func genPLs(rng *rand.Rand, trial string, oldPLNames sets.String, n int) (pls []*fcv1a1.PriorityLevelConfiguration, plMap map[string]*fcv1a1.PriorityLevelConfiguration, goodNames, badNames sets.String) {
|
func genPLs(rng *rand.Rand, trial string, oldPLNames sets.String, n int) (pls []*flowcontrol.PriorityLevelConfiguration, plMap map[string]*flowcontrol.PriorityLevelConfiguration, goodNames, badNames sets.String) {
|
||||||
pls = make([]*fcv1a1.PriorityLevelConfiguration, 0, n)
|
pls = make([]*flowcontrol.PriorityLevelConfiguration, 0, n)
|
||||||
plMap = make(map[string]*fcv1a1.PriorityLevelConfiguration, n)
|
plMap = make(map[string]*flowcontrol.PriorityLevelConfiguration, n)
|
||||||
goodNames = sets.NewString()
|
goodNames = sets.NewString()
|
||||||
badNames = sets.NewString(trial+"-nopl1", trial+"-nopl2")
|
badNames = sets.NewString(trial+"-nopl1", trial+"-nopl2")
|
||||||
addGood := func(pl *fcv1a1.PriorityLevelConfiguration) {
|
addGood := func(pl *flowcontrol.PriorityLevelConfiguration) {
|
||||||
pls = append(pls, pl)
|
pls = append(pls, pl)
|
||||||
plMap[pl.Name] = pl
|
plMap[pl.Name] = pl
|
||||||
goodNames.Insert(pl.Name)
|
goodNames.Insert(pl.Name)
|
||||||
|
|
@ -386,12 +386,12 @@ func genPLs(rng *rand.Rand, trial string, oldPLNames sets.String, n int) (pls []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func genFSs(t *testing.T, rng *rand.Rand, trial string, goodPLNames, badPLNames sets.String, n int) (newFSs []*fcv1a1.FlowSchema, newFSMap map[string]*fcv1a1.FlowSchema, newFTRs map[string]*fsTestingRecord, catchAlls map[bool]*fcv1a1.FlowSchema) {
|
func genFSs(t *testing.T, rng *rand.Rand, trial string, goodPLNames, badPLNames sets.String, n int) (newFSs []*flowcontrol.FlowSchema, newFSMap map[string]*flowcontrol.FlowSchema, newFTRs map[string]*fsTestingRecord, catchAlls map[bool]*flowcontrol.FlowSchema) {
|
||||||
newFTRs = map[string]*fsTestingRecord{}
|
newFTRs = map[string]*fsTestingRecord{}
|
||||||
catchAlls = map[bool]*fcv1a1.FlowSchema{
|
catchAlls = map[bool]*flowcontrol.FlowSchema{
|
||||||
false: fcboot.MandatoryFlowSchemaCatchAll,
|
false: fcboot.MandatoryFlowSchemaCatchAll,
|
||||||
true: fcboot.MandatoryFlowSchemaCatchAll}
|
true: fcboot.MandatoryFlowSchemaCatchAll}
|
||||||
newFSMap = map[string]*fcv1a1.FlowSchema{}
|
newFSMap = map[string]*flowcontrol.FlowSchema{}
|
||||||
add := func(ftr *fsTestingRecord) {
|
add := func(ftr *fsTestingRecord) {
|
||||||
newFSs = append(newFSs, ftr.fs)
|
newFSs = append(newFSs, ftr.fs)
|
||||||
newFSMap[ftr.fs.Name] = ftr.fs
|
newFSMap[ftr.fs.Name] = ftr.fs
|
||||||
|
|
@ -419,7 +419,7 @@ func genFSs(t *testing.T, rng *rand.Rand, trial string, goodPLNames, badPLNames
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func fsPrecedes(a, b *fcv1a1.FlowSchema) bool {
|
func fsPrecedes(a, b *flowcontrol.FlowSchema) bool {
|
||||||
if a.Spec.MatchingPrecedence < b.Spec.MatchingPrecedence {
|
if a.Spec.MatchingPrecedence < b.Spec.MatchingPrecedence {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@ limitations under the License.
|
||||||
package debug
|
package debug
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
// QueueSetDump is an instant dump of queue-set.
|
// QueueSetDump is an instant dump of queue-set.
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
fcv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
)
|
)
|
||||||
|
|
@ -46,25 +46,25 @@ func (sr Stringer) String() string {
|
||||||
return "nil"
|
return "nil"
|
||||||
}
|
}
|
||||||
switch typed := sr.val.(type) {
|
switch typed := sr.val.(type) {
|
||||||
case *fcv1a1.FlowSchema,
|
case *flowcontrol.FlowSchema,
|
||||||
fcv1a1.FlowSchema,
|
flowcontrol.FlowSchema,
|
||||||
fcv1a1.FlowSchemaSpec,
|
flowcontrol.FlowSchemaSpec,
|
||||||
fcv1a1.FlowDistinguisherMethod,
|
flowcontrol.FlowDistinguisherMethod,
|
||||||
*fcv1a1.FlowDistinguisherMethod,
|
*flowcontrol.FlowDistinguisherMethod,
|
||||||
*fcv1a1.PolicyRulesWithSubjects,
|
*flowcontrol.PolicyRulesWithSubjects,
|
||||||
fcv1a1.PolicyRulesWithSubjects,
|
flowcontrol.PolicyRulesWithSubjects,
|
||||||
fcv1a1.Subject,
|
flowcontrol.Subject,
|
||||||
fcv1a1.ResourcePolicyRule,
|
flowcontrol.ResourcePolicyRule,
|
||||||
fcv1a1.NonResourcePolicyRule,
|
flowcontrol.NonResourcePolicyRule,
|
||||||
fcv1a1.FlowSchemaCondition,
|
flowcontrol.FlowSchemaCondition,
|
||||||
*fcv1a1.PriorityLevelConfiguration,
|
*flowcontrol.PriorityLevelConfiguration,
|
||||||
fcv1a1.PriorityLevelConfiguration,
|
flowcontrol.PriorityLevelConfiguration,
|
||||||
fcv1a1.PriorityLevelConfigurationSpec,
|
flowcontrol.PriorityLevelConfigurationSpec,
|
||||||
*fcv1a1.LimitedPriorityLevelConfiguration,
|
*flowcontrol.LimitedPriorityLevelConfiguration,
|
||||||
fcv1a1.LimitedPriorityLevelConfiguration,
|
flowcontrol.LimitedPriorityLevelConfiguration,
|
||||||
fcv1a1.LimitResponse,
|
flowcontrol.LimitResponse,
|
||||||
*fcv1a1.QueuingConfiguration,
|
*flowcontrol.QueuingConfiguration,
|
||||||
fcv1a1.QueuingConfiguration:
|
flowcontrol.QueuingConfiguration:
|
||||||
return ToJSON(sr.val)
|
return ToJSON(sr.val)
|
||||||
case []user.Info:
|
case []user.Info:
|
||||||
return FmtUsers(typed)
|
return FmtUsers(typed)
|
||||||
|
|
@ -88,12 +88,12 @@ func ToJSON(val interface{}) string {
|
||||||
|
|
||||||
// FmtPriorityLevelConfiguration returns a golang source expression
|
// FmtPriorityLevelConfiguration returns a golang source expression
|
||||||
// equivalent to the given value
|
// equivalent to the given value
|
||||||
func FmtPriorityLevelConfiguration(pl *fcv1a1.PriorityLevelConfiguration) string {
|
func FmtPriorityLevelConfiguration(pl *flowcontrol.PriorityLevelConfiguration) string {
|
||||||
if pl == nil {
|
if pl == nil {
|
||||||
return "nil"
|
return "nil"
|
||||||
}
|
}
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
buf.WriteString(fmt.Sprintf("&v1alpha1.PriorityLevelConfiguration{ObjectMeta: %#+v, Spec: ",
|
buf.WriteString(fmt.Sprintf("&flowcontrolv1beta1.PriorityLevelConfiguration{ObjectMeta: %#+v, Spec: ",
|
||||||
pl.ObjectMeta))
|
pl.ObjectMeta))
|
||||||
BufferPriorityLevelConfigurationSpec(&buf, &pl.Spec)
|
BufferPriorityLevelConfigurationSpec(&buf, &pl.Spec)
|
||||||
buf.WriteString(fmt.Sprintf(", Status: %#+v}", pl.Status))
|
buf.WriteString(fmt.Sprintf(", Status: %#+v}", pl.Status))
|
||||||
|
|
@ -102,7 +102,7 @@ func FmtPriorityLevelConfiguration(pl *fcv1a1.PriorityLevelConfiguration) string
|
||||||
|
|
||||||
// FmtPriorityLevelConfigurationSpec returns a golang source
|
// FmtPriorityLevelConfigurationSpec returns a golang source
|
||||||
// expression equivalent to the given value
|
// expression equivalent to the given value
|
||||||
func FmtPriorityLevelConfigurationSpec(plSpec *fcv1a1.PriorityLevelConfigurationSpec) string {
|
func FmtPriorityLevelConfigurationSpec(plSpec *flowcontrol.PriorityLevelConfigurationSpec) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
BufferPriorityLevelConfigurationSpec(&buf, plSpec)
|
BufferPriorityLevelConfigurationSpec(&buf, plSpec)
|
||||||
return buf.String()
|
return buf.String()
|
||||||
|
|
@ -110,10 +110,10 @@ func FmtPriorityLevelConfigurationSpec(plSpec *fcv1a1.PriorityLevelConfiguration
|
||||||
|
|
||||||
// BufferPriorityLevelConfigurationSpec writes a golang source
|
// BufferPriorityLevelConfigurationSpec writes a golang source
|
||||||
// expression for the given value to the given buffer
|
// expression for the given value to the given buffer
|
||||||
func BufferPriorityLevelConfigurationSpec(buf *bytes.Buffer, plSpec *fcv1a1.PriorityLevelConfigurationSpec) {
|
func BufferPriorityLevelConfigurationSpec(buf *bytes.Buffer, plSpec *flowcontrol.PriorityLevelConfigurationSpec) {
|
||||||
buf.WriteString(fmt.Sprintf("v1alpha1.PriorityLevelConfigurationSpec{Type: %#v", plSpec.Type))
|
buf.WriteString(fmt.Sprintf("flowcontrolv1beta1.PriorityLevelConfigurationSpec{Type: %#v", plSpec.Type))
|
||||||
if plSpec.Limited != nil {
|
if plSpec.Limited != nil {
|
||||||
buf.WriteString(fmt.Sprintf(", Limited: &v1alpha1.LimitedPriorityLevelConfiguration{AssuredConcurrencyShares:%d, LimitResponse:v1alpha1.LimitResponse{Type:%#v", plSpec.Limited.AssuredConcurrencyShares, plSpec.Limited.LimitResponse.Type))
|
buf.WriteString(fmt.Sprintf(", Limited: &flowcontrol.LimitedPriorityLevelConfiguration{AssuredConcurrencyShares:%d, LimitResponse:flowcontrol.LimitResponse{Type:%#v", plSpec.Limited.AssuredConcurrencyShares, plSpec.Limited.LimitResponse.Type))
|
||||||
if plSpec.Limited.LimitResponse.Queuing != nil {
|
if plSpec.Limited.LimitResponse.Queuing != nil {
|
||||||
buf.WriteString(fmt.Sprintf(", Queuing:&%#+v", *plSpec.Limited.LimitResponse.Queuing))
|
buf.WriteString(fmt.Sprintf(", Queuing:&%#+v", *plSpec.Limited.LimitResponse.Queuing))
|
||||||
}
|
}
|
||||||
|
|
@ -123,12 +123,12 @@ func BufferPriorityLevelConfigurationSpec(buf *bytes.Buffer, plSpec *fcv1a1.Prio
|
||||||
}
|
}
|
||||||
|
|
||||||
// FmtFlowSchema produces a golang source expression of the value.
|
// FmtFlowSchema produces a golang source expression of the value.
|
||||||
func FmtFlowSchema(fs *fcv1a1.FlowSchema) string {
|
func FmtFlowSchema(fs *flowcontrol.FlowSchema) string {
|
||||||
if fs == nil {
|
if fs == nil {
|
||||||
return "nil"
|
return "nil"
|
||||||
}
|
}
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
buf.WriteString(fmt.Sprintf("&v1alpha1.FlowSchema{ObjectMeta: %#+v, Spec: ",
|
buf.WriteString(fmt.Sprintf("&flowcontrolv1beta1.FlowSchema{ObjectMeta: %#+v, Spec: ",
|
||||||
fs.ObjectMeta))
|
fs.ObjectMeta))
|
||||||
BufferFlowSchemaSpec(&buf, &fs.Spec)
|
BufferFlowSchemaSpec(&buf, &fs.Spec)
|
||||||
buf.WriteString(fmt.Sprintf(", Status: %#+v}", fs.Status))
|
buf.WriteString(fmt.Sprintf(", Status: %#+v}", fs.Status))
|
||||||
|
|
@ -137,7 +137,7 @@ func FmtFlowSchema(fs *fcv1a1.FlowSchema) string {
|
||||||
|
|
||||||
// FmtFlowSchemaSpec produces a golang source expression equivalent to
|
// FmtFlowSchemaSpec produces a golang source expression equivalent to
|
||||||
// the given spec
|
// the given spec
|
||||||
func FmtFlowSchemaSpec(fsSpec *fcv1a1.FlowSchemaSpec) string {
|
func FmtFlowSchemaSpec(fsSpec *flowcontrol.FlowSchemaSpec) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
BufferFlowSchemaSpec(&buf, fsSpec)
|
BufferFlowSchemaSpec(&buf, fsSpec)
|
||||||
return buf.String()
|
return buf.String()
|
||||||
|
|
@ -145,8 +145,8 @@ func FmtFlowSchemaSpec(fsSpec *fcv1a1.FlowSchemaSpec) string {
|
||||||
|
|
||||||
// BufferFlowSchemaSpec writes a golang source expression for the
|
// BufferFlowSchemaSpec writes a golang source expression for the
|
||||||
// given value to the given buffer
|
// given value to the given buffer
|
||||||
func BufferFlowSchemaSpec(buf *bytes.Buffer, fsSpec *fcv1a1.FlowSchemaSpec) {
|
func BufferFlowSchemaSpec(buf *bytes.Buffer, fsSpec *flowcontrol.FlowSchemaSpec) {
|
||||||
buf.WriteString(fmt.Sprintf("v1alpha1.FlowSchemaSpec{PriorityLevelConfiguration: %#+v, MatchingPrecedence: %d, DistinguisherMethod: ",
|
buf.WriteString(fmt.Sprintf("flowcontrolv1beta1.FlowSchemaSpec{PriorityLevelConfiguration: %#+v, MatchingPrecedence: %d, DistinguisherMethod: ",
|
||||||
fsSpec.PriorityLevelConfiguration,
|
fsSpec.PriorityLevelConfiguration,
|
||||||
fsSpec.MatchingPrecedence))
|
fsSpec.MatchingPrecedence))
|
||||||
if fsSpec.DistinguisherMethod == nil {
|
if fsSpec.DistinguisherMethod == nil {
|
||||||
|
|
@ -154,7 +154,7 @@ func BufferFlowSchemaSpec(buf *bytes.Buffer, fsSpec *fcv1a1.FlowSchemaSpec) {
|
||||||
} else {
|
} else {
|
||||||
buf.WriteString(fmt.Sprintf("&%#+v", *fsSpec.DistinguisherMethod))
|
buf.WriteString(fmt.Sprintf("&%#+v", *fsSpec.DistinguisherMethod))
|
||||||
}
|
}
|
||||||
buf.WriteString(", Rules: []v1alpha1.PolicyRulesWithSubjects{")
|
buf.WriteString(", Rules: []flowcontrol.PolicyRulesWithSubjects{")
|
||||||
for idx, rule := range fsSpec.Rules {
|
for idx, rule := range fsSpec.Rules {
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
buf.WriteString(", ")
|
buf.WriteString(", ")
|
||||||
|
|
@ -165,14 +165,14 @@ func BufferFlowSchemaSpec(buf *bytes.Buffer, fsSpec *fcv1a1.FlowSchemaSpec) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FmtPolicyRulesWithSubjects produces a golang source expression of the value.
|
// FmtPolicyRulesWithSubjects produces a golang source expression of the value.
|
||||||
func FmtPolicyRulesWithSubjects(rule fcv1a1.PolicyRulesWithSubjects) string {
|
func FmtPolicyRulesWithSubjects(rule flowcontrol.PolicyRulesWithSubjects) string {
|
||||||
return "v1alpha1.PolicyRulesWithSubjects" + FmtPolicyRulesWithSubjectsSlim(rule)
|
return "flowcontrolv1beta1.PolicyRulesWithSubjects" + FmtPolicyRulesWithSubjectsSlim(rule)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FmtPolicyRulesWithSubjectsSlim produces a golang source expression
|
// FmtPolicyRulesWithSubjectsSlim produces a golang source expression
|
||||||
// of the value but without the leading type name. See above for an
|
// of the value but without the leading type name. See above for an
|
||||||
// example context where this is useful.
|
// example context where this is useful.
|
||||||
func FmtPolicyRulesWithSubjectsSlim(rule fcv1a1.PolicyRulesWithSubjects) string {
|
func FmtPolicyRulesWithSubjectsSlim(rule flowcontrol.PolicyRulesWithSubjects) string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
BufferFmtPolicyRulesWithSubjectsSlim(&buf, rule)
|
BufferFmtPolicyRulesWithSubjectsSlim(&buf, rule)
|
||||||
return buf.String()
|
return buf.String()
|
||||||
|
|
@ -181,8 +181,8 @@ func FmtPolicyRulesWithSubjectsSlim(rule fcv1a1.PolicyRulesWithSubjects) string
|
||||||
// BufferFmtPolicyRulesWithSubjectsSlim writes a golang source
|
// BufferFmtPolicyRulesWithSubjectsSlim writes a golang source
|
||||||
// expression for the given value to the given buffer but excludes the
|
// expression for the given value to the given buffer but excludes the
|
||||||
// leading type name
|
// leading type name
|
||||||
func BufferFmtPolicyRulesWithSubjectsSlim(buf *bytes.Buffer, rule fcv1a1.PolicyRulesWithSubjects) {
|
func BufferFmtPolicyRulesWithSubjectsSlim(buf *bytes.Buffer, rule flowcontrol.PolicyRulesWithSubjects) {
|
||||||
buf.WriteString("{Subjects: []v1alpha1.Subject{")
|
buf.WriteString("{Subjects: []flowcontrolv1beta1.Subject{")
|
||||||
for jdx, subj := range rule.Subjects {
|
for jdx, subj := range rule.Subjects {
|
||||||
if jdx > 0 {
|
if jdx > 0 {
|
||||||
buf.WriteString(", ")
|
buf.WriteString(", ")
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
fcv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
|
fcboot "k8s.io/apiserver/pkg/apis/flowcontrol/bootstrap"
|
||||||
|
|
@ -39,19 +39,19 @@ var noRestraintQSF = fqtesting.NewNoRestraintFactory()
|
||||||
// genPL creates a valid PriorityLevelConfiguration with the given
|
// genPL creates a valid PriorityLevelConfiguration with the given
|
||||||
// name and randomly generated spec. The given name must not be one
|
// name and randomly generated spec. The given name must not be one
|
||||||
// of the mandatory ones.
|
// of the mandatory ones.
|
||||||
func genPL(rng *rand.Rand, name string) *fcv1a1.PriorityLevelConfiguration {
|
func genPL(rng *rand.Rand, name string) *flowcontrol.PriorityLevelConfiguration {
|
||||||
plc := &fcv1a1.PriorityLevelConfiguration{
|
plc := &flowcontrol.PriorityLevelConfiguration{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||||
Spec: fcv1a1.PriorityLevelConfigurationSpec{
|
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||||
Type: fcv1a1.PriorityLevelEnablementLimited,
|
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||||
Limited: &fcv1a1.LimitedPriorityLevelConfiguration{
|
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||||
AssuredConcurrencyShares: rng.Int31n(100) + 1,
|
AssuredConcurrencyShares: rng.Int31n(100) + 1,
|
||||||
LimitResponse: fcv1a1.LimitResponse{
|
LimitResponse: flowcontrol.LimitResponse{
|
||||||
Type: fcv1a1.LimitResponseTypeReject}}}}
|
Type: flowcontrol.LimitResponseTypeReject}}}}
|
||||||
if rng.Float32() < 0.95 {
|
if rng.Float32() < 0.95 {
|
||||||
plc.Spec.Limited.LimitResponse.Type = fcv1a1.LimitResponseTypeQueue
|
plc.Spec.Limited.LimitResponse.Type = flowcontrol.LimitResponseTypeQueue
|
||||||
hs := rng.Int31n(5) + 1
|
hs := rng.Int31n(5) + 1
|
||||||
plc.Spec.Limited.LimitResponse.Queuing = &fcv1a1.QueuingConfiguration{
|
plc.Spec.Limited.LimitResponse.Queuing = &flowcontrol.QueuingConfiguration{
|
||||||
Queues: hs + rng.Int31n(20),
|
Queues: hs + rng.Int31n(20),
|
||||||
HandSize: hs,
|
HandSize: hs,
|
||||||
QueueLengthLimit: 5}
|
QueueLengthLimit: 5}
|
||||||
|
|
@ -65,7 +65,7 @@ func genPL(rng *rand.Rand, name string) *fcv1a1.PriorityLevelConfiguration {
|
||||||
|
|
||||||
// A FlowSchema together with characteristics relevant to testing
|
// A FlowSchema together with characteristics relevant to testing
|
||||||
type fsTestingRecord struct {
|
type fsTestingRecord struct {
|
||||||
fs *fcv1a1.FlowSchema
|
fs *flowcontrol.FlowSchema
|
||||||
// Does this reference an existing priority level?
|
// Does this reference an existing priority level?
|
||||||
wellFormed bool
|
wellFormed bool
|
||||||
matchesAllResourceRequests bool
|
matchesAllResourceRequests bool
|
||||||
|
|
@ -85,8 +85,8 @@ func (ftr *fsTestingRecord) addDigests(digests []RequestDigest, matches bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var flowDistinguisherMethodTypes = sets.NewString(
|
var flowDistinguisherMethodTypes = sets.NewString(
|
||||||
string(fcv1a1.FlowDistinguisherMethodByUserType),
|
string(flowcontrol.FlowDistinguisherMethodByUserType),
|
||||||
string(fcv1a1.FlowDistinguisherMethodByNamespaceType),
|
string(flowcontrol.FlowDistinguisherMethodByNamespaceType),
|
||||||
)
|
)
|
||||||
|
|
||||||
var mandFTRExempt = &fsTestingRecord{
|
var mandFTRExempt = &fsTestingRecord{
|
||||||
|
|
@ -189,9 +189,9 @@ var mandFTRCatchAll = &fsTestingRecord{
|
||||||
// formed spec references a priority level drawn from badPLNames.
|
// formed spec references a priority level drawn from badPLNames.
|
||||||
// goodPLNames may be empty, but badPLNames may not.
|
// goodPLNames may be empty, but badPLNames may not.
|
||||||
func genFS(t *testing.T, rng *rand.Rand, name string, mayMatchClusterScope bool, goodPLNames, badPLNames sets.String) *fsTestingRecord {
|
func genFS(t *testing.T, rng *rand.Rand, name string, mayMatchClusterScope bool, goodPLNames, badPLNames sets.String) *fsTestingRecord {
|
||||||
fs := &fcv1a1.FlowSchema{
|
fs := &flowcontrol.FlowSchema{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: name},
|
ObjectMeta: metav1.ObjectMeta{Name: name},
|
||||||
Spec: fcv1a1.FlowSchemaSpec{}}
|
Spec: flowcontrol.FlowSchemaSpec{}}
|
||||||
// 5% chance of zero rules, otherwise draw from 1--6 biased low
|
// 5% chance of zero rules, otherwise draw from 1--6 biased low
|
||||||
nRules := (1 + rng.Intn(3)) * (1 + rng.Intn(2)) * ((19 + rng.Intn(20)) / 20)
|
nRules := (1 + rng.Intn(3)) * (1 + rng.Intn(2)) * ((19 + rng.Intn(20)) / 20)
|
||||||
ftr := &fsTestingRecord{fs: fs,
|
ftr := &fsTestingRecord{fs: fs,
|
||||||
|
|
@ -202,23 +202,23 @@ func genFS(t *testing.T, rng *rand.Rand, name string, mayMatchClusterScope bool,
|
||||||
false: {false: {}, true: {}},
|
false: {false: {}, true: {}},
|
||||||
true: {false: {}, true: {}}},
|
true: {false: {}, true: {}}},
|
||||||
}
|
}
|
||||||
dangleStatus := fcv1a1.ConditionFalse
|
dangleStatus := flowcontrol.ConditionFalse
|
||||||
if rng.Float32() < 0.9 && len(goodPLNames) > 0 {
|
if rng.Float32() < 0.9 && len(goodPLNames) > 0 {
|
||||||
fs.Spec.PriorityLevelConfiguration = fcv1a1.PriorityLevelConfigurationReference{pickSetString(rng, goodPLNames)}
|
fs.Spec.PriorityLevelConfiguration = flowcontrol.PriorityLevelConfigurationReference{pickSetString(rng, goodPLNames)}
|
||||||
} else {
|
} else {
|
||||||
fs.Spec.PriorityLevelConfiguration = fcv1a1.PriorityLevelConfigurationReference{pickSetString(rng, badPLNames)}
|
fs.Spec.PriorityLevelConfiguration = flowcontrol.PriorityLevelConfigurationReference{pickSetString(rng, badPLNames)}
|
||||||
ftr.wellFormed = false
|
ftr.wellFormed = false
|
||||||
dangleStatus = fcv1a1.ConditionTrue
|
dangleStatus = flowcontrol.ConditionTrue
|
||||||
}
|
}
|
||||||
fs.Status.Conditions = []fcv1a1.FlowSchemaCondition{{
|
fs.Status.Conditions = []flowcontrol.FlowSchemaCondition{{
|
||||||
Type: fcv1a1.FlowSchemaConditionDangling,
|
Type: flowcontrol.FlowSchemaConditionDangling,
|
||||||
Status: dangleStatus}}
|
Status: dangleStatus}}
|
||||||
fs.Spec.MatchingPrecedence = rng.Int31n(9997) + 2
|
fs.Spec.MatchingPrecedence = rng.Int31n(9997) + 2
|
||||||
if rng.Float32() < 0.8 {
|
if rng.Float32() < 0.8 {
|
||||||
fdmt := fcv1a1.FlowDistinguisherMethodType(pickSetString(rng, flowDistinguisherMethodTypes))
|
fdmt := flowcontrol.FlowDistinguisherMethodType(pickSetString(rng, flowDistinguisherMethodTypes))
|
||||||
fs.Spec.DistinguisherMethod = &fcv1a1.FlowDistinguisherMethod{fdmt}
|
fs.Spec.DistinguisherMethod = &flowcontrol.FlowDistinguisherMethod{fdmt}
|
||||||
}
|
}
|
||||||
fs.Spec.Rules = []fcv1a1.PolicyRulesWithSubjects{}
|
fs.Spec.Rules = []flowcontrol.PolicyRulesWithSubjects{}
|
||||||
everyResourceMatcher := -1
|
everyResourceMatcher := -1
|
||||||
if ftr.matchesAllResourceRequests {
|
if ftr.matchesAllResourceRequests {
|
||||||
if mayMatchClusterScope {
|
if mayMatchClusterScope {
|
||||||
|
|
@ -275,12 +275,12 @@ var noextra = make(map[string][]string)
|
||||||
// cluster-scoped request. Thus, these are normally excluded. When
|
// cluster-scoped request. Thus, these are normally excluded. When
|
||||||
// mayMatchClusterScope==true the generated rule may be cluster-scoped
|
// mayMatchClusterScope==true the generated rule may be cluster-scoped
|
||||||
// and there is no promise of cross-rule exclusion.
|
// and there is no promise of cross-rule exclusion.
|
||||||
func genPolicyRuleWithSubjects(t *testing.T, rng *rand.Rand, pfx string, mayMatchClusterScope, someMatchesAllResourceRequests, someMatchesAllNonResourceRequests, matchAllResourceRequests, matchAllNonResourceRequests bool) (fcv1a1.PolicyRulesWithSubjects, []RequestDigest, []RequestDigest, []RequestDigest, []RequestDigest) {
|
func genPolicyRuleWithSubjects(t *testing.T, rng *rand.Rand, pfx string, mayMatchClusterScope, someMatchesAllResourceRequests, someMatchesAllNonResourceRequests, matchAllResourceRequests, matchAllNonResourceRequests bool) (flowcontrol.PolicyRulesWithSubjects, []RequestDigest, []RequestDigest, []RequestDigest, []RequestDigest) {
|
||||||
subjects := []fcv1a1.Subject{}
|
subjects := []flowcontrol.Subject{}
|
||||||
matchingUIs := []user.Info{}
|
matchingUIs := []user.Info{}
|
||||||
skippingUIs := []user.Info{}
|
skippingUIs := []user.Info{}
|
||||||
resourceRules := []fcv1a1.ResourcePolicyRule{}
|
resourceRules := []flowcontrol.ResourcePolicyRule{}
|
||||||
nonResourceRules := []fcv1a1.NonResourcePolicyRule{}
|
nonResourceRules := []flowcontrol.NonResourcePolicyRule{}
|
||||||
matchingRRIs := []*request.RequestInfo{}
|
matchingRRIs := []*request.RequestInfo{}
|
||||||
skippingRRIs := []*request.RequestInfo{}
|
skippingRRIs := []*request.RequestInfo{}
|
||||||
matchingNRIs := []*request.RequestInfo{}
|
matchingNRIs := []*request.RequestInfo{}
|
||||||
|
|
@ -341,7 +341,7 @@ func genPolicyRuleWithSubjects(t *testing.T, rng *rand.Rand, pfx string, mayMatc
|
||||||
if nRR == 0 {
|
if nRR == 0 {
|
||||||
_, _, skippingNRIs = genNonResourceRule(rng, pfx+"-o", false, someMatchesAllNonResourceRequests)
|
_, _, skippingNRIs = genNonResourceRule(rng, pfx+"-o", false, someMatchesAllNonResourceRequests)
|
||||||
}
|
}
|
||||||
rule := fcv1a1.PolicyRulesWithSubjects{subjects, resourceRules, nonResourceRules}
|
rule := flowcontrol.PolicyRulesWithSubjects{subjects, resourceRules, nonResourceRules}
|
||||||
t.Logf("For pfx=%s, mayMatchClusterScope=%v, someMatchesAllResourceRequests=%v, someMatchesAllNonResourceRequests=%v, marr=%v, manrr=%v: generated prws=%s, mu=%s, su=%s, mrr=%s, mnr=%s, srr=%s, snr=%s", pfx, mayMatchClusterScope, someMatchesAllResourceRequests, someMatchesAllNonResourceRequests, matchAllResourceRequests, matchAllNonResourceRequests, fcfmt.Fmt(rule), fcfmt.Fmt(matchingUIs), fcfmt.Fmt(skippingUIs), fcfmt.Fmt(matchingRRIs), fcfmt.Fmt(matchingNRIs), fcfmt.Fmt(skippingRRIs), fcfmt.Fmt(skippingNRIs))
|
t.Logf("For pfx=%s, mayMatchClusterScope=%v, someMatchesAllResourceRequests=%v, someMatchesAllNonResourceRequests=%v, marr=%v, manrr=%v: generated prws=%s, mu=%s, su=%s, mrr=%s, mnr=%s, srr=%s, snr=%s", pfx, mayMatchClusterScope, someMatchesAllResourceRequests, someMatchesAllNonResourceRequests, matchAllResourceRequests, matchAllNonResourceRequests, fcfmt.Fmt(rule), fcfmt.Fmt(matchingUIs), fcfmt.Fmt(skippingUIs), fcfmt.Fmt(matchingRRIs), fcfmt.Fmt(matchingNRIs), fcfmt.Fmt(skippingRRIs), fcfmt.Fmt(skippingNRIs))
|
||||||
matchingRDigests := cross(matchingUIs, matchingRRIs)
|
matchingRDigests := cross(matchingUIs, matchingRRIs)
|
||||||
skippingRDigests := append(append(cross(matchingUIs, skippingRRIs),
|
skippingRDigests := append(append(cross(matchingUIs, skippingRRIs),
|
||||||
|
|
@ -368,7 +368,7 @@ func cross(uis []user.Info, ris []*request.RequestInfo) []RequestDigest {
|
||||||
return ans
|
return ans
|
||||||
}
|
}
|
||||||
|
|
||||||
func shuffleAndTakeDigests(t *testing.T, rng *rand.Rand, rule *fcv1a1.PolicyRulesWithSubjects, toMatch bool, digests []RequestDigest, n int) []RequestDigest {
|
func shuffleAndTakeDigests(t *testing.T, rng *rand.Rand, rule *flowcontrol.PolicyRulesWithSubjects, toMatch bool, digests []RequestDigest, n int) []RequestDigest {
|
||||||
ans := make([]RequestDigest, 0, n)
|
ans := make([]RequestDigest, 0, n)
|
||||||
for len(ans) < n && len(digests) > 0 {
|
for len(ans) < n && len(digests) > 0 {
|
||||||
i := rng.Intn(len(digests))
|
i := rng.Intn(len(digests))
|
||||||
|
|
@ -409,25 +409,25 @@ func uniqify(in RequestDigest) RequestDigest {
|
||||||
// names that begin with the given prefix. The second returned list
|
// names that begin with the given prefix. The second returned list
|
||||||
// contains members that mismatch the generated Subject and involve
|
// contains members that mismatch the generated Subject and involve
|
||||||
// names that begin with the given prefix.
|
// names that begin with the given prefix.
|
||||||
func genSubject(rng *rand.Rand, pfx string) (fcv1a1.Subject, []user.Info, []user.Info) {
|
func genSubject(rng *rand.Rand, pfx string) (flowcontrol.Subject, []user.Info, []user.Info) {
|
||||||
subject := fcv1a1.Subject{}
|
subject := flowcontrol.Subject{}
|
||||||
var matchingUIs, skippingUIs []user.Info
|
var matchingUIs, skippingUIs []user.Info
|
||||||
x := rng.Float32()
|
x := rng.Float32()
|
||||||
switch {
|
switch {
|
||||||
case x < 0.33:
|
case x < 0.33:
|
||||||
subject.Kind = fcv1a1.SubjectKindUser
|
subject.Kind = flowcontrol.SubjectKindUser
|
||||||
subject.User, matchingUIs, skippingUIs = genUser(rng, pfx)
|
subject.User, matchingUIs, skippingUIs = genUser(rng, pfx)
|
||||||
case x < 0.67:
|
case x < 0.67:
|
||||||
subject.Kind = fcv1a1.SubjectKindGroup
|
subject.Kind = flowcontrol.SubjectKindGroup
|
||||||
subject.Group, matchingUIs, skippingUIs = genGroup(rng, pfx)
|
subject.Group, matchingUIs, skippingUIs = genGroup(rng, pfx)
|
||||||
default:
|
default:
|
||||||
subject.Kind = fcv1a1.SubjectKindServiceAccount
|
subject.Kind = flowcontrol.SubjectKindServiceAccount
|
||||||
subject.ServiceAccount, matchingUIs, skippingUIs = genServiceAccount(rng, pfx)
|
subject.ServiceAccount, matchingUIs, skippingUIs = genServiceAccount(rng, pfx)
|
||||||
}
|
}
|
||||||
return subject, matchingUIs, skippingUIs
|
return subject, matchingUIs, skippingUIs
|
||||||
}
|
}
|
||||||
|
|
||||||
func genUser(rng *rand.Rand, pfx string) (*fcv1a1.UserSubject, []user.Info, []user.Info) {
|
func genUser(rng *rand.Rand, pfx string) (*flowcontrol.UserSubject, []user.Info, []user.Info) {
|
||||||
mui := &user.DefaultInfo{
|
mui := &user.DefaultInfo{
|
||||||
Name: pfx + "-u",
|
Name: pfx + "-u",
|
||||||
UID: "good-id",
|
UID: "good-id",
|
||||||
|
|
@ -438,7 +438,7 @@ func genUser(rng *rand.Rand, pfx string) (*fcv1a1.UserSubject, []user.Info, []us
|
||||||
UID: mui.UID,
|
UID: mui.UID,
|
||||||
Groups: mui.Groups,
|
Groups: mui.Groups,
|
||||||
Extra: mui.Extra}}
|
Extra: mui.Extra}}
|
||||||
return &fcv1a1.UserSubject{mui.Name}, []user.Info{mui}, skips
|
return &flowcontrol.UserSubject{mui.Name}, []user.Info{mui}, skips
|
||||||
}
|
}
|
||||||
|
|
||||||
var groupCover = []string{"system:authenticated", "system:unauthenticated"}
|
var groupCover = []string{"system:authenticated", "system:unauthenticated"}
|
||||||
|
|
@ -447,21 +447,21 @@ func mg(rng *rand.Rand) string {
|
||||||
return groupCover[rng.Intn(len(groupCover))]
|
return groupCover[rng.Intn(len(groupCover))]
|
||||||
}
|
}
|
||||||
|
|
||||||
func mkUserSubject(username string) fcv1a1.Subject {
|
func mkUserSubject(username string) flowcontrol.Subject {
|
||||||
return fcv1a1.Subject{
|
return flowcontrol.Subject{
|
||||||
Kind: fcv1a1.SubjectKindUser,
|
Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{username},
|
User: &flowcontrol.UserSubject{username},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mkGroupSubject(group string) fcv1a1.Subject {
|
func mkGroupSubject(group string) flowcontrol.Subject {
|
||||||
return fcv1a1.Subject{
|
return flowcontrol.Subject{
|
||||||
Kind: fcv1a1.SubjectKindGroup,
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
Group: &fcv1a1.GroupSubject{group},
|
Group: &flowcontrol.GroupSubject{group},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genGroup(rng *rand.Rand, pfx string) (*fcv1a1.GroupSubject, []user.Info, []user.Info) {
|
func genGroup(rng *rand.Rand, pfx string) (*flowcontrol.GroupSubject, []user.Info, []user.Info) {
|
||||||
name := pfx + "-g"
|
name := pfx + "-g"
|
||||||
ui := &user.DefaultInfo{
|
ui := &user.DefaultInfo{
|
||||||
Name: pfx + "-u",
|
Name: pfx + "-u",
|
||||||
|
|
@ -487,10 +487,10 @@ func genGroup(rng *rand.Rand, pfx string) (*fcv1a1.GroupSubject, []user.Info, []
|
||||||
if rng.Intn(2) == 0 {
|
if rng.Intn(2) == 0 {
|
||||||
skipper.Groups = append(skipper.Groups, pfx+"-k")
|
skipper.Groups = append(skipper.Groups, pfx+"-k")
|
||||||
}
|
}
|
||||||
return &fcv1a1.GroupSubject{name}, []user.Info{ui}, []user.Info{skipper}
|
return &flowcontrol.GroupSubject{name}, []user.Info{ui}, []user.Info{skipper}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genServiceAccount(rng *rand.Rand, pfx string) (*fcv1a1.ServiceAccountSubject, []user.Info, []user.Info) {
|
func genServiceAccount(rng *rand.Rand, pfx string) (*flowcontrol.ServiceAccountSubject, []user.Info, []user.Info) {
|
||||||
ns := pfx + "-ns"
|
ns := pfx + "-ns"
|
||||||
name := pfx + "-n"
|
name := pfx + "-n"
|
||||||
mname := name
|
mname := name
|
||||||
|
|
@ -516,19 +516,19 @@ func genServiceAccount(rng *rand.Rand, pfx string) (*fcv1a1.ServiceAccountSubjec
|
||||||
Groups: mui.Groups,
|
Groups: mui.Groups,
|
||||||
Extra: mui.Extra}}
|
Extra: mui.Extra}}
|
||||||
}
|
}
|
||||||
return &fcv1a1.ServiceAccountSubject{Namespace: ns, Name: mname}, []user.Info{mui}, skips
|
return &flowcontrol.ServiceAccountSubject{Namespace: ns, Name: mname}, []user.Info{mui}, skips
|
||||||
}
|
}
|
||||||
|
|
||||||
// genResourceRule randomly generates a valid ResourcePolicyRule and lists
|
// genResourceRule randomly generates a valid ResourcePolicyRule and lists
|
||||||
// of matching and non-matching `*request.RequestInfo`.
|
// of matching and non-matching `*request.RequestInfo`.
|
||||||
func genResourceRule(rng *rand.Rand, pfx string, mayMatchClusterScope, matchAllResources, someMatchesAllResources bool) (fcv1a1.ResourcePolicyRule, []*request.RequestInfo, []*request.RequestInfo) {
|
func genResourceRule(rng *rand.Rand, pfx string, mayMatchClusterScope, matchAllResources, someMatchesAllResources bool) (flowcontrol.ResourcePolicyRule, []*request.RequestInfo, []*request.RequestInfo) {
|
||||||
namespaces := []string{pfx + "-n1", pfx + "-n2", pfx + "-n3"}
|
namespaces := []string{pfx + "-n1", pfx + "-n2", pfx + "-n3"}
|
||||||
rnamespaces := namespaces
|
rnamespaces := namespaces
|
||||||
if mayMatchClusterScope && rng.Float32() < 0.1 {
|
if mayMatchClusterScope && rng.Float32() < 0.1 {
|
||||||
namespaces[0] = ""
|
namespaces[0] = ""
|
||||||
rnamespaces = namespaces[1:]
|
rnamespaces = namespaces[1:]
|
||||||
}
|
}
|
||||||
rr := fcv1a1.ResourcePolicyRule{
|
rr := flowcontrol.ResourcePolicyRule{
|
||||||
Verbs: []string{pfx + "-v1", pfx + "-v2", pfx + "-v3"},
|
Verbs: []string{pfx + "-v1", pfx + "-v2", pfx + "-v3"},
|
||||||
APIGroups: []string{pfx + ".g1", pfx + ".g2", pfx + ".g3"},
|
APIGroups: []string{pfx + ".g1", pfx + ".g2", pfx + ".g3"},
|
||||||
Resources: []string{pfx + "-r1s", pfx + "-r2s", pfx + "-r3s"},
|
Resources: []string{pfx + "-r1s", pfx + "-r2s", pfx + "-r3s"},
|
||||||
|
|
@ -550,17 +550,17 @@ func genResourceRule(rng *rand.Rand, pfx string, mayMatchClusterScope, matchAllR
|
||||||
// choose a proper subset of fields to wildcard; only matters if not matching all
|
// choose a proper subset of fields to wildcard; only matters if not matching all
|
||||||
starMask := rng.Intn(15)
|
starMask := rng.Intn(15)
|
||||||
if matchAllResources || starMask&1 == 1 && rng.Float32() < 0.1 {
|
if matchAllResources || starMask&1 == 1 && rng.Float32() < 0.1 {
|
||||||
rr.Verbs = []string{fcv1a1.VerbAll}
|
rr.Verbs = []string{flowcontrol.VerbAll}
|
||||||
}
|
}
|
||||||
if matchAllResources || starMask&2 == 2 && rng.Float32() < 0.1 {
|
if matchAllResources || starMask&2 == 2 && rng.Float32() < 0.1 {
|
||||||
rr.APIGroups = []string{fcv1a1.APIGroupAll}
|
rr.APIGroups = []string{flowcontrol.APIGroupAll}
|
||||||
}
|
}
|
||||||
if matchAllResources || starMask&4 == 4 && rng.Float32() < 0.1 {
|
if matchAllResources || starMask&4 == 4 && rng.Float32() < 0.1 {
|
||||||
rr.Resources = []string{fcv1a1.ResourceAll}
|
rr.Resources = []string{flowcontrol.ResourceAll}
|
||||||
}
|
}
|
||||||
if matchAllResources || starMask&8 == 8 && rng.Float32() < 0.1 {
|
if matchAllResources || starMask&8 == 8 && rng.Float32() < 0.1 {
|
||||||
rr.ClusterScope = true
|
rr.ClusterScope = true
|
||||||
rr.Namespaces = []string{fcv1a1.NamespaceEvery}
|
rr.Namespaces = []string{flowcontrol.NamespaceEvery}
|
||||||
}
|
}
|
||||||
return rr, matchingRIs, skippingRIs
|
return rr, matchingRIs, skippingRIs
|
||||||
}
|
}
|
||||||
|
|
@ -616,8 +616,8 @@ func chooseInts(rng *rand.Rand, n, m int) []int {
|
||||||
// genNonResourceRule returns a randomly generated valid
|
// genNonResourceRule returns a randomly generated valid
|
||||||
// NonResourcePolicyRule and lists of matching and non-matching
|
// NonResourcePolicyRule and lists of matching and non-matching
|
||||||
// `*request.RequestInfo`.
|
// `*request.RequestInfo`.
|
||||||
func genNonResourceRule(rng *rand.Rand, pfx string, matchAllNonResources, someMatchesAllNonResources bool) (fcv1a1.NonResourcePolicyRule, []*request.RequestInfo, []*request.RequestInfo) {
|
func genNonResourceRule(rng *rand.Rand, pfx string, matchAllNonResources, someMatchesAllNonResources bool) (flowcontrol.NonResourcePolicyRule, []*request.RequestInfo, []*request.RequestInfo) {
|
||||||
nrr := fcv1a1.NonResourcePolicyRule{
|
nrr := flowcontrol.NonResourcePolicyRule{
|
||||||
Verbs: []string{pfx + "-v1", pfx + "-v2", pfx + "-v3"},
|
Verbs: []string{pfx + "-v1", pfx + "-v2", pfx + "-v3"},
|
||||||
NonResourceURLs: []string{"/" + pfx + "/g/p1", "/" + pfx + "/g/p2", "/" + pfx + "/g/p3"},
|
NonResourceURLs: []string{"/" + pfx + "/g/p1", "/" + pfx + "/g/p2", "/" + pfx + "/g/p3"},
|
||||||
}
|
}
|
||||||
|
|
@ -631,7 +631,7 @@ func genNonResourceRule(rng *rand.Rand, pfx string, matchAllNonResources, someMa
|
||||||
// choose a proper subset of fields to consider wildcarding; only matters if not matching all
|
// choose a proper subset of fields to consider wildcarding; only matters if not matching all
|
||||||
starMask := rng.Intn(3)
|
starMask := rng.Intn(3)
|
||||||
if matchAllNonResources || starMask&1 == 1 && rng.Float32() < 0.1 {
|
if matchAllNonResources || starMask&1 == 1 && rng.Float32() < 0.1 {
|
||||||
nrr.Verbs = []string{fcv1a1.VerbAll}
|
nrr.Verbs = []string{flowcontrol.VerbAll}
|
||||||
}
|
}
|
||||||
if matchAllNonResources || starMask&2 == 2 && rng.Float32() < 0.1 {
|
if matchAllNonResources || starMask&2 == 2 && rng.Float32() < 0.1 {
|
||||||
nrr.NonResourceURLs = []string{"*"}
|
nrr.NonResourceURLs = []string{"*"}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
fcv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
|
|
@ -116,204 +116,204 @@ func TestLiterals(t *testing.T) {
|
||||||
Path: "/openapi/v2",
|
Path: "/openapi/v2",
|
||||||
Verb: "goodverb"},
|
Verb: "goodverb"},
|
||||||
ui}
|
ui}
|
||||||
checkRules(t, true, reqRN, []fcv1a1.PolicyRulesWithSubjects{{
|
checkRules(t, true, reqRN, []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindGroup,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindGroup,
|
||||||
Group: &fcv1a1.GroupSubject{"goodg1"}}},
|
Group: &flowcontrol.GroupSubject{"goodg1"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"*"}}},
|
User: &flowcontrol.UserSubject{"*"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindGroup,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindGroup,
|
||||||
Group: &fcv1a1.GroupSubject{"*"}}},
|
Group: &flowcontrol.GroupSubject{"*"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"*"},
|
Verbs: []string{"*"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"*"},
|
APIGroups: []string{"*"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"*"},
|
Resources: []string{"*"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"*"}}}},
|
Namespaces: []string{"*"}}}},
|
||||||
})
|
})
|
||||||
checkRules(t, false, reqRN, []fcv1a1.PolicyRulesWithSubjects{{
|
checkRules(t, false, reqRN, []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"badu"}}},
|
User: &flowcontrol.UserSubject{"badu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindGroup,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindGroup,
|
||||||
Group: &fcv1a1.GroupSubject{"badg"}}},
|
Group: &flowcontrol.GroupSubject{"badg"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"badverb"},
|
Verbs: []string{"badverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"badapig"},
|
APIGroups: []string{"badapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"badrscs"},
|
Resources: []string{"badrscs"},
|
||||||
Namespaces: []string{"goodns"}}}}, {
|
Namespaces: []string{"goodns"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
Namespaces: []string{"badns"}}}},
|
Namespaces: []string{"badns"}}}},
|
||||||
})
|
})
|
||||||
checkRules(t, true, reqRU, []fcv1a1.PolicyRulesWithSubjects{{
|
checkRules(t, true, reqRU, []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
ClusterScope: true}}}, {
|
ClusterScope: true}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"*"},
|
Verbs: []string{"*"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
ClusterScope: true}}}, {
|
ClusterScope: true}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"*"},
|
APIGroups: []string{"*"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
ClusterScope: true}}}, {
|
ClusterScope: true}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"*"},
|
Resources: []string{"*"},
|
||||||
ClusterScope: true}}}})
|
ClusterScope: true}}}})
|
||||||
checkRules(t, false, reqRU, []fcv1a1.PolicyRulesWithSubjects{{
|
checkRules(t, false, reqRU, []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"badverb"},
|
Verbs: []string{"badverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
ClusterScope: true}}}, {
|
ClusterScope: true}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"badapig"},
|
APIGroups: []string{"badapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
ClusterScope: true}}}, {
|
ClusterScope: true}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"badrscs"},
|
Resources: []string{"badrscs"},
|
||||||
ClusterScope: true}}}, {
|
ClusterScope: true}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
ResourceRules: []fcv1a1.ResourcePolicyRule{{
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
APIGroups: []string{"goodapig"},
|
APIGroups: []string{"goodapig"},
|
||||||
Resources: []string{"goodrscs"},
|
Resources: []string{"goodrscs"},
|
||||||
ClusterScope: false}}},
|
ClusterScope: false}}},
|
||||||
})
|
})
|
||||||
checkRules(t, true, reqN, []fcv1a1.PolicyRulesWithSubjects{{
|
checkRules(t, true, reqN, []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
NonResourceRules: []fcv1a1.NonResourcePolicyRule{{
|
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
NonResourceURLs: []string{"/openapi/v2"}}}}, {
|
NonResourceURLs: []string{"/openapi/v2"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
NonResourceRules: []fcv1a1.NonResourcePolicyRule{{
|
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
|
||||||
Verbs: []string{"*"},
|
Verbs: []string{"*"},
|
||||||
NonResourceURLs: []string{"/openapi/v2"}}}}, {
|
NonResourceURLs: []string{"/openapi/v2"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
NonResourceRules: []fcv1a1.NonResourcePolicyRule{{
|
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
NonResourceURLs: []string{"*"}}}},
|
NonResourceURLs: []string{"*"}}}},
|
||||||
})
|
})
|
||||||
checkRules(t, false, reqN, []fcv1a1.PolicyRulesWithSubjects{{
|
checkRules(t, false, reqN, []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
NonResourceRules: []fcv1a1.NonResourcePolicyRule{{
|
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
|
||||||
Verbs: []string{"badverb"},
|
Verbs: []string{"badverb"},
|
||||||
NonResourceURLs: []string{"/openapi/v2"}}}}, {
|
NonResourceURLs: []string{"/openapi/v2"}}}}, {
|
||||||
Subjects: []fcv1a1.Subject{{Kind: fcv1a1.SubjectKindUser,
|
Subjects: []flowcontrol.Subject{{Kind: flowcontrol.SubjectKindUser,
|
||||||
User: &fcv1a1.UserSubject{"goodu"}}},
|
User: &flowcontrol.UserSubject{"goodu"}}},
|
||||||
NonResourceRules: []fcv1a1.NonResourcePolicyRule{{
|
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
|
||||||
Verbs: []string{"goodverb"},
|
Verbs: []string{"goodverb"},
|
||||||
NonResourceURLs: []string{"/closedapi/v2"}}}},
|
NonResourceURLs: []string{"/closedapi/v2"}}}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkRules(t *testing.T, expectMatch bool, digest RequestDigest, rules []fcv1a1.PolicyRulesWithSubjects) {
|
func checkRules(t *testing.T, expectMatch bool, digest RequestDigest, rules []flowcontrol.PolicyRulesWithSubjects) {
|
||||||
for idx, rule := range rules {
|
for idx, rule := range rules {
|
||||||
fs := &fcv1a1.FlowSchema{
|
fs := &flowcontrol.FlowSchema{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("rule%d", idx)},
|
ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("rule%d", idx)},
|
||||||
Spec: fcv1a1.FlowSchemaSpec{
|
Spec: flowcontrol.FlowSchemaSpec{
|
||||||
Rules: []fcv1a1.PolicyRulesWithSubjects{rule}}}
|
Rules: []flowcontrol.PolicyRulesWithSubjects{rule}}}
|
||||||
actualMatch := matchesFlowSchema(digest, fs)
|
actualMatch := matchesFlowSchema(digest, fs)
|
||||||
if expectMatch != actualMatch {
|
if expectMatch != actualMatch {
|
||||||
t.Errorf("expectMatch=%v, actualMatch=%v, digest=%#+v, fs=%s", expectMatch, actualMatch, digest, fcfmt.Fmt(fs))
|
t.Errorf("expectMatch=%v, actualMatch=%v, digest=%#+v, fs=%s", expectMatch, actualMatch, digest, fcfmt.Fmt(fs))
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ package flowcontrol
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
fctypesv1a1 "k8s.io/api/flowcontrol/v1alpha1"
|
flowcontrol "k8s.io/api/flowcontrol/v1beta1"
|
||||||
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
"k8s.io/apiserver/pkg/endpoints/request"
|
"k8s.io/apiserver/pkg/endpoints/request"
|
||||||
|
|
@ -27,7 +27,7 @@ import (
|
||||||
|
|
||||||
// Tests whether a given request and FlowSchema match. Nobody mutates
|
// Tests whether a given request and FlowSchema match. Nobody mutates
|
||||||
// either input.
|
// either input.
|
||||||
func matchesFlowSchema(digest RequestDigest, flowSchema *fctypesv1a1.FlowSchema) bool {
|
func matchesFlowSchema(digest RequestDigest, flowSchema *flowcontrol.FlowSchema) bool {
|
||||||
for _, policyRule := range flowSchema.Spec.Rules {
|
for _, policyRule := range flowSchema.Spec.Rules {
|
||||||
if matchesPolicyRule(digest, &policyRule) {
|
if matchesPolicyRule(digest, &policyRule) {
|
||||||
return true
|
return true
|
||||||
|
|
@ -36,7 +36,7 @@ func matchesFlowSchema(digest RequestDigest, flowSchema *fctypesv1a1.FlowSchema)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesPolicyRule(digest RequestDigest, policyRule *fctypesv1a1.PolicyRulesWithSubjects) bool {
|
func matchesPolicyRule(digest RequestDigest, policyRule *flowcontrol.PolicyRulesWithSubjects) bool {
|
||||||
if !matchesASubject(digest.User, policyRule.Subjects) {
|
if !matchesASubject(digest.User, policyRule.Subjects) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,7 @@ func matchesPolicyRule(digest RequestDigest, policyRule *fctypesv1a1.PolicyRules
|
||||||
return matchesANonResourceRule(digest.RequestInfo, policyRule.NonResourceRules)
|
return matchesANonResourceRule(digest.RequestInfo, policyRule.NonResourceRules)
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesASubject(user user.Info, subjects []fctypesv1a1.Subject) bool {
|
func matchesASubject(user user.Info, subjects []flowcontrol.Subject) bool {
|
||||||
for _, subject := range subjects {
|
for _, subject := range subjects {
|
||||||
if matchesSubject(user, subject) {
|
if matchesSubject(user, subject) {
|
||||||
return true
|
return true
|
||||||
|
|
@ -55,11 +55,11 @@ func matchesASubject(user user.Info, subjects []fctypesv1a1.Subject) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesSubject(user user.Info, subject fctypesv1a1.Subject) bool {
|
func matchesSubject(user user.Info, subject flowcontrol.Subject) bool {
|
||||||
switch subject.Kind {
|
switch subject.Kind {
|
||||||
case fctypesv1a1.SubjectKindUser:
|
case flowcontrol.SubjectKindUser:
|
||||||
return subject.User != nil && (subject.User.Name == fctypesv1a1.NameAll || subject.User.Name == user.GetName())
|
return subject.User != nil && (subject.User.Name == flowcontrol.NameAll || subject.User.Name == user.GetName())
|
||||||
case fctypesv1a1.SubjectKindGroup:
|
case flowcontrol.SubjectKindGroup:
|
||||||
if subject.Group == nil {
|
if subject.Group == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -73,11 +73,11 @@ func matchesSubject(user user.Info, subject fctypesv1a1.Subject) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
case fctypesv1a1.SubjectKindServiceAccount:
|
case flowcontrol.SubjectKindServiceAccount:
|
||||||
if subject.ServiceAccount == nil {
|
if subject.ServiceAccount == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if subject.ServiceAccount.Name == fctypesv1a1.NameAll {
|
if subject.ServiceAccount.Name == flowcontrol.NameAll {
|
||||||
return serviceAccountMatchesNamespace(subject.ServiceAccount.Namespace, user.GetName())
|
return serviceAccountMatchesNamespace(subject.ServiceAccount.Namespace, user.GetName())
|
||||||
}
|
}
|
||||||
return serviceaccount.MatchesUsername(subject.ServiceAccount.Namespace, subject.ServiceAccount.Name, user.GetName())
|
return serviceaccount.MatchesUsername(subject.ServiceAccount.Namespace, subject.ServiceAccount.Name, user.GetName())
|
||||||
|
|
@ -107,7 +107,7 @@ func serviceAccountMatchesNamespace(namespace string, username string) bool {
|
||||||
return strings.HasPrefix(username, ServiceAccountUsernameSeparator)
|
return strings.HasPrefix(username, ServiceAccountUsernameSeparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesAResourceRule(ri *request.RequestInfo, rules []fctypesv1a1.ResourcePolicyRule) bool {
|
func matchesAResourceRule(ri *request.RequestInfo, rules []flowcontrol.ResourcePolicyRule) bool {
|
||||||
for _, rr := range rules {
|
for _, rr := range rules {
|
||||||
if matchesResourcePolicyRule(ri, rr) {
|
if matchesResourcePolicyRule(ri, rr) {
|
||||||
return true
|
return true
|
||||||
|
|
@ -116,7 +116,7 @@ func matchesAResourceRule(ri *request.RequestInfo, rules []fctypesv1a1.ResourceP
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesResourcePolicyRule(ri *request.RequestInfo, policyRule fctypesv1a1.ResourcePolicyRule) bool {
|
func matchesResourcePolicyRule(ri *request.RequestInfo, policyRule flowcontrol.ResourcePolicyRule) bool {
|
||||||
if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) {
|
if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -129,10 +129,10 @@ func matchesResourcePolicyRule(ri *request.RequestInfo, policyRule fctypesv1a1.R
|
||||||
if len(ri.Namespace) == 0 {
|
if len(ri.Namespace) == 0 {
|
||||||
return policyRule.ClusterScope
|
return policyRule.ClusterScope
|
||||||
}
|
}
|
||||||
return containsString(ri.Namespace, policyRule.Namespaces, fctypesv1a1.NamespaceEvery)
|
return containsString(ri.Namespace, policyRule.Namespaces, flowcontrol.NamespaceEvery)
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesANonResourceRule(ri *request.RequestInfo, rules []fctypesv1a1.NonResourcePolicyRule) bool {
|
func matchesANonResourceRule(ri *request.RequestInfo, rules []flowcontrol.NonResourcePolicyRule) bool {
|
||||||
for _, rr := range rules {
|
for _, rr := range rules {
|
||||||
if matchesNonResourcePolicyRule(ri, rr) {
|
if matchesNonResourcePolicyRule(ri, rr) {
|
||||||
return true
|
return true
|
||||||
|
|
@ -141,7 +141,7 @@ func matchesANonResourceRule(ri *request.RequestInfo, rules []fctypesv1a1.NonRes
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesNonResourcePolicyRule(ri *request.RequestInfo, policyRule fctypesv1a1.NonResourcePolicyRule) bool {
|
func matchesNonResourcePolicyRule(ri *request.RequestInfo, policyRule flowcontrol.NonResourcePolicyRule) bool {
|
||||||
if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) {
|
if !matchPolicyRuleVerb(policyRule.Verbs, ri.Verb) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -149,12 +149,12 @@ func matchesNonResourcePolicyRule(ri *request.RequestInfo, policyRule fctypesv1a
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPolicyRuleVerb(policyRuleVerbs []string, requestVerb string) bool {
|
func matchPolicyRuleVerb(policyRuleVerbs []string, requestVerb string) bool {
|
||||||
return containsString(requestVerb, policyRuleVerbs, fctypesv1a1.VerbAll)
|
return containsString(requestVerb, policyRuleVerbs, flowcontrol.VerbAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPolicyRuleNonResourceURL(policyRuleRequestURLs []string, requestPath string) bool {
|
func matchPolicyRuleNonResourceURL(policyRuleRequestURLs []string, requestPath string) bool {
|
||||||
for _, rulePath := range policyRuleRequestURLs {
|
for _, rulePath := range policyRuleRequestURLs {
|
||||||
if rulePath == fctypesv1a1.NonResourceAll || rulePath == requestPath {
|
if rulePath == flowcontrol.NonResourceAll || rulePath == requestPath {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
rulePrefix := strings.TrimSuffix(rulePath, "*")
|
rulePrefix := strings.TrimSuffix(rulePath, "*")
|
||||||
|
|
@ -169,7 +169,7 @@ func matchPolicyRuleNonResourceURL(policyRuleRequestURLs []string, requestPath s
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPolicyRuleAPIGroup(policyRuleAPIGroups []string, requestAPIGroup string) bool {
|
func matchPolicyRuleAPIGroup(policyRuleAPIGroups []string, requestAPIGroup string) bool {
|
||||||
return containsString(requestAPIGroup, policyRuleAPIGroups, fctypesv1a1.APIGroupAll)
|
return containsString(requestAPIGroup, policyRuleAPIGroups, flowcontrol.APIGroupAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
func rsJoin(requestResource, requestSubresource string) string {
|
func rsJoin(requestResource, requestSubresource string) string {
|
||||||
|
|
@ -181,7 +181,7 @@ func rsJoin(requestResource, requestSubresource string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchPolicyRuleResource(policyRuleRequestResources []string, requestResource, requestSubresource string) bool {
|
func matchPolicyRuleResource(policyRuleRequestResources []string, requestResource, requestSubresource string) bool {
|
||||||
return containsString(rsJoin(requestResource, requestSubresource), policyRuleRequestResources, fctypesv1a1.ResourceAll)
|
return containsString(rsJoin(requestResource, requestSubresource), policyRuleRequestResources, flowcontrol.ResourceAll)
|
||||||
}
|
}
|
||||||
|
|
||||||
// containsString returns true if either `x` or `wildcard` is in
|
// containsString returns true if either `x` or `wildcard` is in
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue