...

Source file src/k8s.io/kubectl/pkg/polymorphichelpers/mapbasedselectorforobject.go

Documentation: k8s.io/kubectl/pkg/polymorphichelpers

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package polymorphichelpers
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	appsv1 "k8s.io/api/apps/v1"
    24  	appsv1beta1 "k8s.io/api/apps/v1beta1"
    25  	appsv1beta2 "k8s.io/api/apps/v1beta2"
    26  	corev1 "k8s.io/api/core/v1"
    27  	extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
    28  	"k8s.io/apimachinery/pkg/runtime"
    29  )
    30  
    31  // mapBasedSelectorForObject returns the map-based selector associated with the provided object. If a
    32  // new set-based selector is provided, an error is returned if the selector cannot be converted to a
    33  // map-based selector
    34  func mapBasedSelectorForObject(object runtime.Object) (string, error) {
    35  	// TODO: replace with a swagger schema based approach (identify pod selector via schema introspection)
    36  	switch t := object.(type) {
    37  	case *corev1.ReplicationController:
    38  		return MakeLabels(t.Spec.Selector), nil
    39  
    40  	case *corev1.Pod:
    41  		if len(t.Labels) == 0 {
    42  			return "", fmt.Errorf("the pod has no labels and cannot be exposed")
    43  		}
    44  		return MakeLabels(t.Labels), nil
    45  
    46  	case *corev1.Service:
    47  		if t.Spec.Selector == nil {
    48  			return "", fmt.Errorf("the service has no pod selector set")
    49  		}
    50  		return MakeLabels(t.Spec.Selector), nil
    51  
    52  	case *extensionsv1beta1.Deployment:
    53  		// "extensions" deployments use pod template labels if selector is not set.
    54  		var labels map[string]string
    55  		if t.Spec.Selector != nil {
    56  			// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
    57  			// operator, DoubleEquals operator and In operator with only one element in the set.
    58  			if len(t.Spec.Selector.MatchExpressions) > 0 {
    59  				return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions)
    60  			}
    61  			labels = t.Spec.Selector.MatchLabels
    62  		} else {
    63  			labels = t.Spec.Template.Labels
    64  		}
    65  		if len(labels) == 0 {
    66  			return "", fmt.Errorf("the deployment has no labels or selectors and cannot be exposed")
    67  		}
    68  		return MakeLabels(labels), nil
    69  
    70  	case *appsv1.Deployment:
    71  		// "apps" deployments must have the selector set.
    72  		if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 {
    73  			return "", fmt.Errorf("invalid deployment: no selectors, therefore cannot be exposed")
    74  		}
    75  		// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
    76  		// operator, DoubleEquals operator and In operator with only one element in the set.
    77  		if len(t.Spec.Selector.MatchExpressions) > 0 {
    78  			return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions)
    79  		}
    80  		return MakeLabels(t.Spec.Selector.MatchLabels), nil
    81  
    82  	case *appsv1beta2.Deployment:
    83  		// "apps" deployments must have the selector set.
    84  		if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 {
    85  			return "", fmt.Errorf("invalid deployment: no selectors, therefore cannot be exposed")
    86  		}
    87  		// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
    88  		// operator, DoubleEquals operator and In operator with only one element in the set.
    89  		if len(t.Spec.Selector.MatchExpressions) > 0 {
    90  			return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions)
    91  		}
    92  		return MakeLabels(t.Spec.Selector.MatchLabels), nil
    93  
    94  	case *appsv1beta1.Deployment:
    95  		// "apps" deployments must have the selector set.
    96  		if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 {
    97  			return "", fmt.Errorf("invalid deployment: no selectors, therefore cannot be exposed")
    98  		}
    99  		// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
   100  		// operator, DoubleEquals operator and In operator with only one element in the set.
   101  		if len(t.Spec.Selector.MatchExpressions) > 0 {
   102  			return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions)
   103  		}
   104  		return MakeLabels(t.Spec.Selector.MatchLabels), nil
   105  
   106  	case *extensionsv1beta1.ReplicaSet:
   107  		// "extensions" replicasets use pod template labels if selector is not set.
   108  		var labels map[string]string
   109  		if t.Spec.Selector != nil {
   110  			// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
   111  			// operator, DoubleEquals operator and In operator with only one element in the set.
   112  			if len(t.Spec.Selector.MatchExpressions) > 0 {
   113  				return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions)
   114  			}
   115  			labels = t.Spec.Selector.MatchLabels
   116  		} else {
   117  			labels = t.Spec.Template.Labels
   118  		}
   119  		if len(labels) == 0 {
   120  			return "", fmt.Errorf("the replica set has no labels or selectors and cannot be exposed")
   121  		}
   122  		return MakeLabels(labels), nil
   123  
   124  	case *appsv1.ReplicaSet:
   125  		// "apps" replicasets must have the selector set.
   126  		if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 {
   127  			return "", fmt.Errorf("invalid replicaset: no selectors, therefore cannot be exposed")
   128  		}
   129  		// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
   130  		// operator, DoubleEquals operator and In operator with only one element in the set.
   131  		if len(t.Spec.Selector.MatchExpressions) > 0 {
   132  			return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions)
   133  		}
   134  		return MakeLabels(t.Spec.Selector.MatchLabels), nil
   135  
   136  	case *appsv1beta2.ReplicaSet:
   137  		// "apps" replicasets must have the selector set.
   138  		if t.Spec.Selector == nil || len(t.Spec.Selector.MatchLabels) == 0 {
   139  			return "", fmt.Errorf("invalid replicaset: no selectors, therefore cannot be exposed")
   140  		}
   141  		// TODO(madhusudancs): Make this smarter by admitting MatchExpressions with Equals
   142  		// operator, DoubleEquals operator and In operator with only one element in the set.
   143  		if len(t.Spec.Selector.MatchExpressions) > 0 {
   144  			return "", fmt.Errorf("couldn't convert expressions - \"%+v\" to map-based selector format", t.Spec.Selector.MatchExpressions)
   145  		}
   146  		return MakeLabels(t.Spec.Selector.MatchLabels), nil
   147  
   148  	default:
   149  		return "", fmt.Errorf("cannot extract pod selector from %T", object)
   150  	}
   151  
   152  }
   153  
   154  func MakeLabels(labels map[string]string) string {
   155  	out := []string{}
   156  	for key, value := range labels {
   157  		out = append(out, fmt.Sprintf("%s=%s", key, value))
   158  	}
   159  	return strings.Join(out, ",")
   160  }
   161  

View as plain text