Upgrade k8s package verison (#5358)
* upgrade k8s package version Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> * Script upgrade and code formatting. Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
2
vendor/k8s.io/kubectl/pkg/cmd/util/factory.go
generated
vendored
2
vendor/k8s.io/kubectl/pkg/cmd/util/factory.go
generated
vendored
@@ -61,7 +61,7 @@ type Factory interface {
|
||||
UnstructuredClientForMapping(mapping *meta.RESTMapping) (resource.RESTClient, error)
|
||||
|
||||
// Returns a schema that can validate objects stored on disk.
|
||||
Validator(validate bool) (validation.Schema, error)
|
||||
Validator(validationDirective string, verifier *resource.QueryParamVerifier) (validation.Schema, error)
|
||||
// OpenAPISchema returns the parsed openapi schema definition
|
||||
OpenAPISchema() (openapi.Resources, error)
|
||||
// OpenAPIGetter returns a getter for the openapi schema document
|
||||
|
||||
16
vendor/k8s.io/kubectl/pkg/cmd/util/factory_client_access.go
generated
vendored
16
vendor/k8s.io/kubectl/pkg/cmd/util/factory_client_access.go
generated
vendored
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/client-go/discovery"
|
||||
@@ -141,8 +142,14 @@ func (f *factoryImpl) UnstructuredClientForMapping(mapping *meta.RESTMapping) (r
|
||||
return restclient.RESTClientFor(cfg)
|
||||
}
|
||||
|
||||
func (f *factoryImpl) Validator(validate bool) (validation.Schema, error) {
|
||||
if !validate {
|
||||
func (f *factoryImpl) Validator(validationDirective string, verifier *resource.QueryParamVerifier) (validation.Schema, error) {
|
||||
// client-side schema validation is only performed
|
||||
// when the validationDirective is strict.
|
||||
// If the directive is warn, we rely on the ParamVerifyingSchema
|
||||
// to ignore the client-side validation and provide a warning
|
||||
// to the user that attempting warn validation when SS validation
|
||||
// is unsupported is inert.
|
||||
if validationDirective == metav1.FieldValidationIgnore {
|
||||
return validation.NullSchema{}, nil
|
||||
}
|
||||
|
||||
@@ -151,10 +158,11 @@ func (f *factoryImpl) Validator(validate bool) (validation.Schema, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return validation.ConjunctiveSchema{
|
||||
schema := validation.ConjunctiveSchema{
|
||||
openapivalidation.NewSchemaValidation(resources),
|
||||
validation.NoDoubleKeySchema{},
|
||||
}, nil
|
||||
}
|
||||
return validation.NewParamVerifyingSchema(schema, verifier, string(validationDirective)), nil
|
||||
}
|
||||
|
||||
// OpenAPISchema returns metadata and structural information about
|
||||
|
||||
162
vendor/k8s.io/kubectl/pkg/cmd/util/helpers.go
generated
vendored
162
vendor/k8s.io/kubectl/pkg/cmd/util/helpers.go
generated
vendored
@@ -30,12 +30,14 @@ import (
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
@@ -50,6 +52,7 @@ import (
|
||||
const (
|
||||
ApplyAnnotationsFlag = "save-config"
|
||||
DefaultErrorExitCode = 1
|
||||
DefaultChunkSize = 500
|
||||
)
|
||||
|
||||
type debugError interface {
|
||||
@@ -86,10 +89,13 @@ func DefaultBehaviorOnFatal() {
|
||||
fatalErrHandler = fatal
|
||||
}
|
||||
|
||||
// fatal prints the message (if provided) and then exits. If V(6) or greater,
|
||||
// klog.Fatal is invoked for extended information.
|
||||
// fatal prints the message (if provided) and then exits. If V(99) or greater,
|
||||
// klog.Fatal is invoked for extended information. This is intended for maintainer
|
||||
// debugging and out of a reasonable range for users.
|
||||
func fatal(msg string, code int) {
|
||||
if klog.V(6).Enabled() {
|
||||
// nolint:logcheck // Not using the result of klog.V(99) inside the if
|
||||
// branch is okay, we just use it to determine how to terminate.
|
||||
if klog.V(99).Enabled() {
|
||||
klog.FatalDepth(2, msg)
|
||||
}
|
||||
if len(msg) > 0 {
|
||||
@@ -127,6 +133,20 @@ func CheckDiffErr(err error) {
|
||||
})
|
||||
}
|
||||
|
||||
// isInvalidReasonStatusError returns true if this is an API Status error with reason=Invalid.
|
||||
// This is distinct from generic 422 errors we want to fall back to generic error handling.
|
||||
func isInvalidReasonStatusError(err error) bool {
|
||||
if !apierrors.IsInvalid(err) {
|
||||
return false
|
||||
}
|
||||
statusError, isStatusError := err.(*apierrors.StatusError)
|
||||
if !isStatusError {
|
||||
return false
|
||||
}
|
||||
status := statusError.Status()
|
||||
return status.Reason == metav1.StatusReasonInvalid
|
||||
}
|
||||
|
||||
// checkErr formats a given error as a string and calls the passed handleErr
|
||||
// func with that string and an kubectl exit code.
|
||||
func checkErr(err error, handleErr func(string, int)) {
|
||||
@@ -142,16 +162,26 @@ func checkErr(err error, handleErr func(string, int)) {
|
||||
switch {
|
||||
case err == ErrExit:
|
||||
handleErr("", DefaultErrorExitCode)
|
||||
case apierrors.IsInvalid(err):
|
||||
details := err.(*apierrors.StatusError).Status().Details
|
||||
case isInvalidReasonStatusError(err):
|
||||
status := err.(*apierrors.StatusError).Status()
|
||||
details := status.Details
|
||||
s := "The request is invalid"
|
||||
if details == nil {
|
||||
// if we have no other details, include the message from the server if present
|
||||
if len(status.Message) > 0 {
|
||||
s += ": " + status.Message
|
||||
}
|
||||
handleErr(s, DefaultErrorExitCode)
|
||||
return
|
||||
}
|
||||
if len(details.Kind) != 0 || len(details.Name) != 0 {
|
||||
s = fmt.Sprintf("The %s %q is invalid", details.Kind, details.Name)
|
||||
} else if len(status.Message) > 0 && len(details.Causes) == 0 {
|
||||
// only append the message if we have no kind/name details and no causes,
|
||||
// since default invalid error constructors duplicate that information in the message
|
||||
s += ": " + status.Message
|
||||
}
|
||||
|
||||
if len(details.Causes) > 0 {
|
||||
errs := statusCausesToAggrError(details.Causes)
|
||||
handleErr(MultilineError(s+": ", errs), DefaultErrorExitCode)
|
||||
@@ -393,11 +423,16 @@ func GetPodRunningTimeoutFlag(cmd *cobra.Command) (time.Duration, error) {
|
||||
}
|
||||
|
||||
func AddValidateFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("validate", true, "If true, use a schema to validate the input before sending it")
|
||||
}
|
||||
cmd.Flags().String(
|
||||
"validate",
|
||||
"strict",
|
||||
`Must be one of: strict (or true), warn, ignore (or false).
|
||||
"true" or "strict" will use a schema to validate the input and fail the request if invalid. It will perform server side validation if ServerSideFieldValidation is enabled on the api-server, but will fall back to less reliable client-side validation if not.
|
||||
"warn" will warn about unknown or duplicate fields without blocking the request if server-side field validation is enabled on the API server, and behave as "ignore" otherwise.
|
||||
"false" or "ignore" will not perform any schema validation, silently dropping any unknown or duplicate fields.`,
|
||||
)
|
||||
|
||||
func AddValidateOptionFlags(cmd *cobra.Command, options *ValidateOptions) {
|
||||
cmd.Flags().BoolVar(&options.EnableValidation, "validate", options.EnableValidation, "If true, use a schema to validate the input before sending it")
|
||||
cmd.Flags().Lookup("validate").NoOptDefVal = "strict"
|
||||
}
|
||||
|
||||
func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) {
|
||||
@@ -455,19 +490,28 @@ func AddApplyAnnotationVarFlags(cmd *cobra.Command, applyAnnotation *bool) {
|
||||
cmd.Flags().BoolVar(applyAnnotation, ApplyAnnotationsFlag, *applyAnnotation, "If true, the configuration of current object will be saved in its annotation. Otherwise, the annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.")
|
||||
}
|
||||
|
||||
// AddGeneratorFlags adds flags common to resource generation commands
|
||||
// TODO: need to take a pass at other generator commands to use this set of flags
|
||||
func AddGeneratorFlags(cmd *cobra.Command, defaultGenerator string) {
|
||||
cmd.Flags().String("generator", defaultGenerator, "The name of the API generator to use.")
|
||||
cmd.Flags().MarkDeprecated("generator", "has no effect and will be removed in the future.")
|
||||
AddDryRunFlag(cmd)
|
||||
func AddChunkSizeFlag(cmd *cobra.Command, value *int64) {
|
||||
cmd.Flags().Int64Var(value, "chunk-size", *value,
|
||||
"Return large lists in chunks rather than all at once. Pass 0 to disable. This flag is beta and may change in the future.")
|
||||
}
|
||||
|
||||
func AddLabelSelectorFlagVar(cmd *cobra.Command, p *string) {
|
||||
cmd.Flags().StringVarP(p, "selector", "l", *p, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Matching objects must satisfy all of the specified label constraints.")
|
||||
}
|
||||
|
||||
func AddSubresourceFlags(cmd *cobra.Command, subresource *string, usage string, allowedSubresources ...string) {
|
||||
cmd.Flags().StringVar(subresource, "subresource", "", fmt.Sprintf("%s Must be one of %v. This flag is alpha and may change in the future.", usage, allowedSubresources))
|
||||
CheckErr(cmd.RegisterFlagCompletionFunc("subresource", func(*cobra.Command, []string, string) ([]string, cobra.ShellCompDirective) {
|
||||
return allowedSubresources, cobra.ShellCompDirectiveNoFileComp
|
||||
}))
|
||||
}
|
||||
|
||||
type ValidateOptions struct {
|
||||
EnableValidation bool
|
||||
ValidationDirective string
|
||||
}
|
||||
|
||||
// Merge requires JSON serialization
|
||||
// Merge converts the passed in object to JSON, merges the fragment into it using an RFC7396 JSON Merge Patch,
|
||||
// and returns the resulting object
|
||||
// TODO: merge assumes JSON serialization, and does not properly abstract API retrieval
|
||||
func Merge(codec runtime.Codec, dst runtime.Object, fragment string) (runtime.Object, error) {
|
||||
// encode dst into versioned json and apply fragment directly too it
|
||||
@@ -486,6 +530,46 @@ func Merge(codec runtime.Codec, dst runtime.Object, fragment string) (runtime.Ob
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// StrategicMerge converts the passed in object to JSON, merges the fragment into it using a Strategic Merge Patch,
|
||||
// and returns the resulting object
|
||||
func StrategicMerge(codec runtime.Codec, dst runtime.Object, fragment string, dataStruct runtime.Object) (runtime.Object, error) {
|
||||
target, err := runtime.Encode(codec, dst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patched, err := strategicpatch.StrategicMergePatch(target, []byte(fragment), dataStruct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := runtime.Decode(codec, patched)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// JSONPatch converts the passed in object to JSON, performs an RFC6902 JSON Patch using operations specified in the
|
||||
// fragment, and returns the resulting object
|
||||
func JSONPatch(codec runtime.Codec, dst runtime.Object, fragment string) (runtime.Object, error) {
|
||||
target, err := runtime.Encode(codec, dst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patch, err := jsonpatch.DecodePatch([]byte(fragment))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
patched, err := patch.Apply(target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := runtime.Decode(codec, patched)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DumpReaderToFile writes all data from the given io.Reader to the specified file
|
||||
// (usually for temporary use).
|
||||
func DumpReaderToFile(reader io.Reader, filename string) error {
|
||||
@@ -524,6 +608,28 @@ func GetFieldManagerFlag(cmd *cobra.Command) string {
|
||||
return GetFlagString(cmd, "field-manager")
|
||||
}
|
||||
|
||||
func GetValidationDirective(cmd *cobra.Command) (string, error) {
|
||||
var validateFlag = GetFlagString(cmd, "validate")
|
||||
b, err := strconv.ParseBool(validateFlag)
|
||||
if err != nil {
|
||||
switch validateFlag {
|
||||
case "strict":
|
||||
return metav1.FieldValidationStrict, nil
|
||||
case "warn":
|
||||
return metav1.FieldValidationWarn, nil
|
||||
case "ignore":
|
||||
return metav1.FieldValidationIgnore, nil
|
||||
default:
|
||||
return metav1.FieldValidationStrict, fmt.Errorf(`invalid - validate option %q; must be one of: strict (or true), warn, ignore (or false)`, validateFlag)
|
||||
}
|
||||
}
|
||||
// The flag was a boolean
|
||||
if b {
|
||||
return metav1.FieldValidationStrict, nil
|
||||
}
|
||||
return metav1.FieldValidationIgnore, nil
|
||||
}
|
||||
|
||||
type DryRunStrategy int
|
||||
|
||||
const (
|
||||
@@ -666,7 +772,8 @@ func IsSiblingCommandExists(cmd *cobra.Command, targetCmdName string) bool {
|
||||
// arguments (sub-commands) are provided, or a usage error otherwise.
|
||||
func DefaultSubCommandRun(out io.Writer) func(c *cobra.Command, args []string) {
|
||||
return func(c *cobra.Command, args []string) {
|
||||
c.SetOutput(out)
|
||||
c.SetOut(out)
|
||||
c.SetErr(out)
|
||||
RequireNoArguments(c, args)
|
||||
c.Help()
|
||||
CheckErr(ErrExit)
|
||||
@@ -697,7 +804,9 @@ func ManualStrip(file []byte) []byte {
|
||||
stripped := []byte{}
|
||||
lines := bytes.Split(file, []byte("\n"))
|
||||
for i, line := range lines {
|
||||
if bytes.HasPrefix(bytes.TrimSpace(line), []byte("#")) {
|
||||
trimline := bytes.TrimSpace(line)
|
||||
|
||||
if bytes.HasPrefix(trimline, []byte("#")) && !bytes.HasPrefix(trimline, []byte("#!")) {
|
||||
continue
|
||||
}
|
||||
stripped = append(stripped, line...)
|
||||
@@ -748,3 +857,18 @@ func Warning(cmdErr io.Writer, newGeneratorName, oldGeneratorName string) {
|
||||
oldGeneratorName,
|
||||
)
|
||||
}
|
||||
|
||||
// Difference removes any elements of subArray from fullArray and returns the result
|
||||
func Difference(fullArray []string, subArray []string) []string {
|
||||
exclude := make(map[string]bool, len(subArray))
|
||||
for _, elem := range subArray {
|
||||
exclude[elem] = true
|
||||
}
|
||||
var result []string
|
||||
for _, elem := range fullArray {
|
||||
if _, found := exclude[elem]; !found {
|
||||
result = append(result, elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
90
vendor/k8s.io/kubectl/pkg/cmd/util/override_options.go
generated
vendored
Normal file
90
vendor/k8s.io/kubectl/pkg/cmd/util/override_options.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2021 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 util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubectl/pkg/scheme"
|
||||
"k8s.io/kubectl/pkg/util/i18n"
|
||||
)
|
||||
|
||||
type OverrideType string
|
||||
|
||||
const (
|
||||
// OverrideTypeJSON will use an RFC6902 JSON Patch to alter the generated output
|
||||
OverrideTypeJSON OverrideType = "json"
|
||||
|
||||
// OverrideTypeMerge will use an RFC7396 JSON Merge Patch to alter the generated output
|
||||
OverrideTypeMerge OverrideType = "merge"
|
||||
|
||||
// OverrideTypeStrategic will use a Strategic Merge Patch to alter the generated output
|
||||
OverrideTypeStrategic OverrideType = "strategic"
|
||||
)
|
||||
|
||||
const DefaultOverrideType = OverrideTypeMerge
|
||||
|
||||
type OverrideOptions struct {
|
||||
Overrides string
|
||||
OverrideType OverrideType
|
||||
}
|
||||
|
||||
func (o *OverrideOptions) AddOverrideFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVar(&o.Overrides, "overrides", "", i18n.T("An inline JSON override for the generated object. If this is non-empty, it is used to override the generated object. Requires that the object supply a valid apiVersion field."))
|
||||
cmd.Flags().StringVar((*string)(&o.OverrideType), "override-type", string(DefaultOverrideType), fmt.Sprintf("The method used to override the generated object: %s, %s, or %s.", OverrideTypeJSON, OverrideTypeMerge, OverrideTypeStrategic))
|
||||
}
|
||||
|
||||
func (o *OverrideOptions) NewOverrider(dataStruct runtime.Object) *Overrider {
|
||||
return &Overrider{
|
||||
Options: o,
|
||||
DataStruct: dataStruct,
|
||||
}
|
||||
}
|
||||
|
||||
type Overrider struct {
|
||||
Options *OverrideOptions
|
||||
DataStruct runtime.Object
|
||||
}
|
||||
|
||||
func (o *Overrider) Apply(obj runtime.Object) (runtime.Object, error) {
|
||||
if len(o.Options.Overrides) == 0 {
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
codec := runtime.NewCodec(scheme.DefaultJSONEncoder(), scheme.Codecs.UniversalDecoder(scheme.Scheme.PrioritizedVersionsAllGroups()...))
|
||||
|
||||
var overrideType OverrideType
|
||||
if len(o.Options.OverrideType) == 0 {
|
||||
overrideType = DefaultOverrideType
|
||||
} else {
|
||||
overrideType = o.Options.OverrideType
|
||||
}
|
||||
|
||||
switch overrideType {
|
||||
case OverrideTypeJSON:
|
||||
return JSONPatch(codec, obj, o.Options.Overrides)
|
||||
case OverrideTypeMerge:
|
||||
return Merge(codec, obj, o.Options.Overrides)
|
||||
case OverrideTypeStrategic:
|
||||
return StrategicMerge(codec, obj, o.Options.Overrides, o.DataStruct)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid override type: %v", overrideType)
|
||||
}
|
||||
}
|
||||
150
vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go
generated
vendored
Normal file
150
vendor/k8s.io/kubectl/pkg/util/i18n/i18n.go
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
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 i18n
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
gettext "github.com/chai2010/gettext-go"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
//go:embed translations
|
||||
var translations embed.FS
|
||||
|
||||
var knownTranslations = map[string][]string{
|
||||
"kubectl": {
|
||||
"default",
|
||||
"en_US",
|
||||
"fr_FR",
|
||||
"zh_CN",
|
||||
"ja_JP",
|
||||
"zh_TW",
|
||||
"it_IT",
|
||||
"de_DE",
|
||||
"ko_KR",
|
||||
"pt_BR",
|
||||
},
|
||||
// only used for unit tests.
|
||||
"test": {
|
||||
"default",
|
||||
"en_US",
|
||||
},
|
||||
}
|
||||
|
||||
func loadSystemLanguage() string {
|
||||
// Implements the following locale priority order: LC_ALL, LC_MESSAGES, LANG
|
||||
// Similarly to: https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html
|
||||
langStr := os.Getenv("LC_ALL")
|
||||
if langStr == "" {
|
||||
langStr = os.Getenv("LC_MESSAGES")
|
||||
}
|
||||
if langStr == "" {
|
||||
langStr = os.Getenv("LANG")
|
||||
}
|
||||
|
||||
if langStr == "" {
|
||||
klog.V(3).Infof("Couldn't find the LC_ALL, LC_MESSAGES or LANG environment variables, defaulting to en_US")
|
||||
return "default"
|
||||
}
|
||||
pieces := strings.Split(langStr, ".")
|
||||
if len(pieces) != 2 {
|
||||
klog.V(3).Infof("Unexpected system language (%s), defaulting to en_US", langStr)
|
||||
return "default"
|
||||
}
|
||||
return pieces[0]
|
||||
}
|
||||
|
||||
func findLanguage(root string, getLanguageFn func() string) string {
|
||||
langStr := getLanguageFn()
|
||||
|
||||
translations := knownTranslations[root]
|
||||
for ix := range translations {
|
||||
if translations[ix] == langStr {
|
||||
return langStr
|
||||
}
|
||||
}
|
||||
klog.V(3).Infof("Couldn't find translations for %s, using default", langStr)
|
||||
return "default"
|
||||
}
|
||||
|
||||
// LoadTranslations loads translation files. getLanguageFn should return a language
|
||||
// string (e.g. 'en-US'). If getLanguageFn is nil, then the loadSystemLanguage function
|
||||
// is used, which uses the 'LANG' environment variable.
|
||||
func LoadTranslations(root string, getLanguageFn func() string) error {
|
||||
if getLanguageFn == nil {
|
||||
getLanguageFn = loadSystemLanguage
|
||||
}
|
||||
|
||||
langStr := findLanguage(root, getLanguageFn)
|
||||
translationFiles := []string{
|
||||
fmt.Sprintf("%s/%s/LC_MESSAGES/k8s.po", root, langStr),
|
||||
fmt.Sprintf("%s/%s/LC_MESSAGES/k8s.mo", root, langStr),
|
||||
}
|
||||
|
||||
klog.V(3).Infof("Setting language to %s", langStr)
|
||||
// TODO: list the directory and load all files.
|
||||
buf := new(bytes.Buffer)
|
||||
w := zip.NewWriter(buf)
|
||||
|
||||
// Make sure to check the error on Close.
|
||||
for _, file := range translationFiles {
|
||||
filename := "translations/" + file
|
||||
f, err := w.Create(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := translations.ReadFile(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write(data); err != nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
gettext.BindLocale(gettext.New("k8s", root+".zip", buf.Bytes()))
|
||||
gettext.SetDomain("k8s")
|
||||
gettext.SetLanguage(langStr)
|
||||
return nil
|
||||
}
|
||||
|
||||
// T translates a string, possibly substituting arguments into it along
|
||||
// the way. If len(args) is > 0, args1 is assumed to be the plural value
|
||||
// and plural translation is used.
|
||||
func T(defaultValue string, args ...int) string {
|
||||
if len(args) == 0 {
|
||||
return gettext.PGettext("", defaultValue)
|
||||
}
|
||||
return fmt.Sprintf(gettext.PNGettext("", defaultValue, defaultValue+".plural", args[0]),
|
||||
args[0])
|
||||
}
|
||||
|
||||
// Errorf produces an error with a translated error string.
|
||||
// Substitution is performed via the `T` function above, following
|
||||
// the same rules.
|
||||
func Errorf(defaultValue string, args ...int) error {
|
||||
return errors.New(T(defaultValue, args...))
|
||||
}
|
||||
7
vendor/k8s.io/kubectl/pkg/util/i18n/translations/OWNERS
generated
vendored
Normal file
7
vendor/k8s.io/kubectl/pkg/util/i18n/translations/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
reviewers: []
|
||||
approvers:
|
||||
- sig-cli-maintainers
|
||||
emeritus_approvers:
|
||||
- brendandburns
|
||||
82
vendor/k8s.io/kubectl/pkg/util/i18n/translations/README.md
generated
vendored
Normal file
82
vendor/k8s.io/kubectl/pkg/util/i18n/translations/README.md
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# Translations README
|
||||
|
||||
This is a basic sketch of the workflow needed to add translations:
|
||||
|
||||
# Adding/Updating Translations
|
||||
|
||||
## New languages
|
||||
Create `staging/src/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/<language>/LC_MESSAGES/k8s.po`. There's
|
||||
no need to update `translations/test/...` which is only used for unit tests.
|
||||
|
||||
There is an example [PR here](https://github.com/kubernetes/kubernetes/pull/40645) which adds support for French.
|
||||
|
||||
Once you've added a new language, you'll need to register it in
|
||||
`staging/src/k8s.io/kubectl/pkg/util/i18n/i18n.go` by adding it to the `knownTranslations` map.
|
||||
|
||||
## Wrapping strings
|
||||
There is a simple script in `staging/src/k8s.io/kubectl/pkg/util/i18n/translations/extract.py` that performs
|
||||
simple regular expression based wrapping of strings. It can always
|
||||
use improvements to understand additional strings.
|
||||
|
||||
## Extracting strings
|
||||
Once the strings are wrapped, you can extract strings from go files using
|
||||
the `go-xgettext` command which can be installed with:
|
||||
|
||||
```console
|
||||
go get github.com/gosexy/gettext/go-xgettext
|
||||
```
|
||||
|
||||
Once that's installed you can run `./hack/update-translations.sh`, which
|
||||
will extract and sort any new strings.
|
||||
|
||||
## Adding new translations
|
||||
Edit the appropriate `k8s.po` file, `poedit` is a popular open source tool
|
||||
for translations. You can load the `staging/src/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/template.pot` file
|
||||
to find messages that might be missing.
|
||||
|
||||
Once you are done with your `k8s.po` file, generate the corresponding `k8s.mo`
|
||||
file. `poedit` does this automatically on save, but you can also run
|
||||
`./hack/update-translations.sh` to perform the `po` to `mo` translation.
|
||||
|
||||
We use the English translation as the `msgid`.
|
||||
|
||||
## Regenerating the bindata file
|
||||
|
||||
> Note: Regeneration of bindata is no more necessary for Kubernetes 1.22+ as
|
||||
> the translations are now embedded into the binary at compile time.
|
||||
> See: https://github.com/kubernetes/kubernetes/pull/99829
|
||||
|
||||
With the `mo` files up to date, you can now convert the generated files
|
||||
into code using `go-bindata` command which can be installed with:
|
||||
|
||||
```console
|
||||
go get github.com/go-bindata/go-bindata/...
|
||||
```
|
||||
|
||||
Run `./hack/generate-bindata.sh`, this will turn the translation files
|
||||
into generated code which will in turn be packaged into the Kubernetes
|
||||
binaries.
|
||||
|
||||
## Extracting strings
|
||||
|
||||
There is a script in `staging/src/k8s.io/kubectl/pkg/util/i18n/translations/extract.py` that knows how to do some
|
||||
simple extraction. It needs a lot of work.
|
||||
|
||||
# Using translations
|
||||
|
||||
To use translations, you simply need to add:
|
||||
```go
|
||||
import pkg/i18n
|
||||
...
|
||||
// Get a translated string
|
||||
translated := i18n.T("Your message in english here")
|
||||
|
||||
// Get a translated plural string
|
||||
translated := i18n.T("You had % items", items)
|
||||
|
||||
// Translated error
|
||||
return i18n.Error("Something bad happened")
|
||||
|
||||
// Translated plural error
|
||||
return i18n.Error("%d bad things happened")
|
||||
```
|
||||
105
vendor/k8s.io/kubectl/pkg/util/i18n/translations/extract.py
generated
vendored
Normal file
105
vendor/k8s.io/kubectl/pkg/util/i18n/translations/extract.py
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# Copyright 2017 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.
|
||||
|
||||
"""Extract strings from command files and externalize into translation files.
|
||||
Expects to be run from the root directory of the repository.
|
||||
|
||||
Usage:
|
||||
extract.py pkg/kubectl/cmd/apply.go
|
||||
|
||||
"""
|
||||
import fileinput
|
||||
import sys
|
||||
import re
|
||||
|
||||
class MatchHandler(object):
|
||||
""" Simple holder for a regular expression and a function
|
||||
to run if that regular expression matches a line.
|
||||
The function should expect (re.match, file, linenumber) as parameters
|
||||
"""
|
||||
def __init__(self, regex, replace_fn):
|
||||
self.regex = re.compile(regex)
|
||||
self.replace_fn = replace_fn
|
||||
|
||||
def short_replace(match, file, line_number):
|
||||
"""Replace a Short: ... cobra command description with an internationalization
|
||||
"""
|
||||
sys.stdout.write('{}i18n.T({}),\n'.format(match.group(1), match.group(2)))
|
||||
|
||||
SHORT_MATCH = MatchHandler(r'(\s+Short:\s+)("[^"]+"),', short_replace)
|
||||
|
||||
def import_replace(match, file, line_number):
|
||||
"""Add an extra import for the i18n library.
|
||||
Doesn't try to be smart and detect if it's already present, assumes a
|
||||
gofmt round wil fix things.
|
||||
"""
|
||||
sys.stdout.write('{}\n"k8s.io/kubectl/pkg/util/i18n"\n'.format(match.group(1)))
|
||||
|
||||
IMPORT_MATCH = MatchHandler('(.*"k8s.io/kubectl/pkg/cmd/util")', import_replace)
|
||||
|
||||
|
||||
def string_flag_replace(match, file, line_number):
|
||||
"""Replace a cmd.Flags().String("...", "", "...") with an internationalization
|
||||
"""
|
||||
sys.stdout.write('{}i18n.T("{})"))\n'.format(match.group(1), match.group(2)))
|
||||
|
||||
STRING_FLAG_MATCH = MatchHandler('(\s+cmd\.Flags\(\).String\("[^"]*", "[^"]*", )"([^"]*)"\)', string_flag_replace)
|
||||
|
||||
|
||||
def long_string_replace(match, file, line_number):
|
||||
return '{}i18n.T({}){}'.format(match.group(1), match.group(2), match.group(3))
|
||||
|
||||
LONG_DESC_MATCH = MatchHandler('(LongDesc\()(`[^`]+`)([^\n]\n)', long_string_replace)
|
||||
|
||||
EXAMPLE_MATCH = MatchHandler('(Examples\()(`[^`]+`)([^\n]\n)', long_string_replace)
|
||||
|
||||
def replace(filename, matchers, multiline_matchers):
|
||||
"""Given a file and a set of matchers, run those matchers
|
||||
across the file and replace it with the results.
|
||||
"""
|
||||
# Run all the matchers
|
||||
line_number = 0
|
||||
for line in fileinput.input(filename, inplace=True):
|
||||
line_number += 1
|
||||
matched = False
|
||||
for matcher in matchers:
|
||||
match = matcher.regex.match(line)
|
||||
if match:
|
||||
matcher.replace_fn(match, filename, line_number)
|
||||
matched = True
|
||||
break
|
||||
if not matched:
|
||||
sys.stdout.write(line)
|
||||
sys.stdout.flush()
|
||||
with open(filename, 'r') as datafile:
|
||||
content = datafile.read()
|
||||
for matcher in multiline_matchers:
|
||||
match = matcher.regex.search(content)
|
||||
while match:
|
||||
rep = matcher.replace_fn(match, filename, 0)
|
||||
# Escape back references in the replacement string
|
||||
# (And escape for Python)
|
||||
# (And escape for regex)
|
||||
rep = re.sub('\\\\(\\d)', '\\\\\\\\\\1', rep)
|
||||
content = matcher.regex.sub(rep, content, 1)
|
||||
match = matcher.regex.search(content)
|
||||
sys.stdout.write(content)
|
||||
|
||||
# gofmt the file again
|
||||
from subprocess import call
|
||||
call(["goimports", "-w", filename])
|
||||
|
||||
replace(sys.argv[1], [SHORT_MATCH, IMPORT_MATCH, STRING_FLAG_MATCH], [LONG_DESC_MATCH, EXAMPLE_MATCH])
|
||||
6
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/OWNERS
generated
vendored
Normal file
6
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/OWNERS
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- sig-cli-maintainers
|
||||
reviewers:
|
||||
- sig-cli-reviewers
|
||||
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/de_DE/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/de_DE/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
2920
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/de_DE/LC_MESSAGES/k8s.po
generated
vendored
Normal file
2920
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/de_DE/LC_MESSAGES/k8s.po
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/default/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/default/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
5085
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/default/LC_MESSAGES/k8s.po
generated
vendored
Normal file
5085
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/default/LC_MESSAGES/k8s.po
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/en_US/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/en_US/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
5085
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/en_US/LC_MESSAGES/k8s.po
generated
vendored
Normal file
5085
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/en_US/LC_MESSAGES/k8s.po
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/fr_FR/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/fr_FR/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
103
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/fr_FR/LC_MESSAGES/k8s.po
generated
vendored
Normal file
103
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/fr_FR/LC_MESSAGES/k8s.po
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
# Test translations for unit tests.
|
||||
# Copyright (C) 2016
|
||||
# This file is distributed under the same license as the Kubernetes package.
|
||||
# FIRST AUTHOR brendan.d.burns@gmail.com, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gettext-go-examples-hello\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2021-07-07 20:15+0200\n"
|
||||
"PO-Revision-Date: 2017-01-29 22:54-0800\n"
|
||||
"Last-Translator: Brendan Burns <brendan.d.burns@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_cluster.go#L38
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/delete_cluster.go:42
|
||||
msgid "Delete the specified cluster from the kubeconfig"
|
||||
msgstr "Supprimer le cluster spécifié du kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_context.go#L38
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/delete_context.go:42
|
||||
msgid "Delete the specified context from the kubeconfig"
|
||||
msgstr "Supprimer le contexte spécifié du kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_contexts.go#L62
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/get_contexts.go:72
|
||||
msgid "Describe one or many contexts"
|
||||
msgstr "Décrire un ou plusieurs contextes"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_clusters.go#L40
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/get_clusters.go:41
|
||||
msgid "Display clusters defined in the kubeconfig"
|
||||
msgstr "Afficher les cluster définis dans kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/view.go#L64
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/view.go:81
|
||||
msgid "Display merged kubeconfig settings or a specified kubeconfig file"
|
||||
msgstr ""
|
||||
"Afficher les paramètres fusionnés de kubeconfig ou d'un fichier kubeconfig "
|
||||
"spécifié"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/config.go#L39
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/config.go:42
|
||||
msgid "Modify kubeconfig files"
|
||||
msgstr "Modifier des fichiers kubeconfig"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go:135
|
||||
msgid "Update the annotations on a resource"
|
||||
msgstr "Mettre à jour les annotations d'une ressource"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/apply.go#L98
|
||||
#~ msgid "Apply a configuration to a resource by filename or stdin"
|
||||
#~ msgstr ""
|
||||
#~ "Appliquer une configuration à une ressource par nom de fichier ou depuis "
|
||||
#~ "stdin"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/current_context.go#L48
|
||||
#~ msgid "Displays the current-context"
|
||||
#~ msgstr "Affiche le contexte actuel"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_cluster.go#L67
|
||||
#~ msgid "Sets a cluster entry in kubeconfig"
|
||||
#~ msgstr "Définit un cluster dans kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_context.go#L57
|
||||
#~ msgid "Sets a context entry in kubeconfig"
|
||||
#~ msgstr "Définit un contexte dans kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_authinfo.go#L103
|
||||
#~ msgid "Sets a user entry in kubeconfig"
|
||||
#~ msgstr "Définit un utilisateur dans kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/set.go#L59
|
||||
#~ msgid "Sets an individual value in a kubeconfig file"
|
||||
#~ msgstr "Définit une valeur individuelle dans un fichier kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/use_context.go#L48
|
||||
#~ msgid "Sets the current-context in a kubeconfig file"
|
||||
#~ msgstr "Définit le contexte courant dans un fichier kubeconfig"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/unset.go#L47
|
||||
#~ msgid "Unsets an individual value in a kubeconfig file"
|
||||
#~ msgstr "Supprime une valeur individuelle dans un fichier kubeconfig"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "watch is only supported on individual resources and resource collections "
|
||||
#~ "- %d resources were found"
|
||||
#~ msgid_plural ""
|
||||
#~ "watch is only supported on individual resources and resource collections "
|
||||
#~ "- %d resources were found"
|
||||
#~ msgstr[0] ""
|
||||
#~ "watch n'est compatible qu'avec les ressources individuelles et les "
|
||||
#~ "collections de ressources. - %d ressource a été trouvée. "
|
||||
#~ msgstr[1] ""
|
||||
#~ "watch n'est compatible qu'avec les ressources individuelles et les "
|
||||
#~ "collections de ressources. - %d ressources ont été trouvées. "
|
||||
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/it_IT/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/it_IT/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
3249
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/it_IT/LC_MESSAGES/k8s.po
generated
vendored
Normal file
3249
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/it_IT/LC_MESSAGES/k8s.po
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ja_JP/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ja_JP/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
3365
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ja_JP/LC_MESSAGES/k8s.po
generated
vendored
Normal file
3365
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ja_JP/LC_MESSAGES/k8s.po
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ko_KR/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ko_KR/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
96
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ko_KR/LC_MESSAGES/k8s.po
generated
vendored
Normal file
96
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/ko_KR/LC_MESSAGES/k8s.po
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# Test translations for unit tests.
|
||||
# Copyright (C) 2017
|
||||
# This file is distributed under the same license as the Kubernetes package.
|
||||
# FIRST AUTHOR ianyrchoi@gmail.com, 2018.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gettext-go-examples-hello\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2021-07-07 20:15+0200\n"
|
||||
"PO-Revision-Date: 2018-04-03 06:05+0900\n"
|
||||
"Last-Translator: Ian Y. Choi <ianyrchoi@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: ko_KR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_cluster.go#L38
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/delete_cluster.go:42
|
||||
msgid "Delete the specified cluster from the kubeconfig"
|
||||
msgstr "kubeconfig에서 지정된 클러스터를 삭제합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/delete_context.go#L38
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/delete_context.go:42
|
||||
msgid "Delete the specified context from the kubeconfig"
|
||||
msgstr "kubeconfig에서 지정된 컨텍스트를 삭제합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_contexts.go#L62
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/get_contexts.go:72
|
||||
msgid "Describe one or many contexts"
|
||||
msgstr "하나 또는 여러 컨텍스트를 설명합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/get_clusters.go#L40
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/get_clusters.go:41
|
||||
msgid "Display clusters defined in the kubeconfig"
|
||||
msgstr "kubeconfig에 정의된 클러스터를 표시합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/view.go#L64
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/view.go:81
|
||||
msgid "Display merged kubeconfig settings or a specified kubeconfig file"
|
||||
msgstr "병합된 kubeconfig 설정 또는 지정된 kubeconfig 파일을 표시합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/config.go#L39
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/config.go:42
|
||||
msgid "Modify kubeconfig files"
|
||||
msgstr "kubeconfig 파일을 수정합니다"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go:135
|
||||
msgid "Update the annotations on a resource"
|
||||
msgstr "자원에 대한 주석을 업데이트합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/masterpkg/kubectl/cmd/apply.go#L98
|
||||
#~ msgid "Apply a configuration to a resource by filename or stdin"
|
||||
#~ msgstr "구성을 파일 이름 또는 stdin에 의한 자원에 적용합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/current_context.go#L48
|
||||
#~ msgid "Displays the current-context"
|
||||
#~ msgstr "현재-컨텍스트를 표시합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_cluster.go#L67
|
||||
#~ msgid "Sets a cluster entry in kubeconfig"
|
||||
#~ msgstr "kubeconfig에서 클러스터 항목을 설정합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_context.go#L57
|
||||
#~ msgid "Sets a context entry in kubeconfig"
|
||||
#~ msgstr "kubeconfig에서 컨텍스트 항목을 설정합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/create_authinfo.go#L103
|
||||
#~ msgid "Sets a user entry in kubeconfig"
|
||||
#~ msgstr "kubeconfig에서 사용자 항목을 설정합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/set.go#L59
|
||||
#~ msgid "Sets an individual value in a kubeconfig file"
|
||||
#~ msgstr "kubeconfig 파일에서 단일값을 설정합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/use_context.go#L48
|
||||
#~ msgid "Sets the current-context in a kubeconfig file"
|
||||
#~ msgstr "kubeconfig 파일에서 현재-컨텍스트를 설정합니다"
|
||||
|
||||
# https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/config/unset.go#L47
|
||||
#~ msgid "Unsets an individual value in a kubeconfig file"
|
||||
#~ msgstr "kubeconfig 파일에서 단일값 설정을 해제합니다"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "watch is only supported on individual resources and resource collections "
|
||||
#~ "- %d resources were found"
|
||||
#~ msgid_plural ""
|
||||
#~ "watch is only supported on individual resources and resource collections "
|
||||
#~ "- %d resources were found"
|
||||
#~ msgstr[0] ""
|
||||
#~ "watch는 단일 리소스와 리소스 모음만을 지원합니다 - %d 개 자원을 발견하였습"
|
||||
#~ "니다"
|
||||
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/pt_BR/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/pt_BR/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
3250
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/pt_BR/LC_MESSAGES/k8s.po
generated
vendored
Normal file
3250
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/pt_BR/LC_MESSAGES/k8s.po
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3183
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/template.pot
generated
vendored
Normal file
3183
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/template.pot
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_CN/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_CN/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
3236
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_CN/LC_MESSAGES/k8s.po
generated
vendored
Normal file
3236
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_CN/LC_MESSAGES/k8s.po
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_TW/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_TW/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
81
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_TW/LC_MESSAGES/k8s.po
generated
vendored
Normal file
81
vendor/k8s.io/kubectl/pkg/util/i18n/translations/kubectl/zh_TW/LC_MESSAGES/k8s.po
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
# Test translations for unit tests.
|
||||
# Copyright (C) 2017
|
||||
# This file is distributed under the same license as the Kubernetes package.
|
||||
# FIRST AUTHOR warmchang@outlook.com, 2017.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: hello-world\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2021-07-07 20:15+0200\n"
|
||||
"PO-Revision-Date: 2017-06-02 09:13+0800\n"
|
||||
"Last-Translator: William Chang <warmchang@outlook.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: zh\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.2\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/delete_cluster.go:42
|
||||
msgid "Delete the specified cluster from the kubeconfig"
|
||||
msgstr "刪除 kubeconfig 檔案中指定的叢集(cluster)"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/delete_context.go:42
|
||||
msgid "Delete the specified context from the kubeconfig"
|
||||
msgstr "刪除 kubeconfig 檔案中指定的 context"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/get_contexts.go:72
|
||||
msgid "Describe one or many contexts"
|
||||
msgstr "描述一個或多個 context"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/get_clusters.go:41
|
||||
msgid "Display clusters defined in the kubeconfig"
|
||||
msgstr "顯示 kubeconfig 檔案中定義的叢集(cluster)"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/view.go:81
|
||||
msgid "Display merged kubeconfig settings or a specified kubeconfig file"
|
||||
msgstr "顯示合併的 kubeconfig 配置或一個指定的 kubeconfig 檔案"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/config/config.go:42
|
||||
msgid "Modify kubeconfig files"
|
||||
msgstr "修改 kubeconfig 檔案"
|
||||
|
||||
#: staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go:135
|
||||
msgid "Update the annotations on a resource"
|
||||
msgstr "更新一個資源的注解(annotations)"
|
||||
|
||||
#~ msgid "Apply a configuration to a resource by filename or stdin"
|
||||
#~ msgstr "通過檔案名或標準輸入流(stdin)對資源進行配置"
|
||||
|
||||
#~ msgid "Displays the current-context"
|
||||
#~ msgstr "顯示目前的 context"
|
||||
|
||||
#~ msgid "Sets a cluster entry in kubeconfig"
|
||||
#~ msgstr "設置 kubeconfig 檔案中的一個叢集(cluster)條目"
|
||||
|
||||
#~ msgid "Sets a context entry in kubeconfig"
|
||||
#~ msgstr "設置 kubeconfig 檔案中的一個 context 條目"
|
||||
|
||||
#~ msgid "Sets a user entry in kubeconfig"
|
||||
#~ msgstr "設置 kubeconfig 檔案中的一個使用者條目"
|
||||
|
||||
#~ msgid "Sets an individual value in a kubeconfig file"
|
||||
#~ msgstr "設置 kubeconfig 檔案中的一個值"
|
||||
|
||||
#~ msgid "Sets the current-context in a kubeconfig file"
|
||||
#~ msgstr "設置 kubeconfig 檔案中的目前 context"
|
||||
|
||||
#~ msgid "Unsets an individual value in a kubeconfig file"
|
||||
#~ msgstr "取消設置 kubeconfig 檔案中的一個值"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "watch is only supported on individual resources and resource collections "
|
||||
#~ "- %d resources were found"
|
||||
#~ msgid_plural ""
|
||||
#~ "watch is only supported on individual resources and resource collections "
|
||||
#~ "- %d resources were found"
|
||||
#~ msgstr[0] "一次只能 watch 一個資源或資料集合 - 找到了 %d 個資源"
|
||||
#~ msgstr[1] "一次只能 watch 一個資源或資料集合 - 找到了 %d 個資源"
|
||||
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/default/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/default/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
28
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/default/LC_MESSAGES/k8s.po
generated
vendored
Normal file
28
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/default/LC_MESSAGES/k8s.po
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Test translations for unit tests.
|
||||
# Copyright (C) 2016
|
||||
# This file is distributed under the same license as the Kubernetes package.
|
||||
# FIRST AUTHOR brendan.d.burns@gmail.com, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gettext-go-examples-hello\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-12-12 20:03+0000\n"
|
||||
"PO-Revision-Date: 2016-12-13 21:35-0800\n"
|
||||
"Last-Translator: Brendan Burns <brendan.d.burns@gmail.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: en\n"
|
||||
|
||||
msgid "test_plural"
|
||||
msgid_plural "test_plural"
|
||||
msgstr[0] "there was %d item"
|
||||
msgstr[1] "there were %d items"
|
||||
|
||||
msgid "test_string"
|
||||
msgstr "foo"
|
||||
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/en_US/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
BIN
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/en_US/LC_MESSAGES/k8s.mo
generated
vendored
Normal file
Binary file not shown.
28
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/en_US/LC_MESSAGES/k8s.po
generated
vendored
Normal file
28
vendor/k8s.io/kubectl/pkg/util/i18n/translations/test/en_US/LC_MESSAGES/k8s.po
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# Test translations for unit tests.
|
||||
# Copyright (C) 2016
|
||||
# This file is distributed under the same license as the Kubernetes package.
|
||||
# FIRST AUTHOR brendan.d.burns@gmail.com, 2016.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gettext-go-examples-hello\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-12-12 20:03+0000\n"
|
||||
"PO-Revision-Date: 2016-12-13 22:12-0800\n"
|
||||
"Last-Translator: Brendan Burns <brendan.d.burns@gmail.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: en\n"
|
||||
|
||||
msgid "test_plural"
|
||||
msgid_plural "test_plural"
|
||||
msgstr[0] "there was %d item"
|
||||
msgstr[1] "there were %d items"
|
||||
|
||||
msgid "test_string"
|
||||
msgstr "baz"
|
||||
4
vendor/k8s.io/kubectl/pkg/util/openapi/OWNERS
generated
vendored
4
vendor/k8s.io/kubectl/pkg/util/openapi/OWNERS
generated
vendored
@@ -1,6 +1,6 @@
|
||||
# See the OWNERS docs at https://go.k8s.io/owners
|
||||
|
||||
approvers:
|
||||
- apelisse
|
||||
- apelisse
|
||||
reviewers:
|
||||
- apelisse
|
||||
- apelisse
|
||||
|
||||
2
vendor/k8s.io/kubectl/pkg/util/openapi/extensions.go
generated
vendored
2
vendor/k8s.io/kubectl/pkg/util/openapi/extensions.go
generated
vendored
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
|
||||
package openapi
|
||||
|
||||
import "github.com/go-openapi/spec"
|
||||
import "k8s.io/kube-openapi/pkg/validation/spec"
|
||||
|
||||
// PrintColumnsKey is the key that defines which columns should be printed
|
||||
const PrintColumnsKey = "x-kubernetes-print-columns"
|
||||
|
||||
2
vendor/k8s.io/kubectl/pkg/util/openapi/openapi.go
generated
vendored
2
vendor/k8s.io/kubectl/pkg/util/openapi/openapi.go
generated
vendored
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
package openapi
|
||||
|
||||
import (
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
openapi_v2 "github.com/google/gnostic/openapiv2"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
|
||||
2
vendor/k8s.io/kubectl/pkg/util/openapi/openapi_getter.go
generated
vendored
2
vendor/k8s.io/kubectl/pkg/util/openapi/openapi_getter.go
generated
vendored
@@ -19,7 +19,7 @@ package openapi
|
||||
import (
|
||||
"sync"
|
||||
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
openapi_v2 "github.com/google/gnostic/openapiv2"
|
||||
"k8s.io/client-go/discovery"
|
||||
)
|
||||
|
||||
|
||||
10
vendor/k8s.io/kubectl/pkg/util/openapi/validation/validation.go
generated
vendored
10
vendor/k8s.io/kubectl/pkg/util/openapi/validation/validation.go
generated
vendored
@@ -43,12 +43,12 @@ func NewSchemaValidation(resources openapi.Resources) *SchemaValidation {
|
||||
// ValidateBytes will validates the object against using the Resources
|
||||
// object.
|
||||
func (v *SchemaValidation) ValidateBytes(data []byte) error {
|
||||
obj, err := parse(data)
|
||||
obj, err := Parse(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gvk, errs := getObjectKind(obj)
|
||||
gvk, errs := GetObjectKind(obj)
|
||||
if errs != nil {
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func (v *SchemaValidation) validateList(object interface{}) []error {
|
||||
return []error{errors.New("invalid object to validate")}
|
||||
}
|
||||
for _, item := range fields["items"].([]interface{}) {
|
||||
if gvk, errs := getObjectKind(item); errs != nil {
|
||||
if gvk, errs := GetObjectKind(item); errs != nil {
|
||||
allErrors = append(allErrors, errs...)
|
||||
} else {
|
||||
allErrors = append(allErrors, v.validateResource(item, gvk)...)
|
||||
@@ -90,7 +90,7 @@ func (v *SchemaValidation) validateResource(obj interface{}, gvk schema.GroupVer
|
||||
return validation.ValidateModel(obj, resource, gvk.Kind)
|
||||
}
|
||||
|
||||
func parse(data []byte) (interface{}, error) {
|
||||
func Parse(data []byte) (interface{}, error) {
|
||||
var obj interface{}
|
||||
out, err := yaml.ToJSON(data)
|
||||
if err != nil {
|
||||
@@ -102,7 +102,7 @@ func parse(data []byte) (interface{}, error) {
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func getObjectKind(object interface{}) (schema.GroupVersionKind, []error) {
|
||||
func GetObjectKind(object interface{}) (schema.GroupVersionKind, []error) {
|
||||
var listErrors []error
|
||||
fields, ok := object.(map[string]interface{})
|
||||
if !ok || fields == nil {
|
||||
|
||||
76
vendor/k8s.io/kubectl/pkg/util/templates/help_flags_printer.go
generated
vendored
Normal file
76
vendor/k8s.io/kubectl/pkg/util/templates/help_flags_printer.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2022 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 templates
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/go-wordwrap"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const offset = 10
|
||||
|
||||
// HelpFlagPrinter is a printer that
|
||||
// processes the help flag and print
|
||||
// it to i/o writer
|
||||
type HelpFlagPrinter struct {
|
||||
wrapLimit uint
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
// NewHelpFlagPrinter will initialize a HelpFlagPrinter given the
|
||||
// i/o writer
|
||||
func NewHelpFlagPrinter(out io.Writer, wrapLimit uint) *HelpFlagPrinter {
|
||||
return &HelpFlagPrinter{
|
||||
wrapLimit: wrapLimit,
|
||||
out: out,
|
||||
}
|
||||
}
|
||||
|
||||
// PrintHelpFlag will beautify the help flags and print it out to p.out
|
||||
func (p *HelpFlagPrinter) PrintHelpFlag(flag *flag.Flag) {
|
||||
formatBuf := new(bytes.Buffer)
|
||||
writeFlag(formatBuf, flag)
|
||||
|
||||
wrappedStr := formatBuf.String()
|
||||
flagAndUsage := strings.Split(formatBuf.String(), "\n")
|
||||
flagStr := flagAndUsage[0]
|
||||
|
||||
// if the flag usage is longer than one line, wrap it again
|
||||
if len(flagAndUsage) > 1 {
|
||||
nextLines := strings.Join(flagAndUsage[1:], " ")
|
||||
wrappedUsages := wordwrap.WrapString(nextLines, p.wrapLimit-offset)
|
||||
wrappedStr = flagStr + "\n" + wrappedUsages
|
||||
}
|
||||
appendTabStr := strings.ReplaceAll(wrappedStr, "\n", "\n\t")
|
||||
|
||||
fmt.Fprintf(p.out, appendTabStr+"\n\n")
|
||||
}
|
||||
|
||||
// writeFlag will output the help flag based
|
||||
// on the format provided by getFlagFormat to i/o writer
|
||||
func writeFlag(out io.Writer, f *flag.Flag) {
|
||||
deprecated := ""
|
||||
if f.Deprecated != "" {
|
||||
deprecated = fmt.Sprintf(" (DEPRECATED: %s)", f.Deprecated)
|
||||
}
|
||||
fmt.Fprintf(out, getFlagFormat(f), f.Shorthand, f.Name, f.DefValue, f.Usage, deprecated)
|
||||
}
|
||||
49
vendor/k8s.io/kubectl/pkg/util/templates/templater.go
generated
vendored
49
vendor/k8s.io/kubectl/pkg/util/templates/templater.go
generated
vendored
@@ -23,10 +23,10 @@ import (
|
||||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/kubectl/pkg/util/term"
|
||||
)
|
||||
|
||||
type FlagExposer interface {
|
||||
@@ -160,7 +160,7 @@ func (t *templater) cmdGroupsString(c *cobra.Command) string {
|
||||
cmds := []string{cmdGroup.Message}
|
||||
for _, cmd := range cmdGroup.Commands {
|
||||
if cmd.IsAvailableCommand() {
|
||||
cmds = append(cmds, " "+rpad(cmd.Name(), cmd.NamePadding())+" "+cmd.Short)
|
||||
cmds = append(cmds, " "+rpad(cmd.Name(), cmd.NamePadding())+" "+cmd.Short)
|
||||
}
|
||||
}
|
||||
groups = append(groups, strings.Join(cmds, "\n"))
|
||||
@@ -218,29 +218,40 @@ func (t *templater) usageLine(c *cobra.Command) string {
|
||||
return usage
|
||||
}
|
||||
|
||||
func flagsUsages(f *flag.FlagSet) string {
|
||||
x := new(bytes.Buffer)
|
||||
// flagsUsages will print out the kubectl help flags
|
||||
func flagsUsages(f *flag.FlagSet) (string, error) {
|
||||
flagBuf := new(bytes.Buffer)
|
||||
wrapLimit, err := term.GetWordWrapperLimit()
|
||||
if err != nil {
|
||||
wrapLimit = 0
|
||||
}
|
||||
printer := NewHelpFlagPrinter(flagBuf, wrapLimit)
|
||||
|
||||
f.VisitAll(func(flag *flag.Flag) {
|
||||
if flag.Hidden {
|
||||
return
|
||||
}
|
||||
format := "--%s=%s: %s\n"
|
||||
|
||||
if flag.Value.Type() == "string" {
|
||||
format = "--%s='%s': %s\n"
|
||||
}
|
||||
|
||||
if len(flag.Shorthand) > 0 {
|
||||
format = " -%s, " + format
|
||||
} else {
|
||||
format = " %s " + format
|
||||
}
|
||||
|
||||
fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
|
||||
printer.PrintHelpFlag(flag)
|
||||
})
|
||||
|
||||
return x.String()
|
||||
return flagBuf.String(), nil
|
||||
}
|
||||
|
||||
// getFlagFormat will output the flag format
|
||||
func getFlagFormat(f *flag.Flag) string {
|
||||
var format string
|
||||
format = "--%s=%s:\n%s%s"
|
||||
if f.Value.Type() == "string" {
|
||||
format = "--%s='%s':\n%s%s"
|
||||
}
|
||||
|
||||
if len(f.Shorthand) > 0 {
|
||||
format = " -%s, " + format
|
||||
} else {
|
||||
format = " %s" + format
|
||||
}
|
||||
|
||||
return format
|
||||
}
|
||||
|
||||
func rpad(s string, padding int) string {
|
||||
|
||||
1
vendor/k8s.io/kubectl/pkg/util/term/resizeevents.go
generated
vendored
1
vendor/k8s.io/kubectl/pkg/util/term/resizeevents.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
/*
|
||||
|
||||
48
vendor/k8s.io/kubectl/pkg/util/term/term_writer.go
generated
vendored
48
vendor/k8s.io/kubectl/pkg/util/term/term_writer.go
generated
vendored
@@ -17,11 +17,14 @@ limitations under the License.
|
||||
package term
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
wordwrap "github.com/mitchellh/go-wordwrap"
|
||||
"github.com/moby/term"
|
||||
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
)
|
||||
|
||||
type wordWrapWriter struct {
|
||||
@@ -32,9 +35,11 @@ type wordWrapWriter struct {
|
||||
// NewResponsiveWriter creates a Writer that detects the column width of the
|
||||
// terminal we are in, and adjusts every line width to fit and use recommended
|
||||
// terminal sizes for better readability. Does proper word wrapping automatically.
|
||||
// if terminal width >= 120 columns use 120 columns
|
||||
// if terminal width >= 100 columns use 100 columns
|
||||
// if terminal width >= 80 columns use 80 columns
|
||||
//
|
||||
// if terminal width >= 120 columns use 120 columns
|
||||
// if terminal width >= 100 columns use 100 columns
|
||||
// if terminal width >= 80 columns use 80 columns
|
||||
//
|
||||
// In case we're not in a terminal or if it's smaller than 80 columns width,
|
||||
// doesn't do any wrapping.
|
||||
func NewResponsiveWriter(w io.Writer) io.Writer {
|
||||
@@ -51,16 +56,7 @@ func NewResponsiveWriter(w io.Writer) io.Writer {
|
||||
if terminalSize == nil {
|
||||
return w
|
||||
}
|
||||
|
||||
var limit uint
|
||||
switch {
|
||||
case terminalSize.Width >= 120:
|
||||
limit = 120
|
||||
case terminalSize.Width >= 100:
|
||||
limit = 100
|
||||
case terminalSize.Width >= 80:
|
||||
limit = 80
|
||||
}
|
||||
limit := getTerminalLimitWidth(terminalSize)
|
||||
|
||||
return NewWordWrapWriter(w, limit)
|
||||
}
|
||||
@@ -74,6 +70,32 @@ func NewWordWrapWriter(w io.Writer, limit uint) io.Writer {
|
||||
}
|
||||
}
|
||||
|
||||
func getTerminalLimitWidth(terminalSize *remotecommand.TerminalSize) uint {
|
||||
var limit uint
|
||||
switch {
|
||||
case terminalSize.Width >= 120:
|
||||
limit = 120
|
||||
case terminalSize.Width >= 100:
|
||||
limit = 100
|
||||
case terminalSize.Width >= 80:
|
||||
limit = 80
|
||||
}
|
||||
return limit
|
||||
}
|
||||
|
||||
func GetWordWrapperLimit() (uint, error) {
|
||||
stdout := os.Stdout
|
||||
fd := stdout.Fd()
|
||||
if !term.IsTerminal(fd) {
|
||||
return 0, errors.New("file descriptor is not a terminal")
|
||||
}
|
||||
terminalSize := GetSize(fd)
|
||||
if terminalSize == nil {
|
||||
return 0, errors.New("terminal size is nil")
|
||||
}
|
||||
return getTerminalLimitWidth(terminalSize), nil
|
||||
}
|
||||
|
||||
func (w wordWrapWriter) Write(p []byte) (nn int, err error) {
|
||||
if w.limit == 0 {
|
||||
return w.writer.Write(p)
|
||||
|
||||
51
vendor/k8s.io/kubectl/pkg/validation/schema.go
generated
vendored
51
vendor/k8s.io/kubectl/pkg/validation/schema.go
generated
vendored
@@ -22,7 +22,11 @@ import (
|
||||
"fmt"
|
||||
|
||||
ejson "github.com/exponent-io/jsonpath"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/cli-runtime/pkg/resource"
|
||||
"k8s.io/klog/v2"
|
||||
schemavalidation "k8s.io/kubectl/pkg/util/openapi/validation"
|
||||
)
|
||||
|
||||
// Schema is an interface that knows how to validate an API object serialized to a byte array.
|
||||
@@ -101,3 +105,50 @@ func (c ConjunctiveSchema) ValidateBytes(data []byte) error {
|
||||
}
|
||||
return utilerrors.NewAggregate(list)
|
||||
}
|
||||
|
||||
func NewParamVerifyingSchema(s Schema, verifier resource.Verifier, directive string) Schema {
|
||||
return ¶mVerifyingSchema{
|
||||
schema: s,
|
||||
verifier: verifier,
|
||||
directive: directive,
|
||||
}
|
||||
}
|
||||
|
||||
// paramVerifyingSchema only performs validation
|
||||
// based on the fieldValidation query param
|
||||
// being unsupported by the apiserver, because
|
||||
// server-side validation will be performed instead
|
||||
// of client-side validation.
|
||||
type paramVerifyingSchema struct {
|
||||
schema Schema
|
||||
verifier resource.Verifier
|
||||
directive string
|
||||
}
|
||||
|
||||
// ValidateBytes validates bytes per a ParamVerifyingSchema
|
||||
func (c *paramVerifyingSchema) ValidateBytes(data []byte) error {
|
||||
obj, err := schemavalidation.Parse(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gvk, errs := schemavalidation.GetObjectKind(obj)
|
||||
if errs != nil {
|
||||
return utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
err = c.verifier.HasSupport(gvk)
|
||||
if resource.IsParamUnsupportedError(err) {
|
||||
switch c.directive {
|
||||
case metav1.FieldValidationStrict:
|
||||
return c.schema.ValidateBytes(data)
|
||||
case metav1.FieldValidationWarn:
|
||||
klog.Warningf("cannot perform warn validation if server-side field validation is unsupported, skipping validation")
|
||||
default:
|
||||
// can't be reached
|
||||
klog.Warningf("unexpected field validation directive: %s, skipping validation", c.directive)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user