Commit 6b83f89d authored by juanvallejo's avatar juanvallejo

Add option to set a service nodeport

This patch adds the option to set a nodeport when creating a NodePort service. In case of a port allocation error due to a specified port being out of the valid range, the error now includes the valid range. If a `--node-port` value is not specified, it defaults to zero, in which case the allocator will default to its current behavior of assigning an available port. This patch also adds a new helper function in `cmd/util/helpers.go` to retrieve `Int32` cobra flags. **Example** ``` $ kubectl create service nodeport mynodeport --tcp=8080:7777 --node-port=1 The Service "mynodeport" is invalid: spec.ports[0].nodePort: Invalid value: 1: provided port is not in the valid range. Valid ports range from 30000-32767 $ kubectl create service nodeport mynodeport --tcp=8080:7777 --node-port=30000 service "mynodeport" created $ oc describe service mynodeport Name: mynodeport Namespace: default Labels: app=mynodeport Selector: app=mynodeport Type: NodePort IP: 172.30.81.254 Port: 8080-7777 8080/TCP NodePort: 8080-7777 30000/TCP Endpoints: <none> Session Affinity: None No events. ```
parent c2f68886
......@@ -134,6 +134,7 @@ func NewCmdCreateServiceNodePort(f *cmdutil.Factory, cmdOut io.Writer) *cobra.Co
cmdutil.AddValidateFlags(cmd)
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddGeneratorFlags(cmd, cmdutil.ServiceNodePortGeneratorV1Name)
cmd.Flags().Int32("node-port", 0, "Port used to expose the service on each node in a cluster.")
addPortFlags(cmd)
return cmd
}
......@@ -152,6 +153,7 @@ func CreateServiceNodePort(f *cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Comm
TCP: cmdutil.GetFlagStringSlice(cmd, "tcp"),
Type: api.ServiceTypeNodePort,
ClusterIP: "",
NodePort: cmdutil.GetFlagInt32(cmd, "node-port"),
}
default:
return cmdutil.UsageError(cmd, fmt.Sprintf("Generator: %s not supported.", generatorName))
......
......@@ -296,7 +296,7 @@ func isWatch(cmd *cobra.Command) bool {
func GetFlagString(cmd *cobra.Command, flag string) string {
s, err := cmd.Flags().GetString(flag)
if err != nil {
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
}
return s
}
......@@ -305,7 +305,7 @@ func GetFlagString(cmd *cobra.Command, flag string) string {
func GetFlagStringSlice(cmd *cobra.Command, flag string) []string {
s, err := cmd.Flags().GetStringSlice(flag)
if err != nil {
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
}
return s
}
......@@ -331,7 +331,7 @@ func GetWideFlag(cmd *cobra.Command) bool {
func GetFlagBool(cmd *cobra.Command, flag string) bool {
b, err := cmd.Flags().GetBool(flag)
if err != nil {
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
}
return b
}
......@@ -340,7 +340,7 @@ func GetFlagBool(cmd *cobra.Command, flag string) bool {
func GetFlagInt(cmd *cobra.Command, flag string) int {
i, err := cmd.Flags().GetInt(flag)
if err != nil {
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
}
return i
}
......@@ -349,7 +349,16 @@ func GetFlagInt(cmd *cobra.Command, flag string) int {
func GetFlagInt64(cmd *cobra.Command, flag string) int64 {
i, err := cmd.Flags().GetInt64(flag)
if err != nil {
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
}
return i
}
// Assumes the flag has a default value.
func GetFlagInt32(cmd *cobra.Command, flag string) int32 {
i, err := cmd.Flags().GetInt32(flag)
if err != nil {
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
}
return i
}
......@@ -357,7 +366,7 @@ func GetFlagInt64(cmd *cobra.Command, flag string) int64 {
func GetFlagDuration(cmd *cobra.Command, flag string) time.Duration {
d, err := cmd.Flags().GetDuration(flag)
if err != nil {
glog.Fatalf("err accessing flag %s for command %s: %v", flag, cmd.Name(), err)
glog.Fatalf("error accessing flag %s for command %s: %v", flag, cmd.Name(), err)
}
return d
}
......
......@@ -31,6 +31,7 @@ type ServiceCommonGeneratorV1 struct {
TCP []string
Type api.ServiceType
ClusterIP string
NodePort int32
}
type ServiceClusterIPGeneratorV1 struct {
......@@ -56,6 +57,7 @@ func (ServiceNodePortGeneratorV1) ParamNames() []GeneratorParam {
return []GeneratorParam{
{"name", true},
{"tcp", true},
{"nodeport", true},
}
}
func (ServiceLoadBalancerGeneratorV1) ParamNames() []GeneratorParam {
......@@ -174,12 +176,14 @@ func (s ServiceCommonGeneratorV1) StructuredGenerate() (runtime.Object, error) {
if err != nil {
return nil, err
}
portName := strings.Replace(tcpString, ":", "-", -1)
ports = append(ports, api.ServicePort{
Name: portName,
Port: port,
TargetPort: targetPort,
Protocol: api.Protocol("TCP"),
NodePort: s.NodePort,
})
}
......
......@@ -82,7 +82,10 @@ func (r *PortAllocator) Free() int {
func (r *PortAllocator) Allocate(port int) error {
ok, offset := r.contains(port)
if !ok {
return ErrNotInRange
// include valid port range in error
validPorts := r.portRange.String()
msg := fmt.Sprintf("Valid ports range is %s", validPorts)
return fmt.Errorf("%v. %s", ErrNotInRange, msg)
}
allocated, err := r.alloc.Allocate(offset)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment