1package linodego 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7) 8 9// NodeBalancerConfig objects allow a NodeBalancer to accept traffic on a new port 10type NodeBalancerConfig struct { 11 ID int `json:"id"` 12 Port int `json:"port"` 13 Protocol ConfigProtocol `json:"protocol"` 14 ProxyProtocol ConfigProxyProtocol `json:"proxy_protocol"` 15 Algorithm ConfigAlgorithm `json:"algorithm"` 16 Stickiness ConfigStickiness `json:"stickiness"` 17 Check ConfigCheck `json:"check"` 18 CheckInterval int `json:"check_interval"` 19 CheckAttempts int `json:"check_attempts"` 20 CheckPath string `json:"check_path"` 21 CheckBody string `json:"check_body"` 22 CheckPassive bool `json:"check_passive"` 23 CheckTimeout int `json:"check_timeout"` 24 CipherSuite ConfigCipher `json:"cipher_suite"` 25 NodeBalancerID int `json:"nodebalancer_id"` 26 SSLCommonName string `json:"ssl_commonname"` 27 SSLFingerprint string `json:"ssl_fingerprint"` 28 SSLCert string `json:"ssl_cert"` 29 SSLKey string `json:"ssl_key"` 30 NodesStatus *NodeBalancerNodeStatus `json:"nodes_status"` 31} 32 33// ConfigAlgorithm constants start with Algorithm and include Linode API NodeBalancer Config Algorithms 34type ConfigAlgorithm string 35 36// ConfigAlgorithm constants reflect the NodeBalancer Config Algorithm 37const ( 38 AlgorithmRoundRobin ConfigAlgorithm = "roundrobin" 39 AlgorithmLeastConn ConfigAlgorithm = "leastconn" 40 AlgorithmSource ConfigAlgorithm = "source" 41) 42 43// ConfigStickiness constants start with Stickiness and include Linode API NodeBalancer Config Stickiness 44type ConfigStickiness string 45 46// ConfigStickiness constants reflect the node stickiness method for a NodeBalancer Config 47const ( 48 StickinessNone ConfigStickiness = "none" 49 StickinessTable ConfigStickiness = "table" 50 StickinessHTTPCookie ConfigStickiness = "http_cookie" 51) 52 53// ConfigCheck constants start with Check and include Linode API NodeBalancer Config Check methods 54type ConfigCheck string 55 56// ConfigCheck constants reflect the node health status checking method for a NodeBalancer Config 57const ( 58 CheckNone ConfigCheck = "none" 59 CheckConnection ConfigCheck = "connection" 60 CheckHTTP ConfigCheck = "http" 61 CheckHTTPBody ConfigCheck = "http_body" 62) 63 64// ConfigProtocol constants start with Protocol and include Linode API Nodebalancer Config protocols 65type ConfigProtocol string 66 67// ConfigProtocol constants reflect the protocol used by a NodeBalancer Config 68const ( 69 ProtocolHTTP ConfigProtocol = "http" 70 ProtocolHTTPS ConfigProtocol = "https" 71 ProtocolTCP ConfigProtocol = "tcp" 72) 73 74// ConfigProxyProtocol constants start with ProxyProtocol and include Linode API NodeBalancer Config proxy protocol versions 75type ConfigProxyProtocol string 76 77// ConfigProxyProtocol constatns reflect the proxy protocol version used by a NodeBalancer Config 78const ( 79 ProxyProtocolNone ConfigProxyProtocol = "none" 80 ProxyProtocolV1 ConfigProxyProtocol = "v1" 81 ProxyProtocolV2 ConfigProxyProtocol = "v2" 82) 83 84// ConfigCipher constants start with Cipher and include Linode API NodeBalancer Config Cipher values 85type ConfigCipher string 86 87// ConfigCipher constants reflect the preferred cipher set for a NodeBalancer Config 88const ( 89 CipherRecommended ConfigCipher = "recommended" 90 CipherLegacy ConfigCipher = "legacy" 91) 92 93// NodeBalancerNodeStatus represents the total number of nodes whose status is Up or Down 94type NodeBalancerNodeStatus struct { 95 Up int `json:"up"` 96 Down int `json:"down"` 97} 98 99// NodeBalancerConfigCreateOptions are permitted by CreateNodeBalancerConfig 100type NodeBalancerConfigCreateOptions struct { 101 Port int `json:"port"` 102 Protocol ConfigProtocol `json:"protocol,omitempty"` 103 ProxyProtocol ConfigProxyProtocol `json:"proxy_protocol,omitempty"` 104 Algorithm ConfigAlgorithm `json:"algorithm,omitempty"` 105 Stickiness ConfigStickiness `json:"stickiness,omitempty"` 106 Check ConfigCheck `json:"check,omitempty"` 107 CheckInterval int `json:"check_interval,omitempty"` 108 CheckAttempts int `json:"check_attempts,omitempty"` 109 CheckPath string `json:"check_path,omitempty"` 110 CheckBody string `json:"check_body,omitempty"` 111 CheckPassive *bool `json:"check_passive,omitempty"` 112 CheckTimeout int `json:"check_timeout,omitempty"` 113 CipherSuite ConfigCipher `json:"cipher_suite,omitempty"` 114 SSLCert string `json:"ssl_cert,omitempty"` 115 SSLKey string `json:"ssl_key,omitempty"` 116 Nodes []NodeBalancerNodeCreateOptions `json:"nodes,omitempty"` 117} 118 119// NodeBalancerConfigRebuildOptions used by RebuildNodeBalancerConfig 120type NodeBalancerConfigRebuildOptions struct { 121 Port int `json:"port"` 122 Protocol ConfigProtocol `json:"protocol,omitempty"` 123 ProxyProtocol ConfigProxyProtocol `json:"proxy_protocol,omitempty"` 124 Algorithm ConfigAlgorithm `json:"algorithm,omitempty"` 125 Stickiness ConfigStickiness `json:"stickiness,omitempty"` 126 Check ConfigCheck `json:"check,omitempty"` 127 CheckInterval int `json:"check_interval,omitempty"` 128 CheckAttempts int `json:"check_attempts,omitempty"` 129 CheckPath string `json:"check_path,omitempty"` 130 CheckBody string `json:"check_body,omitempty"` 131 CheckPassive *bool `json:"check_passive,omitempty"` 132 CheckTimeout int `json:"check_timeout,omitempty"` 133 CipherSuite ConfigCipher `json:"cipher_suite,omitempty"` 134 SSLCert string `json:"ssl_cert,omitempty"` 135 SSLKey string `json:"ssl_key,omitempty"` 136 Nodes []NodeBalancerNodeCreateOptions `json:"nodes"` 137} 138 139// NodeBalancerConfigUpdateOptions are permitted by UpdateNodeBalancerConfig 140type NodeBalancerConfigUpdateOptions NodeBalancerConfigCreateOptions 141 142// GetCreateOptions converts a NodeBalancerConfig to NodeBalancerConfigCreateOptions for use in CreateNodeBalancerConfig 143func (i NodeBalancerConfig) GetCreateOptions() NodeBalancerConfigCreateOptions { 144 return NodeBalancerConfigCreateOptions{ 145 Port: i.Port, 146 Protocol: i.Protocol, 147 ProxyProtocol: i.ProxyProtocol, 148 Algorithm: i.Algorithm, 149 Stickiness: i.Stickiness, 150 Check: i.Check, 151 CheckInterval: i.CheckInterval, 152 CheckAttempts: i.CheckAttempts, 153 CheckTimeout: i.CheckTimeout, 154 CheckPath: i.CheckPath, 155 CheckBody: i.CheckBody, 156 CheckPassive: copyBool(&i.CheckPassive), 157 CipherSuite: i.CipherSuite, 158 SSLCert: i.SSLCert, 159 SSLKey: i.SSLKey, 160 } 161} 162 163// GetUpdateOptions converts a NodeBalancerConfig to NodeBalancerConfigUpdateOptions for use in UpdateNodeBalancerConfig 164func (i NodeBalancerConfig) GetUpdateOptions() NodeBalancerConfigUpdateOptions { 165 return NodeBalancerConfigUpdateOptions{ 166 Port: i.Port, 167 Protocol: i.Protocol, 168 ProxyProtocol: i.ProxyProtocol, 169 Algorithm: i.Algorithm, 170 Stickiness: i.Stickiness, 171 Check: i.Check, 172 CheckInterval: i.CheckInterval, 173 CheckAttempts: i.CheckAttempts, 174 CheckPath: i.CheckPath, 175 CheckBody: i.CheckBody, 176 CheckPassive: copyBool(&i.CheckPassive), 177 CheckTimeout: i.CheckTimeout, 178 CipherSuite: i.CipherSuite, 179 SSLCert: i.SSLCert, 180 SSLKey: i.SSLKey, 181 } 182} 183 184// GetRebuildOptions converts a NodeBalancerConfig to NodeBalancerConfigRebuildOptions for use in RebuildNodeBalancerConfig 185func (i NodeBalancerConfig) GetRebuildOptions() NodeBalancerConfigRebuildOptions { 186 return NodeBalancerConfigRebuildOptions{ 187 Port: i.Port, 188 Protocol: i.Protocol, 189 ProxyProtocol: i.ProxyProtocol, 190 Algorithm: i.Algorithm, 191 Stickiness: i.Stickiness, 192 Check: i.Check, 193 CheckInterval: i.CheckInterval, 194 CheckAttempts: i.CheckAttempts, 195 CheckTimeout: i.CheckTimeout, 196 CheckPath: i.CheckPath, 197 CheckBody: i.CheckBody, 198 CheckPassive: copyBool(&i.CheckPassive), 199 CipherSuite: i.CipherSuite, 200 SSLCert: i.SSLCert, 201 SSLKey: i.SSLKey, 202 Nodes: make([]NodeBalancerNodeCreateOptions, 0), 203 } 204} 205 206// NodeBalancerConfigsPagedResponse represents a paginated NodeBalancerConfig API response 207type NodeBalancerConfigsPagedResponse struct { 208 *PageOptions 209 Data []NodeBalancerConfig `json:"data"` 210} 211 212// endpointWithID gets the endpoint URL for NodeBalancerConfig 213func (NodeBalancerConfigsPagedResponse) endpointWithID(c *Client, id int) string { 214 endpoint, err := c.NodeBalancerConfigs.endpointWithParams(id) 215 if err != nil { 216 panic(err) 217 } 218 return endpoint 219} 220 221// appendData appends NodeBalancerConfigs when processing paginated NodeBalancerConfig responses 222func (resp *NodeBalancerConfigsPagedResponse) appendData(r *NodeBalancerConfigsPagedResponse) { 223 resp.Data = append(resp.Data, r.Data...) 224} 225 226// ListNodeBalancerConfigs lists NodeBalancerConfigs 227func (c *Client) ListNodeBalancerConfigs(ctx context.Context, nodebalancerID int, opts *ListOptions) ([]NodeBalancerConfig, error) { 228 response := NodeBalancerConfigsPagedResponse{} 229 err := c.listHelperWithID(ctx, &response, nodebalancerID, opts) 230 if err != nil { 231 return nil, err 232 } 233 return response.Data, nil 234} 235 236// GetNodeBalancerConfig gets the template with the provided ID 237func (c *Client) GetNodeBalancerConfig(ctx context.Context, nodebalancerID int, configID int) (*NodeBalancerConfig, error) { 238 e, err := c.NodeBalancerConfigs.endpointWithParams(nodebalancerID) 239 if err != nil { 240 return nil, err 241 } 242 e = fmt.Sprintf("%s/%d", e, configID) 243 r, err := coupleAPIErrors(c.R(ctx).SetResult(&NodeBalancerConfig{}).Get(e)) 244 if err != nil { 245 return nil, err 246 } 247 return r.Result().(*NodeBalancerConfig), nil 248} 249 250// CreateNodeBalancerConfig creates a NodeBalancerConfig 251func (c *Client) CreateNodeBalancerConfig(ctx context.Context, nodebalancerID int, nodebalancerConfig NodeBalancerConfigCreateOptions) (*NodeBalancerConfig, error) { 252 var body string 253 e, err := c.NodeBalancerConfigs.endpointWithParams(nodebalancerID) 254 if err != nil { 255 return nil, err 256 } 257 258 req := c.R(ctx).SetResult(&NodeBalancerConfig{}) 259 260 if bodyData, err := json.Marshal(nodebalancerConfig); err == nil { 261 body = string(bodyData) 262 } else { 263 return nil, NewError(err) 264 } 265 266 r, err := coupleAPIErrors(req. 267 SetHeader("Content-Type", "application/json"). 268 SetBody(body). 269 Post(e)) 270 if err != nil { 271 return nil, err 272 } 273 return r.Result().(*NodeBalancerConfig), nil 274} 275 276// UpdateNodeBalancerConfig updates the NodeBalancerConfig with the specified id 277func (c *Client) UpdateNodeBalancerConfig(ctx context.Context, nodebalancerID int, configID int, updateOpts NodeBalancerConfigUpdateOptions) (*NodeBalancerConfig, error) { 278 var body string 279 e, err := c.NodeBalancerConfigs.endpointWithParams(nodebalancerID) 280 if err != nil { 281 return nil, err 282 } 283 e = fmt.Sprintf("%s/%d", e, configID) 284 285 req := c.R(ctx).SetResult(&NodeBalancerConfig{}) 286 287 if bodyData, err := json.Marshal(updateOpts); err == nil { 288 body = string(bodyData) 289 } else { 290 return nil, NewError(err) 291 } 292 293 r, err := coupleAPIErrors(req. 294 SetBody(body). 295 Put(e)) 296 if err != nil { 297 return nil, err 298 } 299 return r.Result().(*NodeBalancerConfig), nil 300} 301 302// DeleteNodeBalancerConfig deletes the NodeBalancerConfig with the specified id 303func (c *Client) DeleteNodeBalancerConfig(ctx context.Context, nodebalancerID int, configID int) error { 304 e, err := c.NodeBalancerConfigs.endpointWithParams(nodebalancerID) 305 if err != nil { 306 return err 307 } 308 e = fmt.Sprintf("%s/%d", e, configID) 309 310 _, err = coupleAPIErrors(c.R(ctx).Delete(e)) 311 return err 312} 313 314// RebuildNodeBalancerConfig updates the NodeBalancer with the specified id 315func (c *Client) RebuildNodeBalancerConfig(ctx context.Context, nodeBalancerID int, configID int, rebuildOpts NodeBalancerConfigRebuildOptions) (*NodeBalancerConfig, error) { 316 var body string 317 e, err := c.NodeBalancerConfigs.endpointWithParams(nodeBalancerID) 318 if err != nil { 319 return nil, err 320 } 321 e = fmt.Sprintf("%s/%d/rebuild", e, configID) 322 323 req := c.R(ctx).SetResult(&NodeBalancerConfig{}) 324 325 if bodyData, err := json.Marshal(rebuildOpts); err == nil { 326 body = string(bodyData) 327 } else { 328 return nil, NewError(err) 329 } 330 331 r, err := coupleAPIErrors(req. 332 SetBody(body). 333 Post(e)) 334 if err != nil { 335 return nil, err 336 } 337 return r.Result().(*NodeBalancerConfig), nil 338} 339