cleanup some dead kubectl code and narrow scope of helpers

This commit is contained in:
David Eads
2018-05-29 09:57:15 -04:00
parent e3a4104479
commit 207e9d1d90
22 changed files with 18 additions and 447 deletions

View File

@@ -58,10 +58,7 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"factory_test.go",
"helpers_test.go",
],
srcs = ["helpers_test.go"],
embed = [":go_default_library"],
deps = [
"//pkg/api/testapi:go_default_library",
@@ -90,8 +87,6 @@ filegroup(
srcs = [
":package-srcs",
"//pkg/kubectl/cmd/util/editor:all-srcs",
"//pkg/kubectl/cmd/util/env:all-srcs",
"//pkg/kubectl/cmd/util/jsonmerge:all-srcs",
"//pkg/kubectl/cmd/util/openapi:all-srcs",
"//pkg/kubectl/cmd/util/sanity:all-srcs",
],

View File

@@ -18,11 +18,11 @@ go_library(
"//pkg/apis/core:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/editor/crlf:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//pkg/kubectl/genericclioptions/printers:go_default_library",
"//pkg/kubectl/genericclioptions/resource:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//pkg/kubectl/util/crlf:go_default_library",
"//pkg/kubectl/util/term:go_default_library",
"//vendor/github.com/evanphx/json-patch:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
@@ -57,7 +57,10 @@ filegroup(
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
srcs = [
":package-srcs",
"//pkg/kubectl/cmd/util/editor/crlf:all-srcs",
],
tags = ["automanaged"],
visibility = [
"//build/visible_to:pkg_kubectl_cmd_util_editor_CONSUMERS",

View File

@@ -0,0 +1,25 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["crlf.go"],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/crlf",
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@@ -0,0 +1,57 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package crlf
import (
"bytes"
"io"
)
type crlfWriter struct {
io.Writer
}
// NewCRLFWriter implements a CR/LF line ending writer used for normalizing
// text for Windows platforms.
func NewCRLFWriter(w io.Writer) io.Writer {
return crlfWriter{w}
}
func (w crlfWriter) Write(b []byte) (n int, err error) {
for i, written := 0, 0; ; {
next := bytes.Index(b[i:], []byte("\n"))
if next == -1 {
n, err := w.Writer.Write(b[i:])
return written + n, err
}
next = next + i
n, err := w.Writer.Write(b[i:next])
if err != nil {
return written + n, err
}
written += n
n, err = w.Writer.Write([]byte("\r\n"))
if err != nil {
if n > 1 {
n = 1
}
return written + n, err
}
written++
i = next + 1
}
}

View File

@@ -45,11 +45,11 @@ import (
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor/crlf"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/crlf"
)
// EditOptions contains all the options for running edit cli command.

View File

@@ -1,41 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"env_parse.go",
"env_resolve.go",
],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/env",
visibility = ["//visibility:public"],
deps = [
"//pkg/api/v1/resource:go_default_library",
"//pkg/fieldpath:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/client-go/kubernetes: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"],
)
go_test(
name = "go_default_test",
srcs = ["env_parse_test.go"],
embed = [":go_default_library"],
)

View File

@@ -1,18 +0,0 @@
/*
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.
*/
// Package env provides functions to incorporate environment variables into kubectl commands.
package env // import "k8s.io/kubernetes/pkg/kubectl/cmd/util/env"

View File

@@ -1,156 +0,0 @@
/*
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.
*/
package env
import (
"bufio"
"fmt"
"io"
"os"
"regexp"
"strings"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
)
// Env returns an environment variable if not nil, or a default value.
func Env(key string, defaultValue string) string {
val := os.Getenv(key)
if len(val) == 0 {
return defaultValue
}
return val
}
// GetEnv returns an environment value if not nil, and an ok boolean.
func GetEnv(key string) (string, bool) {
val := os.Getenv(key)
if len(val) == 0 {
return "", false
}
return val, true
}
var argumentEnvironment = regexp.MustCompile("(?ms)^(.+)\\=(.*)$")
var validArgumentEnvironment = regexp.MustCompile("(?ms)^(\\w+)\\=(.*)$")
// IsEnvironmentArgument checks whether a string is an environment argument, that is, whether it matches the "anycharacters=anycharacters" pattern.
func IsEnvironmentArgument(s string) bool {
return argumentEnvironment.MatchString(s)
}
// IsValidEnvironmentArgument checks whether a string is a valid environment argument, that is, whether it matches the "wordcharacters=anycharacters" pattern. Word characters can be letters, numbers, and underscores.
func IsValidEnvironmentArgument(s string) bool {
return validArgumentEnvironment.MatchString(s)
}
// SplitEnvironmentFromResources separates resources from environment arguments.
// Resources must come first. Arguments may have the "DASH-" syntax.
func SplitEnvironmentFromResources(args []string) (resources, envArgs []string, ok bool) {
first := true
for _, s := range args {
// this method also has to understand env removal syntax, i.e. KEY-
isEnv := IsEnvironmentArgument(s) || strings.HasSuffix(s, "-")
switch {
case first && isEnv:
first = false
fallthrough
case !first && isEnv:
envArgs = append(envArgs, s)
case first && !isEnv:
resources = append(resources, s)
case !first && !isEnv:
return nil, nil, false
}
}
return resources, envArgs, true
}
// parseIntoEnvVar parses the list of key-value pairs into kubernetes EnvVar.
// envVarType is for making errors more specific to user intentions.
func parseIntoEnvVar(spec []string, defaultReader io.Reader, envVarType string) ([]v1.EnvVar, []string, error) {
env := []v1.EnvVar{}
exists := sets.NewString()
var remove []string
for _, envSpec := range spec {
switch {
case !IsValidEnvironmentArgument(envSpec) && !strings.HasSuffix(envSpec, "-"):
return nil, nil, fmt.Errorf("%ss must be of the form key=value and can only contain letters, numbers, and underscores", envVarType)
case envSpec == "-":
if defaultReader == nil {
return nil, nil, fmt.Errorf("when '-' is used, STDIN must be open")
}
fileEnv, err := readEnv(defaultReader, envVarType)
if err != nil {
return nil, nil, err
}
env = append(env, fileEnv...)
case strings.Index(envSpec, "=") != -1:
parts := strings.SplitN(envSpec, "=", 2)
if len(parts) != 2 {
return nil, nil, fmt.Errorf("invalid %s: %v", envVarType, envSpec)
}
exists.Insert(parts[0])
env = append(env, v1.EnvVar{
Name: parts[0],
Value: parts[1],
})
case strings.HasSuffix(envSpec, "-"):
remove = append(remove, envSpec[:len(envSpec)-1])
default:
return nil, nil, fmt.Errorf("unknown %s: %v", envVarType, envSpec)
}
}
for _, removeLabel := range remove {
if _, found := exists[removeLabel]; found {
return nil, nil, fmt.Errorf("can not both modify and remove the same %s in the same command", envVarType)
}
}
return env, remove, nil
}
// ParseEnv parses the elements of the first argument looking for environment variables in key=value form and, if one of those values is "-", it also scans the reader.
// The same environment variable cannot be both modified and removed in the same command.
func ParseEnv(spec []string, defaultReader io.Reader) ([]v1.EnvVar, []string, error) {
return parseIntoEnvVar(spec, defaultReader, "environment variable")
}
func readEnv(r io.Reader, envVarType string) ([]v1.EnvVar, error) {
env := []v1.EnvVar{}
scanner := bufio.NewScanner(r)
for scanner.Scan() {
envSpec := scanner.Text()
if pos := strings.Index(envSpec, "#"); pos != -1 {
envSpec = envSpec[:pos]
}
if strings.Index(envSpec, "=") != -1 {
parts := strings.SplitN(envSpec, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid %s: %v", envVarType, envSpec)
}
env = append(env, v1.EnvVar{
Name: parts[0],
Value: parts[1],
})
}
}
if err := scanner.Err(); err != nil && err != io.EOF {
return nil, err
}
return env, nil
}

View File

@@ -1,96 +0,0 @@
/*
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.
*/
package env
import (
"fmt"
"io"
"os"
"strings"
)
func ExampleEnv_defaultValue() {
fmt.Println(Env("TESTENVVAR", "default"))
// Output: default
}
func ExampleEnv_variableExists() {
os.Setenv("TESTENVVAR", "test value")
defer os.Unsetenv("TESTENVVAR")
fmt.Println(Env("TESTENVVAR", "default"))
// Output: test value
}
func ExampleGetEnv_variableExists() {
os.Setenv("THISVAREXISTS", "value")
defer os.Unsetenv("THISVAREXISTS")
fmt.Println(GetEnv("THISVAREXISTS"))
// Output:
// value true
}
func ExampleGetEnv_variableDoesNotExist() {
fmt.Println(GetEnv("THISVARDOESNOTEXIST"))
// Output:
// false
}
func ExampleIsEnvironmentArgument_true() {
test := "returns=true"
fmt.Println(IsEnvironmentArgument(test))
// Output: true
}
func ExampleIsEnvironmentArgument_false() {
test := "returnsfalse"
fmt.Println(IsEnvironmentArgument(test))
// Output: false
}
func ExampleIsValidEnvironmentArgument_true() {
test := "wordcharacters=true"
fmt.Println(IsValidEnvironmentArgument(test))
// Output: true
}
func ExampleIsValidEnvironmentArgument_false() {
test := "not$word^characters=test"
fmt.Println(IsValidEnvironmentArgument(test))
// Output: false
}
func ExampleSplitEnvironmentFromResources() {
args := []string{`resource`, "ENV\\=ARG", `ONE\=MORE`, `DASH-`}
fmt.Println(SplitEnvironmentFromResources(args))
// Output: [resource] [ENV\=ARG ONE\=MORE DASH-] true
}
func ExampleParseEnv_good() {
r := strings.NewReader("FROM=READER")
ss := []string{"ENV=VARIABLE", "AND=ANOTHER", "REMOVE-", "-"}
fmt.Println(ParseEnv(ss, r))
// Output:
// [{ENV VARIABLE nil} {AND ANOTHER nil} {FROM READER nil}] [REMOVE] <nil>
}
func ExampleParseEnv_bad() {
var r io.Reader
bad := []string{"This not in the key=value format."}
fmt.Println(ParseEnv(bad, r))
// Output:
// [] [] environment variables must be of the form key=value and can only contain letters, numbers, and underscores
}

View File

@@ -1,133 +0,0 @@
/*
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.
*/
package env
import (
"fmt"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/api/v1/resource"
"k8s.io/kubernetes/pkg/fieldpath"
)
// ResourceStore defines a new resource store data structure.
type ResourceStore struct {
SecretStore map[string]*v1.Secret
ConfigMapStore map[string]*v1.ConfigMap
}
// NewResourceStore returns a pointer to a new resource store data structure.
func NewResourceStore() *ResourceStore {
return &ResourceStore{
SecretStore: make(map[string]*v1.Secret),
ConfigMapStore: make(map[string]*v1.ConfigMap),
}
}
// getSecretRefValue returns the value of a secret in the supplied namespace
func getSecretRefValue(client kubernetes.Interface, namespace string, store *ResourceStore, secretSelector *v1.SecretKeySelector) (string, error) {
secret, ok := store.SecretStore[secretSelector.Name]
if !ok {
var err error
secret, err = client.CoreV1().Secrets(namespace).Get(secretSelector.Name, metav1.GetOptions{})
if err != nil {
return "", err
}
store.SecretStore[secretSelector.Name] = secret
}
if data, ok := secret.Data[secretSelector.Key]; ok {
return string(data), nil
}
return "", fmt.Errorf("key %s not found in secret %s", secretSelector.Key, secretSelector.Name)
}
// getConfigMapRefValue returns the value of a configmap in the supplied namespace
func getConfigMapRefValue(client kubernetes.Interface, namespace string, store *ResourceStore, configMapSelector *v1.ConfigMapKeySelector) (string, error) {
configMap, ok := store.ConfigMapStore[configMapSelector.Name]
if !ok {
var err error
configMap, err = client.CoreV1().ConfigMaps(namespace).Get(configMapSelector.Name, metav1.GetOptions{})
if err != nil {
return "", err
}
store.ConfigMapStore[configMapSelector.Name] = configMap
}
if data, ok := configMap.Data[configMapSelector.Key]; ok {
return string(data), nil
}
return "", fmt.Errorf("key %s not found in config map %s", configMapSelector.Key, configMapSelector.Name)
}
// getFieldRef returns the value of the supplied path in the given object
func getFieldRef(obj runtime.Object, from *v1.EnvVarSource) (string, error) {
return fieldpath.ExtractFieldPathAsString(obj, from.FieldRef.FieldPath)
}
// getResourceFieldRef returns the value of a resource in the given container
func getResourceFieldRef(from *v1.EnvVarSource, c *v1.Container) (string, error) {
return resource.ExtractContainerResourceValue(from.ResourceFieldRef, c)
}
// GetEnvVarRefValue returns the value referenced by the supplied EnvVarSource given the other supplied information.
func GetEnvVarRefValue(kc kubernetes.Interface, ns string, store *ResourceStore, from *v1.EnvVarSource, obj runtime.Object, c *v1.Container) (string, error) {
if from.SecretKeyRef != nil {
return getSecretRefValue(kc, ns, store, from.SecretKeyRef)
}
if from.ConfigMapKeyRef != nil {
return getConfigMapRefValue(kc, ns, store, from.ConfigMapKeyRef)
}
if from.FieldRef != nil {
return getFieldRef(obj, from)
}
if from.ResourceFieldRef != nil {
return getResourceFieldRef(from, c)
}
return "", fmt.Errorf("invalid valueFrom")
}
// GetEnvVarRefString returns a text description of whichever field is set within the supplied EnvVarSource argument.
func GetEnvVarRefString(from *v1.EnvVarSource) string {
if from.ConfigMapKeyRef != nil {
return fmt.Sprintf("configmap %s, key %s", from.ConfigMapKeyRef.Name, from.ConfigMapKeyRef.Key)
}
if from.SecretKeyRef != nil {
return fmt.Sprintf("secret %s, key %s", from.SecretKeyRef.Name, from.SecretKeyRef.Key)
}
if from.FieldRef != nil {
return fmt.Sprintf("field path %s", from.FieldRef.FieldPath)
}
if from.ResourceFieldRef != nil {
containerPrefix := ""
if from.ResourceFieldRef.ContainerName != "" {
containerPrefix = fmt.Sprintf("%s/", from.ResourceFieldRef.ContainerName)
}
return fmt.Sprintf("resource field %s%s", containerPrefix, from.ResourceFieldRef.Resource)
}
return "invalid valueFrom"
}

View File

@@ -17,15 +17,10 @@ limitations under the License.
package util
import (
"fmt"
"strconv"
"strings"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
@@ -73,26 +68,3 @@ type Factory interface {
// OpenAPISchema returns the schema openapi schema definition
OpenAPISchema() (openapi.Resources, error)
}
func makePortsString(ports []api.ServicePort, useNodePort bool) string {
pieces := make([]string, len(ports))
for ix := range ports {
var port int32
if useNodePort {
port = ports[ix].NodePort
} else {
port = ports[ix].Port
}
pieces[ix] = fmt.Sprintf("%s:%d", strings.ToLower(string(ports[ix].Protocol)), port)
}
return strings.Join(pieces, ",")
}
// Extracts the protocols exposed by a service from the given service spec.
func getServiceProtocols(spec api.ServiceSpec) map[string]string {
result := make(map[string]string)
for _, servicePort := range spec.Ports {
result[strconv.Itoa(int(servicePort.Port))] = string(servicePort.Protocol)
}
return result
}

View File

@@ -28,7 +28,6 @@ import (
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
scaleclient "k8s.io/client-go/scale"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core"
@@ -189,24 +188,6 @@ func (f *factoryImpl) OpenAPISchema() (openapi.Resources, error) {
return f.openAPIGetter.getter.Get()
}
func (f *factoryImpl) ScaleClient() (scaleclient.ScalesGetter, error) {
discoClient, err := f.clientGetter.ToDiscoveryClient()
if err != nil {
return nil, err
}
restClient, err := f.RESTClient()
if err != nil {
return nil, err
}
resolver := scaleclient.NewDiscoveryScaleKindResolver(discoClient)
mapper, err := f.clientGetter.ToRESTMapper()
if err != nil {
return nil, err
}
return scaleclient.New(restClient, mapper, dynamic.LegacyAPIPathResolverFunc, resolver), nil
}
// this method exists to help us find the points still relying on internal types.
func InternalVersionDecoder() runtime.Decoder {
return legacyscheme.Codecs.UniversalDecoder()

View File

@@ -1,79 +0,0 @@
/*
Copyright 2014 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 (
"testing"
api "k8s.io/kubernetes/pkg/apis/core"
)
func TestMakePortsString(t *testing.T) {
tests := []struct {
ports []api.ServicePort
useNodePort bool
expectedOutput string
}{
{ports: nil, expectedOutput: ""},
{ports: []api.ServicePort{}, expectedOutput: ""},
{ports: []api.ServicePort{
{
Port: 80,
Protocol: "TCP",
},
},
expectedOutput: "tcp:80",
},
{ports: []api.ServicePort{
{
Port: 80,
Protocol: "TCP",
},
{
Port: 8080,
Protocol: "UDP",
},
{
Port: 9000,
Protocol: "TCP",
},
},
expectedOutput: "tcp:80,udp:8080,tcp:9000",
},
{ports: []api.ServicePort{
{
Port: 80,
NodePort: 9090,
Protocol: "TCP",
},
{
Port: 8080,
NodePort: 80,
Protocol: "UDP",
},
},
useNodePort: true,
expectedOutput: "tcp:9090,udp:80",
},
}
for _, test := range tests {
output := makePortsString(test.ports, test.useNodePort)
if output != test.expectedOutput {
t.Errorf("expected: %s, saw: %s.", test.expectedOutput, output)
}
}
}

View File

@@ -62,7 +62,6 @@ const (
ConfigMapV1GeneratorName = "configmap/v1"
ClusterRoleBindingV1GeneratorName = "clusterrolebinding.rbac.authorization.k8s.io/v1alpha1"
RoleBindingV1GeneratorName = "rolebinding.rbac.authorization.k8s.io/v1alpha1"
ClusterV1Beta1GeneratorName = "cluster/v1beta1"
PodDisruptionBudgetV1GeneratorName = "poddisruptionbudget/v1beta1"
PodDisruptionBudgetV2GeneratorName = "poddisruptionbudget/v1beta1/v2"
PriorityClassV1Alpha1GeneratorName = "priorityclass/v1alpha1"

View File

@@ -300,16 +300,6 @@ func IsFilenameSliceEmpty(filenames []string) bool {
return len(filenames) == 0
}
// Whether this cmd need watching objects.
func isWatch(cmd *cobra.Command) bool {
if w, err := cmd.Flags().GetBool("watch"); err == nil && w {
return true
}
wo, err := cmd.Flags().GetBool("watch-only")
return err == nil && wo
}
func GetFlagString(cmd *cobra.Command, flag string) string {
s, err := cmd.Flags().GetString(flag)
if err != nil {
@@ -336,15 +326,6 @@ func GetFlagStringArray(cmd *cobra.Command, flag string) []string {
return s
}
// GetWideFlag is used to determine if "-o wide" is used
func GetWideFlag(cmd *cobra.Command) bool {
f := cmd.Flags().Lookup("output")
if f != nil && f.Value != nil && f.Value.String() == "wide" {
return true
}
return false
}
func GetFlagBool(cmd *cobra.Command, flag string) bool {
b, err := cmd.Flags().GetBool(flag)
if err != nil {

View File

@@ -1,32 +0,0 @@
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["jsonmerge.go"],
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/util/jsonmerge",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/evanphx/json-patch:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/mergepatch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = [
"//build/visible_to:pkg_kubectl_cmd_util_jsonmerge_CONSUMERS",
],
)

View File

@@ -1,193 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package jsonmerge
import (
"encoding/json"
"fmt"
"github.com/evanphx/json-patch"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/util/mergepatch"
"k8s.io/apimachinery/pkg/util/yaml"
)
// Delta represents a change between two JSON documents.
type Delta struct {
original []byte
edit []byte
preconditions []PreconditionFunc
}
// PreconditionFunc is a test to verify that an incompatible change
// has occurred before an Apply can be successful.
type PreconditionFunc func(interface{}) (hold bool, message string)
// AddPreconditions adds precondition checks to a change which must
// be satisfied before an Apply is considered successful. If a
// precondition returns false, the Apply is failed with
// ErrPreconditionFailed.
func (d *Delta) AddPreconditions(fns ...PreconditionFunc) {
d.preconditions = append(d.preconditions, fns...)
}
// RequireKeyUnchanged creates a precondition function that fails
// if the provided key is present in the diff (indicating its value
// has changed).
func RequireKeyUnchanged(key string) PreconditionFunc {
return func(diff interface{}) (bool, string) {
m, ok := diff.(map[string]interface{})
if !ok {
return true, ""
}
// the presence of key in a diff means that its value has been changed, therefore
// we should fail the precondition.
_, ok = m[key]
if ok {
return false, key + " should not be changed\n"
} else {
return true, ""
}
}
}
// RequireMetadataKeyUnchanged creates a precondition function that fails
// if the metadata.key is present in the diff (indicating its value
// has changed).
func RequireMetadataKeyUnchanged(key string) PreconditionFunc {
return func(diff interface{}) (bool, string) {
m, ok := diff.(map[string]interface{})
if !ok {
return true, ""
}
m1, ok := m["metadata"]
if !ok {
return true, ""
}
m2, ok := m1.(map[string]interface{})
if !ok {
return true, ""
}
_, ok = m2[key]
if ok {
return false, "metadata." + key + " should not be changed\n"
} else {
return true, ""
}
}
}
// TestPreconditions test if preconditions hold given the edit
func TestPreconditionsHold(edit []byte, preconditions []PreconditionFunc) (bool, string) {
diff := make(map[string]interface{})
if err := json.Unmarshal(edit, &diff); err != nil {
return false, err.Error()
}
for _, fn := range preconditions {
if hold, msg := fn(diff); !hold {
return false, msg
}
}
return true, ""
}
// NewDelta accepts two JSON or YAML documents and calculates the difference
// between them. It returns a Delta object which can be used to resolve
// conflicts against a third version with a common parent, or an error
// if either document is in error.
func NewDelta(from, to []byte) (*Delta, error) {
d := &Delta{}
before, err := yaml.ToJSON(from)
if err != nil {
return nil, err
}
after, err := yaml.ToJSON(to)
if err != nil {
return nil, err
}
diff, err := jsonpatch.CreateMergePatch(before, after)
if err != nil {
return nil, err
}
glog.V(6).Infof("Patch created from:\n%s\n%s\n%s", string(before), string(after), string(diff))
d.original = before
d.edit = diff
return d, nil
}
// Apply attempts to apply the changes described by Delta onto latest,
// returning an error if the changes cannot be applied cleanly.
// IsConflicting will be true if the changes overlap, otherwise a
// generic error will be returned.
func (d *Delta) Apply(latest []byte) ([]byte, error) {
base, err := yaml.ToJSON(latest)
if err != nil {
return nil, err
}
changes, err := jsonpatch.CreateMergePatch(d.original, base)
if err != nil {
return nil, err
}
diff1 := make(map[string]interface{})
if err := json.Unmarshal(d.edit, &diff1); err != nil {
return nil, err
}
diff2 := make(map[string]interface{})
if err := json.Unmarshal(changes, &diff2); err != nil {
return nil, err
}
for _, fn := range d.preconditions {
hold1, _ := fn(diff1)
hold2, _ := fn(diff2)
if !hold1 || !hold2 {
return nil, ErrPreconditionFailed
}
}
glog.V(6).Infof("Testing for conflict between:\n%s\n%s", string(d.edit), string(changes))
hasConflicts, err := mergepatch.HasConflicts(diff1, diff2)
if err != nil {
return nil, err
}
if hasConflicts {
return nil, ErrConflict
}
return jsonpatch.MergePatch(base, d.edit)
}
// IsConflicting returns true if the provided error indicates a
// conflict exists between the original changes and the applied
// changes.
func IsConflicting(err error) bool {
return err == ErrConflict
}
// IsPreconditionFailed returns true if the provided error indicates
// a Delta precondition did not succeed.
func IsPreconditionFailed(err error) bool {
return err == ErrPreconditionFailed
}
var ErrPreconditionFailed = fmt.Errorf("a precondition failed")
var ErrConflict = fmt.Errorf("changes are in conflict")
func (d *Delta) Edit() []byte {
return d.edit
}