mirror of https://github.com/k3s-io/k3s
Merge pull request #70950 from yue9944882/chore/prune-cli-describer-internal
Use versioned types in kubectl describerpull/58/head
commit
e615df9d23
|
@ -181,6 +181,7 @@ pkg/kubectl/cmd/util/openapi
|
|||
pkg/kubectl/cmd/util/sanity
|
||||
pkg/kubectl/cmd/version
|
||||
pkg/kubectl/cmd/wait
|
||||
pkg/kubectl/describe/versioned
|
||||
pkg/kubectl/generate
|
||||
pkg/kubectl/generate/versioned
|
||||
pkg/kubectl/metricsutil
|
||||
|
|
|
@ -12,7 +12,6 @@ filegroup(
|
|||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/api/endpoints:all-srcs",
|
||||
"//pkg/api/events:all-srcs",
|
||||
"//pkg/api/legacyscheme:all-srcs",
|
||||
"//pkg/api/persistentvolume:all-srcs",
|
||||
"//pkg/api/persistentvolumeclaim:all-srcs",
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
reviewers:
|
||||
- gmarek
|
|
@ -58,15 +58,13 @@ go_library(
|
|||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/v1:go_default_library",
|
||||
"//pkg/kubectl/apps:go_default_library",
|
||||
"//pkg/kubectl/describe/versioned:go_default_library",
|
||||
"//pkg/kubectl/scheme:go_default_library",
|
||||
"//pkg/kubectl/util:go_default_library",
|
||||
"//pkg/kubectl/util/deployment:go_default_library",
|
||||
"//pkg/kubectl/util/podutils:go_default_library",
|
||||
"//pkg/kubectl/util/slice:go_default_library",
|
||||
"//pkg/printers/internalversion:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
|
|
|
@ -2,12 +2,30 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
|||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["convert.go"],
|
||||
srcs = [
|
||||
"convert.go",
|
||||
"import_known_versions.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/convert",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/apps/install:go_default_library",
|
||||
"//pkg/apis/authentication/install:go_default_library",
|
||||
"//pkg/apis/authorization/install:go_default_library",
|
||||
"//pkg/apis/autoscaling/install:go_default_library",
|
||||
"//pkg/apis/batch/install:go_default_library",
|
||||
"//pkg/apis/certificates/install:go_default_library",
|
||||
"//pkg/apis/coordination/install:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/apis/events/install:go_default_library",
|
||||
"//pkg/apis/extensions/install:go_default_library",
|
||||
"//pkg/apis/policy/install:go_default_library",
|
||||
"//pkg/apis/rbac/install:go_default_library",
|
||||
"//pkg/apis/scheduling/install:go_default_library",
|
||||
"//pkg/apis/settings/install:go_default_library",
|
||||
"//pkg/apis/storage/install:go_default_library",
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/util/i18n:go_default_library",
|
||||
"//pkg/kubectl/util/templates:go_default_library",
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package convert
|
||||
|
||||
// These imports are the API groups the client will support.
|
||||
// TODO: Remove these manual install once we don't need legacy scheme in convert
|
||||
import (
|
||||
_ "k8s.io/kubernetes/pkg/apis/apps/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authentication/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authorization/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/batch/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/certificates/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/coordination/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/events/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/policy/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/rbac/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/scheduling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/settings/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/storage/install"
|
||||
)
|
|
@ -7,10 +7,10 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/util:go_default_library",
|
||||
"//pkg/kubectl/describe:go_default_library",
|
||||
"//pkg/kubectl/describe/versioned:go_default_library",
|
||||
"//pkg/kubectl/util/i18n:go_default_library",
|
||||
"//pkg/kubectl/util/templates:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
|
@ -30,9 +30,9 @@ go_test(
|
|||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/kubectl/cmd/testing:go_default_library",
|
||||
"//pkg/kubectl/describe:go_default_library",
|
||||
"//pkg/kubectl/describe/versioned:go_default_library",
|
||||
"//pkg/kubectl/scheme:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource:go_default_library",
|
||||
|
|
|
@ -29,10 +29,10 @@ import (
|
|||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/describe"
|
||||
describeversioned "k8s.io/kubernetes/pkg/kubectl/describe/versioned"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/templates"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -74,7 +74,7 @@ type DescribeOptions struct {
|
|||
Selector string
|
||||
Namespace string
|
||||
|
||||
Describer func(*meta.RESTMapping) (printers.Describer, error)
|
||||
Describer func(*meta.RESTMapping) (describe.Describer, error)
|
||||
NewBuilder func() *resource.Builder
|
||||
|
||||
BuilderArgs []string
|
||||
|
@ -83,7 +83,7 @@ type DescribeOptions struct {
|
|||
AllNamespaces bool
|
||||
IncludeUninitialized bool
|
||||
|
||||
DescriberSettings *printers.DescriberSettings
|
||||
DescriberSettings *describe.DescriberSettings
|
||||
FilenameOptions *resource.FilenameOptions
|
||||
|
||||
genericclioptions.IOStreams
|
||||
|
@ -92,7 +92,7 @@ type DescribeOptions struct {
|
|||
func NewCmdDescribe(parent string, f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := &DescribeOptions{
|
||||
FilenameOptions: &resource.FilenameOptions{},
|
||||
DescriberSettings: &printers.DescriberSettings{
|
||||
DescriberSettings: &describe.DescriberSettings{
|
||||
ShowEvents: true,
|
||||
},
|
||||
|
||||
|
@ -138,7 +138,7 @@ func (o *DescribeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [
|
|||
|
||||
o.BuilderArgs = args
|
||||
|
||||
o.Describer = func(mapping *meta.RESTMapping) (printers.Describer, error) {
|
||||
o.Describer = func(mapping *meta.RESTMapping) (describe.Describer, error) {
|
||||
return describeversioned.DescriberFn(f, mapping)
|
||||
}
|
||||
|
||||
|
|
|
@ -27,19 +27,19 @@ import (
|
|||
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
describe "k8s.io/kubernetes/pkg/kubectl/describe/versioned"
|
||||
"k8s.io/kubernetes/pkg/kubectl/describe"
|
||||
versioneddescribe "k8s.io/kubernetes/pkg/kubectl/describe/versioned"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
|
||||
func TestDescribeUnknownSchemaObject(t *testing.T) {
|
||||
d := &testDescriber{Output: "test output"}
|
||||
oldFn := describe.DescriberFn
|
||||
oldFn := versioneddescribe.DescriberFn
|
||||
defer func() {
|
||||
describe.DescriberFn = oldFn
|
||||
versioneddescribe.DescriberFn = oldFn
|
||||
}()
|
||||
describe.DescriberFn = d.describerFor
|
||||
versioneddescribe.DescriberFn = d.describerFor
|
||||
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("non-default")
|
||||
defer tf.Cleanup()
|
||||
|
@ -67,11 +67,11 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
|
|||
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
|
||||
func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
|
||||
d := &testDescriber{Output: "test output"}
|
||||
oldFn := describe.DescriberFn
|
||||
oldFn := versioneddescribe.DescriberFn
|
||||
defer func() {
|
||||
describe.DescriberFn = oldFn
|
||||
versioneddescribe.DescriberFn = oldFn
|
||||
}()
|
||||
describe.DescriberFn = d.describerFor
|
||||
versioneddescribe.DescriberFn = d.describerFor
|
||||
|
||||
tf := cmdtesting.NewTestFactory()
|
||||
defer tf.Cleanup()
|
||||
|
@ -99,11 +99,11 @@ func TestDescribeUnknownNamespacedSchemaObject(t *testing.T) {
|
|||
|
||||
func TestDescribeObject(t *testing.T) {
|
||||
d := &testDescriber{Output: "test output"}
|
||||
oldFn := describe.DescriberFn
|
||||
oldFn := versioneddescribe.DescriberFn
|
||||
defer func() {
|
||||
describe.DescriberFn = oldFn
|
||||
versioneddescribe.DescriberFn = oldFn
|
||||
}()
|
||||
describe.DescriberFn = d.describerFor
|
||||
versioneddescribe.DescriberFn = d.describerFor
|
||||
|
||||
_, _, rc := cmdtesting.TestData()
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
|
@ -140,11 +140,11 @@ func TestDescribeObject(t *testing.T) {
|
|||
|
||||
func TestDescribeListObjects(t *testing.T) {
|
||||
d := &testDescriber{Output: "test output"}
|
||||
oldFn := describe.DescriberFn
|
||||
oldFn := versioneddescribe.DescriberFn
|
||||
defer func() {
|
||||
describe.DescriberFn = oldFn
|
||||
versioneddescribe.DescriberFn = oldFn
|
||||
}()
|
||||
describe.DescriberFn = d.describerFor
|
||||
versioneddescribe.DescriberFn = d.describerFor
|
||||
|
||||
pods, _, _ := cmdtesting.TestData()
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
|
@ -167,11 +167,11 @@ func TestDescribeListObjects(t *testing.T) {
|
|||
|
||||
func TestDescribeObjectShowEvents(t *testing.T) {
|
||||
d := &testDescriber{Output: "test output"}
|
||||
oldFn := describe.DescriberFn
|
||||
oldFn := versioneddescribe.DescriberFn
|
||||
defer func() {
|
||||
describe.DescriberFn = oldFn
|
||||
versioneddescribe.DescriberFn = oldFn
|
||||
}()
|
||||
describe.DescriberFn = d.describerFor
|
||||
versioneddescribe.DescriberFn = d.describerFor
|
||||
|
||||
pods, _, _ := cmdtesting.TestData()
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
|
@ -193,11 +193,11 @@ func TestDescribeObjectShowEvents(t *testing.T) {
|
|||
|
||||
func TestDescribeObjectSkipEvents(t *testing.T) {
|
||||
d := &testDescriber{Output: "test output"}
|
||||
oldFn := describe.DescriberFn
|
||||
oldFn := versioneddescribe.DescriberFn
|
||||
defer func() {
|
||||
describe.DescriberFn = oldFn
|
||||
versioneddescribe.DescriberFn = oldFn
|
||||
}()
|
||||
describe.DescriberFn = d.describerFor
|
||||
versioneddescribe.DescriberFn = d.describerFor
|
||||
|
||||
pods, _, _ := cmdtesting.TestData()
|
||||
tf := cmdtesting.NewTestFactory().WithNamespace("test")
|
||||
|
@ -247,16 +247,16 @@ func TestDescribeHelpMessage(t *testing.T) {
|
|||
|
||||
type testDescriber struct {
|
||||
Name, Namespace string
|
||||
Settings printers.DescriberSettings
|
||||
Settings describe.DescriberSettings
|
||||
Output string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (t *testDescriber) Describe(namespace, name string, describerSettings printers.DescriberSettings) (output string, err error) {
|
||||
func (t *testDescriber) Describe(namespace, name string, describerSettings describe.DescriberSettings) (output string, err error) {
|
||||
t.Namespace, t.Name = namespace, name
|
||||
t.Settings = describerSettings
|
||||
return t.Output, t.Err
|
||||
}
|
||||
func (t *testDescriber) describerFor(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (printers.Describer, error) {
|
||||
func (t *testDescriber) describerFor(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (describe.Describer, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
|
|
@ -2,11 +2,10 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
|||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["describe.go"],
|
||||
srcs = ["interface.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/describe",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/printers:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
],
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package describe
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
// DescriberFunc gives a way to display the specified RESTMapping type
|
||||
type DescriberFunc func(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (printers.Describer, error)
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package describe
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
)
|
||||
|
||||
const (
|
||||
// LoadBalancerWidth is the width how we describe load balancer
|
||||
LoadBalancerWidth = 16
|
||||
|
||||
// LabelNodeRolePrefix is a label prefix for node roles
|
||||
// It's copied over to here until it's merged in core: https://github.com/kubernetes/kubernetes/pull/39112
|
||||
LabelNodeRolePrefix = "node-role.kubernetes.io/"
|
||||
|
||||
// NodeLabelRole specifies the role of a node
|
||||
NodeLabelRole = "kubernetes.io/role"
|
||||
)
|
||||
|
||||
// DescriberFunc gives a way to display the specified RESTMapping type
|
||||
type DescriberFunc func(restClientGetter genericclioptions.RESTClientGetter, mapping *meta.RESTMapping) (Describer, error)
|
||||
|
||||
// Describer generates output for the named resource or an error
|
||||
// if the output could not be generated. Implementers typically
|
||||
// abstract the retrieval of the named object from a remote server.
|
||||
type Describer interface {
|
||||
Describe(namespace, name string, describerSettings DescriberSettings) (output string, err error)
|
||||
}
|
||||
|
||||
// DescriberSettings holds display configuration for each object
|
||||
// describer to control what is printed.
|
||||
type DescriberSettings struct {
|
||||
ShowEvents bool
|
||||
}
|
||||
|
||||
// ObjectDescriber is an interface for displaying arbitrary objects with extra
|
||||
// information. Use when an object is in hand (on disk, or already retrieved).
|
||||
// Implementers may ignore the additional information passed on extra, or use it
|
||||
// by default. ObjectDescribers may return ErrNoDescriber if no suitable describer
|
||||
// is found.
|
||||
type ObjectDescriber interface {
|
||||
DescribeObject(object interface{}, extra ...interface{}) (output string, err error)
|
||||
}
|
||||
|
||||
// ErrNoDescriber is a structured error indicating the provided object or objects
|
||||
// cannot be described.
|
||||
type ErrNoDescriber struct {
|
||||
Types []string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e ErrNoDescriber) Error() string {
|
||||
return fmt.Sprintf("no describer has been defined for %v", e.Types)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
|
@ -7,10 +7,47 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/kubectl/describe:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/printers/internalversion:go_default_library",
|
||||
"//pkg/kubectl/scheme:go_default_library",
|
||||
"//pkg/kubectl/util/certificate:go_default_library",
|
||||
"//pkg/kubectl/util/deployment:go_default_library",
|
||||
"//pkg/kubectl/util/event:go_default_library",
|
||||
"//pkg/kubectl/util/fieldpath:go_default_library",
|
||||
"//pkg/kubectl/util/qos:go_default_library",
|
||||
"//pkg/kubectl/util/rbac:go_default_library",
|
||||
"//pkg/kubectl/util/resource:go_default_library",
|
||||
"//pkg/kubectl/util/slice:go_default_library",
|
||||
"//pkg/kubectl/util/storage:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/scheduling/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/reference:go_default_library",
|
||||
"//vendor/github.com/fatih/camelcase:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -27,3 +64,26 @@ filegroup(
|
|||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["describe_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/kubectl/describe:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -34,12 +34,10 @@ import (
|
|||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
clientappsv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
apiv1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
kapps "k8s.io/kubernetes/pkg/kubectl/apps"
|
||||
describe "k8s.io/kubernetes/pkg/kubectl/describe/versioned"
|
||||
deploymentutil "k8s.io/kubernetes/pkg/kubectl/util/deployment"
|
||||
sliceutil "k8s.io/kubernetes/pkg/kubectl/util/slice"
|
||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -168,12 +166,8 @@ func (h *DeploymentHistoryViewer) ViewHistory(namespace, name string, revision i
|
|||
|
||||
func printTemplate(template *corev1.PodTemplateSpec) (string, error) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
internalTemplate := &api.PodTemplateSpec{}
|
||||
if err := apiv1.Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(template, internalTemplate, nil); err != nil {
|
||||
return "", fmt.Errorf("failed to convert podtemplate, %v", err)
|
||||
}
|
||||
w := printersinternal.NewPrefixWriter(buf)
|
||||
printersinternal.DescribePodTemplate(internalTemplate, w)
|
||||
w := describe.NewPrefixWriter(buf)
|
||||
describe.DescribePodTemplate(template, w)
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -66,13 +66,20 @@ filegroup(
|
|||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubectl/util/certificate:all-srcs",
|
||||
"//pkg/kubectl/util/deployment:all-srcs",
|
||||
"//pkg/kubectl/util/event:all-srcs",
|
||||
"//pkg/kubectl/util/fieldpath:all-srcs",
|
||||
"//pkg/kubectl/util/hash:all-srcs",
|
||||
"//pkg/kubectl/util/i18n:all-srcs",
|
||||
"//pkg/kubectl/util/logs:all-srcs",
|
||||
"//pkg/kubectl/util/podutils:all-srcs",
|
||||
"//pkg/kubectl/util/printers:all-srcs",
|
||||
"//pkg/kubectl/util/qos:all-srcs",
|
||||
"//pkg/kubectl/util/rbac:all-srcs",
|
||||
"//pkg/kubectl/util/resource:all-srcs",
|
||||
"//pkg/kubectl/util/slice:all-srcs",
|
||||
"//pkg/kubectl/util/storage:all-srcs",
|
||||
"//pkg/kubectl/util/templates:all-srcs",
|
||||
"//pkg/kubectl/util/term:all-srcs",
|
||||
],
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["certificate.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/util/certificate",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//staging/src/k8s.io/api/certificates/v1beta1:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package certificate
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
)
|
||||
|
||||
// TODO(yue9944882): Remove this helper package once it's copied to k/api
|
||||
|
||||
// ParseCSR extracts the CSR from the API object and decodes it.
|
||||
func ParseCSR(obj *certificatesv1beta1.CertificateSigningRequest) (*x509.CertificateRequest, error) {
|
||||
// extract PEM from request object
|
||||
pemBytes := obj.Spec.Request
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil || block.Type != "CERTIFICATE REQUEST" {
|
||||
return nil, errors.New("PEM block type must be CERTIFICATE REQUEST")
|
||||
}
|
||||
csr, err := x509.ParseCertificateRequest(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return csr, nil
|
||||
}
|
|
@ -9,8 +9,8 @@ load(
|
|||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["sorted_event_list.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/api/events",
|
||||
deps = ["//pkg/apis/core:go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/util/event",
|
||||
deps = ["//staging/src/k8s.io/api/core/v1:go_default_library"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
|
@ -18,7 +18,7 @@ go_test(
|
|||
srcs = ["sorted_event_list_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
],
|
||||
)
|
|
@ -14,14 +14,14 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package events
|
||||
package event
|
||||
|
||||
import (
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// SortableEvents implements sort.Interface for []api.Event based on the Timestamp field
|
||||
type SortableEvents []api.Event
|
||||
type SortableEvents []corev1.Event
|
||||
|
||||
func (list SortableEvents) Len() int {
|
||||
return len(list)
|
|
@ -14,43 +14,43 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package events
|
||||
package event
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
func TestSortableEvents(t *testing.T) {
|
||||
// Arrange
|
||||
list := SortableEvents([]api.Event{
|
||||
list := SortableEvents([]corev1.Event{
|
||||
{
|
||||
Source: api.EventSource{Component: "kubelet"},
|
||||
Source: corev1.EventSource{Component: "kubelet"},
|
||||
Message: "Item 1",
|
||||
FirstTimestamp: metav1.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)),
|
||||
LastTimestamp: metav1.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)),
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
Type: corev1.EventTypeNormal,
|
||||
},
|
||||
{
|
||||
Source: api.EventSource{Component: "scheduler"},
|
||||
Source: corev1.EventSource{Component: "scheduler"},
|
||||
Message: "Item 2",
|
||||
FirstTimestamp: metav1.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)),
|
||||
LastTimestamp: metav1.NewTime(time.Date(1987, time.June, 17, 0, 0, 0, 0, time.UTC)),
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
Type: corev1.EventTypeNormal,
|
||||
},
|
||||
{
|
||||
Source: api.EventSource{Component: "kubelet"},
|
||||
Source: corev1.EventSource{Component: "kubelet"},
|
||||
Message: "Item 3",
|
||||
FirstTimestamp: metav1.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)),
|
||||
LastTimestamp: metav1.NewTime(time.Date(2002, time.December, 25, 0, 0, 0, 0, time.UTC)),
|
||||
Count: 1,
|
||||
Type: api.EventTypeNormal,
|
||||
Type: corev1.EventTypeNormal,
|
||||
},
|
||||
})
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["fieldpath.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/util/fieldpath",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package fieldpath
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
)
|
||||
|
||||
// TODO(yue9944882): Remove this helper package once it's copied to k/apimachinery
|
||||
|
||||
// FormatMap formats map[string]string to a string.
|
||||
func FormatMap(m map[string]string) (fmtStr string) {
|
||||
// output with keys in sorted order to provide stable output
|
||||
keys := sets.NewString()
|
||||
for key := range m {
|
||||
keys.Insert(key)
|
||||
}
|
||||
for _, key := range keys.List() {
|
||||
fmtStr += fmt.Sprintf("%v=%q\n", key, m[key])
|
||||
}
|
||||
fmtStr = strings.TrimSuffix(fmtStr, "\n")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ExtractFieldPathAsString extracts the field from the given object
|
||||
// and returns it as a string. The object must be a pointer to an
|
||||
// API type.
|
||||
func ExtractFieldPathAsString(obj interface{}, fieldPath string) (string, error) {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if path, subscript, ok := SplitMaybeSubscriptedPath(fieldPath); ok {
|
||||
switch path {
|
||||
case "metadata.annotations":
|
||||
if errs := validation.IsQualifiedName(strings.ToLower(subscript)); len(errs) != 0 {
|
||||
return "", fmt.Errorf("invalid key subscript in %s: %s", fieldPath, strings.Join(errs, ";"))
|
||||
}
|
||||
return accessor.GetAnnotations()[subscript], nil
|
||||
case "metadata.labels":
|
||||
if errs := validation.IsQualifiedName(subscript); len(errs) != 0 {
|
||||
return "", fmt.Errorf("invalid key subscript in %s: %s", fieldPath, strings.Join(errs, ";"))
|
||||
}
|
||||
return accessor.GetLabels()[subscript], nil
|
||||
default:
|
||||
return "", fmt.Errorf("fieldPath %q does not support subscript", fieldPath)
|
||||
}
|
||||
}
|
||||
|
||||
switch fieldPath {
|
||||
case "metadata.annotations":
|
||||
return FormatMap(accessor.GetAnnotations()), nil
|
||||
case "metadata.labels":
|
||||
return FormatMap(accessor.GetLabels()), nil
|
||||
case "metadata.name":
|
||||
return accessor.GetName(), nil
|
||||
case "metadata.namespace":
|
||||
return accessor.GetNamespace(), nil
|
||||
case "metadata.uid":
|
||||
return string(accessor.GetUID()), nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("unsupported fieldPath: %v", fieldPath)
|
||||
}
|
||||
|
||||
// SplitMaybeSubscriptedPath checks whether the specified fieldPath is
|
||||
// subscripted, and
|
||||
// - if yes, this function splits the fieldPath into path and subscript, and
|
||||
// returns (path, subscript, true).
|
||||
// - if no, this function returns (fieldPath, "", false).
|
||||
//
|
||||
// Example inputs and outputs:
|
||||
// - "metadata.annotations['myKey']" --> ("metadata.annotations", "myKey", true)
|
||||
// - "metadata.annotations['a[b]c']" --> ("metadata.annotations", "a[b]c", true)
|
||||
// - "metadata.labels['']" --> ("metadata.labels", "", true)
|
||||
// - "metadata.labels" --> ("metadata.labels", "", false)
|
||||
func SplitMaybeSubscriptedPath(fieldPath string) (string, string, bool) {
|
||||
if !strings.HasSuffix(fieldPath, "']") {
|
||||
return fieldPath, "", false
|
||||
}
|
||||
s := strings.TrimSuffix(fieldPath, "']")
|
||||
parts := strings.SplitN(s, "['", 2)
|
||||
if len(parts) < 2 {
|
||||
return fieldPath, "", false
|
||||
}
|
||||
if len(parts[0]) == 0 {
|
||||
return fieldPath, "", false
|
||||
}
|
||||
return parts[0], parts[1], true
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["qos.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/util/qos",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package qos
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
var supportedQoSComputeResources = sets.NewString(string(core.ResourceCPU), string(core.ResourceMemory))
|
||||
|
||||
func isSupportedQoSComputeResource(name v1.ResourceName) bool {
|
||||
return supportedQoSComputeResources.Has(string(name))
|
||||
}
|
||||
|
||||
// GetPodQOS returns the QoS class of a pod.
|
||||
// A pod is besteffort if none of its containers have specified any requests or limits.
|
||||
// A pod is guaranteed only when requests and limits are specified for all the containers and they are equal.
|
||||
// A pod is burstable if limits and requests do not match across all containers.
|
||||
func GetPodQOS(pod *v1.Pod) v1.PodQOSClass {
|
||||
requests := v1.ResourceList{}
|
||||
limits := v1.ResourceList{}
|
||||
zeroQuantity := resource.MustParse("0")
|
||||
isGuaranteed := true
|
||||
for _, container := range pod.Spec.Containers {
|
||||
// process requests
|
||||
for name, quantity := range container.Resources.Requests {
|
||||
if !isSupportedQoSComputeResource(name) {
|
||||
continue
|
||||
}
|
||||
if quantity.Cmp(zeroQuantity) == 1 {
|
||||
delta := quantity.Copy()
|
||||
if _, exists := requests[name]; !exists {
|
||||
requests[name] = *delta
|
||||
} else {
|
||||
delta.Add(requests[name])
|
||||
requests[name] = *delta
|
||||
}
|
||||
}
|
||||
}
|
||||
// process limits
|
||||
qosLimitsFound := sets.NewString()
|
||||
for name, quantity := range container.Resources.Limits {
|
||||
if !isSupportedQoSComputeResource(name) {
|
||||
continue
|
||||
}
|
||||
if quantity.Cmp(zeroQuantity) == 1 {
|
||||
qosLimitsFound.Insert(string(name))
|
||||
delta := quantity.Copy()
|
||||
if _, exists := limits[name]; !exists {
|
||||
limits[name] = *delta
|
||||
} else {
|
||||
delta.Add(limits[name])
|
||||
limits[name] = *delta
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !qosLimitsFound.HasAll(string(v1.ResourceMemory), string(v1.ResourceCPU)) {
|
||||
isGuaranteed = false
|
||||
}
|
||||
}
|
||||
if len(requests) == 0 && len(limits) == 0 {
|
||||
return v1.PodQOSBestEffort
|
||||
}
|
||||
// Check is requests match limits for all resources.
|
||||
if isGuaranteed {
|
||||
for name, req := range requests {
|
||||
if lim, exists := limits[name]; !exists || lim.Cmp(req) != 0 {
|
||||
isGuaranteed = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if isGuaranteed &&
|
||||
len(requests) == len(limits) {
|
||||
return v1.PodQOSGuaranteed
|
||||
}
|
||||
return v1.PodQOSBurstable
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["rbac.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/util/rbac",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//staging/src/k8s.io/api/rbac/v1:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package rbac
|
||||
|
||||
import (
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type simpleResource struct {
|
||||
Group string
|
||||
Resource string
|
||||
ResourceNameExist bool
|
||||
ResourceName string
|
||||
}
|
||||
|
||||
// CompactRules combines rules that contain a single APIGroup/Resource, differ only by verb, and contain no other attributes.
|
||||
// this is a fast check, and works well with the decomposed "missing rules" list from a Covers check.
|
||||
func CompactRules(rules []rbacv1.PolicyRule) ([]rbacv1.PolicyRule, error) {
|
||||
compacted := make([]rbacv1.PolicyRule, 0, len(rules))
|
||||
|
||||
simpleRules := map[simpleResource]*rbacv1.PolicyRule{}
|
||||
for _, rule := range rules {
|
||||
if resource, isSimple := isSimpleResourceRule(&rule); isSimple {
|
||||
if existingRule, ok := simpleRules[resource]; ok {
|
||||
// Add the new verbs to the existing simple resource rule
|
||||
if existingRule.Verbs == nil {
|
||||
existingRule.Verbs = []string{}
|
||||
}
|
||||
existingRule.Verbs = append(existingRule.Verbs, rule.Verbs...)
|
||||
} else {
|
||||
// Copy the rule to accumulate matching simple resource rules into
|
||||
simpleRules[resource] = rule.DeepCopy()
|
||||
}
|
||||
} else {
|
||||
compacted = append(compacted, rule)
|
||||
}
|
||||
}
|
||||
|
||||
// Once we've consolidated the simple resource rules, add them to the compacted list
|
||||
for _, simpleRule := range simpleRules {
|
||||
compacted = append(compacted, *simpleRule)
|
||||
}
|
||||
|
||||
return compacted, nil
|
||||
}
|
||||
|
||||
// isSimpleResourceRule returns true if the given rule contains verbs, a single resource, a single API group, at most one Resource Name, and no other values
|
||||
func isSimpleResourceRule(rule *rbacv1.PolicyRule) (simpleResource, bool) {
|
||||
resource := simpleResource{}
|
||||
|
||||
// If we have "complex" rule attributes, return early without allocations or expensive comparisons
|
||||
if len(rule.ResourceNames) > 1 || len(rule.NonResourceURLs) > 0 {
|
||||
return resource, false
|
||||
}
|
||||
// If we have multiple api groups or resources, return early
|
||||
if len(rule.APIGroups) != 1 || len(rule.Resources) != 1 {
|
||||
return resource, false
|
||||
}
|
||||
|
||||
// Test if this rule only contains APIGroups/Resources/Verbs/ResourceNames
|
||||
simpleRule := &rbacv1.PolicyRule{APIGroups: rule.APIGroups, Resources: rule.Resources, Verbs: rule.Verbs, ResourceNames: rule.ResourceNames}
|
||||
if !reflect.DeepEqual(simpleRule, rule) {
|
||||
return resource, false
|
||||
}
|
||||
|
||||
if len(rule.ResourceNames) == 0 {
|
||||
resource = simpleResource{Group: rule.APIGroups[0], Resource: rule.Resources[0], ResourceNameExist: false}
|
||||
} else {
|
||||
resource = simpleResource{Group: rule.APIGroups[0], Resource: rule.Resources[0], ResourceNameExist: true, ResourceName: rule.ResourceNames[0]}
|
||||
}
|
||||
|
||||
return resource, true
|
||||
}
|
||||
|
||||
// BreakdownRule takes a rule and builds an equivalent list of rules that each have at most one verb, one
|
||||
// resource, and one resource name
|
||||
func BreakdownRule(rule rbacv1.PolicyRule) []rbacv1.PolicyRule {
|
||||
subrules := []rbacv1.PolicyRule{}
|
||||
for _, group := range rule.APIGroups {
|
||||
for _, resource := range rule.Resources {
|
||||
for _, verb := range rule.Verbs {
|
||||
if len(rule.ResourceNames) > 0 {
|
||||
for _, resourceName := range rule.ResourceNames {
|
||||
subrules = append(subrules, rbacv1.PolicyRule{APIGroups: []string{group}, Resources: []string{resource}, Verbs: []string{verb}, ResourceNames: []string{resourceName}})
|
||||
}
|
||||
|
||||
} else {
|
||||
subrules = append(subrules, rbacv1.PolicyRule{APIGroups: []string{group}, Resources: []string{resource}, Verbs: []string{verb}})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Non-resource URLs are unique because they only combine with verbs.
|
||||
for _, nonResourceURL := range rule.NonResourceURLs {
|
||||
for _, verb := range rule.Verbs {
|
||||
subrules = append(subrules, rbacv1.PolicyRule{NonResourceURLs: []string{nonResourceURL}, Verbs: []string{verb}})
|
||||
}
|
||||
}
|
||||
|
||||
return subrules
|
||||
}
|
||||
|
||||
// SortableRuleSlice is used to sort rule slice
|
||||
type SortableRuleSlice []rbacv1.PolicyRule
|
||||
|
||||
func (s SortableRuleSlice) Len() int { return len(s) }
|
||||
func (s SortableRuleSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s SortableRuleSlice) Less(i, j int) bool {
|
||||
return strings.Compare(s[i].String(), s[j].String()) < 0
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["resource.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/util/resource",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
// PodRequestsAndLimits returns a dictionary of all defined resources summed up for all
|
||||
// containers of the pod.
|
||||
func PodRequestsAndLimits(pod *v1.Pod) (reqs, limits v1.ResourceList) {
|
||||
reqs, limits = v1.ResourceList{}, v1.ResourceList{}
|
||||
for _, container := range pod.Spec.Containers {
|
||||
addResourceList(reqs, container.Resources.Requests)
|
||||
addResourceList(limits, container.Resources.Limits)
|
||||
}
|
||||
// init containers define the minimum of any resource
|
||||
for _, container := range pod.Spec.InitContainers {
|
||||
maxResourceList(reqs, container.Resources.Requests)
|
||||
maxResourceList(limits, container.Resources.Limits)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// addResourceList adds the resources in newList to list
|
||||
func addResourceList(list, new v1.ResourceList) {
|
||||
for name, quantity := range new {
|
||||
if value, ok := list[name]; !ok {
|
||||
list[name] = *quantity.Copy()
|
||||
} else {
|
||||
value.Add(quantity)
|
||||
list[name] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// maxResourceList sets list to the greater of list/newList for every resource
|
||||
// either list
|
||||
func maxResourceList(list, new v1.ResourceList) {
|
||||
for name, quantity := range new {
|
||||
if value, ok := list[name]; !ok {
|
||||
list[name] = *quantity.Copy()
|
||||
continue
|
||||
} else {
|
||||
if quantity.Cmp(value) > 0 {
|
||||
list[name] = *quantity.Copy()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ExtractContainerResourceValue extracts the value of a resource
|
||||
// in an already known container
|
||||
func ExtractContainerResourceValue(fs *v1.ResourceFieldSelector, container *v1.Container) (string, error) {
|
||||
divisor := resource.Quantity{}
|
||||
if divisor.Cmp(fs.Divisor) == 0 {
|
||||
divisor = resource.MustParse("1")
|
||||
} else {
|
||||
divisor = fs.Divisor
|
||||
}
|
||||
|
||||
switch fs.Resource {
|
||||
case "limits.cpu":
|
||||
return convertResourceCPUToString(container.Resources.Limits.Cpu(), divisor)
|
||||
case "limits.memory":
|
||||
return convertResourceMemoryToString(container.Resources.Limits.Memory(), divisor)
|
||||
case "limits.ephemeral-storage":
|
||||
return convertResourceEphemeralStorageToString(container.Resources.Limits.StorageEphemeral(), divisor)
|
||||
case "requests.cpu":
|
||||
return convertResourceCPUToString(container.Resources.Requests.Cpu(), divisor)
|
||||
case "requests.memory":
|
||||
return convertResourceMemoryToString(container.Resources.Requests.Memory(), divisor)
|
||||
case "requests.ephemeral-storage":
|
||||
return convertResourceEphemeralStorageToString(container.Resources.Requests.StorageEphemeral(), divisor)
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Unsupported container resource : %v", fs.Resource)
|
||||
}
|
||||
|
||||
// convertResourceCPUToString converts cpu value to the format of divisor and returns
|
||||
// ceiling of the value.
|
||||
func convertResourceCPUToString(cpu *resource.Quantity, divisor resource.Quantity) (string, error) {
|
||||
c := int64(math.Ceil(float64(cpu.MilliValue()) / float64(divisor.MilliValue())))
|
||||
return strconv.FormatInt(c, 10), nil
|
||||
}
|
||||
|
||||
// convertResourceMemoryToString converts memory value to the format of divisor and returns
|
||||
// ceiling of the value.
|
||||
func convertResourceMemoryToString(memory *resource.Quantity, divisor resource.Quantity) (string, error) {
|
||||
m := int64(math.Ceil(float64(memory.Value()) / float64(divisor.Value())))
|
||||
return strconv.FormatInt(m, 10), nil
|
||||
}
|
||||
|
||||
// convertResourceEphemeralStorageToString converts ephemeral storage value to the format of divisor and returns
|
||||
// ceiling of the value.
|
||||
func convertResourceEphemeralStorageToString(ephemeralStorage *resource.Quantity, divisor resource.Quantity) (string, error) {
|
||||
m := int64(math.Ceil(float64(ephemeralStorage.Value()) / float64(divisor.Value())))
|
||||
return strconv.FormatInt(m, 10), nil
|
||||
}
|
||||
|
||||
var standardContainerResources = sets.NewString(
|
||||
string(v1.ResourceCPU),
|
||||
string(v1.ResourceMemory),
|
||||
string(v1.ResourceEphemeralStorage),
|
||||
)
|
||||
|
||||
// IsStandardContainerResourceName returns true if the container can make a resource request
|
||||
// for the specified resource
|
||||
func IsStandardContainerResourceName(str string) bool {
|
||||
return standardContainerResources.Has(str) || IsHugePageResourceName(v1.ResourceName(str))
|
||||
}
|
||||
|
||||
// IsHugePageResourceName returns true if the resource name has the huge page
|
||||
// resource prefix.
|
||||
func IsHugePageResourceName(name v1.ResourceName) bool {
|
||||
return strings.HasPrefix(string(name), v1.ResourceHugePagesPrefix)
|
||||
}
|
|
@ -22,3 +22,17 @@ import (
|
|||
|
||||
// SortInts64 sorts []int64 in increasing order
|
||||
func SortInts64(a []int64) { sort.Slice(a, func(i, j int) bool { return a[i] < a[j] }) }
|
||||
|
||||
// ContainsString checks if a given slice of strings contains the provided string.
|
||||
// If a modifier func is provided, it is called with the slice item before the comparation.
|
||||
func ContainsString(slice []string, s string, modifier func(s string) string) bool {
|
||||
for _, item := range slice {
|
||||
if item == s {
|
||||
return true
|
||||
}
|
||||
if modifier != nil && modifier(item) == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["storage.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/util/storage",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TODO(yue9944882): Remove this helper package once it's copied to k/api
|
||||
|
||||
// IsDefaultStorageClassAnnotation represents a StorageClass annotation that
|
||||
// marks a class as the default StorageClass
|
||||
const IsDefaultStorageClassAnnotation = "storageclass.kubernetes.io/is-default-class"
|
||||
|
||||
// BetaIsDefaultStorageClassAnnotation is the beta version of BetaIsDefaultStorageClassAnnotation.
|
||||
const BetaIsDefaultStorageClassAnnotation = "storageclass.beta.kubernetes.io/is-default-class"
|
||||
|
||||
// IsDefaultAnnotationText returns a pretty Yes/No String if
|
||||
// the annotation is set
|
||||
func IsDefaultAnnotationText(obj metav1.ObjectMeta) string {
|
||||
if obj.Annotations[IsDefaultStorageClassAnnotation] == "true" {
|
||||
return "Yes"
|
||||
}
|
||||
if obj.Annotations[BetaIsDefaultStorageClassAnnotation] == "true" {
|
||||
return "Yes"
|
||||
}
|
||||
|
||||
return "No"
|
||||
}
|
||||
|
||||
// GetAccessModesAsString returns a string representation of an array of access modes.
|
||||
// modes, when present, are always in the same order: RWO,ROX,RWX.
|
||||
func GetAccessModesAsString(modes []v1.PersistentVolumeAccessMode) string {
|
||||
modes = removeDuplicateAccessModes(modes)
|
||||
modesStr := []string{}
|
||||
if containsAccessMode(modes, v1.ReadWriteOnce) {
|
||||
modesStr = append(modesStr, "RWO")
|
||||
}
|
||||
if containsAccessMode(modes, v1.ReadOnlyMany) {
|
||||
modesStr = append(modesStr, "ROX")
|
||||
}
|
||||
if containsAccessMode(modes, v1.ReadWriteMany) {
|
||||
modesStr = append(modesStr, "RWX")
|
||||
}
|
||||
return strings.Join(modesStr, ",")
|
||||
}
|
||||
|
||||
// removeDuplicateAccessModes returns an array of access modes without any duplicates
|
||||
func removeDuplicateAccessModes(modes []v1.PersistentVolumeAccessMode) []v1.PersistentVolumeAccessMode {
|
||||
accessModes := []v1.PersistentVolumeAccessMode{}
|
||||
for _, m := range modes {
|
||||
if !containsAccessMode(accessModes, m) {
|
||||
accessModes = append(accessModes, m)
|
||||
}
|
||||
}
|
||||
return accessModes
|
||||
}
|
||||
|
||||
func containsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
|
||||
for _, m := range modes {
|
||||
if m == mode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// GetPersistentVolumeClass returns StorageClassName.
|
||||
func GetPersistentVolumeClass(volume *v1.PersistentVolume) string {
|
||||
// Use beta annotation first
|
||||
if class, found := volume.Annotations[v1.BetaStorageClassAnnotation]; found {
|
||||
return class
|
||||
}
|
||||
|
||||
return volume.Spec.StorageClassName
|
||||
}
|
||||
|
||||
// GetPersistentVolumeClaimClass returns StorageClassName. If no storage class was
|
||||
// requested, it returns "".
|
||||
func GetPersistentVolumeClaimClass(claim *v1.PersistentVolumeClaim) string {
|
||||
// Use beta annotation first
|
||||
if class, found := claim.Annotations[v1.BetaStorageClassAnnotation]; found {
|
||||
return class
|
||||
}
|
||||
|
||||
if claim.Spec.StorageClassName != nil {
|
||||
return *claim.Spec.StorageClassName
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package printers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
@ -58,36 +57,3 @@ type PrintOptions struct {
|
|||
// indicates if it is OK to ignore missing keys for rendering an output template.
|
||||
AllowMissingKeys bool
|
||||
}
|
||||
|
||||
// Describer generates output for the named resource or an error
|
||||
// if the output could not be generated. Implementers typically
|
||||
// abstract the retrieval of the named object from a remote server.
|
||||
type Describer interface {
|
||||
Describe(namespace, name string, describerSettings DescriberSettings) (output string, err error)
|
||||
}
|
||||
|
||||
// DescriberSettings holds display configuration for each object
|
||||
// describer to control what is printed.
|
||||
type DescriberSettings struct {
|
||||
ShowEvents bool
|
||||
}
|
||||
|
||||
// ObjectDescriber is an interface for displaying arbitrary objects with extra
|
||||
// information. Use when an object is in hand (on disk, or already retrieved).
|
||||
// Implementers may ignore the additional information passed on extra, or use it
|
||||
// by default. ObjectDescribers may return ErrNoDescriber if no suitable describer
|
||||
// is found.
|
||||
type ObjectDescriber interface {
|
||||
DescribeObject(object interface{}, extra ...interface{}) (output string, err error)
|
||||
}
|
||||
|
||||
// ErrNoDescriber is a structured error indicating the provided object or objects
|
||||
// cannot be described.
|
||||
type ErrNoDescriber struct {
|
||||
Types []string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e ErrNoDescriber) Error() string {
|
||||
return fmt.Sprintf("no describer has been defined for %v", e.Types)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ load(
|
|||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"describe_test.go",
|
||||
"printers_test.go",
|
||||
"sorted_resource_name_list_test.go",
|
||||
],
|
||||
|
@ -23,16 +22,11 @@ go_test(
|
|||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/networking:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/apis/scheduling:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
|
@ -45,8 +39,6 @@ go_test(
|
|||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/printers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -54,40 +46,42 @@ go_test(
|
|||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"describe.go",
|
||||
"import_known_versions.go",
|
||||
"printers.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/printers/internalversion",
|
||||
deps = [
|
||||
"//pkg/api/events:go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/api/ref:go_default_library",
|
||||
"//pkg/api/resource:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/apps/install:go_default_library",
|
||||
"//pkg/apis/authentication/install:go_default_library",
|
||||
"//pkg/apis/authorization/install:go_default_library",
|
||||
"//pkg/apis/autoscaling:go_default_library",
|
||||
"//pkg/apis/autoscaling/install:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/batch/install:go_default_library",
|
||||
"//pkg/apis/certificates:go_default_library",
|
||||
"//pkg/apis/certificates/install:go_default_library",
|
||||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/coordination/install:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//pkg/apis/core/helper/qos:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/apis/events/install:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/extensions/install:go_default_library",
|
||||
"//pkg/apis/networking:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/apis/policy/install:go_default_library",
|
||||
"//pkg/apis/rbac:go_default_library",
|
||||
"//pkg/apis/rbac/v1:go_default_library",
|
||||
"//pkg/apis/rbac/install:go_default_library",
|
||||
"//pkg/apis/scheduling:go_default_library",
|
||||
"//pkg/apis/scheduling/install:go_default_library",
|
||||
"//pkg/apis/settings/install:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/apis/storage/install:go_default_library",
|
||||
"//pkg/apis/storage/util:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||
"//pkg/controller/deployment/util:go_default_library",
|
||||
"//pkg/fieldpath:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/registry/rbac/validation:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//pkg/util/slice:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
||||
|
@ -97,28 +91,17 @@ go_library(
|
|||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/scheduling/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/fields:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//vendor/github.com/fatih/camelcase:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package internalversion
|
||||
|
||||
// These imports are the API groups the client will support.
|
||||
// TODO: Remove these manual install once we don't need legacy scheme in get comman
|
||||
import (
|
||||
_ "k8s.io/kubernetes/pkg/apis/apps/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authentication/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authorization/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/batch/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/certificates/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/coordination/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/events/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/policy/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/rbac/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/scheduling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/settings/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/storage/install"
|
||||
)
|
|
@ -1965,3 +1965,33 @@ func printPriorityClassList(list *scheduling.PriorityClassList, options printers
|
|||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printBoolPtr(value *bool) string {
|
||||
if value != nil {
|
||||
return printBool(*value)
|
||||
}
|
||||
|
||||
return "<unset>"
|
||||
}
|
||||
|
||||
func printBool(value bool) string {
|
||||
if value {
|
||||
return "True"
|
||||
}
|
||||
|
||||
return "False"
|
||||
}
|
||||
|
||||
type SortableResourceNames []api.ResourceName
|
||||
|
||||
func (list SortableResourceNames) Len() int {
|
||||
return len(list)
|
||||
}
|
||||
|
||||
func (list SortableResourceNames) Swap(i, j int) {
|
||||
list[i], list[j] = list[j], list[i]
|
||||
}
|
||||
|
||||
func (list SortableResourceNames) Less(i, j int) bool {
|
||||
return list[i] < list[j]
|
||||
}
|
||||
|
|
|
@ -3569,3 +3569,27 @@ func verifyTable(t *testing.T, table *metav1beta1.Table) {
|
|||
t.Errorf("unexpected panic during deepcopy of table %#v: %v", table, panicErr)
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyDatesInOrder checks the start of each line for a RFC1123Z date
|
||||
// and posts error if all subsequent dates are not equal or increasing
|
||||
func VerifyDatesInOrder(
|
||||
resultToTest, rowDelimiter, columnDelimiter string, t *testing.T) {
|
||||
lines := strings.Split(resultToTest, rowDelimiter)
|
||||
var previousTime time.Time
|
||||
for _, str := range lines {
|
||||
columns := strings.Split(str, columnDelimiter)
|
||||
if len(columns) > 0 {
|
||||
currentTime, err := time.Parse(time.RFC1123Z, columns[0])
|
||||
if err == nil {
|
||||
if previousTime.After(currentTime) {
|
||||
t.Errorf(
|
||||
"Output is not sorted by time. %s should be listed after %s. Complete output: %s",
|
||||
previousTime.Format(time.RFC1123Z),
|
||||
currentTime.Format(time.RFC1123Z),
|
||||
resultToTest)
|
||||
}
|
||||
previousTime = currentTime
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue