Update godeps
This commit is contained in:
parent
1c8773fc98
commit
1bc383f9c5
1723 changed files with 287976 additions and 411028 deletions
179
vendor/k8s.io/kubernetes/pkg/kubectl/BUILD
generated
vendored
Normal file
179
vendor/k8s.io/kubernetes/pkg/kubectl/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
"go_test",
|
||||
"cgo_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"apply.go",
|
||||
"autoscale.go",
|
||||
"bash_comp_utils.go",
|
||||
"cluster.go",
|
||||
"configmap.go",
|
||||
"custom_column_printer.go",
|
||||
"deployment.go",
|
||||
"describe.go",
|
||||
"doc.go",
|
||||
"explain.go",
|
||||
"generate.go",
|
||||
"history.go",
|
||||
"interfaces.go",
|
||||
"kubectl.go",
|
||||
"namespace.go",
|
||||
"proxy_server.go",
|
||||
"quota.go",
|
||||
"resource_filter.go",
|
||||
"resource_printer.go",
|
||||
"rollback.go",
|
||||
"rolling_updater.go",
|
||||
"rollout_status.go",
|
||||
"run.go",
|
||||
"scale.go",
|
||||
"secret.go",
|
||||
"secret_for_docker_registry.go",
|
||||
"secret_for_tls.go",
|
||||
"service.go",
|
||||
"service_basic.go",
|
||||
"serviceaccount.go",
|
||||
"sorted_resource_name_list.go",
|
||||
"sorting_printer.go",
|
||||
"stop.go",
|
||||
"version.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/apis/federation/v1beta1:go_default_library",
|
||||
"//federation/client/clientset_generated/federation_internalclientset:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/annotations:go_default_library",
|
||||
"//pkg/api/errors:go_default_library",
|
||||
"//pkg/api/events:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/resource:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/util:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/autoscaling:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/batch/v1:go_default_library",
|
||||
"//pkg/apis/batch/v2alpha1:go_default_library",
|
||||
"//pkg/apis/certificates:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/rbac:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/apis/storage/util:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/apps/internalversion:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/batch/internalversion:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/client/retry:go_default_library",
|
||||
"//pkg/client/unversioned:go_default_library",
|
||||
"//pkg/controller/deployment/util:go_default_library",
|
||||
"//pkg/credentialprovider:go_default_library",
|
||||
"//pkg/fieldpath:go_default_library",
|
||||
"//pkg/fields:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/kubelet/qos:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/types:go_default_library",
|
||||
"//pkg/util:go_default_library",
|
||||
"//pkg/util/cert:go_default_library",
|
||||
"//pkg/util/errors:go_default_library",
|
||||
"//pkg/util/integer:go_default_library",
|
||||
"//pkg/util/intstr:go_default_library",
|
||||
"//pkg/util/jsonpath:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//pkg/util/sets:go_default_library",
|
||||
"//pkg/util/slice:go_default_library",
|
||||
"//pkg/util/uuid:go_default_library",
|
||||
"//pkg/util/validation:go_default_library",
|
||||
"//pkg/util/wait:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//vendor:github.com/emicklei/go-restful/swagger",
|
||||
"//vendor:github.com/ghodss/yaml",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:github.com/spf13/cobra",
|
||||
"//vendor:github.com/spf13/pflag",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"cluster_test.go",
|
||||
"configmap_test.go",
|
||||
"custom_column_printer_test.go",
|
||||
"deployment_test.go",
|
||||
"describe_test.go",
|
||||
"generate_test.go",
|
||||
"kubectl_test.go",
|
||||
"namespace_test.go",
|
||||
"proxy_server_test.go",
|
||||
"quota_test.go",
|
||||
"resource_printer_test.go",
|
||||
"rolling_updater_test.go",
|
||||
"rollout_status_test.go",
|
||||
"run_test.go",
|
||||
"scale_test.go",
|
||||
"secret_for_docker_registry_test.go",
|
||||
"secret_for_tls_test.go",
|
||||
"secret_test.go",
|
||||
"service_basic_test.go",
|
||||
"service_test.go",
|
||||
"serviceaccount_test.go",
|
||||
"sorted_resource_name_list_test.go",
|
||||
"sorting_printer_test.go",
|
||||
"stop_test.go",
|
||||
],
|
||||
library = "go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/apis/federation/v1beta1:go_default_library",
|
||||
"//federation/client/clientset_generated/federation_internalclientset/fake:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/errors:go_default_library",
|
||||
"//pkg/api/resource:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apimachinery/registered:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/batch/internalversion:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/client/restclient/fake:go_default_library",
|
||||
"//pkg/client/testing/core:go_default_library",
|
||||
"//pkg/controller/deployment/util:go_default_library",
|
||||
"//pkg/kubectl/testing:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/serializer/yaml:go_default_library",
|
||||
"//pkg/util/diff:go_default_library",
|
||||
"//pkg/util/intstr:go_default_library",
|
||||
"//pkg/util/sets:go_default_library",
|
||||
"//pkg/util/testing:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//vendor:github.com/ghodss/yaml",
|
||||
"//vendor:github.com/spf13/cobra",
|
||||
],
|
||||
)
|
||||
11
vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS
generated
vendored
11
vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS
generated
vendored
|
|
@ -1,7 +1,4 @@
|
|||
assignees:
|
||||
- brendandburns
|
||||
- deads2k
|
||||
- janetkuo
|
||||
- jlowdermilk
|
||||
- pwittrock
|
||||
- smarterclayton
|
||||
approvers:
|
||||
- sig-cli-maintainers
|
||||
reviewers:
|
||||
- sig-cli
|
||||
|
|
|
|||
6
vendor/k8s.io/kubernetes/pkg/kubectl/apply.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/kubectl/apply.go
generated
vendored
|
|
@ -25,10 +25,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
type debugError interface {
|
||||
DebugError() (msg string, args []interface{})
|
||||
}
|
||||
|
||||
// GetOriginalConfiguration retrieves the original configuration of the object
|
||||
// from the annotation, or nil if no annotation was found.
|
||||
func GetOriginalConfiguration(mapping *meta.RESTMapping, obj runtime.Object) ([]byte, error) {
|
||||
|
|
@ -75,7 +71,7 @@ func SetOriginalConfiguration(info *resource.Info, original []byte) error {
|
|||
}
|
||||
|
||||
// GetModifiedConfiguration retrieves the modified configuration of the object.
|
||||
// If annotate is true, it embeds the result as an anotation in the modified
|
||||
// If annotate is true, it embeds the result as an annotation in the modified
|
||||
// configuration. If an object was read from the command input, it will use that
|
||||
// version of the object. Otherwise, it will use the version from the server.
|
||||
func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.Encoder) ([]byte, error) {
|
||||
|
|
|
|||
125
vendor/k8s.io/kubernetes/pkg/kubectl/cluster.go
generated
vendored
Normal file
125
vendor/k8s.io/kubernetes/pkg/kubectl/cluster.go
generated
vendored
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
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 kubectl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
federationapi "k8s.io/kubernetes/federation/apis/federation/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// ClusterGeneratorV1Beta1 supports stable generation of a
|
||||
// federation/cluster resource.
|
||||
type ClusterGeneratorV1Beta1 struct {
|
||||
// Name of the cluster context (required)
|
||||
Name string
|
||||
// ClientCIDR is the CIDR range in which the Kubernetes APIServer
|
||||
// is available for the client (optional)
|
||||
ClientCIDR string
|
||||
// ServerAddress is the APIServer address of the Kubernetes cluster
|
||||
// that is being registered (required)
|
||||
ServerAddress string
|
||||
// SecretName is the name of the secret that stores the credentials
|
||||
// for the Kubernetes cluster that is being registered (optional)
|
||||
SecretName string
|
||||
}
|
||||
|
||||
// Ensure it supports the generator pattern that uses parameter
|
||||
// injection.
|
||||
var _ Generator = &ClusterGeneratorV1Beta1{}
|
||||
|
||||
// Ensure it supports the generator pattern that uses parameters
|
||||
// specified during construction.
|
||||
var _ StructuredGenerator = &ClusterGeneratorV1Beta1{}
|
||||
|
||||
// Generate returns a cluster resource using the specified parameters.
|
||||
func (s ClusterGeneratorV1Beta1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
err := ValidateParams(s.ParamNames(), genericParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
clustergen := &ClusterGeneratorV1Beta1{}
|
||||
params := map[string]string{}
|
||||
for key, value := range genericParams {
|
||||
strVal, isString := value.(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
|
||||
}
|
||||
params[key] = strVal
|
||||
}
|
||||
clustergen.Name = params["name"]
|
||||
clustergen.ClientCIDR = params["client-cidr"]
|
||||
clustergen.ServerAddress = params["server-address"]
|
||||
clustergen.SecretName = params["secret"]
|
||||
return clustergen.StructuredGenerate()
|
||||
}
|
||||
|
||||
// ParamNames returns the set of supported input parameters when using
|
||||
// the parameter injection generator pattern.
|
||||
func (s ClusterGeneratorV1Beta1) ParamNames() []GeneratorParam {
|
||||
return []GeneratorParam{
|
||||
{"name", true},
|
||||
{"client-cidr", false},
|
||||
{"server-address", true},
|
||||
{"secret", false},
|
||||
}
|
||||
}
|
||||
|
||||
// StructuredGenerate outputs a federation cluster resource object
|
||||
// using the configured fields.
|
||||
func (s ClusterGeneratorV1Beta1) StructuredGenerate() (runtime.Object, error) {
|
||||
if err := s.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s.ClientCIDR == "" {
|
||||
s.ClientCIDR = "0.0.0.0/0"
|
||||
}
|
||||
if s.SecretName == "" {
|
||||
s.SecretName = s.Name
|
||||
}
|
||||
cluster := &federationapi.Cluster{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: s.Name,
|
||||
},
|
||||
Spec: federationapi.ClusterSpec{
|
||||
ServerAddressByClientCIDRs: []federationapi.ServerAddressByClientCIDR{
|
||||
{
|
||||
ClientCIDR: s.ClientCIDR,
|
||||
ServerAddress: s.ServerAddress,
|
||||
},
|
||||
},
|
||||
SecretRef: &v1.LocalObjectReference{
|
||||
Name: s.SecretName,
|
||||
},
|
||||
},
|
||||
}
|
||||
return cluster, nil
|
||||
}
|
||||
|
||||
// validate validates required fields are set to support structured
|
||||
// generation.
|
||||
func (s ClusterGeneratorV1Beta1) validate() error {
|
||||
if len(s.Name) == 0 {
|
||||
return fmt.Errorf("name must be specified")
|
||||
}
|
||||
if len(s.ServerAddress) == 0 {
|
||||
return fmt.Errorf("server address must be specified")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
111
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/BUILD
generated
vendored
Normal file
111
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
"go_test",
|
||||
"cgo_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"cached_discovery.go",
|
||||
"clientcache.go",
|
||||
"factory.go",
|
||||
"helpers.go",
|
||||
"printing.go",
|
||||
"shortcut_restmapper.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//federation/apis/federation:go_default_library",
|
||||
"//federation/client/clientset_generated/federation_internalclientset:go_default_library",
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/errors:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/service:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/apimachinery/registered:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/client/typed/discovery:go_default_library",
|
||||
"//pkg/client/typed/dynamic:go_default_library",
|
||||
"//pkg/client/unversioned:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/registry/extensions/thirdpartyresourcedata:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/serializer/json:go_default_library",
|
||||
"//pkg/util/errors:go_default_library",
|
||||
"//pkg/util/exec:go_default_library",
|
||||
"//pkg/util/flag:go_default_library",
|
||||
"//pkg/util/homedir:go_default_library",
|
||||
"//pkg/util/sets:go_default_library",
|
||||
"//pkg/util/strategicpatch:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//vendor:github.com/emicklei/go-restful/swagger",
|
||||
"//vendor:github.com/evanphx/json-patch",
|
||||
"//vendor:github.com/golang/glog",
|
||||
"//vendor:github.com/spf13/cobra",
|
||||
"//vendor:github.com/spf13/pflag",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"cached_discovery_test.go",
|
||||
"factory_test.go",
|
||||
"helpers_test.go",
|
||||
"shortcut_restmapper_test.go",
|
||||
],
|
||||
data = [
|
||||
"//api/swagger-spec",
|
||||
],
|
||||
library = "go_default_library",
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/errors:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/apimachinery/registered:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/client/restclient/fake:go_default_library",
|
||||
"//pkg/client/testing/core:go_default_library",
|
||||
"//pkg/client/typed/discovery:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||
"//pkg/client/unversioned/clientcmd/api:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/resource:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/util/exec:go_default_library",
|
||||
"//pkg/util/flag:go_default_library",
|
||||
"//pkg/util/validation/field:go_default_library",
|
||||
"//pkg/version:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//vendor:github.com/emicklei/go-restful/swagger",
|
||||
"//vendor:github.com/stretchr/testify/assert",
|
||||
],
|
||||
)
|
||||
252
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/cached_discovery.go
generated
vendored
Normal file
252
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/cached_discovery.go
generated
vendored
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/emicklei/go-restful/swagger"
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
)
|
||||
|
||||
// CachedDiscoveryClient implements the functions that discovery server-supported API groups,
|
||||
// versions and resources.
|
||||
type CachedDiscoveryClient struct {
|
||||
delegate discovery.DiscoveryInterface
|
||||
|
||||
// cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well.
|
||||
cacheDirectory string
|
||||
|
||||
// ttl is how long the cache should be considered valid
|
||||
ttl time.Duration
|
||||
|
||||
// mutex protects the variables below
|
||||
mutex sync.Mutex
|
||||
|
||||
// ourFiles are all filenames of cache files created by this process
|
||||
ourFiles map[string]struct{}
|
||||
// invalidated is true if all cache files should be ignored that are not ours (e.g. after Invalidate() was called)
|
||||
invalidated bool
|
||||
// fresh is true if all used cache files were ours
|
||||
fresh bool
|
||||
}
|
||||
|
||||
var _ discovery.CachedDiscoveryInterface = &CachedDiscoveryClient{}
|
||||
|
||||
// ServerResourcesForGroupVersion returns the supported resources for a group and version.
|
||||
func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*unversioned.APIResourceList, error) {
|
||||
filename := filepath.Join(d.cacheDirectory, groupVersion, "serverresources.json")
|
||||
cachedBytes, err := d.getCachedFile(filename)
|
||||
// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
|
||||
if err == nil {
|
||||
cachedResources := &unversioned.APIResourceList{}
|
||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedResources); err == nil {
|
||||
glog.V(6).Infof("returning cached discovery info from %v", filename)
|
||||
return cachedResources, nil
|
||||
}
|
||||
}
|
||||
|
||||
liveResources, err := d.delegate.ServerResourcesForGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
return liveResources, err
|
||||
}
|
||||
|
||||
if err := d.writeCachedFile(filename, liveResources); err != nil {
|
||||
glog.V(3).Infof("failed to write cache to %v due to %v", filename, err)
|
||||
}
|
||||
|
||||
return liveResources, nil
|
||||
}
|
||||
|
||||
// ServerResources returns the supported resources for all groups and versions.
|
||||
func (d *CachedDiscoveryClient) ServerResources() (map[string]*unversioned.APIResourceList, error) {
|
||||
apiGroups, err := d.ServerGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupVersions := unversioned.ExtractGroupVersions(apiGroups)
|
||||
result := map[string]*unversioned.APIResourceList{}
|
||||
for _, groupVersion := range groupVersions {
|
||||
resources, err := d.ServerResourcesForGroupVersion(groupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[groupVersion] = resources
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerGroups() (*unversioned.APIGroupList, error) {
|
||||
filename := filepath.Join(d.cacheDirectory, "servergroups.json")
|
||||
cachedBytes, err := d.getCachedFile(filename)
|
||||
// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
|
||||
if err == nil {
|
||||
cachedGroups := &unversioned.APIGroupList{}
|
||||
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), cachedBytes, cachedGroups); err == nil {
|
||||
glog.V(6).Infof("returning cached discovery info from %v", filename)
|
||||
return cachedGroups, nil
|
||||
}
|
||||
}
|
||||
|
||||
liveGroups, err := d.delegate.ServerGroups()
|
||||
if err != nil {
|
||||
return liveGroups, err
|
||||
}
|
||||
|
||||
if err := d.writeCachedFile(filename, liveGroups); err != nil {
|
||||
glog.V(3).Infof("failed to write cache to %v due to %v", filename, err)
|
||||
}
|
||||
|
||||
return liveGroups, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) getCachedFile(filename string) ([]byte, error) {
|
||||
// after invalidation ignore cache files not created by this process
|
||||
d.mutex.Lock()
|
||||
_, ourFile := d.ourFiles[filename]
|
||||
if d.invalidated && !ourFile {
|
||||
d.mutex.Unlock()
|
||||
return nil, errors.New("cache invalidated")
|
||||
}
|
||||
d.mutex.Unlock()
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileInfo, err := file.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if time.Now().After(fileInfo.ModTime().Add(d.ttl)) {
|
||||
return nil, errors.New("cache expired")
|
||||
}
|
||||
|
||||
// the cache is present and its valid. Try to read and use it.
|
||||
cachedBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
d.fresh = d.fresh && ourFile
|
||||
|
||||
return cachedBytes, nil
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Object) error {
|
||||
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)+".")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
_, err = f.Write(bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = f.Chmod(0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
name := f.Name()
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// atomic rename
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
err = os.Rename(name, filename)
|
||||
if err == nil {
|
||||
d.ourFiles[filename] = struct{}{}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) RESTClient() restclient.Interface {
|
||||
return d.delegate.RESTClient()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerPreferredResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return d.delegate.ServerPreferredResources()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerPreferredNamespacedResources() ([]unversioned.GroupVersionResource, error) {
|
||||
return d.delegate.ServerPreferredNamespacedResources()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) ServerVersion() (*version.Info, error) {
|
||||
return d.delegate.ServerVersion()
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) SwaggerSchema(version unversioned.GroupVersion) (*swagger.ApiDeclaration, error) {
|
||||
return d.delegate.SwaggerSchema(version)
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) Fresh() bool {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
return d.fresh
|
||||
}
|
||||
|
||||
func (d *CachedDiscoveryClient) Invalidate() {
|
||||
d.mutex.Lock()
|
||||
defer d.mutex.Unlock()
|
||||
|
||||
d.ourFiles = map[string]struct{}{}
|
||||
d.fresh = true
|
||||
d.invalidated = true
|
||||
}
|
||||
|
||||
// NewCachedDiscoveryClient creates a new DiscoveryClient. cacheDirectory is the directory where discovery docs are held. It must be unique per host:port combination to work well.
|
||||
func NewCachedDiscoveryClient(delegate discovery.DiscoveryInterface, cacheDirectory string, ttl time.Duration) *CachedDiscoveryClient {
|
||||
return &CachedDiscoveryClient{
|
||||
delegate: delegate,
|
||||
cacheDirectory: cacheDirectory,
|
||||
ttl: ttl,
|
||||
ourFiles: map[string]struct{}{},
|
||||
fresh: true,
|
||||
}
|
||||
}
|
||||
123
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/clientcache.go
generated
vendored
123
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/clientcache.go
generated
vendored
|
|
@ -17,17 +17,21 @@ limitations under the License.
|
|||
package util
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
fed_clientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
oldclient "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
)
|
||||
|
||||
func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
|
||||
return &ClientCache{
|
||||
clients: make(map[unversioned.GroupVersion]*client.Client),
|
||||
clientsets: make(map[unversioned.GroupVersion]*internalclientset.Clientset),
|
||||
configs: make(map[unversioned.GroupVersion]*restclient.Config),
|
||||
fedClientSets: make(map[unversioned.GroupVersion]fed_clientset.Interface),
|
||||
loader: loader,
|
||||
|
|
@ -38,53 +42,78 @@ func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
|
|||
// is invoked only once
|
||||
type ClientCache struct {
|
||||
loader clientcmd.ClientConfig
|
||||
clients map[unversioned.GroupVersion]*client.Client
|
||||
clientsets map[unversioned.GroupVersion]*internalclientset.Clientset
|
||||
fedClientSets map[unversioned.GroupVersion]fed_clientset.Interface
|
||||
configs map[unversioned.GroupVersion]*restclient.Config
|
||||
defaultConfig *restclient.Config
|
||||
defaultClient *client.Client
|
||||
matchVersion bool
|
||||
|
||||
matchVersion bool
|
||||
|
||||
defaultConfigLock sync.Mutex
|
||||
defaultConfig *restclient.Config
|
||||
discoveryClient discovery.DiscoveryInterface
|
||||
}
|
||||
|
||||
// also looks up the discovery client. We can't do this during init because the flags won't have been set
|
||||
// because this is constructed pre-command execution before the command tree is even set up
|
||||
func (c *ClientCache) getDefaultConfig() (restclient.Config, discovery.DiscoveryInterface, error) {
|
||||
c.defaultConfigLock.Lock()
|
||||
defer c.defaultConfigLock.Unlock()
|
||||
|
||||
if c.defaultConfig != nil && c.discoveryClient != nil {
|
||||
return *c.defaultConfig, c.discoveryClient, nil
|
||||
}
|
||||
|
||||
config, err := c.loader.ClientConfig()
|
||||
if err != nil {
|
||||
return restclient.Config{}, nil, err
|
||||
}
|
||||
discoveryClient, err := discovery.NewDiscoveryClientForConfig(config)
|
||||
if err != nil {
|
||||
return restclient.Config{}, nil, err
|
||||
}
|
||||
if c.matchVersion {
|
||||
if err := discovery.MatchesServerVersion(discoveryClient); err != nil {
|
||||
return restclient.Config{}, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
c.defaultConfig = config
|
||||
c.discoveryClient = discoveryClient
|
||||
return *c.defaultConfig, c.discoveryClient, nil
|
||||
}
|
||||
|
||||
// ClientConfigForVersion returns the correct config for a server
|
||||
func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion) (*restclient.Config, error) {
|
||||
if c.defaultConfig == nil {
|
||||
config, err := c.loader.ClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.defaultConfig = config
|
||||
if c.matchVersion {
|
||||
if err := client.MatchesServerVersion(c.defaultClient, config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
func (c *ClientCache) ClientConfigForVersion(requiredVersion *unversioned.GroupVersion) (*restclient.Config, error) {
|
||||
// TODO: have a better config copy method
|
||||
config, discoveryClient, err := c.getDefaultConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if version != nil {
|
||||
if config, ok := c.configs[*version]; ok {
|
||||
if requiredVersion == nil && config.GroupVersion != nil {
|
||||
// if someone has set the values via flags, our config will have the groupVersion set
|
||||
// that means it is required.
|
||||
requiredVersion = config.GroupVersion
|
||||
}
|
||||
|
||||
// required version may still be nil, since config.GroupVersion may have been nil. Do the check
|
||||
// before looking up from the cache
|
||||
if requiredVersion != nil {
|
||||
if config, ok := c.configs[*requiredVersion]; ok {
|
||||
return config, nil
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: have a better config copy method
|
||||
config := *c.defaultConfig
|
||||
|
||||
// TODO these fall out when we finish the refactor
|
||||
var preferredGV *unversioned.GroupVersion
|
||||
if version != nil {
|
||||
versionCopy := *version
|
||||
preferredGV = &versionCopy
|
||||
}
|
||||
|
||||
client.SetKubernetesDefaults(&config)
|
||||
negotiatedVersion, err := client.NegotiateVersion(c.defaultClient, &config, preferredGV, registered.EnabledVersions())
|
||||
negotiatedVersion, err := discovery.NegotiateVersion(discoveryClient, requiredVersion, registered.EnabledVersions())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.GroupVersion = negotiatedVersion
|
||||
|
||||
if version != nil {
|
||||
c.configs[*version] = &config
|
||||
// TODO this isn't what we want. Each clientset should be setting defaults as it sees fit.
|
||||
oldclient.SetKubernetesDefaults(&config)
|
||||
|
||||
if requiredVersion != nil {
|
||||
c.configs[*requiredVersion] = &config
|
||||
}
|
||||
|
||||
// `version` does not necessarily equal `config.Version`. However, we know that we call this method again with
|
||||
|
|
@ -95,38 +124,38 @@ func (c *ClientCache) ClientConfigForVersion(version *unversioned.GroupVersion)
|
|||
return &config, nil
|
||||
}
|
||||
|
||||
// ClientForVersion initializes or reuses a client for the specified version, or returns an
|
||||
// ClientSetForVersion initializes or reuses a clientset for the specified version, or returns an
|
||||
// error if that is not possible
|
||||
func (c *ClientCache) ClientForVersion(version *unversioned.GroupVersion) (*client.Client, error) {
|
||||
if version != nil {
|
||||
if client, ok := c.clients[*version]; ok {
|
||||
return client, nil
|
||||
func (c *ClientCache) ClientSetForVersion(requiredVersion *unversioned.GroupVersion) (*internalclientset.Clientset, error) {
|
||||
if requiredVersion != nil {
|
||||
if clientset, ok := c.clientsets[*requiredVersion]; ok {
|
||||
return clientset, nil
|
||||
}
|
||||
}
|
||||
config, err := c.ClientConfigForVersion(version)
|
||||
config, err := c.ClientConfigForVersion(requiredVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kubeclient, err := client.New(config)
|
||||
clientset, err := internalclientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.clients[*config.GroupVersion] = kubeclient
|
||||
c.clientsets[*config.GroupVersion] = clientset
|
||||
|
||||
// `version` does not necessarily equal `config.Version`. However, we know that if we call this method again with
|
||||
// `version`, we should get a client based on the same config we just found. There's no guarantee that a client
|
||||
// is copiable, so create a new client and save it in the cache.
|
||||
if version != nil {
|
||||
if requiredVersion != nil {
|
||||
configCopy := *config
|
||||
kubeclient, err := client.New(&configCopy)
|
||||
clientset, err := internalclientset.NewForConfig(&configCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.clients[*version] = kubeclient
|
||||
c.clientsets[*requiredVersion] = clientset
|
||||
}
|
||||
|
||||
return kubeclient, nil
|
||||
return clientset, nil
|
||||
}
|
||||
|
||||
func (c *ClientCache) FederationClientSetForVersion(version *unversioned.GroupVersion) (fed_clientset.Interface, error) {
|
||||
|
|
@ -164,5 +193,5 @@ func (c *ClientCache) FederationClientForVersion(version *unversioned.GroupVersi
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fedClientSet.(*fed_clientset.Clientset).FederationClient.RESTClient, nil
|
||||
return fedClientSet.Federation().RESTClient().(*restclient.RESTClient), nil
|
||||
}
|
||||
|
|
|
|||
1467
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
generated
vendored
1467
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
generated
vendored
File diff suppressed because it is too large
Load diff
250
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go
generated
vendored
250
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go
generated
vendored
|
|
@ -28,12 +28,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
kerrors "k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
|
|
@ -43,10 +43,9 @@ import (
|
|||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/util/strategicpatch"
|
||||
|
||||
"github.com/evanphx/json-patch"
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -60,7 +59,7 @@ type debugError interface {
|
|||
|
||||
// AddSourceToErr adds handleResourcePrefix and source string to error message.
|
||||
// verb is the string like "creating", "deleting" etc.
|
||||
// souce is the filename or URL to the template file(*.json or *.yaml), or stdin to use to handle the resource.
|
||||
// source is the filename or URL to the template file(*.json or *.yaml), or stdin to use to handle the resource.
|
||||
func AddSourceToErr(verb string, source string, err error) error {
|
||||
if source != "" {
|
||||
if statusError, ok := err.(kerrors.APIStatus); ok {
|
||||
|
|
@ -88,23 +87,26 @@ func DefaultBehaviorOnFatal() {
|
|||
fatalErrHandler = fatal
|
||||
}
|
||||
|
||||
// fatal prints the message if set and then exits. If V(2) or greater, glog.Fatal
|
||||
// is invoked for extended information.
|
||||
// fatal prints the message (if provided) and then exits. If V(2) or greater,
|
||||
// glog.Fatal is invoked for extended information.
|
||||
func fatal(msg string, code int) {
|
||||
if glog.V(2) {
|
||||
glog.FatalDepth(2, msg)
|
||||
}
|
||||
if len(msg) > 0 {
|
||||
// add newline if needed
|
||||
if !strings.HasSuffix(msg, "\n") {
|
||||
msg += "\n"
|
||||
}
|
||||
|
||||
if glog.V(2) {
|
||||
glog.FatalDepth(2, msg)
|
||||
}
|
||||
fmt.Fprint(os.Stderr, msg)
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// ErrExit may be passed to CheckError to instruct it to output nothing but exit with
|
||||
// status code 1.
|
||||
var ErrExit = fmt.Errorf("exit")
|
||||
|
||||
// CheckErr prints a user friendly error to STDERR and exits with a non-zero
|
||||
// exit code. Unrecognized errors will be printed with an "error: " prefix.
|
||||
//
|
||||
|
|
@ -122,9 +124,17 @@ func checkErrWithPrefix(prefix string, err error) {
|
|||
// checkErr formats a given error as a string and calls the passed handleErr
|
||||
// func with that string and an kubectl exit code.
|
||||
func checkErr(prefix string, err error, handleErr func(string, int)) {
|
||||
// unwrap aggregates of 1
|
||||
if agg, ok := err.(utilerrors.Aggregate); ok && len(agg.Errors()) == 1 {
|
||||
err = agg.Errors()[0]
|
||||
}
|
||||
|
||||
switch {
|
||||
case err == nil:
|
||||
return
|
||||
case err == ErrExit:
|
||||
handleErr("", DefaultErrorExitCode)
|
||||
return
|
||||
case kerrors.IsInvalid(err):
|
||||
details := err.(*kerrors.StatusError).Status().Details
|
||||
s := fmt.Sprintf("%sThe %s %q is invalid", prefix, details.Kind, details.Name)
|
||||
|
|
@ -196,8 +206,10 @@ func StandardErrorMessage(err error) (string, bool) {
|
|||
switch {
|
||||
case isStatus:
|
||||
switch s := status.Status(); {
|
||||
case s.Reason == "Unauthorized":
|
||||
case s.Reason == unversioned.StatusReasonUnauthorized:
|
||||
return fmt.Sprintf("error: You must be logged in to the server (%s)", s.Message), true
|
||||
case len(s.Reason) > 0:
|
||||
return fmt.Sprintf("Error from server (%s): %s", s.Reason, err.Error()), true
|
||||
default:
|
||||
return fmt.Sprintf("Error from server: %s", err.Error()), true
|
||||
}
|
||||
|
|
@ -242,6 +254,26 @@ func MultilineError(prefix string, err error) string {
|
|||
return fmt.Sprintf("%s%s\n", prefix, err)
|
||||
}
|
||||
|
||||
// PrintErrorWithCauses prints an error's kind, name, and each of the error's causes in a new line.
|
||||
// The returned string will end with a newline.
|
||||
// Returns true if a case exists to handle the error type, or false otherwise.
|
||||
func PrintErrorWithCauses(err error, errOut io.Writer) bool {
|
||||
switch t := err.(type) {
|
||||
case *kerrors.StatusError:
|
||||
errorDetails := t.Status().Details
|
||||
if errorDetails != nil {
|
||||
fmt.Fprintf(errOut, "error: %s %q is invalid\n\n", errorDetails.Kind, errorDetails.Name)
|
||||
for _, cause := range errorDetails.Causes {
|
||||
fmt.Fprintf(errOut, "* %s: %s\n", cause.Field, cause.Message)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(errOut, "error: %v\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// MultipleErrors returns a newline delimited string containing
|
||||
// the prefix and referenced errors in standard form.
|
||||
func MultipleErrors(prefix string, errs []error) string {
|
||||
|
|
@ -266,6 +298,13 @@ func UsageError(cmd *cobra.Command, format string, args ...interface{}) error {
|
|||
return fmt.Errorf("%s\nSee '%s -h' for help and examples.", msg, cmd.CommandPath())
|
||||
}
|
||||
|
||||
func IsFilenameEmpty(filenames []string) bool {
|
||||
if len(filenames) == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Whether this cmd need watching objects.
|
||||
func isWatch(cmd *cobra.Command) bool {
|
||||
if w, err := cmd.Flags().GetBool("watch"); w && err == nil {
|
||||
|
|
@ -279,25 +318,26 @@ func isWatch(cmd *cobra.Command) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func getFlag(cmd *cobra.Command, flag string) *pflag.Flag {
|
||||
f := cmd.Flags().Lookup(flag)
|
||||
if f == nil {
|
||||
glog.Fatalf("flag accessed but not defined for command %s: %s", cmd.Name(), flag)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func GetFlagString(cmd *cobra.Command, flag string) string {
|
||||
s, err := cmd.Flags().GetString(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// GetFlagStringList can be used to accept multiple argument with flag repetition (e.g. -f arg1 -f arg2 ...)
|
||||
// GetFlagStringSlice can be used to accept multiple argument with flag repetition (e.g. -f arg1,arg2 -f arg3 ...)
|
||||
func GetFlagStringSlice(cmd *cobra.Command, flag string) []string {
|
||||
s, err := cmd.Flags().GetStringSlice(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// GetFlagStringArray can be used to accept multiple argument with flag repetition (e.g. -f arg1 -f arg2 ...)
|
||||
func GetFlagStringArray(cmd *cobra.Command, flag string) []string {
|
||||
s, err := cmd.Flags().GetStringArray(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
|
|
@ -316,7 +356,7 @@ func GetWideFlag(cmd *cobra.Command) bool {
|
|||
func GetFlagBool(cmd *cobra.Command, flag string) bool {
|
||||
b, err := cmd.Flags().GetBool(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
|
@ -325,7 +365,7 @@ func GetFlagBool(cmd *cobra.Command, flag string) bool {
|
|||
func GetFlagInt(cmd *cobra.Command, flag string) int {
|
||||
i, err := cmd.Flags().GetInt(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
|
@ -334,7 +374,7 @@ func GetFlagInt(cmd *cobra.Command, flag string) int {
|
|||
func GetFlagInt64(cmd *cobra.Command, flag string) int64 {
|
||||
i, err := cmd.Flags().GetInt64(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
|
@ -342,7 +382,7 @@ func GetFlagInt64(cmd *cobra.Command, flag string) int64 {
|
|||
func GetFlagDuration(cmd *cobra.Command, flag string) time.Duration {
|
||||
d, err := cmd.Flags().GetDuration(flag)
|
||||
if err != nil {
|
||||
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
|
@ -353,8 +393,9 @@ func AddValidateFlags(cmd *cobra.Command) {
|
|||
cmd.MarkFlagFilename("schema-cache-dir")
|
||||
}
|
||||
|
||||
func AddRecursiveFlag(cmd *cobra.Command, value *bool) {
|
||||
cmd.Flags().BoolVarP(value, "recursive", "R", *value, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
|
||||
func AddFilenameOptionFlags(cmd *cobra.Command, options *resource.FilenameOptions, usage string) {
|
||||
kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, "Filename, directory, or URL to files "+usage)
|
||||
cmd.Flags().BoolVarP(&options.Recursive, "recursive", "R", options.Recursive, "Process the directory used in -f, --filename recursively. Useful when you want to manage related manifests organized within the same directory.")
|
||||
}
|
||||
|
||||
// AddDryRunFlag adds dry-run flag to a command. Usually used by mutations.
|
||||
|
|
@ -509,58 +550,9 @@ func ShouldRecord(cmd *cobra.Command, info *resource.Info) bool {
|
|||
return GetRecordFlag(cmd) || (ContainsChangeCause(info) && !cmd.Flags().Changed("record"))
|
||||
}
|
||||
|
||||
// GetThirdPartyGroupVersions returns the thirdparty "group/versions"s and
|
||||
// resources supported by the server. A user may delete a thirdparty resource
|
||||
// when this function is running, so this function may return a "NotFound" error
|
||||
// due to the race.
|
||||
func GetThirdPartyGroupVersions(discovery discovery.DiscoveryInterface) ([]unversioned.GroupVersion, []unversioned.GroupVersionKind, error) {
|
||||
result := []unversioned.GroupVersion{}
|
||||
gvks := []unversioned.GroupVersionKind{}
|
||||
|
||||
groupList, err := discovery.ServerGroups()
|
||||
if err != nil {
|
||||
// On forbidden or not found, just return empty lists.
|
||||
if kerrors.IsForbidden(err) || kerrors.IsNotFound(err) {
|
||||
return result, gvks, nil
|
||||
}
|
||||
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
for ix := range groupList.Groups {
|
||||
group := &groupList.Groups[ix]
|
||||
for jx := range group.Versions {
|
||||
gv, err2 := unversioned.ParseGroupVersion(group.Versions[jx].GroupVersion)
|
||||
if err2 != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
// Skip GroupVersionKinds that have been statically registered.
|
||||
if registered.IsRegisteredVersion(gv) {
|
||||
continue
|
||||
}
|
||||
result = append(result, gv)
|
||||
|
||||
resourceList, err := discovery.ServerResourcesForGroupVersion(group.Versions[jx].GroupVersion)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for kx := range resourceList.APIResources {
|
||||
gvks = append(gvks, gv.WithKind(resourceList.APIResources[kx].Kind))
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, gvks, nil
|
||||
}
|
||||
|
||||
func GetIncludeThirdPartyAPIs(cmd *cobra.Command) bool {
|
||||
if cmd.Flags().Lookup("include-extended-apis") == nil {
|
||||
return false
|
||||
}
|
||||
return GetFlagBool(cmd, "include-extended-apis")
|
||||
}
|
||||
|
||||
func AddInclude3rdPartyFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("include-extended-apis", true, "If true, include definitions of new APIs via calls to the API server. [default true]")
|
||||
cmd.Flags().MarkDeprecated("include-extended-apis", "No longer required.")
|
||||
}
|
||||
|
||||
// GetResourcesAndPairs retrieves resources and "KEY=VALUE or KEY-" pair args from given args
|
||||
|
|
@ -595,7 +587,7 @@ func ParsePairs(pairArgs []string, pairType string, supportRemove bool) (newPair
|
|||
for _, pairArg := range pairArgs {
|
||||
if strings.Index(pairArg, "=") != -1 {
|
||||
parts := strings.SplitN(pairArg, "=", 2)
|
||||
if len(parts) != 2 || len(parts[1]) == 0 {
|
||||
if len(parts) != 2 {
|
||||
if invalidBuf.Len() > 0 {
|
||||
invalidBuf.WriteString(", ")
|
||||
}
|
||||
|
|
@ -631,3 +623,105 @@ func MaybeConvertObject(obj runtime.Object, gv unversioned.GroupVersion, convert
|
|||
return converter.ConvertToVersion(obj, gv)
|
||||
}
|
||||
}
|
||||
|
||||
// MustPrintWithKinds determines if printer is dealing
|
||||
// with multiple resource kinds, in which case it will
|
||||
// return true, indicating resource kind will be
|
||||
// included as part of printer output
|
||||
func MustPrintWithKinds(objs []runtime.Object, infos []*resource.Info, sorter *kubectl.RuntimeSort, printAll bool) bool {
|
||||
var lastMap *meta.RESTMapping
|
||||
|
||||
if len(infos) == 1 && printAll {
|
||||
return true
|
||||
}
|
||||
|
||||
for ix := range objs {
|
||||
var mapping *meta.RESTMapping
|
||||
if sorter != nil {
|
||||
mapping = infos[sorter.OriginalPosition(ix)].Mapping
|
||||
} else {
|
||||
mapping = infos[ix].Mapping
|
||||
}
|
||||
|
||||
// display "kind" only if we have mixed resources
|
||||
if lastMap != nil && mapping.Resource != lastMap.Resource {
|
||||
return true
|
||||
}
|
||||
lastMap = mapping
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// FilterResourceList receives a list of runtime objects.
|
||||
// If any objects are filtered, that number is returned along with a modified list.
|
||||
func FilterResourceList(obj runtime.Object, filterFuncs kubectl.Filters, filterOpts *kubectl.PrintOptions) (int, []runtime.Object, error) {
|
||||
items, err := meta.ExtractList(obj)
|
||||
if err != nil {
|
||||
return 0, []runtime.Object{obj}, utilerrors.NewAggregate([]error{err})
|
||||
}
|
||||
if errs := runtime.DecodeList(items, api.Codecs.UniversalDecoder(), runtime.UnstructuredJSONScheme); len(errs) > 0 {
|
||||
return 0, []runtime.Object{obj}, utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
||||
filterCount := 0
|
||||
list := make([]runtime.Object, 0, len(items))
|
||||
for _, obj := range items {
|
||||
if isFiltered, err := filterFuncs.Filter(obj, filterOpts); !isFiltered {
|
||||
if err != nil {
|
||||
glog.V(2).Infof("Unable to filter resource: %v", err)
|
||||
continue
|
||||
}
|
||||
list = append(list, obj)
|
||||
} else if isFiltered {
|
||||
filterCount++
|
||||
}
|
||||
}
|
||||
return filterCount, list, nil
|
||||
}
|
||||
|
||||
func PrintFilterCount(hiddenObjNum int, resource string, options *kubectl.PrintOptions) {
|
||||
if !options.NoHeaders && !options.ShowAll && hiddenObjNum > 0 {
|
||||
glog.V(2).Infof(" info: %d completed object(s) was(were) not shown in %s list. Pass --show-all to see all objects.\n\n", hiddenObjNum, resource)
|
||||
}
|
||||
}
|
||||
|
||||
// ObjectListToVersionedObject receives a list of api objects and a group version
|
||||
// and squashes the list's items into a single versioned runtime.Object.
|
||||
func ObjectListToVersionedObject(objects []runtime.Object, version unversioned.GroupVersion) (runtime.Object, error) {
|
||||
objectList := &api.List{Items: objects}
|
||||
converted, err := resource.TryConvert(api.Scheme, objectList, version, registered.GroupOrDie(api.GroupName).GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return converted, nil
|
||||
}
|
||||
|
||||
// IsSiblingCommandExists receives a pointer to a cobra command and a target string.
|
||||
// Returns true if the target string is found in the list of sibling commands.
|
||||
func IsSiblingCommandExists(cmd *cobra.Command, targetCmdName string) bool {
|
||||
for _, c := range cmd.Parent().Commands() {
|
||||
if c.Name() == targetCmdName {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// DefaultSubCommandRun prints a command's help string to the specified output if no
|
||||
// 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)
|
||||
RequireNoArguments(c, args)
|
||||
c.Help()
|
||||
}
|
||||
}
|
||||
|
||||
// RequireNoArguments exits with a usage error if extra arguments are provided.
|
||||
func RequireNoArguments(c *cobra.Command, args []string) {
|
||||
if len(args) > 0 {
|
||||
CheckErr(UsageError(c, fmt.Sprintf(`unknown command %q`, strings.Join(args, " "))))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/printing.go
generated
vendored
|
|
@ -56,8 +56,12 @@ func AddNoHeadersFlags(cmd *cobra.Command) {
|
|||
}
|
||||
|
||||
// PrintSuccess prints message after finishing mutating operations
|
||||
func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource string, name string, operation string) {
|
||||
func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource string, name string, dryRun bool, operation string) {
|
||||
resource, _ = mapper.ResourceSingularizer(resource)
|
||||
dryRunMsg := ""
|
||||
if dryRun {
|
||||
dryRunMsg = " (dry run)"
|
||||
}
|
||||
if shortOutput {
|
||||
// -o name: prints resource/name
|
||||
if len(resource) > 0 {
|
||||
|
|
@ -68,9 +72,9 @@ func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resou
|
|||
} else {
|
||||
// understandable output by default
|
||||
if len(resource) > 0 {
|
||||
fmt.Fprintf(out, "%s \"%s\" %s\n", resource, name, operation)
|
||||
fmt.Fprintf(out, "%s \"%s\" %s%s\n", resource, name, operation, dryRunMsg)
|
||||
} else {
|
||||
fmt.Fprintf(out, "\"%s\" %s\n", name, operation)
|
||||
fmt.Fprintf(out, "\"%s\" %s%s\n", name, operation, dryRunMsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
147
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/shortcut_restmapper.go
generated
vendored
Normal file
147
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/shortcut_restmapper.go
generated
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
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 util
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/typed/discovery"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
)
|
||||
|
||||
// ShortcutExpander is a RESTMapper that can be used for Kubernetes resources. It expands the resource first, then invokes the wrapped
|
||||
type ShortcutExpander struct {
|
||||
RESTMapper meta.RESTMapper
|
||||
|
||||
All []unversioned.GroupResource
|
||||
|
||||
discoveryClient discovery.DiscoveryInterface
|
||||
}
|
||||
|
||||
var _ meta.RESTMapper = &ShortcutExpander{}
|
||||
|
||||
func NewShortcutExpander(delegate meta.RESTMapper, client discovery.DiscoveryInterface) ShortcutExpander {
|
||||
return ShortcutExpander{All: userResources, RESTMapper: delegate, discoveryClient: client}
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) getAll() []unversioned.GroupResource {
|
||||
if e.discoveryClient == nil {
|
||||
return e.All
|
||||
}
|
||||
|
||||
// Check if we have access to server resources
|
||||
apiResources, err := e.discoveryClient.ServerResources()
|
||||
if err != nil {
|
||||
return e.All
|
||||
}
|
||||
|
||||
availableResources := []unversioned.GroupVersionResource{}
|
||||
for groupVersionString, resourceList := range apiResources {
|
||||
currVersion, err := unversioned.ParseGroupVersion(groupVersionString)
|
||||
if err != nil {
|
||||
return e.All
|
||||
}
|
||||
|
||||
for _, resource := range resourceList.APIResources {
|
||||
availableResources = append(availableResources, currVersion.WithResource(resource.Name))
|
||||
}
|
||||
}
|
||||
|
||||
availableAll := []unversioned.GroupResource{}
|
||||
for _, requestedResource := range e.All {
|
||||
for _, availableResource := range availableResources {
|
||||
if requestedResource.Group == availableResource.Group &&
|
||||
requestedResource.Resource == availableResource.Resource {
|
||||
availableAll = append(availableAll, requestedResource)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return availableAll
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
return e.RESTMapper.KindFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
|
||||
return e.RESTMapper.KindsFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourcesFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
return e.RESTMapper.ResourcesFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
return e.RESTMapper.ResourceFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourceSingularizer(resource string) (string, error) {
|
||||
return e.RESTMapper.ResourceSingularizer(expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource)
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) RESTMapping(gk unversioned.GroupKind, versions ...string) (*meta.RESTMapping, error) {
|
||||
return e.RESTMapper.RESTMapping(gk, versions...)
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) {
|
||||
return e.RESTMapper.RESTMappings(gk)
|
||||
}
|
||||
|
||||
// userResources are the resource names that apply to the primary, user facing resources used by
|
||||
// client tools. They are in deletion-first order - dependent resources should be last.
|
||||
var userResources = []unversioned.GroupResource{
|
||||
{Group: "", Resource: "pods"},
|
||||
{Group: "", Resource: "replicationcontrollers"},
|
||||
{Group: "", Resource: "services"},
|
||||
{Group: "apps", Resource: "statefulsets"},
|
||||
{Group: "autoscaling", Resource: "horizontalpodautoscalers"},
|
||||
{Group: "extensions", Resource: "jobs"},
|
||||
{Group: "extensions", Resource: "deployments"},
|
||||
{Group: "extensions", Resource: "replicasets"},
|
||||
}
|
||||
|
||||
// AliasesForResource returns whether a resource has an alias or not
|
||||
func (e ShortcutExpander) AliasesForResource(resource string) ([]string, bool) {
|
||||
if strings.ToLower(resource) == "all" {
|
||||
var resources []unversioned.GroupResource
|
||||
if resources = e.getAll(); len(resources) == 0 {
|
||||
resources = userResources
|
||||
}
|
||||
aliases := []string{}
|
||||
for _, r := range resources {
|
||||
aliases = append(aliases, r.Resource)
|
||||
}
|
||||
return aliases, true
|
||||
}
|
||||
expanded := expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource
|
||||
return []string{expanded}, (expanded != resource)
|
||||
}
|
||||
|
||||
// expandResourceShortcut will return the expanded version of resource
|
||||
// (something that a pkg/api/meta.RESTMapper can understand), if it is
|
||||
// indeed a shortcut. Otherwise, will return resource unmodified.
|
||||
func expandResourceShortcut(resource unversioned.GroupVersionResource) unversioned.GroupVersionResource {
|
||||
if expanded, ok := kubectl.ShortForms[resource.Resource]; ok {
|
||||
resource.Resource = expanded
|
||||
return resource
|
||||
}
|
||||
return resource
|
||||
}
|
||||
13
vendor/k8s.io/kubernetes/pkg/kubectl/custom_column_printer.go
generated
vendored
13
vendor/k8s.io/kubernetes/pkg/kubectl/custom_column_printer.go
generated
vendored
|
|
@ -155,7 +155,7 @@ type CustomColumnsPrinter struct {
|
|||
NoHeaders bool
|
||||
}
|
||||
|
||||
func (s *CustomColumnsPrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (s *CustomColumnsPrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -206,9 +206,18 @@ func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jso
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ix := range parsers {
|
||||
parser := parsers[ix]
|
||||
values, err := parser.FindResults(reflect.ValueOf(obj).Elem().Interface())
|
||||
|
||||
var values [][]reflect.Value
|
||||
var err error
|
||||
if unstructured, ok := obj.(*runtime.Unstructured); ok {
|
||||
values, err = parser.FindResults(unstructured.Object)
|
||||
} else {
|
||||
values, err = parser.FindResults(reflect.ValueOf(obj).Elem().Interface())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
454
vendor/k8s.io/kubernetes/pkg/kubectl/describe.go
generated
vendored
454
vendor/k8s.io/kubernetes/pkg/kubectl/describe.go
generated
vendored
|
|
@ -32,6 +32,7 @@ import (
|
|||
fed_clientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_internalclientset"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/events"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
|
|
@ -39,16 +40,18 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/certificates"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
adapter "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset"
|
||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion"
|
||||
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
|
||||
"k8s.io/kubernetes/pkg/fieldpath"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
utilcertificates "k8s.io/kubernetes/pkg/util/certificates"
|
||||
certutil "k8s.io/kubernetes/pkg/util/cert"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
|
||||
|
|
@ -88,7 +91,7 @@ func (e ErrNoDescriber) Error() string {
|
|||
return fmt.Sprintf("no describer has been defined for %v", e.Types)
|
||||
}
|
||||
|
||||
func describerMap(c *client.Client) map[unversioned.GroupKind]Describer {
|
||||
func describerMap(c clientset.Interface) map[unversioned.GroupKind]Describer {
|
||||
m := map[unversioned.GroupKind]Describer{
|
||||
api.Kind("Pod"): &PodDescriber{c},
|
||||
api.Kind("ReplicationController"): &ReplicationControllerDescriber{c},
|
||||
|
|
@ -109,13 +112,14 @@ func describerMap(c *client.Client) map[unversioned.GroupKind]Describer {
|
|||
extensions.Kind("NetworkPolicy"): &NetworkPolicyDescriber{c},
|
||||
autoscaling.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
|
||||
extensions.Kind("DaemonSet"): &DaemonSetDescriber{c},
|
||||
extensions.Kind("Deployment"): &DeploymentDescriber{adapter.FromUnversionedClient(c)},
|
||||
extensions.Kind("Deployment"): &DeploymentDescriber{c},
|
||||
extensions.Kind("Job"): &JobDescriber{c},
|
||||
extensions.Kind("Ingress"): &IngressDescriber{c},
|
||||
batch.Kind("Job"): &JobDescriber{c},
|
||||
batch.Kind("ScheduledJob"): &ScheduledJobDescriber{adapter.FromUnversionedClient(c)},
|
||||
apps.Kind("PetSet"): &PetSetDescriber{c},
|
||||
batch.Kind("CronJob"): &CronJobDescriber{c},
|
||||
apps.Kind("StatefulSet"): &StatefulSetDescriber{c},
|
||||
certificates.Kind("CertificateSigningRequest"): &CertificateSigningRequestDescriber{c},
|
||||
storage.Kind("StorageClass"): &StorageClassDescriber{c},
|
||||
}
|
||||
|
||||
return m
|
||||
|
|
@ -134,7 +138,7 @@ func DescribableResources() []string {
|
|||
|
||||
// Describer returns the default describe functions for each of the standard
|
||||
// Kubernetes types.
|
||||
func DescriberFor(kind unversioned.GroupKind, c *client.Client) (Describer, bool) {
|
||||
func DescriberFor(kind unversioned.GroupKind, c clientset.Interface) (Describer, bool) {
|
||||
f, ok := describerMap(c)[kind]
|
||||
return f, ok
|
||||
}
|
||||
|
|
@ -162,15 +166,15 @@ func init() {
|
|||
|
||||
// NamespaceDescriber generates information about a namespace
|
||||
type NamespaceDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *NamespaceDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
ns, err := d.Namespaces().Get(name)
|
||||
ns, err := d.Core().Namespaces().Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resourceQuotaList, err := d.ResourceQuotas(name).List(api.ListOptions{})
|
||||
resourceQuotaList, err := d.Core().ResourceQuotas(name).List(api.ListOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
// Server does not support resource quotas.
|
||||
|
|
@ -180,7 +184,7 @@ func (d *NamespaceDescriber) Describe(namespace, name string, describerSettings
|
|||
return "", err
|
||||
}
|
||||
}
|
||||
limitRangeList, err := d.LimitRanges(name).List(api.ListOptions{})
|
||||
limitRangeList, err := d.Core().LimitRanges(name).List(api.ListOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
// Server does not support limit ranges.
|
||||
|
|
@ -210,6 +214,71 @@ func describeNamespace(namespace *api.Namespace, resourceQuotaList *api.Resource
|
|||
})
|
||||
}
|
||||
|
||||
func describeLimitRangeSpec(spec api.LimitRangeSpec, prefix string, w io.Writer) {
|
||||
for i := range spec.Limits {
|
||||
item := spec.Limits[i]
|
||||
maxResources := item.Max
|
||||
minResources := item.Min
|
||||
defaultLimitResources := item.Default
|
||||
defaultRequestResources := item.DefaultRequest
|
||||
ratio := item.MaxLimitRequestRatio
|
||||
|
||||
set := map[api.ResourceName]bool{}
|
||||
for k := range maxResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range minResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range defaultLimitResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range defaultRequestResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range ratio {
|
||||
set[k] = true
|
||||
}
|
||||
|
||||
for k := range set {
|
||||
// if no value is set, we output -
|
||||
maxValue := "-"
|
||||
minValue := "-"
|
||||
defaultLimitValue := "-"
|
||||
defaultRequestValue := "-"
|
||||
ratioValue := "-"
|
||||
|
||||
maxQuantity, maxQuantityFound := maxResources[k]
|
||||
if maxQuantityFound {
|
||||
maxValue = maxQuantity.String()
|
||||
}
|
||||
|
||||
minQuantity, minQuantityFound := minResources[k]
|
||||
if minQuantityFound {
|
||||
minValue = minQuantity.String()
|
||||
}
|
||||
|
||||
defaultLimitQuantity, defaultLimitQuantityFound := defaultLimitResources[k]
|
||||
if defaultLimitQuantityFound {
|
||||
defaultLimitValue = defaultLimitQuantity.String()
|
||||
}
|
||||
|
||||
defaultRequestQuantity, defaultRequestQuantityFound := defaultRequestResources[k]
|
||||
if defaultRequestQuantityFound {
|
||||
defaultRequestValue = defaultRequestQuantity.String()
|
||||
}
|
||||
|
||||
ratioQuantity, ratioQuantityFound := ratio[k]
|
||||
if ratioQuantityFound {
|
||||
ratioValue = ratioQuantity.String()
|
||||
}
|
||||
|
||||
msg := "%s%s\t%v\t%v\t%v\t%v\t%v\t%v\n"
|
||||
fmt.Fprintf(w, msg, prefix, item.Type, k, minValue, maxValue, defaultRequestValue, defaultLimitValue, ratioValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DescribeLimitRanges merges a set of limit range items into a single tabular description
|
||||
func DescribeLimitRanges(limitRanges *api.LimitRangeList, w io.Writer) {
|
||||
if len(limitRanges.Items) == 0 {
|
||||
|
|
@ -219,68 +288,7 @@ func DescribeLimitRanges(limitRanges *api.LimitRangeList, w io.Writer) {
|
|||
fmt.Fprintf(w, "Resource Limits\n Type\tResource\tMin\tMax\tDefault Request\tDefault Limit\tMax Limit/Request Ratio\n")
|
||||
fmt.Fprintf(w, " ----\t--------\t---\t---\t---------------\t-------------\t-----------------------\n")
|
||||
for _, limitRange := range limitRanges.Items {
|
||||
for i := range limitRange.Spec.Limits {
|
||||
item := limitRange.Spec.Limits[i]
|
||||
maxResources := item.Max
|
||||
minResources := item.Min
|
||||
defaultLimitResources := item.Default
|
||||
defaultRequestResources := item.DefaultRequest
|
||||
ratio := item.MaxLimitRequestRatio
|
||||
|
||||
set := map[api.ResourceName]bool{}
|
||||
for k := range maxResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range minResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range defaultLimitResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range defaultRequestResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range ratio {
|
||||
set[k] = true
|
||||
}
|
||||
|
||||
for k := range set {
|
||||
// if no value is set, we output -
|
||||
maxValue := "-"
|
||||
minValue := "-"
|
||||
defaultLimitValue := "-"
|
||||
defaultRequestValue := "-"
|
||||
ratioValue := "-"
|
||||
|
||||
maxQuantity, maxQuantityFound := maxResources[k]
|
||||
if maxQuantityFound {
|
||||
maxValue = maxQuantity.String()
|
||||
}
|
||||
|
||||
minQuantity, minQuantityFound := minResources[k]
|
||||
if minQuantityFound {
|
||||
minValue = minQuantity.String()
|
||||
}
|
||||
|
||||
defaultLimitQuantity, defaultLimitQuantityFound := defaultLimitResources[k]
|
||||
if defaultLimitQuantityFound {
|
||||
defaultLimitValue = defaultLimitQuantity.String()
|
||||
}
|
||||
|
||||
defaultRequestQuantity, defaultRequestQuantityFound := defaultRequestResources[k]
|
||||
if defaultRequestQuantityFound {
|
||||
defaultRequestValue = defaultRequestQuantity.String()
|
||||
}
|
||||
|
||||
ratioQuantity, ratioQuantityFound := ratio[k]
|
||||
if ratioQuantityFound {
|
||||
ratioValue = ratioQuantity.String()
|
||||
}
|
||||
|
||||
msg := " %s\t%v\t%v\t%v\t%v\t%v\t%v\n"
|
||||
fmt.Fprintf(w, msg, item.Type, k, minValue, maxValue, defaultRequestValue, defaultLimitValue, ratioValue)
|
||||
}
|
||||
}
|
||||
describeLimitRangeSpec(limitRange.Spec, " ", w)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,11 +337,11 @@ func DescribeResourceQuotas(quotas *api.ResourceQuotaList, w io.Writer) {
|
|||
|
||||
// LimitRangeDescriber generates information about a limit range
|
||||
type LimitRangeDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *LimitRangeDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
lr := d.LimitRanges(namespace)
|
||||
lr := d.Core().LimitRanges(namespace)
|
||||
|
||||
limitRange, err := lr.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -348,79 +356,18 @@ func describeLimitRange(limitRange *api.LimitRange) (string, error) {
|
|||
fmt.Fprintf(out, "Namespace:\t%s\n", limitRange.Namespace)
|
||||
fmt.Fprintf(out, "Type\tResource\tMin\tMax\tDefault Request\tDefault Limit\tMax Limit/Request Ratio\n")
|
||||
fmt.Fprintf(out, "----\t--------\t---\t---\t---------------\t-------------\t-----------------------\n")
|
||||
for i := range limitRange.Spec.Limits {
|
||||
item := limitRange.Spec.Limits[i]
|
||||
maxResources := item.Max
|
||||
minResources := item.Min
|
||||
defaultLimitResources := item.Default
|
||||
defaultRequestResources := item.DefaultRequest
|
||||
ratio := item.MaxLimitRequestRatio
|
||||
|
||||
set := map[api.ResourceName]bool{}
|
||||
for k := range maxResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range minResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range defaultLimitResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range defaultRequestResources {
|
||||
set[k] = true
|
||||
}
|
||||
for k := range ratio {
|
||||
set[k] = true
|
||||
}
|
||||
|
||||
for k := range set {
|
||||
// if no value is set, we output -
|
||||
maxValue := "-"
|
||||
minValue := "-"
|
||||
defaultLimitValue := "-"
|
||||
defaultRequestValue := "-"
|
||||
ratioValue := "-"
|
||||
|
||||
maxQuantity, maxQuantityFound := maxResources[k]
|
||||
if maxQuantityFound {
|
||||
maxValue = maxQuantity.String()
|
||||
}
|
||||
|
||||
minQuantity, minQuantityFound := minResources[k]
|
||||
if minQuantityFound {
|
||||
minValue = minQuantity.String()
|
||||
}
|
||||
|
||||
defaultLimitQuantity, defaultLimitQuantityFound := defaultLimitResources[k]
|
||||
if defaultLimitQuantityFound {
|
||||
defaultLimitValue = defaultLimitQuantity.String()
|
||||
}
|
||||
|
||||
defaultRequestQuantity, defaultRequestQuantityFound := defaultRequestResources[k]
|
||||
if defaultRequestQuantityFound {
|
||||
defaultRequestValue = defaultRequestQuantity.String()
|
||||
}
|
||||
|
||||
ratioQuantity, ratioQuantityFound := ratio[k]
|
||||
if ratioQuantityFound {
|
||||
ratioValue = ratioQuantity.String()
|
||||
}
|
||||
|
||||
msg := "%v\t%v\t%v\t%v\t%v\t%v\t%v\n"
|
||||
fmt.Fprintf(out, msg, item.Type, k, minValue, maxValue, defaultRequestValue, defaultLimitValue, ratioValue)
|
||||
}
|
||||
}
|
||||
describeLimitRangeSpec(limitRange.Spec, "", out)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// ResourceQuotaDescriber generates information about a resource quota
|
||||
type ResourceQuotaDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ResourceQuotaDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
rq := d.ResourceQuotas(namespace)
|
||||
rq := d.Core().ResourceQuotas(namespace)
|
||||
|
||||
resourceQuota, err := rq.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -485,14 +432,14 @@ func describeQuota(resourceQuota *api.ResourceQuota) (string, error) {
|
|||
// PodDescriber generates information about a pod and the replication controllers that
|
||||
// create it.
|
||||
type PodDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *PodDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
pod, err := d.Pods(namespace).Get(name)
|
||||
pod, err := d.Core().Pods(namespace).Get(name)
|
||||
if err != nil {
|
||||
if describerSettings.ShowEvents {
|
||||
eventsInterface := d.Events(namespace)
|
||||
eventsInterface := d.Core().Events(namespace)
|
||||
selector := eventsInterface.GetFieldSelector(&name, &namespace, nil, nil)
|
||||
options := api.ListOptions{FieldSelector: selector}
|
||||
events, err2 := eventsInterface.List(options)
|
||||
|
|
@ -513,7 +460,7 @@ func (d *PodDescriber) Describe(namespace, name string, describerSettings Descri
|
|||
glog.Errorf("Unable to construct reference to '%#v': %v", pod, err)
|
||||
} else {
|
||||
ref.Kind = ""
|
||||
events, _ = d.Events(namespace).Search(ref)
|
||||
events, _ = d.Core().Events(namespace).Search(ref)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -621,6 +568,12 @@ func describeVolumes(volumes []api.Volume, out io.Writer, space string) {
|
|||
printDownwardAPIVolumeSource(volume.VolumeSource.DownwardAPI, out)
|
||||
case volume.VolumeSource.AzureDisk != nil:
|
||||
printAzureDiskVolumeSource(volume.VolumeSource.AzureDisk, out)
|
||||
case volume.VolumeSource.VsphereVolume != nil:
|
||||
printVsphereVolumeSource(volume.VolumeSource.VsphereVolume, out)
|
||||
case volume.VolumeSource.Cinder != nil:
|
||||
printCinderVolumeSource(volume.VolumeSource.Cinder, out)
|
||||
case volume.VolumeSource.PhotonPersistentDisk != nil:
|
||||
printPhotonPersistentDiskVolumeSource(volume.VolumeSource.PhotonPersistentDisk, out)
|
||||
default:
|
||||
fmt.Fprintf(out, " <unknown>\n")
|
||||
}
|
||||
|
|
@ -749,12 +702,34 @@ func printAzureDiskVolumeSource(d *api.AzureDiskVolumeSource, out io.Writer) {
|
|||
d.DiskName, d.DataDiskURI, *d.FSType, *d.CachingMode, *d.ReadOnly)
|
||||
}
|
||||
|
||||
func printVsphereVolumeSource(vsphere *api.VsphereVirtualDiskVolumeSource, out io.Writer) {
|
||||
fmt.Fprintf(out, " Type:\tvSphereVolume (a Persistent Disk resource in vSphere)\n"+
|
||||
" VolumePath:\t%v\n"+
|
||||
" FSType:\t%v\n",
|
||||
vsphere.VolumePath, vsphere.FSType)
|
||||
}
|
||||
|
||||
func printPhotonPersistentDiskVolumeSource(photon *api.PhotonPersistentDiskVolumeSource, out io.Writer) {
|
||||
fmt.Fprintf(out, " Type:\tPhotonPersistentDisk (a Persistent Disk resource in photon platform)\n"+
|
||||
" PdID:\t%v\n"+
|
||||
" FSType:\t%v\n",
|
||||
photon.PdID, photon.FSType)
|
||||
}
|
||||
|
||||
func printCinderVolumeSource(cinder *api.CinderVolumeSource, out io.Writer) {
|
||||
fmt.Fprintf(out, " Type:\tCinder (a Persistent Disk resource in OpenStack)\n"+
|
||||
" VolumeID:\t%v\n"+
|
||||
" FSType:\t%v\n"+
|
||||
" ReadOnly:\t%v\n",
|
||||
cinder.VolumeID, cinder.FSType, cinder.ReadOnly)
|
||||
}
|
||||
|
||||
type PersistentVolumeDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.PersistentVolumes()
|
||||
c := d.Core().PersistentVolumes()
|
||||
|
||||
pv, err := c.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -765,12 +740,13 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
|
|||
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.Events(namespace).Search(pv)
|
||||
events, _ = d.Core().Events(namespace).Search(pv)
|
||||
}
|
||||
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", pv.Name)
|
||||
printLabelsMultiline(out, "Labels", pv.Labels)
|
||||
fmt.Fprintf(out, "StorageClass:\t%s\n", storageutil.GetStorageClassAnnotation(pv.ObjectMeta))
|
||||
fmt.Fprintf(out, "Status:\t%s\n", pv.Status.Phase)
|
||||
if pv.Spec.ClaimRef != nil {
|
||||
fmt.Fprintf(out, "Claim:\t%s\n", pv.Spec.ClaimRef.Namespace+"/"+pv.Spec.ClaimRef.Name)
|
||||
|
|
@ -800,6 +776,14 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
|
|||
printRBDVolumeSource(pv.Spec.RBD, out)
|
||||
case pv.Spec.Quobyte != nil:
|
||||
printQuobyteVolumeSource(pv.Spec.Quobyte, out)
|
||||
case pv.Spec.VsphereVolume != nil:
|
||||
printVsphereVolumeSource(pv.Spec.VsphereVolume, out)
|
||||
case pv.Spec.Cinder != nil:
|
||||
printCinderVolumeSource(pv.Spec.Cinder, out)
|
||||
case pv.Spec.AzureDisk != nil:
|
||||
printAzureDiskVolumeSource(pv.Spec.AzureDisk, out)
|
||||
case pv.Spec.PhotonPersistentDisk != nil:
|
||||
printPhotonPersistentDiskVolumeSource(pv.Spec.PhotonPersistentDisk, out)
|
||||
}
|
||||
|
||||
if events != nil {
|
||||
|
|
@ -811,11 +795,11 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
|
|||
}
|
||||
|
||||
type PersistentVolumeClaimDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.PersistentVolumeClaims(namespace)
|
||||
c := d.Core().PersistentVolumeClaims(namespace)
|
||||
|
||||
pvc, err := c.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -831,11 +815,12 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
|
|||
capacity = storage.String()
|
||||
}
|
||||
|
||||
events, _ := d.Events(namespace).Search(pvc)
|
||||
events, _ := d.Core().Events(namespace).Search(pvc)
|
||||
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", pvc.Name)
|
||||
fmt.Fprintf(out, "Namespace:\t%s\n", pvc.Namespace)
|
||||
fmt.Fprintf(out, "StorageClass:\t%s\n", storageutil.GetStorageClassAnnotation(pvc.ObjectMeta))
|
||||
fmt.Fprintf(out, "Status:\t%v\n", pvc.Status.Phase)
|
||||
fmt.Fprintf(out, "Volume:\t%s\n", pvc.Spec.VolumeName)
|
||||
printLabelsMultiline(out, "Labels", pvc.Labels)
|
||||
|
|
@ -1083,12 +1068,12 @@ func printBool(value bool) string {
|
|||
// ReplicationControllerDescriber generates information about a replication controller
|
||||
// and the pods it has created.
|
||||
type ReplicationControllerDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ReplicationControllerDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
rc := d.ReplicationControllers(namespace)
|
||||
pc := d.Pods(namespace)
|
||||
rc := d.Core().ReplicationControllers(namespace)
|
||||
pc := d.Core().Pods(namespace)
|
||||
|
||||
controller, err := rc.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -1102,7 +1087,7 @@ func (d *ReplicationControllerDescriber) Describe(namespace, name string, descri
|
|||
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.Events(namespace).Search(controller)
|
||||
events, _ = d.Core().Events(namespace).Search(controller)
|
||||
}
|
||||
|
||||
return describeReplicationController(controller, events, running, waiting, succeeded, failed)
|
||||
|
|
@ -1152,12 +1137,12 @@ func DescribePodTemplate(template *api.PodTemplateSpec, out io.Writer) {
|
|||
|
||||
// ReplicaSetDescriber generates information about a ReplicaSet and the pods it has created.
|
||||
type ReplicaSetDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ReplicaSetDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
rsc := d.Extensions().ReplicaSets(namespace)
|
||||
pc := d.Pods(namespace)
|
||||
pc := d.Core().Pods(namespace)
|
||||
|
||||
rs, err := rsc.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -1169,20 +1154,17 @@ func (d *ReplicaSetDescriber) Describe(namespace, name string, describerSettings
|
|||
return "", err
|
||||
}
|
||||
|
||||
running, waiting, succeeded, failed, err := getPodStatusForController(pc, selector)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
running, waiting, succeeded, failed, getPodErr := getPodStatusForController(pc, selector)
|
||||
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.Events(namespace).Search(rs)
|
||||
events, _ = d.Core().Events(namespace).Search(rs)
|
||||
}
|
||||
|
||||
return describeReplicaSet(rs, events, running, waiting, succeeded, failed)
|
||||
return describeReplicaSet(rs, events, running, waiting, succeeded, failed, getPodErr)
|
||||
}
|
||||
|
||||
func describeReplicaSet(rs *extensions.ReplicaSet, events *api.EventList, running, waiting, succeeded, failed int) (string, error) {
|
||||
func describeReplicaSet(rs *extensions.ReplicaSet, events *api.EventList, running, waiting, succeeded, failed int, getPodErr error) (string, error) {
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", rs.Name)
|
||||
fmt.Fprintf(out, "Namespace:\t%s\n", rs.Namespace)
|
||||
|
|
@ -1190,7 +1172,12 @@ func describeReplicaSet(rs *extensions.ReplicaSet, events *api.EventList, runnin
|
|||
fmt.Fprintf(out, "Selector:\t%s\n", unversioned.FormatLabelSelector(rs.Spec.Selector))
|
||||
printLabelsMultiline(out, "Labels", rs.Labels)
|
||||
fmt.Fprintf(out, "Replicas:\t%d current / %d desired\n", rs.Status.Replicas, rs.Spec.Replicas)
|
||||
fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed)
|
||||
fmt.Fprintf(out, "Pods Status:\t")
|
||||
if getPodErr != nil {
|
||||
fmt.Fprintf(out, "error in fetching pods: %s\n", getPodErr)
|
||||
} else {
|
||||
fmt.Fprintf(out, "%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed)
|
||||
}
|
||||
describeVolumes(rs.Spec.Template.Spec.Volumes, out, "")
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
|
|
@ -1201,7 +1188,7 @@ func describeReplicaSet(rs *extensions.ReplicaSet, events *api.EventList, runnin
|
|||
|
||||
// JobDescriber generates information about a job and the pods it has created.
|
||||
type JobDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *JobDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
|
|
@ -1212,7 +1199,7 @@ func (d *JobDescriber) Describe(namespace, name string, describerSettings Descri
|
|||
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.Events(namespace).Search(job)
|
||||
events, _ = d.Core().Events(namespace).Search(job)
|
||||
}
|
||||
|
||||
return describeJob(job, events)
|
||||
|
|
@ -1247,13 +1234,13 @@ func describeJob(job *batch.Job, events *api.EventList) (string, error) {
|
|||
})
|
||||
}
|
||||
|
||||
// ScheduledJobDescriber generates information about a scheduled job and the jobs it has created.
|
||||
type ScheduledJobDescriber struct {
|
||||
// CronJobDescriber generates information about a scheduled job and the jobs it has created.
|
||||
type CronJobDescriber struct {
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ScheduledJobDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
scheduledJob, err := d.Batch().ScheduledJobs(namespace).Get(name)
|
||||
func (d *CronJobDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
scheduledJob, err := d.Batch().CronJobs(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -1263,10 +1250,10 @@ func (d *ScheduledJobDescriber) Describe(namespace, name string, describerSettin
|
|||
events, _ = d.Core().Events(namespace).Search(scheduledJob)
|
||||
}
|
||||
|
||||
return describeScheduledJob(scheduledJob, events)
|
||||
return describeCronJob(scheduledJob, events)
|
||||
}
|
||||
|
||||
func describeScheduledJob(scheduledJob *batch.ScheduledJob, events *api.EventList) (string, error) {
|
||||
func describeCronJob(scheduledJob *batch.CronJob, events *api.EventList) (string, error) {
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", scheduledJob.Name)
|
||||
fmt.Fprintf(out, "Namespace:\t%s\n", scheduledJob.Namespace)
|
||||
|
|
@ -1335,12 +1322,12 @@ func printActiveJobs(out io.Writer, title string, jobs []api.ObjectReference) {
|
|||
|
||||
// DaemonSetDescriber generates information about a daemon set and the pods it has created.
|
||||
type DaemonSetDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *DaemonSetDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
dc := d.Extensions().DaemonSets(namespace)
|
||||
pc := d.Pods(namespace)
|
||||
pc := d.Core().Pods(namespace)
|
||||
|
||||
daemon, err := dc.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -1358,7 +1345,7 @@ func (d *DaemonSetDescriber) Describe(namespace, name string, describerSettings
|
|||
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.Events(namespace).Search(daemon)
|
||||
events, _ = d.Core().Events(namespace).Search(daemon)
|
||||
}
|
||||
|
||||
return describeDaemonSet(daemon, events, running, waiting, succeeded, failed)
|
||||
|
|
@ -1389,11 +1376,11 @@ func describeDaemonSet(daemon *extensions.DaemonSet, events *api.EventList, runn
|
|||
|
||||
// SecretDescriber generates information about a secret
|
||||
type SecretDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *SecretDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.Secrets(namespace)
|
||||
c := d.Core().Secrets(namespace)
|
||||
|
||||
secret, err := c.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -1427,11 +1414,11 @@ func describeSecret(secret *api.Secret) (string, error) {
|
|||
}
|
||||
|
||||
type IngressDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (i *IngressDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := i.Extensions().Ingress(namespace)
|
||||
c := i.Extensions().Ingresses(namespace)
|
||||
ing, err := c.Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -1440,8 +1427,8 @@ func (i *IngressDescriber) Describe(namespace, name string, describerSettings De
|
|||
}
|
||||
|
||||
func (i *IngressDescriber) describeBackend(ns string, backend *extensions.IngressBackend) string {
|
||||
endpoints, _ := i.Endpoints(ns).Get(backend.ServiceName)
|
||||
service, _ := i.Services(ns).Get(backend.ServiceName)
|
||||
endpoints, _ := i.Core().Endpoints(ns).Get(backend.ServiceName)
|
||||
service, _ := i.Core().Services(ns).Get(backend.ServiceName)
|
||||
spName := ""
|
||||
for i := range service.Spec.Ports {
|
||||
sp := &service.Spec.Ports[i]
|
||||
|
|
@ -1502,7 +1489,7 @@ func (i *IngressDescriber) describeIngress(ing *extensions.Ingress, describerSet
|
|||
describeIngressAnnotations(out, ing.Annotations)
|
||||
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ := i.Events(ing.Namespace).Search(ing)
|
||||
events, _ := i.Core().Events(ing.Namespace).Search(ing)
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
|
|
@ -1539,21 +1526,21 @@ func describeIngressAnnotations(out io.Writer, annotations map[string]string) {
|
|||
|
||||
// ServiceDescriber generates information about a service.
|
||||
type ServiceDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ServiceDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.Services(namespace)
|
||||
c := d.Core().Services(namespace)
|
||||
|
||||
service, err := c.Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
endpoints, _ := d.Endpoints(namespace).Get(name)
|
||||
endpoints, _ := d.Core().Endpoints(namespace).Get(name)
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.Events(namespace).Search(service)
|
||||
events, _ = d.Core().Events(namespace).Search(service)
|
||||
}
|
||||
return describeService(service, endpoints, events)
|
||||
}
|
||||
|
|
@ -1618,11 +1605,11 @@ func describeService(service *api.Service, endpoints *api.Endpoints, events *api
|
|||
|
||||
// EndpointsDescriber generates information about an Endpoint.
|
||||
type EndpointsDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *EndpointsDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.Endpoints(namespace)
|
||||
c := d.Core().Endpoints(namespace)
|
||||
|
||||
ep, err := c.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -1631,7 +1618,7 @@ func (d *EndpointsDescriber) Describe(namespace, name string, describerSettings
|
|||
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.Events(namespace).Search(ep)
|
||||
events, _ = d.Core().Events(namespace).Search(ep)
|
||||
}
|
||||
|
||||
return describeEndpoints(ep, events)
|
||||
|
|
@ -1691,11 +1678,11 @@ func describeEndpoints(ep *api.Endpoints, events *api.EventList) (string, error)
|
|||
|
||||
// ServiceAccountDescriber generates information about a service.
|
||||
type ServiceAccountDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ServiceAccountDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.ServiceAccounts(namespace)
|
||||
c := d.Core().ServiceAccounts(namespace)
|
||||
|
||||
serviceAccount, err := c.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -1706,7 +1693,7 @@ func (d *ServiceAccountDescriber) Describe(namespace, name string, describerSett
|
|||
|
||||
tokenSelector := fields.SelectorFromSet(map[string]string{api.SecretTypeField: string(api.SecretTypeServiceAccountToken)})
|
||||
options := api.ListOptions{FieldSelector: tokenSelector}
|
||||
secrets, err := d.Secrets(namespace).List(options)
|
||||
secrets, err := d.Core().Secrets(namespace).List(options)
|
||||
if err == nil {
|
||||
for _, s := range secrets.Items {
|
||||
name, _ := s.Annotations[api.ServiceAccountNameKey]
|
||||
|
|
@ -1772,11 +1759,11 @@ func describeServiceAccount(serviceAccount *api.ServiceAccount, tokens []api.Sec
|
|||
|
||||
// NodeDescriber generates information about a node.
|
||||
type NodeDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *NodeDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
mc := d.Nodes()
|
||||
mc := d.Core().Nodes()
|
||||
node, err := mc.Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -1789,7 +1776,7 @@ func (d *NodeDescriber) Describe(namespace, name string, describerSettings Descr
|
|||
// in a policy aware setting, users may have access to a node, but not all pods
|
||||
// in that case, we note that the user does not have access to the pods
|
||||
canViewPods := true
|
||||
nodeNonTerminatedPodsList, err := d.Pods(namespace).List(api.ListOptions{FieldSelector: fieldSelector})
|
||||
nodeNonTerminatedPodsList, err := d.Core().Pods(namespace).List(api.ListOptions{FieldSelector: fieldSelector})
|
||||
if err != nil {
|
||||
if !errors.IsForbidden(err) {
|
||||
return "", err
|
||||
|
|
@ -1804,7 +1791,7 @@ func (d *NodeDescriber) Describe(namespace, name string, describerSettings Descr
|
|||
} else {
|
||||
// TODO: We haven't decided the namespace for Node object yet.
|
||||
ref.UID = types.UID(ref.Name)
|
||||
events, _ = d.Events("").Search(ref)
|
||||
events, _ = d.Core().Events("").Search(ref)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1890,16 +1877,16 @@ func describeNode(node *api.Node, nodeNonTerminatedPodsList *api.PodList, events
|
|||
})
|
||||
}
|
||||
|
||||
type PetSetDescriber struct {
|
||||
client *client.Client
|
||||
type StatefulSetDescriber struct {
|
||||
client clientset.Interface
|
||||
}
|
||||
|
||||
func (p *PetSetDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
ps, err := p.client.Apps().PetSets(namespace).Get(name)
|
||||
func (p *StatefulSetDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
ps, err := p.client.Apps().StatefulSets(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
pc := p.client.Pods(namespace)
|
||||
pc := p.client.Core().Pods(namespace)
|
||||
|
||||
selector, err := unversioned.LabelSelectorAsSelector(ps.Spec.Selector)
|
||||
if err != nil {
|
||||
|
|
@ -1923,7 +1910,7 @@ func (p *PetSetDescriber) Describe(namespace, name string, describerSettings Des
|
|||
fmt.Fprintf(out, "Pods Status:\t%d Running / %d Waiting / %d Succeeded / %d Failed\n", running, waiting, succeeded, failed)
|
||||
describeVolumes(ps.Spec.Template.Spec.Volumes, out, "")
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ := p.client.Events(namespace).Search(ps)
|
||||
events, _ := p.client.Core().Events(namespace).Search(ps)
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
|
|
@ -1933,7 +1920,7 @@ func (p *PetSetDescriber) Describe(namespace, name string, describerSettings Des
|
|||
}
|
||||
|
||||
type CertificateSigningRequestDescriber struct {
|
||||
client *client.Client
|
||||
client clientset.Interface
|
||||
}
|
||||
|
||||
func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
|
|
@ -1942,7 +1929,7 @@ func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, de
|
|||
return "", err
|
||||
}
|
||||
|
||||
cr, err := utilcertificates.ParseCertificateRequestObject(csr)
|
||||
cr, err := certutil.ParseCSR(csr)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error parsing CSR: %v", err)
|
||||
}
|
||||
|
|
@ -1991,7 +1978,7 @@ func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, de
|
|||
}
|
||||
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ := p.client.Events(namespace).Search(csr)
|
||||
events, _ := p.client.Core().Events(namespace).Search(csr)
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
|
|
@ -2002,7 +1989,7 @@ func (p *CertificateSigningRequestDescriber) Describe(namespace, name string, de
|
|||
|
||||
// HorizontalPodAutoscalerDescriber generates information about a horizontal pod autoscaler.
|
||||
type HorizontalPodAutoscalerDescriber struct {
|
||||
client *client.Client
|
||||
client clientset.Interface
|
||||
}
|
||||
|
||||
func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
|
|
@ -2038,7 +2025,7 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, desc
|
|||
// TODO: switch to scale subresource once the required code is submitted.
|
||||
if strings.ToLower(hpa.Spec.ScaleTargetRef.Kind) == "replicationcontroller" {
|
||||
fmt.Fprintf(out, "ReplicationController pods:\t")
|
||||
rc, err := d.client.ReplicationControllers(hpa.Namespace).Get(hpa.Spec.ScaleTargetRef.Name)
|
||||
rc, err := d.client.Core().ReplicationControllers(hpa.Namespace).Get(hpa.Spec.ScaleTargetRef.Name)
|
||||
if err == nil {
|
||||
fmt.Fprintf(out, "%d current / %d desired\n", rc.Status.Replicas, rc.Spec.Replicas)
|
||||
} else {
|
||||
|
|
@ -2047,7 +2034,7 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, desc
|
|||
}
|
||||
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ := d.client.Events(namespace).Search(hpa)
|
||||
events, _ := d.client.Core().Events(namespace).Search(hpa)
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
|
|
@ -2140,11 +2127,11 @@ func getPodsTotalRequestsAndLimits(podList *api.PodList) (reqs map[api.ResourceN
|
|||
|
||||
func DescribeEvents(el *api.EventList, w io.Writer) {
|
||||
if len(el.Items) == 0 {
|
||||
fmt.Fprint(w, "No events.")
|
||||
fmt.Fprint(w, "No events.\n")
|
||||
return
|
||||
}
|
||||
sort.Sort(SortableEvents(el.Items))
|
||||
fmt.Fprint(w, "Events:\n FirstSeen\tLastSeen\tCount\tFrom\tSubobjectPath\tType\tReason\tMessage\n")
|
||||
sort.Sort(events.SortableEvents(el.Items))
|
||||
fmt.Fprint(w, "Events:\n FirstSeen\tLastSeen\tCount\tFrom\tSubObjectPath\tType\tReason\tMessage\n")
|
||||
fmt.Fprint(w, " ---------\t--------\t-----\t----\t-------------\t--------\t------\t-------\n")
|
||||
for _, e := range el.Items {
|
||||
fmt.Fprintf(w, " %s\t%s\t%d\t%v\t%v\t%v\t%v\t%v\n",
|
||||
|
|
@ -2186,6 +2173,13 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting
|
|||
ru := d.Spec.Strategy.RollingUpdate
|
||||
fmt.Fprintf(out, "RollingUpdateStrategy:\t%s max unavailable, %s max surge\n", ru.MaxUnavailable.String(), ru.MaxSurge.String())
|
||||
}
|
||||
if len(d.Status.Conditions) > 0 {
|
||||
fmt.Fprint(out, "Conditions:\n Type\tStatus\tReason\n")
|
||||
fmt.Fprint(out, " ----\t------\t------\n")
|
||||
for _, c := range d.Status.Conditions {
|
||||
fmt.Fprintf(out, " %v \t%v\t%v\n", c.Type, c.Status, c.Reason)
|
||||
}
|
||||
}
|
||||
oldRSs, _, newRS, err := deploymentutil.GetAllReplicaSets(d, dd)
|
||||
if err == nil {
|
||||
fmt.Fprintf(out, "OldReplicaSets:\t%s\n", printReplicaSetsByLabels(oldRSs))
|
||||
|
|
@ -2214,7 +2208,7 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting
|
|||
// of getting all DS's and searching through them manually).
|
||||
// TODO: write an interface for controllers and fuse getReplicationControllersForLabels
|
||||
// and getDaemonSetsForLabels.
|
||||
func getDaemonSetsForLabels(c client.DaemonSetInterface, labelsToMatch labels.Labels) ([]extensions.DaemonSet, error) {
|
||||
func getDaemonSetsForLabels(c extensionsclient.DaemonSetInterface, labelsToMatch labels.Labels) ([]extensions.DaemonSet, error) {
|
||||
// Get all daemon sets
|
||||
// TODO: this needs a namespace scope as argument
|
||||
dss, err := c.List(api.ListOptions{})
|
||||
|
|
@ -2265,7 +2259,7 @@ func printReplicaSetsByLabels(matchingRSs []*extensions.ReplicaSet) string {
|
|||
return list
|
||||
}
|
||||
|
||||
func getPodStatusForController(c client.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) {
|
||||
func getPodStatusForController(c coreclient.PodInterface, selector labels.Selector) (running, waiting, succeeded, failed int, err error) {
|
||||
options := api.ListOptions{LabelSelector: selector}
|
||||
rcPods, err := c.List(options)
|
||||
if err != nil {
|
||||
|
|
@ -2288,11 +2282,11 @@ func getPodStatusForController(c client.PodInterface, selector labels.Selector)
|
|||
|
||||
// ConfigMapDescriber generates information about a ConfigMap
|
||||
type ConfigMapDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ConfigMapDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.ConfigMaps(namespace)
|
||||
c := d.Core().ConfigMaps(namespace)
|
||||
|
||||
configMap, err := c.Get(name)
|
||||
if err != nil {
|
||||
|
|
@ -2360,7 +2354,7 @@ func describeCluster(cluster *federation.Cluster) (string, error) {
|
|||
|
||||
// NetworkPolicyDescriber generates information about a NetworkPolicy
|
||||
type NetworkPolicyDescriber struct {
|
||||
client.Interface
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (d *NetworkPolicyDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
|
|
@ -2385,6 +2379,34 @@ func describeNetworkPolicy(networkPolicy *extensions.NetworkPolicy) (string, err
|
|||
})
|
||||
}
|
||||
|
||||
type StorageClassDescriber struct {
|
||||
clientset.Interface
|
||||
}
|
||||
|
||||
func (s *StorageClassDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
sc, err := s.Storage().StorageClasses().Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", sc.Name)
|
||||
fmt.Fprintf(out, "IsDefaultClass:\t%s\n", storageutil.IsDefaultAnnotationText(sc.ObjectMeta))
|
||||
fmt.Fprintf(out, "Annotations:\t%s\n", labels.FormatLabels(sc.Annotations))
|
||||
fmt.Fprintf(out, "Provisioner:\t%s\n", sc.Provisioner)
|
||||
fmt.Fprintf(out, "Parameters:\t%s\n", labels.FormatLabels(sc.Parameters))
|
||||
if describerSettings.ShowEvents {
|
||||
events, err := s.Core().Events(namespace).Search(sc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// newErrNoDescriber creates a new ErrNoDescriber with the names of the provided types.
|
||||
func newErrNoDescriber(types ...reflect.Type) error {
|
||||
names := make([]string, 0, len(types))
|
||||
|
|
|
|||
84
vendor/k8s.io/kubernetes/pkg/kubectl/kubectl.go
generated
vendored
84
vendor/k8s.io/kubernetes/pkg/kubectl/kubectl.go
generated
vendored
|
|
@ -48,28 +48,6 @@ func makeImageList(spec *api.PodSpec) string {
|
|||
return strings.Join(listOfImages(spec), ",")
|
||||
}
|
||||
|
||||
func NewThirdPartyResourceMapper(gvs []unversioned.GroupVersion, gvks []unversioned.GroupVersionKind) (meta.RESTMapper, error) {
|
||||
mapper := meta.NewDefaultRESTMapper(gvs, func(gv unversioned.GroupVersion) (*meta.VersionInterfaces, error) {
|
||||
for ix := range gvs {
|
||||
if gvs[ix].Group == gv.Group && gvs[ix].Version == gv.Version {
|
||||
return &meta.VersionInterfaces{
|
||||
ObjectConvertor: api.Scheme,
|
||||
MetadataAccessor: meta.NewAccessor(),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
groupVersions := make([]string, 0, len(gvs))
|
||||
for ix := range gvs {
|
||||
groupVersions = append(groupVersions, gvs[ix].String())
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", gv.String(), strings.Join(groupVersions, ", "))
|
||||
})
|
||||
for ix := range gvks {
|
||||
mapper.Add(gvks[ix], meta.RESTScopeNamespace)
|
||||
}
|
||||
return mapper, nil
|
||||
}
|
||||
|
||||
// OutputVersionMapper is a RESTMapper that will prefer mappings that
|
||||
// correspond to a preferred output version (if feasible)
|
||||
type OutputVersionMapper struct {
|
||||
|
|
@ -97,48 +75,8 @@ func (m OutputVersionMapper) RESTMapping(gk unversioned.GroupKind, versions ...s
|
|||
return m.RESTMapper.RESTMapping(gk, versions...)
|
||||
}
|
||||
|
||||
// ShortcutExpander is a RESTMapper that can be used for Kubernetes
|
||||
// resources. It expands the resource first, then invokes the wrapped RESTMapper
|
||||
type ShortcutExpander struct {
|
||||
RESTMapper meta.RESTMapper
|
||||
}
|
||||
|
||||
var _ meta.RESTMapper = &ShortcutExpander{}
|
||||
|
||||
func (e ShortcutExpander) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) {
|
||||
return e.RESTMapper.KindFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) KindsFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionKind, error) {
|
||||
return e.RESTMapper.KindsFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourcesFor(resource unversioned.GroupVersionResource) ([]unversioned.GroupVersionResource, error) {
|
||||
return e.RESTMapper.ResourcesFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourceFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionResource, error) {
|
||||
return e.RESTMapper.ResourceFor(expandResourceShortcut(resource))
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) RESTMapping(gk unversioned.GroupKind, versions ...string) (*meta.RESTMapping, error) {
|
||||
return e.RESTMapper.RESTMapping(gk, versions...)
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) RESTMappings(gk unversioned.GroupKind) ([]*meta.RESTMapping, error) {
|
||||
return e.RESTMapper.RESTMappings(gk)
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) ResourceSingularizer(resource string) (string, error) {
|
||||
return e.RESTMapper.ResourceSingularizer(expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource)
|
||||
}
|
||||
|
||||
func (e ShortcutExpander) AliasesForResource(resource string) ([]string, bool) {
|
||||
return e.RESTMapper.AliasesForResource(expandResourceShortcut(unversioned.GroupVersionResource{Resource: resource}).Resource)
|
||||
}
|
||||
|
||||
// shortForms is the list of short names to their expanded names
|
||||
var shortForms = map[string]string{
|
||||
// ShortForms is the list of short names to their expanded names
|
||||
var ShortForms = map[string]string{
|
||||
// Please keep this alphabetized
|
||||
// If you add an entry here, please also take a look at pkg/kubectl/cmd/cmd.go
|
||||
// and add an entry to valid_resources when appropriate.
|
||||
|
|
@ -165,30 +103,20 @@ var shortForms = map[string]string{
|
|||
"svc": "services",
|
||||
}
|
||||
|
||||
// Look-up for resource short forms by value
|
||||
// ResourceShortFormFor looks up for a short form of resource names.
|
||||
func ResourceShortFormFor(resource string) (string, bool) {
|
||||
var alias string
|
||||
exists := false
|
||||
for k, val := range shortForms {
|
||||
for k, val := range ShortForms {
|
||||
if val == resource {
|
||||
alias = k
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return alias, exists
|
||||
}
|
||||
|
||||
// expandResourceShortcut will return the expanded version of resource
|
||||
// (something that a pkg/api/meta.RESTMapper can understand), if it is
|
||||
// indeed a shortcut. Otherwise, will return resource unmodified.
|
||||
func expandResourceShortcut(resource unversioned.GroupVersionResource) unversioned.GroupVersionResource {
|
||||
if expanded, ok := shortForms[resource.Resource]; ok {
|
||||
// don't change the group or version that's already been specified
|
||||
resource.Resource = expanded
|
||||
}
|
||||
return resource
|
||||
}
|
||||
|
||||
// ResourceAliases returns the resource shortcuts and plural forms for the given resources.
|
||||
func ResourceAliases(rs []string) []string {
|
||||
as := make([]string, 0, len(rs))
|
||||
|
|
@ -210,7 +138,7 @@ func ResourceAliases(rs []string) []string {
|
|||
plurals[plural] = struct{}{}
|
||||
}
|
||||
|
||||
for sf, r := range shortForms {
|
||||
for sf, r := range ShortForms {
|
||||
if _, found := plurals[r]; found {
|
||||
as = append(as, sf)
|
||||
}
|
||||
|
|
|
|||
80
vendor/k8s.io/kubernetes/pkg/kubectl/resource/BUILD
generated
vendored
Normal file
80
vendor/k8s.io/kubernetes/pkg/kubectl/resource/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_binary",
|
||||
"go_library",
|
||||
"go_test",
|
||||
"cgo_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"builder.go",
|
||||
"doc.go",
|
||||
"helper.go",
|
||||
"interfaces.go",
|
||||
"mapper.go",
|
||||
"result.go",
|
||||
"selector.go",
|
||||
"visitor.go",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/errors:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/validation:go_default_library",
|
||||
"//pkg/apimachinery/registered:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/client/restclient:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/util/errors:go_default_library",
|
||||
"//pkg/util/sets:go_default_library",
|
||||
"//pkg/util/yaml:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"builder_test.go",
|
||||
"helper_test.go",
|
||||
"visitor_test.go",
|
||||
],
|
||||
data = [
|
||||
"//examples:config",
|
||||
"//test/fixtures",
|
||||
],
|
||||
library = "go_default_library",
|
||||
tags = [
|
||||
"automanaged",
|
||||
"skip",
|
||||
],
|
||||
deps = [
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/meta:go_default_library",
|
||||
"//pkg/api/resource:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/api/testing:go_default_library",
|
||||
"//pkg/api/unversioned:go_default_library",
|
||||
"//pkg/api/v1:go_default_library",
|
||||
"//pkg/apimachinery/registered:go_default_library",
|
||||
"//pkg/client/restclient/fake:go_default_library",
|
||||
"//pkg/labels:go_default_library",
|
||||
"//pkg/runtime:go_default_library",
|
||||
"//pkg/runtime/serializer/streaming:go_default_library",
|
||||
"//pkg/util/errors:go_default_library",
|
||||
"//pkg/util/testing:go_default_library",
|
||||
"//pkg/watch:go_default_library",
|
||||
"//pkg/watch/versioned:go_default_library",
|
||||
"//vendor:github.com/ghodss/yaml",
|
||||
"//vendor:github.com/stretchr/testify/assert",
|
||||
],
|
||||
)
|
||||
349
vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go
generated
vendored
349
vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go
generated
vendored
|
|
@ -55,8 +55,9 @@ type Builder struct {
|
|||
|
||||
resources []string
|
||||
|
||||
namespace string
|
||||
names []string
|
||||
namespace string
|
||||
allNamespace bool
|
||||
names []string
|
||||
|
||||
resourceTuples []resourceTuple
|
||||
|
||||
|
|
@ -93,6 +94,11 @@ func IsUsageError(err error) bool {
|
|||
return err == missingResourceError
|
||||
}
|
||||
|
||||
type FilenameOptions struct {
|
||||
Filenames []string
|
||||
Recursive bool
|
||||
}
|
||||
|
||||
type resourceTuple struct {
|
||||
Resource string
|
||||
Name string
|
||||
|
|
@ -117,7 +123,9 @@ func (b *Builder) Schema(schema validation.Schema) *Builder {
|
|||
// will cause an error.
|
||||
// If ContinueOnError() is set prior to this method, objects on the path that are not
|
||||
// recognized will be ignored (but logged at V(2)).
|
||||
func (b *Builder) FilenameParam(enforceNamespace, recursive bool, paths ...string) *Builder {
|
||||
func (b *Builder) FilenameParam(enforceNamespace bool, filenameOptions *FilenameOptions) *Builder {
|
||||
recursive := filenameOptions.Recursive
|
||||
paths := filenameOptions.Filenames
|
||||
for _, s := range paths {
|
||||
switch {
|
||||
case s == "-":
|
||||
|
|
@ -284,11 +292,12 @@ func (b *Builder) DefaultNamespace() *Builder {
|
|||
}
|
||||
|
||||
// AllNamespaces instructs the builder to use NamespaceAll as a namespace to request resources
|
||||
// acroll all namespace. This overrides the namespace set by NamespaceParam().
|
||||
// across all of the namespace. This overrides the namespace set by NamespaceParam().
|
||||
func (b *Builder) AllNamespaces(allNamespace bool) *Builder {
|
||||
if allNamespace {
|
||||
b.namespace = api.NamespaceAll
|
||||
}
|
||||
b.allNamespace = allNamespace
|
||||
return b
|
||||
}
|
||||
|
||||
|
|
@ -336,7 +345,7 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string
|
|||
}
|
||||
if len(args) > 0 {
|
||||
// Try replacing aliases only in types
|
||||
args[0] = b.replaceAliases(args[0])
|
||||
args[0] = b.ReplaceAliases(args[0])
|
||||
}
|
||||
switch {
|
||||
case len(args) > 2:
|
||||
|
|
@ -357,9 +366,9 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string
|
|||
return b
|
||||
}
|
||||
|
||||
// replaceAliases accepts an argument and tries to expand any existing
|
||||
// ReplaceAliases accepts an argument and tries to expand any existing
|
||||
// aliases found in it
|
||||
func (b *Builder) replaceAliases(input string) string {
|
||||
func (b *Builder) ReplaceAliases(input string) string {
|
||||
replaced := []string{}
|
||||
for _, arg := range strings.Split(input, ",") {
|
||||
if aliases, ok := b.mapper.AliasesForResource(arg); ok {
|
||||
|
|
@ -531,191 +540,213 @@ func (b *Builder) visitorResult() *Result {
|
|||
b.selector = labels.Everything()
|
||||
}
|
||||
|
||||
// visit items specified by paths
|
||||
if len(b.paths) != 0 {
|
||||
return b.visitByPaths()
|
||||
}
|
||||
|
||||
// visit selectors
|
||||
if b.selector != nil {
|
||||
if len(b.names) != 0 {
|
||||
return &Result{err: fmt.Errorf("name cannot be provided when a selector is specified")}
|
||||
}
|
||||
if len(b.resourceTuples) != 0 {
|
||||
return &Result{err: fmt.Errorf("selectors and the all flag cannot be used when passing resource/name arguments")}
|
||||
}
|
||||
if len(b.resources) == 0 {
|
||||
return &Result{err: fmt.Errorf("at least one resource must be specified to use a selector")}
|
||||
}
|
||||
// empty selector has different error message for paths being provided
|
||||
if len(b.paths) != 0 {
|
||||
if b.selector.Empty() {
|
||||
return &Result{err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")}
|
||||
} else {
|
||||
return &Result{err: fmt.Errorf("a selector may not be specified when path, URL, or stdin is provided as input")}
|
||||
}
|
||||
}
|
||||
mappings, err := b.resourceMappings()
|
||||
if err != nil {
|
||||
return &Result{err: err}
|
||||
}
|
||||
|
||||
visitors := []Visitor{}
|
||||
for _, mapping := range mappings {
|
||||
client, err := b.mapper.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return &Result{err: err}
|
||||
}
|
||||
selectorNamespace := b.namespace
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
}
|
||||
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, b.selector, b.export))
|
||||
}
|
||||
if b.continueOnError {
|
||||
return &Result{visitor: EagerVisitorList(visitors), sources: visitors}
|
||||
}
|
||||
return &Result{visitor: VisitorList(visitors), sources: visitors}
|
||||
return b.visitBySelector()
|
||||
}
|
||||
|
||||
// visit items specified by resource and name
|
||||
if len(b.resourceTuples) != 0 {
|
||||
// if b.singular is false, this could be by default, so double-check length
|
||||
// of resourceTuples to determine if in fact it is singular or not
|
||||
isSingular := b.singular
|
||||
if !isSingular {
|
||||
isSingular = len(b.resourceTuples) == 1
|
||||
}
|
||||
|
||||
if len(b.paths) != 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")}
|
||||
}
|
||||
if len(b.resources) != 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you may not specify individual resources and bulk resources in the same call")}
|
||||
}
|
||||
|
||||
// retrieve one client for each resource
|
||||
mappings, err := b.resourceTupleMappings()
|
||||
if err != nil {
|
||||
return &Result{singular: isSingular, err: err}
|
||||
}
|
||||
clients := make(map[string]RESTClient)
|
||||
for _, mapping := range mappings {
|
||||
s := fmt.Sprintf("%s/%s", mapping.GroupVersionKind.GroupVersion().String(), mapping.Resource)
|
||||
if _, ok := clients[s]; ok {
|
||||
continue
|
||||
}
|
||||
client, err := b.mapper.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return &Result{err: err}
|
||||
}
|
||||
clients[s] = client
|
||||
}
|
||||
|
||||
items := []Visitor{}
|
||||
for _, tuple := range b.resourceTuples {
|
||||
mapping, ok := mappings[tuple.Resource]
|
||||
if !ok {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("resource %q is not recognized: %v", tuple.Resource, mappings)}
|
||||
}
|
||||
s := fmt.Sprintf("%s/%s", mapping.GroupVersionKind.GroupVersion().String(), mapping.Resource)
|
||||
client, ok := clients[s]
|
||||
if !ok {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("could not find a client for resource %q", tuple.Resource)}
|
||||
}
|
||||
|
||||
selectorNamespace := b.namespace
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
} else {
|
||||
if len(b.namespace) == 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("namespace may not be empty when retrieving a resource by name")}
|
||||
}
|
||||
}
|
||||
|
||||
info := NewInfo(client, mapping, selectorNamespace, tuple.Name, b.export)
|
||||
items = append(items, info)
|
||||
}
|
||||
|
||||
var visitors Visitor
|
||||
if b.continueOnError {
|
||||
visitors = EagerVisitorList(items)
|
||||
} else {
|
||||
visitors = VisitorList(items)
|
||||
}
|
||||
return &Result{singular: isSingular, visitor: visitors, sources: items}
|
||||
return b.visitByResource()
|
||||
}
|
||||
|
||||
// visit items specified by name
|
||||
if len(b.names) != 0 {
|
||||
isSingular := len(b.names) == 1
|
||||
return b.visitByName()
|
||||
}
|
||||
|
||||
if len(b.paths) != 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")}
|
||||
}
|
||||
if len(b.resources) == 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you must provide a resource and a resource name together")}
|
||||
}
|
||||
if len(b.resources) > 1 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you must specify only one resource")}
|
||||
}
|
||||
if len(b.resources) != 0 {
|
||||
return &Result{err: fmt.Errorf("resource(s) were provided, but no name, label selector, or --all flag specified")}
|
||||
}
|
||||
return &Result{err: missingResourceError}
|
||||
}
|
||||
|
||||
mappings, err := b.resourceMappings()
|
||||
if err != nil {
|
||||
return &Result{singular: isSingular, err: err}
|
||||
}
|
||||
mapping := mappings[0]
|
||||
func (b *Builder) visitBySelector() *Result {
|
||||
if len(b.names) != 0 {
|
||||
return &Result{err: fmt.Errorf("name cannot be provided when a selector is specified")}
|
||||
}
|
||||
if len(b.resourceTuples) != 0 {
|
||||
return &Result{err: fmt.Errorf("selectors and the all flag cannot be used when passing resource/name arguments")}
|
||||
}
|
||||
if len(b.resources) == 0 {
|
||||
return &Result{err: fmt.Errorf("at least one resource must be specified to use a selector")}
|
||||
}
|
||||
mappings, err := b.resourceMappings()
|
||||
if err != nil {
|
||||
return &Result{err: err}
|
||||
}
|
||||
|
||||
visitors := []Visitor{}
|
||||
for _, mapping := range mappings {
|
||||
client, err := b.mapper.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return &Result{err: err}
|
||||
}
|
||||
selectorNamespace := b.namespace
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
}
|
||||
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, b.selector, b.export))
|
||||
}
|
||||
if b.continueOnError {
|
||||
return &Result{visitor: EagerVisitorList(visitors), sources: visitors}
|
||||
}
|
||||
return &Result{visitor: VisitorList(visitors), sources: visitors}
|
||||
}
|
||||
|
||||
func (b *Builder) visitByResource() *Result {
|
||||
// if b.singular is false, this could be by default, so double-check length
|
||||
// of resourceTuples to determine if in fact it is singular or not
|
||||
isSingular := b.singular
|
||||
if !isSingular {
|
||||
isSingular = len(b.resourceTuples) == 1
|
||||
}
|
||||
|
||||
if len(b.resources) != 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you may not specify individual resources and bulk resources in the same call")}
|
||||
}
|
||||
|
||||
// retrieve one client for each resource
|
||||
mappings, err := b.resourceTupleMappings()
|
||||
if err != nil {
|
||||
return &Result{singular: isSingular, err: err}
|
||||
}
|
||||
clients := make(map[string]RESTClient)
|
||||
for _, mapping := range mappings {
|
||||
s := fmt.Sprintf("%s/%s", mapping.GroupVersionKind.GroupVersion().String(), mapping.Resource)
|
||||
if _, ok := clients[s]; ok {
|
||||
continue
|
||||
}
|
||||
client, err := b.mapper.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return &Result{err: err}
|
||||
}
|
||||
clients[s] = client
|
||||
}
|
||||
|
||||
items := []Visitor{}
|
||||
for _, tuple := range b.resourceTuples {
|
||||
mapping, ok := mappings[tuple.Resource]
|
||||
if !ok {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("resource %q is not recognized: %v", tuple.Resource, mappings)}
|
||||
}
|
||||
s := fmt.Sprintf("%s/%s", mapping.GroupVersionKind.GroupVersion().String(), mapping.Resource)
|
||||
client, ok := clients[s]
|
||||
if !ok {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("could not find a client for resource %q", tuple.Resource)}
|
||||
}
|
||||
|
||||
selectorNamespace := b.namespace
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
} else {
|
||||
if len(b.namespace) == 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("namespace may not be empty when retrieving a resource by name")}
|
||||
errMsg := "namespace may not be empty when retrieving a resource by name"
|
||||
if b.allNamespace {
|
||||
errMsg = "a resource cannot be retrieved by name across all namespaces"
|
||||
}
|
||||
return &Result{singular: isSingular, err: fmt.Errorf(errMsg)}
|
||||
}
|
||||
}
|
||||
|
||||
visitors := []Visitor{}
|
||||
for _, name := range b.names {
|
||||
info := NewInfo(client, mapping, selectorNamespace, name, b.export)
|
||||
visitors = append(visitors, info)
|
||||
}
|
||||
return &Result{singular: isSingular, visitor: VisitorList(visitors), sources: visitors}
|
||||
info := NewInfo(client, mapping, selectorNamespace, tuple.Name, b.export)
|
||||
items = append(items, info)
|
||||
}
|
||||
|
||||
// visit items specified by paths
|
||||
var visitors Visitor
|
||||
if b.continueOnError {
|
||||
visitors = EagerVisitorList(items)
|
||||
} else {
|
||||
visitors = VisitorList(items)
|
||||
}
|
||||
return &Result{singular: isSingular, visitor: visitors, sources: items}
|
||||
}
|
||||
|
||||
func (b *Builder) visitByName() *Result {
|
||||
isSingular := len(b.names) == 1
|
||||
|
||||
if len(b.paths) != 0 {
|
||||
singular := !b.dir && !b.stream && len(b.paths) == 1
|
||||
if len(b.resources) != 0 {
|
||||
return &Result{singular: singular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify resource arguments as well")}
|
||||
}
|
||||
|
||||
var visitors Visitor
|
||||
if b.continueOnError {
|
||||
visitors = EagerVisitorList(b.paths)
|
||||
} else {
|
||||
visitors = VisitorList(b.paths)
|
||||
}
|
||||
|
||||
// only items from disk can be refetched
|
||||
if b.latest {
|
||||
// must flatten lists prior to fetching
|
||||
if b.flatten {
|
||||
visitors = NewFlattenListVisitor(visitors, b.mapper)
|
||||
}
|
||||
// must set namespace prior to fetching
|
||||
if b.defaultNamespace {
|
||||
visitors = NewDecoratedVisitor(visitors, SetNamespace(b.namespace))
|
||||
}
|
||||
visitors = NewDecoratedVisitor(visitors, RetrieveLatest)
|
||||
}
|
||||
return &Result{singular: singular, visitor: visitors, sources: b.paths}
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")}
|
||||
}
|
||||
if len(b.resources) == 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you must provide a resource and a resource name together")}
|
||||
}
|
||||
if len(b.resources) > 1 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you must specify only one resource")}
|
||||
}
|
||||
|
||||
mappings, err := b.resourceMappings()
|
||||
if err != nil {
|
||||
return &Result{singular: isSingular, err: err}
|
||||
}
|
||||
mapping := mappings[0]
|
||||
|
||||
client, err := b.mapper.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return &Result{err: err}
|
||||
}
|
||||
|
||||
selectorNamespace := b.namespace
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
} else {
|
||||
if len(b.namespace) == 0 {
|
||||
errMsg := "namespace may not be empty when retrieving a resource by name"
|
||||
if b.allNamespace {
|
||||
errMsg = "a resource cannot be retrieved by name across all namespaces"
|
||||
}
|
||||
return &Result{singular: isSingular, err: fmt.Errorf(errMsg)}
|
||||
}
|
||||
}
|
||||
|
||||
visitors := []Visitor{}
|
||||
for _, name := range b.names {
|
||||
info := NewInfo(client, mapping, selectorNamespace, name, b.export)
|
||||
visitors = append(visitors, info)
|
||||
}
|
||||
return &Result{singular: isSingular, visitor: VisitorList(visitors), sources: visitors}
|
||||
}
|
||||
|
||||
func (b *Builder) visitByPaths() *Result {
|
||||
singular := !b.dir && !b.stream && len(b.paths) == 1
|
||||
if len(b.resources) != 0 {
|
||||
return &Result{err: fmt.Errorf("resource(s) were provided, but no name, label selector, or --all flag specified")}
|
||||
return &Result{singular: singular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify resource arguments as well")}
|
||||
}
|
||||
return &Result{err: missingResourceError}
|
||||
if len(b.names) != 0 {
|
||||
return &Result{err: fmt.Errorf("name cannot be provided when a path is specified")}
|
||||
}
|
||||
if len(b.resourceTuples) != 0 {
|
||||
return &Result{err: fmt.Errorf("resource/name arguments cannot be provided when a path is specified")}
|
||||
}
|
||||
|
||||
var visitors Visitor
|
||||
if b.continueOnError {
|
||||
visitors = EagerVisitorList(b.paths)
|
||||
} else {
|
||||
visitors = VisitorList(b.paths)
|
||||
}
|
||||
|
||||
// only items from disk can be refetched
|
||||
if b.latest {
|
||||
// must flatten lists prior to fetching
|
||||
if b.flatten {
|
||||
visitors = NewFlattenListVisitor(visitors, b.mapper)
|
||||
}
|
||||
// must set namespace prior to fetching
|
||||
if b.defaultNamespace {
|
||||
visitors = NewDecoratedVisitor(visitors, SetNamespace(b.namespace))
|
||||
}
|
||||
visitors = NewDecoratedVisitor(visitors, RetrieveLatest)
|
||||
}
|
||||
if b.selector != nil {
|
||||
visitors = NewFilteredVisitor(visitors, FilterBySelector(b.selector))
|
||||
}
|
||||
return &Result{singular: singular, visitor: visitors, sources: b.paths}
|
||||
}
|
||||
|
||||
// Do returns a Result object with a Visitor for the resources identified by the Builder.
|
||||
|
|
|
|||
8
vendor/k8s.io/kubernetes/pkg/kubectl/resource/result.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/kubectl/resource/result.go
generated
vendored
|
|
@ -222,7 +222,7 @@ func AsVersionedObject(infos []*Info, forceList bool, version unversioned.GroupV
|
|||
object = objects[0]
|
||||
} else {
|
||||
object = &api.List{Items: objects}
|
||||
converted, err := tryConvert(api.Scheme, object, version, registered.GroupOrDie(api.GroupName).GroupVersion)
|
||||
converted, err := TryConvert(api.Scheme, object, version, registered.GroupOrDie(api.GroupName).GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -263,7 +263,7 @@ func AsVersionedObjects(infos []*Info, version unversioned.GroupVersion, encoder
|
|||
}
|
||||
}
|
||||
|
||||
converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion())
|
||||
converted, err := TryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -272,9 +272,9 @@ func AsVersionedObjects(infos []*Info, version unversioned.GroupVersion, encoder
|
|||
return objects, nil
|
||||
}
|
||||
|
||||
// tryConvert attempts to convert the given object to the provided versions in order. This function assumes
|
||||
// TryConvert attempts to convert the given object to the provided versions in order. This function assumes
|
||||
// the object is in internal version.
|
||||
func tryConvert(converter runtime.ObjectConvertor, object runtime.Object, versions ...unversioned.GroupVersion) (runtime.Object, error) {
|
||||
func TryConvert(converter runtime.ObjectConvertor, object runtime.Object, versions ...unversioned.GroupVersion) (runtime.Object, error) {
|
||||
var last error
|
||||
for _, version := range versions {
|
||||
if version.Empty() {
|
||||
|
|
|
|||
57
vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go
generated
vendored
57
vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go
generated
vendored
|
|
@ -26,9 +26,12 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||
"k8s.io/kubernetes/pkg/util/yaml"
|
||||
|
|
@ -110,6 +113,12 @@ func (i *Info) Visit(fn VisitorFunc) error {
|
|||
func (i *Info) Get() (err error) {
|
||||
obj, err := NewHelper(i.Client, i.Mapping).Get(i.Namespace, i.Name, i.Export)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) && len(i.Namespace) > 0 && i.Namespace != api.NamespaceDefault && i.Namespace != api.NamespaceAll {
|
||||
err2 := i.Client.Get().AbsPath("api", "v1", "namespaces", i.Namespace).Do().Error()
|
||||
if err2 != nil && errors.IsNotFound(err2) {
|
||||
return err2
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
i.Object = obj
|
||||
|
|
@ -631,3 +640,51 @@ func RetrieveLazy(info *Info, err error) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FilterFunc func(info *Info, err error) (bool, error)
|
||||
|
||||
type FilteredVisitor struct {
|
||||
visitor Visitor
|
||||
filters []FilterFunc
|
||||
}
|
||||
|
||||
func NewFilteredVisitor(v Visitor, fn ...FilterFunc) Visitor {
|
||||
if len(fn) == 0 {
|
||||
return v
|
||||
}
|
||||
return FilteredVisitor{v, fn}
|
||||
}
|
||||
|
||||
func (v FilteredVisitor) Visit(fn VisitorFunc) error {
|
||||
return v.visitor.Visit(func(info *Info, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, filter := range v.filters {
|
||||
ok, err := filter(info, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fn(info, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func FilterBySelector(s labels.Selector) FilterFunc {
|
||||
return func(info *Info, err error) (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
a, err := meta.Accessor(info.Object)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !s.Matches(labels.Set(a.GetLabels())) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
67
vendor/k8s.io/kubernetes/pkg/kubectl/resource_filter.go
generated
vendored
Normal file
67
vendor/k8s.io/kubernetes/pkg/kubectl/resource_filter.go
generated
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
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 kubectl
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// FilterFunc is a function that knows how to filter a specific resource kind.
|
||||
// It receives a generic runtime.Object which must be type-checked by the function.
|
||||
// Returns a boolean value true if a resource is filtered, or false otherwise.
|
||||
type FilterFunc func(runtime.Object, PrintOptions) bool
|
||||
|
||||
// Filters is a collection of filter funcs
|
||||
type Filters []FilterFunc
|
||||
|
||||
func NewResourceFilter() Filters {
|
||||
return []FilterFunc{
|
||||
filterPods,
|
||||
}
|
||||
}
|
||||
|
||||
// filterPods returns true if a pod should be skipped.
|
||||
// defaults to true for terminated pods
|
||||
func filterPods(obj runtime.Object, options PrintOptions) bool {
|
||||
switch p := obj.(type) {
|
||||
case *v1.Pod:
|
||||
reason := string(p.Status.Phase)
|
||||
if p.Status.Reason != "" {
|
||||
reason = p.Status.Reason
|
||||
}
|
||||
return !options.ShowAll && (reason == string(v1.PodSucceeded) || reason == string(v1.PodFailed))
|
||||
case *api.Pod:
|
||||
reason := string(p.Status.Phase)
|
||||
if p.Status.Reason != "" {
|
||||
reason = p.Status.Reason
|
||||
}
|
||||
return !options.ShowAll && (reason == string(api.PodSucceeded) || reason == string(api.PodFailed))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Filter loops through a collection of FilterFuncs until it finds one that can filter the given resource
|
||||
func (f Filters) Filter(obj runtime.Object, opts *PrintOptions) (bool, error) {
|
||||
for _, filter := range f {
|
||||
if ok := filter(obj, *opts); ok {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
340
vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go
generated
vendored
340
vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go
generated
vendored
|
|
@ -30,10 +30,9 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/events"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
|
|
@ -43,11 +42,16 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||
"k8s.io/kubernetes/pkg/util/jsonpath"
|
||||
"k8s.io/kubernetes/pkg/util/node"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -150,7 +154,7 @@ type ResourcePrinter interface {
|
|||
HandledResources() []string
|
||||
//Can be used to print out warning/clarifications if needed
|
||||
//after all objects were printed
|
||||
FinishPrint(io.Writer, string) error
|
||||
AfterPrint(io.Writer, string) error
|
||||
}
|
||||
|
||||
// ResourcePrinterFunc is a function that can print objects
|
||||
|
|
@ -166,7 +170,7 @@ func (fn ResourcePrinterFunc) HandledResources() []string {
|
|||
return []string{}
|
||||
}
|
||||
|
||||
func (fn ResourcePrinterFunc) FinishPrint(io.Writer, string) error {
|
||||
func (fn ResourcePrinterFunc) AfterPrint(io.Writer, string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +191,7 @@ func NewVersionedPrinter(printer ResourcePrinter, converter runtime.ObjectConver
|
|||
}
|
||||
}
|
||||
|
||||
func (p *VersionedPrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (p *VersionedPrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +218,7 @@ type NamePrinter struct {
|
|||
Typer runtime.ObjectTyper
|
||||
}
|
||||
|
||||
func (p *NamePrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (p *NamePrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -237,8 +241,6 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO: this is wrong, runtime.Unknown and runtime.Unstructured are not handled properly here.
|
||||
|
||||
name := "<unknown>"
|
||||
if acc, err := meta.Accessor(obj); err == nil {
|
||||
if n := acc.GetName(); len(n) > 0 {
|
||||
|
|
@ -246,12 +248,22 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
|||
}
|
||||
}
|
||||
|
||||
if gvks, _, err := p.Typer.ObjectKinds(obj); err == nil {
|
||||
// TODO: this is wrong, it assumes that meta knows about all Kinds - should take a RESTMapper
|
||||
_, resource := meta.KindToResource(gvks[0])
|
||||
fmt.Fprintf(w, "%s/%s\n", resource.Resource, name)
|
||||
if kind := obj.GetObjectKind().GroupVersionKind(); len(kind.Kind) == 0 {
|
||||
// this is the old code. It's unnecessary on decoded external objects, but on internal objects
|
||||
// you may have to do it. Tests are definitely calling it with internals and I'm not sure who else
|
||||
// is
|
||||
if gvks, _, err := p.Typer.ObjectKinds(obj); err == nil {
|
||||
// TODO: this is wrong, it assumes that meta knows about all Kinds - should take a RESTMapper
|
||||
_, resource := meta.KindToResource(gvks[0])
|
||||
fmt.Fprintf(w, "%s/%s\n", resource.Resource, name)
|
||||
} else {
|
||||
fmt.Fprintf(w, "<unknown>/%s\n", name)
|
||||
}
|
||||
|
||||
} else {
|
||||
fmt.Fprintf(w, "<unknown>/%s\n", name)
|
||||
// TODO: this is wrong, it assumes that meta knows about all Kinds - should take a RESTMapper
|
||||
_, resource := meta.KindToResource(kind)
|
||||
fmt.Fprintf(w, "%s/%s\n", resource.Resource, name)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -266,7 +278,7 @@ func (p *NamePrinter) HandledResources() []string {
|
|||
type JSONPrinter struct {
|
||||
}
|
||||
|
||||
func (p *JSONPrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (p *JSONPrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -274,7 +286,13 @@ func (p *JSONPrinter) FinishPrint(w io.Writer, res string) error {
|
|||
func (p *JSONPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
switch obj := obj.(type) {
|
||||
case *runtime.Unknown:
|
||||
_, err := w.Write(obj.Raw)
|
||||
var buf bytes.Buffer
|
||||
err := json.Indent(&buf, obj.Raw, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteRune('\n')
|
||||
_, err = buf.WriteTo(w)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -300,7 +318,7 @@ type YAMLPrinter struct {
|
|||
converter runtime.ObjectConvertor
|
||||
}
|
||||
|
||||
func (p *YAMLPrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (p *YAMLPrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -447,62 +465,55 @@ func (h *HumanReadablePrinter) HandledResources() []string {
|
|||
return keys
|
||||
}
|
||||
|
||||
func (h *HumanReadablePrinter) FinishPrint(output io.Writer, res string) error {
|
||||
if !h.options.NoHeaders && !h.options.ShowAll && h.hiddenObjNum > 0 {
|
||||
_, err := fmt.Fprintf(output, " info: %d completed object(s) was(were) not shown in %s list. Pass --show-all to see all objects.\n\n", h.hiddenObjNum, res)
|
||||
return err
|
||||
}
|
||||
func (h *HumanReadablePrinter) AfterPrint(output io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// NOTE: When adding a new resource type here, please update the list
|
||||
// pkg/kubectl/cmd/get.go to reflect the new resource type.
|
||||
var podColumns = []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE"}
|
||||
var podTemplateColumns = []string{"TEMPLATE", "CONTAINER(S)", "IMAGE(S)", "PODLABELS"}
|
||||
var replicationControllerColumns = []string{"NAME", "DESIRED", "CURRENT", "READY", "AGE"}
|
||||
var replicaSetColumns = []string{"NAME", "DESIRED", "CURRENT", "READY", "AGE"}
|
||||
var jobColumns = []string{"NAME", "DESIRED", "SUCCESSFUL", "AGE"}
|
||||
var scheduledJobColumns = []string{"NAME", "SCHEDULE", "SUSPEND", "ACTIVE", "LAST-SCHEDULE"}
|
||||
var serviceColumns = []string{"NAME", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE"}
|
||||
var ingressColumns = []string{"NAME", "HOSTS", "ADDRESS", "PORTS", "AGE"}
|
||||
var petSetColumns = []string{"NAME", "DESIRED", "CURRENT", "AGE"}
|
||||
var endpointColumns = []string{"NAME", "ENDPOINTS", "AGE"}
|
||||
var nodeColumns = []string{"NAME", "STATUS", "AGE"}
|
||||
var daemonSetColumns = []string{"NAME", "DESIRED", "CURRENT", "NODE-SELECTOR", "AGE"}
|
||||
var eventColumns = []string{"LASTSEEN", "FIRSTSEEN", "COUNT", "NAME", "KIND", "SUBOBJECT", "TYPE", "REASON", "SOURCE", "MESSAGE"}
|
||||
var limitRangeColumns = []string{"NAME", "AGE"}
|
||||
var resourceQuotaColumns = []string{"NAME", "AGE"}
|
||||
var namespaceColumns = []string{"NAME", "STATUS", "AGE"}
|
||||
var secretColumns = []string{"NAME", "TYPE", "DATA", "AGE"}
|
||||
var serviceAccountColumns = []string{"NAME", "SECRETS", "AGE"}
|
||||
var persistentVolumeColumns = []string{"NAME", "CAPACITY", "ACCESSMODES", "RECLAIMPOLICY", "STATUS", "CLAIM", "REASON", "AGE"}
|
||||
var persistentVolumeClaimColumns = []string{"NAME", "STATUS", "VOLUME", "CAPACITY", "ACCESSMODES", "AGE"}
|
||||
var componentStatusColumns = []string{"NAME", "STATUS", "MESSAGE", "ERROR"}
|
||||
var thirdPartyResourceColumns = []string{"NAME", "DESCRIPTION", "VERSION(S)"}
|
||||
var roleColumns = []string{"NAME", "AGE"}
|
||||
var roleBindingColumns = []string{"NAME", "AGE"}
|
||||
var clusterRoleColumns = []string{"NAME", "AGE"}
|
||||
var clusterRoleBindingColumns = []string{"NAME", "AGE"}
|
||||
var storageClassColumns = []string{"NAME", "TYPE"}
|
||||
var (
|
||||
podColumns = []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE"}
|
||||
podTemplateColumns = []string{"TEMPLATE", "CONTAINER(S)", "IMAGE(S)", "PODLABELS"}
|
||||
replicationControllerColumns = []string{"NAME", "DESIRED", "CURRENT", "READY", "AGE"}
|
||||
replicaSetColumns = []string{"NAME", "DESIRED", "CURRENT", "READY", "AGE"}
|
||||
jobColumns = []string{"NAME", "DESIRED", "SUCCESSFUL", "AGE"}
|
||||
cronJobColumns = []string{"NAME", "SCHEDULE", "SUSPEND", "ACTIVE", "LAST-SCHEDULE"}
|
||||
serviceColumns = []string{"NAME", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE"}
|
||||
ingressColumns = []string{"NAME", "HOSTS", "ADDRESS", "PORTS", "AGE"}
|
||||
statefulSetColumns = []string{"NAME", "DESIRED", "CURRENT", "AGE"}
|
||||
endpointColumns = []string{"NAME", "ENDPOINTS", "AGE"}
|
||||
nodeColumns = []string{"NAME", "STATUS", "AGE"}
|
||||
daemonSetColumns = []string{"NAME", "DESIRED", "CURRENT", "READY", "NODE-SELECTOR", "AGE"}
|
||||
eventColumns = []string{"LASTSEEN", "FIRSTSEEN", "COUNT", "NAME", "KIND", "SUBOBJECT", "TYPE", "REASON", "SOURCE", "MESSAGE"}
|
||||
limitRangeColumns = []string{"NAME", "AGE"}
|
||||
resourceQuotaColumns = []string{"NAME", "AGE"}
|
||||
namespaceColumns = []string{"NAME", "STATUS", "AGE"}
|
||||
secretColumns = []string{"NAME", "TYPE", "DATA", "AGE"}
|
||||
serviceAccountColumns = []string{"NAME", "SECRETS", "AGE"}
|
||||
persistentVolumeColumns = []string{"NAME", "CAPACITY", "ACCESSMODES", "RECLAIMPOLICY", "STATUS", "CLAIM", "REASON", "AGE"}
|
||||
persistentVolumeClaimColumns = []string{"NAME", "STATUS", "VOLUME", "CAPACITY", "ACCESSMODES", "AGE"}
|
||||
componentStatusColumns = []string{"NAME", "STATUS", "MESSAGE", "ERROR"}
|
||||
thirdPartyResourceColumns = []string{"NAME", "DESCRIPTION", "VERSION(S)"}
|
||||
roleColumns = []string{"NAME", "AGE"}
|
||||
roleBindingColumns = []string{"NAME", "AGE"}
|
||||
clusterRoleColumns = []string{"NAME", "AGE"}
|
||||
clusterRoleBindingColumns = []string{"NAME", "AGE"}
|
||||
storageClassColumns = []string{"NAME", "TYPE"}
|
||||
statusColumns = []string{"STATUS", "REASON", "MESSAGE"}
|
||||
|
||||
// TODO: consider having 'KIND' for third party resource data
|
||||
var thirdPartyResourceDataColumns = []string{"NAME", "LABELS", "DATA"}
|
||||
var horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGET", "CURRENT", "MINPODS", "MAXPODS", "AGE"}
|
||||
var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too.
|
||||
var deploymentColumns = []string{"NAME", "DESIRED", "CURRENT", "UP-TO-DATE", "AVAILABLE", "AGE"}
|
||||
var configMapColumns = []string{"NAME", "DATA", "AGE"}
|
||||
var podSecurityPolicyColumns = []string{"NAME", "PRIV", "CAPS", "VOLUMEPLUGINS", "SELINUX", "RUNASUSER"}
|
||||
var clusterColumns = []string{"NAME", "STATUS", "AGE"}
|
||||
var networkPolicyColumns = []string{"NAME", "POD-SELECTOR", "AGE"}
|
||||
var certificateSigningRequestColumns = []string{"NAME", "AGE", "REQUESTOR", "CONDITION"}
|
||||
// TODO: consider having 'KIND' for third party resource data
|
||||
thirdPartyResourceDataColumns = []string{"NAME", "LABELS", "DATA"}
|
||||
horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGET", "CURRENT", "MINPODS", "MAXPODS", "AGE"}
|
||||
withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too.
|
||||
deploymentColumns = []string{"NAME", "DESIRED", "CURRENT", "UP-TO-DATE", "AVAILABLE", "AGE"}
|
||||
configMapColumns = []string{"NAME", "DATA", "AGE"}
|
||||
podSecurityPolicyColumns = []string{"NAME", "PRIV", "CAPS", "VOLUMEPLUGINS", "SELINUX", "RUNASUSER"}
|
||||
clusterColumns = []string{"NAME", "STATUS", "AGE"}
|
||||
networkPolicyColumns = []string{"NAME", "POD-SELECTOR", "AGE"}
|
||||
certificateSigningRequestColumns = []string{"NAME", "AGE", "REQUESTOR", "CONDITION"}
|
||||
)
|
||||
|
||||
func (h *HumanReadablePrinter) printPod(pod *api.Pod, w io.Writer, options PrintOptions) error {
|
||||
reason := string(pod.Status.Phase)
|
||||
// if not printing all pods, skip terminated pods (default)
|
||||
if !options.ShowAll && (reason == string(api.PodSucceeded) || reason == string(api.PodFailed)) {
|
||||
h.hiddenObjNum++
|
||||
return nil
|
||||
}
|
||||
if err := printPodBase(pod, w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -512,13 +523,6 @@ func (h *HumanReadablePrinter) printPod(pod *api.Pod, w io.Writer, options Print
|
|||
|
||||
func (h *HumanReadablePrinter) printPodList(podList *api.PodList, w io.Writer, options PrintOptions) error {
|
||||
for _, pod := range podList.Items {
|
||||
reason := string(pod.Status.Phase)
|
||||
// if not printing all pods, skip terminated pods (default)
|
||||
if !options.ShowAll && (reason == string(api.PodSucceeded) || reason == string(api.PodFailed)) {
|
||||
h.hiddenObjNum++
|
||||
continue
|
||||
}
|
||||
|
||||
if err := printPodBase(&pod, w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -540,14 +544,14 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
|
|||
h.Handler(daemonSetColumns, printDaemonSetList)
|
||||
h.Handler(jobColumns, printJob)
|
||||
h.Handler(jobColumns, printJobList)
|
||||
h.Handler(scheduledJobColumns, printScheduledJob)
|
||||
h.Handler(scheduledJobColumns, printScheduledJobList)
|
||||
h.Handler(cronJobColumns, printCronJob)
|
||||
h.Handler(cronJobColumns, printCronJobList)
|
||||
h.Handler(serviceColumns, printService)
|
||||
h.Handler(serviceColumns, printServiceList)
|
||||
h.Handler(ingressColumns, printIngress)
|
||||
h.Handler(ingressColumns, printIngressList)
|
||||
h.Handler(petSetColumns, printPetSet)
|
||||
h.Handler(petSetColumns, printPetSetList)
|
||||
h.Handler(statefulSetColumns, printStatefulSet)
|
||||
h.Handler(statefulSetColumns, printStatefulSetList)
|
||||
h.Handler(endpointColumns, printEndpoints)
|
||||
h.Handler(endpointColumns, printEndpointsList)
|
||||
h.Handler(nodeColumns, printNode)
|
||||
|
|
@ -598,6 +602,7 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
|
|||
h.Handler(certificateSigningRequestColumns, printCertificateSigningRequestList)
|
||||
h.Handler(storageClassColumns, printStorageClass)
|
||||
h.Handler(storageClassColumns, printStorageClassList)
|
||||
h.Handler(statusColumns, printStatus)
|
||||
}
|
||||
|
||||
func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error {
|
||||
|
|
@ -736,7 +741,10 @@ func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
if pod.DeletionTimestamp != nil {
|
||||
|
||||
if pod.DeletionTimestamp != nil && pod.Status.Reason == node.NodeUnreachablePodReason {
|
||||
reason = "Unknown"
|
||||
} else if pod.DeletionTimestamp != nil {
|
||||
reason = "Terminating"
|
||||
}
|
||||
|
||||
|
|
@ -1020,9 +1028,9 @@ func printJobList(list *batch.JobList, w io.Writer, options PrintOptions) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func printScheduledJob(scheduledJob *batch.ScheduledJob, w io.Writer, options PrintOptions) error {
|
||||
name := scheduledJob.Name
|
||||
namespace := scheduledJob.Namespace
|
||||
func printCronJob(cronJob *batch.CronJob, w io.Writer, options PrintOptions) error {
|
||||
name := cronJob.Name
|
||||
namespace := cronJob.Namespace
|
||||
|
||||
if options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
|
||||
|
|
@ -1031,14 +1039,14 @@ func printScheduledJob(scheduledJob *batch.ScheduledJob, w io.Writer, options Pr
|
|||
}
|
||||
|
||||
lastScheduleTime := "<none>"
|
||||
if scheduledJob.Status.LastScheduleTime != nil {
|
||||
lastScheduleTime = scheduledJob.Status.LastScheduleTime.Time.Format(time.RFC1123Z)
|
||||
if cronJob.Status.LastScheduleTime != nil {
|
||||
lastScheduleTime = cronJob.Status.LastScheduleTime.Time.Format(time.RFC1123Z)
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\n",
|
||||
name,
|
||||
scheduledJob.Spec.Schedule,
|
||||
printBoolPtr(scheduledJob.Spec.Suspend),
|
||||
len(scheduledJob.Status.Active),
|
||||
cronJob.Spec.Schedule,
|
||||
printBoolPtr(cronJob.Spec.Suspend),
|
||||
len(cronJob.Status.Active),
|
||||
lastScheduleTime,
|
||||
); err != nil {
|
||||
return err
|
||||
|
|
@ -1047,9 +1055,9 @@ func printScheduledJob(scheduledJob *batch.ScheduledJob, w io.Writer, options Pr
|
|||
return nil
|
||||
}
|
||||
|
||||
func printScheduledJobList(list *batch.ScheduledJobList, w io.Writer, options PrintOptions) error {
|
||||
for _, scheduledJob := range list.Items {
|
||||
if err := printScheduledJob(&scheduledJob, w, options); err != nil {
|
||||
func printCronJobList(list *batch.CronJobList, w io.Writer, options PrintOptions) error {
|
||||
for _, cronJob := range list.Items {
|
||||
if err := printCronJob(&cronJob, w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -1108,6 +1116,9 @@ func makePortString(ports []api.ServicePort) string {
|
|||
for ix := range ports {
|
||||
port := &ports[ix]
|
||||
pieces[ix] = fmt.Sprintf("%d/%s", port.Port, port.Protocol)
|
||||
if port.NodePort > 0 {
|
||||
pieces[ix] = fmt.Sprintf("%d:%d/%s", port.Port, port.NodePort, port.Protocol)
|
||||
}
|
||||
}
|
||||
return strings.Join(pieces, ",")
|
||||
}
|
||||
|
|
@ -1231,7 +1242,7 @@ func printIngressList(ingressList *extensions.IngressList, w io.Writer, options
|
|||
return nil
|
||||
}
|
||||
|
||||
func printPetSet(ps *apps.PetSet, w io.Writer, options PrintOptions) error {
|
||||
func printStatefulSet(ps *apps.StatefulSet, w io.Writer, options PrintOptions) error {
|
||||
name := formatResourceName(options.Kind, ps.Name, options.WithKind)
|
||||
|
||||
namespace := ps.Namespace
|
||||
|
|
@ -1270,9 +1281,9 @@ func printPetSet(ps *apps.PetSet, w io.Writer, options PrintOptions) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func printPetSetList(petSetList *apps.PetSetList, w io.Writer, options PrintOptions) error {
|
||||
for _, ps := range petSetList.Items {
|
||||
if err := printPetSet(&ps, w, options); err != nil {
|
||||
func printStatefulSetList(statefulSetList *apps.StatefulSetList, w io.Writer, options PrintOptions) error {
|
||||
for _, ps := range statefulSetList.Items {
|
||||
if err := printStatefulSet(&ps, w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -1294,15 +1305,17 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options PrintOptions)
|
|||
|
||||
desiredScheduled := ds.Status.DesiredNumberScheduled
|
||||
currentScheduled := ds.Status.CurrentNumberScheduled
|
||||
numberReady := ds.Status.NumberReady
|
||||
selector, err := unversioned.LabelSelectorAsSelector(ds.Spec.Selector)
|
||||
if err != nil {
|
||||
// this shouldn't happen if LabelSelector passed validation
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%s\t%s",
|
||||
if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%s\t%s",
|
||||
name,
|
||||
desiredScheduled,
|
||||
currentScheduled,
|
||||
numberReady,
|
||||
labels.FormatLabels(ds.Spec.Template.Spec.NodeSelector),
|
||||
translateTimestamp(ds.CreationTimestamp),
|
||||
); err != nil {
|
||||
|
|
@ -1482,6 +1495,12 @@ func printNode(node *api.Node, w io.Writer, options PrintOptions) error {
|
|||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s", name, strings.Join(status, ","), translateTimestamp(node.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if options.Wide {
|
||||
if _, err := fmt.Fprintf(w, "\t%s", getNodeExternalIP(node)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Display caller specify column labels first.
|
||||
if _, err := fmt.Fprint(w, AppendLabels(node.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
|
|
@ -1490,6 +1509,17 @@ func printNode(node *api.Node, w io.Writer, options PrintOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Returns first external ip of the node or "<none>" if none is found.
|
||||
func getNodeExternalIP(node *api.Node) string {
|
||||
for _, address := range node.Status.Addresses {
|
||||
if address.Type == api.NodeExternalIP {
|
||||
return address.Address
|
||||
}
|
||||
}
|
||||
|
||||
return "<none>"
|
||||
}
|
||||
|
||||
func printNodeList(list *api.NodeList, w io.Writer, options PrintOptions) error {
|
||||
for _, node := range list.Items {
|
||||
if err := printNode(&node, w, options); err != nil {
|
||||
|
|
@ -1629,7 +1659,7 @@ func printEvent(event *api.Event, w io.Writer, options PrintOptions) error {
|
|||
|
||||
// Sorts and prints the EventList in a human-friendly format.
|
||||
func printEventList(list *api.EventList, w io.Writer, options PrintOptions) error {
|
||||
sort.Sort(SortableEvents(list.Items))
|
||||
sort.Sort(events.SortableEvents(list.Items))
|
||||
for i := range list.Items {
|
||||
if err := printEvent(&list.Items[i], w, options); err != nil {
|
||||
return err
|
||||
|
|
@ -2071,6 +2101,10 @@ func printNetworkPolicyList(list *extensions.NetworkPolicyList, w io.Writer, opt
|
|||
|
||||
func printStorageClass(sc *storage.StorageClass, w io.Writer, options PrintOptions) error {
|
||||
name := sc.Name
|
||||
|
||||
if storageutil.IsDefaultAnnotation(sc.ObjectMeta) {
|
||||
name += " (default)"
|
||||
}
|
||||
provtype := sc.Provisioner
|
||||
|
||||
if _, err := fmt.Fprintf(w, "%s\t%s\t", name, provtype); err != nil {
|
||||
|
|
@ -2095,6 +2129,14 @@ func printStorageClassList(scList *storage.StorageClassList, w io.Writer, option
|
|||
return nil
|
||||
}
|
||||
|
||||
func printStatus(status *unversioned.Status, w io.Writer, options PrintOptions) error {
|
||||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\n", status.Status, status.Reason, status.Message); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func AppendLabels(itemLabels map[string]string, columnLabels []string) string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
|
|
@ -2187,6 +2229,9 @@ func formatWideHeaders(wide bool, t reflect.Type) []string {
|
|||
if t.String() == "*extensions.ReplicaSet" || t.String() == "*extensions.ReplicaSetList" {
|
||||
return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
|
||||
}
|
||||
if t.String() == "*api.Node" || t.String() == "*api.NodeList" {
|
||||
return []string{"EXTERNAL-IP"}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -2214,6 +2259,18 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||
w = GetNewTabWriter(output)
|
||||
defer w.Flush()
|
||||
}
|
||||
|
||||
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before
|
||||
// trying to print, since the printers are keyed by type. This is extremely expensive.
|
||||
switch obj.(type) {
|
||||
case *runtime.Unstructured, *runtime.Unknown:
|
||||
if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil {
|
||||
if decodedObj, err := runtime.Decode(api.Codecs.UniversalDecoder(), objBytes); err == nil {
|
||||
obj = decodedObj
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(obj)
|
||||
if handler := h.handlerMap[t]; handler != nil {
|
||||
if !h.options.NoHeaders && t != h.lastType {
|
||||
|
|
@ -2234,9 +2291,78 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||
}
|
||||
return resultValue.Interface().(error)
|
||||
}
|
||||
|
||||
// we don't recognize this type, but we can still attempt to print some reasonable information about.
|
||||
unstructured, ok := obj.(*runtime.Unstructured)
|
||||
if !ok {
|
||||
return fmt.Errorf("error: unknown type %#v", obj)
|
||||
}
|
||||
|
||||
if _, err := meta.Accessor(obj); err == nil {
|
||||
if !h.options.NoHeaders && t != h.lastType {
|
||||
headers := []string{"NAME", "KIND"}
|
||||
headers = append(headers, formatLabelHeaders(h.options.ColumnLabels)...)
|
||||
// LABELS is always the last column.
|
||||
headers = append(headers, formatShowLabelsHeader(h.options.ShowLabels, t)...)
|
||||
if h.options.WithNamespace {
|
||||
headers = append(withNamespacePrefixColumns, headers...)
|
||||
}
|
||||
h.printHeader(headers, w)
|
||||
h.lastType = t
|
||||
}
|
||||
// if the error isn't nil, report the "I don't recognize this" error
|
||||
if err := printUnstructured(unstructured, w, h.options); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// we failed all reasonable printing efforts, report failure
|
||||
return fmt.Errorf("error: unknown type %#v", obj)
|
||||
}
|
||||
|
||||
func printUnstructured(unstructured *runtime.Unstructured, w io.Writer, options PrintOptions) error {
|
||||
metadata, err := meta.Accessor(unstructured)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", metadata.GetNamespace()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
kind := "<missing>"
|
||||
if objKind, ok := unstructured.Object["kind"]; ok {
|
||||
if str, ok := objKind.(string); ok {
|
||||
kind = str
|
||||
}
|
||||
}
|
||||
if objAPIVersion, ok := unstructured.Object["apiVersion"]; ok {
|
||||
if str, ok := objAPIVersion.(string); ok {
|
||||
version, err := unversioned.ParseGroupVersion(str)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
kind = kind + "." + version.Version + "." + version.Group
|
||||
}
|
||||
}
|
||||
name := formatResourceName(options.Kind, metadata.GetName(), options.WithKind)
|
||||
|
||||
if _, err := fmt.Fprintf(w, "%s\t%s", name, kind); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, AppendLabels(metadata.GetLabels(), options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, metadata.GetLabels())); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TemplatePrinter is an implementation of ResourcePrinter which formats data with a Go Template.
|
||||
type TemplatePrinter struct {
|
||||
rawTemplate string
|
||||
|
|
@ -2256,16 +2382,24 @@ func NewTemplatePrinter(tmpl []byte) (*TemplatePrinter, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (p *TemplatePrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (p *TemplatePrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrintObj formats the obj with the Go Template.
|
||||
func (p *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
data, err := json.Marshal(obj)
|
||||
var data []byte
|
||||
var err error
|
||||
if unstructured, ok := obj.(*runtime.Unstructured); ok {
|
||||
data, err = json.Marshal(unstructured.Object)
|
||||
} else {
|
||||
data, err = json.Marshal(obj)
|
||||
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out := map[string]interface{}{}
|
||||
if err := json.Unmarshal(data, &out); err != nil {
|
||||
return err
|
||||
|
|
@ -2407,7 +2541,7 @@ func NewJSONPathPrinter(tmpl string) (*JSONPathPrinter, error) {
|
|||
return &JSONPathPrinter{tmpl, j}, nil
|
||||
}
|
||||
|
||||
func (j *JSONPathPrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (j *JSONPathPrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -2425,6 +2559,20 @@ func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
|||
}
|
||||
}
|
||||
|
||||
if unknown, ok := obj.(*runtime.Unknown); ok {
|
||||
data, err := json.Marshal(unknown)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryObj = map[string]interface{}{}
|
||||
if err := json.Unmarshal(data, &queryObj); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if unstructured, ok := obj.(*runtime.Unstructured); ok {
|
||||
queryObj = unstructured.Object
|
||||
}
|
||||
|
||||
if err := j.JSONPath.Execute(w, queryObj); err != nil {
|
||||
fmt.Fprintf(w, "Error executing template: %v. Printing more information for debugging the template:\n", err)
|
||||
fmt.Fprintf(w, "\ttemplate was:\n\t\t%v\n", j.rawTemplate)
|
||||
|
|
|
|||
66
vendor/k8s.io/kubernetes/pkg/kubectl/rollback.go
generated
vendored
66
vendor/k8s.io/kubernetes/pkg/kubectl/rollback.go
generated
vendored
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package kubectl
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
|
@ -25,18 +26,19 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
sliceutil "k8s.io/kubernetes/pkg/util/slice"
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// Rollbacker provides an interface for resources that can be rolled back.
|
||||
type Rollbacker interface {
|
||||
Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64) (string, error)
|
||||
Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64, dryRun bool) (string, error)
|
||||
}
|
||||
|
||||
func RollbackerFor(kind unversioned.GroupKind, c client.Interface) (Rollbacker, error) {
|
||||
func RollbackerFor(kind unversioned.GroupKind, c clientset.Interface) (Rollbacker, error) {
|
||||
switch kind {
|
||||
case extensions.Kind("Deployment"):
|
||||
return &DeploymentRollbacker{c}, nil
|
||||
|
|
@ -45,14 +47,17 @@ func RollbackerFor(kind unversioned.GroupKind, c client.Interface) (Rollbacker,
|
|||
}
|
||||
|
||||
type DeploymentRollbacker struct {
|
||||
c client.Interface
|
||||
c clientset.Interface
|
||||
}
|
||||
|
||||
func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64) (string, error) {
|
||||
func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations map[string]string, toRevision int64, dryRun bool) (string, error) {
|
||||
d, ok := obj.(*extensions.Deployment)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("passed object is not a Deployment: %#v", obj)
|
||||
}
|
||||
if dryRun {
|
||||
return simpleDryRun(d, r.c, toRevision)
|
||||
}
|
||||
if d.Spec.Paused {
|
||||
return "", fmt.Errorf("you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume deployment/%s' and try again", d.Name)
|
||||
}
|
||||
|
|
@ -66,7 +71,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
|
|||
result := ""
|
||||
|
||||
// Get current events
|
||||
events, err := r.c.Events(d.Namespace).List(api.ListOptions{})
|
||||
events, err := r.c.Core().Events(d.Namespace).List(api.ListOptions{})
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
|
@ -75,7 +80,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
|
|||
return result, err
|
||||
}
|
||||
// Watch for the changes of events
|
||||
watch, err := r.c.Events(d.Namespace).Watch(api.ListOptions{Watch: true, ResourceVersion: events.ResourceVersion})
|
||||
watch, err := r.c.Core().Events(d.Namespace).Watch(api.ListOptions{Watch: true, ResourceVersion: events.ResourceVersion})
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
|
@ -123,3 +128,50 @@ func isRollbackEvent(e *api.Event) (bool, string) {
|
|||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func simpleDryRun(deployment *extensions.Deployment, c clientset.Interface, toRevision int64) (string, error) {
|
||||
_, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(deployment, c)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to retrieve replica sets from deployment %s: %v", deployment.Name, err)
|
||||
}
|
||||
allRSs := allOldRSs
|
||||
if newRS != nil {
|
||||
allRSs = append(allRSs, newRS)
|
||||
}
|
||||
|
||||
revisionToSpec := make(map[int64]*api.PodTemplateSpec)
|
||||
for _, rs := range allRSs {
|
||||
v, err := deploymentutil.Revision(rs)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
revisionToSpec[v] = &rs.Spec.Template
|
||||
}
|
||||
|
||||
if len(revisionToSpec) == 0 {
|
||||
return "No rollout history found.", nil
|
||||
}
|
||||
|
||||
if toRevision > 0 {
|
||||
template, ok := revisionToSpec[toRevision]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("unable to find specified revision")
|
||||
}
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
DescribePodTemplate(template, buf)
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
||||
// Sort the revisionToSpec map by revision
|
||||
revisions := make([]int64, 0, len(revisionToSpec))
|
||||
for r := range revisionToSpec {
|
||||
revisions = append(revisions, r)
|
||||
}
|
||||
sliceutil.SortInts64(revisions)
|
||||
|
||||
template, _ := revisionToSpec[revisions[len(revisions)-1]]
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
buf.WriteString("\n")
|
||||
DescribePodTemplate(template, buf)
|
||||
return buf.String(), nil
|
||||
}
|
||||
|
|
|
|||
90
vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go
generated
vendored
90
vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go
generated
vendored
|
|
@ -27,6 +27,8 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/client/retry"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
|
|
@ -109,8 +111,8 @@ const (
|
|||
// RollingUpdater provides methods for updating replicated pods in a predictable,
|
||||
// fault-tolerant way.
|
||||
type RollingUpdater struct {
|
||||
// Client interface for creating and updating controllers
|
||||
c client.Interface
|
||||
rcClient coreclient.ReplicationControllersGetter
|
||||
podClient coreclient.PodsGetter
|
||||
// Namespace for resources
|
||||
ns string
|
||||
// scaleAndWait scales a controller and returns its updated state.
|
||||
|
|
@ -127,10 +129,11 @@ type RollingUpdater struct {
|
|||
}
|
||||
|
||||
// NewRollingUpdater creates a RollingUpdater from a client.
|
||||
func NewRollingUpdater(namespace string, client client.Interface) *RollingUpdater {
|
||||
func NewRollingUpdater(namespace string, rcClient coreclient.ReplicationControllersGetter, podClient coreclient.PodsGetter) *RollingUpdater {
|
||||
updater := &RollingUpdater{
|
||||
c: client,
|
||||
ns: namespace,
|
||||
rcClient: rcClient,
|
||||
podClient: podClient,
|
||||
ns: namespace,
|
||||
}
|
||||
// Inject real implementations.
|
||||
updater.scaleAndWait = updater.scaleAndWaitWithScaler
|
||||
|
|
@ -189,7 +192,7 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
|
|||
// annotation if it doesn't yet exist.
|
||||
_, hasOriginalAnnotation := oldRc.Annotations[originalReplicasAnnotation]
|
||||
if !hasOriginalAnnotation {
|
||||
existing, err := r.c.ReplicationControllers(oldRc.Namespace).Get(oldRc.Name)
|
||||
existing, err := r.rcClient.ReplicationControllers(oldRc.Namespace).Get(oldRc.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -200,7 +203,7 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
|
|||
}
|
||||
rc.Annotations[originalReplicasAnnotation] = originReplicas
|
||||
}
|
||||
if oldRc, err = updateRcWithRetries(r.c, existing.Namespace, existing, applyUpdate); err != nil {
|
||||
if oldRc, err = updateRcWithRetries(r.rcClient, existing.Namespace, existing, applyUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -390,14 +393,11 @@ func (r *RollingUpdater) scaleDown(newRc, oldRc *api.ReplicationController, desi
|
|||
|
||||
// scalerScaleAndWait scales a controller using a Scaler and a real client.
|
||||
func (r *RollingUpdater) scaleAndWaitWithScaler(rc *api.ReplicationController, retry *RetryParams, wait *RetryParams) (*api.ReplicationController, error) {
|
||||
scaler, err := ScalerFor(api.Kind("ReplicationController"), r.c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't make scaler: %s", err)
|
||||
}
|
||||
scaler := &ReplicationControllerScaler{r.rcClient}
|
||||
if err := scaler.Scale(rc.Namespace, rc.Name, uint(rc.Spec.Replicas), &ScalePrecondition{-1, ""}, retry, wait); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return r.c.ReplicationControllers(rc.Namespace).Get(rc.Name)
|
||||
return r.rcClient.ReplicationControllers(rc.Namespace).Get(rc.Name)
|
||||
}
|
||||
|
||||
// readyPods returns the old and new ready counts for their pods.
|
||||
|
|
@ -415,7 +415,7 @@ func (r *RollingUpdater) readyPods(oldRc, newRc *api.ReplicationController, minR
|
|||
controller := controllers[i]
|
||||
selector := labels.Set(controller.Spec.Selector).AsSelector()
|
||||
options := api.ListOptions{LabelSelector: selector}
|
||||
pods, err := r.c.Pods(controller.Namespace).List(options)
|
||||
pods, err := r.podClient.Pods(controller.Namespace).List(options)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
|
@ -460,7 +460,7 @@ func (r *RollingUpdater) getOrCreateTargetControllerWithClient(controller *api.R
|
|||
controller.Annotations[desiredReplicasAnnotation] = fmt.Sprintf("%d", controller.Spec.Replicas)
|
||||
controller.Annotations[sourceIdAnnotation] = sourceId
|
||||
controller.Spec.Replicas = 0
|
||||
newRc, err := r.c.ReplicationControllers(r.ns).Create(controller)
|
||||
newRc, err := r.rcClient.ReplicationControllers(r.ns).Create(controller)
|
||||
return newRc, false, err
|
||||
}
|
||||
// Validate and use the existing controller.
|
||||
|
|
@ -480,7 +480,7 @@ func (r *RollingUpdater) existingController(controller *api.ReplicationControlle
|
|||
return nil, errors.NewNotFound(api.Resource("replicationcontrollers"), controller.Name)
|
||||
}
|
||||
// controller name is required to get rc back
|
||||
return r.c.ReplicationControllers(controller.Namespace).Get(controller.Name)
|
||||
return r.rcClient.ReplicationControllers(controller.Namespace).Get(controller.Name)
|
||||
}
|
||||
|
||||
// cleanupWithClients performs cleanup tasks after the rolling update. Update
|
||||
|
|
@ -489,7 +489,7 @@ func (r *RollingUpdater) existingController(controller *api.ReplicationControlle
|
|||
func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *api.ReplicationController, config *RollingUpdaterConfig) error {
|
||||
// Clean up annotations
|
||||
var err error
|
||||
newRc, err = r.c.ReplicationControllers(r.ns).Get(newRc.Name)
|
||||
newRc, err = r.rcClient.ReplicationControllers(r.ns).Get(newRc.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -497,14 +497,14 @@ func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *api.ReplicationControl
|
|||
delete(rc.Annotations, sourceIdAnnotation)
|
||||
delete(rc.Annotations, desiredReplicasAnnotation)
|
||||
}
|
||||
if newRc, err = updateRcWithRetries(r.c, r.ns, newRc, applyUpdate); err != nil {
|
||||
if newRc, err = updateRcWithRetries(r.rcClient, r.ns, newRc, applyUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = wait.Poll(config.Interval, config.Timeout, client.ControllerHasDesiredReplicas(r.c, newRc)); err != nil {
|
||||
if err = wait.Poll(config.Interval, config.Timeout, client.ControllerHasDesiredReplicas(r.rcClient, newRc)); err != nil {
|
||||
return err
|
||||
}
|
||||
newRc, err = r.c.ReplicationControllers(r.ns).Get(newRc.Name)
|
||||
newRc, err = r.rcClient.ReplicationControllers(r.ns).Get(newRc.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -513,15 +513,15 @@ func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *api.ReplicationControl
|
|||
case DeleteRollingUpdateCleanupPolicy:
|
||||
// delete old rc
|
||||
fmt.Fprintf(config.Out, "Update succeeded. Deleting %s\n", oldRc.Name)
|
||||
return r.c.ReplicationControllers(r.ns).Delete(oldRc.Name, nil)
|
||||
return r.rcClient.ReplicationControllers(r.ns).Delete(oldRc.Name, nil)
|
||||
case RenameRollingUpdateCleanupPolicy:
|
||||
// delete old rc
|
||||
fmt.Fprintf(config.Out, "Update succeeded. Deleting old controller: %s\n", oldRc.Name)
|
||||
if err := r.c.ReplicationControllers(r.ns).Delete(oldRc.Name, nil); err != nil {
|
||||
if err := r.rcClient.ReplicationControllers(r.ns).Delete(oldRc.Name, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(config.Out, "Renaming %s to %s\n", oldRc.Name, newRc.Name)
|
||||
return Rename(r.c, newRc, oldRc.Name)
|
||||
return Rename(r.rcClient, newRc, oldRc.Name)
|
||||
case PreserveRollingUpdateCleanupPolicy:
|
||||
return nil
|
||||
default:
|
||||
|
|
@ -529,7 +529,7 @@ func (r *RollingUpdater) cleanupWithClients(oldRc, newRc *api.ReplicationControl
|
|||
}
|
||||
}
|
||||
|
||||
func Rename(c client.ReplicationControllersNamespacer, rc *api.ReplicationController, newName string) error {
|
||||
func Rename(c coreclient.ReplicationControllersGetter, rc *api.ReplicationController, newName string) error {
|
||||
oldName := rc.Name
|
||||
rc.Name = newName
|
||||
rc.ResourceVersion = ""
|
||||
|
|
@ -560,7 +560,7 @@ func Rename(c client.ReplicationControllersNamespacer, rc *api.ReplicationContro
|
|||
return nil
|
||||
}
|
||||
|
||||
func LoadExistingNextReplicationController(c client.ReplicationControllersNamespacer, namespace, newName string) (*api.ReplicationController, error) {
|
||||
func LoadExistingNextReplicationController(c coreclient.ReplicationControllersGetter, namespace, newName string) (*api.ReplicationController, error) {
|
||||
if len(newName) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -580,10 +580,10 @@ type NewControllerConfig struct {
|
|||
PullPolicy api.PullPolicy
|
||||
}
|
||||
|
||||
func CreateNewControllerFromCurrentController(c client.Interface, codec runtime.Codec, cfg *NewControllerConfig) (*api.ReplicationController, error) {
|
||||
func CreateNewControllerFromCurrentController(rcClient coreclient.ReplicationControllersGetter, codec runtime.Codec, cfg *NewControllerConfig) (*api.ReplicationController, error) {
|
||||
containerIndex := 0
|
||||
// load the old RC into the "new" RC
|
||||
newRc, err := c.ReplicationControllers(cfg.Namespace).Get(cfg.OldName)
|
||||
newRc, err := rcClient.ReplicationControllers(cfg.Namespace).Get(cfg.OldName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -669,21 +669,21 @@ func SetNextControllerAnnotation(rc *api.ReplicationController, name string) {
|
|||
rc.Annotations[nextControllerAnnotation] = name
|
||||
}
|
||||
|
||||
func UpdateExistingReplicationController(c client.Interface, oldRc *api.ReplicationController, namespace, newName, deploymentKey, deploymentValue string, out io.Writer) (*api.ReplicationController, error) {
|
||||
func UpdateExistingReplicationController(rcClient coreclient.ReplicationControllersGetter, podClient coreclient.PodsGetter, oldRc *api.ReplicationController, namespace, newName, deploymentKey, deploymentValue string, out io.Writer) (*api.ReplicationController, error) {
|
||||
if _, found := oldRc.Spec.Selector[deploymentKey]; !found {
|
||||
SetNextControllerAnnotation(oldRc, newName)
|
||||
return AddDeploymentKeyToReplicationController(oldRc, c, deploymentKey, deploymentValue, namespace, out)
|
||||
return AddDeploymentKeyToReplicationController(oldRc, rcClient, podClient, deploymentKey, deploymentValue, namespace, out)
|
||||
} else {
|
||||
// If we didn't need to update the controller for the deployment key, we still need to write
|
||||
// the "next" controller.
|
||||
applyUpdate := func(rc *api.ReplicationController) {
|
||||
SetNextControllerAnnotation(rc, newName)
|
||||
}
|
||||
return updateRcWithRetries(c, namespace, oldRc, applyUpdate)
|
||||
return updateRcWithRetries(rcClient, namespace, oldRc, applyUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, client client.Interface, deploymentKey, deploymentValue, namespace string, out io.Writer) (*api.ReplicationController, error) {
|
||||
func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, rcClient coreclient.ReplicationControllersGetter, podClient coreclient.PodsGetter, deploymentKey, deploymentValue, namespace string, out io.Writer) (*api.ReplicationController, error) {
|
||||
var err error
|
||||
// First, update the template label. This ensures that any newly created pods will have the new label
|
||||
applyUpdate := func(rc *api.ReplicationController) {
|
||||
|
|
@ -692,7 +692,7 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
|
|||
}
|
||||
rc.Spec.Template.Labels[deploymentKey] = deploymentValue
|
||||
}
|
||||
if oldRc, err = updateRcWithRetries(client, namespace, oldRc, applyUpdate); err != nil {
|
||||
if oldRc, err = updateRcWithRetries(rcClient, namespace, oldRc, applyUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -700,7 +700,7 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
|
|||
// TODO: extract the code from the label command and re-use it here.
|
||||
selector := labels.SelectorFromSet(oldRc.Spec.Selector)
|
||||
options := api.ListOptions{LabelSelector: selector}
|
||||
podList, err := client.Pods(namespace).List(options)
|
||||
podList, err := podClient.Pods(namespace).List(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -715,7 +715,7 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
|
|||
p.Labels[deploymentKey] = deploymentValue
|
||||
}
|
||||
}
|
||||
if pod, err = updatePodWithRetries(client, namespace, pod, applyUpdate); err != nil {
|
||||
if pod, err = updatePodWithRetries(podClient, namespace, pod, applyUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -732,7 +732,7 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
|
|||
rc.Spec.Selector[deploymentKey] = deploymentValue
|
||||
}
|
||||
// Update the selector of the rc so it manages all the pods we updated above
|
||||
if oldRc, err = updateRcWithRetries(client, namespace, oldRc, applyUpdate); err != nil {
|
||||
if oldRc, err = updateRcWithRetries(rcClient, namespace, oldRc, applyUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -741,11 +741,11 @@ func AddDeploymentKeyToReplicationController(oldRc *api.ReplicationController, c
|
|||
// we've finished re-adopting existing pods to the rc.
|
||||
selector = labels.SelectorFromSet(selectorCopy)
|
||||
options = api.ListOptions{LabelSelector: selector}
|
||||
podList, err = client.Pods(namespace).List(options)
|
||||
podList, err = podClient.Pods(namespace).List(options)
|
||||
for ix := range podList.Items {
|
||||
pod := &podList.Items[ix]
|
||||
if value, found := pod.Labels[deploymentKey]; !found || value != deploymentValue {
|
||||
if err := client.Pods(namespace).Delete(pod.Name, nil); err != nil {
|
||||
if err := podClient.Pods(namespace).Delete(pod.Name, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -760,24 +760,24 @@ type updateRcFunc func(controller *api.ReplicationController)
|
|||
// 1. Get latest resource
|
||||
// 2. applyUpdate
|
||||
// 3. Update the resource
|
||||
func updateRcWithRetries(c client.Interface, namespace string, rc *api.ReplicationController, applyUpdate updateRcFunc) (*api.ReplicationController, error) {
|
||||
func updateRcWithRetries(rcClient coreclient.ReplicationControllersGetter, namespace string, rc *api.ReplicationController, applyUpdate updateRcFunc) (*api.ReplicationController, error) {
|
||||
// Deep copy the rc in case we failed on Get during retry loop
|
||||
obj, err := api.Scheme.Copy(rc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to deep copy rc before updating it: %v", err)
|
||||
}
|
||||
oldRc := obj.(*api.ReplicationController)
|
||||
err = client.RetryOnConflict(client.DefaultBackoff, func() (e error) {
|
||||
err = retry.RetryOnConflict(retry.DefaultBackoff, func() (e error) {
|
||||
// Apply the update, then attempt to push it to the apiserver.
|
||||
applyUpdate(rc)
|
||||
if rc, e = c.ReplicationControllers(namespace).Update(rc); e == nil {
|
||||
if rc, e = rcClient.ReplicationControllers(namespace).Update(rc); e == nil {
|
||||
// rc contains the latest controller post update
|
||||
return
|
||||
}
|
||||
updateErr := e
|
||||
// Update the controller with the latest resource version, if the update failed we
|
||||
// can't trust rc so use oldRc.Name.
|
||||
if rc, e = c.ReplicationControllers(namespace).Get(oldRc.Name); e != nil {
|
||||
if rc, e = rcClient.ReplicationControllers(namespace).Get(oldRc.Name); e != nil {
|
||||
// The Get failed: Value in rc cannot be trusted.
|
||||
rc = oldRc
|
||||
}
|
||||
|
|
@ -795,21 +795,21 @@ type updatePodFunc func(controller *api.Pod)
|
|||
// 1. Get latest resource
|
||||
// 2. applyUpdate
|
||||
// 3. Update the resource
|
||||
func updatePodWithRetries(c client.Interface, namespace string, pod *api.Pod, applyUpdate updatePodFunc) (*api.Pod, error) {
|
||||
func updatePodWithRetries(podClient coreclient.PodsGetter, namespace string, pod *api.Pod, applyUpdate updatePodFunc) (*api.Pod, error) {
|
||||
// Deep copy the pod in case we failed on Get during retry loop
|
||||
obj, err := api.Scheme.Copy(pod)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to deep copy pod before updating it: %v", err)
|
||||
}
|
||||
oldPod := obj.(*api.Pod)
|
||||
err = client.RetryOnConflict(client.DefaultBackoff, func() (e error) {
|
||||
err = retry.RetryOnConflict(retry.DefaultBackoff, func() (e error) {
|
||||
// Apply the update, then attempt to push it to the apiserver.
|
||||
applyUpdate(pod)
|
||||
if pod, e = c.Pods(namespace).Update(pod); e == nil {
|
||||
if pod, e = podClient.Pods(namespace).Update(pod); e == nil {
|
||||
return
|
||||
}
|
||||
updateErr := e
|
||||
if pod, e = c.Pods(namespace).Get(oldPod.Name); e != nil {
|
||||
if pod, e = podClient.Pods(namespace).Get(oldPod.Name); e != nil {
|
||||
pod = oldPod
|
||||
}
|
||||
// Only return the error from update
|
||||
|
|
@ -820,7 +820,7 @@ func updatePodWithRetries(c client.Interface, namespace string, pod *api.Pod, ap
|
|||
return pod, err
|
||||
}
|
||||
|
||||
func FindSourceController(r client.ReplicationControllersNamespacer, namespace, name string) (*api.ReplicationController, error) {
|
||||
func FindSourceController(r coreclient.ReplicationControllersGetter, namespace, name string) (*api.ReplicationController, error) {
|
||||
list, err := r.ReplicationControllers(namespace).List(api.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
41
vendor/k8s.io/kubernetes/pkg/kubectl/rollout_status.go
generated
vendored
41
vendor/k8s.io/kubernetes/pkg/kubectl/rollout_status.go
generated
vendored
|
|
@ -21,15 +21,17 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion"
|
||||
"k8s.io/kubernetes/pkg/controller/deployment/util"
|
||||
)
|
||||
|
||||
// StatusViewer provides an interface for resources that provides rollout status.
|
||||
// StatusViewer provides an interface for resources that have rollout status.
|
||||
type StatusViewer interface {
|
||||
Status(namespace, name string) (string, bool, error)
|
||||
Status(namespace, name string, revision int64) (string, bool, error)
|
||||
}
|
||||
|
||||
func StatusViewerFor(kind unversioned.GroupKind, c client.Interface) (StatusViewer, error) {
|
||||
func StatusViewerFor(kind unversioned.GroupKind, c internalclientset.Interface) (StatusViewer, error) {
|
||||
switch kind {
|
||||
case extensions.Kind("Deployment"):
|
||||
return &DeploymentStatusViewer{c.Extensions()}, nil
|
||||
|
|
@ -38,20 +40,39 @@ func StatusViewerFor(kind unversioned.GroupKind, c client.Interface) (StatusView
|
|||
}
|
||||
|
||||
type DeploymentStatusViewer struct {
|
||||
c client.ExtensionsInterface
|
||||
c extensionsclient.DeploymentsGetter
|
||||
}
|
||||
|
||||
// Status returns a message describing deployment status, and a bool value indicating if the status is considered done
|
||||
func (s *DeploymentStatusViewer) Status(namespace, name string) (string, bool, error) {
|
||||
func (s *DeploymentStatusViewer) Status(namespace, name string, revision int64) (string, bool, error) {
|
||||
deployment, err := s.c.Deployments(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
if deployment.Generation <= deployment.Status.ObservedGeneration {
|
||||
if deployment.Status.UpdatedReplicas == deployment.Spec.Replicas {
|
||||
return fmt.Sprintf("deployment %s successfully rolled out\n", name), true, nil
|
||||
if revision > 0 {
|
||||
deploymentRev, err := util.Revision(deployment)
|
||||
if err != nil {
|
||||
return "", false, fmt.Errorf("cannot get the revision of deployment %q: %v", deployment.Name, err)
|
||||
}
|
||||
return fmt.Sprintf("Waiting for rollout to finish: %d out of %d new replicas have been updated...\n", deployment.Status.UpdatedReplicas, deployment.Spec.Replicas), false, nil
|
||||
if revision != deploymentRev {
|
||||
return "", false, fmt.Errorf("desired revision (%d) is different from the running revision (%d)", revision, deploymentRev)
|
||||
}
|
||||
}
|
||||
if deployment.Generation <= deployment.Status.ObservedGeneration {
|
||||
cond := util.GetDeploymentCondition(deployment.Status, extensions.DeploymentProgressing)
|
||||
if cond != nil && cond.Reason == util.TimedOutReason {
|
||||
return "", false, fmt.Errorf("deployment %q exceeded its progress deadline", name)
|
||||
}
|
||||
if deployment.Status.UpdatedReplicas < deployment.Spec.Replicas {
|
||||
return fmt.Sprintf("Waiting for rollout to finish: %d out of %d new replicas have been updated...\n", deployment.Status.UpdatedReplicas, deployment.Spec.Replicas), false, nil
|
||||
}
|
||||
if deployment.Status.Replicas > deployment.Status.UpdatedReplicas {
|
||||
return fmt.Sprintf("Waiting for rollout to finish: %d old replicas are pending termination...\n", deployment.Status.Replicas-deployment.Status.UpdatedReplicas), false, nil
|
||||
}
|
||||
if deployment.Status.AvailableReplicas < deployment.Status.UpdatedReplicas {
|
||||
return fmt.Sprintf("Waiting for rollout to finish: %d of %d updated replicas are available...\n", deployment.Status.AvailableReplicas, deployment.Status.UpdatedReplicas), false, nil
|
||||
}
|
||||
return fmt.Sprintf("deployment %q successfully rolled out\n", name), true, nil
|
||||
}
|
||||
return fmt.Sprintf("Waiting for deployment spec update to be observed...\n"), false, nil
|
||||
}
|
||||
|
|
|
|||
16
vendor/k8s.io/kubernetes/pkg/kubectl/run.go
generated
vendored
16
vendor/k8s.io/kubernetes/pkg/kubectl/run.go
generated
vendored
|
|
@ -401,9 +401,9 @@ func (JobV1) Generate(genericParams map[string]interface{}) (runtime.Object, err
|
|||
return &job, nil
|
||||
}
|
||||
|
||||
type ScheduledJobV2Alpha1 struct{}
|
||||
type CronJobV2Alpha1 struct{}
|
||||
|
||||
func (ScheduledJobV2Alpha1) ParamNames() []GeneratorParam {
|
||||
func (CronJobV2Alpha1) ParamNames() []GeneratorParam {
|
||||
return []GeneratorParam{
|
||||
{"labels", false},
|
||||
{"default-name", false},
|
||||
|
|
@ -425,7 +425,7 @@ func (ScheduledJobV2Alpha1) ParamNames() []GeneratorParam {
|
|||
}
|
||||
}
|
||||
|
||||
func (ScheduledJobV2Alpha1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
func (CronJobV2Alpha1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
args, err := getArgs(genericParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -477,12 +477,12 @@ func (ScheduledJobV2Alpha1) Generate(genericParams map[string]interface{}) (runt
|
|||
}
|
||||
podSpec.RestartPolicy = restartPolicy
|
||||
|
||||
scheduledJob := batchv2alpha1.ScheduledJob{
|
||||
cronJob := batchv2alpha1.CronJob{
|
||||
ObjectMeta: v1.ObjectMeta{
|
||||
Name: name,
|
||||
Labels: labels,
|
||||
},
|
||||
Spec: batchv2alpha1.ScheduledJobSpec{
|
||||
Spec: batchv2alpha1.CronJobSpec{
|
||||
Schedule: params["schedule"],
|
||||
ConcurrencyPolicy: batchv2alpha1.AllowConcurrent,
|
||||
JobTemplate: batchv2alpha1.JobTemplateSpec{
|
||||
|
|
@ -498,7 +498,7 @@ func (ScheduledJobV2Alpha1) Generate(genericParams map[string]interface{}) (runt
|
|||
},
|
||||
}
|
||||
|
||||
return &scheduledJob, nil
|
||||
return &cronJob, nil
|
||||
}
|
||||
|
||||
type BasicReplicationController struct{}
|
||||
|
|
@ -796,7 +796,7 @@ func updatePodPorts(params map[string]string, podSpec *api.PodSpec) (err error)
|
|||
}
|
||||
|
||||
// Don't include the port if it was not specified.
|
||||
if port > 0 {
|
||||
if len(params["port"]) > 0 {
|
||||
podSpec.Containers[0].Ports = []api.ContainerPort{
|
||||
{
|
||||
ContainerPort: int32(port),
|
||||
|
|
@ -830,7 +830,7 @@ func updateV1PodPorts(params map[string]string, podSpec *v1.PodSpec) (err error)
|
|||
}
|
||||
|
||||
// Don't include the port if it was not specified.
|
||||
if port > 0 {
|
||||
if len(params["port"]) > 0 {
|
||||
podSpec.Containers[0].Ports = []v1.ContainerPort{
|
||||
{
|
||||
ContainerPort: int32(port),
|
||||
|
|
|
|||
49
vendor/k8s.io/kubernetes/pkg/kubectl/scale.go
generated
vendored
49
vendor/k8s.io/kubernetes/pkg/kubectl/scale.go
generated
vendored
|
|
@ -27,6 +27,11 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
appsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion"
|
||||
batchclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/internalversion"
|
||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
|
|
@ -44,16 +49,16 @@ type Scaler interface {
|
|||
ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) (updatedResourceVersion string, err error)
|
||||
}
|
||||
|
||||
func ScalerFor(kind unversioned.GroupKind, c client.Interface) (Scaler, error) {
|
||||
func ScalerFor(kind unversioned.GroupKind, c internalclientset.Interface) (Scaler, error) {
|
||||
switch kind {
|
||||
case api.Kind("ReplicationController"):
|
||||
return &ReplicationControllerScaler{c}, nil
|
||||
return &ReplicationControllerScaler{c.Core()}, nil
|
||||
case extensions.Kind("ReplicaSet"):
|
||||
return &ReplicaSetScaler{c.Extensions()}, nil
|
||||
case extensions.Kind("Job"), batch.Kind("Job"):
|
||||
return &JobScaler{c.Batch()}, nil // Either kind of job can be scaled with Batch interface.
|
||||
case apps.Kind("PetSet"):
|
||||
return &PetSetScaler{c.Apps()}, nil
|
||||
case apps.Kind("StatefulSet"):
|
||||
return &StatefulSetScaler{c.Apps()}, nil
|
||||
case extensions.Kind("Deployment"):
|
||||
return &DeploymentScaler{c.Extensions()}, nil
|
||||
}
|
||||
|
|
@ -132,8 +137,8 @@ func ScaleCondition(r Scaler, precondition *ScalePrecondition, namespace, name s
|
|||
}
|
||||
}
|
||||
|
||||
// ValidatePetSet ensures that the preconditions match. Returns nil if they are valid, an error otherwise.
|
||||
func (precondition *ScalePrecondition) ValidatePetSet(ps *apps.PetSet) error {
|
||||
// ValidateStatefulSet ensures that the preconditions match. Returns nil if they are valid, an error otherwise.
|
||||
func (precondition *ScalePrecondition) ValidateStatefulSet(ps *apps.StatefulSet) error {
|
||||
if precondition.Size != -1 && int(ps.Spec.Replicas) != precondition.Size {
|
||||
return PreconditionError{"replicas", strconv.Itoa(precondition.Size), strconv.Itoa(int(ps.Spec.Replicas))}
|
||||
}
|
||||
|
|
@ -155,7 +160,7 @@ func (precondition *ScalePrecondition) ValidateReplicationController(controller
|
|||
}
|
||||
|
||||
type ReplicationControllerScaler struct {
|
||||
c client.Interface
|
||||
c coreclient.ReplicationControllersGetter
|
||||
}
|
||||
|
||||
// ScaleSimple does a simple one-shot attempt at scaling. It returns the
|
||||
|
|
@ -253,7 +258,7 @@ func (precondition *ScalePrecondition) ValidateReplicaSet(replicaSet *extensions
|
|||
}
|
||||
|
||||
type ReplicaSetScaler struct {
|
||||
c client.ExtensionsInterface
|
||||
c extensionsclient.ReplicaSetsGetter
|
||||
}
|
||||
|
||||
// ScaleSimple does a simple one-shot attempt at scaling. It returns the
|
||||
|
|
@ -323,34 +328,34 @@ func (precondition *ScalePrecondition) ValidateJob(job *batch.Job) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
type PetSetScaler struct {
|
||||
c client.AppsInterface
|
||||
type StatefulSetScaler struct {
|
||||
c appsclient.StatefulSetsGetter
|
||||
}
|
||||
|
||||
// ScaleSimple does a simple one-shot attempt at scaling. It returns the
|
||||
// resourceVersion of the petset if the update is successful.
|
||||
func (scaler *PetSetScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) (string, error) {
|
||||
ps, err := scaler.c.PetSets(namespace).Get(name)
|
||||
// resourceVersion of the statefulset if the update is successful.
|
||||
func (scaler *StatefulSetScaler) ScaleSimple(namespace, name string, preconditions *ScalePrecondition, newSize uint) (string, error) {
|
||||
ps, err := scaler.c.StatefulSets(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", ScaleError{ScaleGetFailure, "Unknown", err}
|
||||
}
|
||||
if preconditions != nil {
|
||||
if err := preconditions.ValidatePetSet(ps); err != nil {
|
||||
if err := preconditions.ValidateStatefulSet(ps); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
ps.Spec.Replicas = int(newSize)
|
||||
updatedPetSet, err := scaler.c.PetSets(namespace).Update(ps)
|
||||
ps.Spec.Replicas = int32(newSize)
|
||||
updatedStatefulSet, err := scaler.c.StatefulSets(namespace).Update(ps)
|
||||
if err != nil {
|
||||
if errors.IsConflict(err) {
|
||||
return "", ScaleError{ScaleUpdateConflictFailure, ps.ResourceVersion, err}
|
||||
}
|
||||
return "", ScaleError{ScaleUpdateFailure, ps.ResourceVersion, err}
|
||||
}
|
||||
return updatedPetSet.ResourceVersion, nil
|
||||
return updatedStatefulSet.ResourceVersion, nil
|
||||
}
|
||||
|
||||
func (scaler *PetSetScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
|
||||
func (scaler *StatefulSetScaler) Scale(namespace, name string, newSize uint, preconditions *ScalePrecondition, retry, waitForReplicas *RetryParams) error {
|
||||
if preconditions == nil {
|
||||
preconditions = &ScalePrecondition{-1, ""}
|
||||
}
|
||||
|
|
@ -363,11 +368,11 @@ func (scaler *PetSetScaler) Scale(namespace, name string, newSize uint, precondi
|
|||
return err
|
||||
}
|
||||
if waitForReplicas != nil {
|
||||
job, err := scaler.c.PetSets(namespace).Get(name)
|
||||
job, err := scaler.c.StatefulSets(namespace).Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.PetSetHasDesiredPets(scaler.c, job))
|
||||
err = wait.Poll(waitForReplicas.Interval, waitForReplicas.Timeout, client.StatefulSetHasDesiredPets(scaler.c, job))
|
||||
if err == wait.ErrWaitTimeout {
|
||||
return fmt.Errorf("timed out waiting for %q to be synced", name)
|
||||
}
|
||||
|
|
@ -377,7 +382,7 @@ func (scaler *PetSetScaler) Scale(namespace, name string, newSize uint, precondi
|
|||
}
|
||||
|
||||
type JobScaler struct {
|
||||
c client.BatchInterface
|
||||
c batchclient.JobsGetter
|
||||
}
|
||||
|
||||
// ScaleSimple is responsible for updating job's parallelism. It returns the
|
||||
|
|
@ -445,7 +450,7 @@ func (precondition *ScalePrecondition) ValidateDeployment(deployment *extensions
|
|||
}
|
||||
|
||||
type DeploymentScaler struct {
|
||||
c client.ExtensionsInterface
|
||||
c extensionsclient.DeploymentsGetter
|
||||
}
|
||||
|
||||
// ScaleSimple is responsible for updating a deployment's desired replicas
|
||||
|
|
|
|||
4
vendor/k8s.io/kubernetes/pkg/kubectl/service_basic.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/kubectl/service_basic.go
generated
vendored
|
|
@ -31,6 +31,7 @@ type ServiceCommonGeneratorV1 struct {
|
|||
TCP []string
|
||||
Type api.ServiceType
|
||||
ClusterIP string
|
||||
NodePort int
|
||||
}
|
||||
|
||||
type ServiceClusterIPGeneratorV1 struct {
|
||||
|
|
@ -56,6 +57,7 @@ func (ServiceNodePortGeneratorV1) ParamNames() []GeneratorParam {
|
|||
return []GeneratorParam{
|
||||
{"name", true},
|
||||
{"tcp", true},
|
||||
{"nodeport", true},
|
||||
}
|
||||
}
|
||||
func (ServiceLoadBalancerGeneratorV1) ParamNames() []GeneratorParam {
|
||||
|
|
@ -174,12 +176,14 @@ func (s ServiceCommonGeneratorV1) StructuredGenerate() (runtime.Object, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
portName := strings.Replace(tcpString, ":", "-", -1)
|
||||
ports = append(ports, api.ServicePort{
|
||||
Name: portName,
|
||||
Port: port,
|
||||
TargetPort: targetPort,
|
||||
Protocol: api.Protocol("TCP"),
|
||||
NodePort: int32(s.NodePort),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
36
vendor/k8s.io/kubernetes/pkg/kubectl/sorted_event_list.go
generated
vendored
36
vendor/k8s.io/kubernetes/pkg/kubectl/sorted_event_list.go
generated
vendored
|
|
@ -1,36 +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 kubectl
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// SortableEvents implements sort.Interface for []api.Event based on the Timestamp field
|
||||
type SortableEvents []api.Event
|
||||
|
||||
func (list SortableEvents) Len() int {
|
||||
return len(list)
|
||||
}
|
||||
|
||||
func (list SortableEvents) Swap(i, j int) {
|
||||
list[i], list[j] = list[j], list[i]
|
||||
}
|
||||
|
||||
func (list SortableEvents) Less(i, j int) bool {
|
||||
return list[i].LastTimestamp.Time.Before(list[j].LastTimestamp.Time)
|
||||
}
|
||||
87
vendor/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go
generated
vendored
87
vendor/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go
generated
vendored
|
|
@ -40,7 +40,7 @@ type SortingPrinter struct {
|
|||
Decoder runtime.Decoder
|
||||
}
|
||||
|
||||
func (s *SortingPrinter) FinishPrint(w io.Writer, res string) error {
|
||||
func (s *SortingPrinter) AfterPrint(w io.Writer, res string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +109,13 @@ func SortObjects(decoder runtime.Decoder, objs []runtime.Object, fieldInput stri
|
|||
}
|
||||
}
|
||||
|
||||
values, err := parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface())
|
||||
var values [][]reflect.Value
|
||||
if unstructured, ok := objs[0].(*runtime.Unstructured); ok {
|
||||
values, err = parser.FindResults(unstructured.Object)
|
||||
} else {
|
||||
values, err = parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -182,6 +188,66 @@ func isLess(i, j reflect.Value) (bool, error) {
|
|||
}
|
||||
}
|
||||
return true, nil
|
||||
|
||||
case reflect.Interface:
|
||||
switch itype := i.Interface().(type) {
|
||||
case uint8:
|
||||
if jtype, ok := j.Interface().(uint8); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case uint16:
|
||||
if jtype, ok := j.Interface().(uint16); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case uint32:
|
||||
if jtype, ok := j.Interface().(uint32); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case uint64:
|
||||
if jtype, ok := j.Interface().(uint64); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case int8:
|
||||
if jtype, ok := j.Interface().(int8); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case int16:
|
||||
if jtype, ok := j.Interface().(int16); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case int32:
|
||||
if jtype, ok := j.Interface().(int32); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case int64:
|
||||
if jtype, ok := j.Interface().(int64); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case uint:
|
||||
if jtype, ok := j.Interface().(uint); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case int:
|
||||
if jtype, ok := j.Interface().(int); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case float32:
|
||||
if jtype, ok := j.Interface().(float32); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case float64:
|
||||
if jtype, ok := j.Interface().(float64); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
case string:
|
||||
if jtype, ok := j.Interface().(string); ok {
|
||||
return itype < jtype, nil
|
||||
}
|
||||
default:
|
||||
return false, fmt.Errorf("unsortable type: %T", itype)
|
||||
}
|
||||
return false, fmt.Errorf("unsortable interface: %v", i.Kind())
|
||||
|
||||
default:
|
||||
return false, fmt.Errorf("unsortable type: %v", i.Kind())
|
||||
}
|
||||
|
|
@ -194,11 +260,24 @@ func (r *RuntimeSort) Less(i, j int) bool {
|
|||
parser := jsonpath.New("sorting")
|
||||
parser.Parse(r.field)
|
||||
|
||||
iValues, err := parser.FindResults(reflect.ValueOf(iObj).Elem().Interface())
|
||||
var iValues [][]reflect.Value
|
||||
var jValues [][]reflect.Value
|
||||
var err error
|
||||
|
||||
if unstructured, ok := iObj.(*runtime.Unstructured); ok {
|
||||
iValues, err = parser.FindResults(unstructured.Object)
|
||||
} else {
|
||||
iValues, err = parser.FindResults(reflect.ValueOf(iObj).Elem().Interface())
|
||||
}
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to get i values for %#v using %s (%#v)", iObj, r.field, err)
|
||||
}
|
||||
jValues, err := parser.FindResults(reflect.ValueOf(jObj).Elem().Interface())
|
||||
|
||||
if unstructured, ok := jObj.(*runtime.Unstructured); ok {
|
||||
jValues, err = parser.FindResults(unstructured.Object)
|
||||
} else {
|
||||
jValues, err = parser.FindResults(reflect.ValueOf(jObj).Elem().Interface())
|
||||
}
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to get j values for %#v using %s (%v)", jObj, r.field, err)
|
||||
}
|
||||
|
|
|
|||
132
vendor/k8s.io/kubernetes/pkg/kubectl/stop.go
generated
vendored
132
vendor/k8s.io/kubernetes/pkg/kubectl/stop.go
generated
vendored
|
|
@ -28,7 +28,11 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
appsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/apps/internalversion"
|
||||
batchclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/batch/internalversion"
|
||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion"
|
||||
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
|
@ -63,68 +67,71 @@ func IsNoSuchReaperError(err error) bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
func ReaperFor(kind unversioned.GroupKind, c client.Interface) (Reaper, error) {
|
||||
func ReaperFor(kind unversioned.GroupKind, c internalclientset.Interface) (Reaper, error) {
|
||||
switch kind {
|
||||
case api.Kind("ReplicationController"):
|
||||
return &ReplicationControllerReaper{c, Interval, Timeout}, nil
|
||||
return &ReplicationControllerReaper{c.Core(), Interval, Timeout}, nil
|
||||
|
||||
case extensions.Kind("ReplicaSet"):
|
||||
return &ReplicaSetReaper{c, Interval, Timeout}, nil
|
||||
return &ReplicaSetReaper{c.Extensions(), Interval, Timeout}, nil
|
||||
|
||||
case extensions.Kind("DaemonSet"):
|
||||
return &DaemonSetReaper{c, Interval, Timeout}, nil
|
||||
return &DaemonSetReaper{c.Extensions(), Interval, Timeout}, nil
|
||||
|
||||
case api.Kind("Pod"):
|
||||
return &PodReaper{c}, nil
|
||||
return &PodReaper{c.Core()}, nil
|
||||
|
||||
case api.Kind("Service"):
|
||||
return &ServiceReaper{c}, nil
|
||||
return &ServiceReaper{c.Core()}, nil
|
||||
|
||||
case extensions.Kind("Job"), batch.Kind("Job"):
|
||||
return &JobReaper{c, Interval, Timeout}, nil
|
||||
return &JobReaper{c.Batch(), c.Core(), Interval, Timeout}, nil
|
||||
|
||||
case apps.Kind("PetSet"):
|
||||
return &PetSetReaper{c, Interval, Timeout}, nil
|
||||
case apps.Kind("StatefulSet"):
|
||||
return &StatefulSetReaper{c.Apps(), c.Core(), Interval, Timeout}, nil
|
||||
|
||||
case extensions.Kind("Deployment"):
|
||||
return &DeploymentReaper{c, Interval, Timeout}, nil
|
||||
return &DeploymentReaper{c.Extensions(), c.Extensions(), Interval, Timeout}, nil
|
||||
|
||||
}
|
||||
return nil, &NoSuchReaperError{kind}
|
||||
}
|
||||
|
||||
func ReaperForReplicationController(c client.Interface, timeout time.Duration) (Reaper, error) {
|
||||
return &ReplicationControllerReaper{c, Interval, timeout}, nil
|
||||
func ReaperForReplicationController(rcClient coreclient.ReplicationControllersGetter, timeout time.Duration) (Reaper, error) {
|
||||
return &ReplicationControllerReaper{rcClient, Interval, timeout}, nil
|
||||
}
|
||||
|
||||
type ReplicationControllerReaper struct {
|
||||
client.Interface
|
||||
client coreclient.ReplicationControllersGetter
|
||||
pollInterval, timeout time.Duration
|
||||
}
|
||||
type ReplicaSetReaper struct {
|
||||
client.Interface
|
||||
client extensionsclient.ReplicaSetsGetter
|
||||
pollInterval, timeout time.Duration
|
||||
}
|
||||
type DaemonSetReaper struct {
|
||||
client.Interface
|
||||
client extensionsclient.DaemonSetsGetter
|
||||
pollInterval, timeout time.Duration
|
||||
}
|
||||
type JobReaper struct {
|
||||
client.Interface
|
||||
client batchclient.JobsGetter
|
||||
podClient coreclient.PodsGetter
|
||||
pollInterval, timeout time.Duration
|
||||
}
|
||||
type DeploymentReaper struct {
|
||||
client.Interface
|
||||
dClient extensionsclient.DeploymentsGetter
|
||||
rsClient extensionsclient.ReplicaSetsGetter
|
||||
pollInterval, timeout time.Duration
|
||||
}
|
||||
type PodReaper struct {
|
||||
client.Interface
|
||||
client coreclient.PodsGetter
|
||||
}
|
||||
type ServiceReaper struct {
|
||||
client.Interface
|
||||
client coreclient.ServicesGetter
|
||||
}
|
||||
type PetSetReaper struct {
|
||||
client.Interface
|
||||
type StatefulSetReaper struct {
|
||||
client appsclient.StatefulSetsGetter
|
||||
podClient coreclient.PodsGetter
|
||||
pollInterval, timeout time.Duration
|
||||
}
|
||||
|
||||
|
|
@ -134,8 +141,8 @@ type objInterface interface {
|
|||
}
|
||||
|
||||
// getOverlappingControllers finds rcs that this controller overlaps, as well as rcs overlapping this controller.
|
||||
func getOverlappingControllers(c client.ReplicationControllerInterface, rc *api.ReplicationController) ([]api.ReplicationController, error) {
|
||||
rcs, err := c.List(api.ListOptions{})
|
||||
func getOverlappingControllers(rcClient coreclient.ReplicationControllerInterface, rc *api.ReplicationController) ([]api.ReplicationController, error) {
|
||||
rcs, err := rcClient.List(api.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting replication controllers: %v", err)
|
||||
}
|
||||
|
|
@ -151,11 +158,8 @@ func getOverlappingControllers(c client.ReplicationControllerInterface, rc *api.
|
|||
}
|
||||
|
||||
func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
rc := reaper.ReplicationControllers(namespace)
|
||||
scaler, err := ScalerFor(api.Kind("ReplicationController"), *reaper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rc := reaper.client.ReplicationControllers(namespace)
|
||||
scaler := &ReplicationControllerScaler{reaper.client}
|
||||
ctrl, err := rc.Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -217,17 +221,14 @@ func (reaper *ReplicationControllerReaper) Stop(namespace, name string, timeout
|
|||
|
||||
// TODO(madhusudancs): Implement it when controllerRef is implemented - https://github.com/kubernetes/kubernetes/issues/2210
|
||||
// getOverlappingReplicaSets finds ReplicaSets that this ReplicaSet overlaps, as well as ReplicaSets overlapping this ReplicaSet.
|
||||
func getOverlappingReplicaSets(c client.ReplicaSetInterface, rs *extensions.ReplicaSet) ([]extensions.ReplicaSet, []extensions.ReplicaSet, error) {
|
||||
func getOverlappingReplicaSets(c extensionsclient.ReplicaSetInterface, rs *extensions.ReplicaSet) ([]extensions.ReplicaSet, []extensions.ReplicaSet, error) {
|
||||
var overlappingRSs, exactMatchRSs []extensions.ReplicaSet
|
||||
return overlappingRSs, exactMatchRSs, nil
|
||||
}
|
||||
|
||||
func (reaper *ReplicaSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
rsc := reaper.Extensions().ReplicaSets(namespace)
|
||||
scaler, err := ScalerFor(extensions.Kind("ReplicaSet"), *reaper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rsc := reaper.client.ReplicaSets(namespace)
|
||||
scaler := &ReplicaSetScaler{reaper.client}
|
||||
rs, err := rsc.Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -290,7 +291,7 @@ func (reaper *ReplicaSetReaper) Stop(namespace, name string, timeout time.Durati
|
|||
}
|
||||
|
||||
func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
ds, err := reaper.Extensions().DaemonSets(namespace).Get(name)
|
||||
ds, err := reaper.client.DaemonSets(namespace).Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -305,13 +306,13 @@ func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duratio
|
|||
// force update to avoid version conflict
|
||||
ds.ResourceVersion = ""
|
||||
|
||||
if ds, err = reaper.Extensions().DaemonSets(namespace).Update(ds); err != nil {
|
||||
if ds, err = reaper.client.DaemonSets(namespace).Update(ds); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait for the daemon set controller to kill all the daemon pods.
|
||||
if err := wait.Poll(reaper.pollInterval, reaper.timeout, func() (bool, error) {
|
||||
updatedDS, err := reaper.Extensions().DaemonSets(namespace).Get(name)
|
||||
updatedDS, err := reaper.client.DaemonSets(namespace).Get(name)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
|
@ -321,16 +322,13 @@ func (reaper *DaemonSetReaper) Stop(namespace, name string, timeout time.Duratio
|
|||
return err
|
||||
}
|
||||
|
||||
return reaper.Extensions().DaemonSets(namespace).Delete(name)
|
||||
return reaper.client.DaemonSets(namespace).Delete(name, nil)
|
||||
}
|
||||
|
||||
func (reaper *PetSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
petsets := reaper.Apps().PetSets(namespace)
|
||||
scaler, err := ScalerFor(apps.Kind("PetSet"), *reaper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ps, err := petsets.Get(name)
|
||||
func (reaper *StatefulSetReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
statefulsets := reaper.client.StatefulSets(namespace)
|
||||
scaler := &StatefulSetScaler{reaper.client}
|
||||
ps, err := statefulsets.Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -339,14 +337,14 @@ func (reaper *PetSetReaper) Stop(namespace, name string, timeout time.Duration,
|
|||
timeout = Timeout + time.Duration(10*numPets)*time.Second
|
||||
}
|
||||
retry := NewRetryParams(reaper.pollInterval, reaper.timeout)
|
||||
waitForPetSet := NewRetryParams(reaper.pollInterval, reaper.timeout)
|
||||
if err = scaler.Scale(namespace, name, 0, nil, retry, waitForPetSet); err != nil {
|
||||
waitForStatefulSet := NewRetryParams(reaper.pollInterval, reaper.timeout)
|
||||
if err = scaler.Scale(namespace, name, 0, nil, retry, waitForStatefulSet); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: This shouldn't be needed, see corresponding TODO in PetSetHasDesiredPets.
|
||||
// PetSet should track generation number.
|
||||
pods := reaper.Pods(namespace)
|
||||
// TODO: This shouldn't be needed, see corresponding TODO in StatefulSetHasDesiredPets.
|
||||
// StatefulSet should track generation number.
|
||||
pods := reaper.podClient.Pods(namespace)
|
||||
selector, _ := unversioned.LabelSelectorAsSelector(ps.Spec.Selector)
|
||||
options := api.ListOptions{LabelSelector: selector}
|
||||
podList, err := pods.List(options)
|
||||
|
|
@ -367,17 +365,14 @@ func (reaper *PetSetReaper) Stop(namespace, name string, timeout time.Duration,
|
|||
}
|
||||
|
||||
// TODO: Cleanup volumes? We don't want to accidentally delete volumes from
|
||||
// stop, so just leave this up to the petset.
|
||||
return petsets.Delete(name, nil)
|
||||
// stop, so just leave this up to the statefulset.
|
||||
return statefulsets.Delete(name, nil)
|
||||
}
|
||||
|
||||
func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
jobs := reaper.Batch().Jobs(namespace)
|
||||
pods := reaper.Pods(namespace)
|
||||
scaler, err := ScalerFor(batch.Kind("Job"), *reaper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
jobs := reaper.client.Jobs(namespace)
|
||||
pods := reaper.podClient.Pods(namespace)
|
||||
scaler := &JobScaler{reaper.client}
|
||||
job, err := jobs.Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -418,9 +413,9 @@ func (reaper *JobReaper) Stop(namespace, name string, timeout time.Duration, gra
|
|||
}
|
||||
|
||||
func (reaper *DeploymentReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
deployments := reaper.Extensions().Deployments(namespace)
|
||||
replicaSets := reaper.Extensions().ReplicaSets(namespace)
|
||||
rsReaper, _ := ReaperFor(extensions.Kind("ReplicaSet"), reaper)
|
||||
deployments := reaper.dClient.Deployments(namespace)
|
||||
replicaSets := reaper.rsClient.ReplicaSets(namespace)
|
||||
rsReaper := &ReplicaSetReaper{reaper.rsClient, reaper.pollInterval, reaper.timeout}
|
||||
|
||||
deployment, err := reaper.updateDeploymentWithRetries(namespace, name, func(d *extensions.Deployment) {
|
||||
// set deployment's history and scale to 0
|
||||
|
|
@ -440,6 +435,11 @@ func (reaper *DeploymentReaper) Stop(namespace, name string, timeout time.Durati
|
|||
return err
|
||||
}
|
||||
|
||||
// Do not cascade deletion for overlapping deployments.
|
||||
if len(deployment.Annotations[deploymentutil.OverlapAnnotation]) > 0 {
|
||||
return deployments.Delete(name, nil)
|
||||
}
|
||||
|
||||
// Stop all replica sets.
|
||||
selector, err := unversioned.LabelSelectorAsSelector(deployment.Spec.Selector)
|
||||
if err != nil {
|
||||
|
|
@ -473,7 +473,7 @@ func (reaper *DeploymentReaper) Stop(namespace, name string, timeout time.Durati
|
|||
type updateDeploymentFunc func(d *extensions.Deployment)
|
||||
|
||||
func (reaper *DeploymentReaper) updateDeploymentWithRetries(namespace, name string, applyUpdate updateDeploymentFunc) (deployment *extensions.Deployment, err error) {
|
||||
deployments := reaper.Extensions().Deployments(namespace)
|
||||
deployments := reaper.dClient.Deployments(namespace)
|
||||
err = wait.Poll(10*time.Millisecond, 1*time.Minute, func() (bool, error) {
|
||||
if deployment, err = deployments.Get(name); err != nil {
|
||||
return false, err
|
||||
|
|
@ -493,7 +493,7 @@ func (reaper *DeploymentReaper) updateDeploymentWithRetries(namespace, name stri
|
|||
}
|
||||
|
||||
func (reaper *PodReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
pods := reaper.Pods(namespace)
|
||||
pods := reaper.client.Pods(namespace)
|
||||
_, err := pods.Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -502,10 +502,10 @@ func (reaper *PodReaper) Stop(namespace, name string, timeout time.Duration, gra
|
|||
}
|
||||
|
||||
func (reaper *ServiceReaper) Stop(namespace, name string, timeout time.Duration, gracePeriod *api.DeleteOptions) error {
|
||||
services := reaper.Services(namespace)
|
||||
services := reaper.client.Services(namespace)
|
||||
_, err := services.Get(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return services.Delete(name)
|
||||
return services.Delete(name, nil)
|
||||
}
|
||||
|
|
|
|||
12
vendor/k8s.io/kubernetes/pkg/kubectl/version.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/kubectl/version.go
generated
vendored
|
|
@ -19,22 +19,10 @@ package kubectl
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
)
|
||||
|
||||
func GetServerVersion(w io.Writer, kubeClient client.Interface) {
|
||||
serverVersion, err := kubeClient.Discovery().ServerVersion()
|
||||
if err != nil {
|
||||
fmt.Printf("Couldn't read server version from server: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "Server Version: %#v\n", *serverVersion)
|
||||
}
|
||||
|
||||
func GetClientVersion(w io.Writer) {
|
||||
fmt.Fprintf(w, "Client Version: %#v\n", version.Get())
|
||||
}
|
||||
|
|
|
|||
45
vendor/k8s.io/kubernetes/pkg/kubectl/watchloop.go
generated
vendored
45
vendor/k8s.io/kubernetes/pkg/kubectl/watchloop.go
generated
vendored
|
|
@ -1,45 +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 kubectl
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"k8s.io/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
// WatchLoop loops, passing events in w to fn.
|
||||
// If user sends interrupt signal, shut down cleanly. Otherwise, never return.
|
||||
func WatchLoop(w watch.Interface, fn func(watch.Event) error) {
|
||||
signals := make(chan os.Signal, 1)
|
||||
signal.Notify(signals, os.Interrupt)
|
||||
defer signal.Stop(signals)
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-w.ResultChan():
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if err := fn(event); err != nil {
|
||||
w.Stop()
|
||||
}
|
||||
case <-signals:
|
||||
w.Stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue