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 (
18	"fmt"
19	"net"
20)
21
22// VPCRouter VPCルーター
23type VPCRouter struct {
24	*Appliance // アプライアンス共通属性
25
26	Remark   *VPCRouterRemark   `json:",omitempty"` // リマーク
27	Settings *VPCRouterSettings `json:",omitempty"` // VPCルーター設定リスト
28}
29
30// VPCRouterRemark リマーク
31type VPCRouterRemark struct {
32	*ApplianceRemarkBase
33	// TODO Zone
34	//Zone *Resource
35}
36
37// VPCRouterSettings VPCルーター設定リスト
38type VPCRouterSettings struct {
39	Router *VPCRouterSetting `json:",omitempty"` // VPCルーター設定
40}
41
42// CreateNewVPCRouter VPCルーター作成
43func CreateNewVPCRouter() *VPCRouter {
44	return &VPCRouter{
45		Appliance: &Appliance{
46			Class:      "vpcrouter",
47			propPlanID: propPlanID{Plan: &Resource{}},
48		},
49		Remark: &VPCRouterRemark{
50			ApplianceRemarkBase: &ApplianceRemarkBase{
51				Servers: []interface{}{""},
52				Switch:  &ApplianceRemarkSwitch{},
53			},
54		},
55		Settings: &VPCRouterSettings{
56			Router: &VPCRouterSetting{},
57		},
58	}
59}
60
61// InitVPCRouterSetting VPCルーター設定初期化
62func (v *VPCRouter) InitVPCRouterSetting() {
63	settings := &VPCRouterSettings{
64		Router: &VPCRouterSetting{},
65	}
66
67	if v.Settings != nil && v.Settings.Router != nil && v.Settings.Router.Interfaces != nil {
68		settings.Router.Interfaces = v.Settings.Router.Interfaces
69	}
70	if v.Settings != nil && v.Settings.Router != nil && v.Settings.Router.VRID != nil {
71		settings.Router.VRID = v.Settings.Router.VRID
72	}
73
74	v.Settings = settings
75}
76
77// IsStandardPlan スタンダードプランか判定
78func (v *VPCRouter) IsStandardPlan() bool {
79	return v.Plan.ID == 1
80}
81
82// IsPremiumPlan プレミアムプランか判定
83func (v *VPCRouter) IsPremiumPlan() bool {
84	return v.Plan.ID == 2
85}
86
87// IsHighSpecPlan ハイスペックプランか判定
88func (v *VPCRouter) IsHighSpecPlan() bool {
89	return v.Plan.ID == 3
90}
91
92// IsHighSpec4000MbpsPlan ハイスペック4000Mbpsプランか判定
93func (v *VPCRouter) IsHighSpec4000MbpsPlan() bool {
94	return v.Plan.ID == 4
95}
96
97// SetStandardPlan スタンダードプランへ設定
98func (v *VPCRouter) SetStandardPlan() {
99	v.Plan.SetID(1)
100	v.Remark.Switch = &ApplianceRemarkSwitch{
101		// Scope
102		propScope: propScope{Scope: "shared"},
103	}
104	v.Settings = nil
105}
106
107// SetPremiumPlan プレミアムプランへ設定
108func (v *VPCRouter) SetPremiumPlan(switchID string, virtualIPAddress string, ipAddress1 string, ipAddress2 string, vrid int, ipAliases []string) {
109	v.Plan.SetID(2)
110	v.setPremiumServices(switchID, virtualIPAddress, ipAddress1, ipAddress2, vrid, ipAliases)
111}
112
113// SetHighSpecPlan ハイスペックプランへ設定
114func (v *VPCRouter) SetHighSpecPlan(switchID string, virtualIPAddress string, ipAddress1 string, ipAddress2 string, vrid int, ipAliases []string) {
115	v.Plan.SetID(3)
116	v.setPremiumServices(switchID, virtualIPAddress, ipAddress1, ipAddress2, vrid, ipAliases)
117}
118
119// SetHighSpec4000MbpsPlan ハイスペックプランへ設定
120func (v *VPCRouter) SetHighSpec4000MbpsPlan(switchID string, virtualIPAddress string, ipAddress1 string, ipAddress2 string, vrid int, ipAliases []string) {
121	v.Plan.SetID(4)
122	v.setPremiumServices(switchID, virtualIPAddress, ipAddress1, ipAddress2, vrid, ipAliases)
123}
124
125func (v *VPCRouter) setPremiumServices(switchID string, virtualIPAddress string, ipAddress1 string, ipAddress2 string, vrid int, ipAliases []string) {
126	v.Remark.Switch = &ApplianceRemarkSwitch{
127		ID: StringID(switchID),
128	}
129	v.Remark.Servers = []interface{}{
130		map[string]string{"IPAddress": ipAddress1},
131		map[string]string{"IPAddress": ipAddress2},
132	}
133
134	v.Settings = &VPCRouterSettings{
135		Router: &VPCRouterSetting{
136			Interfaces: []*VPCRouterInterface{
137				{
138					IPAddress: []string{
139						ipAddress1,
140						ipAddress2,
141					},
142					VirtualIPAddress: virtualIPAddress,
143					IPAliases:        ipAliases,
144				},
145			},
146			VRID: &vrid,
147		},
148	}
149
150}
151
152// HasSetting VPCルータ設定を保持しているか
153func (v *VPCRouter) HasSetting() bool {
154	return v.Settings != nil && v.Settings.Router != nil
155}
156
157// HasInterfaces NIC設定を保持しているか
158func (v *VPCRouter) HasInterfaces() bool {
159	return v.HasSetting() && v.Settings.Router.HasInterfaces()
160}
161
162// HasStaticNAT スタティックNAT設定を保持しているか
163func (v *VPCRouter) HasStaticNAT() bool {
164	return v.HasSetting() && v.Settings.Router.HasStaticNAT()
165}
166
167// HasPortForwarding ポートフォワーディング設定を保持しているか
168func (v *VPCRouter) HasPortForwarding() bool {
169	return v.HasSetting() && v.Settings.Router.HasPortForwarding()
170}
171
172// HasFirewall ファイアウォール設定を保持しているか
173func (v *VPCRouter) HasFirewall() bool {
174	return v.HasSetting() && v.Settings.Router.HasFirewall()
175}
176
177// HasDHCPServer DHCPサーバー設定を保持しているか
178func (v *VPCRouter) HasDHCPServer() bool {
179	return v.HasSetting() && v.Settings.Router.HasDHCPServer()
180}
181
182// HasDHCPStaticMapping DHCPスタティックマッピング設定を保持しているか
183func (v *VPCRouter) HasDHCPStaticMapping() bool {
184	return v.HasSetting() && v.Settings.Router.HasDHCPStaticMapping()
185}
186
187// HasL2TPIPsecServer L2TP/IPSecサーバを保持しているか
188func (v *VPCRouter) HasL2TPIPsecServer() bool {
189	return v.HasSetting() && v.Settings.Router.HasL2TPIPsecServer()
190}
191
192// HasPPTPServer PPTPサーバを保持しているか
193func (v *VPCRouter) HasPPTPServer() bool {
194	return v.HasSetting() && v.Settings.Router.HasPPTPServer()
195}
196
197// HasRemoteAccessUsers リモートアクセスユーザー設定を保持しているか
198func (v *VPCRouter) HasRemoteAccessUsers() bool {
199	return v.HasSetting() && v.Settings.Router.HasRemoteAccessUsers()
200}
201
202// HasSiteToSiteIPsecVPN サイト間VPN設定を保持しているか
203func (v *VPCRouter) HasSiteToSiteIPsecVPN() bool {
204	return v.HasSetting() && v.Settings.Router.HasSiteToSiteIPsecVPN()
205}
206
207// HasStaticRoutes スタティックルートを保持しているか
208func (v *VPCRouter) HasStaticRoutes() bool {
209	return v.HasSetting() && v.Settings.Router.HasStaticRoutes()
210}
211
212// RealIPAddress プランに応じて外部向けIPアドレスを返す
213//
214// Standard: IPAddress1
215// Other: VirtualIPAddress
216func (v *VPCRouter) RealIPAddress(index int) (string, int) {
217	if !v.HasInterfaces() {
218		return "", -1
219	}
220	for i, nic := range v.Settings.Router.Interfaces {
221		if i == index {
222			if index > 0 && nic == nil {
223				return "", -1
224			}
225
226			if index == 0 && v.IsStandardPlan() {
227				return v.Interfaces[0].IPAddress, v.Interfaces[0].Switch.Subnet.NetworkMaskLen
228			}
229
230			nwMask := nic.NetworkMaskLen
231			if index == 0 {
232				nwMask = v.Interfaces[0].Switch.Subnet.NetworkMaskLen
233			}
234
235			if v.IsStandardPlan() {
236				return nic.IPAddress[0], nwMask
237			}
238			return nic.VirtualIPAddress, nwMask
239		}
240	}
241	return "", -1
242}
243
244// FindBelongsInterface 指定のIPアドレスが所属するIPレンジを持つインターフェースを取得
245func (v *VPCRouter) FindBelongsInterface(ip net.IP) (int, *VPCRouterInterface) {
246	if !v.HasInterfaces() {
247		return -1, nil
248	}
249
250	for i, nic := range v.Settings.Router.Interfaces {
251		nicIP, maskLen := v.RealIPAddress(i)
252		if nicIP != "" {
253			_, ipv4Net, err := net.ParseCIDR(fmt.Sprintf("%s/%d", nicIP, maskLen))
254			if err != nil {
255				return -1, nil
256			}
257			if ipv4Net.Contains(ip) {
258				return i, nic
259			}
260		}
261	}
262	return -1, nil
263}
264
265// IPAddress1 1番目(0番目)のNICのIPアドレス1
266func (v *VPCRouter) IPAddress1() string {
267	return v.IPAddress1At(0)
268}
269
270// IPAddress1At 指定インデックスのNICのIPアドレス1
271func (v *VPCRouter) IPAddress1At(index int) string {
272	if len(v.Interfaces) <= index {
273		return ""
274	}
275
276	if index == 0 {
277		if v.IsStandardPlan() {
278			return v.Interfaces[0].IPAddress
279		}
280
281		if !v.HasInterfaces() {
282			return ""
283		}
284		if len(v.Settings.Router.Interfaces[0].IPAddress) < 1 {
285			return ""
286		}
287		return v.Settings.Router.Interfaces[0].IPAddress[0]
288	}
289
290	nic := v.Settings.Router.Interfaces[index]
291	if len(nic.IPAddress) < 1 {
292		return ""
293	}
294	return nic.IPAddress[0]
295}
296
297// IPAddress2 1番目(0番目)のNICのIPアドレス2
298func (v *VPCRouter) IPAddress2() string {
299	return v.IPAddress2At(0)
300}
301
302// IPAddress2At 指定インデックスのNICのIPアドレス2
303func (v *VPCRouter) IPAddress2At(index int) string {
304	if v.IsStandardPlan() {
305		return ""
306	}
307	if len(v.Interfaces) <= index {
308		return ""
309	}
310
311	if index == 0 {
312		if !v.HasInterfaces() {
313			return ""
314		}
315		if len(v.Settings.Router.Interfaces[0].IPAddress) < 2 {
316			return ""
317		}
318		return v.Settings.Router.Interfaces[0].IPAddress[1]
319	}
320
321	nic := v.Settings.Router.Interfaces[index]
322	if len(nic.IPAddress) < 2 {
323		return ""
324	}
325	return nic.IPAddress[1]
326}
327
328// VirtualIPAddress 1番目(0番目)のNICのVIP
329func (v *VPCRouter) VirtualIPAddress() string {
330	return v.VirtualIPAddressAt(0)
331}
332
333// VirtualIPAddressAt 指定インデックスのNICのVIP
334func (v *VPCRouter) VirtualIPAddressAt(index int) string {
335	if v.IsStandardPlan() {
336		return ""
337	}
338	if len(v.Interfaces) <= index {
339		return ""
340	}
341
342	return v.Settings.Router.Interfaces[0].VirtualIPAddress
343}
344
345// NetworkMaskLen 1番目(0番目)のNICのネットワークマスク長
346func (v *VPCRouter) NetworkMaskLen() int {
347	return v.NetworkMaskLenAt(0)
348}
349
350// NetworkMaskLenAt 指定インデックスのNICのネットワークマスク長
351func (v *VPCRouter) NetworkMaskLenAt(index int) int {
352	if !v.HasInterfaces() {
353		return -1
354	}
355	if len(v.Interfaces) <= index {
356		return -1
357	}
358
359	if index == 0 {
360		return v.Interfaces[0].Switch.Subnet.NetworkMaskLen
361	}
362
363	return v.Settings.Router.Interfaces[index].NetworkMaskLen
364}
365
366// Zone スイッチから現在のゾーン名を取得
367//
368// Note: 共有セグメント接続時は取得不能
369func (v *VPCRouter) Zone() string {
370	if v.Switch != nil {
371		return v.Switch.GetZoneName()
372	}
373
374	if len(v.Interfaces) > 0 && v.Interfaces[0].Switch != nil {
375		return v.Interfaces[0].Switch.GetZoneName()
376	}
377
378	return ""
379}
380
381// VRID VRIDを取得
382//
383// スタンダードプラン、またはVRIDの参照に失敗した場合は-1を返す
384func (v *VPCRouter) VRID() int {
385	if v.IsStandardPlan() {
386		return -1
387	}
388
389	if !v.HasSetting() || v.Settings.Router.VRID == nil {
390		return -1
391	}
392
393	return *v.Settings.Router.VRID
394}
395