APF: graduate API and types to beta

Signed-off-by: Adhityaa Chandrasekar <adtac@google.com>

Kubernetes-commit: 849be447f563fc93a27a0827fb1185b885b57114
This commit is contained in:
yue9944882 2020-11-04 16:33:14 +08:00 committed by Kubernetes Publisher
parent 13d987893e
commit a4a3fc9b87
15 changed files with 300 additions and 299 deletions

View File

@ -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"

View File

@ -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},

View File

@ -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)
} }
} }

View File

@ -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}

View File

@ -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(),
) { ) {

View File

@ -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,
) )

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -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
} }

View File

@ -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.

View File

@ -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(", ")

View File

@ -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{"*"}

View File

@ -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))

View File

@ -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