Skip to content

Commit 65ee911

Browse files
allmightyspiffGitHub Enterprise
authored andcommitted
Merge pull request #869 from SoftLayer/issues714
Adds SSL support for LoadBalancer protocols
2 parents dc1e25d + ba5a8ba commit 65ee911

5 files changed

Lines changed: 107 additions & 89 deletions

File tree

plugin/commands/loadbal/protocol_edit.go

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type ProtocolEditCommand struct {
2727
Sticky string
2828
ClientTimeout int
2929
ServerTimeout int
30+
SslId int
3031
}
3132

3233
func NewProtocolEditCommand(sl *metadata.SoftlayerCommand) *ProtocolEditCommand {
@@ -37,23 +38,30 @@ func NewProtocolEditCommand(sl *metadata.SoftlayerCommand) *ProtocolEditCommand
3738
cobraCmd := &cobra.Command{
3839
Use: "protocol-edit",
3940
Short: T("Edit load balancer protocol"),
40-
Long: T("${COMMAND_NAME} sl loadbal protocol-edit (--id LOADBAL_ID) (--protocol-uuid PROTOCOL_UUID) [--front-protocol PROTOCOL] [back-protocol PROTOCOL] [--front-port PORT] [--back-port PORT] [-m, --method METHOD] [-c, --connections CONNECTIONS] [--sticky cookie | source-ip] [--client-timeout SECONDS] [--server-timeout SECONDS]"),
41-
Args: metadata.NoArgs,
41+
Long: T(`Use '${COMMAND_NAME} sl loadbal detail' to find the --protocol-uuid values for a loadbalancer
42+
Example:
43+
${COMMAND_NAME} sl loadbal protocol-add --id 1115129 --protocol-uuid 8ec8911a-c32d-4678-89fe-979f182c822f --ssl-id 123
44+
This command changes the SSL certificate
45+
`),
46+
Args: metadata.NoArgs,
4247
RunE: func(cmd *cobra.Command, args []string) error {
4348
return thisCmd.Run(args)
4449
},
4550
}
46-
cobraCmd.Flags().IntVar(&thisCmd.Id, "id", 0, T("ID for the load balancer [required]"))
51+
cobraCmd.Flags().IntVar(&thisCmd.Id, "id", -1, T("ID for the load balancer [required]"))
4752
cobraCmd.Flags().StringVar(&thisCmd.ProtocolUuid, "protocol-uuid", "", T("UUID of the protocol you want to edit."))
48-
cobraCmd.Flags().StringVar(&thisCmd.FrontProtocol, "front-protocol", "HTTP", T("Protocol type to use for incoming connections: [HTTP|HTTPS|TCP]. Default: HTTP"))
53+
cobraCmd.Flags().StringVar(&thisCmd.FrontProtocol, "front-protocol", "", T("Protocol type to use for incoming connections: [HTTP|HTTPS|TCP]. Default: HTTP"))
4954
cobraCmd.Flags().StringVar(&thisCmd.BackProtocol, "back-protocol", "", T("Protocol type to use when connecting to backend servers: [HTTP|HTTPS|TCP]. Defaults to whatever --front-protocol is"))
50-
cobraCmd.Flags().IntVar(&thisCmd.FrontPort, "front-port", 80, T("Internet side port"))
51-
cobraCmd.Flags().IntVar(&thisCmd.BackPort, "back-port", 80, T("Private side port"))
52-
cobraCmd.Flags().StringVarP(&thisCmd.Method, "method", "m", "ROUNDROBIN", T("Balancing Method: [ROUNDROBIN|LEASTCONNECTION|WEIGHTED_RR]"))
53-
cobraCmd.Flags().IntVarP(&thisCmd.Connections, "connections", "c", 0, T("Maximum number of connections to allow"))
55+
cobraCmd.Flags().IntVar(&thisCmd.FrontPort, "front-port", -1, T("Internet side port"))
56+
cobraCmd.Flags().IntVar(&thisCmd.BackPort, "back-port", -1, T("Private side port"))
57+
cobraCmd.Flags().StringVarP(&thisCmd.Method, "method", "m", "", T("Balancing Method: [ROUNDROBIN|LEASTCONNECTION|WEIGHTED_RR]"))
58+
cobraCmd.Flags().IntVarP(&thisCmd.Connections, "connections", "c", -1, T("Maximum number of connections to allow"))
5459
cobraCmd.Flags().StringVar(&thisCmd.Sticky, "sticky", "", T("Use 'cookie' or 'source-ip' to stick"))
55-
cobraCmd.Flags().IntVar(&thisCmd.ClientTimeout, "client-timeout", 0, T("Client side timeout setting, in seconds"))
56-
cobraCmd.Flags().IntVar(&thisCmd.ServerTimeout, "server-timeout", 0, T("Server side timeout setting, in seconds"))
60+
cobraCmd.Flags().IntVar(&thisCmd.ClientTimeout, "client-timeout", -1, T("Client side timeout setting, in seconds"))
61+
cobraCmd.Flags().IntVar(&thisCmd.ServerTimeout, "server-timeout", -1, T("Server side timeout setting, in seconds"))
62+
cobraCmd.Flags().IntVar(&thisCmd.SslId, "ssl-id", -1, T("Identifier of the SSL certificate to attach to this protocol. Only valid for HTTPS."))
63+
cobraCmd.MarkFlagRequired("id") //#nosec G104
64+
cobraCmd.MarkFlagRequired("protocol-uuid") //#nosec G104
5765
thisCmd.Command = cobraCmd
5866
return thisCmd
5967
}
@@ -62,7 +70,7 @@ func (cmd *ProtocolEditCommand) Run(args []string) error {
6270
protocolConfiguration := datatypes.Network_LBaaS_LoadBalancerProtocolConfiguration{}
6371

6472
loadbalID := cmd.Id
65-
if loadbalID == 0 {
73+
if loadbalID == -1 {
6674
return errors.NewMissingInputError("--id")
6775
}
6876

@@ -71,45 +79,37 @@ func (cmd *ProtocolEditCommand) Run(args []string) error {
7179
return errors.New(T("Failed to get load balancer: {{.ERR}}.", map[string]interface{}{"ERR": err.Error()}))
7280
}
7381

74-
protoUUID := cmd.ProtocolUuid
75-
if protoUUID == "" {
82+
if cmd.ProtocolUuid == "" {
7683
return errors.NewMissingInputError("--protocol-uuid")
7784
}
78-
protocolConfiguration.ListenerUuid = &protoUUID
85+
protocolConfiguration.ListenerUuid = &cmd.ProtocolUuid
7986

8087
if cmd.FrontProtocol != "" {
81-
frontProtocol := cmd.FrontProtocol
82-
protocolConfiguration.FrontendProtocol = &frontProtocol
88+
protocolConfiguration.FrontendProtocol = &cmd.FrontProtocol
8389
}
8490

8591
if cmd.BackProtocol != "" {
86-
backProtocol := cmd.BackProtocol
87-
protocolConfiguration.BackendProtocol = &backProtocol
92+
protocolConfiguration.BackendProtocol = &cmd.BackProtocol
8893
}
8994

90-
if cmd.FrontPort != 0 {
91-
frontPort := cmd.FrontPort
92-
protocolConfiguration.FrontendPort = &frontPort
95+
if cmd.FrontPort != -1 {
96+
protocolConfiguration.FrontendPort = &cmd.FrontPort
9397
}
9498

95-
if cmd.BackPort != 0 {
96-
backPort := cmd.BackPort
97-
protocolConfiguration.BackendPort = &backPort
99+
if cmd.BackPort != -1 {
100+
protocolConfiguration.BackendPort = &cmd.BackPort
98101
}
99102

100103
if cmd.Method != "" {
101-
method := cmd.Method
102-
protocolConfiguration.LoadBalancingMethod = &method
104+
protocolConfiguration.LoadBalancingMethod = &cmd.Method
103105
}
104106

105-
if cmd.ClientTimeout != 0 {
106-
cTimeout := cmd.ClientTimeout
107-
protocolConfiguration.ClientTimeout = &cTimeout
107+
if cmd.ClientTimeout != -1 {
108+
protocolConfiguration.ClientTimeout = &cmd.ClientTimeout
108109
}
109110

110-
if cmd.ServerTimeout != 0 {
111-
sTimeout := cmd.ServerTimeout
112-
protocolConfiguration.ServerTimeout = &sTimeout
111+
if cmd.ServerTimeout != -1 {
112+
protocolConfiguration.ServerTimeout = &cmd.ServerTimeout
113113
}
114114

115115
var sessionType string
@@ -123,12 +123,17 @@ func (cmd *ProtocolEditCommand) Run(args []string) error {
123123
return errors.NewInvalidUsageError(T("Value of option '--sticky' should be cookie or source-ip"))
124124
}
125125

126-
if cmd.Connections != 0 {
127-
connections := cmd.Connections
128-
protocolConfiguration.MaxConn = &connections
126+
if cmd.Connections != -1 {
127+
protocolConfiguration.MaxConn = &cmd.Connections
129128
}
130129

131-
_, err = cmd.LoadBalancerManager.AddLoadBalancerListener(&loadbalancerUUID, []datatypes.Network_LBaaS_LoadBalancerProtocolConfiguration{protocolConfiguration})
130+
if cmd.SslId != 0 {
131+
protocolConfiguration.TlsCertificateId = &cmd.SslId
132+
}
133+
134+
_, err = cmd.LoadBalancerManager.AddLoadBalancerListener(
135+
&loadbalancerUUID, []datatypes.Network_LBaaS_LoadBalancerProtocolConfiguration{protocolConfiguration},
136+
)
132137
if err != nil {
133138
return errors.New(T("Failed to edit protocol: {{.Error}}.\n", map[string]interface{}{"Error": err.Error()}))
134139
}

plugin/commands/loadbal/protocol_edit_test.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package loadbal_test
22

33
import (
44
"errors"
5-
65
"github.com/IBM-Cloud/ibm-cloud-cli-sdk/testhelpers/terminal"
76
. "github.com/onsi/ginkgo/v2"
87
. "github.com/onsi/gomega"
@@ -41,11 +40,11 @@ var _ = Describe("LoadBal_protocol-edit_Test", func() {
4140
It("Error No Id", func() {
4241
err := testhelpers.RunCobraCommand(cliCommand.Command)
4342
Expect(err).To(HaveOccurred())
44-
Expect(err.Error()).To(ContainSubstring("Incorrect Usage: '--id' is required"))
43+
Expect(err.Error()).To(ContainSubstring(`required flag(s) "id", "protocol-uuid" not set`))
4544
})
4645
It("Error unable to find Id", func() {
4746
fakeLBManager.GetLoadBalancerUUIDReturns("-", errors.New("SoftLayer_Exception_ApiError"))
48-
err := testhelpers.RunCobraCommand(cliCommand.Command, "--id", "12345")
47+
err := testhelpers.RunCobraCommand(cliCommand.Command, "--id", "12345", "--protocol-uuid=aaaa")
4948
Expect(err).To(HaveOccurred())
5049
Expect(err.Error()).To(ContainSubstring("Failed to get load balancer: SoftLayer_Exception_ApiError"))
5150
})
@@ -55,11 +54,14 @@ var _ = Describe("LoadBal_protocol-edit_Test", func() {
5554
It("Error no UUID", func() {
5655
err := testhelpers.RunCobraCommand(cliCommand.Command, "--id", "12345")
5756
Expect(err).To(HaveOccurred())
58-
Expect(err.Error()).To(ContainSubstring("'--protocol-uuid' is required"))
57+
Expect(err.Error()).To(ContainSubstring(`required flag(s) "protocol-uuid" not set`))
5958
})
6059
})
6160

6261
Context("Testing Options", func() {
62+
BeforeEach(func() {
63+
fakeLBManager.GetLoadBalancerUUIDReturns("aaa-bbb-111", nil)
64+
})
6365
It("with all arguments", func() {
6466
err := testhelpers.RunCobraCommand(cliCommand.Command, "--id", "12345", "--protocol-uuid", "abc123", "--front-protocol", "HTTP", "--back-protocol", "HTTP", "--front-port", "80", "--back-port", "80", "--method", "ROUNDROBIN", "--client-timeout", "100", "--server-timeout", "100", "--sticky", "cookie", "--connections", "5")
6567
Expect(err).NotTo(HaveOccurred())
@@ -77,6 +79,19 @@ var _ = Describe("LoadBal_protocol-edit_Test", func() {
7779
Expect(err).To(HaveOccurred())
7880
Expect(err.Error()).To(ContainSubstring("Value of option '--sticky' should be cookie or source-ip"))
7981
})
82+
It("--ssl-id option", func() {
83+
err := testhelpers.RunCobraCommand(cliCommand.Command, "--id", "12345", "--protocol-uuid=aaaa", "--ssl-id=9999", "--front-protocol=HTTPS")
84+
Expect(err).NotTo(HaveOccurred())
85+
lbUUID, argsForCall := fakeLBManager.AddLoadBalancerListenerArgsForCall(0)
86+
Expect(*lbUUID).To(Equal("aaa-bbb-111"))
87+
Expect(len(argsForCall)).To(Equal(1))
88+
// Making sure we are not sending in options we did not specify
89+
Expect(argsForCall[0].BackendProtocol).To(BeNil())
90+
91+
Expect(*argsForCall[0].FrontendProtocol).To(Equal("HTTPS"))
92+
Expect(*argsForCall[0].TlsCertificateId).To(Equal(9999))
93+
Expect(fakeUI.Outputs()).To(ContainSubstring("OK"))
94+
})
8095
})
8196

8297
Context("API Error", func() {

plugin/commands/loadbal/protocols_add.go

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type ProtocolAddCommand struct {
2626
Sticky string
2727
ClientTimeout int
2828
ServerTimeout int
29+
SslId int
2930
}
3031

3132
func NewProtocolAddCommand(sl *metadata.SoftlayerCommand) *ProtocolAddCommand {
@@ -36,22 +37,30 @@ func NewProtocolAddCommand(sl *metadata.SoftlayerCommand) *ProtocolAddCommand {
3637
cobraCmd := &cobra.Command{
3738
Use: "protocol-add",
3839
Short: T("Add a new load balancer protocol"),
39-
Long: T("${COMMAND_NAME} sl loadbal protocol-add (--id LOADBAL_ID) [--front-protocol PROTOCOL] [back-protocol PROTOCOL] [--front-port PORT] [--back-port PORT] [-m, --method METHOD] [-c, --connections CONNECTIONS] [--sticky cookie | source-ip] [--client-timeout SECONDS] [--server-timeout SECONDS]"),
40-
Args: metadata.NoArgs,
40+
Long: T(`Creates a new mapping between incoming traffic to the loadbalancer and the backend servers.
41+
Use '{COMMAND_NAME} sl security cert-list' to get IDs for the --ssl-id option.
42+
See: https://cloud.ibm.com/docs/loadbalancer-service?topic=loadbalancer-service-about-ibm-cloud-load-balancer for more details
43+
44+
Example:
45+
${COMMAND_NAME} sl loadbal protocol-add --id 1115129 --front-port 443 --front-protocol HTTPS --back-port 80 --back-protocol HTTP --ssl-id 335659 --client-timeout 60 --connections 100
46+
Creates a new protocol on Load Balancer 1115129 that terminates SSL on port 443, mapping to a backend port 80 HTTP. Using SSL cert 335659
47+
`),
48+
Args: metadata.NoArgs,
4149
RunE: func(cmd *cobra.Command, args []string) error {
4250
return thisCmd.Run(args)
4351
},
4452
}
4553
cobraCmd.Flags().IntVar(&thisCmd.Id, "id", 0, T("ID for the load balancer [required]"))
4654
cobraCmd.Flags().StringVar(&thisCmd.FrontProtocol, "front-protocol", "HTTP", T("Protocol type to use for incoming connections: [HTTP|HTTPS|TCP]. Default: HTTP"))
47-
cobraCmd.Flags().StringVar(&thisCmd.BackProtocol, "back-protocol", "", T("Protocol type to use when connecting to backend servers: [HTTP|HTTPS|TCP]. Defaults to whatever --front-protocol is"))
55+
cobraCmd.Flags().StringVar(&thisCmd.BackProtocol, "back-protocol", "HTTP", T("Protocol type to use when connecting to backend servers: [HTTP|HTTPS|TCP]. Defaults to whatever --front-protocol is"))
4856
cobraCmd.Flags().IntVar(&thisCmd.FrontPort, "front-port", 80, T("Internet side port"))
4957
cobraCmd.Flags().IntVar(&thisCmd.BackPort, "back-port", 80, T("Private side port"))
5058
cobraCmd.Flags().StringVarP(&thisCmd.Method, "method", "m", "ROUNDROBIN", T("Balancing Method: [ROUNDROBIN|LEASTCONNECTION|WEIGHTED_RR]"))
5159
cobraCmd.Flags().IntVarP(&thisCmd.Connections, "connections", "c", 0, T("Maximum number of connections to allow"))
5260
cobraCmd.Flags().StringVar(&thisCmd.Sticky, "sticky", "", T("Use 'cookie' or 'source-ip' to stick"))
5361
cobraCmd.Flags().IntVar(&thisCmd.ClientTimeout, "client-timeout", 0, T("Client side timeout setting, in seconds"))
5462
cobraCmd.Flags().IntVar(&thisCmd.ServerTimeout, "server-timeout", 0, T("Server side timeout setting, in seconds"))
63+
cobraCmd.Flags().IntVar(&thisCmd.SslId, "ssl-id", 0, T("Identifier of the SSL certificate to attach to this protocol. Only valid for HTTPS."))
5564
thisCmd.Command = cobraCmd
5665
return thisCmd
5766
}
@@ -62,42 +71,18 @@ func (cmd *ProtocolAddCommand) Run(args []string) error {
6271
return errors.NewMissingInputError("--id")
6372
}
6473

65-
frontProtocol := cmd.FrontProtocol
66-
if frontProtocol == "" {
67-
frontProtocol = "HTTP"
68-
}
69-
70-
backProtocol := cmd.BackProtocol
71-
if backProtocol == "" {
72-
backProtocol = frontProtocol
73-
}
74-
75-
frontPort := cmd.FrontPort
76-
if frontPort == 0 {
77-
frontPort = 80
78-
}
79-
80-
backPort := cmd.BackPort
81-
if backPort == 0 {
82-
backPort = 80
83-
}
84-
85-
method := cmd.Method
86-
if method == "" {
87-
method = "ROUNDROBIN"
88-
}
89-
9074
loadbalancerUUID, err := cmd.LoadBalancerManager.GetLoadBalancerUUID(loadbalID)
9175
if err != nil {
9276
return errors.New(T("Failed to get load balancer: {{.ERR}}.", map[string]interface{}{"ERR": err.Error()}))
9377
}
9478

79+
// Sets up all the required parameters
9580
protocolConfigurations := datatypes.Network_LBaaS_LoadBalancerProtocolConfiguration{
96-
BackendPort: &backPort,
97-
BackendProtocol: &backProtocol,
98-
FrontendPort: &frontPort,
99-
FrontendProtocol: &frontProtocol,
100-
LoadBalancingMethod: &method,
81+
BackendPort: &cmd.BackPort,
82+
BackendProtocol: &cmd.BackProtocol,
83+
FrontendPort: &cmd.FrontPort,
84+
FrontendProtocol: &cmd.FrontProtocol,
85+
LoadBalancingMethod: &cmd.Method,
10186
}
10287

10388
var sessionType string
@@ -112,21 +97,23 @@ func (cmd *ProtocolAddCommand) Run(args []string) error {
11297
}
11398

11499
if cmd.Connections != 0 {
115-
connections := cmd.Connections
116-
protocolConfigurations.MaxConn = &connections
100+
protocolConfigurations.MaxConn = &cmd.Connections
117101
}
118102

119103
if cmd.ClientTimeout != 0 {
120-
cTimeout := cmd.ClientTimeout
121-
protocolConfigurations.ClientTimeout = &cTimeout
104+
protocolConfigurations.ClientTimeout = &cmd.ClientTimeout
122105
}
123106

124107
if cmd.ServerTimeout != 0 {
125-
sTimeout := cmd.ServerTimeout
126-
protocolConfigurations.ServerTimeout = &sTimeout
108+
protocolConfigurations.ServerTimeout = &cmd.ServerTimeout
127109
}
128110

129-
_, err = cmd.LoadBalancerManager.AddLoadBalancerListener(&loadbalancerUUID, []datatypes.Network_LBaaS_LoadBalancerProtocolConfiguration{protocolConfigurations})
111+
if cmd.SslId != 0 {
112+
protocolConfigurations.TlsCertificateId = &cmd.SslId
113+
}
114+
_, err = cmd.LoadBalancerManager.AddLoadBalancerListener(
115+
&loadbalancerUUID, []datatypes.Network_LBaaS_LoadBalancerProtocolConfiguration{protocolConfigurations},
116+
)
130117
if err != nil {
131118
return errors.New(T("Failed to add protocol: {{.Error}}.\n", map[string]interface{}{"Error": err.Error()}))
132119
}

plugin/commands/loadbal/protocols_add_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ var _ = Describe("LoadBal_protocol-add_Test", func() {
8787
Expect(*argsForCall[0].LoadBalancingMethod).To(Equal("ROUNDROBIN"))
8888
Expect(fakeUI.Outputs()).To(ContainSubstring("OK"))
8989
})
90+
It("--ssl-id option", func() {
91+
err := testhelpers.RunCobraCommand(cliCommand.Command, "--id", "12345", "--ssl-id=9999", "--front-protocol=HTTPS")
92+
Expect(err).NotTo(HaveOccurred())
93+
lbUUID, argsForCall := fakeLBManager.AddLoadBalancerListenerArgsForCall(0)
94+
Expect(*lbUUID).To(Equal("aaa-bbb-111"))
95+
Expect(len(argsForCall)).To(Equal(1))
96+
Expect(*argsForCall[0].FrontendProtocol).To(Equal("HTTPS"))
97+
Expect(*argsForCall[0].BackendProtocol).To(Equal("HTTP"))
98+
Expect(*argsForCall[0].TlsCertificateId).To(Equal(9999))
99+
Expect(fakeUI.Outputs()).To(ContainSubstring("OK"))
100+
})
90101
It("with sticky as cookie", func() {
91102
err := testhelpers.RunCobraCommand(cliCommand.Command, "--id", "12345", "--sticky", "cookie")
92103
Expect(err).NotTo(HaveOccurred())

0 commit comments

Comments
 (0)