k8s.io/kubernetes@v1.29.3/pkg/api/service/testing/make.go (about)

     1  /*
     2  Copyright 2021 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 testing
    18  
    19  import (
    20  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    21  	"k8s.io/apimachinery/pkg/util/intstr"
    22  	utilpointer "k8s.io/utils/pointer"
    23  
    24  	api "k8s.io/kubernetes/pkg/apis/core"
    25  )
    26  
    27  // Tweak is a function that modifies a Service.
    28  type Tweak func(*api.Service)
    29  
    30  // MakeService helps construct Service objects (which pass API validation) more
    31  // legibly and tersely than a Go struct definition.  By default this produces
    32  // a ClusterIP service with a single port and a trivial selector.  The caller
    33  // can pass any number of tweak functions to further modify the result.
    34  func MakeService(name string, tweaks ...Tweak) *api.Service {
    35  	// NOTE: Any field that would be populated by defaulting needs to be
    36  	// present and valid here.
    37  	svc := &api.Service{
    38  		ObjectMeta: metav1.ObjectMeta{
    39  			Name:      name,
    40  			Namespace: metav1.NamespaceDefault,
    41  		},
    42  		Spec: api.ServiceSpec{
    43  			Selector:        map[string]string{"k": "v"},
    44  			SessionAffinity: api.ServiceAffinityNone,
    45  		},
    46  	}
    47  	// Default to ClusterIP
    48  	SetTypeClusterIP(svc)
    49  	// Default to 1 port
    50  	SetPorts(MakeServicePort("", 93, intstr.FromInt32(76), api.ProtocolTCP))(svc)
    51  
    52  	for _, tweak := range tweaks {
    53  		tweak(svc)
    54  	}
    55  
    56  	return svc
    57  }
    58  
    59  // SetTypeClusterIP sets the service type to ClusterIP and clears other fields.
    60  func SetTypeClusterIP(svc *api.Service) {
    61  	svc.Spec.Type = api.ServiceTypeClusterIP
    62  	for i := range svc.Spec.Ports {
    63  		svc.Spec.Ports[i].NodePort = 0
    64  	}
    65  	svc.Spec.ExternalName = ""
    66  	svc.Spec.ExternalTrafficPolicy = ""
    67  	svc.Spec.AllocateLoadBalancerNodePorts = nil
    68  	internalTrafficPolicy := api.ServiceInternalTrafficPolicyCluster
    69  	svc.Spec.InternalTrafficPolicy = &internalTrafficPolicy
    70  }
    71  
    72  // SetTypeNodePort sets the service type to NodePort and clears other fields.
    73  func SetTypeNodePort(svc *api.Service) {
    74  	svc.Spec.Type = api.ServiceTypeNodePort
    75  	svc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyCluster
    76  	svc.Spec.ExternalName = ""
    77  	svc.Spec.AllocateLoadBalancerNodePorts = nil
    78  	internalTrafficPolicy := api.ServiceInternalTrafficPolicyCluster
    79  	svc.Spec.InternalTrafficPolicy = &internalTrafficPolicy
    80  }
    81  
    82  // SetTypeLoadBalancer sets the service type to LoadBalancer and clears other fields.
    83  func SetTypeLoadBalancer(svc *api.Service) {
    84  	svc.Spec.Type = api.ServiceTypeLoadBalancer
    85  	svc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyCluster
    86  	svc.Spec.AllocateLoadBalancerNodePorts = utilpointer.BoolPtr(true)
    87  	svc.Spec.ExternalName = ""
    88  	internalTrafficPolicy := api.ServiceInternalTrafficPolicyCluster
    89  	svc.Spec.InternalTrafficPolicy = &internalTrafficPolicy
    90  }
    91  
    92  // SetTypeExternalName sets the service type to ExternalName and clears other fields.
    93  func SetTypeExternalName(svc *api.Service) {
    94  	svc.Spec.Type = api.ServiceTypeExternalName
    95  	svc.Spec.ExternalName = "example.com"
    96  	svc.Spec.ExternalTrafficPolicy = ""
    97  	svc.Spec.ClusterIP = ""
    98  	svc.Spec.ClusterIPs = nil
    99  	svc.Spec.AllocateLoadBalancerNodePorts = nil
   100  	svc.Spec.InternalTrafficPolicy = nil
   101  }
   102  
   103  // SetPorts sets the service ports list.
   104  func SetPorts(ports ...api.ServicePort) Tweak {
   105  	return func(svc *api.Service) {
   106  		svc.Spec.Ports = ports
   107  	}
   108  }
   109  
   110  // MakeServicePort helps construct ServicePort objects which pass API
   111  // validation.
   112  func MakeServicePort(name string, port int, tgtPort intstr.IntOrString, proto api.Protocol) api.ServicePort {
   113  	return api.ServicePort{
   114  		Name:       name,
   115  		Port:       int32(port),
   116  		TargetPort: tgtPort,
   117  		Protocol:   proto,
   118  	}
   119  }
   120  
   121  // SetHeadless sets the service as headless and clears other fields.
   122  func SetHeadless(svc *api.Service) {
   123  	SetTypeClusterIP(svc)
   124  	SetClusterIPs(api.ClusterIPNone)(svc)
   125  }
   126  
   127  // SetSelector sets the service selector.
   128  func SetSelector(sel map[string]string) Tweak {
   129  	return func(svc *api.Service) {
   130  		svc.Spec.Selector = map[string]string{}
   131  		for k, v := range sel {
   132  			svc.Spec.Selector[k] = v
   133  		}
   134  	}
   135  }
   136  
   137  // SetClusterIP sets the service ClusterIP fields.
   138  func SetClusterIP(ip string) Tweak {
   139  	return func(svc *api.Service) {
   140  		svc.Spec.ClusterIP = ip
   141  	}
   142  }
   143  
   144  // SetClusterIPs sets the service ClusterIP and ClusterIPs fields.
   145  func SetClusterIPs(ips ...string) Tweak {
   146  	return func(svc *api.Service) {
   147  		svc.Spec.ClusterIP = ips[0]
   148  		svc.Spec.ClusterIPs = ips
   149  	}
   150  }
   151  
   152  // SetIPFamilies sets the service IPFamilies field.
   153  func SetIPFamilies(families ...api.IPFamily) Tweak {
   154  	return func(svc *api.Service) {
   155  		svc.Spec.IPFamilies = families
   156  	}
   157  }
   158  
   159  // SetIPFamilyPolicy sets the service IPFamilyPolicy field.
   160  func SetIPFamilyPolicy(policy api.IPFamilyPolicy) Tweak {
   161  	return func(svc *api.Service) {
   162  		svc.Spec.IPFamilyPolicy = &policy
   163  	}
   164  }
   165  
   166  // SetNodePorts sets the values for each node port, in order.  If less values
   167  // are specified than there are ports, the rest are untouched.
   168  func SetNodePorts(values ...int) Tweak {
   169  	return func(svc *api.Service) {
   170  		for i := range svc.Spec.Ports {
   171  			if i >= len(values) {
   172  				break
   173  			}
   174  			svc.Spec.Ports[i].NodePort = int32(values[i])
   175  		}
   176  	}
   177  }
   178  
   179  // SetInternalTrafficPolicy sets the internalTrafficPolicy field for a Service.
   180  func SetInternalTrafficPolicy(policy api.ServiceInternalTrafficPolicy) Tweak {
   181  	return func(svc *api.Service) {
   182  		svc.Spec.InternalTrafficPolicy = &policy
   183  	}
   184  }
   185  
   186  // SetExternalTrafficPolicy sets the externalTrafficPolicy field for a Service.
   187  func SetExternalTrafficPolicy(policy api.ServiceExternalTrafficPolicy) Tweak {
   188  	return func(svc *api.Service) {
   189  		svc.Spec.ExternalTrafficPolicy = policy
   190  	}
   191  }
   192  
   193  // SetAllocateLoadBalancerNodePorts sets the allocate LB node port field.
   194  func SetAllocateLoadBalancerNodePorts(val bool) Tweak {
   195  	return func(svc *api.Service) {
   196  		svc.Spec.AllocateLoadBalancerNodePorts = utilpointer.BoolPtr(val)
   197  	}
   198  }
   199  
   200  // SetUniqueNodePorts sets all nodeports to unique values.
   201  func SetUniqueNodePorts(svc *api.Service) {
   202  	for i := range svc.Spec.Ports {
   203  		svc.Spec.Ports[i].NodePort = int32(30000 + i)
   204  	}
   205  }
   206  
   207  // SetHealthCheckNodePort sets the healthCheckNodePort field for a Service.
   208  func SetHealthCheckNodePort(value int32) Tweak {
   209  	return func(svc *api.Service) {
   210  		svc.Spec.HealthCheckNodePort = value
   211  	}
   212  }
   213  
   214  // SetSessionAffinity sets the SessionAffinity field.
   215  func SetSessionAffinity(affinity api.ServiceAffinity) Tweak {
   216  	return func(svc *api.Service) {
   217  		svc.Spec.SessionAffinity = affinity
   218  		switch affinity {
   219  		case api.ServiceAffinityNone:
   220  			svc.Spec.SessionAffinityConfig = nil
   221  		case api.ServiceAffinityClientIP:
   222  			timeout := int32(10)
   223  			svc.Spec.SessionAffinityConfig = &api.SessionAffinityConfig{
   224  				ClientIP: &api.ClientIPConfig{
   225  					TimeoutSeconds: &timeout,
   226  				},
   227  			}
   228  		}
   229  	}
   230  }
   231  
   232  // SetExternalName sets the ExternalName field.
   233  func SetExternalName(val string) Tweak {
   234  	return func(svc *api.Service) {
   235  		svc.Spec.ExternalName = val
   236  	}
   237  }