1// Copyright 2016-2020 The Libsacloud Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package sacloud 16 17import "strconv" 18 19// LoadBalancer ロードバランサー 20type LoadBalancer struct { 21 *Appliance // アプライアンス共通属性 22 23 Remark *LoadBalancerRemark `json:",omitempty"` // リマーク 24 Settings *LoadBalancerSettings `json:",omitempty"` // ロードバランサー設定 25} 26 27// IsHA 冗長化されている場合にtrueを返す 28func (l *LoadBalancer) IsHA() bool { 29 isHA := false 30 if len(l.Remark.Servers) > 1 { 31 if v, ok := l.Remark.Servers[1].(map[string]string); ok { 32 if _, ok := v["IPAddress"]; ok { 33 isHA = true 34 } 35 } 36 } 37 return isHA 38} 39 40// IPAddress1 ロードバランサ本体のIPアドレス(1番目)を返す 41func (l *LoadBalancer) IPAddress1() string { 42 if len(l.Remark.Servers) > 0 { 43 if v, ok := l.Remark.Servers[0].(map[string]string); ok { 44 if v, ok := v["IPAddress"]; ok { 45 return v 46 } 47 } 48 } 49 return "" 50} 51 52// IPAddress2 ロードバランサ本体のIPアドレス(2番目)を返す 53func (l *LoadBalancer) IPAddress2() string { 54 if len(l.Remark.Servers) > 1 { 55 if v, ok := l.Remark.Servers[1].(map[string]string); ok { 56 if v, ok := v["IPAddress"]; ok { 57 return v 58 } 59 } 60 } 61 return "" 62} 63 64// LoadBalancerRemark リマーク 65type LoadBalancerRemark struct { 66 *ApplianceRemarkBase 67 // TODO Zone 68 //Zone *Resource 69} 70 71// LoadBalancerSettings ロードバランサー設定リスト 72type LoadBalancerSettings struct { 73 LoadBalancer []*LoadBalancerSetting // ロードバランサー設定リスト 74} 75 76// LoadBalancerSetting ロードバランサー仮想IP設定 77type LoadBalancerSetting struct { 78 VirtualIPAddress string `json:",omitempty"` // 仮想IPアドレス 79 Port string `json:",omitempty"` // ポート番号 80 DelayLoop string `json:",omitempty"` // 監視間隔 81 SorryServer string `json:",omitempty"` // ソーリーサーバー 82 Description string `json:",omitempty"` // 説明 83 Servers []*LoadBalancerServer `json:",omitempty"` // 仮想IP配下の実サーバー 84} 85 86// LoadBalancerServer 仮想IP設定配下のサーバー 87type LoadBalancerServer struct { 88 IPAddress string `json:",omitempty"` // IPアドレス 89 Port string `json:",omitempty"` // ポート番号 90 HealthCheck *LoadBalancerHealthCheck `json:",omitempty"` // ヘルスチェック 91 Enabled string `json:",omitempty"` // 有効/無効 92 Status string `json:",omitempty"` // ステータス 93 ActiveConn string `json:",omitempty"` // アクティブなコネクション 94} 95 96// LoadBalancerHealthCheck ヘルスチェック 97type LoadBalancerHealthCheck struct { 98 Protocol string `json:",omitempty"` // プロトコル 99 Path string `json:",omitempty"` // HTTP/HTTPSの場合のリクエストパス 100 Status string `json:",omitempty"` // HTTP/HTTPSの場合の期待するレスポンスコード 101} 102 103// LoadBalancerPlan ロードバランサープラン 104type LoadBalancerPlan int 105 106var ( 107 // LoadBalancerPlanStandard スタンダードプラン 108 LoadBalancerPlanStandard = LoadBalancerPlan(1) 109 // LoadBalancerPlanPremium プレミアムプラン 110 LoadBalancerPlanPremium = LoadBalancerPlan(2) 111) 112 113// CreateLoadBalancerValue ロードバランサー作成用パラメーター 114type CreateLoadBalancerValue struct { 115 SwitchID ID // 接続先スイッチID 116 VRID int // VRID 117 Plan LoadBalancerPlan // プラン 118 IPAddress1 string // IPアドレス 119 MaskLen int // ネットワークマスク長 120 DefaultRoute string // デフォルトルート 121 Name string // 名称 122 Description string // 説明 123 Tags []string // タグ 124 Icon *Resource // アイコン 125} 126 127// CreateDoubleLoadBalancerValue ロードバランサー(冗長化あり)作成用パラメーター 128type CreateDoubleLoadBalancerValue struct { 129 *CreateLoadBalancerValue 130 IPAddress2 string // IPアドレス2 131} 132 133// AllowLoadBalancerHealthCheckProtocol ロードバランサーでのヘルスチェック対応プロトコルリスト 134func AllowLoadBalancerHealthCheckProtocol() []string { 135 return []string{"http", "https", "ping", "tcp"} 136} 137 138// CreateNewLoadBalancerSingle ロードバランサー作成(冗長化なし) 139func CreateNewLoadBalancerSingle(values *CreateLoadBalancerValue, settings []*LoadBalancerSetting) (*LoadBalancer, error) { 140 141 lb := &LoadBalancer{ 142 Appliance: &Appliance{ 143 Class: "loadbalancer", 144 propName: propName{Name: values.Name}, 145 propDescription: propDescription{Description: values.Description}, 146 propTags: propTags{Tags: values.Tags}, 147 propPlanID: propPlanID{Plan: &Resource{ID: ID(values.Plan)}}, 148 propIcon: propIcon{ 149 &Icon{ 150 Resource: values.Icon, 151 }, 152 }, 153 }, 154 Remark: &LoadBalancerRemark{ 155 ApplianceRemarkBase: &ApplianceRemarkBase{ 156 Switch: &ApplianceRemarkSwitch{ 157 ID: values.SwitchID, 158 }, 159 VRRP: &ApplianceRemarkVRRP{ 160 VRID: values.VRID, 161 }, 162 Network: &ApplianceRemarkNetwork{ 163 NetworkMaskLen: values.MaskLen, 164 DefaultRoute: values.DefaultRoute, 165 }, 166 Servers: []interface{}{ 167 map[string]string{"IPAddress": values.IPAddress1}, 168 }, 169 }, 170 }, 171 } 172 173 for _, s := range settings { 174 lb.AddLoadBalancerSetting(s) 175 } 176 177 return lb, nil 178} 179 180// CreateNewLoadBalancerDouble ロードバランサー(冗長化あり)作成 181func CreateNewLoadBalancerDouble(values *CreateDoubleLoadBalancerValue, settings []*LoadBalancerSetting) (*LoadBalancer, error) { 182 lb, err := CreateNewLoadBalancerSingle(values.CreateLoadBalancerValue, settings) 183 if err != nil { 184 return nil, err 185 } 186 lb.Remark.Servers = append(lb.Remark.Servers, map[string]string{"IPAddress": values.IPAddress2}) 187 return lb, nil 188} 189 190// AddLoadBalancerSetting ロードバランサー仮想IP設定追加 191// 192// ロードバランサー設定は仮想IPアドレス単位で保持しています。 193// 仮想IPを増やす場合にこのメソッドを利用します。 194func (l *LoadBalancer) AddLoadBalancerSetting(setting *LoadBalancerSetting) { 195 if l.Settings == nil { 196 l.Settings = &LoadBalancerSettings{} 197 } 198 if l.Settings.LoadBalancer == nil { 199 l.Settings.LoadBalancer = []*LoadBalancerSetting{} 200 } 201 l.Settings.LoadBalancer = append(l.Settings.LoadBalancer, setting) 202} 203 204// DeleteLoadBalancerSetting ロードバランサー仮想IP設定の削除 205func (l *LoadBalancer) DeleteLoadBalancerSetting(vip string, port string) { 206 res := []*LoadBalancerSetting{} 207 for _, l := range l.Settings.LoadBalancer { 208 if l.VirtualIPAddress != vip || l.Port != port { 209 res = append(res, l) 210 } 211 } 212 213 l.Settings.LoadBalancer = res 214} 215 216// AddServer 仮想IP設定配下へ実サーバーを追加 217func (s *LoadBalancerSetting) AddServer(server *LoadBalancerServer) { 218 if s.Servers == nil { 219 s.Servers = []*LoadBalancerServer{} 220 } 221 s.Servers = append(s.Servers, server) 222} 223 224// DeleteServer 仮想IP設定配下の実サーバーを削除 225func (s *LoadBalancerSetting) DeleteServer(ip string, port string) { 226 res := []*LoadBalancerServer{} 227 for _, server := range s.Servers { 228 if server.IPAddress != ip || server.Port != port { 229 res = append(res, server) 230 } 231 } 232 233 s.Servers = res 234 235} 236 237// LoadBalancerStatusResult ロードバランサーのステータスAPI戻り値 238type LoadBalancerStatusResult []*LoadBalancerStatus 239 240// Get VIPに対応するステータスを取得 241func (l *LoadBalancerStatusResult) Get(vip string) *LoadBalancerStatus { 242 for _, v := range *l { 243 if v.VirtualIPAddress == vip { 244 return v 245 } 246 } 247 return nil 248} 249 250// LoadBalancerStatus ロードバランサーのステータス 251type LoadBalancerStatus struct { 252 VirtualIPAddress string 253 Port string 254 Servers []*LoadBalancerServerStatus `json:",omitempty"` 255 CPS string 256} 257 258// Get IPアドレスに対応する実サーバのステータスを取得 259func (l *LoadBalancerStatus) Get(ip string) *LoadBalancerServerStatus { 260 for _, v := range l.Servers { 261 if v.IPAddress == ip { 262 return v 263 } 264 } 265 return nil 266} 267 268// NumCPS CPSを数値にして返す 269func (l *LoadBalancerStatus) NumCPS() int { 270 v, _ := strconv.Atoi(l.CPS) // nolint - ignore error 271 return v 272} 273 274// NumPort Portを数値にして返す 275func (l *LoadBalancerStatus) NumPort() int { 276 v, _ := strconv.Atoi(l.Port) // nolint - ignore error 277 return v 278} 279 280// LoadBalancerServerStatus ロードバランサーのVIP配下の実サーバのステータス 281type LoadBalancerServerStatus struct { 282 ActiveConn string 283 IPAddress string 284 Status string 285 Port string 286 CPS string 287} 288 289// NumActiveConn ActiveConnを数値にして返す 290func (l *LoadBalancerServerStatus) NumActiveConn() int { 291 v, _ := strconv.Atoi(l.ActiveConn) // nolint - ignore error 292 return v 293} 294 295// NumCPS CPSを数値にして返す 296func (l *LoadBalancerServerStatus) NumCPS() int { 297 v, _ := strconv.Atoi(l.CPS) // nolint - ignore error 298 return v 299} 300 301// NumPort Portを数値にして返す 302func (l *LoadBalancerServerStatus) NumPort() int { 303 v, _ := strconv.Atoi(l.Port) // nolint - ignore error 304 return v 305} 306