Update godeps
This commit is contained in:
parent
423433bc5f
commit
701c5a0e30
482 changed files with 86915 additions and 19741 deletions
1
vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/kubectl/OWNERS
generated
vendored
|
|
@ -4,4 +4,5 @@ assignees:
|
|||
- deads2k
|
||||
- janetkuo
|
||||
- jlowdermilk
|
||||
- pwittrock
|
||||
- smarterclayton
|
||||
|
|
|
|||
65
vendor/k8s.io/kubernetes/pkg/kubectl/apply.go
generated
vendored
65
vendor/k8s.io/kubernetes/pkg/kubectl/apply.go
generated
vendored
|
|
@ -19,6 +19,7 @@ package kubectl
|
|||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/annotations"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
|
|
@ -28,23 +29,19 @@ type debugError interface {
|
|||
DebugError() (msg string, args []interface{})
|
||||
}
|
||||
|
||||
// LastAppliedConfigAnnotation is the annotation used to store the previous
|
||||
// configuration of a resource for use in a three way diff by UpdateApplyAnnotation.
|
||||
const LastAppliedConfigAnnotation = kubectlAnnotationPrefix + "last-applied-configuration"
|
||||
|
||||
// GetOriginalConfiguration retrieves the original configuration of the object
|
||||
// from the annotation, or nil if no annotation was found.
|
||||
func GetOriginalConfiguration(info *resource.Info) ([]byte, error) {
|
||||
annotations, err := info.Mapping.MetadataAccessor.Annotations(info.Object)
|
||||
func GetOriginalConfiguration(mapping *meta.RESTMapping, obj runtime.Object) ([]byte, error) {
|
||||
annots, err := mapping.MetadataAccessor.Annotations(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if annotations == nil {
|
||||
if annots == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
original, ok := annotations[LastAppliedConfigAnnotation]
|
||||
original, ok := annots[annotations.LastAppliedConfigAnnotation]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
|
@ -60,17 +57,17 @@ func SetOriginalConfiguration(info *resource.Info, original []byte) error {
|
|||
}
|
||||
|
||||
accessor := info.Mapping.MetadataAccessor
|
||||
annotations, err := accessor.Annotations(info.Object)
|
||||
annots, err := accessor.Annotations(info.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if annotations == nil {
|
||||
annotations = map[string]string{}
|
||||
if annots == nil {
|
||||
annots = map[string]string{}
|
||||
}
|
||||
|
||||
annotations[LastAppliedConfigAnnotation] = string(original)
|
||||
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annotations); err != nil {
|
||||
annots[annotations.LastAppliedConfigAnnotation] = string(original)
|
||||
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annots); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -93,14 +90,14 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
|
|||
}
|
||||
|
||||
// Get the current annotations from the object.
|
||||
annotations := accessor.GetAnnotations()
|
||||
if annotations == nil {
|
||||
annotations = map[string]string{}
|
||||
annots := accessor.GetAnnotations()
|
||||
if annots == nil {
|
||||
annots = map[string]string{}
|
||||
}
|
||||
|
||||
original := annotations[LastAppliedConfigAnnotation]
|
||||
delete(annotations, LastAppliedConfigAnnotation)
|
||||
accessor.SetAnnotations(annotations)
|
||||
original := annots[annotations.LastAppliedConfigAnnotation]
|
||||
delete(annots, annotations.LastAppliedConfigAnnotation)
|
||||
accessor.SetAnnotations(annots)
|
||||
// TODO: this needs to be abstracted - there should be no assumption that versioned object
|
||||
// can be marshalled to JSON.
|
||||
modified, err = json.Marshal(info.VersionedObject)
|
||||
|
|
@ -109,8 +106,8 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
|
|||
}
|
||||
|
||||
if annotate {
|
||||
annotations[LastAppliedConfigAnnotation] = string(modified)
|
||||
accessor.SetAnnotations(annotations)
|
||||
annots[annotations.LastAppliedConfigAnnotation] = string(modified)
|
||||
accessor.SetAnnotations(annots)
|
||||
// TODO: this needs to be abstracted - there should be no assumption that versioned object
|
||||
// can be marshalled to JSON.
|
||||
modified, err = json.Marshal(info.VersionedObject)
|
||||
|
|
@ -120,24 +117,24 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
|
|||
}
|
||||
|
||||
// Restore the object to its original condition.
|
||||
annotations[LastAppliedConfigAnnotation] = original
|
||||
accessor.SetAnnotations(annotations)
|
||||
annots[annotations.LastAppliedConfigAnnotation] = original
|
||||
accessor.SetAnnotations(annots)
|
||||
} else {
|
||||
// Otherwise, use the server side version of the object.
|
||||
accessor := info.Mapping.MetadataAccessor
|
||||
// Get the current annotations from the object.
|
||||
annotations, err := accessor.Annotations(info.Object)
|
||||
annots, err := accessor.Annotations(info.Object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if annotations == nil {
|
||||
annotations = map[string]string{}
|
||||
if annots == nil {
|
||||
annots = map[string]string{}
|
||||
}
|
||||
|
||||
original := annotations[LastAppliedConfigAnnotation]
|
||||
delete(annotations, LastAppliedConfigAnnotation)
|
||||
if err := accessor.SetAnnotations(info.Object, annotations); err != nil {
|
||||
original := annots[annotations.LastAppliedConfigAnnotation]
|
||||
delete(annots, annotations.LastAppliedConfigAnnotation)
|
||||
if err := accessor.SetAnnotations(info.Object, annots); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -147,8 +144,8 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
|
|||
}
|
||||
|
||||
if annotate {
|
||||
annotations[LastAppliedConfigAnnotation] = string(modified)
|
||||
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annotations); err != nil {
|
||||
annots[annotations.LastAppliedConfigAnnotation] = string(modified)
|
||||
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annots); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -159,8 +156,8 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
|
|||
}
|
||||
|
||||
// Restore the object to its original condition.
|
||||
annotations[LastAppliedConfigAnnotation] = original
|
||||
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annotations); err != nil {
|
||||
annots[annotations.LastAppliedConfigAnnotation] = original
|
||||
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annots); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -171,7 +168,7 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
|
|||
// UpdateApplyAnnotation calls CreateApplyAnnotation if the last applied
|
||||
// configuration annotation is already present. Otherwise, it does nothing.
|
||||
func UpdateApplyAnnotation(info *resource.Info, codec runtime.Encoder) error {
|
||||
if original, err := GetOriginalConfiguration(info); err != nil || len(original) <= 0 {
|
||||
if original, err := GetOriginalConfiguration(info.Mapping, info.Object); err != nil || len(original) <= 0 {
|
||||
return err
|
||||
}
|
||||
return CreateApplyAnnotation(info, codec)
|
||||
|
|
|
|||
45
vendor/k8s.io/kubernetes/pkg/kubectl/autoscale.go
generated
vendored
45
vendor/k8s.io/kubernetes/pkg/kubectl/autoscale.go
generated
vendored
|
|
@ -21,14 +21,10 @@ import (
|
|||
"strconv"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
const (
|
||||
scaleSubResource = "scale"
|
||||
)
|
||||
|
||||
type HorizontalPodAutoscalerV1Beta1 struct{}
|
||||
|
||||
func (HorizontalPodAutoscalerV1Beta1) ParamNames() []GeneratorParam {
|
||||
|
|
@ -46,6 +42,29 @@ func (HorizontalPodAutoscalerV1Beta1) ParamNames() []GeneratorParam {
|
|||
}
|
||||
|
||||
func (HorizontalPodAutoscalerV1Beta1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
return generateHPA(genericParams)
|
||||
}
|
||||
|
||||
type HorizontalPodAutoscalerV1 struct{}
|
||||
|
||||
func (HorizontalPodAutoscalerV1) ParamNames() []GeneratorParam {
|
||||
return []GeneratorParam{
|
||||
{"default-name", true},
|
||||
{"name", false},
|
||||
{"scaleRef-kind", false},
|
||||
{"scaleRef-name", false},
|
||||
{"scaleRef-apiVersion", false},
|
||||
{"min", false},
|
||||
{"max", true},
|
||||
{"cpu-percent", false},
|
||||
}
|
||||
}
|
||||
|
||||
func (HorizontalPodAutoscalerV1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
return generateHPA(genericParams)
|
||||
}
|
||||
|
||||
func generateHPA(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
params := map[string]string{}
|
||||
for key, value := range genericParams {
|
||||
strVal, isString := value.(string)
|
||||
|
|
@ -86,16 +105,15 @@ func (HorizontalPodAutoscalerV1Beta1) Generate(genericParams map[string]interfac
|
|||
}
|
||||
}
|
||||
|
||||
scaler := extensions.HorizontalPodAutoscaler{
|
||||
scaler := autoscaling.HorizontalPodAutoscaler{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Spec: extensions.HorizontalPodAutoscalerSpec{
|
||||
ScaleRef: extensions.SubresourceReference{
|
||||
Kind: params["scaleRef-kind"],
|
||||
Name: params["scaleRef-name"],
|
||||
APIVersion: params["scaleRef-apiVersion"],
|
||||
Subresource: scaleSubResource,
|
||||
Spec: autoscaling.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscaling.CrossVersionObjectReference{
|
||||
Kind: params["scaleRef-kind"],
|
||||
Name: params["scaleRef-name"],
|
||||
APIVersion: params["scaleRef-apiVersion"],
|
||||
},
|
||||
MaxReplicas: int32(max),
|
||||
},
|
||||
|
|
@ -105,7 +123,8 @@ func (HorizontalPodAutoscalerV1Beta1) Generate(genericParams map[string]interfac
|
|||
scaler.Spec.MinReplicas = &v
|
||||
}
|
||||
if cpu >= 0 {
|
||||
scaler.Spec.CPUUtilization = &extensions.CPUTargetUtilization{TargetPercentage: int32(cpu)}
|
||||
c := int32(cpu)
|
||||
scaler.Spec.TargetCPUUtilizationPercentage = &c
|
||||
}
|
||||
return &scaler, nil
|
||||
}
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/kubectl/bash_comp_utils.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/kubectl/bash_comp_utils.go
generated
vendored
|
|
@ -28,7 +28,7 @@ import (
|
|||
|
||||
func AddJsonFilenameFlag(cmd *cobra.Command, value *[]string, usage string) {
|
||||
cmd.Flags().StringSliceVarP(value, "filename", "f", *value, usage)
|
||||
annotations := []string{}
|
||||
annotations := make([]string, 0, len(resource.FileExtensions))
|
||||
for _, ext := range resource.FileExtensions {
|
||||
annotations = append(annotations, strings.TrimLeft(ext, "."))
|
||||
}
|
||||
|
|
|
|||
47
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/clientcache.go
generated
vendored
47
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/clientcache.go
generated
vendored
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package util
|
||||
|
||||
import (
|
||||
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/restclient"
|
||||
|
|
@ -26,9 +27,10 @@ import (
|
|||
|
||||
func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
|
||||
return &ClientCache{
|
||||
clients: make(map[unversioned.GroupVersion]*client.Client),
|
||||
configs: make(map[unversioned.GroupVersion]*restclient.Config),
|
||||
loader: loader,
|
||||
clients: make(map[unversioned.GroupVersion]*client.Client),
|
||||
configs: make(map[unversioned.GroupVersion]*restclient.Config),
|
||||
fedClientSets: make(map[unversioned.GroupVersion]fed_clientset.Interface),
|
||||
loader: loader,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +39,7 @@ func NewClientCache(loader clientcmd.ClientConfig) *ClientCache {
|
|||
type ClientCache struct {
|
||||
loader clientcmd.ClientConfig
|
||||
clients map[unversioned.GroupVersion]*client.Client
|
||||
fedClientSets map[unversioned.GroupVersion]fed_clientset.Interface
|
||||
configs map[unversioned.GroupVersion]*restclient.Config
|
||||
defaultConfig *restclient.Config
|
||||
defaultClient *client.Client
|
||||
|
|
@ -125,3 +128,41 @@ func (c *ClientCache) ClientForVersion(version *unversioned.GroupVersion) (*clie
|
|||
|
||||
return kubeclient, nil
|
||||
}
|
||||
|
||||
func (c *ClientCache) FederationClientSetForVersion(version *unversioned.GroupVersion) (fed_clientset.Interface, error) {
|
||||
if version != nil {
|
||||
if clientSet, found := c.fedClientSets[*version]; found {
|
||||
return clientSet, nil
|
||||
}
|
||||
}
|
||||
config, err := c.ClientConfigForVersion(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: support multi versions of client with clientset
|
||||
clientSet, err := fed_clientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.fedClientSets[*config.GroupVersion] = clientSet
|
||||
|
||||
if version != nil {
|
||||
configCopy := *config
|
||||
clientSet, err := fed_clientset.NewForConfig(&configCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.fedClientSets[*version] = clientSet
|
||||
}
|
||||
|
||||
return clientSet, nil
|
||||
}
|
||||
|
||||
func (c *ClientCache) FederationClientForVersion(version *unversioned.GroupVersion) (*restclient.RESTClient, error) {
|
||||
fedClientSet, err := c.FederationClientSetForVersion(version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fedClientSet.(*fed_clientset.Clientset).FederationClient.RESTClient, nil
|
||||
}
|
||||
|
|
|
|||
251
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
generated
vendored
251
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
generated
vendored
|
|
@ -36,8 +36,11 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apierrors "k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/service"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/apimachinery"
|
||||
|
|
@ -46,7 +49,8 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/metrics"
|
||||
"k8s.io/kubernetes/pkg/apis/policy"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/client/restclient"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
clientset "k8s.io/kubernetes/pkg/client/unversioned/adapters/internalclientset"
|
||||
|
|
@ -103,12 +107,16 @@ type Factory struct {
|
|||
HistoryViewer func(mapping *meta.RESTMapping) (kubectl.HistoryViewer, error)
|
||||
// Returns a Rollbacker for changing the rollback version of the specified RESTMapping type or an error
|
||||
Rollbacker func(mapping *meta.RESTMapping) (kubectl.Rollbacker, error)
|
||||
// Returns a StatusViewer for printing rollout status.
|
||||
StatusViewer func(mapping *meta.RESTMapping) (kubectl.StatusViewer, error)
|
||||
// MapBasedSelectorForObject returns the map-based selector associated with the provided object. If a
|
||||
// new set-based selector is provided, an error is returned if the selector cannot be converted to a
|
||||
// map-based selector
|
||||
MapBasedSelectorForObject func(object runtime.Object) (string, error)
|
||||
// PortsForObject returns the ports associated with the provided object
|
||||
PortsForObject func(object runtime.Object) ([]string, error)
|
||||
// ProtocolsForObject returns the <port, protocol> mapping associated with the provided object
|
||||
ProtocolsForObject func(object runtime.Object) (map[string]string, error)
|
||||
// LabelsForObject returns the labels associated with the provided object
|
||||
LabelsForObject func(object runtime.Object) (map[string]string, error)
|
||||
// LogsForObject returns a request for the logs associated with the provided object
|
||||
|
|
@ -123,7 +131,7 @@ type Factory struct {
|
|||
SwaggerSchema func(unversioned.GroupVersionKind) (*swagger.ApiDeclaration, error)
|
||||
// Returns the default namespace to use in cases where no
|
||||
// other namespace is specified and whether the namespace was
|
||||
// overriden.
|
||||
// overridden.
|
||||
DefaultNamespace func() (string, bool, error)
|
||||
// Generators returns the generators for the provided command
|
||||
Generators func(cmdName string) map[string]kubectl.Generator
|
||||
|
|
@ -133,10 +141,15 @@ type Factory struct {
|
|||
CanBeAutoscaled func(kind unversioned.GroupKind) error
|
||||
// AttachablePodForObject returns the pod to which to attach given an object.
|
||||
AttachablePodForObject func(object runtime.Object) (*api.Pod, error)
|
||||
// UpdatePodSpecForObject will call the provided function on the pod spec this object supports,
|
||||
// return false if no pod spec is supported, or return an error.
|
||||
UpdatePodSpecForObject func(obj runtime.Object, fn func(*api.PodSpec) error) (bool, error)
|
||||
// EditorEnvs returns a group of environment variables that the edit command
|
||||
// can range over in order to determine if the user has specified an editor
|
||||
// of their choice.
|
||||
EditorEnvs func() []string
|
||||
// PrintObjectSpecificMessage prints object-specific messages on the provided writer
|
||||
PrintObjectSpecificMessage func(obj runtime.Object, out io.Writer)
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
@ -146,12 +159,14 @@ const (
|
|||
ServiceV2GeneratorName = "service/v2"
|
||||
ServiceAccountV1GeneratorName = "serviceaccount/v1"
|
||||
HorizontalPodAutoscalerV1Beta1GeneratorName = "horizontalpodautoscaler/v1beta1"
|
||||
HorizontalPodAutoscalerV1GeneratorName = "horizontalpodautoscaler/v1"
|
||||
DeploymentV1Beta1GeneratorName = "deployment/v1beta1"
|
||||
JobV1Beta1GeneratorName = "job/v1beta1"
|
||||
JobV1GeneratorName = "job/v1"
|
||||
NamespaceV1GeneratorName = "namespace/v1"
|
||||
SecretV1GeneratorName = "secret/v1"
|
||||
SecretForDockerRegistryV1GeneratorName = "secret-for-docker-registry/v1"
|
||||
SecretForTLSV1GeneratorName = "secret-for-tls/v1"
|
||||
ConfigMapV1GeneratorName = "configmap/v1"
|
||||
)
|
||||
|
||||
|
|
@ -171,6 +186,7 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator {
|
|||
}
|
||||
generators["autoscale"] = map[string]kubectl.Generator{
|
||||
HorizontalPodAutoscalerV1Beta1GeneratorName: kubectl.HorizontalPodAutoscalerV1Beta1{},
|
||||
HorizontalPodAutoscalerV1GeneratorName: kubectl.HorizontalPodAutoscalerV1{},
|
||||
}
|
||||
generators["namespace"] = map[string]kubectl.Generator{
|
||||
NamespaceV1GeneratorName: kubectl.NamespaceGeneratorV1{},
|
||||
|
|
@ -181,6 +197,10 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator {
|
|||
generators["secret-for-docker-registry"] = map[string]kubectl.Generator{
|
||||
SecretForDockerRegistryV1GeneratorName: kubectl.SecretForDockerRegistryGeneratorV1{},
|
||||
}
|
||||
generators["secret-for-tls"] = map[string]kubectl.Generator{
|
||||
SecretForTLSV1GeneratorName: kubectl.SecretForTLSGeneratorV1{},
|
||||
}
|
||||
|
||||
return generators[cmdName]
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +262,18 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
client, err := clients.ClientForVersion(&unversioned.GroupVersion{Version: "v1"})
|
||||
CheckErr(err)
|
||||
|
||||
versions, gvks, err := GetThirdPartyGroupVersions(client.Discovery())
|
||||
var versions []unversioned.GroupVersion
|
||||
var gvks []unversioned.GroupVersionKind
|
||||
retries := 3
|
||||
for i := 0; i < retries; i++ {
|
||||
versions, gvks, err = GetThirdPartyGroupVersions(client.Discovery())
|
||||
// Retry if we got a NotFound error, because user may delete
|
||||
// a thirdparty group when the GetThirdPartyGroupVersions is
|
||||
// running.
|
||||
if err == nil || !apierrors.IsNotFound(err) {
|
||||
break
|
||||
}
|
||||
}
|
||||
CheckErr(err)
|
||||
if len(versions) > 0 {
|
||||
priorityMapper, ok := mapper.RESTMapper.(meta.PriorityRESTMapper)
|
||||
|
|
@ -288,13 +319,15 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
Delegate: outputRESTMapper,
|
||||
ResourcePriority: []unversioned.GroupVersionResource{
|
||||
{Group: api.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource},
|
||||
{Group: autoscaling.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource},
|
||||
{Group: extensions.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource},
|
||||
{Group: metrics.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource},
|
||||
{Group: federation.GroupName, Version: meta.AnyVersion, Resource: meta.AnyResource},
|
||||
},
|
||||
KindPriority: []unversioned.GroupVersionKind{
|
||||
{Group: api.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind},
|
||||
{Group: autoscaling.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind},
|
||||
{Group: extensions.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind},
|
||||
{Group: metrics.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind},
|
||||
{Group: federation.GroupName, Version: meta.AnyVersion, Kind: meta.AnyKind},
|
||||
},
|
||||
}
|
||||
return priorityRESTMapper, api.Scheme
|
||||
|
|
@ -319,6 +352,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
return c.AutoscalingClient.RESTClient, nil
|
||||
case batch.GroupName:
|
||||
return c.BatchClient.RESTClient, nil
|
||||
case policy.GroupName:
|
||||
return c.PolicyClient.RESTClient, nil
|
||||
case apps.GroupName:
|
||||
return c.AppsClient.RESTClient, nil
|
||||
case extensions.GroupName:
|
||||
|
|
@ -327,6 +362,10 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
return c.RESTClient, nil
|
||||
case extensions.SchemeGroupVersion.Group:
|
||||
return c.ExtensionsClient.RESTClient, nil
|
||||
case federation.GroupName:
|
||||
return clients.FederationClientForVersion(&mappingVersion)
|
||||
case rbac.GroupName:
|
||||
return c.RbacClient.RESTClient, nil
|
||||
default:
|
||||
if !registered.IsThirdPartyAPIGroupVersion(gvk.GroupVersion()) {
|
||||
return nil, fmt.Errorf("unknown api group/version: %s", gvk.String())
|
||||
|
|
@ -338,12 +377,22 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
gv := gvk.GroupVersion()
|
||||
cfg.GroupVersion = &gv
|
||||
cfg.APIPath = "/apis"
|
||||
cfg.Codec = thirdpartyresourcedata.NewCodec(c.ExtensionsClient.RESTClient.Codec(), gvk.Kind)
|
||||
cfg.Codec = thirdpartyresourcedata.NewCodec(c.ExtensionsClient.RESTClient.Codec(), gvk)
|
||||
cfg.NegotiatedSerializer = thirdpartyresourcedata.NewNegotiatedSerializer(api.Codecs, gvk.Kind, gv, gv)
|
||||
return restclient.RESTClientFor(cfg)
|
||||
}
|
||||
},
|
||||
Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) {
|
||||
mappingVersion := mapping.GroupVersionKind.GroupVersion()
|
||||
if mapping.GroupVersionKind.Group == federation.GroupName {
|
||||
fedClientSet, err := clients.FederationClientSetForVersion(&mappingVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if mapping.GroupVersionKind.Kind == "Cluster" {
|
||||
return &kubectl.ClusterDescriber{Interface: fedClientSet}, nil
|
||||
}
|
||||
}
|
||||
client, err := clients.ClientForVersion(&mappingVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -354,10 +403,14 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
return nil, fmt.Errorf("no description has been implemented for %q", mapping.GroupVersionKind.Kind)
|
||||
},
|
||||
Decoder: func(toInternal bool) runtime.Decoder {
|
||||
var decoder runtime.Decoder
|
||||
if toInternal {
|
||||
return api.Codecs.UniversalDecoder()
|
||||
decoder = api.Codecs.UniversalDecoder()
|
||||
} else {
|
||||
decoder = api.Codecs.UniversalDeserializer()
|
||||
}
|
||||
return api.Codecs.UniversalDeserializer()
|
||||
return thirdpartyresourcedata.NewDecoder(decoder, "")
|
||||
|
||||
},
|
||||
JSONEncoder: func() runtime.Encoder {
|
||||
return api.Codecs.LegacyCodec(registered.EnabledVersions()...)
|
||||
|
|
@ -395,11 +448,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
}
|
||||
return kubectl.MakeLabels(t.Spec.Selector.MatchLabels), nil
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return "", fmt.Errorf("cannot extract pod selector from %v", gvk)
|
||||
return "", fmt.Errorf("cannot extract pod selector from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
PortsForObject: func(object runtime.Object) ([]string, error) {
|
||||
|
|
@ -416,11 +469,32 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
case *extensions.ReplicaSet:
|
||||
return getPorts(t.Spec.Template.Spec), nil
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot extract ports from %v", gvk)
|
||||
return nil, fmt.Errorf("cannot extract ports from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
ProtocolsForObject: func(object runtime.Object) (map[string]string, error) {
|
||||
// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
|
||||
switch t := object.(type) {
|
||||
case *api.ReplicationController:
|
||||
return getProtocols(t.Spec.Template.Spec), nil
|
||||
case *api.Pod:
|
||||
return getProtocols(t.Spec), nil
|
||||
case *api.Service:
|
||||
return getServiceProtocols(t.Spec), nil
|
||||
case *extensions.Deployment:
|
||||
return getProtocols(t.Spec.Template.Spec), nil
|
||||
case *extensions.ReplicaSet:
|
||||
return getProtocols(t.Spec.Template.Spec), nil
|
||||
default:
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot extract protocols from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
LabelsForObject: func(object runtime.Object) (map[string]string, error) {
|
||||
|
|
@ -478,11 +552,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
return c.Pods(pod.Namespace).GetLogs(pod.Name, opts), nil
|
||||
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot get the logs from %v", gvk)
|
||||
return nil, fmt.Errorf("cannot get the logs from %v", gvks[0])
|
||||
}
|
||||
},
|
||||
PauseObject: func(object runtime.Object) (bool, error) {
|
||||
|
|
@ -500,11 +574,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
_, err := c.Extensions().Deployments(t.Namespace).Update(t)
|
||||
return false, err
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, fmt.Errorf("cannot pause %v", gvk)
|
||||
return false, fmt.Errorf("cannot pause %v", gvks[0])
|
||||
}
|
||||
},
|
||||
ResumeObject: func(object runtime.Object) (bool, error) {
|
||||
|
|
@ -522,11 +596,11 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
_, err := c.Extensions().Deployments(t.Namespace).Update(t)
|
||||
return false, err
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, fmt.Errorf("cannot resume %v", gvk)
|
||||
return false, fmt.Errorf("cannot resume %v", gvks[0])
|
||||
}
|
||||
},
|
||||
Scaler: func(mapping *meta.RESTMapping) (kubectl.Scaler, error) {
|
||||
|
|
@ -562,6 +636,14 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
}
|
||||
return kubectl.RollbackerFor(mapping.GroupVersionKind.GroupKind(), client)
|
||||
},
|
||||
StatusViewer: func(mapping *meta.RESTMapping) (kubectl.StatusViewer, error) {
|
||||
mappingVersion := mapping.GroupVersionKind.GroupVersion()
|
||||
client, err := clients.ClientForVersion(&mappingVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kubectl.StatusViewerFor(mapping.GroupVersionKind.GroupKind(), client)
|
||||
},
|
||||
Validator: func(validate bool, cacheDir string) (validation.Schema, error) {
|
||||
if validate {
|
||||
client, err := clients.ClientForVersion(nil)
|
||||
|
|
@ -576,8 +658,13 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
}
|
||||
dir = path.Join(cacheDir, version.String())
|
||||
}
|
||||
fedClient, err := clients.FederationClientForVersion(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &clientSwaggerSchema{
|
||||
c: client,
|
||||
fedc: fedClient,
|
||||
cacheDir: dir,
|
||||
mapper: api.RESTMapper,
|
||||
}, nil
|
||||
|
|
@ -646,16 +733,68 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
|
|||
case *api.Pod:
|
||||
return t, nil
|
||||
default:
|
||||
gvk, err := api.Scheme.ObjectKind(object)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("cannot attach to %v: not implemented", gvk)
|
||||
return nil, fmt.Errorf("cannot attach to %v: not implemented", gvks[0])
|
||||
}
|
||||
},
|
||||
// UpdatePodSpecForObject update the pod specification for the provided object
|
||||
UpdatePodSpecForObject: func(obj runtime.Object, fn func(*api.PodSpec) error) (bool, error) {
|
||||
// TODO: replace with a swagger schema based approach (identify pod template via schema introspection)
|
||||
switch t := obj.(type) {
|
||||
case *api.Pod:
|
||||
return true, fn(&t.Spec)
|
||||
case *api.ReplicationController:
|
||||
if t.Spec.Template == nil {
|
||||
t.Spec.Template = &api.PodTemplateSpec{}
|
||||
}
|
||||
return true, fn(&t.Spec.Template.Spec)
|
||||
case *extensions.Deployment:
|
||||
return true, fn(&t.Spec.Template.Spec)
|
||||
case *extensions.DaemonSet:
|
||||
return true, fn(&t.Spec.Template.Spec)
|
||||
case *extensions.ReplicaSet:
|
||||
return true, fn(&t.Spec.Template.Spec)
|
||||
case *apps.PetSet:
|
||||
return true, fn(&t.Spec.Template.Spec)
|
||||
case *batch.Job:
|
||||
return true, fn(&t.Spec.Template.Spec)
|
||||
default:
|
||||
return false, fmt.Errorf("the object is not a pod or does not have a pod template")
|
||||
}
|
||||
},
|
||||
EditorEnvs: func() []string {
|
||||
return []string{"KUBE_EDITOR", "EDITOR"}
|
||||
},
|
||||
PrintObjectSpecificMessage: func(obj runtime.Object, out io.Writer) {
|
||||
switch obj := obj.(type) {
|
||||
case *api.Service:
|
||||
if obj.Spec.Type == api.ServiceTypeNodePort {
|
||||
msg := fmt.Sprintf(
|
||||
`You have exposed your service on an external port on all nodes in your
|
||||
cluster. If you want to expose this service to the external internet, you may
|
||||
need to set up firewall rules for the service port(s) (%s) to serve traffic.
|
||||
|
||||
See http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md for more details.
|
||||
`,
|
||||
makePortsString(obj.Spec.Ports, true))
|
||||
out.Write([]byte(msg))
|
||||
}
|
||||
|
||||
if _, ok := obj.Annotations[service.AnnotationLoadBalancerSourceRangesKey]; ok {
|
||||
msg := fmt.Sprintf(
|
||||
`You are using service annotation [service.beta.kubernetes.io/load-balancer-source-ranges].
|
||||
It has been promoted to field [loadBalancerSourceRanges] in service spec. This annotation will be deprecated in the future.
|
||||
Please use the loadBalancerSourceRanges field instead.
|
||||
|
||||
See http://releases.k8s.io/HEAD/docs/user-guide/services-firewalls.md for more details.
|
||||
`)
|
||||
out.Write([]byte(msg))
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -734,6 +873,20 @@ func (f *Factory) BindExternalFlags(flags *pflag.FlagSet) {
|
|||
flags.AddGoFlagSet(flag.CommandLine)
|
||||
}
|
||||
|
||||
func makePortsString(ports []api.ServicePort, useNodePort bool) string {
|
||||
pieces := make([]string, len(ports))
|
||||
for ix := range ports {
|
||||
var port int32
|
||||
if useNodePort {
|
||||
port = ports[ix].NodePort
|
||||
} else {
|
||||
port = ports[ix].Port
|
||||
}
|
||||
pieces[ix] = fmt.Sprintf("%s:%d", strings.ToLower(string(ports[ix].Protocol)), port)
|
||||
}
|
||||
return strings.Join(pieces, ",")
|
||||
}
|
||||
|
||||
func getPorts(spec api.PodSpec) []string {
|
||||
result := []string{}
|
||||
for _, container := range spec.Containers {
|
||||
|
|
@ -744,6 +897,16 @@ func getPorts(spec api.PodSpec) []string {
|
|||
return result
|
||||
}
|
||||
|
||||
func getProtocols(spec api.PodSpec) map[string]string {
|
||||
result := make(map[string]string)
|
||||
for _, container := range spec.Containers {
|
||||
for _, port := range container.Ports {
|
||||
result[strconv.Itoa(int(port.ContainerPort))] = string(port.Protocol)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Extracts the ports exposed by a service from the given service spec.
|
||||
func getServicePorts(spec api.ServiceSpec) []string {
|
||||
result := []string{}
|
||||
|
|
@ -753,8 +916,18 @@ func getServicePorts(spec api.ServiceSpec) []string {
|
|||
return result
|
||||
}
|
||||
|
||||
// Extracts the protocols exposed by a service from the given service spec.
|
||||
func getServiceProtocols(spec api.ServiceSpec) map[string]string {
|
||||
result := make(map[string]string)
|
||||
for _, servicePort := range spec.Ports {
|
||||
result[strconv.Itoa(int(servicePort.Port))] = string(servicePort.Protocol)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
type clientSwaggerSchema struct {
|
||||
c *client.Client
|
||||
fedc *restclient.RESTClient
|
||||
cacheDir string
|
||||
mapper meta.RESTMapper
|
||||
}
|
||||
|
|
@ -815,7 +988,7 @@ func writeSchemaFile(schemaData []byte, cacheDir, cacheFile, prefix, groupVersio
|
|||
return nil
|
||||
}
|
||||
|
||||
func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cacheDir string) (err error) {
|
||||
func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cacheDir string, delegate validation.Schema) (err error) {
|
||||
var schemaData []byte
|
||||
var firstSeen bool
|
||||
fullDir, err := substituteUserHome(cacheDir)
|
||||
|
|
@ -836,7 +1009,7 @@ func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cac
|
|||
return err
|
||||
}
|
||||
}
|
||||
schema, err := validation.NewSwaggerSchemaFromBytes(schemaData)
|
||||
schema, err := validation.NewSwaggerSchemaFromBytes(schemaData, delegate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -849,7 +1022,7 @@ func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cac
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
schema, err := validation.NewSwaggerSchemaFromBytes(schemaData)
|
||||
schema, err := validation.NewSwaggerSchemaFromBytes(schemaData, delegate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -888,20 +1061,32 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
|
|||
if c.c.AutoscalingClient == nil {
|
||||
return errors.New("unable to validate: no autoscaling client")
|
||||
}
|
||||
return getSchemaAndValidate(c.c.AutoscalingClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir)
|
||||
return getSchemaAndValidate(c.c.AutoscalingClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
if gvk.Group == policy.GroupName {
|
||||
if c.c.PolicyClient == nil {
|
||||
return errors.New("unable to validate: no policy client")
|
||||
}
|
||||
return getSchemaAndValidate(c.c.PolicyClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
if gvk.Group == apps.GroupName {
|
||||
if c.c.AppsClient == nil {
|
||||
return errors.New("unable to validate: no autoscaling client")
|
||||
}
|
||||
return getSchemaAndValidate(c.c.AppsClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir)
|
||||
return getSchemaAndValidate(c.c.AppsClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
|
||||
if gvk.Group == batch.GroupName {
|
||||
if c.c.BatchClient == nil {
|
||||
return errors.New("unable to validate: no batch client")
|
||||
}
|
||||
return getSchemaAndValidate(c.c.BatchClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir)
|
||||
return getSchemaAndValidate(c.c.BatchClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
if gvk.Group == rbac.GroupName {
|
||||
if c.c.RbacClient == nil {
|
||||
return errors.New("unable to validate: no rbac client")
|
||||
}
|
||||
return getSchemaAndValidate(c.c.RbacClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
if registered.IsThirdPartyAPIGroupVersion(gvk.GroupVersion()) {
|
||||
// Don't attempt to validate third party objects
|
||||
|
|
@ -911,9 +1096,15 @@ func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
|
|||
if c.c.ExtensionsClient == nil {
|
||||
return errors.New("unable to validate: no experimental client")
|
||||
}
|
||||
return getSchemaAndValidate(c.c.ExtensionsClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir)
|
||||
return getSchemaAndValidate(c.c.ExtensionsClient.RESTClient, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
return getSchemaAndValidate(c.c.RESTClient, data, "api", gvk.GroupVersion().String(), c.cacheDir)
|
||||
if gvk.Group == federation.GroupName {
|
||||
if c.fedc == nil {
|
||||
return errors.New("unable to validate: no federation client")
|
||||
}
|
||||
return getSchemaAndValidate(c.fedc, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
return getSchemaAndValidate(c.c.RESTClient, data, "api", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
|
||||
// DefaultClientConfig creates a clientcmd.ClientConfig with the following hierarchy:
|
||||
|
|
@ -972,12 +1163,12 @@ func DefaultClientConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
|
|||
|
||||
// PrintObject prints an api object given command line flags to modify the output format
|
||||
func (f *Factory) PrintObject(cmd *cobra.Command, mapper meta.RESTMapper, obj runtime.Object, out io.Writer) error {
|
||||
gvk, err := api.Scheme.ObjectKind(obj)
|
||||
gvks, _, err := api.Scheme.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mapping, err := mapper.RESTMapping(gvk.GroupKind())
|
||||
mapping, err := mapper.RESTMapping(gvks[0].GroupKind())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
87
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go
generated
vendored
87
vendor/k8s.io/kubernetes/pkg/kubectl/cmd/util/helpers.go
generated
vendored
|
|
@ -31,6 +31,7 @@ import (
|
|||
"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"
|
||||
|
|
@ -333,7 +334,12 @@ func AddValidateFlags(cmd *cobra.Command) {
|
|||
}
|
||||
|
||||
func AddRecursiveFlag(cmd *cobra.Command, value *bool) {
|
||||
cmd.Flags().BoolVarP(value, "recursive", "R", *value, "If true, process directory recursively.")
|
||||
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.")
|
||||
}
|
||||
|
||||
// AddDryRunFlag adds dry-run flag to a command. Usually used by mutations.
|
||||
func AddDryRunFlag(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")
|
||||
}
|
||||
|
||||
func AddApplyAnnotationFlags(cmd *cobra.Command) {
|
||||
|
|
@ -344,7 +350,7 @@ func AddApplyAnnotationFlags(cmd *cobra.Command) {
|
|||
// TODO: need to take a pass at other generator commands to use this set of flags
|
||||
func AddGeneratorFlags(cmd *cobra.Command, defaultGenerator string) {
|
||||
cmd.Flags().String("generator", defaultGenerator, "The name of the API generator to use.")
|
||||
cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.")
|
||||
AddDryRunFlag(cmd)
|
||||
}
|
||||
|
||||
func ReadConfigDataFromReader(reader io.Reader, source string) ([]byte, error) {
|
||||
|
|
@ -433,6 +439,10 @@ func GetRecordFlag(cmd *cobra.Command) bool {
|
|||
return GetFlagBool(cmd, "record")
|
||||
}
|
||||
|
||||
func GetDryRunFlag(cmd *cobra.Command) bool {
|
||||
return GetFlagBool(cmd, "dry-run")
|
||||
}
|
||||
|
||||
// RecordChangeCause annotate change-cause to input runtime object.
|
||||
func RecordChangeCause(obj runtime.Object, changeCause string) error {
|
||||
accessor, err := meta.Accessor(obj)
|
||||
|
|
@ -479,6 +489,10 @@ func ShouldRecord(cmd *cobra.Command, info *resource.Info) bool {
|
|||
return GetRecordFlag(cmd) || ContainsChangeCause(info)
|
||||
}
|
||||
|
||||
// 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{}
|
||||
|
|
@ -528,3 +542,72 @@ func GetIncludeThirdPartyAPIs(cmd *cobra.Command) bool {
|
|||
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]")
|
||||
}
|
||||
|
||||
// GetResourcesAndPairs retrieves resources and "KEY=VALUE or KEY-" pair args from given args
|
||||
func GetResourcesAndPairs(args []string, pairType string) (resources []string, pairArgs []string, err error) {
|
||||
foundPair := false
|
||||
for _, s := range args {
|
||||
nonResource := strings.Contains(s, "=") || strings.HasSuffix(s, "-")
|
||||
switch {
|
||||
case !foundPair && nonResource:
|
||||
foundPair = true
|
||||
fallthrough
|
||||
case foundPair && nonResource:
|
||||
pairArgs = append(pairArgs, s)
|
||||
case !foundPair && !nonResource:
|
||||
resources = append(resources, s)
|
||||
case foundPair && !nonResource:
|
||||
err = fmt.Errorf("all resources must be specified before %s changes: %s", pairType, s)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ParsePairs retrieves new and remove pairs (if supportRemove is true) from "KEY=VALUE or KEY-" pair args
|
||||
func ParsePairs(pairArgs []string, pairType string, supportRemove bool) (newPairs map[string]string, removePairs []string, err error) {
|
||||
newPairs = map[string]string{}
|
||||
if supportRemove {
|
||||
removePairs = []string{}
|
||||
}
|
||||
var invalidBuf bytes.Buffer
|
||||
|
||||
for _, pairArg := range pairArgs {
|
||||
if strings.Index(pairArg, "=") != -1 {
|
||||
parts := strings.SplitN(pairArg, "=", 2)
|
||||
if len(parts) != 2 || len(parts[1]) == 0 {
|
||||
if invalidBuf.Len() > 0 {
|
||||
invalidBuf.WriteString(", ")
|
||||
}
|
||||
invalidBuf.WriteString(fmt.Sprintf(pairArg))
|
||||
} else {
|
||||
newPairs[parts[0]] = parts[1]
|
||||
}
|
||||
} else if supportRemove && strings.HasSuffix(pairArg, "-") {
|
||||
removePairs = append(removePairs, pairArg[:len(pairArg)-1])
|
||||
} else {
|
||||
if invalidBuf.Len() > 0 {
|
||||
invalidBuf.WriteString(", ")
|
||||
}
|
||||
invalidBuf.WriteString(fmt.Sprintf(pairArg))
|
||||
}
|
||||
}
|
||||
if invalidBuf.Len() > 0 {
|
||||
err = fmt.Errorf("invalid %s format: %s", pairType, invalidBuf.String())
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// MaybeConvertObject attempts to convert an object to a specific group/version. If the object is
|
||||
// a third party resource it is simply passed through.
|
||||
func MaybeConvertObject(obj runtime.Object, gv unversioned.GroupVersion, converter runtime.ObjectConvertor) (runtime.Object, error) {
|
||||
switch obj.(type) {
|
||||
case *extensions.ThirdPartyResourceData:
|
||||
// conversion is not supported for 3rd party objects
|
||||
return obj, nil
|
||||
default:
|
||||
return converter.ConvertToVersion(obj, gv)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
316
vendor/k8s.io/kubernetes/pkg/kubectl/describe.go
generated
vendored
316
vendor/k8s.io/kubernetes/pkg/kubectl/describe.go
generated
vendored
|
|
@ -29,6 +29,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
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/resource"
|
||||
|
|
@ -101,6 +103,7 @@ func describerMap(c *client.Client) map[unversioned.GroupKind]Describer {
|
|||
|
||||
extensions.Kind("ReplicaSet"): &ReplicaSetDescriber{c},
|
||||
extensions.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
|
||||
extensions.Kind("NetworkPolicy"): &NetworkPolicyDescriber{c},
|
||||
autoscaling.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c},
|
||||
extensions.Kind("DaemonSet"): &DaemonSetDescriber{c},
|
||||
extensions.Kind("Deployment"): &DeploymentDescriber{adapter.FromUnversionedClient(c)},
|
||||
|
|
@ -277,7 +280,7 @@ func DescribeResourceQuotas(quotas *api.ResourceQuotaList, w io.Writer) {
|
|||
for _, q := range quotas.Items {
|
||||
fmt.Fprintf(w, "\n Name:\t%s\n", q.Name)
|
||||
if len(q.Spec.Scopes) > 0 {
|
||||
scopes := []string{}
|
||||
scopes := make([]string, 0, len(q.Spec.Scopes))
|
||||
for _, scope := range q.Spec.Scopes {
|
||||
scopes = append(scopes, string(scope))
|
||||
}
|
||||
|
|
@ -294,7 +297,7 @@ func DescribeResourceQuotas(quotas *api.ResourceQuotaList, w io.Writer) {
|
|||
fmt.Fprintf(w, " Resource\tUsed\tHard\n")
|
||||
fmt.Fprint(w, " --------\t---\t---\n")
|
||||
|
||||
resources := []api.ResourceName{}
|
||||
resources := make([]api.ResourceName, 0, len(q.Status.Hard))
|
||||
for resource := range q.Status.Hard {
|
||||
resources = append(resources, resource)
|
||||
}
|
||||
|
|
@ -430,7 +433,7 @@ func describeQuota(resourceQuota *api.ResourceQuota) (string, error) {
|
|||
fmt.Fprintf(out, "Name:\t%s\n", resourceQuota.Name)
|
||||
fmt.Fprintf(out, "Namespace:\t%s\n", resourceQuota.Namespace)
|
||||
if len(resourceQuota.Spec.Scopes) > 0 {
|
||||
scopes := []string{}
|
||||
scopes := make([]string, 0, len(resourceQuota.Spec.Scopes))
|
||||
for _, scope := range resourceQuota.Spec.Scopes {
|
||||
scopes = append(scopes, string(scope))
|
||||
}
|
||||
|
|
@ -446,7 +449,7 @@ func describeQuota(resourceQuota *api.ResourceQuota) (string, error) {
|
|||
fmt.Fprintf(out, "Resource\tUsed\tHard\n")
|
||||
fmt.Fprintf(out, "--------\t----\t----\n")
|
||||
|
||||
resources := []api.ResourceName{}
|
||||
resources := make([]api.ResourceName, 0, len(resourceQuota.Status.Hard))
|
||||
for resource := range resourceQuota.Status.Hard {
|
||||
resources = append(resources, resource)
|
||||
}
|
||||
|
|
@ -524,7 +527,10 @@ func describePod(pod *api.Pod, events *api.EventList) (string, error) {
|
|||
}
|
||||
fmt.Fprintf(out, "IP:\t%s\n", pod.Status.PodIP)
|
||||
fmt.Fprintf(out, "Controllers:\t%s\n", printControllers(pod.Annotations))
|
||||
describeContainers(pod.Spec.Containers, pod.Status.ContainerStatuses, EnvValueRetriever(pod), out, "")
|
||||
if len(pod.Spec.InitContainers) > 0 {
|
||||
describeContainers("Init Containers", pod.Spec.InitContainers, pod.Status.InitContainerStatuses, EnvValueRetriever(pod), out, "")
|
||||
}
|
||||
describeContainers("Containers", pod.Spec.Containers, pod.Status.ContainerStatuses, EnvValueRetriever(pod), out, "")
|
||||
if len(pod.Status.Conditions) > 0 {
|
||||
fmt.Fprint(out, "Conditions:\n Type\tStatus\n")
|
||||
for _, c := range pod.Status.Conditions {
|
||||
|
|
@ -534,6 +540,7 @@ func describePod(pod *api.Pod, events *api.EventList) (string, error) {
|
|||
}
|
||||
}
|
||||
describeVolumes(pod.Spec.Volumes, out, "")
|
||||
fmt.Fprintf(out, "QoS Tier:\t%s\n", qosutil.GetPodQos(pod))
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
|
|
@ -694,7 +701,12 @@ func printRBDVolumeSource(rbd *api.RBDVolumeSource, out io.Writer) {
|
|||
func printDownwardAPIVolumeSource(d *api.DownwardAPIVolumeSource, out io.Writer) {
|
||||
fmt.Fprintf(out, " Type:\tDownwardAPI (a volume populated by information about the pod)\n Items:\n")
|
||||
for _, mapping := range d.Items {
|
||||
fmt.Fprintf(out, " %v -> %v\n", mapping.FieldRef.FieldPath, mapping.Path)
|
||||
if mapping.FieldRef != nil {
|
||||
fmt.Fprintf(out, " %v -> %v\n", mapping.FieldRef.FieldPath, mapping.Path)
|
||||
}
|
||||
if mapping.ResourceFieldRef != nil {
|
||||
fmt.Fprintf(out, " %v -> %v\n", mapping.ResourceFieldRef.Resource, mapping.Path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -712,6 +724,11 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
|
|||
|
||||
storage := pv.Spec.Capacity[api.ResourceStorage]
|
||||
|
||||
var events *api.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.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)
|
||||
|
|
@ -744,6 +761,10 @@ func (d *PersistentVolumeDescriber) Describe(namespace, name string, describerSe
|
|||
printRBDVolumeSource(pv.Spec.RBD, out)
|
||||
}
|
||||
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
@ -769,6 +790,8 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
|
|||
capacity = storage.String()
|
||||
}
|
||||
|
||||
events, _ := d.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)
|
||||
|
|
@ -777,17 +800,25 @@ func (d *PersistentVolumeClaimDescriber) Describe(namespace, name string, descri
|
|||
printLabelsMultiline(out, "Labels", pvc.Labels)
|
||||
fmt.Fprintf(out, "Capacity:\t%s\n", capacity)
|
||||
fmt.Fprintf(out, "Access Modes:\t%s\n", accessModes)
|
||||
if events != nil {
|
||||
DescribeEvents(events, out)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: Do a better job at indenting, maybe by using a prefix writer
|
||||
func describeContainers(containers []api.Container, containerStatuses []api.ContainerStatus, resolverFn EnvVarResolverFunc, out io.Writer, space string) {
|
||||
func describeContainers(label string, containers []api.Container, containerStatuses []api.ContainerStatus, resolverFn EnvVarResolverFunc, out io.Writer, space string) {
|
||||
statuses := map[string]api.ContainerStatus{}
|
||||
for _, status := range containerStatuses {
|
||||
statuses[status.Name] = status
|
||||
}
|
||||
fmt.Fprintf(out, "%sContainers:\n", space)
|
||||
if len(containers) == 0 {
|
||||
fmt.Fprintf(out, "%s%s: <none>\n", space, label)
|
||||
} else {
|
||||
fmt.Fprintf(out, "%s%s:\n", space, label)
|
||||
}
|
||||
for _, container := range containers {
|
||||
status, ok := statuses[container.Name]
|
||||
nameIndent := ""
|
||||
|
|
@ -822,25 +853,20 @@ func describeContainers(containers []api.Container, containerStatuses []api.Cont
|
|||
}
|
||||
}
|
||||
|
||||
resourceToQoS := qosutil.GetQoS(&container)
|
||||
if len(resourceToQoS) > 0 {
|
||||
fmt.Fprintf(out, " QoS Tier:\n")
|
||||
}
|
||||
for resource, qos := range resourceToQoS {
|
||||
fmt.Fprintf(out, " %s:\t%s\n", resource, qos)
|
||||
}
|
||||
|
||||
if len(container.Resources.Limits) > 0 {
|
||||
resources := container.Resources
|
||||
if len(resources.Limits) > 0 {
|
||||
fmt.Fprintf(out, " Limits:\n")
|
||||
}
|
||||
for name, quantity := range container.Resources.Limits {
|
||||
for _, name := range SortedResourceNames(resources.Limits) {
|
||||
quantity := resources.Limits[name]
|
||||
fmt.Fprintf(out, " %s:\t%s\n", name, quantity.String())
|
||||
}
|
||||
|
||||
if len(container.Resources.Requests) > 0 {
|
||||
if len(resources.Requests) > 0 {
|
||||
fmt.Fprintf(out, " Requests:\n")
|
||||
}
|
||||
for name, quantity := range container.Resources.Requests {
|
||||
for _, name := range SortedResourceNames(resources.Requests) {
|
||||
quantity := resources.Requests[name]
|
||||
fmt.Fprintf(out, " %s:\t%s\n", name, quantity.String())
|
||||
}
|
||||
|
||||
|
|
@ -879,6 +905,12 @@ func describeContainers(containers []api.Container, containerStatuses []api.Cont
|
|||
valueFrom = resolverFn(e)
|
||||
}
|
||||
fmt.Fprintf(out, " %s:\t%s (%s:%s)\n", e.Name, valueFrom, e.ValueFrom.FieldRef.APIVersion, e.ValueFrom.FieldRef.FieldPath)
|
||||
case e.ValueFrom.ResourceFieldRef != nil:
|
||||
valueFrom, err := fieldpath.ExtractContainerResourceValue(e.ValueFrom.ResourceFieldRef, &container)
|
||||
if err != nil {
|
||||
valueFrom = ""
|
||||
}
|
||||
fmt.Fprintf(out, " %s:\t%s (%s)\n", e.Name, valueFrom, e.ValueFrom.ResourceFieldRef.Resource)
|
||||
case e.ValueFrom.SecretKeyRef != nil:
|
||||
fmt.Fprintf(out, " %s:\t<set to the key '%s' in secret '%s'>\n", e.Name, e.ValueFrom.SecretKeyRef.Key, e.ValueFrom.SecretKeyRef.Name)
|
||||
case e.ValueFrom.ConfigMapKeyRef != nil:
|
||||
|
|
@ -889,7 +921,7 @@ func describeContainers(containers []api.Container, containerStatuses []api.Cont
|
|||
}
|
||||
|
||||
func describeContainerPorts(cPorts []api.ContainerPort) string {
|
||||
ports := []string{}
|
||||
ports := make([]string, 0, len(cPorts))
|
||||
for _, cPort := range cPorts {
|
||||
ports = append(ports, fmt.Sprintf("%d/%s", cPort.ContainerPort, cPort.Protocol))
|
||||
}
|
||||
|
|
@ -1037,7 +1069,10 @@ func DescribePodTemplate(template *api.PodTemplateSpec, out io.Writer) {
|
|||
if len(template.Spec.ServiceAccountName) > 0 {
|
||||
fmt.Fprintf(out, " Service Account:\t%s\n", template.Spec.ServiceAccountName)
|
||||
}
|
||||
describeContainers(template.Spec.Containers, nil, nil, out, " ")
|
||||
if len(template.Spec.InitContainers) > 0 {
|
||||
describeContainers("Init Containers", template.Spec.InitContainers, nil, nil, out, " ")
|
||||
}
|
||||
describeContainers("Containers", template.Spec.Containers, nil, nil, out, " ")
|
||||
describeVolumes(template.Spec.Volumes, out, " ")
|
||||
}
|
||||
|
||||
|
|
@ -1268,7 +1303,7 @@ func (i *IngressDescriber) describeIngress(ing *extensions.Ingress, describerSet
|
|||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%v\n", ing.Name)
|
||||
fmt.Fprintf(out, "Namespace:\t%v\n", ing.Namespace)
|
||||
fmt.Fprintf(out, "Address:\t%v\n", loadBalancerStatusStringer(ing.Status.LoadBalancer))
|
||||
fmt.Fprintf(out, "Address:\t%v\n", loadBalancerStatusStringer(ing.Status.LoadBalancer, true))
|
||||
def := ing.Spec.Backend
|
||||
ns := ing.Namespace
|
||||
if def == nil {
|
||||
|
|
@ -1286,14 +1321,23 @@ func (i *IngressDescriber) describeIngress(ing *extensions.Ingress, describerSet
|
|||
}
|
||||
fmt.Fprint(out, "Rules:\n Host\tPath\tBackends\n")
|
||||
fmt.Fprint(out, " ----\t----\t--------\n")
|
||||
count := 0
|
||||
for _, rules := range ing.Spec.Rules {
|
||||
if rules.HTTP == nil {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(out, " %s\t\n", rules.Host)
|
||||
for _, path := range rules.HTTP.Paths {
|
||||
fmt.Fprintf(out, " \t%s \t%s (%s)\n", path.Path, backendStringer(&path.Backend), i.describeBackend(ing.Namespace, &path.Backend))
|
||||
count++
|
||||
host := rules.Host
|
||||
if len(host) == 0 {
|
||||
host = "*"
|
||||
}
|
||||
fmt.Fprintf(out, " %s\t\n", host)
|
||||
for _, path := range rules.HTTP.Paths {
|
||||
fmt.Fprintf(out, " \t%s \t%s (%s)\n", path.Path, backendStringer(&path.Backend), i.describeBackend(ns, &path.Backend))
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
fmt.Fprintf(out, " %s\t%s \t%s (%s)\n", "*", "*", backendStringer(def), i.describeBackend(ns, def))
|
||||
}
|
||||
describeIngressAnnotations(out, ing.Annotations)
|
||||
|
||||
|
|
@ -1437,7 +1481,7 @@ func describeEndpoints(ep *api.Endpoints, events *api.EventList) (string, error)
|
|||
for i := range ep.Subsets {
|
||||
subset := &ep.Subsets[i]
|
||||
|
||||
addresses := []string{}
|
||||
addresses := make([]string, 0, len(subset.Addresses))
|
||||
for _, addr := range subset.Addresses {
|
||||
addresses = append(addresses, addr.IP)
|
||||
}
|
||||
|
|
@ -1447,7 +1491,7 @@ func describeEndpoints(ep *api.Endpoints, events *api.EventList) (string, error)
|
|||
}
|
||||
fmt.Fprintf(out, " Addresses:\t%s\n", addressesString)
|
||||
|
||||
notReadyAddresses := []string{}
|
||||
notReadyAddresses := make([]string, 0, len(subset.NotReadyAddresses))
|
||||
for _, addr := range subset.NotReadyAddresses {
|
||||
notReadyAddresses = append(notReadyAddresses, addr.IP)
|
||||
}
|
||||
|
|
@ -1605,6 +1649,7 @@ func describeNode(node *api.Node, nodeNonTerminatedPodsList *api.PodList, events
|
|||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", node.Name)
|
||||
printLabelsMultiline(out, "Labels", node.Labels)
|
||||
printTaintsInAnnotationMultiline(out, "Taints", node.Annotations)
|
||||
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", node.CreationTimestamp.Time.Format(time.RFC1123Z))
|
||||
fmt.Fprintf(out, "Phase:\t%v\n", node.Status.Phase)
|
||||
if len(node.Status.Conditions) > 0 {
|
||||
|
|
@ -1620,16 +1665,31 @@ func describeNode(node *api.Node, nodeNonTerminatedPodsList *api.PodList, events
|
|||
c.Message)
|
||||
}
|
||||
}
|
||||
var addresses []string
|
||||
addresses := make([]string, 0, len(node.Status.Addresses))
|
||||
for _, address := range node.Status.Addresses {
|
||||
addresses = append(addresses, address.Address)
|
||||
}
|
||||
|
||||
printResourceList := func(resourceList api.ResourceList) {
|
||||
resources := make([]api.ResourceName, 0, len(resourceList))
|
||||
for resource := range resourceList {
|
||||
resources = append(resources, resource)
|
||||
}
|
||||
sort.Sort(SortableResourceNames(resources))
|
||||
for _, resource := range resources {
|
||||
value := resourceList[resource]
|
||||
fmt.Fprintf(out, " %s:\t%s\n", resource, value.String())
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "Addresses:\t%s\n", strings.Join(addresses, ","))
|
||||
if len(node.Status.Capacity) > 0 {
|
||||
fmt.Fprintf(out, "Capacity:\n")
|
||||
for resource, value := range node.Status.Capacity {
|
||||
fmt.Fprintf(out, " %s:\t%s\n", resource, value.String())
|
||||
}
|
||||
printResourceList(node.Status.Capacity)
|
||||
}
|
||||
if len(node.Status.Allocatable) > 0 {
|
||||
fmt.Fprintf(out, "Allocatable:\n")
|
||||
printResourceList(node.Status.Allocatable)
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "System Info:\n")
|
||||
|
|
@ -1638,6 +1698,8 @@ func describeNode(node *api.Node, nodeNonTerminatedPodsList *api.PodList, events
|
|||
fmt.Fprintf(out, " Boot ID:\t%s\n", node.Status.NodeInfo.BootID)
|
||||
fmt.Fprintf(out, " Kernel Version:\t%s\n", node.Status.NodeInfo.KernelVersion)
|
||||
fmt.Fprintf(out, " OS Image:\t%s\n", node.Status.NodeInfo.OSImage)
|
||||
fmt.Fprintf(out, " Operating System:\t%s\n", node.Status.NodeInfo.OperatingSystem)
|
||||
fmt.Fprintf(out, " Architecture:\t%s\n", node.Status.NodeInfo.Architecture)
|
||||
fmt.Fprintf(out, " Container Runtime Version:\t%s\n", node.Status.NodeInfo.ContainerRuntimeVersion)
|
||||
fmt.Fprintf(out, " Kubelet Version:\t%s\n", node.Status.NodeInfo.KubeletVersion)
|
||||
fmt.Fprintf(out, " Kube-Proxy Version:\t%s\n", node.Status.NodeInfo.KubeProxyVersion)
|
||||
|
|
@ -1710,7 +1772,7 @@ type HorizontalPodAutoscalerDescriber struct {
|
|||
}
|
||||
|
||||
func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
hpa, err := d.client.Extensions().HorizontalPodAutoscalers(namespace).Get(name)
|
||||
hpa, err := d.client.Autoscaling().HorizontalPodAutoscalers(namespace).Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
@ -1720,12 +1782,11 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, desc
|
|||
printLabelsMultiline(out, "Labels", hpa.Labels)
|
||||
printLabelsMultiline(out, "Annotations", hpa.Annotations)
|
||||
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", hpa.CreationTimestamp.Time.Format(time.RFC1123Z))
|
||||
fmt.Fprintf(out, "Reference:\t%s/%s/%s\n",
|
||||
hpa.Spec.ScaleRef.Kind,
|
||||
hpa.Spec.ScaleRef.Name,
|
||||
hpa.Spec.ScaleRef.Subresource)
|
||||
if hpa.Spec.CPUUtilization != nil {
|
||||
fmt.Fprintf(out, "Target CPU utilization:\t%d%%\n", hpa.Spec.CPUUtilization.TargetPercentage)
|
||||
fmt.Fprintf(out, "Reference:\t%s/%s\n",
|
||||
hpa.Spec.ScaleTargetRef.Kind,
|
||||
hpa.Spec.ScaleTargetRef.Name)
|
||||
if hpa.Spec.TargetCPUUtilizationPercentage != nil {
|
||||
fmt.Fprintf(out, "Target CPU utilization:\t%d%%\n", *hpa.Spec.TargetCPUUtilizationPercentage)
|
||||
fmt.Fprintf(out, "Current CPU utilization:\t")
|
||||
if hpa.Status.CurrentCPUUtilizationPercentage != nil {
|
||||
fmt.Fprintf(out, "%d%%\n", *hpa.Status.CurrentCPUUtilizationPercentage)
|
||||
|
|
@ -1741,9 +1802,9 @@ func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, desc
|
|||
fmt.Fprintf(out, "Max replicas:\t%d\n", hpa.Spec.MaxReplicas)
|
||||
|
||||
// TODO: switch to scale subresource once the required code is submitted.
|
||||
if strings.ToLower(hpa.Spec.ScaleRef.Kind) == "replicationcontroller" {
|
||||
if strings.ToLower(hpa.Spec.ScaleTargetRef.Kind) == "replicationcontroller" {
|
||||
fmt.Fprintf(out, "ReplicationController pods:\t")
|
||||
rc, err := d.client.ReplicationControllers(hpa.Namespace).Get(hpa.Spec.ScaleRef.Name)
|
||||
rc, err := d.client.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 {
|
||||
|
|
@ -1765,16 +1826,21 @@ func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node
|
|||
fmt.Fprintf(out, "Non-terminated Pods:\t(%d in total)\n", len(nodeNonTerminatedPodsList.Items))
|
||||
fmt.Fprint(out, " Namespace\tName\t\tCPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\n")
|
||||
fmt.Fprint(out, " ---------\t----\t\t------------\t----------\t---------------\t-------------\n")
|
||||
allocatable := node.Status.Capacity
|
||||
if len(node.Status.Allocatable) > 0 {
|
||||
allocatable = node.Status.Allocatable
|
||||
}
|
||||
|
||||
for _, pod := range nodeNonTerminatedPodsList.Items {
|
||||
req, limit, err := api.PodRequestsAndLimits(&pod)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cpuReq, cpuLimit, memoryReq, memoryLimit := req[api.ResourceCPU], limit[api.ResourceCPU], req[api.ResourceMemory], limit[api.ResourceMemory]
|
||||
fractionCpuReq := float64(cpuReq.MilliValue()) / float64(node.Status.Capacity.Cpu().MilliValue()) * 100
|
||||
fractionCpuLimit := float64(cpuLimit.MilliValue()) / float64(node.Status.Capacity.Cpu().MilliValue()) * 100
|
||||
fractionMemoryReq := float64(memoryReq.MilliValue()) / float64(node.Status.Capacity.Memory().MilliValue()) * 100
|
||||
fractionMemoryLimit := float64(memoryLimit.MilliValue()) / float64(node.Status.Capacity.Memory().MilliValue()) * 100
|
||||
fractionCpuReq := float64(cpuReq.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
|
||||
fractionCpuLimit := float64(cpuLimit.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
|
||||
fractionMemoryReq := float64(memoryReq.Value()) / float64(allocatable.Memory().Value()) * 100
|
||||
fractionMemoryLimit := float64(memoryLimit.Value()) / float64(allocatable.Memory().Value()) * 100
|
||||
fmt.Fprintf(out, " %s\t%s\t\t%s (%d%%)\t%s (%d%%)\t%s (%d%%)\t%s (%d%%)\n", pod.Namespace, pod.Name,
|
||||
cpuReq.String(), int64(fractionCpuReq), cpuLimit.String(), int64(fractionCpuLimit),
|
||||
memoryReq.String(), int64(fractionMemoryReq), memoryLimit.String(), int64(fractionMemoryLimit))
|
||||
|
|
@ -1787,10 +1853,10 @@ func describeNodeResource(nodeNonTerminatedPodsList *api.PodList, node *api.Node
|
|||
return err
|
||||
}
|
||||
cpuReqs, cpuLimits, memoryReqs, memoryLimits := reqs[api.ResourceCPU], limits[api.ResourceCPU], reqs[api.ResourceMemory], limits[api.ResourceMemory]
|
||||
fractionCpuReqs := float64(cpuReqs.MilliValue()) / float64(node.Status.Capacity.Cpu().MilliValue()) * 100
|
||||
fractionCpuLimits := float64(cpuLimits.MilliValue()) / float64(node.Status.Capacity.Cpu().MilliValue()) * 100
|
||||
fractionMemoryReqs := float64(memoryReqs.MilliValue()) / float64(node.Status.Capacity.Memory().MilliValue()) * 100
|
||||
fractionMemoryLimits := float64(memoryLimits.MilliValue()) / float64(node.Status.Capacity.Memory().MilliValue()) * 100
|
||||
fractionCpuReqs := float64(cpuReqs.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
|
||||
fractionCpuLimits := float64(cpuLimits.MilliValue()) / float64(allocatable.Cpu().MilliValue()) * 100
|
||||
fractionMemoryReqs := float64(memoryReqs.Value()) / float64(allocatable.Memory().Value()) * 100
|
||||
fractionMemoryLimits := float64(memoryLimits.Value()) / float64(allocatable.Memory().Value()) * 100
|
||||
fmt.Fprintf(out, " %s (%d%%)\t%s (%d%%)\t%s (%d%%)\t%s (%d%%)\n",
|
||||
cpuReqs.String(), int64(fractionCpuReqs), cpuLimits.String(), int64(fractionCpuLimits),
|
||||
memoryReqs.String(), int64(fractionMemoryReqs), memoryLimits.String(), int64(fractionMemoryLimits))
|
||||
|
|
@ -1821,15 +1887,17 @@ func getPodsTotalRequestsAndLimits(podList *api.PodList) (reqs map[api.ResourceN
|
|||
for podReqName, podReqValue := range podReqs {
|
||||
if value, ok := reqs[podReqName]; !ok {
|
||||
reqs[podReqName] = *podReqValue.Copy()
|
||||
} else if err = value.Add(podReqValue); err != nil {
|
||||
return nil, nil, err
|
||||
} else {
|
||||
value.Add(podReqValue)
|
||||
reqs[podReqName] = value
|
||||
}
|
||||
}
|
||||
for podLimitName, podLimitValue := range podLimits {
|
||||
if value, ok := limits[podLimitName]; !ok {
|
||||
limits[podLimitName] = *podLimitValue.Copy()
|
||||
} else if err = value.Add(podLimitValue); err != nil {
|
||||
return nil, nil, err
|
||||
} else {
|
||||
value.Add(podLimitValue)
|
||||
limits[podLimitName] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1884,12 +1952,9 @@ 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())
|
||||
}
|
||||
oldRSs, _, err := deploymentutil.GetOldReplicaSets(d, dd)
|
||||
oldRSs, _, newRS, err := deploymentutil.GetAllReplicaSets(d, dd)
|
||||
if err == nil {
|
||||
fmt.Fprintf(out, "OldReplicaSets:\t%s\n", printReplicaSetsByLabels(oldRSs))
|
||||
}
|
||||
newRS, err := deploymentutil.GetNewReplicaSet(d, dd)
|
||||
if err == nil {
|
||||
var newRSs []*extensions.ReplicaSet
|
||||
if newRS != nil {
|
||||
newRSs = append(newRSs, newRS)
|
||||
|
|
@ -1936,7 +2001,7 @@ func getDaemonSetsForLabels(c client.DaemonSetInterface, labelsToMatch labels.La
|
|||
|
||||
func printReplicationControllersByLabels(matchingRCs []*api.ReplicationController) string {
|
||||
// Format the matching RC's into strings.
|
||||
var rcStrings []string
|
||||
rcStrings := make([]string, 0, len(matchingRCs))
|
||||
for _, controller := range matchingRCs {
|
||||
rcStrings = append(rcStrings, fmt.Sprintf("%s (%d/%d replicas created)", controller.Name, controller.Status.Replicas, controller.Spec.Replicas))
|
||||
}
|
||||
|
|
@ -1950,7 +2015,7 @@ func printReplicationControllersByLabels(matchingRCs []*api.ReplicationControlle
|
|||
|
||||
func printReplicaSetsByLabels(matchingRSs []*extensions.ReplicaSet) string {
|
||||
// Format the matching ReplicaSets into strings.
|
||||
var rsStrings []string
|
||||
rsStrings := make([]string, 0, len(matchingRSs))
|
||||
for _, rs := range matchingRSs {
|
||||
rsStrings = append(rsStrings, fmt.Sprintf("%s (%d/%d replicas created)", rs.Name, rs.Status.Replicas, rs.Spec.Replicas))
|
||||
}
|
||||
|
|
@ -2015,9 +2080,92 @@ func describeConfigMap(configMap *api.ConfigMap) (string, error) {
|
|||
})
|
||||
}
|
||||
|
||||
type ClusterDescriber struct {
|
||||
fed_clientset.Interface
|
||||
}
|
||||
|
||||
func (d *ClusterDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
cluster, err := d.Federation().Clusters().Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return describeCluster(cluster)
|
||||
}
|
||||
|
||||
func describeCluster(cluster *federation.Cluster) (string, error) {
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", cluster.Name)
|
||||
fmt.Fprintf(out, "Labels:\t%s\n", labels.FormatLabels(cluster.Labels))
|
||||
|
||||
fmt.Fprintf(out, "ServerAddressByClientCIDRs:\n ClientCIDR\tServerAddress\n")
|
||||
fmt.Fprintf(out, " ----\t----\n")
|
||||
for _, cidrAddr := range cluster.Spec.ServerAddressByClientCIDRs {
|
||||
fmt.Fprintf(out, " %v \t%v\n\n", cidrAddr.ClientCIDR, cidrAddr.ServerAddress)
|
||||
}
|
||||
|
||||
if len(cluster.Status.Conditions) > 0 {
|
||||
fmt.Fprint(out, "Conditions:\n Type\tStatus\tLastUpdateTime\tLastTransitionTime\tReason\tMessage\n")
|
||||
fmt.Fprint(out, " ----\t------\t-----------------\t------------------\t------\t-------\n")
|
||||
for _, c := range cluster.Status.Conditions {
|
||||
fmt.Fprintf(out, " %v \t%v \t%s \t%s \t%v \t%v\n",
|
||||
c.Type,
|
||||
c.Status,
|
||||
c.LastProbeTime.Time.Format(time.RFC1123Z),
|
||||
c.LastTransitionTime.Time.Format(time.RFC1123Z),
|
||||
c.Reason,
|
||||
c.Message)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "Version:\t%s\n", cluster.Status.Version)
|
||||
|
||||
if len(cluster.Status.Capacity) > 0 {
|
||||
fmt.Fprintf(out, "Capacity:\n")
|
||||
for resource, value := range cluster.Status.Capacity {
|
||||
fmt.Fprintf(out, " %s:\t%s\n", resource, value.String())
|
||||
}
|
||||
}
|
||||
|
||||
if len(cluster.Status.Allocatable) > 0 {
|
||||
fmt.Fprintf(out, "Allocatable:\n")
|
||||
for resource, value := range cluster.Status.Allocatable {
|
||||
fmt.Fprintf(out, " %s:\t%s\n", resource, value.String())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// NetworkPolicyDescriber generates information about a NetworkPolicy
|
||||
type NetworkPolicyDescriber struct {
|
||||
client.Interface
|
||||
}
|
||||
|
||||
func (d *NetworkPolicyDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) {
|
||||
c := d.Extensions().NetworkPolicies(namespace)
|
||||
|
||||
networkPolicy, err := c.Get(name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return describeNetworkPolicy(networkPolicy)
|
||||
}
|
||||
|
||||
func describeNetworkPolicy(networkPolicy *extensions.NetworkPolicy) (string, error) {
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "Name:\t%s\n", networkPolicy.Name)
|
||||
fmt.Fprintf(out, "Namespace:\t%s\n", networkPolicy.Namespace)
|
||||
printLabelsMultiline(out, "Labels", networkPolicy.Labels)
|
||||
printLabelsMultiline(out, "Annotations", networkPolicy.Annotations)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// newErrNoDescriber creates a new ErrNoDescriber with the names of the provided types.
|
||||
func newErrNoDescriber(types ...reflect.Type) error {
|
||||
names := []string{}
|
||||
names := make([]string, 0, len(types))
|
||||
for _, t := range types {
|
||||
names = append(names, t.String())
|
||||
}
|
||||
|
|
@ -2056,7 +2204,7 @@ func (d *Describers) DescribeObject(exact interface{}, extra ...interface{}) (st
|
|||
return fns[0].Describe(exact, extra...)
|
||||
}
|
||||
|
||||
types := []reflect.Type{}
|
||||
types := make([]reflect.Type, 0, len(extra))
|
||||
for _, obj := range extra {
|
||||
types = append(types, reflect.TypeOf(obj))
|
||||
}
|
||||
|
|
@ -2081,14 +2229,15 @@ func (d *Describers) Add(fns ...interface{}) error {
|
|||
if ft.Kind() != reflect.Func {
|
||||
return fmt.Errorf("expected func, got: %v", ft)
|
||||
}
|
||||
if ft.NumIn() == 0 {
|
||||
numIn := ft.NumIn()
|
||||
if numIn == 0 {
|
||||
return fmt.Errorf("expected at least one 'in' params, got: %v", ft)
|
||||
}
|
||||
if ft.NumOut() != 2 {
|
||||
return fmt.Errorf("expected two 'out' params - (string, error), got: %v", ft)
|
||||
}
|
||||
types := []reflect.Type{}
|
||||
for i := 0; i < ft.NumIn(); i++ {
|
||||
types := make([]reflect.Type, 0, numIn)
|
||||
for i := 0; i < numIn; i++ {
|
||||
types = append(types, ft.In(i))
|
||||
}
|
||||
if ft.Out(0) != reflect.TypeOf(string("")) {
|
||||
|
|
@ -2186,3 +2335,42 @@ func printLabelsMultilineWithIndent(out io.Writer, initialIndent, title, innerIn
|
|||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// printTaintsMultiline prints multiple taints with a proper alignment.
|
||||
func printTaintsInAnnotationMultiline(out io.Writer, title string, annotations map[string]string) {
|
||||
taints, err := api.GetTaintsFromNodeAnnotations(annotations)
|
||||
if err != nil {
|
||||
taints = []api.Taint{}
|
||||
}
|
||||
printTaintsMultilineWithIndent(out, "", title, "\t", taints)
|
||||
}
|
||||
|
||||
// printTaintsMultilineWithIndent prints multiple taints with a user-defined alignment.
|
||||
func printTaintsMultilineWithIndent(out io.Writer, initialIndent, title, innerIndent string, taints []api.Taint) {
|
||||
fmt.Fprintf(out, "%s%s:%s", initialIndent, title, innerIndent)
|
||||
|
||||
if taints == nil || len(taints) == 0 {
|
||||
fmt.Fprintln(out, "<none>")
|
||||
return
|
||||
}
|
||||
|
||||
// to print taints in the sorted order
|
||||
keys := make([]string, 0, len(taints))
|
||||
for _, taint := range taints {
|
||||
keys = append(keys, taint.Key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
for i, key := range keys {
|
||||
for _, taint := range taints {
|
||||
if taint.Key == key {
|
||||
if i != 0 {
|
||||
fmt.Fprint(out, initialIndent)
|
||||
fmt.Fprint(out, innerIndent)
|
||||
}
|
||||
fmt.Fprintf(out, "%s=%s:%s\n", taint.Key, taint.Value, taint.Effect)
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
28
vendor/k8s.io/kubernetes/pkg/kubectl/generate.go
generated
vendored
28
vendor/k8s.io/kubernetes/pkg/kubectl/generate.go
generated
vendored
|
|
@ -134,6 +134,34 @@ func MakeParams(cmd *cobra.Command, params []GeneratorParam) map[string]interfac
|
|||
return result
|
||||
}
|
||||
|
||||
func MakeProtocols(protocols map[string]string) string {
|
||||
out := []string{}
|
||||
for key, value := range protocols {
|
||||
out = append(out, fmt.Sprintf("%s/%s", key, value))
|
||||
}
|
||||
return strings.Join(out, ",")
|
||||
}
|
||||
|
||||
func ParseProtocols(protocols interface{}) (map[string]string, error) {
|
||||
protocolsString, isString := protocols.(string)
|
||||
if !isString {
|
||||
return nil, fmt.Errorf("expected string, found %v", protocols)
|
||||
}
|
||||
if len(protocolsString) == 0 {
|
||||
return nil, fmt.Errorf("no protocols passed")
|
||||
}
|
||||
portProtocolMap := map[string]string{}
|
||||
protocolsSlice := strings.Split(protocolsString, ",")
|
||||
for ix := range protocolsSlice {
|
||||
portProtocol := strings.Split(protocolsSlice[ix], "/")
|
||||
if len(portProtocol) != 2 {
|
||||
return nil, fmt.Errorf("unexpected port protocol mapping: %s", protocolsSlice[ix])
|
||||
}
|
||||
portProtocolMap[portProtocol[0]] = portProtocol[1]
|
||||
}
|
||||
return portProtocolMap, nil
|
||||
}
|
||||
|
||||
func MakeLabels(labels map[string]string) string {
|
||||
out := []string{}
|
||||
for key, value := range labels {
|
||||
|
|
|
|||
35
vendor/k8s.io/kubernetes/pkg/kubectl/history.go
generated
vendored
35
vendor/k8s.io/kubernetes/pkg/kubectl/history.go
generated
vendored
|
|
@ -19,8 +19,6 @@ package kubectl
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
|
|
@ -29,7 +27,7 @@ import (
|
|||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
deploymentutil "k8s.io/kubernetes/pkg/util/deployment"
|
||||
"k8s.io/kubernetes/pkg/util/errors"
|
||||
sliceutil "k8s.io/kubernetes/pkg/util/slice"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -68,15 +66,14 @@ func (h *DeploymentHistoryViewer) History(namespace, name string) (HistoryInfo,
|
|||
if err != nil {
|
||||
return historyInfo, fmt.Errorf("failed to retrieve deployment %s: %v", name, err)
|
||||
}
|
||||
_, allOldRSs, err := deploymentutil.GetOldReplicaSets(deployment, h.c)
|
||||
_, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(deployment, h.c)
|
||||
if err != nil {
|
||||
return historyInfo, fmt.Errorf("failed to retrieve old replica sets from deployment %s: %v", name, err)
|
||||
return historyInfo, fmt.Errorf("failed to retrieve replica sets from deployment %s: %v", name, err)
|
||||
}
|
||||
newRS, err := deploymentutil.GetNewReplicaSet(deployment, h.c)
|
||||
if err != nil {
|
||||
return historyInfo, fmt.Errorf("failed to retrieve new replica set from deployment %s: %v", name, err)
|
||||
allRSs := allOldRSs
|
||||
if newRS != nil {
|
||||
allRSs = append(allRSs, newRS)
|
||||
}
|
||||
allRSs := append(allOldRSs, newRS)
|
||||
for _, rs := range allRSs {
|
||||
v, err := deploymentutil.Revision(rs)
|
||||
if err != nil {
|
||||
|
|
@ -100,30 +97,24 @@ func PrintRolloutHistory(historyInfo HistoryInfo, resource, name string) (string
|
|||
return fmt.Sprintf("No rollout history found in %s %q", resource, name), nil
|
||||
}
|
||||
// Sort the revisionToChangeCause map by revision
|
||||
var revisions []string
|
||||
for k := range historyInfo.RevisionToTemplate {
|
||||
revisions = append(revisions, strconv.FormatInt(k, 10))
|
||||
revisions := make([]int64, 0, len(historyInfo.RevisionToTemplate))
|
||||
for r := range historyInfo.RevisionToTemplate {
|
||||
revisions = append(revisions, r)
|
||||
}
|
||||
sort.Strings(revisions)
|
||||
sliceutil.SortInts64(revisions)
|
||||
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
fmt.Fprintf(out, "%s %q:\n", resource, name)
|
||||
fmt.Fprintf(out, "REVISION\tCHANGE-CAUSE\n")
|
||||
errs := []error{}
|
||||
for _, r := range revisions {
|
||||
// Find the change-cause of revision r
|
||||
r64, err := strconv.ParseInt(r, 10, 64)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
changeCause := historyInfo.RevisionToTemplate[r64].Annotations[ChangeCauseAnnotation]
|
||||
changeCause := historyInfo.RevisionToTemplate[r].Annotations[ChangeCauseAnnotation]
|
||||
if len(changeCause) == 0 {
|
||||
changeCause = "<none>"
|
||||
}
|
||||
fmt.Fprintf(out, "%s\t%s\n", r, changeCause)
|
||||
fmt.Fprintf(out, "%d\t%s\n", r, changeCause)
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
4
vendor/k8s.io/kubernetes/pkg/kubectl/kubectl.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/kubectl/kubectl.go
generated
vendored
|
|
@ -43,7 +43,7 @@ type NamespaceInfo struct {
|
|||
}
|
||||
|
||||
func listOfImages(spec *api.PodSpec) []string {
|
||||
var images []string
|
||||
images := make([]string, 0, len(spec.Containers))
|
||||
for _, container := range spec.Containers {
|
||||
images = append(images, container.Image)
|
||||
}
|
||||
|
|
@ -64,7 +64,7 @@ func NewThirdPartyResourceMapper(gvs []unversioned.GroupVersion, gvks []unversio
|
|||
}, nil
|
||||
}
|
||||
}
|
||||
groupVersions := []string{}
|
||||
groupVersions := make([]string, 0, len(gvs))
|
||||
for ix := range gvs {
|
||||
groupVersions = append(groupVersions, gvs[ix].String())
|
||||
}
|
||||
|
|
|
|||
23
vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go
generated
vendored
23
vendor/k8s.io/kubernetes/pkg/kubectl/resource/builder.go
generated
vendored
|
|
@ -36,6 +36,8 @@ import (
|
|||
var FileExtensions = []string{".json", ".yaml", ".yml"}
|
||||
var InputExtensions = append(FileExtensions, "stdin")
|
||||
|
||||
const defaultHttpGetAttempts int = 3
|
||||
|
||||
// Builder provides convenience functions for taking arguments and parameters
|
||||
// from the command line and converting them to a list of resources to iterate
|
||||
// over using the Visitor interface.
|
||||
|
|
@ -69,6 +71,8 @@ type Builder struct {
|
|||
singleResourceType bool
|
||||
continueOnError bool
|
||||
|
||||
singular bool
|
||||
|
||||
export bool
|
||||
|
||||
schema validation.Schema
|
||||
|
|
@ -109,8 +113,11 @@ func (b *Builder) FilenameParam(enforceNamespace, recursive bool, paths ...strin
|
|||
b.errs = append(b.errs, fmt.Errorf("the URL passed to filename %q is not valid: %v", s, err))
|
||||
continue
|
||||
}
|
||||
b.URL(url)
|
||||
b.URL(defaultHttpGetAttempts, url)
|
||||
default:
|
||||
if !recursive {
|
||||
b.singular = true
|
||||
}
|
||||
b.Path(recursive, s)
|
||||
}
|
||||
}
|
||||
|
|
@ -123,11 +130,12 @@ func (b *Builder) FilenameParam(enforceNamespace, recursive bool, paths ...strin
|
|||
}
|
||||
|
||||
// URL accepts a number of URLs directly.
|
||||
func (b *Builder) URL(urls ...*url.URL) *Builder {
|
||||
func (b *Builder) URL(httpAttemptCount int, urls ...*url.URL) *Builder {
|
||||
for _, u := range urls {
|
||||
b.paths = append(b.paths, &URLVisitor{
|
||||
URL: u,
|
||||
StreamVisitor: NewStreamVisitor(nil, b.mapper, u.String(), b.schema),
|
||||
URL: u,
|
||||
StreamVisitor: NewStreamVisitor(nil, b.mapper, u.String(), b.schema),
|
||||
HttpAttemptCount: httpAttemptCount,
|
||||
})
|
||||
}
|
||||
return b
|
||||
|
|
@ -543,7 +551,12 @@ func (b *Builder) visitorResult() *Result {
|
|||
|
||||
// visit items specified by resource and name
|
||||
if len(b.resourceTuples) != 0 {
|
||||
isSingular := len(b.resourceTuples) == 1
|
||||
// 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")}
|
||||
|
|
|
|||
10
vendor/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/kubectl/resource/mapper.go
generated
vendored
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/registry/thirdpartyresourcedata"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
|
@ -57,9 +56,12 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
|
|||
}
|
||||
var obj runtime.Object
|
||||
var versioned runtime.Object
|
||||
if registered.IsThirdPartyAPIGroupVersion(gvk.GroupVersion()) {
|
||||
obj, err = runtime.Decode(thirdpartyresourcedata.NewDecoder(nil, gvk.Kind), data)
|
||||
if isThirdParty, gvkOut, err := thirdpartyresourcedata.IsThirdPartyObject(data, gvk); err != nil {
|
||||
return nil, err
|
||||
} else if isThirdParty {
|
||||
obj, err = runtime.Decode(thirdpartyresourcedata.NewDecoder(nil, gvkOut.Kind), data)
|
||||
versioned = obj
|
||||
gvk = gvkOut
|
||||
} else {
|
||||
obj, versioned = versions.Last(), versions.First()
|
||||
}
|
||||
|
|
@ -96,7 +98,7 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
|
|||
// if the object cannot be introspected. Name and namespace will be set into Info
|
||||
// if the mapping's MetadataAccessor can retrieve them.
|
||||
func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []unversioned.GroupVersionKind) (*Info, error) {
|
||||
groupVersionKinds, err := m.ObjectKinds(obj)
|
||||
groupVersionKinds, _, err := m.ObjectKinds(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get type info from the object %q: %v", reflect.TypeOf(obj), err)
|
||||
}
|
||||
|
|
|
|||
16
vendor/k8s.io/kubernetes/pkg/kubectl/resource/result.go
generated
vendored
16
vendor/k8s.io/kubernetes/pkg/kubectl/resource/result.go
generated
vendored
|
|
@ -211,7 +211,7 @@ func (r *Result) Watch(resourceVersion string) (watch.Interface, error) {
|
|||
// the objects as children, or if only a single Object is present, as that object. The provided
|
||||
// version will be preferred as the conversion target, but the Object's mapping version will be
|
||||
// used if that version is not present.
|
||||
func AsVersionedObject(infos []*Info, forceList bool, version string, encoder runtime.Encoder) (runtime.Object, error) {
|
||||
func AsVersionedObject(infos []*Info, forceList bool, version unversioned.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) {
|
||||
objects, err := AsVersionedObjects(infos, version, encoder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -222,7 +222,7 @@ func AsVersionedObject(infos []*Info, forceList bool, version string, encoder ru
|
|||
object = objects[0]
|
||||
} else {
|
||||
object = &api.List{Items: objects}
|
||||
converted, err := tryConvert(api.Scheme, object, version, registered.GroupOrDie(api.GroupName).GroupVersion.Version)
|
||||
converted, err := tryConvert(api.Scheme, object, version, registered.GroupOrDie(api.GroupName).GroupVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -234,7 +234,7 @@ func AsVersionedObject(infos []*Info, forceList bool, version string, encoder ru
|
|||
// AsVersionedObjects converts a list of infos into versioned objects. The provided
|
||||
// version will be preferred as the conversion target, but the Object's mapping version will be
|
||||
// used if that version is not present.
|
||||
func AsVersionedObjects(infos []*Info, version string, encoder runtime.Encoder) ([]runtime.Object, error) {
|
||||
func AsVersionedObjects(infos []*Info, version unversioned.GroupVersion, encoder runtime.Encoder) ([]runtime.Object, error) {
|
||||
objects := []runtime.Object{}
|
||||
for _, info := range infos {
|
||||
if info.Object == nil {
|
||||
|
|
@ -250,8 +250,8 @@ func AsVersionedObjects(infos []*Info, version string, encoder runtime.Encoder)
|
|||
|
||||
// objects that are not part of api.Scheme must be converted to JSON
|
||||
// TODO: convert to map[string]interface{}, attach to runtime.Unknown?
|
||||
if len(version) > 0 {
|
||||
if _, err := api.Scheme.ObjectKind(info.Object); runtime.IsNotRegisteredError(err) {
|
||||
if !version.IsEmpty() {
|
||||
if _, _, err := api.Scheme.ObjectKinds(info.Object); runtime.IsNotRegisteredError(err) {
|
||||
// TODO: ideally this would encode to version, but we don't expose multiple codecs here.
|
||||
data, err := runtime.Encode(encoder, info.Object)
|
||||
if err != nil {
|
||||
|
|
@ -263,7 +263,7 @@ func AsVersionedObjects(infos []*Info, version string, encoder runtime.Encoder)
|
|||
}
|
||||
}
|
||||
|
||||
converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion().String())
|
||||
converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, version, info.Mapping.GroupVersionKind.GroupVersion())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -274,10 +274,10 @@ func AsVersionedObjects(infos []*Info, version string, encoder runtime.Encoder)
|
|||
|
||||
// tryConvert attempts to convert the given object to the provided versions in order. This function assumes
|
||||
// the object is in internal version.
|
||||
func tryConvert(convertor runtime.ObjectConvertor, object runtime.Object, versions ...string) (runtime.Object, error) {
|
||||
func tryConvert(convertor runtime.ObjectConvertor, object runtime.Object, versions ...unversioned.GroupVersion) (runtime.Object, error) {
|
||||
var last error
|
||||
for _, version := range versions {
|
||||
if len(version) == 0 {
|
||||
if version.IsEmpty() {
|
||||
return object, nil
|
||||
}
|
||||
obj, err := convertor.ConvertToVersion(object, version)
|
||||
|
|
|
|||
62
vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go
generated
vendored
62
vendor/k8s.io/kubernetes/pkg/kubectl/resource/visitor.go
generated
vendored
|
|
@ -24,6 +24,7 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
|
|
@ -221,22 +222,69 @@ func ValidateSchema(data []byte, schema validation.Schema) error {
|
|||
type URLVisitor struct {
|
||||
URL *url.URL
|
||||
*StreamVisitor
|
||||
HttpAttemptCount int
|
||||
}
|
||||
|
||||
func (v *URLVisitor) Visit(fn VisitorFunc) error {
|
||||
res, err := http.Get(v.URL.String())
|
||||
body, err := readHttpWithRetries(httpgetImpl, time.Second, v.URL.String(), v.HttpAttemptCount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != 200 {
|
||||
return fmt.Errorf("unable to read URL %q, server reported %d %s", v.URL, res.StatusCode, res.Status)
|
||||
}
|
||||
|
||||
v.StreamVisitor.Reader = res.Body
|
||||
defer body.Close()
|
||||
v.StreamVisitor.Reader = body
|
||||
return v.StreamVisitor.Visit(fn)
|
||||
}
|
||||
|
||||
// readHttpWithRetries tries to http.Get the v.URL retries times before giving up.
|
||||
func readHttpWithRetries(get httpget, duration time.Duration, u string, attempts int) (io.ReadCloser, error) {
|
||||
var err error
|
||||
var body io.ReadCloser
|
||||
if attempts <= 0 {
|
||||
return nil, fmt.Errorf("http attempts must be greater than 0, was %d", attempts)
|
||||
}
|
||||
for i := 0; i < attempts; i++ {
|
||||
var statusCode int
|
||||
var status string
|
||||
if i > 0 {
|
||||
time.Sleep(duration)
|
||||
}
|
||||
|
||||
// Try to get the URL
|
||||
statusCode, status, body, err = get(u)
|
||||
|
||||
// Retry Errors
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Error - Set the error condition from the StatusCode
|
||||
if statusCode != 200 {
|
||||
err = fmt.Errorf("unable to read URL %q, server reported %s, status code=%d", u, status, statusCode)
|
||||
}
|
||||
|
||||
if statusCode >= 500 && statusCode < 600 {
|
||||
// Retry 500's
|
||||
continue
|
||||
} else {
|
||||
// Don't retry other StatusCodes
|
||||
break
|
||||
}
|
||||
}
|
||||
return body, err
|
||||
}
|
||||
|
||||
// httpget Defines function to retrieve a url and return the results. Exists for unit test stubbing.
|
||||
type httpget func(url string) (int, string, io.ReadCloser, error)
|
||||
|
||||
// httpgetImpl Implements a function to retrieve a url and return the results.
|
||||
func httpgetImpl(url string) (int, string, io.ReadCloser, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return 0, "", nil, err
|
||||
}
|
||||
return resp.StatusCode, resp.Status, resp.Body, nil
|
||||
}
|
||||
|
||||
// DecoratedVisitor will invoke the decorators in order prior to invoking the visitor function
|
||||
// passed to Visit. An error will terminate the visit.
|
||||
type DecoratedVisitor struct {
|
||||
|
|
|
|||
463
vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go
generated
vendored
463
vendor/k8s.io/kubernetes/pkg/kubectl/resource_printer.go
generated
vendored
|
|
@ -32,12 +32,15 @@ import (
|
|||
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/federation/apis/federation"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
utilerrors "k8s.io/kubernetes/pkg/util/errors"
|
||||
|
|
@ -51,6 +54,7 @@ const (
|
|||
tabwriterPadding = 3
|
||||
tabwriterPadChar = ' '
|
||||
tabwriterFlags = 0
|
||||
loadBalancerWidth = 16
|
||||
)
|
||||
|
||||
// GetPrinter takes a format type, an optional format argument. It will return true
|
||||
|
|
@ -67,7 +71,8 @@ func GetPrinter(format, formatArgument string) (ResourcePrinter, bool, error) {
|
|||
printer = &YAMLPrinter{}
|
||||
case "name":
|
||||
printer = &NamePrinter{
|
||||
Typer: runtime.ObjectTyperToTyper(api.Scheme),
|
||||
// TODO: this is wrong, these should be provided as an argument to GetPrinter
|
||||
Typer: api.Scheme,
|
||||
Decoder: api.Codecs.UniversalDecoder(),
|
||||
}
|
||||
case "template", "go-template":
|
||||
|
|
@ -181,7 +186,7 @@ func (p *VersionedPrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
|||
if version.IsEmpty() {
|
||||
continue
|
||||
}
|
||||
converted, err := p.convertor.ConvertToVersion(obj, version.String())
|
||||
converted, err := p.convertor.ConvertToVersion(obj, version)
|
||||
if runtime.IsNotRegisteredError(err) {
|
||||
continue
|
||||
}
|
||||
|
|
@ -201,14 +206,12 @@ func (p *VersionedPrinter) HandledResources() []string {
|
|||
// NamePrinter is an implementation of ResourcePrinter which outputs "resource/name" pair of an object.
|
||||
type NamePrinter struct {
|
||||
Decoder runtime.Decoder
|
||||
Typer runtime.Typer
|
||||
Typer runtime.ObjectTyper
|
||||
}
|
||||
|
||||
// PrintObj is an implementation of ResourcePrinter.PrintObj which decodes the object
|
||||
// and print "resource/name" pair. If the object is a List, print all items in it.
|
||||
func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
||||
gvk, _, _ := p.Typer.ObjectKind(obj)
|
||||
|
||||
if meta.IsListType(obj) {
|
||||
items, err := meta.ExtractList(obj)
|
||||
if err != nil {
|
||||
|
|
@ -234,10 +237,9 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
|
|||
}
|
||||
}
|
||||
|
||||
if gvk != nil {
|
||||
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(*gvk)
|
||||
|
||||
_, resource := meta.KindToResource(gvks[0])
|
||||
fmt.Fprintf(w, "%s/%s\n", resource.Resource, name)
|
||||
} else {
|
||||
fmt.Fprintf(w, "<unknown>/%s\n", name)
|
||||
|
|
@ -418,12 +420,12 @@ var replicationControllerColumns = []string{"NAME", "DESIRED", "CURRENT", "AGE"}
|
|||
var replicaSetColumns = []string{"NAME", "DESIRED", "CURRENT", "AGE"}
|
||||
var jobColumns = []string{"NAME", "DESIRED", "SUCCESSFUL", "AGE"}
|
||||
var serviceColumns = []string{"NAME", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE"}
|
||||
var ingressColumns = []string{"NAME", "RULE", "BACKEND", "ADDRESS", "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{"FIRSTSEEN", "LASTSEEN", "COUNT", "NAME", "KIND", "SUBOBJECT", "TYPE", "REASON", "SOURCE", "MESSAGE"}
|
||||
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"}
|
||||
|
|
@ -433,6 +435,10 @@ var persistentVolumeColumns = []string{"NAME", "CAPACITY", "ACCESSMODES", "STATU
|
|||
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"}
|
||||
|
||||
// TODO: consider having 'KIND' for third party resource data
|
||||
var thirdPartyResourceDataColumns = []string{"NAME", "LABELS", "DATA"}
|
||||
|
|
@ -441,6 +447,8 @@ var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print
|
|||
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", "VERSION", "AGE"}
|
||||
var networkPolicyColumns = []string{"NAME", "POD-SELECTOR", "AGE"}
|
||||
|
||||
// addDefaultHandlers adds print handlers for default Kubernetes types.
|
||||
func (h *HumanReadablePrinter) addDefaultHandlers() {
|
||||
|
|
@ -496,6 +504,18 @@ func (h *HumanReadablePrinter) addDefaultHandlers() {
|
|||
h.Handler(podSecurityPolicyColumns, printPodSecurityPolicyList)
|
||||
h.Handler(thirdPartyResourceDataColumns, printThirdPartyResourceData)
|
||||
h.Handler(thirdPartyResourceDataColumns, printThirdPartyResourceDataList)
|
||||
h.Handler(clusterColumns, printCluster)
|
||||
h.Handler(clusterColumns, printClusterList)
|
||||
h.Handler(networkPolicyColumns, printNetworkPolicy)
|
||||
h.Handler(networkPolicyColumns, printNetworkPolicyList)
|
||||
h.Handler(roleColumns, printRole)
|
||||
h.Handler(roleColumns, printRoleList)
|
||||
h.Handler(roleBindingColumns, printRoleBinding)
|
||||
h.Handler(roleBindingColumns, printRoleBindingList)
|
||||
h.Handler(clusterRoleColumns, printClusterRole)
|
||||
h.Handler(clusterRoleColumns, printClusterRoleList)
|
||||
h.Handler(clusterRoleBindingColumns, printClusterRoleBinding)
|
||||
h.Handler(clusterRoleBindingColumns, printClusterRoleBindingList)
|
||||
}
|
||||
|
||||
func (h *HumanReadablePrinter) unknown(data []byte, w io.Writer) error {
|
||||
|
|
@ -593,22 +613,51 @@ func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error {
|
|||
reason = pod.Status.Reason
|
||||
}
|
||||
|
||||
for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- {
|
||||
container := pod.Status.ContainerStatuses[i]
|
||||
|
||||
restarts += int(container.RestartCount)
|
||||
if container.State.Waiting != nil && container.State.Waiting.Reason != "" {
|
||||
reason = container.State.Waiting.Reason
|
||||
} else if container.State.Terminated != nil && container.State.Terminated.Reason != "" {
|
||||
reason = container.State.Terminated.Reason
|
||||
} else if container.State.Terminated != nil && container.State.Terminated.Reason == "" {
|
||||
if container.State.Terminated.Signal != 0 {
|
||||
reason = fmt.Sprintf("Signal:%d", container.State.Terminated.Signal)
|
||||
initializing := false
|
||||
for i := range pod.Status.InitContainerStatuses {
|
||||
container := pod.Status.InitContainerStatuses[i]
|
||||
switch {
|
||||
case container.State.Terminated != nil && container.State.Terminated.ExitCode == 0:
|
||||
continue
|
||||
case container.State.Terminated != nil:
|
||||
// initialization is failed
|
||||
if len(container.State.Terminated.Reason) == 0 {
|
||||
if container.State.Terminated.Signal != 0 {
|
||||
reason = fmt.Sprintf("Init:Signal:%d", container.State.Terminated.Signal)
|
||||
} else {
|
||||
reason = fmt.Sprintf("Init:ExitCode:%d", container.State.Terminated.ExitCode)
|
||||
}
|
||||
} else {
|
||||
reason = fmt.Sprintf("ExitCode:%d", container.State.Terminated.ExitCode)
|
||||
reason = "Init:" + container.State.Terminated.Reason
|
||||
}
|
||||
initializing = true
|
||||
case container.State.Waiting != nil && len(container.State.Waiting.Reason) > 0 && container.State.Waiting.Reason != "PodInitializing":
|
||||
reason = "Init:" + container.State.Waiting.Reason
|
||||
initializing = true
|
||||
default:
|
||||
reason = fmt.Sprintf("Init:%d/%d", i, len(pod.Spec.InitContainers))
|
||||
initializing = true
|
||||
}
|
||||
break
|
||||
}
|
||||
if !initializing {
|
||||
for i := len(pod.Status.ContainerStatuses) - 1; i >= 0; i-- {
|
||||
container := pod.Status.ContainerStatuses[i]
|
||||
|
||||
restarts += int(container.RestartCount)
|
||||
if container.State.Waiting != nil && container.State.Waiting.Reason != "" {
|
||||
reason = container.State.Waiting.Reason
|
||||
} else if container.State.Terminated != nil && container.State.Terminated.Reason != "" {
|
||||
reason = container.State.Terminated.Reason
|
||||
} else if container.State.Terminated != nil && container.State.Terminated.Reason == "" {
|
||||
if container.State.Terminated.Signal != 0 {
|
||||
reason = fmt.Sprintf("Signal:%d", container.State.Terminated.Signal)
|
||||
} else {
|
||||
reason = fmt.Sprintf("ExitCode:%d", container.State.Terminated.ExitCode)
|
||||
}
|
||||
} else if container.Ready && container.State.Running != nil {
|
||||
readyContainers++
|
||||
}
|
||||
} else if container.Ready && container.State.Running != nil {
|
||||
readyContainers++
|
||||
}
|
||||
}
|
||||
if pod.DeletionTimestamp != nil {
|
||||
|
|
@ -633,17 +682,22 @@ func printPodBase(pod *api.Pod, w io.Writer, options PrintOptions) error {
|
|||
|
||||
if options.Wide {
|
||||
nodeName := pod.Spec.NodeName
|
||||
if _, err := fmt.Fprintf(w, "\t%s",
|
||||
podIP := pod.Status.PodIP
|
||||
if podIP == "" {
|
||||
podIP = "<none>"
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "\t%s\t%s",
|
||||
podIP,
|
||||
nodeName,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, appendLabels(pod.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(pod.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, pod.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, pod.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -679,10 +733,10 @@ func printPodTemplate(pod *api.PodTemplate, w io.Writer, options PrintOptions) e
|
|||
if _, err := fmt.Fprintf(w, "\t%s", labels.FormatLabels(pod.Template.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(pod.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(pod.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, pod.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, pod.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -729,10 +783,10 @@ func printReplicationController(controller *api.ReplicationController, w io.Writ
|
|||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(controller.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(controller.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, controller.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, controller.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -777,10 +831,10 @@ func printReplicaSet(rs *extensions.ReplicaSet, w io.Writer, options PrintOption
|
|||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(rs.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(rs.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, rs.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, rs.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -796,6 +850,38 @@ func printReplicaSetList(list *extensions.ReplicaSetList, w io.Writer, options P
|
|||
return nil
|
||||
}
|
||||
|
||||
func printCluster(c *federation.Cluster, w io.Writer, options PrintOptions) error {
|
||||
var statuses []string
|
||||
for _, condition := range c.Status.Conditions {
|
||||
if condition.Status == api.ConditionTrue {
|
||||
statuses = append(statuses, string(condition.Type))
|
||||
} else {
|
||||
statuses = append(statuses, "Not"+string(condition.Type))
|
||||
}
|
||||
}
|
||||
if len(statuses) == 0 {
|
||||
statuses = append(statuses, "Unknown")
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
|
||||
c.Name,
|
||||
strings.Join(statuses, ","),
|
||||
c.Status.Version,
|
||||
translateTimestamp(c.CreationTimestamp),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func printClusterList(list *federation.ClusterList, w io.Writer, options PrintOptions) error {
|
||||
for _, rs := range list.Items {
|
||||
if err := printCluster(&rs, w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printJob(job *batch.Job, w io.Writer, options PrintOptions) error {
|
||||
name := job.Name
|
||||
namespace := job.Namespace
|
||||
|
|
@ -839,10 +925,10 @@ func printJob(job *batch.Job, w io.Writer, options PrintOptions) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(job.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(job.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, job.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, job.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -858,19 +944,26 @@ func printJobList(list *batch.JobList, w io.Writer, options PrintOptions) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// loadBalancerStatusStringer behaves just like a string interface and converts the given status to a string.
|
||||
func loadBalancerStatusStringer(s api.LoadBalancerStatus) string {
|
||||
// loadBalancerStatusStringer behaves mostly like a string interface and converts the given status to a string.
|
||||
// `wide` indicates whether the returned value is meant for --o=wide output. If not, it's clipped to 16 bytes.
|
||||
func loadBalancerStatusStringer(s api.LoadBalancerStatus, wide bool) string {
|
||||
ingress := s.Ingress
|
||||
result := []string{}
|
||||
for i := range ingress {
|
||||
if ingress[i].IP != "" {
|
||||
result = append(result, ingress[i].IP)
|
||||
} else if ingress[i].Hostname != "" {
|
||||
result = append(result, ingress[i].Hostname)
|
||||
}
|
||||
}
|
||||
return strings.Join(result, ",")
|
||||
r := strings.Join(result, ",")
|
||||
if !wide && len(r) > loadBalancerWidth {
|
||||
r = r[0:(loadBalancerWidth-3)] + "..."
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func getServiceExternalIP(svc *api.Service) string {
|
||||
func getServiceExternalIP(svc *api.Service, wide bool) string {
|
||||
switch svc.Spec.Type {
|
||||
case api.ServiceTypeClusterIP:
|
||||
if len(svc.Spec.ExternalIPs) > 0 {
|
||||
|
|
@ -883,7 +976,7 @@ func getServiceExternalIP(svc *api.Service) string {
|
|||
}
|
||||
return "<nodes>"
|
||||
case api.ServiceTypeLoadBalancer:
|
||||
lbIps := loadBalancerStatusStringer(svc.Status.LoadBalancer)
|
||||
lbIps := loadBalancerStatusStringer(svc.Status.LoadBalancer, wide)
|
||||
if len(svc.Spec.ExternalIPs) > 0 {
|
||||
result := append(strings.Split(lbIps, ","), svc.Spec.ExternalIPs...)
|
||||
return strings.Join(result, ",")
|
||||
|
|
@ -910,7 +1003,7 @@ func printService(svc *api.Service, w io.Writer, options PrintOptions) error {
|
|||
namespace := svc.Namespace
|
||||
|
||||
internalIP := svc.Spec.ClusterIP
|
||||
externalIP := getServiceExternalIP(svc)
|
||||
externalIP := getServiceExternalIP(svc, options.Wide)
|
||||
|
||||
if options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
|
||||
|
|
@ -931,10 +1024,10 @@ func printService(svc *api.Service, w io.Writer, options PrintOptions) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(svc.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(svc.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, svc.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, svc.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -955,11 +1048,39 @@ func backendStringer(backend *extensions.IngressBackend) string {
|
|||
return fmt.Sprintf("%v:%v", backend.ServiceName, backend.ServicePort.String())
|
||||
}
|
||||
|
||||
func formatHosts(rules []extensions.IngressRule) string {
|
||||
list := []string{}
|
||||
max := 3
|
||||
more := false
|
||||
for _, rule := range rules {
|
||||
if len(list) == max {
|
||||
more = true
|
||||
}
|
||||
if !more && len(rule.Host) != 0 {
|
||||
list = append(list, rule.Host)
|
||||
}
|
||||
}
|
||||
if len(list) == 0 {
|
||||
return "*"
|
||||
}
|
||||
ret := strings.Join(list, ",")
|
||||
if more {
|
||||
return fmt.Sprintf("%s + %d more...", ret, len(rules)-max)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func formatPorts(tls []extensions.IngressTLS) string {
|
||||
if len(tls) != 0 {
|
||||
return "80, 443"
|
||||
}
|
||||
return "80"
|
||||
}
|
||||
|
||||
func printIngress(ingress *extensions.Ingress, w io.Writer, options PrintOptions) error {
|
||||
name := ingress.Name
|
||||
namespace := ingress.Namespace
|
||||
|
||||
hostRules := ingress.Spec.Rules
|
||||
if options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
|
||||
return err
|
||||
|
|
@ -968,49 +1089,20 @@ func printIngress(ingress *extensions.Ingress, w io.Writer, options PrintOptions
|
|||
|
||||
if _, err := fmt.Fprintf(w, "%s\t%v\t%v\t%v\t%s",
|
||||
name,
|
||||
"-",
|
||||
backendStringer(ingress.Spec.Backend),
|
||||
loadBalancerStatusStringer(ingress.Status.LoadBalancer),
|
||||
formatHosts(ingress.Spec.Rules),
|
||||
loadBalancerStatusStringer(ingress.Status.LoadBalancer, options.Wide),
|
||||
formatPorts(ingress.Spec.TLS),
|
||||
translateTimestamp(ingress.CreationTimestamp),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(ingress.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(ingress.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, ingress.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, ingress.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Lay out all the rules on separate lines if use wide output.
|
||||
// TODO(AdoHe): improve ingress output
|
||||
extraLinePrefix := ""
|
||||
if options.WithNamespace {
|
||||
extraLinePrefix = "\t"
|
||||
}
|
||||
for _, rules := range hostRules {
|
||||
if rules.HTTP == nil {
|
||||
continue
|
||||
}
|
||||
_, err := fmt.Fprintf(w, "%s\t%v\t", extraLinePrefix, rules.Host)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabelTabs(options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, rule := range rules.HTTP.Paths {
|
||||
_, err := fmt.Fprintf(w, "%s\t%v\t%v", extraLinePrefix, rule.Path, backendStringer(&rule.Backend))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabelTabs(options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -1051,10 +1143,10 @@ func printPetSet(ps *apps.PetSet, w io.Writer, options PrintOptions) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(ps.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(ps.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, ps.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, ps.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1106,10 +1198,10 @@ func printDaemonSet(ds *extensions.DaemonSet, w io.Writer, options PrintOptions)
|
|||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(ds.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(ds.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, ds.Labels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, ds.Labels)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1137,10 +1229,10 @@ func printEndpoints(endpoints *api.Endpoints, w io.Writer, options PrintOptions)
|
|||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s", name, formatEndpoints(endpoints, nil), translateTimestamp(endpoints.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(endpoints.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(endpoints.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, endpoints.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, endpoints.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1161,10 +1253,10 @@ func printNamespace(item *api.Namespace, w io.Writer, options PrintOptions) erro
|
|||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s", item.Name, item.Status.Phase, translateTimestamp(item.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, item.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, item.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1189,10 +1281,10 @@ func printSecret(item *api.Secret, w io.Writer, options PrintOptions) error {
|
|||
if _, err := fmt.Fprintf(w, "%s\t%s\t%v\t%s", name, item.Type, len(item.Data), translateTimestamp(item.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, item.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, item.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1218,10 +1310,10 @@ func printServiceAccount(item *api.ServiceAccount, w io.Writer, options PrintOpt
|
|||
if _, err := fmt.Fprintf(w, "%s\t%d\t%s", name, len(item.Secrets), translateTimestamp(item.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, item.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, item.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1266,10 +1358,10 @@ func printNode(node *api.Node, w io.Writer, options PrintOptions) error {
|
|||
return err
|
||||
}
|
||||
// Display caller specify column labels first.
|
||||
if _, err := fmt.Fprint(w, appendLabels(node.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(node.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, node.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, node.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1310,10 +1402,10 @@ func printPersistentVolume(pv *api.PersistentVolume, w io.Writer, options PrintO
|
|||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(pv.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(pv.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, pv.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, pv.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1349,10 +1441,10 @@ func printPersistentVolumeClaim(pvc *api.PersistentVolumeClaim, w io.Writer, opt
|
|||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s", name, phase, pvc.Spec.VolumeName, capacity, accessModes, translateTimestamp(pvc.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(pvc.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(pvc.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, pvc.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, pvc.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1385,8 +1477,8 @@ func printEvent(event *api.Event, w io.Writer, options PrintOptions) error {
|
|||
|
||||
if _, err := fmt.Fprintf(
|
||||
w, "%s\t%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
|
||||
FirstTimestamp,
|
||||
LastTimestamp,
|
||||
FirstTimestamp,
|
||||
event.Count,
|
||||
event.InvolvedObject.Name,
|
||||
event.InvolvedObject.Kind,
|
||||
|
|
@ -1398,10 +1490,10 @@ func printEvent(event *api.Event, w io.Writer, options PrintOptions) error {
|
|||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(event.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(event.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, event.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, event.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1417,27 +1509,7 @@ func printEventList(list *api.EventList, w io.Writer, options PrintOptions) erro
|
|||
}
|
||||
|
||||
func printLimitRange(limitRange *api.LimitRange, w io.Writer, options PrintOptions) error {
|
||||
name := limitRange.Name
|
||||
namespace := limitRange.Namespace
|
||||
|
||||
if options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(
|
||||
w, "%s\t%s",
|
||||
name,
|
||||
translateTimestamp(limitRange.CreationTimestamp),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(limitRange.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, limitRange.Labels))
|
||||
return err
|
||||
return printObjectMeta(limitRange.ObjectMeta, w, options, true)
|
||||
}
|
||||
|
||||
// Prints the LimitRangeList in a human-friendly format.
|
||||
|
|
@ -1450,30 +1522,32 @@ func printLimitRangeList(list *api.LimitRangeList, w io.Writer, options PrintOpt
|
|||
return nil
|
||||
}
|
||||
|
||||
func printResourceQuota(resourceQuota *api.ResourceQuota, w io.Writer, options PrintOptions) error {
|
||||
name := resourceQuota.Name
|
||||
namespace := resourceQuota.Namespace
|
||||
|
||||
if options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
|
||||
// printObjectMeta prints the object metadata of a given resource.
|
||||
func printObjectMeta(meta api.ObjectMeta, w io.Writer, options PrintOptions, namespaced bool) error {
|
||||
if namespaced && options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", meta.Namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(
|
||||
w, "%s\t%s",
|
||||
name,
|
||||
translateTimestamp(resourceQuota.CreationTimestamp),
|
||||
meta.Name,
|
||||
translateTimestamp(meta.CreationTimestamp),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(resourceQuota.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(meta.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, resourceQuota.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, meta.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
func printResourceQuota(resourceQuota *api.ResourceQuota, w io.Writer, options PrintOptions) error {
|
||||
return printObjectMeta(resourceQuota.ObjectMeta, w, options, true)
|
||||
}
|
||||
|
||||
// Prints the ResourceQuotaList in a human-friendly format.
|
||||
func printResourceQuotaList(list *api.ResourceQuotaList, w io.Writer, options PrintOptions) error {
|
||||
for i := range list.Items {
|
||||
|
|
@ -1484,6 +1558,62 @@ func printResourceQuotaList(list *api.ResourceQuotaList, w io.Writer, options Pr
|
|||
return nil
|
||||
}
|
||||
|
||||
func printRole(role *rbac.Role, w io.Writer, options PrintOptions) error {
|
||||
return printObjectMeta(role.ObjectMeta, w, options, true)
|
||||
}
|
||||
|
||||
// Prints the Role in a human-friendly format.
|
||||
func printRoleList(list *rbac.RoleList, w io.Writer, options PrintOptions) error {
|
||||
for i := range list.Items {
|
||||
if err := printRole(&list.Items[i], w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printRoleBinding(roleBinding *rbac.RoleBinding, w io.Writer, options PrintOptions) error {
|
||||
return printObjectMeta(roleBinding.ObjectMeta, w, options, true)
|
||||
}
|
||||
|
||||
// Prints the RoleBinding in a human-friendly format.
|
||||
func printRoleBindingList(list *rbac.RoleBindingList, w io.Writer, options PrintOptions) error {
|
||||
for i := range list.Items {
|
||||
if err := printRoleBinding(&list.Items[i], w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printClusterRole(clusterRole *rbac.ClusterRole, w io.Writer, options PrintOptions) error {
|
||||
return printObjectMeta(clusterRole.ObjectMeta, w, options, false)
|
||||
}
|
||||
|
||||
// Prints the ClusterRole in a human-friendly format.
|
||||
func printClusterRoleList(list *rbac.ClusterRoleList, w io.Writer, options PrintOptions) error {
|
||||
for i := range list.Items {
|
||||
if err := printClusterRole(&list.Items[i], w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printClusterRoleBinding(clusterRoleBinding *rbac.ClusterRoleBinding, w io.Writer, options PrintOptions) error {
|
||||
return printObjectMeta(clusterRoleBinding.ObjectMeta, w, options, false)
|
||||
}
|
||||
|
||||
// Prints the ClusterRoleBinding in a human-friendly format.
|
||||
func printClusterRoleBindingList(list *rbac.ClusterRoleBindingList, w io.Writer, options PrintOptions) error {
|
||||
for i := range list.Items {
|
||||
if err := printClusterRoleBinding(&list.Items[i], w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printComponentStatus(item *api.ComponentStatus, w io.Writer, options PrintOptions) error {
|
||||
if options.WithNamespace {
|
||||
return fmt.Errorf("componentStatus is not namespaced")
|
||||
|
|
@ -1507,10 +1637,10 @@ func printComponentStatus(item *api.ComponentStatus, w io.Writer, options PrintO
|
|||
if _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s", item.Name, status, message, error); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(item.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, item.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, item.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1591,10 +1721,10 @@ func printDeployment(deployment *extensions.Deployment, w io.Writer, options Pri
|
|||
if _, err := fmt.Fprintf(w, "%s\t%d\t%d\t%d\t%d\t%s", deployment.Name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(deployment.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(deployment.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, deployment.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, deployment.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1607,16 +1737,15 @@ func printDeploymentList(list *extensions.DeploymentList, w io.Writer, options P
|
|||
return nil
|
||||
}
|
||||
|
||||
func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io.Writer, options PrintOptions) error {
|
||||
func printHorizontalPodAutoscaler(hpa *autoscaling.HorizontalPodAutoscaler, w io.Writer, options PrintOptions) error {
|
||||
namespace := hpa.Namespace
|
||||
name := hpa.Name
|
||||
reference := fmt.Sprintf("%s/%s/%s",
|
||||
hpa.Spec.ScaleRef.Kind,
|
||||
hpa.Spec.ScaleRef.Name,
|
||||
hpa.Spec.ScaleRef.Subresource)
|
||||
reference := fmt.Sprintf("%s/%s",
|
||||
hpa.Spec.ScaleTargetRef.Kind,
|
||||
hpa.Spec.ScaleTargetRef.Name)
|
||||
target := "<unset>"
|
||||
if hpa.Spec.CPUUtilization != nil {
|
||||
target = fmt.Sprintf("%d%%", hpa.Spec.CPUUtilization.TargetPercentage)
|
||||
if hpa.Spec.TargetCPUUtilizationPercentage != nil {
|
||||
target = fmt.Sprintf("%d%%", *hpa.Spec.TargetCPUUtilizationPercentage)
|
||||
}
|
||||
current := "<waiting>"
|
||||
if hpa.Status.CurrentCPUUtilizationPercentage != nil {
|
||||
|
|
@ -1644,14 +1773,14 @@ func printHorizontalPodAutoscaler(hpa *extensions.HorizontalPodAutoscaler, w io.
|
|||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(hpa.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(hpa.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, hpa.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, hpa.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
func printHorizontalPodAutoscalerList(list *extensions.HorizontalPodAutoscalerList, w io.Writer, options PrintOptions) error {
|
||||
func printHorizontalPodAutoscalerList(list *autoscaling.HorizontalPodAutoscalerList, w io.Writer, options PrintOptions) error {
|
||||
for i := range list.Items {
|
||||
if err := printHorizontalPodAutoscaler(&list.Items[i], w, options); err != nil {
|
||||
return err
|
||||
|
|
@ -1672,10 +1801,10 @@ func printConfigMap(configMap *api.ConfigMap, w io.Writer, options PrintOptions)
|
|||
if _, err := fmt.Fprintf(w, "%s\t%v\t%s", name, len(configMap.Data), translateTimestamp(configMap.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, appendLabels(configMap.Labels, options.ColumnLabels)); err != nil {
|
||||
if _, err := fmt.Fprint(w, AppendLabels(configMap.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, configMap.Labels))
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, configMap.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1689,9 +1818,9 @@ func printConfigMapList(list *api.ConfigMapList, w io.Writer, options PrintOptio
|
|||
}
|
||||
|
||||
func printPodSecurityPolicy(item *extensions.PodSecurityPolicy, w io.Writer, options PrintOptions) error {
|
||||
_, err := fmt.Fprintf(w, "%s\t%t\t%v\t%v\t%s\t%s\n", item.Name, item.Spec.Privileged,
|
||||
item.Spec.Capabilities, item.Spec.Volumes, item.Spec.SELinux.Rule,
|
||||
item.Spec.RunAsUser.Rule)
|
||||
_, err := fmt.Fprintf(w, "%s\t%t\t%v\t%s\t%s\t%s\t%s\t%t\t%v\n", item.Name, item.Spec.Privileged,
|
||||
item.Spec.AllowedCapabilities, item.Spec.SELinux.Rule,
|
||||
item.Spec.RunAsUser.Rule, item.Spec.FSGroup.Rule, item.Spec.SupplementalGroups.Rule, item.Spec.ReadOnlyRootFilesystem, item.Spec.Volumes)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -1705,7 +1834,35 @@ func printPodSecurityPolicyList(list *extensions.PodSecurityPolicyList, w io.Wri
|
|||
return nil
|
||||
}
|
||||
|
||||
func appendLabels(itemLabels map[string]string, columnLabels []string) string {
|
||||
func printNetworkPolicy(networkPolicy *extensions.NetworkPolicy, w io.Writer, options PrintOptions) error {
|
||||
name := networkPolicy.Name
|
||||
namespace := networkPolicy.Namespace
|
||||
|
||||
if options.WithNamespace {
|
||||
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "%s\t%v\t%s", name, unversioned.FormatLabelSelector(&networkPolicy.Spec.PodSelector), translateTimestamp(networkPolicy.CreationTimestamp)); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprint(w, AppendLabels(networkPolicy.Labels, options.ColumnLabels)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := fmt.Fprint(w, AppendAllLabels(options.ShowLabels, networkPolicy.Labels))
|
||||
return err
|
||||
}
|
||||
|
||||
func printNetworkPolicyList(list *extensions.NetworkPolicyList, w io.Writer, options PrintOptions) error {
|
||||
for i := range list.Items {
|
||||
if err := printNetworkPolicy(&list.Items[i], w, options); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AppendLabels(itemLabels map[string]string, columnLabels []string) string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
for _, cl := range columnLabels {
|
||||
|
|
@ -1722,7 +1879,7 @@ func appendLabels(itemLabels map[string]string, columnLabels []string) string {
|
|||
|
||||
// Append all labels to a single column. We need this even when show-labels flag* is
|
||||
// false, since this adds newline delimiter to the end of each row.
|
||||
func appendAllLabels(showLabels bool, itemLabels map[string]string) string {
|
||||
func AppendAllLabels(showLabels bool, itemLabels map[string]string) string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
if showLabels {
|
||||
|
|
@ -1736,7 +1893,7 @@ func appendAllLabels(showLabels bool, itemLabels map[string]string) string {
|
|||
|
||||
// Append a set of tabs for each label column. We need this in the case where
|
||||
// we have extra lines so that the tabwriter will still line things up.
|
||||
func appendLabelTabs(columnLabels []string) string {
|
||||
func AppendLabelTabs(columnLabels []string) string {
|
||||
var buffer bytes.Buffer
|
||||
|
||||
for range columnLabels {
|
||||
|
|
@ -1780,7 +1937,7 @@ func formatLabelHeaders(columnLabels []string) []string {
|
|||
func formatWideHeaders(wide bool, t reflect.Type) []string {
|
||||
if wide {
|
||||
if t.String() == "*api.Pod" || t.String() == "*api.PodList" {
|
||||
return []string{"NODE"}
|
||||
return []string{"IP", "NODE"}
|
||||
}
|
||||
if t.String() == "*api.ReplicationController" || t.String() == "*api.ReplicationControllerList" {
|
||||
return []string{"CONTAINER(S)", "IMAGE(S)", "SELECTOR"}
|
||||
|
|
|
|||
39
vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go
generated
vendored
39
vendor/k8s.io/kubernetes/pkg/kubectl/rolling_updater.go
generated
vendored
|
|
@ -83,6 +83,10 @@ type RollingUpdaterConfig struct {
|
|||
// further, ensuring that total number of pods running at any time during
|
||||
// the update is atmost 130% of desired pods.
|
||||
MaxSurge intstr.IntOrString
|
||||
// OnProgress is invoked if set during each scale cycle, to allow the caller to perform additional logic or
|
||||
// abort the scale. If an error is returned the cleanup method will not be invoked. The percentage value
|
||||
// is a synthetic "progress" calculation that represents the approximate percentage completion.
|
||||
OnProgress func(oldRc, newRc *api.ReplicationController, percentage int) error
|
||||
}
|
||||
|
||||
// RollingUpdaterCleanupPolicy is a cleanup action to take after the
|
||||
|
|
@ -217,6 +221,26 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
|
|||
fmt.Fprintf(out, "Scaling up %s from %d to %d, scaling down %s from %d to 0 (keep %d pods available, don't exceed %d pods)\n",
|
||||
newRc.Name, newRc.Spec.Replicas, desired, oldRc.Name, oldRc.Spec.Replicas, minAvailable, desired+maxSurge)
|
||||
|
||||
// give a caller incremental notification and allow them to exit early
|
||||
goal := desired - newRc.Spec.Replicas
|
||||
if goal < 0 {
|
||||
goal = -goal
|
||||
}
|
||||
progress := func(complete bool) error {
|
||||
if config.OnProgress == nil {
|
||||
return nil
|
||||
}
|
||||
progress := desired - newRc.Spec.Replicas
|
||||
if progress < 0 {
|
||||
progress = -progress
|
||||
}
|
||||
percentage := 100
|
||||
if !complete && goal > 0 {
|
||||
percentage = int((goal - progress) * 100 / goal)
|
||||
}
|
||||
return config.OnProgress(oldRc, newRc, percentage)
|
||||
}
|
||||
|
||||
// Scale newRc and oldRc until newRc has the desired number of replicas and
|
||||
// oldRc has 0 replicas.
|
||||
progressDeadline := time.Now().UnixNano() + config.Timeout.Nanoseconds()
|
||||
|
|
@ -232,6 +256,11 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
|
|||
}
|
||||
newRc = scaledRc
|
||||
|
||||
// notify the caller if necessary
|
||||
if err := progress(false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Wait between scaling operations for things to settle.
|
||||
time.Sleep(config.UpdatePeriod)
|
||||
|
||||
|
|
@ -242,6 +271,11 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
|
|||
}
|
||||
oldRc = scaledRc
|
||||
|
||||
// notify the caller if necessary
|
||||
if err := progress(false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If we are making progress, continue to advance the progress deadline.
|
||||
// Otherwise, time out with an error.
|
||||
progressMade := (newRc.Spec.Replicas != newReplicas) || (oldRc.Spec.Replicas != oldReplicas)
|
||||
|
|
@ -252,6 +286,11 @@ func (r *RollingUpdater) Update(config *RollingUpdaterConfig) error {
|
|||
}
|
||||
}
|
||||
|
||||
// notify the caller if necessary
|
||||
if err := progress(true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Housekeeping and cleanup policy execution.
|
||||
return r.cleanup(oldRc, newRc, config)
|
||||
}
|
||||
|
|
|
|||
57
vendor/k8s.io/kubernetes/pkg/kubectl/rollout_status.go
generated
vendored
Normal file
57
vendor/k8s.io/kubernetes/pkg/kubectl/rollout_status.go
generated
vendored
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
)
|
||||
|
||||
// StatusViewer provides an interface for resources that provides rollout status.
|
||||
type StatusViewer interface {
|
||||
Status(namespace, name string) (string, bool, error)
|
||||
}
|
||||
|
||||
func StatusViewerFor(kind unversioned.GroupKind, c client.Interface) (StatusViewer, error) {
|
||||
switch kind {
|
||||
case extensions.Kind("Deployment"):
|
||||
return &DeploymentStatusViewer{c.Extensions()}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("no status viewer has been implemented for %v", kind)
|
||||
}
|
||||
|
||||
type DeploymentStatusViewer struct {
|
||||
c client.ExtensionsInterface
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
return fmt.Sprintf("Waiting for deployment spec update to be observed...\n"), false, nil
|
||||
}
|
||||
6
vendor/k8s.io/kubernetes/pkg/kubectl/run.go
generated
vendored
6
vendor/k8s.io/kubernetes/pkg/kubectl/run.go
generated
vendored
|
|
@ -434,7 +434,7 @@ func populateResourceList(spec string) (api.ResourceList, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[resourceName] = *resourceQuantity
|
||||
result[resourceName] = resourceQuantity
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -458,7 +458,7 @@ func populateV1ResourceList(spec string) (v1.ResourceList, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result[resourceName] = *resourceQuantity
|
||||
result[resourceName] = resourceQuantity
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -827,7 +827,7 @@ func (BasicPod) Generate(genericParams map[string]interface{}) (runtime.Object,
|
|||
}
|
||||
|
||||
func parseEnvs(envArray []string) ([]api.EnvVar, error) {
|
||||
envs := []api.EnvVar{}
|
||||
envs := make([]api.EnvVar, 0, len(envArray))
|
||||
for _, env := range envArray {
|
||||
pos := strings.Index(env, "=")
|
||||
if pos == -1 {
|
||||
|
|
|
|||
124
vendor/k8s.io/kubernetes/pkg/kubectl/secret_for_tls.go
generated
vendored
Normal file
124
vendor/k8s.io/kubernetes/pkg/kubectl/secret_for_tls.go
generated
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// SecretForTLSGeneratorV1 supports stable generation of a TLS secret.
|
||||
type SecretForTLSGeneratorV1 struct {
|
||||
// Name is the name of this TLS secret.
|
||||
Name string
|
||||
// Key is the path to the user's private key.
|
||||
Key string
|
||||
// Cert is the path to the user's public key certificate.
|
||||
Cert string
|
||||
}
|
||||
|
||||
// Ensure it supports the generator pattern that uses parameter injection
|
||||
var _ Generator = &SecretForTLSGeneratorV1{}
|
||||
|
||||
// Ensure it supports the generator pattern that uses parameters specified during construction
|
||||
var _ StructuredGenerator = &SecretForTLSGeneratorV1{}
|
||||
|
||||
// Generate returns a secret using the specified parameters
|
||||
func (s SecretForTLSGeneratorV1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
||||
err := ValidateParams(s.ParamNames(), genericParams)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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
|
||||
}
|
||||
delegate := &SecretForTLSGeneratorV1{
|
||||
Name: params["name"],
|
||||
Key: params["key"],
|
||||
Cert: params["cert"],
|
||||
}
|
||||
return delegate.StructuredGenerate()
|
||||
}
|
||||
|
||||
// StructuredGenerate outputs a secret object using the configured fields
|
||||
func (s SecretForTLSGeneratorV1) StructuredGenerate() (runtime.Object, error) {
|
||||
if err := s.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsCrt, err := readFile(s.Cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tlsKey, err := readFile(s.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secret := &api.Secret{}
|
||||
secret.Name = s.Name
|
||||
secret.Type = api.SecretTypeTLS
|
||||
secret.Data = map[string][]byte{}
|
||||
secret.Data[api.TLSCertKey] = []byte(tlsCrt)
|
||||
secret.Data[api.TLSPrivateKeyKey] = []byte(tlsKey)
|
||||
return secret, nil
|
||||
}
|
||||
|
||||
// readFile just reads a file into a byte array.
|
||||
func readFile(file string) ([]byte, error) {
|
||||
b, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return []byte{}, fmt.Errorf("Cannot read file %v, %v", file, err)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// ParamNames returns the set of supported input parameters when using the parameter injection generator pattern
|
||||
func (s SecretForTLSGeneratorV1) ParamNames() []GeneratorParam {
|
||||
return []GeneratorParam{
|
||||
{"name", true},
|
||||
{"key", true},
|
||||
{"cert", true},
|
||||
}
|
||||
}
|
||||
|
||||
// validate validates required fields are set to support structured generation
|
||||
func (s SecretForTLSGeneratorV1) validate() error {
|
||||
// TODO: This is not strictly necessary. We can generate a self signed cert
|
||||
// if no key/cert is given. The only requiredment is that we either get both
|
||||
// or none. See test/e2e/ingress_utils for self signed cert generation.
|
||||
if len(s.Key) == 0 {
|
||||
return fmt.Errorf("key must be specified.")
|
||||
}
|
||||
if len(s.Cert) == 0 {
|
||||
return fmt.Errorf("certificate must be specified.")
|
||||
}
|
||||
if _, err := tls.LoadX509KeyPair(s.Cert, s.Key); err != nil {
|
||||
return fmt.Errorf("failed to load key pair %v", err)
|
||||
}
|
||||
// TODO: Add more validation.
|
||||
// 1. If the certificate contains intermediates, it is a valid chain.
|
||||
// 2. Format etc.
|
||||
return nil
|
||||
}
|
||||
31
vendor/k8s.io/kubernetes/pkg/kubectl/service.go
generated
vendored
31
vendor/k8s.io/kubernetes/pkg/kubectl/service.go
generated
vendored
|
|
@ -65,6 +65,9 @@ func paramNames() []GeneratorParam {
|
|||
{"load-balancer-ip", false},
|
||||
{"type", false},
|
||||
{"protocol", false},
|
||||
// protocols will be used to keep port-protocol mapping derived from
|
||||
// exposed object
|
||||
{"protocols", false},
|
||||
{"container-port", false}, // alias of target-port
|
||||
{"target-port", false},
|
||||
{"port-name", false},
|
||||
|
|
@ -112,6 +115,15 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
|||
// Leave the port unnamed.
|
||||
servicePortName = ""
|
||||
}
|
||||
|
||||
protocolsString, found := params["protocols"]
|
||||
var portProtocolMap map[string]string
|
||||
if found && len(protocolsString) > 0 {
|
||||
portProtocolMap, err = ParseProtocols(protocolsString)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// ports takes precedence over port since it will be
|
||||
// specified only when the user hasn't specified a port
|
||||
// via --port and the exposed object has multiple ports.
|
||||
|
|
@ -122,6 +134,7 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
|||
return nil, fmt.Errorf("'port' is a required parameter.")
|
||||
}
|
||||
}
|
||||
|
||||
portStringSlice := strings.Split(portString, ",")
|
||||
for i, stillPortString := range portStringSlice {
|
||||
port, err := strconv.Atoi(stillPortString)
|
||||
|
|
@ -134,10 +147,26 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
|
|||
if len(portStringSlice) > 1 {
|
||||
name = fmt.Sprintf("port-%d", i+1)
|
||||
}
|
||||
protocol := params["protocol"]
|
||||
|
||||
switch {
|
||||
case len(protocol) == 0 && len(portProtocolMap) == 0:
|
||||
// Default to TCP, what the flag was doing previously.
|
||||
protocol = "TCP"
|
||||
case len(protocol) > 0 && len(portProtocolMap) > 0:
|
||||
// User has specified the --protocol while exposing a multiprotocol resource
|
||||
// We should stomp multiple protocols with the one specified ie. do nothing
|
||||
case len(protocol) == 0 && len(portProtocolMap) > 0:
|
||||
// no --protocol and we expose a multiprotocol resource
|
||||
protocol = "TCP" // have the default so we can stay sane
|
||||
if exposeProtocol, found := portProtocolMap[stillPortString]; found {
|
||||
protocol = exposeProtocol
|
||||
}
|
||||
}
|
||||
ports = append(ports, api.ServicePort{
|
||||
Name: name,
|
||||
Port: int32(port),
|
||||
Protocol: api.Protocol(params["protocol"]),
|
||||
Protocol: api.Protocol(protocol),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
23
vendor/k8s.io/kubernetes/pkg/kubectl/sorted_resource_name_list.go
generated
vendored
23
vendor/k8s.io/kubernetes/pkg/kubectl/sorted_resource_name_list.go
generated
vendored
|
|
@ -17,7 +17,10 @@ limitations under the License.
|
|||
package kubectl
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
qosutil "k8s.io/kubernetes/pkg/kubelet/qos/util"
|
||||
)
|
||||
|
||||
type SortableResourceNames []api.ResourceName
|
||||
|
|
@ -34,6 +37,16 @@ func (list SortableResourceNames) Less(i, j int) bool {
|
|||
return list[i] < list[j]
|
||||
}
|
||||
|
||||
// SortedResourceNames returns the sorted resource names of a resource list.
|
||||
func SortedResourceNames(list api.ResourceList) []api.ResourceName {
|
||||
resources := make([]api.ResourceName, 0, len(list))
|
||||
for res := range list {
|
||||
resources = append(resources, res)
|
||||
}
|
||||
sort.Sort(SortableResourceNames(resources))
|
||||
return resources
|
||||
}
|
||||
|
||||
type SortableResourceQuotas []api.ResourceQuota
|
||||
|
||||
func (list SortableResourceQuotas) Len() int {
|
||||
|
|
@ -47,3 +60,13 @@ func (list SortableResourceQuotas) Swap(i, j int) {
|
|||
func (list SortableResourceQuotas) Less(i, j int) bool {
|
||||
return list[i].Name < list[j].Name
|
||||
}
|
||||
|
||||
// SortedQoSResourceNames returns the sorted resource names of a QoS list.
|
||||
func SortedQoSResourceNames(list qosutil.QoSList) []api.ResourceName {
|
||||
resources := make([]api.ResourceName, 0, len(list))
|
||||
for res := range list {
|
||||
resources = append(resources, res)
|
||||
}
|
||||
sort.Sort(SortableResourceNames(resources))
|
||||
return resources
|
||||
}
|
||||
|
|
|
|||
25
vendor/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go
generated
vendored
25
vendor/k8s.io/kubernetes/pkg/kubectl/sorting_printer.go
generated
vendored
|
|
@ -23,8 +23,10 @@ import (
|
|||
"sort"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/integer"
|
||||
"k8s.io/kubernetes/pkg/util/jsonpath"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
|
@ -153,6 +155,29 @@ func isLess(i, j reflect.Value) (bool, error) {
|
|||
return i.String() < j.String(), nil
|
||||
case reflect.Ptr:
|
||||
return isLess(i.Elem(), j.Elem())
|
||||
case reflect.Struct:
|
||||
// sort unversioned.Time
|
||||
in := i.Interface()
|
||||
if t, ok := in.(unversioned.Time); ok {
|
||||
return t.Before(j.Interface().(unversioned.Time)), nil
|
||||
}
|
||||
// fallback to the fields comparison
|
||||
for idx := 0; idx < i.NumField(); idx++ {
|
||||
less, err := isLess(i.Field(idx), j.Field(idx))
|
||||
if err != nil || !less {
|
||||
return less, err
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
case reflect.Array, reflect.Slice:
|
||||
// note: the length of i and j may be different
|
||||
for idx := 0; idx < integer.IntMin(i.Len(), j.Len()); idx++ {
|
||||
less, err := isLess(i.Index(idx), j.Index(idx))
|
||||
if err != nil || !less {
|
||||
return less, err
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
default:
|
||||
return false, fmt.Errorf("unsortable type: %v", i.Kind())
|
||||
}
|
||||
|
|
|
|||
5
vendor/k8s.io/kubernetes/pkg/kubectl/stop.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/kubectl/stop.go
generated
vendored
|
|
@ -378,7 +378,7 @@ func (reaper *DeploymentReaper) Stop(namespace, name string, timeout time.Durati
|
|||
// Use observedGeneration to determine if the deployment controller noticed the pause.
|
||||
if err := deploymentutil.WaitForObservedDeployment(func() (*extensions.Deployment, error) {
|
||||
return deployments.Get(name)
|
||||
}, deployment.Generation, 10*time.Millisecond, 1*time.Minute); err != nil {
|
||||
}, deployment.Generation, 1*time.Second, 1*time.Minute); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -396,7 +396,8 @@ func (reaper *DeploymentReaper) Stop(namespace, name string, timeout time.Durati
|
|||
errList := []error{}
|
||||
for _, rc := range rsList.Items {
|
||||
if err := rsReaper.Stop(rc.Namespace, rc.Name, timeout, gracePeriod); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
scaleGetErr, ok := err.(*ScaleError)
|
||||
if !errors.IsNotFound(err) || ok && !errors.IsNotFound(scaleGetErr.ActualError) {
|
||||
errList = append(errList, err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue