mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Added server-side printers for the API object types for API priority and fairness
This commit is contained in:
parent
3d8317ae91
commit
ce12105edc
@ -21,6 +21,7 @@ go_test(
|
|||||||
"//pkg/apis/coordination:go_default_library",
|
"//pkg/apis/coordination:go_default_library",
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
"//pkg/apis/discovery:go_default_library",
|
"//pkg/apis/discovery:go_default_library",
|
||||||
|
"//pkg/apis/flowcontrol:go_default_library",
|
||||||
"//pkg/apis/networking:go_default_library",
|
"//pkg/apis/networking:go_default_library",
|
||||||
"//pkg/apis/node:go_default_library",
|
"//pkg/apis/node:go_default_library",
|
||||||
"//pkg/apis/policy:go_default_library",
|
"//pkg/apis/policy:go_default_library",
|
||||||
@ -65,6 +66,8 @@ go_library(
|
|||||||
"//pkg/apis/discovery/install:go_default_library",
|
"//pkg/apis/discovery/install:go_default_library",
|
||||||
"//pkg/apis/events/install:go_default_library",
|
"//pkg/apis/events/install:go_default_library",
|
||||||
"//pkg/apis/extensions/install:go_default_library",
|
"//pkg/apis/extensions/install:go_default_library",
|
||||||
|
"//pkg/apis/flowcontrol:go_default_library",
|
||||||
|
"//pkg/apis/flowcontrol/util:go_default_library",
|
||||||
"//pkg/apis/networking:go_default_library",
|
"//pkg/apis/networking:go_default_library",
|
||||||
"//pkg/apis/node:go_default_library",
|
"//pkg/apis/node:go_default_library",
|
||||||
"//pkg/apis/policy:go_default_library",
|
"//pkg/apis/policy:go_default_library",
|
||||||
@ -88,6 +91,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/discovery/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/discovery/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/api/flowcontrol/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/rbac/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/rbac/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/api/scheduling/v1:go_default_library",
|
"//staging/src/k8s.io/api/scheduling/v1:go_default_library",
|
||||||
@ -99,6 +103,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
apiv1 "k8s.io/api/core/v1"
|
apiv1 "k8s.io/api/core/v1"
|
||||||
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
discoveryv1beta1 "k8s.io/api/discovery/v1beta1"
|
||||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
|
flowcontrolv1alpha1 "k8s.io/api/flowcontrol/v1alpha1"
|
||||||
policyv1beta1 "k8s.io/api/policy/v1beta1"
|
policyv1beta1 "k8s.io/api/policy/v1beta1"
|
||||||
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
|
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
|
||||||
schedulingv1 "k8s.io/api/scheduling/v1"
|
schedulingv1 "k8s.io/api/scheduling/v1"
|
||||||
@ -45,6 +46,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/duration"
|
"k8s.io/apimachinery/pkg/util/duration"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
"k8s.io/kubernetes/pkg/apis/admissionregistration"
|
||||||
"k8s.io/kubernetes/pkg/apis/apps"
|
"k8s.io/kubernetes/pkg/apis/apps"
|
||||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||||
@ -54,6 +56,8 @@ import (
|
|||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||||
"k8s.io/kubernetes/pkg/apis/discovery"
|
"k8s.io/kubernetes/pkg/apis/discovery"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/flowcontrol"
|
||||||
|
apihelpers "k8s.io/kubernetes/pkg/apis/flowcontrol/util"
|
||||||
"k8s.io/kubernetes/pkg/apis/networking"
|
"k8s.io/kubernetes/pkg/apis/networking"
|
||||||
nodeapi "k8s.io/kubernetes/pkg/apis/node"
|
nodeapi "k8s.io/kubernetes/pkg/apis/node"
|
||||||
"k8s.io/kubernetes/pkg/apis/policy"
|
"k8s.io/kubernetes/pkg/apis/policy"
|
||||||
@ -517,6 +521,29 @@ func AddHandlers(h printers.PrintHandler) {
|
|||||||
}
|
}
|
||||||
h.TableHandler(validatingWebhookColumnDefinitions, printValidatingWebhook)
|
h.TableHandler(validatingWebhookColumnDefinitions, printValidatingWebhook)
|
||||||
h.TableHandler(validatingWebhookColumnDefinitions, printValidatingWebhookList)
|
h.TableHandler(validatingWebhookColumnDefinitions, printValidatingWebhookList)
|
||||||
|
|
||||||
|
flowSchemaColumnDefinitions := []metav1.TableColumnDefinition{
|
||||||
|
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||||
|
{Name: "PriorityLevel", Type: "string", Description: flowcontrolv1alpha1.PriorityLevelConfigurationReference{}.SwaggerDoc()["name"]},
|
||||||
|
{Name: "MatchingPrecedence", Type: "string", Description: flowcontrolv1alpha1.FlowSchemaSpec{}.SwaggerDoc()["matchingPrecedence"]},
|
||||||
|
{Name: "DistinguisherMethod", Type: "string", Description: flowcontrolv1alpha1.FlowSchemaSpec{}.SwaggerDoc()["distinguisherMethod"]},
|
||||||
|
{Name: "MatchesAll", Type: "bolean", Description: "matches all requests"},
|
||||||
|
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||||
|
}
|
||||||
|
h.TableHandler(flowSchemaColumnDefinitions, printFlowSchema)
|
||||||
|
h.TableHandler(flowSchemaColumnDefinitions, printFlowSchemaList)
|
||||||
|
|
||||||
|
priorityLevelColumnDefinitions := []metav1.TableColumnDefinition{
|
||||||
|
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||||
|
{Name: "Type", Type: "string", Description: flowcontrolv1alpha1.PriorityLevelConfigurationSpec{}.SwaggerDoc()["type"]},
|
||||||
|
{Name: "AssuredConcurrencyShares", Type: "string", Description: flowcontrolv1alpha1.LimitedPriorityLevelConfiguration{}.SwaggerDoc()["assuredConcurrencyShares"]},
|
||||||
|
{Name: "Queues", Type: "string", Description: flowcontrolv1alpha1.QueuingConfiguration{}.SwaggerDoc()["queues"]},
|
||||||
|
{Name: "HandSize", Type: "string", Description: flowcontrolv1alpha1.QueuingConfiguration{}.SwaggerDoc()["handSize"]},
|
||||||
|
{Name: "QueueLengthLimit", Type: "string", Description: flowcontrolv1alpha1.QueuingConfiguration{}.SwaggerDoc()["queueLengthLimit"]},
|
||||||
|
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||||
|
}
|
||||||
|
h.TableHandler(priorityLevelColumnDefinitions, printPriorityLevelConfiguration)
|
||||||
|
h.TableHandler(priorityLevelColumnDefinitions, printPriorityLevelConfigurationList)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass ports=nil for all ports.
|
// Pass ports=nil for all ports.
|
||||||
@ -2245,6 +2272,118 @@ func printVolumeAttachmentList(list *storage.VolumeAttachmentList, options print
|
|||||||
return rows, nil
|
return rows, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fsMatchesAll(obj *flowcontrol.FlowSchema) bool {
|
||||||
|
var allResources, allNonResources [2]bool
|
||||||
|
for _, prws := range obj.Spec.Rules {
|
||||||
|
allAuth, allUnauth := false, false
|
||||||
|
for _, subj := range prws.Subjects {
|
||||||
|
if subj.Group == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
allAuth = allAuth || subj.Group.Name == user.AllAuthenticated
|
||||||
|
allUnauth = allUnauth || subj.Group.Name == user.AllUnauthenticated
|
||||||
|
}
|
||||||
|
anyAll := allAuth || allUnauth
|
||||||
|
if !anyAll {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, nrr := range prws.NonResourceRules {
|
||||||
|
if hasWildcard(nrr.Verbs) && hasWildcard(nrr.NonResourceURLs) {
|
||||||
|
allNonResources[0] = allNonResources[0] || allAuth
|
||||||
|
allNonResources[1] = allNonResources[1] || allUnauth
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, rr := range prws.ResourceRules {
|
||||||
|
if hasWildcard(rr.Verbs) && hasWildcard(rr.APIGroups) && hasWildcard(rr.Resources) && rr.ClusterScope && hasWildcard(rr.Namespaces) {
|
||||||
|
allResources[0] = allResources[0] || allAuth
|
||||||
|
allResources[1] = allResources[1] || allUnauth
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if allResources[0] && allResources[1] && allNonResources[0] && allNonResources[1] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasWildcard(arr []string) bool {
|
||||||
|
for _, elt := range arr {
|
||||||
|
if elt == "*" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func printFlowSchema(obj *flowcontrol.FlowSchema, options printers.GenerateOptions) ([]metav1.TableRow, error) {
|
||||||
|
row := metav1.TableRow{
|
||||||
|
Object: runtime.RawExtension{Object: obj},
|
||||||
|
}
|
||||||
|
|
||||||
|
name := obj.Name
|
||||||
|
plName := obj.Spec.PriorityLevelConfiguration.Name
|
||||||
|
distinguisherMethod := "<none>"
|
||||||
|
if obj.Spec.DistinguisherMethod != nil {
|
||||||
|
distinguisherMethod = string(obj.Spec.DistinguisherMethod.Type)
|
||||||
|
}
|
||||||
|
row.Cells = append(row.Cells, name, plName, obj.Spec.MatchingPrecedence, distinguisherMethod, fsMatchesAll(obj), translateTimestampSince(obj.CreationTimestamp))
|
||||||
|
|
||||||
|
return []metav1.TableRow{row}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func printFlowSchemaList(list *flowcontrol.FlowSchemaList, options printers.GenerateOptions) ([]metav1.TableRow, error) {
|
||||||
|
rows := make([]metav1.TableRow, 0, len(list.Items))
|
||||||
|
fsSeq := make(apihelpers.FlowSchemaSequence, len(list.Items))
|
||||||
|
for i := range list.Items {
|
||||||
|
fsSeq[i] = &list.Items[i]
|
||||||
|
}
|
||||||
|
sort.Sort(fsSeq)
|
||||||
|
for i := range fsSeq {
|
||||||
|
r, err := printFlowSchema(fsSeq[i], options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows = append(rows, r...)
|
||||||
|
}
|
||||||
|
return rows, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func printPriorityLevelConfiguration(obj *flowcontrol.PriorityLevelConfiguration, options printers.GenerateOptions) ([]metav1.TableRow, error) {
|
||||||
|
row := metav1.TableRow{
|
||||||
|
Object: runtime.RawExtension{Object: obj},
|
||||||
|
}
|
||||||
|
name := obj.Name
|
||||||
|
acs := interface{}("<none>")
|
||||||
|
queues := interface{}("<none>")
|
||||||
|
handSize := interface{}("<none>")
|
||||||
|
queueLengthLimit := interface{}("<none>")
|
||||||
|
if obj.Spec.Limited != nil {
|
||||||
|
acs = obj.Spec.Limited.AssuredConcurrencyShares
|
||||||
|
if qc := obj.Spec.Limited.LimitResponse.Queuing; qc != nil {
|
||||||
|
queues = qc.Queues
|
||||||
|
handSize = qc.HandSize
|
||||||
|
queueLengthLimit = qc.QueueLengthLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
row.Cells = append(row.Cells, name, string(obj.Spec.Type), acs, queues, handSize, queueLengthLimit, translateTimestampSince(obj.CreationTimestamp))
|
||||||
|
|
||||||
|
return []metav1.TableRow{row}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func printPriorityLevelConfigurationList(list *flowcontrol.PriorityLevelConfigurationList, options printers.GenerateOptions) ([]metav1.TableRow, error) {
|
||||||
|
rows := make([]metav1.TableRow, 0, len(list.Items))
|
||||||
|
for i := range list.Items {
|
||||||
|
r, err := printPriorityLevelConfiguration(&list.Items[i], options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows = append(rows, r...)
|
||||||
|
}
|
||||||
|
return rows, nil
|
||||||
|
}
|
||||||
|
|
||||||
func printBoolPtr(value *bool) string {
|
func printBoolPtr(value *bool) string {
|
||||||
if value != nil {
|
if value != nil {
|
||||||
return printBool(*value)
|
return printBool(*value)
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package internalversion
|
package internalversion
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -33,6 +34,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/apis/coordination"
|
"k8s.io/kubernetes/pkg/apis/coordination"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/apis/discovery"
|
"k8s.io/kubernetes/pkg/apis/discovery"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/flowcontrol"
|
||||||
"k8s.io/kubernetes/pkg/apis/networking"
|
"k8s.io/kubernetes/pkg/apis/networking"
|
||||||
nodeapi "k8s.io/kubernetes/pkg/apis/node"
|
nodeapi "k8s.io/kubernetes/pkg/apis/node"
|
||||||
"k8s.io/kubernetes/pkg/apis/policy"
|
"k8s.io/kubernetes/pkg/apis/policy"
|
||||||
@ -4831,3 +4833,221 @@ func TestPrintEndpointSlice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPrintFlowSchema(t *testing.T) {
|
||||||
|
all := []string{"*"}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
fs flowcontrol.FlowSchema
|
||||||
|
expected []metav1.TableRow
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
fs: flowcontrol.FlowSchema{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "all-matcher",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||||
|
},
|
||||||
|
Spec: flowcontrol.FlowSchemaSpec{
|
||||||
|
PriorityLevelConfiguration: flowcontrol.PriorityLevelConfigurationReference{Name: "allee"},
|
||||||
|
MatchingPrecedence: math.MaxInt32,
|
||||||
|
DistinguisherMethod: &flowcontrol.FlowDistinguisherMethod{Type: flowcontrol.FlowDistinguisherMethodByUserType},
|
||||||
|
Rules: []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
|
Subjects: []flowcontrol.Subject{{
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:authenticated"},
|
||||||
|
}},
|
||||||
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
|
Verbs: all,
|
||||||
|
APIGroups: all,
|
||||||
|
Resources: all,
|
||||||
|
ClusterScope: true,
|
||||||
|
Namespaces: all,
|
||||||
|
}},
|
||||||
|
}, {
|
||||||
|
Subjects: []flowcontrol.Subject{{
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:unauthenticated"},
|
||||||
|
}},
|
||||||
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
|
Verbs: all,
|
||||||
|
APIGroups: all,
|
||||||
|
Resources: all,
|
||||||
|
ClusterScope: true,
|
||||||
|
Namespaces: all,
|
||||||
|
}},
|
||||||
|
}, {
|
||||||
|
Subjects: []flowcontrol.Subject{{
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:authenticated"},
|
||||||
|
}, {
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:unauthenticated"},
|
||||||
|
}},
|
||||||
|
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
|
||||||
|
Verbs: all,
|
||||||
|
NonResourceURLs: all,
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, PriorityLevelName, MatchingPrecedence, DistinguisherMethod, MatchesAll, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"all-matcher", "allee", int32(math.MaxInt32), "ByUser", true, "0s"}}},
|
||||||
|
}, {
|
||||||
|
fs: flowcontrol.FlowSchema{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "some-matcher",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(-3e11)},
|
||||||
|
},
|
||||||
|
Spec: flowcontrol.FlowSchemaSpec{
|
||||||
|
PriorityLevelConfiguration: flowcontrol.PriorityLevelConfigurationReference{Name: "allee"},
|
||||||
|
MatchingPrecedence: 0,
|
||||||
|
DistinguisherMethod: &flowcontrol.FlowDistinguisherMethod{Type: flowcontrol.FlowDistinguisherMethodByNamespaceType},
|
||||||
|
Rules: []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
|
Subjects: []flowcontrol.Subject{{
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:unauthenticated"},
|
||||||
|
}},
|
||||||
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
|
Verbs: all,
|
||||||
|
APIGroups: all,
|
||||||
|
Resources: all,
|
||||||
|
ClusterScope: true,
|
||||||
|
Namespaces: all,
|
||||||
|
}},
|
||||||
|
}, {
|
||||||
|
Subjects: []flowcontrol.Subject{{
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:authenticated"},
|
||||||
|
}, {
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:unauthenticated"},
|
||||||
|
}},
|
||||||
|
NonResourceRules: []flowcontrol.NonResourcePolicyRule{{
|
||||||
|
Verbs: all,
|
||||||
|
NonResourceURLs: all,
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, PriorityLevelName, MatchingPrecedence, DistinguisherMethod, MatchesAll, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"some-matcher", "allee", int32(0), "ByNamespace", false, "5m"}}},
|
||||||
|
}, {
|
||||||
|
fs: flowcontrol.FlowSchema{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "exempt",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(-3e11)},
|
||||||
|
},
|
||||||
|
Spec: flowcontrol.FlowSchemaSpec{
|
||||||
|
PriorityLevelConfiguration: flowcontrol.PriorityLevelConfigurationReference{Name: "allee"},
|
||||||
|
MatchingPrecedence: 0,
|
||||||
|
DistinguisherMethod: nil,
|
||||||
|
Rules: []flowcontrol.PolicyRulesWithSubjects{{
|
||||||
|
Subjects: []flowcontrol.Subject{{
|
||||||
|
Kind: flowcontrol.SubjectKindGroup,
|
||||||
|
Group: &flowcontrol.GroupSubject{Name: "system:masters"},
|
||||||
|
}},
|
||||||
|
ResourceRules: []flowcontrol.ResourcePolicyRule{{
|
||||||
|
Verbs: all,
|
||||||
|
APIGroups: all,
|
||||||
|
Resources: all,
|
||||||
|
ClusterScope: true,
|
||||||
|
Namespaces: all,
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, PriorityLevelName, MatchingPrecedence, DistinguisherMethod, MatchesAll, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"exempt", "allee", int32(0), "<none>", false, "5m"}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
rows, err := printFlowSchema(&test.fs, printers.GenerateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
for i := range rows {
|
||||||
|
rows[i].Object.Object = nil
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(test.expected, rows) {
|
||||||
|
t.Errorf("%d mismatch: %s", i, diff.ObjectReflectDiff(test.expected, rows))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrintPriorityLevelConfiguration(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
pl flowcontrol.PriorityLevelConfiguration
|
||||||
|
expected []metav1.TableRow
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
pl: flowcontrol.PriorityLevelConfiguration{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "unlimited",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||||
|
},
|
||||||
|
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||||
|
Type: flowcontrol.PriorityLevelEnablementExempt,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, Type, AssuredConcurrencyShares, Queues, HandSize, QueueLengthLimit, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"unlimited", "Exempt", "<none>", "<none>", "<none>", "<none>", "0s"}}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pl: flowcontrol.PriorityLevelConfiguration{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "unqueued",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||||
|
},
|
||||||
|
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||||
|
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||||
|
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||||
|
AssuredConcurrencyShares: 47,
|
||||||
|
LimitResponse: flowcontrol.LimitResponse{
|
||||||
|
Type: flowcontrol.LimitResponseTypeReject,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, Type, AssuredConcurrencyShares, Queues, HandSize, QueueLengthLimit, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"unqueued", "Limited", int32(47), "<none>", "<none>", "<none>", "0s"}}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pl: flowcontrol.PriorityLevelConfiguration{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "queued",
|
||||||
|
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||||
|
},
|
||||||
|
Spec: flowcontrol.PriorityLevelConfigurationSpec{
|
||||||
|
Type: flowcontrol.PriorityLevelEnablementLimited,
|
||||||
|
Limited: &flowcontrol.LimitedPriorityLevelConfiguration{
|
||||||
|
AssuredConcurrencyShares: 42,
|
||||||
|
LimitResponse: flowcontrol.LimitResponse{
|
||||||
|
Type: flowcontrol.LimitResponseTypeQueue,
|
||||||
|
Queuing: &flowcontrol.QueuingConfiguration{
|
||||||
|
Queues: 8,
|
||||||
|
HandSize: 3,
|
||||||
|
QueueLengthLimit: 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Columns: Name, Type, AssuredConcurrencyShares, Queues, HandSize, QueueLengthLimit, Age
|
||||||
|
expected: []metav1.TableRow{{Cells: []interface{}{"queued", "Limited", int32(42), int32(8), int32(3), int32(4), "0s"}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
rows, err := printPriorityLevelConfiguration(&test.pl, printers.GenerateOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
for i := range rows {
|
||||||
|
rows[i].Object.Object = nil
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(test.expected, rows) {
|
||||||
|
t.Errorf("%d mismatch: %s", i, diff.ObjectReflectDiff(test.expected, rows))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -129,8 +129,6 @@ var missingHanlders = sets.NewString(
|
|||||||
"PriorityClass",
|
"PriorityClass",
|
||||||
"PodPreset",
|
"PodPreset",
|
||||||
"AuditSink",
|
"AuditSink",
|
||||||
"FlowSchema", // TODO(yue9944882): remove this comment by merging print-handler for flow-control API
|
|
||||||
"PriorityLevelConfiguration", // TODO(yue9944882): remove this comment by merging print-handler for flow-control API
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// known types that are no longer served we should tolerate restmapper errors for
|
// known types that are no longer served we should tolerate restmapper errors for
|
||||||
|
Loading…
Reference in New Issue
Block a user