mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	prune internal clients from kubectl describer
This commit is contained in:
		@@ -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",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								pkg/kubectl/cmd/convert/import_known_versions.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								pkg/kubectl/cmd/convert/import_known_versions.go
									
									
									
									
									
										Normal file
									
								
							@@ -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)
 | 
			
		||||
							
								
								
									
										71
									
								
								pkg/kubectl/describe/interface.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								pkg/kubectl/describe/interface.go
									
									
									
									
									
										Normal file
									
								
							@@ -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",
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								pkg/kubectl/util/certificate/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								pkg/kubectl/util/certificate/BUILD
									
									
									
									
									
										Normal file
									
								
							@@ -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"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										42
									
								
								pkg/kubectl/util/certificate/certificate.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								pkg/kubectl/util/certificate/certificate.go
									
									
									
									
									
										Normal file
									
								
							@@ -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,
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								pkg/kubectl/util/fieldpath/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								pkg/kubectl/util/fieldpath/BUILD
									
									
									
									
									
										Normal file
									
								
							@@ -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"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										111
									
								
								pkg/kubectl/util/fieldpath/fieldpath.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								pkg/kubectl/util/fieldpath/fieldpath.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								pkg/kubectl/util/qos/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								pkg/kubectl/util/qos/BUILD
									
									
									
									
									
										Normal file
									
								
							@@ -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"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										96
									
								
								pkg/kubectl/util/qos/qos.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								pkg/kubectl/util/qos/qos.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								pkg/kubectl/util/rbac/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								pkg/kubectl/util/rbac/BUILD
									
									
									
									
									
										Normal file
									
								
							@@ -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"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										128
									
								
								pkg/kubectl/util/rbac/rbac.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								pkg/kubectl/util/rbac/rbac.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								pkg/kubectl/util/resource/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								pkg/kubectl/util/resource/BUILD
									
									
									
									
									
										Normal file
									
								
							@@ -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"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										138
									
								
								pkg/kubectl/util/resource/resource.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								pkg/kubectl/util/resource/resource.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								pkg/kubectl/util/storage/BUILD
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								pkg/kubectl/util/storage/BUILD
									
									
									
									
									
										Normal file
									
								
							@@ -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"],
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										107
									
								
								pkg/kubectl/util/storage/storage.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								pkg/kubectl/util/storage/storage.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
											
										
									
								
							
							
								
								
									
										37
									
								
								pkg/printers/internalversion/import_known_versions.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								pkg/printers/internalversion/import_known_versions.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user