Merge pull request #78764 from bart0sh/PR0070-kubeadm-structured-output-v2

Structured output for 'kubeadm token list'
This commit is contained in:
Kubernetes Prow Robot 2019-10-09 14:50:54 -07:00 committed by GitHub
commit a7e0b768ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1194 additions and 43 deletions

View File

@ -29,6 +29,7 @@ filegroup(
srcs = [
":package-srcs",
"//cmd/kubeadm/app/apis/kubeadm:all-srcs",
"//cmd/kubeadm/app/apis/output:all-srcs",
"//cmd/kubeadm/app/cmd:all-srcs",
"//cmd/kubeadm/app/componentconfigs:all-srcs",
"//cmd/kubeadm/app/constants:all-srcs",

View File

@ -0,0 +1,38 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"register.go",
"types.go",
"zz_generated.deepcopy.go",
],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/output",
visibility = ["//visibility:public"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm/v1beta2:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//cmd/kubeadm/app/apis/output/fuzzer:all-srcs",
"//cmd/kubeadm/app/apis/output/scheme:all-srcs",
"//cmd/kubeadm/app/apis/output/v1alpha1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,24 @@
/*
Copyright 2019 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.
*/
// +k8s:deepcopy-gen=package
// +groupName=output.kubeadm.k8s.io
// Package output implements the kubeadm structured output
// The purpose of the kubeadm structured output is to have a well
// defined versioned output format that other software that uses
// kubeadm for cluster deployments can use and rely on.
package output // import "k8s.io/kubernetes/cmd/kubeadm/app/apis/output"

View File

@ -0,0 +1,43 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_library(
name = "go_default_library",
srcs = ["fuzzer.go"],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/fuzzer",
deps = [
"//cmd/kubeadm/app/apis/kubeadm/v1beta2:go_default_library",
"//cmd/kubeadm/app/apis/output:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//vendor/github.com/google/gofuzz:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
go_test(
name = "go_default_test",
srcs = ["fuzzer_test.go"],
embed = [":go_default_library"],
deps = [
"//cmd/kubeadm/app/apis/output/scheme:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/apitesting/roundtrip:go_default_library",
],
)

View File

@ -0,0 +1,45 @@
/*
Copyright 2019 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 fuzzer
import (
"time"
fuzz "github.com/google/gofuzz"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/output"
)
// Funcs returns the fuzzer functions for the kubeadm apis.
func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
return []interface{}{
fuzzBootstrapToken,
}
}
func fuzzBootstrapToken(obj *output.BootstrapToken, c fuzz.Continue) {
c.FuzzNoCustom(obj)
obj.ObjectMeta = metav1.ObjectMeta{}
obj.Token = &kubeadmapiv1beta2.BootstrapTokenString{ID: "uvxdac", Secret: "fq35fuyue3kd4gda"}
obj.Description = ""
obj.TTL = &metav1.Duration{Duration: time.Hour * 24}
obj.Usages = []string{"authentication", "signing"}
obj.Groups = []string{"system:bootstrappers:kubeadm:default-node-token"}
}

View File

@ -0,0 +1,28 @@
/*
Copyright 2019 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 fuzzer
import (
"testing"
"k8s.io/apimachinery/pkg/api/apitesting/roundtrip"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme"
)
func TestRoundTripTypes(t *testing.T) {
roundtrip.RoundTripTestForAPIGroup(t, scheme.AddToScheme, Funcs)
}

View File

@ -0,0 +1,52 @@
/*
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 output
import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "output.kubeadm.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal}
var (
// SchemeBuilder points to a list of functions added to Scheme.
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
// AddToScheme applies all the stored functions to the scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&BootstrapToken{},
)
return nil
}

View File

@ -0,0 +1,31 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["scheme.go"],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme",
visibility = ["//visibility:public"],
deps = [
"//cmd/kubeadm/app/apis/output:go_default_library",
"//cmd/kubeadm/app/apis/output/v1alpha1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1: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/runtime/serializer:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime: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"],
)

View File

@ -0,0 +1,45 @@
/*
Copyright 2019 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 scheme
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/output"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha1"
)
// Scheme is the runtime.Scheme to which all kubeadm api types are registered.
var Scheme = runtime.NewScheme()
// Codecs provides access to encoding and decoding for the scheme.
var Codecs = serializer.NewCodecFactory(Scheme)
func init() {
metav1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
AddToScheme(Scheme)
}
// AddToScheme builds the kubeadm scheme using all known versions of the kubeadm api.
func AddToScheme(scheme *runtime.Scheme) {
utilruntime.Must(output.AddToScheme(scheme))
utilruntime.Must(v1alpha1.AddToScheme(scheme))
utilruntime.Must(scheme.SetVersionPriority(v1alpha1.SchemeGroupVersion))
}

View File

@ -0,0 +1,34 @@
/*
Copyright 2019 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 output
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// BootstrapToken represents information for the output produced by 'kubeadm token list'
// This is a copy of BoostrapToken struct from ../kubeadm/types.go with 2 additions:
// metav1.TypeMeta and metav1.ObjectMeta
type BootstrapToken struct {
metav1.TypeMeta
metav1.ObjectMeta
kubeadmapiv1beta2.BootstrapToken
}

View File

@ -0,0 +1,38 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"defaults.go",
"doc.go",
"register.go",
"types.go",
"zz_generated.conversion.go",
"zz_generated.deepcopy.go",
"zz_generated.defaults.go",
],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha1",
visibility = ["//visibility:public"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm/v1beta2:go_default_library",
"//cmd/kubeadm/app/apis/output:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema: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"],
)

View File

@ -0,0 +1,25 @@
/*
Copyright 2019 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 v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime"
)
func addDefaultingFuncs(scheme *runtime.Scheme) error {
return RegisterDefaults(scheme)
}

View File

@ -0,0 +1,27 @@
/*
Copyright 2019 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.
*/
// +k8s:defaulter-gen=TypeMeta
// +groupName=output.kubeadm.k8s.io
// +k8s:deepcopy-gen=package
// +k8s:conversion-gen=k8s.io/kubernetes/cmd/kubeadm/app/apis/output
// Package v1alpha1 defines the v1alpha1 version of the kubeadm data structures
// related to structured output
// The purpose of the kubeadm structured output is to have a well
// defined versioned output format that other software that uses
// kubeadm for cluster deployments can use and rely on.
package v1alpha1 // import "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha1"

View File

@ -0,0 +1,65 @@
/*
Copyright 2019 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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
// GroupName is the group name use in this package
const GroupName = "output.kubeadm.k8s.io"
// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
// SchemeBuilder points to a list of functions added to Scheme.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
// AddToScheme applies all the stored functions to the scheme.
AddToScheme = localSchemeBuilder.AddToScheme
)
func init() {
// We only register manually written functions here. The registration of the
// generated functions takes place in the generated files. The separation
// makes the code compile even when the generated files are missing.
localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs)
}
// Kind takes an unqualified kind and returns a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}
// Resource takes an unqualified resource and returns a Group qualified GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&BootstrapToken{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}

View File

@ -0,0 +1,34 @@
/*
Copyright 2019 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 v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// BootstrapToken represents information for the bootstrap token output produced by kubeadm
// This is a copy of BoostrapToken struct from ../kubeadm/types.go with 2 additions:
// metav1.TypeMeta and metav1.ObjectMeta
type BootstrapToken struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:",inline"`
kubeadmapiv1beta2.BootstrapToken
}

View File

@ -0,0 +1,69 @@
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by conversion-gen. DO NOT EDIT.
package v1alpha1
import (
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
output "k8s.io/kubernetes/cmd/kubeadm/app/apis/output"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(s *runtime.Scheme) error {
if err := s.AddGeneratedConversionFunc((*BootstrapToken)(nil), (*output.BootstrapToken)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_v1alpha1_BootstrapToken_To_output_BootstrapToken(a.(*BootstrapToken), b.(*output.BootstrapToken), scope)
}); err != nil {
return err
}
if err := s.AddGeneratedConversionFunc((*output.BootstrapToken)(nil), (*BootstrapToken)(nil), func(a, b interface{}, scope conversion.Scope) error {
return Convert_output_BootstrapToken_To_v1alpha1_BootstrapToken(a.(*output.BootstrapToken), b.(*BootstrapToken), scope)
}); err != nil {
return err
}
return nil
}
func autoConvert_v1alpha1_BootstrapToken_To_output_BootstrapToken(in *BootstrapToken, out *output.BootstrapToken, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.BootstrapToken = in.BootstrapToken
return nil
}
// Convert_v1alpha1_BootstrapToken_To_output_BootstrapToken is an autogenerated conversion function.
func Convert_v1alpha1_BootstrapToken_To_output_BootstrapToken(in *BootstrapToken, out *output.BootstrapToken, s conversion.Scope) error {
return autoConvert_v1alpha1_BootstrapToken_To_output_BootstrapToken(in, out, s)
}
func autoConvert_output_BootstrapToken_To_v1alpha1_BootstrapToken(in *output.BootstrapToken, out *BootstrapToken, s conversion.Scope) error {
out.ObjectMeta = in.ObjectMeta
out.BootstrapToken = in.BootstrapToken
return nil
}
// Convert_output_BootstrapToken_To_v1alpha1_BootstrapToken is an autogenerated conversion function.
func Convert_output_BootstrapToken_To_v1alpha1_BootstrapToken(in *output.BootstrapToken, out *BootstrapToken, s conversion.Scope) error {
return autoConvert_output_BootstrapToken_To_v1alpha1_BootstrapToken(in, out, s)
}

View File

@ -0,0 +1,52 @@
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BootstrapToken) DeepCopyInto(out *BootstrapToken) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.BootstrapToken.DeepCopyInto(&out.BootstrapToken)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapToken.
func (in *BootstrapToken) DeepCopy() *BootstrapToken {
if in == nil {
return nil
}
out := new(BootstrapToken)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *BootstrapToken) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@ -0,0 +1,38 @@
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by defaulter-gen. DO NOT EDIT.
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
v1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
)
// RegisterDefaults adds defaulters functions to the given scheme.
// Public to allow building arbitrary schemes.
// All generated defaulters are covering - they call all nested defaulters.
func RegisterDefaults(scheme *runtime.Scheme) error {
scheme.AddTypeDefaultingFunc(&BootstrapToken{}, func(obj interface{}) { SetObjectDefaults_BootstrapToken(obj.(*BootstrapToken)) })
return nil
}
func SetObjectDefaults_BootstrapToken(in *BootstrapToken) {
v1beta2.SetDefaults_BootstrapToken(&in.BootstrapToken)
}

View File

@ -0,0 +1,52 @@
// +build !ignore_autogenerated
/*
Copyright 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.
*/
// Code generated by deepcopy-gen. DO NOT EDIT.
package output
import (
runtime "k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BootstrapToken) DeepCopyInto(out *BootstrapToken) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.BootstrapToken.DeepCopyInto(&out.BootstrapToken)
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapToken.
func (in *BootstrapToken) DeepCopy() *BootstrapToken {
if in == nil {
return nil
}
out := new(BootstrapToken)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *BootstrapToken) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}

View File

@ -1,10 +1,4 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
@ -19,11 +13,14 @@ go_library(
"version.go",
],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd",
visibility = ["//visibility:public"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/scheme:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/v1beta2:go_default_library",
"//cmd/kubeadm/app/apis/kubeadm/validation:go_default_library",
"//cmd/kubeadm/app/apis/output/scheme:go_default_library",
"//cmd/kubeadm/app/apis/output/v1alpha1:go_default_library",
"//cmd/kubeadm/app/cmd/alpha:go_default_library",
"//cmd/kubeadm/app/cmd/options:go_default_library",
"//cmd/kubeadm/app/cmd/phases:go_default_library",
@ -46,12 +43,15 @@ go_library(
"//cmd/kubeadm/app/util/apiclient:go_default_library",
"//cmd/kubeadm/app/util/config:go_default_library",
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
"//cmd/kubeadm/app/util/output:go_default_library",
"//cmd/kubeadm/app/util/runtime: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/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/version:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library",
@ -81,12 +81,15 @@ go_test(
embed = [":go_default_library"],
deps = [
"//cmd/kubeadm/app/apis/kubeadm/v1beta2:go_default_library",
"//cmd/kubeadm/app/apis/output/scheme:go_default_library",
"//cmd/kubeadm/app/apis/output/v1alpha1:go_default_library",
"//cmd/kubeadm/app/cmd/options:go_default_library",
"//cmd/kubeadm/app/componentconfigs:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/features:go_default_library",
"//cmd/kubeadm/app/util:go_default_library",
"//cmd/kubeadm/app/util/config:go_default_library",
"//cmd/kubeadm/app/util/output:go_default_library",
"//cmd/kubeadm/app/util/runtime:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
@ -123,4 +126,5 @@ filegroup(
"//cmd/kubeadm/app/cmd/util:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -31,7 +31,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/duration"
"k8s.io/cli-runtime/pkg/genericclioptions"
clientset "k8s.io/client-go/kubernetes"
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
bootstraputil "k8s.io/cluster-bootstrap/token/util"
@ -39,6 +41,8 @@ import (
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
outputapischeme "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme"
outputapiv1alpha1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha1"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
@ -46,6 +50,7 @@ import (
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
)
// NewCmdToken returns cobra.Command for token management
@ -142,6 +147,8 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
tokenCmd.AddCommand(createCmd)
tokenCmd.AddCommand(NewCmdTokenGenerate(out))
outputFlags := output.NewOutputFlags(&tokenTextPrintFlags{}).WithTypeSetter(outputapischeme.Scheme).WithDefaultOutput(output.TextOutput)
listCmd := &cobra.Command{
Use: "list",
Short: "List bootstrap tokens on the server",
@ -155,9 +162,17 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
return err
}
return RunListTokens(out, errW, client)
printer, err := outputFlags.ToPrinter()
if err != nil {
return err
}
return RunListTokens(out, errW, client, printer)
},
}
outputFlags.AddFlags(listCmd)
tokenCmd.AddCommand(listCmd)
deleteCmd := &cobra.Command{
@ -268,8 +283,71 @@ func RunGenerateToken(out io.Writer) error {
return nil
}
func formatBootstrapToken(obj *outputapiv1alpha1.BootstrapToken) string {
ttl := "<forever>"
expires := "<never>"
if obj.Expires != nil {
ttl = duration.ShortHumanDuration(obj.Expires.Sub(time.Now()))
expires = obj.Expires.Format(time.RFC3339)
}
ttl = fmt.Sprintf("%-9s", ttl)
usages := strings.Join(obj.Usages, ",")
if len(usages) == 0 {
usages = "<none>"
}
usages = fmt.Sprintf("%-22s", usages)
description := obj.Description
if len(description) == 0 {
description = "<none>"
}
description = fmt.Sprintf("%-56s", description)
groups := strings.Join(obj.Groups, ",")
if len(groups) == 0 {
groups = "<none>"
}
return fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t%s\n", obj.Token, ttl, expires, usages, description, groups)
}
// tokenTextPrinter prints bootstrap token in a text form
type tokenTextPrinter struct {
output.TextPrinter
columns []string
headerIsPrinted bool
}
// PrintObj is an implementation of ResourcePrinter.PrintObj for plain text output
func (ttp *tokenTextPrinter) PrintObj(obj runtime.Object, writer io.Writer) error {
tabw := tabwriter.NewWriter(writer, 10, 4, 3, ' ', 0)
// Print header
if !ttp.headerIsPrinted {
fmt.Fprintln(tabw, strings.Join(ttp.columns, "\t"))
ttp.headerIsPrinted = true
}
// Print token
fmt.Fprint(tabw, formatBootstrapToken(obj.(*outputapiv1alpha1.BootstrapToken)))
return tabw.Flush()
}
// tokenTextPrintFlags provides flags necessary for printing bootstrap token in a text form.
type tokenTextPrintFlags struct{}
// ToPrinter returns kubeadm printer for the text output format
func (tpf *tokenTextPrintFlags) ToPrinter(outputFormat string) (output.Printer, error) {
if outputFormat == output.TextOutput {
return &tokenTextPrinter{columns: []string{"TOKEN", "TTL", "EXPIRES", "USAGES", "DESCRIPTION", "EXTRA GROUPS"}}, nil
}
return nil, genericclioptions.NoCompatiblePrinterError{OutputFormat: &outputFormat, AllowedFormats: []string{output.TextOutput}}
}
// RunListTokens lists details on all existing bootstrap tokens on the server.
func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) error {
func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface, printer output.Printer) error {
// First, build our selector for bootstrap tokens only
klog.V(1).Infoln("[token] preparing selector for bootstrap token")
tokenSelector := fields.SelectorFromSet(
@ -284,16 +362,13 @@ func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) er
FieldSelector: tokenSelector.String(),
}
klog.V(1).Infoln("[token] retrieving list of bootstrap tokens")
klog.V(1).Info("[token] retrieving list of bootstrap tokens")
secrets, err := client.CoreV1().Secrets(metav1.NamespaceSystem).List(listOptions)
if err != nil {
return errors.Wrap(err, "failed to list bootstrap tokens")
}
w := tabwriter.NewWriter(out, 10, 4, 3, ' ', 0)
fmt.Fprintln(w, "TOKEN\tTTL\tEXPIRES\tUSAGES\tDESCRIPTION\tEXTRA GROUPS")
for _, secret := range secrets.Items {
// Get the BootstrapToken struct representation from the Secret object
token, err := kubeadmapi.BootstrapTokenFromSecret(&secret)
if err != nil {
@ -301,11 +376,22 @@ func RunListTokens(out io.Writer, errW io.Writer, client clientset.Interface) er
continue
}
// Get the human-friendly string representation for the token
humanFriendlyTokenOutput := humanReadableBootstrapToken(token)
fmt.Fprintln(w, humanFriendlyTokenOutput)
// Convert token into versioned output structure
outputToken := outputapiv1alpha1.BootstrapToken{
BootstrapToken: kubeadmapiv1beta2.BootstrapToken{
Token: &kubeadmapiv1beta2.BootstrapTokenString{ID: token.Token.ID, Secret: token.Token.Secret},
Description: token.Description,
TTL: token.TTL,
Expires: token.Expires,
Usages: token.Usages,
Groups: token.Groups,
},
}
if err := printer.PrintObj(&outputToken, out); err != nil {
return errors.Wrapf(err, "unable to print token %s", token.Token)
}
}
w.Flush()
return nil
}
@ -335,32 +421,6 @@ func RunDeleteTokens(out io.Writer, client clientset.Interface, tokenIDsOrTokens
return nil
}
func humanReadableBootstrapToken(token *kubeadmapi.BootstrapToken) string {
description := token.Description
if len(description) == 0 {
description = "<none>"
}
ttl := "<forever>"
expires := "<never>"
if token.Expires != nil {
ttl = duration.ShortHumanDuration(token.Expires.Sub(time.Now()))
expires = token.Expires.Format(time.RFC3339)
}
usagesString := strings.Join(token.Usages, ",")
if len(usagesString) == 0 {
usagesString = "<none>"
}
groupsString := strings.Join(token.Groups, ",")
if len(groupsString) == 0 {
groupsString = "<none>"
}
return fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t%s", token.Token.String(), ttl, expires, usagesString, description, groupsString)
}
func getClientset(file string, dryRun bool) (clientset.Interface, error) {
if dryRun {
dryRunGetter, err := apiclient.NewClientBackedDryRunGetterFromKubeconfig(file)

View File

@ -32,6 +32,9 @@ import (
core "k8s.io/client-go/testing"
"k8s.io/client-go/tools/clientcmd"
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
outputapischeme "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/scheme"
outputapiv1alpha1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/output/v1alpha1"
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
)
const (
@ -332,3 +335,125 @@ func TestRunDeleteTokens(t *testing.T) {
t.Errorf("RunDeleteToken() succeeded for an invalid token: %v", err)
}
}
func TestTokenOutput(t *testing.T) {
testCases := []struct {
name string
id string
secret string
description string
usages []string
extraGroups []string
outputFormat string
expectedBytes []byte
}{
{
name: "JSON output",
id: "abcdef",
secret: "1234567890123456",
description: "valid bootstrap tooken",
usages: []string{"signing", "authentication"},
extraGroups: []string{"system:bootstrappers:kubeadm:default-node-token"},
outputFormat: "json",
expectedBytes: []byte(`{
"kind": "BootstrapToken",
"apiVersion": "output.kubeadm.k8s.io/v1alpha1",
"creationTimestamp": null,
"token": "abcdef.1234567890123456",
"description": "valid bootstrap tooken",
"usages": [
"signing",
"authentication"
],
"groups": [
"system:bootstrappers:kubeadm:default-node-token"
]
}
`),
},
{
name: "YAML output",
id: "abcdef",
secret: "1234567890123456",
description: "valid bootstrap tooken",
usages: []string{"signing", "authentication"},
extraGroups: []string{"system:bootstrappers:kubeadm:default-node-token"},
outputFormat: "yaml",
expectedBytes: []byte(`apiVersion: output.kubeadm.k8s.io/v1alpha1
creationTimestamp: null
description: valid bootstrap tooken
groups:
- system:bootstrappers:kubeadm:default-node-token
kind: BootstrapToken
token: abcdef.1234567890123456
usages:
- signing
- authentication
`),
},
{
name: "Go template output",
id: "abcdef",
secret: "1234567890123456",
description: "valid bootstrap tooken",
usages: []string{"signing", "authentication"},
extraGroups: []string{"system:bootstrappers:kubeadm:default-node-token"},
outputFormat: "go-template={{println .token .description .usages .groups}}",
expectedBytes: []byte(`abcdef.1234567890123456 valid bootstrap tooken [signing authentication] [system:bootstrappers:kubeadm:default-node-token]
`),
},
{
name: "text output",
id: "abcdef",
secret: "1234567890123456",
description: "valid bootstrap tooken",
usages: []string{"signing", "authentication"},
extraGroups: []string{"system:bootstrappers:kubeadm:default-node-token"},
outputFormat: "text",
expectedBytes: []byte(`TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
abcdef.1234567890123456 <forever> <never> signing,authentication valid bootstrap tooken system:bootstrappers:kubeadm:default-node-token
`),
},
{
name: "jsonpath output",
id: "abcdef",
secret: "1234567890123456",
description: "valid bootstrap tooken",
usages: []string{"signing", "authentication"},
extraGroups: []string{"system:bootstrappers:kubeadm:default-node-token"},
outputFormat: "jsonpath={.token} {.groups}",
expectedBytes: []byte(`abcdef.1234567890123456 [system:bootstrappers:kubeadm:default-node-token]`),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
token := outputapiv1alpha1.BootstrapToken{
BootstrapToken: kubeadmapiv1beta2.BootstrapToken{
Token: &kubeadmapiv1beta2.BootstrapTokenString{ID: tc.id, Secret: tc.secret},
Description: tc.description,
Usages: tc.usages,
Groups: tc.extraGroups,
},
}
buf := bytes.NewBufferString("")
outputFlags := output.NewOutputFlags(&tokenTextPrintFlags{}).WithTypeSetter(outputapischeme.Scheme).WithDefaultOutput(tc.outputFormat)
printer, err := outputFlags.ToPrinter()
if err != nil {
t.Errorf("can't create printer for output format %s: %+v", tc.outputFormat, err)
}
if err := printer.PrintObj(&token, buf); err != nil {
t.Errorf("unable to print token %s: %+v", token.Token, err)
}
actualBytes := buf.Bytes()
if !bytes.Equal(actualBytes, tc.expectedBytes) {
t.Errorf(
"failed TestTokenOutput:\n\nexpected:\n%s\n\nactual:\n%s",
string(tc.expectedBytes),
string(actualBytes),
)
}
})
}
}

View File

@ -84,6 +84,7 @@ filegroup(
"//cmd/kubeadm/app/util/initsystem:all-srcs",
"//cmd/kubeadm/app/util/kubeconfig:all-srcs",
"//cmd/kubeadm/app/util/kustomize:all-srcs",
"//cmd/kubeadm/app/util/output:all-srcs",
"//cmd/kubeadm/app/util/pkiutil:all-srcs",
"//cmd/kubeadm/app/util/pubkeypin:all-srcs",
"//cmd/kubeadm/app/util/runtime:all-srcs",

View File

@ -0,0 +1,28 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["output.go"],
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/util/output",
visibility = ["//visibility:public"],
deps = [
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/printers:go_default_library",
"//vendor/github.com/spf13/cobra: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"],
)

View File

@ -0,0 +1,192 @@
/*
Copyright 2019 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 output
import (
"fmt"
"io"
"strings"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/printers"
)
// TextOutput describes the plain text output
const TextOutput = "text"
// TextPrintFlags is an iterface to handle custom text output
type TextPrintFlags interface {
ToPrinter(outputFormat string) (Printer, error)
}
// PrintFlags composes common printer flag structs
// used across kubeadm commands, and provides a method
// of retrieving a known printer based on flag values provided.
type PrintFlags struct {
// JSONYamlPrintFlags provides default flags necessary for json/yaml printing.
JSONYamlPrintFlags *genericclioptions.JSONYamlPrintFlags
// KubeTemplatePrintFlags composes print flags that provide both a JSONPath and a go-template printer.
KubeTemplatePrintFlags *genericclioptions.KubeTemplatePrintFlags
// JSONYamlPrintFlags provides default flags necessary for kubeadm text printing.
TextPrintFlags TextPrintFlags
// TypeSetterPrinter is an implementation of ResourcePrinter that wraps another printer with types set on the objects
TypeSetterPrinter *printers.TypeSetterPrinter
// OutputFormat contains currently set output format
OutputFormat *string
// OutputFlagSpecified indicates whether the user specifically requested a certain kind of output.
// Using this function allows a sophisticated caller to change the flag binding logic if they so desire.
OutputFlagSpecified func() bool
}
// AllowedFormats returns list of allowed output formats
func (pf *PrintFlags) AllowedFormats() []string {
ret := []string{TextOutput}
ret = append(ret, pf.JSONYamlPrintFlags.AllowedFormats()...)
ret = append(ret, pf.KubeTemplatePrintFlags.AllowedFormats()...)
return ret
}
// ToPrinter receives an outputFormat and returns a printer capable of
// handling format printing.
// Returns error if the specified outputFormat does not match supported formats.
func (pf *PrintFlags) ToPrinter() (Printer, error) {
outputFormat := ""
if pf.OutputFormat != nil {
outputFormat = *pf.OutputFormat
}
if pf.TextPrintFlags != nil {
if p, err := pf.TextPrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
return p, err
}
}
if pf.JSONYamlPrintFlags != nil {
if p, err := pf.JSONYamlPrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
return NewResourcePrinterWrapper(pf.TypeSetterPrinter.WrapToPrinter(p, err))
}
}
if pf.KubeTemplatePrintFlags != nil {
if p, err := pf.KubeTemplatePrintFlags.ToPrinter(outputFormat); !genericclioptions.IsNoCompatiblePrinterError(err) {
return NewResourcePrinterWrapper(pf.TypeSetterPrinter.WrapToPrinter(p, err))
}
}
return nil, genericclioptions.NoCompatiblePrinterError{OutputFormat: pf.OutputFormat, AllowedFormats: pf.AllowedFormats()}
}
// AddFlags receives a *cobra.Command reference and binds
// flags related to Kubeadm printing to it
func (pf *PrintFlags) AddFlags(cmd *cobra.Command) {
pf.JSONYamlPrintFlags.AddFlags(cmd)
pf.KubeTemplatePrintFlags.AddFlags(cmd)
cmd.Flags().StringVarP(pf.OutputFormat, "experimental-output", "o", *pf.OutputFormat, fmt.Sprintf("Output format. One of: %s.", strings.Join(pf.AllowedFormats(), "|")))
}
// WithDefaultOutput sets a default output format if one is not provided through a flag value
func (pf *PrintFlags) WithDefaultOutput(outputFormat string) *PrintFlags {
pf.OutputFormat = &outputFormat
return pf
}
// WithTypeSetter sets a wrapper than will surround the returned printer with a printer to type resources
func (pf *PrintFlags) WithTypeSetter(scheme *runtime.Scheme) *PrintFlags {
pf.TypeSetterPrinter = printers.NewTypeSetter(scheme)
return pf
}
// NewOutputFlags creates new KubeadmOutputFlags
func NewOutputFlags(textPrintFlags TextPrintFlags) *PrintFlags {
outputFormat := ""
pf := &PrintFlags{
OutputFormat: &outputFormat,
JSONYamlPrintFlags: genericclioptions.NewJSONYamlPrintFlags(),
KubeTemplatePrintFlags: genericclioptions.NewKubeTemplatePrintFlags(),
TextPrintFlags: textPrintFlags,
}
// disable deprecated --template option
pf.KubeTemplatePrintFlags.TemplateArgument = nil
return pf
}
// Printer is a common printing interface in Kubeadm
type Printer interface {
PrintObj(obj runtime.Object, writer io.Writer) error
Fprintf(writer io.Writer, format string, args ...interface{}) (n int, err error)
Printf(format string, args ...interface{}) (n int, err error)
}
// TextPrinter implements Printer interface for generic text output
type TextPrinter struct {
}
// PrintObj is an implementation of ResourcePrinter.PrintObj that prints object
func (tp *TextPrinter) PrintObj(obj runtime.Object, writer io.Writer) error {
_, err := fmt.Fprintf(writer, "%+v\n", obj)
return err
}
// Fprintf is a wrapper around fmt.Fprintf
func (tp *TextPrinter) Fprintf(writer io.Writer, format string, args ...interface{}) (n int, err error) {
return fmt.Fprintf(writer, format, args...)
}
// Printf is a wrapper around fmt.Printf
func (tp *TextPrinter) Printf(format string, args ...interface{}) (n int, err error) {
return fmt.Printf(format, args...)
}
// ResourcePrinterWrapper wraps ResourcePrinter and implements Printer interface
type ResourcePrinterWrapper struct {
Printer printers.ResourcePrinter
}
// NewResourcePrinterWrapper creates new ResourcePrinter object
func NewResourcePrinterWrapper(resourcePrinter printers.ResourcePrinter, err error) (Printer, error) {
if err != nil {
return nil, err
}
return &ResourcePrinterWrapper{Printer: resourcePrinter}, nil
}
// PrintObj is an implementation of ResourcePrinter.PrintObj that calls underlying printer API
func (rpw *ResourcePrinterWrapper) PrintObj(obj runtime.Object, writer io.Writer) error {
return rpw.Printer.PrintObj(obj, writer)
}
// Fprintf is an empty method to satisfy Printer interface
// and silent info printing for structured output
// This method is usually redefined for the text output
func (rpw *ResourcePrinterWrapper) Fprintf(writer io.Writer, format string, args ...interface{}) (n int, err error) {
return 0, nil
}
// Printf is an empty method to satisfy Printer interface
// and silent info printing for structured output
// This method is usually redefined for the text output
func (rpw *ResourcePrinterWrapper) Printf(format string, args ...interface{}) (n int, err error) {
return 0, nil
}