github.com/sacloud/iaas-api-go@v1.12.0/naked/proxylb.go (about) 1 // Copyright 2022-2023 The sacloud/iaas-api-go 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 15 package naked 16 17 import ( 18 "encoding/json" 19 "strings" 20 "time" 21 22 "github.com/sacloud/iaas-api-go/types" 23 ) 24 25 // ProxyLB エンハンスドロードバランサ 26 type ProxyLB struct { 27 ID types.ID `json:",omitempty" yaml:"id,omitempty" structs:",omitempty"` 28 Name string `json:",omitempty" yaml:"name,omitempty" structs:",omitempty"` 29 Description string `yaml:"description"` 30 Tags types.Tags `yaml:"tags"` 31 Icon *Icon `json:",omitempty" yaml:"icon,omitempty" structs:",omitempty"` 32 CreatedAt *time.Time `json:",omitempty" yaml:"created_at,omitempty" structs:",omitempty"` 33 ModifiedAt *time.Time `json:",omitempty" yaml:"modified_at,omitempty" structs:",omitempty"` 34 Availability types.EAvailability `json:",omitempty" yaml:"availability,omitempty" structs:",omitempty"` 35 Provider *Provider `json:",omitempty" yaml:"provider,omitempty" structs:",omitempty"` 36 Settings *ProxyLBSettings `json:",omitempty" yaml:"settings,omitempty" structs:",omitempty"` 37 SettingsHash string `json:",omitempty" yaml:"settings_hash,omitempty" structs:",omitempty"` 38 Status *ProxyLBStatus `json:",omitempty" yaml:"status,omitempty" structs:",omitempty"` 39 40 // ServiceClass [HACK] ServiceClassはプランとリージョンから決定するためjson.Marshalerで出力する。 41 // see https://github.com/sacloud/libsacloud/issues/577 42 ServiceClass string `json:",omitempty" yaml:"service_class,omitempty" structs:",omitempty"` 43 Plan types.EProxyLBPlan `json:"-"` 44 } 45 46 // MarshalJSON implements json.Marshaler 47 func (p *ProxyLB) MarshalJSON() ([]byte, error) { 48 if p.Status != nil && p.Plan != types.EProxyLBPlan(0) { 49 p.ServiceClass = types.ProxyLBServiceClass(p.Plan, p.Status.Region) 50 } 51 52 type alias ProxyLB 53 tmp := alias(*p) 54 return json.Marshal(&tmp) 55 } 56 57 // UnmarshalJSON implements json.Unmarshaler 58 func (p *ProxyLB) UnmarshalJSON(b []byte) error { 59 type alias ProxyLB 60 var tmp alias 61 if err := json.Unmarshal(b, &tmp); err != nil { 62 return err 63 } 64 65 tmp.Plan = types.ProxyLBPlanFromServiceClass(tmp.ServiceClass) 66 *p = ProxyLB(tmp) 67 return nil 68 } 69 70 // ProxyLBPlanChange エンハンスドロードバランサのプラン変更 71 type ProxyLBPlanChange struct { 72 ServiceClass string `yaml:"service_class"` 73 } 74 75 // ProxyLBSettingsUpdate エンハンスドロードバランサ 76 type ProxyLBSettingsUpdate struct { 77 Settings *ProxyLBSettings `json:",omitempty" yaml:"settings,omitempty" structs:",omitempty"` 78 SettingsHash string `json:",omitempty" yaml:"settings_hash,omitempty" structs:",omitempty"` 79 } 80 81 // ProxyLBSettings エンハンスドロードバランサ設定 82 type ProxyLBSettings struct { 83 ProxyLB *ProxyLBSetting `json:",omitempty" yaml:"proxy_lb,omitempty" structs:",omitempty"` 84 } 85 86 // ProxyLBSetting エンハンスドロードバランサ設定 87 type ProxyLBSetting struct { 88 HealthCheck ProxyLBHealthCheck `yaml:"health_check"` // ヘルスチェック 89 SorryServer ProxyLBSorryServer `yaml:"sorry_server"` // ソーリーサーバー 90 BindPorts []*ProxyLBBindPorts `yaml:"bind_ports"` // プロキシ方式(プロトコル&ポート) 91 Servers []ProxyLBServer `yaml:"servers"` // サーバー 92 Rules []ProxyLBRule `yaml:"rules"` // 振り分けルール 93 LetsEncrypt *ProxyLBACMESetting `json:",omitempty" yaml:"lets_encrypt,omitempty" structs:",omitempty"` // Let's encryptでの証明書取得設定 94 StickySession ProxyLBStickySession `yaml:"sticky_session"` // StickySession 95 Timeout ProxyLBTimeout `json:",omitempty" yaml:"timeout,omitempty" structs:",omitempty"` // タイムアウト 96 Gzip ProxyLBGzip `yaml:"gzip"` // Gzip 97 BackendHttpKeepAlive *ProxyLBBackendHTTPKeepAlive `json:",omitempty" yaml:",backend_http_keey_alive,omitempty" structs:",omitempty"` // 実サーバとのHTTP持続接続 98 ProxyProtocol ProxyLBProxyProtocol `yaml:"proxy_protocol"` 99 Syslog ProxyLBSyslog `yaml:"syslog"` 100 } 101 102 // MarshalJSON nullの場合に空配列を出力するための実装 103 func (s ProxyLBSetting) MarshalJSON() ([]byte, error) { 104 if s.BindPorts == nil { 105 s.BindPorts = make([]*ProxyLBBindPorts, 0) 106 } 107 if s.Servers == nil { 108 s.Servers = make([]ProxyLBServer, 0) 109 } 110 if s.Rules == nil { 111 s.Rules = make([]ProxyLBRule, 0) 112 } 113 // syslogは値がないと400エラーになるため両方空の場合はポートのデフォルト値だけ設定しておく 114 if s.Syslog.Server == "" && s.Syslog.Port == 0 { 115 s.Syslog.Port = 514 116 } 117 118 type alias ProxyLBSetting 119 tmp := alias(s) 120 return json.Marshal(&tmp) 121 } 122 123 // ProxyLBHealthCheck ヘルスチェック 124 type ProxyLBHealthCheck struct { 125 Protocol types.EProxyLBHealthCheckProtocol `json:",omitempty" yaml:"protocol,omitempty" structs:",omitempty"` 126 Path string `json:",omitempty" yaml:"path,omitempty" structs:",omitempty"` 127 Host string `json:",omitempty" yaml:"host,omitempty" structs:",omitempty"` 128 DelayLoop int `json:",omitempty" yaml:"delay_loop,omitempty" structs:",omitempty"` 129 } 130 131 // ProxyLBSorryServer ソーリーサーバ設定 132 type ProxyLBSorryServer struct { 133 IPAddress string `yaml:"ip_address"` 134 Port *int `yaml:"port"` 135 } 136 137 // ProxyLBBindPorts プロキシ方式 138 type ProxyLBBindPorts struct { 139 ProxyMode types.EProxyLBProxyMode `json:",omitempty" yaml:"proxy_mode,omitempty" structs:",omitempty"` // モード(プロトコル) 140 Port int `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"` // ポート 141 RedirectToHTTPS bool `json:"RedirectToHttps" yaml:"redirect_to_https"` // HTTPSへのリダイレクト(モードがhttpの場合のみ) 142 SupportHTTP2 bool `json:"SupportHttp2" yaml:"support_http2"` // HTTP/2のサポート(モードがhttpsの場合のみ) 143 AddResponseHeader []*ProxyLBResponseHeader `json:",omitempty" yaml:"add_response_header,omitempty" structs:",omitempty"` // レスポンスヘッダ 144 SSLPolicy string `json:",omitempty" yaml:"ssl_policy,omitempty" structs:",omitempty"` // SSLポリシー 145 } 146 147 // ProxyLBResponseHeader ポートごとの追加レスポンスヘッダ 148 type ProxyLBResponseHeader struct { 149 Header string // ヘッダ名称(英字, 数字, ハイフン) 150 Value string // 値(英字, 数字, 半角スペース, 一部記号(!#$%&'()*+,-./:;<=>?@[]^_`{|}~)) 151 } 152 153 // ProxyLBServer ProxyLB配下のサーバー 154 type ProxyLBServer struct { 155 IPAddress string `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"` // IPアドレス 156 Port int `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"` // ポート 157 ServerGroup string `yaml:"server_group"` // サーバグループ 158 Enabled bool // 有効/無効 159 } 160 161 // ProxyLBRule ProxyLBの振り分けルール 162 type ProxyLBRule struct { 163 // 条件部 164 Host string `json:",omitempty" yaml:"host,omitempty" structs:",omitempty"` // ホストヘッダのパターン(ワイルドカードとして?と*が利用可能) 165 Path string `json:",omitempty" yaml:"path,omitempty" structs:",omitempty"` // パス 166 167 SourceIPs string `json:",omitempty" yaml:"source_ips,omitempty" structs:",omitempty"` 168 169 RequestHeaderName string `json:",omitempty" yaml:"request_header_name,omitempty" structs:",omitempty"` 170 RequestHeaderValue string `json:",omitempty" yaml:"request_header_value,omitempty" structs:",omitempty"` 171 RequestHeaderValueIgnoreCase bool `yaml:"request_header_value_ignore_case"` 172 RequestHeaderValueNotMatch bool `yaml:"request_header_value_not_match"` 173 174 // アクション部 175 Action types.EProxyLBRuleAction `json:",omitempty" yaml:"action,omitempty" structs:",omitempty"` // forward(実サーバへ転送) | redirect | fixed(固定レスポンス) 176 ServerGroup string `json:",omitempty" yaml:"server_group,omitempty" structs:",omitempty"` 177 178 RedirectLocation string `json:",omitempty" yaml:"redirect_location,omitempty" structs:",omitempty"` 179 RedirectStatusCode string `json:",omitempty" yaml:"redirect_status_code,omitempty" structs:",omitempty"` // 301 | 302 180 181 FixedStatusCode string `json:",omitempty" yaml:"fixed_status_code,omitempty" structs:",omitempty"` 182 FixedContentType types.EProxyLBFixedContentType `json:",omitempty" yaml:"fixed_content_type,omitempty" structs:",omitempty"` 183 FixedMessageBody string `json:",omitempty" yaml:"fixed_message_body,omitempty" structs:",omitempty"` 184 } 185 186 // ProxyLBACMESetting Let's Encryptでの証明書取得設定 187 type ProxyLBACMESetting struct { 188 Enabled bool `yaml:"enabled"` 189 CommonName string `json:",omitempty" yaml:",omitempty" structs:",omitempty"` 190 SubjectAltNames []string `json:",omitempty" yaml:",omitempty" structs:",omitempty"` 191 } 192 193 // MarshalJSON SubjectAltNamesをスライスから文字列にする 194 func (p ProxyLBACMESetting) MarshalJSON() ([]byte, error) { 195 type tmpSetting struct { 196 Enabled bool `yaml:"enabled"` 197 CommonName string `json:",omitempty" yaml:",omitempty" structs:",omitempty"` 198 SubjectAltNames string `json:",omitempty" yaml:",omitempty" structs:",omitempty"` 199 } 200 tmp := tmpSetting{ 201 Enabled: p.Enabled, 202 CommonName: p.CommonName, 203 SubjectAltNames: strings.Join(p.SubjectAltNames, ","), // Note: カンマ区切りで統一 204 } 205 return json.Marshal(&tmp) 206 } 207 208 // UnmarshalJSON SubjectAltNamesを文字列からスライスにする 209 func (p *ProxyLBACMESetting) UnmarshalJSON(data []byte) error { 210 type tmpSetting struct { 211 Enabled bool `yaml:"enabled"` 212 CommonName string `json:",omitempty" yaml:",omitempty" structs:",omitempty"` 213 SubjectAltNames string `json:",omitempty" yaml:",omitempty" structs:",omitempty"` 214 } 215 var setting *tmpSetting 216 if err := json.Unmarshal(data, &setting); err != nil { 217 return err 218 } 219 220 *p = ProxyLBACMESetting{ 221 Enabled: setting.Enabled, 222 CommonName: setting.CommonName, 223 SubjectAltNames: strings.FieldsFunc(setting.SubjectAltNames, func(r rune) bool { 224 return r == ' ' || r == ',' || r == '\n' 225 }), 226 } 227 return nil 228 } 229 230 // ProxyLBStickySession セッション維持(Sticky session)設定 231 type ProxyLBStickySession struct { 232 Enabled bool `yaml:"enabled"` 233 Method string `json:",omitempty" yaml:"method,omitempty" structs:",omitempty"` 234 } 235 236 // ProxyLBGzip Gzip圧縮設定 237 type ProxyLBGzip struct { 238 Enabled bool `yaml:"enabled"` 239 } 240 241 type ProxyLBBackendHTTPKeepAlive struct { 242 Mode types.EProxyLBBackendHttpKeepAlive `json:",omitempty" yaml:"mode,omitempty" structs:",omitempty"` 243 } 244 245 // ProxyLBProxyProtocol ProxyProtocol(v2)の有効設定 246 type ProxyLBProxyProtocol struct { 247 Enabled bool `yaml:"enabled"` 248 } 249 250 // ProxyLBSyslog Syslog設定 251 type ProxyLBSyslog struct { 252 Server string `yaml:"server"` 253 Port int `yaml:"port"` 254 } 255 256 // ProxyLBTimeout 実サーバの通信タイムアウト 257 type ProxyLBTimeout struct { 258 InactiveSec int `json:",omitempty" yaml:"inactive_sec" structs:",omitempty"` // 10から600まで1秒刻みで設定可 259 } 260 261 // ProxyLBStatus ステータス 262 type ProxyLBStatus struct { 263 UseVIPFailover bool `yaml:"use_vip_failover"` 264 Region types.EProxyLBRegion `json:",omitempty" yaml:"region,omitempty" structs:",omitempty"` 265 ProxyNetworks []string `json:",omitempty" yaml:"proxy_networks,omitempty" structs:",omitempty"` 266 FQDN string `json:",omitempty" yaml:"fqdn,omitempty" structs:",omitempty"` 267 VirtualIPAddress string `json:",omitempty" yaml:"virtual_ip_address,omitempty" structs:",omitempty"` 268 } 269 270 // ProxyLBAdditionalCerts additional certificates 271 type ProxyLBAdditionalCerts []*ProxyLBCertificate 272 273 // ProxyLBCertificates ProxyLBのSSL証明書 274 type ProxyLBCertificates struct { 275 PrimaryCert *ProxyLBCertificate `yaml:"primary_cert"` 276 AdditionalCerts ProxyLBAdditionalCerts `yaml:"additional_certs"` 277 } 278 279 // MarshalJSON nullの場合に空配列を出力するための実装 280 func (s ProxyLBCertificates) MarshalJSON() ([]byte, error) { 281 if s.AdditionalCerts == nil { 282 s.AdditionalCerts = make([]*ProxyLBCertificate, 0) 283 } 284 type alias ProxyLBCertificates 285 tmp := alias(s) 286 return json.Marshal(&tmp) 287 } 288 289 // UnmarshalJSON UnmarshalJSON(AdditionalCertsが空の場合に空文字を返す問題への対応) 290 func (p *ProxyLBAdditionalCerts) UnmarshalJSON(data []byte) error { 291 targetData := strings.ReplaceAll(strings.ReplaceAll(string(data), " ", ""), "\n", "") 292 if targetData == `` { 293 return nil 294 } 295 296 var certs []*ProxyLBCertificate 297 if err := json.Unmarshal(data, &certs); err != nil { 298 return err 299 } 300 301 *p = certs 302 return nil 303 } 304 305 // ProxyLBCertificate ProxyLBのSSL証明書詳細 306 type ProxyLBCertificate struct { 307 ServerCertificate string `yaml:"server_certificate"` // サーバ証明書 308 IntermediateCertificate string `yaml:"intermediate_certificate"` // 中間証明書 309 PrivateKey string `yaml:"private_key"` // 秘密鍵 310 CertificateEndDate *time.Time `json:",omitempty" yaml:"certificate_end_date,omitempty" structs:",omitempty"` // 有効期限 311 CertificateCommonName string `json:",omitempty" yaml:"certificate_common_name,omitempty" structs:",omitempty"` // CommonName 312 CertificateAltNames string `json:",omitempty" yaml:"certificate_alt_names,omitempty" structs:",omitempty"` // SAN 313 } 314 315 // UnmarshalJSON UnmarshalJSON(CertificateEndDateのtime.TimeへのUnmarshal対応) 316 func (p *ProxyLBCertificate) UnmarshalJSON(data []byte) error { 317 var tmp map[string]interface{} 318 if err := json.Unmarshal(data, &tmp); err != nil { 319 return err 320 } 321 322 p.ServerCertificate = tmp["ServerCertificate"].(string) 323 p.IntermediateCertificate = tmp["IntermediateCertificate"].(string) 324 p.PrivateKey = tmp["PrivateKey"].(string) 325 p.CertificateCommonName = tmp["CertificateCommonName"].(string) 326 p.CertificateAltNames = tmp["CertificateAltNames"].(string) 327 endDate := tmp["CertificateEndDate"].(string) 328 if endDate != "" { 329 date, err := time.Parse("Jan _2 15:04:05 2006 MST", endDate) 330 if err != nil { 331 return err 332 } 333 p.CertificateEndDate = &date 334 } 335 336 return nil 337 } 338 339 // ProxyLBHealth ProxyLBのヘルスチェック戻り値 340 type ProxyLBHealth struct { 341 ActiveConn int `json:",omitempty" yaml:"active_conn,omitempty" structs:",omitempty"` // アクティブなコネクション数 342 CPS float64 `json:",omitempty" yaml:"cps,omitempty" structs:",omitempty"` // 秒あたりコネクション数 343 Servers []*ProxyLBHealthServer `json:",omitempty" yaml:"servers,omitempty" structs:",omitempty"` // 実サーバのステータス 344 CurrentVIP string `json:",omitempty" yaml:"current_vip,omitempty" structs:",omitempty"` // 現在のVIP 345 } 346 347 // ProxyLBHealthServer ProxyLBの実サーバのステータス 348 type ProxyLBHealthServer struct { 349 ActiveConn int `json:",omitempty" yaml:"active_conn,omitempty" structs:",omitempty"` // アクティブなコネクション数 350 Status types.EServerInstanceStatus `json:",omitempty" yaml:"status,omitempty" structs:",omitempty"` // ステータス(UP or DOWN) 351 IPAddress string `json:",omitempty" yaml:"ip_address,omitempty" structs:",omitempty"` // IPアドレス 352 Port string `json:",omitempty" yaml:"port,omitempty" structs:",omitempty"` // ポート 353 CPS float64 `json:",omitempty" yaml:"cps,omitempty" structs:",omitempty"` // 秒あたりコネクション数 354 }