mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	Merge pull request #32811 from fraenkel/headless_service
Automatic merge from submit-queue (batch tested with PRs 38260, 32811, 28458, 33570, 37096) Allow no ports when exposing headless service fixes #32795
This commit is contained in:
		@@ -177,6 +177,8 @@ func RunExpose(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
 | 
			
		||||
			params["selector"] = s
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		isHeadlessService := params["cluster-ip"] == "None"
 | 
			
		||||
 | 
			
		||||
		// For objects that need a port, derive it from the exposed object in case a user
 | 
			
		||||
		// didn't explicitly specify one via --port
 | 
			
		||||
		if port, found := params["port"]; found && kubectl.IsZero(port) {
 | 
			
		||||
@@ -186,7 +188,9 @@ func RunExpose(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
 | 
			
		||||
			}
 | 
			
		||||
			switch len(ports) {
 | 
			
		||||
			case 0:
 | 
			
		||||
				if !isHeadlessService {
 | 
			
		||||
					return cmdutil.UsageError(cmd, "couldn't find port via --port flag or introspection")
 | 
			
		||||
				}
 | 
			
		||||
			case 1:
 | 
			
		||||
				params["port"] = ports[0]
 | 
			
		||||
			default:
 | 
			
		||||
 
 | 
			
		||||
@@ -264,6 +264,32 @@ func TestRunExposeService(t *testing.T) {
 | 
			
		||||
			expected: "service \"foo\" exposed",
 | 
			
		||||
			status:   200,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "expose-headless-service-no-port",
 | 
			
		||||
			args: []string{"service", "baz"},
 | 
			
		||||
			ns:   "test",
 | 
			
		||||
			calls: map[string]string{
 | 
			
		||||
				"GET":  "/namespaces/test/services/baz",
 | 
			
		||||
				"POST": "/namespaces/test/services",
 | 
			
		||||
			},
 | 
			
		||||
			input: &api.Service{
 | 
			
		||||
				ObjectMeta: api.ObjectMeta{Name: "baz", Namespace: "test", ResourceVersion: "12"},
 | 
			
		||||
				Spec: api.ServiceSpec{
 | 
			
		||||
					Selector: map[string]string{"app": "go"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			flags: map[string]string{"selector": "func=stream", "name": "foo", "labels": "svc=test", "cluster-ip": "None", "dry-run": "true"},
 | 
			
		||||
			output: &api.Service{
 | 
			
		||||
				ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "", Labels: map[string]string{"svc": "test"}},
 | 
			
		||||
				Spec: api.ServiceSpec{
 | 
			
		||||
					Ports:     []api.ServicePort{},
 | 
			
		||||
					Selector:  map[string]string{"func": "stream"},
 | 
			
		||||
					ClusterIP: api.ClusterIPNone,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expected: "service \"foo\" exposed",
 | 
			
		||||
			status:   200,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "expose-from-file",
 | 
			
		||||
			args: []string{},
 | 
			
		||||
 
 | 
			
		||||
@@ -110,6 +110,9 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
			return nil, fmt.Errorf("'name' is a required parameter.")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	isHeadlessService := params["cluster-ip"] == "None"
 | 
			
		||||
 | 
			
		||||
	ports := []api.ServicePort{}
 | 
			
		||||
	servicePortName, found := params["port-name"]
 | 
			
		||||
	if !found {
 | 
			
		||||
@@ -131,11 +134,12 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
	var portString string
 | 
			
		||||
	if portString, found = params["ports"]; !found {
 | 
			
		||||
		portString, found = params["port"]
 | 
			
		||||
		if !found {
 | 
			
		||||
		if !found && !isHeadlessService {
 | 
			
		||||
			return nil, fmt.Errorf("'port' is a required parameter.")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if portString != "" {
 | 
			
		||||
		portStringSlice := strings.Split(portString, ",")
 | 
			
		||||
		for i, stillPortString := range portStringSlice {
 | 
			
		||||
			port, err := strconv.Atoi(stillPortString)
 | 
			
		||||
@@ -170,6 +174,7 @@ func generate(genericParams map[string]interface{}) (runtime.Object, error) {
 | 
			
		||||
				Protocol: api.Protocol(protocol),
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	service := api.Service{
 | 
			
		||||
		ObjectMeta: api.ObjectMeta{
 | 
			
		||||
 
 | 
			
		||||
@@ -536,6 +536,29 @@ func TestGenerateService(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			generator: ServiceGeneratorV2{},
 | 
			
		||||
			params: map[string]interface{}{
 | 
			
		||||
				"selector":       "foo=bar,baz=blah",
 | 
			
		||||
				"name":           "test",
 | 
			
		||||
				"protocol":       "TCP",
 | 
			
		||||
				"container-port": "1234",
 | 
			
		||||
				"cluster-ip":     "None",
 | 
			
		||||
			},
 | 
			
		||||
			expected: api.Service{
 | 
			
		||||
				ObjectMeta: api.ObjectMeta{
 | 
			
		||||
					Name: "test",
 | 
			
		||||
				},
 | 
			
		||||
				Spec: api.ServiceSpec{
 | 
			
		||||
					Selector: map[string]string{
 | 
			
		||||
						"foo": "bar",
 | 
			
		||||
						"baz": "blah",
 | 
			
		||||
					},
 | 
			
		||||
					Ports:     []api.ServicePort{},
 | 
			
		||||
					ClusterIP: api.ClusterIPNone,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, test := range tests {
 | 
			
		||||
		obj, err := test.generator.Generate(test.params)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user