ops_mobile_gateway.go raw
1 // Copyright 2022-2025 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 fake
16
17 import (
18 "context"
19 "fmt"
20 "time"
21
22 "github.com/sacloud/iaas-api-go"
23 "github.com/sacloud/iaas-api-go/types"
24 )
25
26 // Find is fake implementation
27 func (o *MobileGatewayOp) Find(ctx context.Context, zone string, conditions *iaas.FindCondition) (*iaas.MobileGatewayFindResult, error) {
28 results, _ := find(o.key, zone, conditions)
29 var values []*iaas.MobileGateway
30 for _, res := range results {
31 dest := &iaas.MobileGateway{}
32 copySameNameField(res, dest)
33 values = append(values, dest)
34 }
35 return &iaas.MobileGatewayFindResult{
36 Total: len(results),
37 Count: len(results),
38 From: 0,
39 MobileGateways: values,
40 }, nil
41 }
42
43 // Create is fake implementation
44 func (o *MobileGatewayOp) Create(ctx context.Context, zone string, param *iaas.MobileGatewayCreateRequest) (*iaas.MobileGateway, error) {
45 result := &iaas.MobileGateway{}
46 copySameNameField(param, result)
47 fill(result, fillID, fillCreatedAt)
48
49 result.Availability = types.Availabilities.Available
50 result.Class = "mobilegateway"
51 result.ZoneID = zoneIDs[zone]
52 result.SettingsHash = ""
53
54 // set interface
55 ifOp := NewInterfaceOp()
56 iface, err := ifOp.Create(ctx, zone, &iaas.InterfaceCreateRequest{ServerID: result.ID})
57 if err != nil {
58 return nil, newErrorConflict(o.key, types.ID(0), err.Error())
59 }
60 if err := ifOp.ConnectToSharedSegment(ctx, zone, iface.ID); err != nil {
61 return nil, newErrorConflict(o.key, types.ID(0), err.Error())
62 }
63 iface, err = ifOp.Read(ctx, zone, iface.ID)
64 if err != nil {
65 return nil, newErrorConflict(o.key, types.ID(0), err.Error())
66 }
67 ifaceView := &iaas.MobileGatewayInterface{}
68 copySameNameField(iface, ifaceView)
69 result.Interfaces = append(result.Interfaces, ifaceView)
70
71 putMobileGateway(zone, result)
72 return result, nil
73 }
74
75 // Read is fake implementation
76 func (o *MobileGatewayOp) Read(ctx context.Context, zone string, id types.ID) (*iaas.MobileGateway, error) {
77 value := getMobileGatewayByID(zone, id)
78 if value == nil {
79 return nil, newErrorNotFound(o.key, id)
80 }
81 dest := &iaas.MobileGateway{}
82 copySameNameField(value, dest)
83 return dest, nil
84 }
85
86 // Update is fake implementation
87 func (o *MobileGatewayOp) Update(ctx context.Context, zone string, id types.ID, param *iaas.MobileGatewayUpdateRequest) (*iaas.MobileGateway, error) {
88 value, err := o.Read(ctx, zone, id)
89 if err != nil {
90 return nil, err
91 }
92 copySameNameField(param, value)
93 fill(value, fillModifiedAt)
94
95 putMobileGateway(zone, value)
96 return value, nil
97 }
98
99 // UpdateSettings is fake implementation
100 func (o *MobileGatewayOp) UpdateSettings(ctx context.Context, zone string, id types.ID, param *iaas.MobileGatewayUpdateSettingsRequest) (*iaas.MobileGateway, error) {
101 value, err := o.Read(ctx, zone, id)
102 if err != nil {
103 return nil, err
104 }
105 copySameNameField(param, value)
106 fill(value, fillModifiedAt)
107
108 putMobileGateway(zone, value)
109 return value, nil
110 }
111
112 // Delete is fake implementation
113 func (o *MobileGatewayOp) Delete(ctx context.Context, zone string, id types.ID) error {
114 _, err := o.Read(ctx, zone, id)
115 if err != nil {
116 return err
117 }
118
119 ds().Delete(o.key, zone, id)
120 return nil
121 }
122
123 // Config is fake implementation
124 func (o *MobileGatewayOp) Config(ctx context.Context, zone string, id types.ID) error {
125 _, err := o.Read(ctx, zone, id)
126 return err
127 }
128
129 // Boot is fake implementation
130 func (o *MobileGatewayOp) Boot(ctx context.Context, zone string, id types.ID) error {
131 value, err := o.Read(ctx, zone, id)
132 if err != nil {
133 return err
134 }
135 if value.InstanceStatus.IsUp() {
136 return newErrorConflict(o.key, id, "Boot is failed")
137 }
138
139 startPowerOn(o.key, zone, func() (interface{}, error) {
140 return o.Read(context.Background(), zone, id)
141 })
142
143 return err
144 }
145
146 // Shutdown is fake implementation
147 func (o *MobileGatewayOp) Shutdown(ctx context.Context, zone string, id types.ID, shutdownOption *iaas.ShutdownOption) error {
148 value, err := o.Read(ctx, zone, id)
149 if err != nil {
150 return err
151 }
152 if !value.InstanceStatus.IsUp() {
153 return newErrorConflict(o.key, id, "Shutdown is failed")
154 }
155
156 startPowerOff(o.key, zone, func() (interface{}, error) {
157 return o.Read(context.Background(), zone, id)
158 })
159
160 return err
161 }
162
163 // Reset is fake implementation
164 func (o *MobileGatewayOp) Reset(ctx context.Context, zone string, id types.ID) error {
165 value, err := o.Read(ctx, zone, id)
166 if err != nil {
167 return err
168 }
169 if !value.InstanceStatus.IsUp() {
170 return newErrorConflict(o.key, id, "Reset is failed")
171 }
172
173 startPowerOn(o.key, zone, func() (interface{}, error) {
174 return o.Read(context.Background(), zone, id)
175 })
176
177 return nil
178 }
179
180 // ConnectToSwitch is fake implementation
181 func (o *MobileGatewayOp) ConnectToSwitch(ctx context.Context, zone string, id types.ID, switchID types.ID) error {
182 value, err := o.Read(ctx, zone, id)
183 if err != nil {
184 return err
185 }
186
187 for _, nic := range value.Interfaces {
188 if nic.Index == 1 {
189 return newErrorBadRequest(o.key, id, fmt.Sprintf("nic[%d] already connected to switch", 1))
190 }
191 }
192
193 // find switch
194 swOp := NewSwitchOp()
195 _, err = swOp.Read(ctx, zone, switchID)
196 if err != nil {
197 return fmt.Errorf("ConnectToSwitch is failed: %s", err)
198 }
199
200 // create interface
201 ifOp := NewInterfaceOp()
202 iface, err := ifOp.Create(ctx, zone, &iaas.InterfaceCreateRequest{ServerID: id})
203 if err != nil {
204 return newErrorConflict(o.key, types.ID(0), err.Error())
205 }
206
207 if err := ifOp.ConnectToSwitch(ctx, zone, iface.ID, switchID); err != nil {
208 return newErrorConflict(o.key, types.ID(0), err.Error())
209 }
210
211 iface, err = ifOp.Read(ctx, zone, iface.ID)
212 if err != nil {
213 return newErrorConflict(o.key, types.ID(0), err.Error())
214 }
215
216 mobileGatewayInterface := &iaas.MobileGatewayInterface{}
217 copySameNameField(iface, mobileGatewayInterface)
218 mobileGatewayInterface.Index = 1 // 1固定
219 value.Interfaces = append(value.Interfaces, mobileGatewayInterface)
220
221 putMobileGateway(zone, value)
222 return nil
223 }
224
225 // DisconnectFromSwitch is fake implementation
226 func (o *MobileGatewayOp) DisconnectFromSwitch(ctx context.Context, zone string, id types.ID) error {
227 value, err := o.Read(ctx, zone, id)
228 if err != nil {
229 return err
230 }
231
232 var exists bool
233 var nicID types.ID
234 var interfaces []*iaas.MobileGatewayInterface
235
236 for _, nic := range value.Interfaces {
237 if nic != nil && nic.Index == 1 {
238 exists = true
239 nicID = nic.ID
240 } else {
241 interfaces = append(interfaces, nic)
242 }
243 }
244 if !exists {
245 return newErrorBadRequest(o.key, id, fmt.Sprintf("nic[%d] is not exists", 1))
246 }
247
248 ifOp := NewInterfaceOp()
249 if err := ifOp.DisconnectFromSwitch(ctx, zone, nicID); err != nil {
250 return newErrorConflict(o.key, types.ID(0), err.Error())
251 }
252
253 value.Interfaces = interfaces
254 putMobileGateway(zone, value)
255 return nil
256 }
257
258 // GetDNS is fake implementation
259 func (o *MobileGatewayOp) GetDNS(ctx context.Context, zone string, id types.ID) (*iaas.MobileGatewayDNSSetting, error) {
260 _, err := o.Read(ctx, zone, id)
261 if err != nil {
262 return nil, err
263 }
264
265 dns := ds().Get(o.dnsStoreKey(), zone, id)
266 if dns == nil {
267 return &iaas.MobileGatewayDNSSetting{
268 DNS1: "133.242.0.1",
269 DNS2: "133.242.0.2",
270 }, nil
271 }
272 return dns.(*iaas.MobileGatewayDNSSetting), nil
273 }
274
275 // SetDNS is fake implementation
276 func (o *MobileGatewayOp) SetDNS(ctx context.Context, zone string, id types.ID, param *iaas.MobileGatewayDNSSetting) error {
277 _, err := o.Read(ctx, zone, id)
278 if err != nil {
279 return err
280 }
281
282 ds().Put(o.dnsStoreKey(), zone, id, param)
283 return nil
284 }
285
286 // GetSIMRoutes is fake implementation
287 func (o *MobileGatewayOp) GetSIMRoutes(ctx context.Context, zone string, id types.ID) (iaas.MobileGatewaySIMRoutes, error) {
288 _, err := o.Read(ctx, zone, id)
289 if err != nil {
290 return nil, err
291 }
292
293 routes := ds().Get(o.simRoutesStoreKey(), zone, id)
294 if routes == nil {
295 return nil, nil
296 }
297
298 rs := routes.(*[]*iaas.MobileGatewaySIMRoute)
299 var res []*iaas.MobileGatewaySIMRoute
300 res = append(res, *rs...)
301 return res, nil
302 }
303
304 // SetSIMRoutes is fake implementation
305 func (o *MobileGatewayOp) SetSIMRoutes(ctx context.Context, zone string, id types.ID, param []*iaas.MobileGatewaySIMRouteParam) error {
306 _, err := o.Read(ctx, zone, id)
307 if err != nil {
308 return err
309 }
310
311 simOp := NewSIMOp()
312 var values []*iaas.MobileGatewaySIMRoute
313 for _, p := range param {
314 sim, err := simOp.Read(ctx, types.StringID(p.ResourceID))
315 if err != nil {
316 return err
317 }
318 values = append(values, &iaas.MobileGatewaySIMRoute{
319 ResourceID: p.ResourceID,
320 Prefix: p.Prefix,
321 ICCID: sim.ICCID,
322 })
323 }
324
325 ds().Put(o.simRoutesStoreKey(), zone, id, &values)
326 return nil
327 }
328
329 // ListSIM is fake implementation
330 func (o *MobileGatewayOp) ListSIM(ctx context.Context, zone string, id types.ID) (iaas.MobileGatewaySIMs, error) {
331 _, err := o.Read(ctx, zone, id)
332 if err != nil {
333 return nil, err
334 }
335
336 sims := ds().Get(o.simsStoreKey(), zone, id)
337 if sims == nil {
338 return nil, nil
339 }
340
341 ss := sims.(*[]*iaas.MobileGatewaySIMInfo)
342 var res []*iaas.MobileGatewaySIMInfo
343 res = append(res, *ss...)
344 return res, nil
345 }
346
347 // AddSIM is fake implementation
348 func (o *MobileGatewayOp) AddSIM(ctx context.Context, zone string, id types.ID, param *iaas.MobileGatewayAddSIMRequest) error {
349 _, err := o.Read(ctx, zone, id)
350 if err != nil {
351 return err
352 }
353
354 var sims []*iaas.MobileGatewaySIMInfo
355 rawSIMs := ds().Get(o.simsStoreKey(), zone, id)
356 if rawSIMs != nil {
357 sims = rawSIMs.([]*iaas.MobileGatewaySIMInfo)
358 for _, sim := range sims {
359 if sim.ResourceID == param.SIMID {
360 return newErrorBadRequest(o.key, id, fmt.Sprintf("SIM %s already exists", param.SIMID))
361 }
362 }
363 }
364
365 simOp := NewSIMOp()
366 simInfo, err := simOp.Status(context.Background(), types.StringID(param.SIMID))
367 if err != nil {
368 return err
369 }
370 sim := &iaas.MobileGatewaySIMInfo{}
371 copySameNameField(simInfo, sim)
372
373 sims = append(sims, sim)
374
375 ds().Put(o.simsStoreKey(), zone, id, &sims)
376 return nil
377 }
378
379 // DeleteSIM is fake implementation
380 func (o *MobileGatewayOp) DeleteSIM(ctx context.Context, zone string, id types.ID, simID types.ID) error {
381 _, err := o.Read(ctx, zone, id)
382 if err != nil {
383 return err
384 }
385
386 var updSIMs []*iaas.MobileGatewaySIMInfo
387 rawSIMs := ds().Get(o.simsStoreKey(), zone, id)
388 if rawSIMs != nil {
389 ss := rawSIMs.(*[]*iaas.MobileGatewaySIMInfo)
390 for _, sim := range *ss {
391 if sim.ResourceID != simID.String() {
392 updSIMs = append(updSIMs, sim)
393 }
394 }
395 if len(*ss) != len(updSIMs) {
396 ds().Put(o.simsStoreKey(), zone, id, &updSIMs)
397 return nil
398 }
399 }
400 return newErrorBadRequest(o.key, id, fmt.Sprintf("SIM %d is not exists", simID))
401 }
402
403 // Logs is fake implementation
404 func (o *MobileGatewayOp) Logs(ctx context.Context, zone string, id types.ID) ([]*iaas.MobileGatewaySIMLogs, error) {
405 _, err := o.Read(ctx, zone, id)
406 if err != nil {
407 return nil, err
408 }
409
410 return []*iaas.MobileGatewaySIMLogs{
411 {
412 Date: time.Now(),
413 SessionStatus: "UP",
414 ResourceID: types.ID(1).String(),
415 },
416 }, nil
417 }
418
419 // GetTrafficConfig is fake implementation
420 func (o *MobileGatewayOp) GetTrafficConfig(ctx context.Context, zone string, id types.ID) (*iaas.MobileGatewayTrafficControl, error) {
421 _, err := o.Read(ctx, zone, id)
422 if err != nil {
423 return nil, err
424 }
425
426 config := ds().Get(o.trafficConfigStoreKey(), zone, id)
427 if config == nil {
428 return nil, nil
429 }
430 return config.(*iaas.MobileGatewayTrafficControl), nil
431 }
432
433 // SetTrafficConfig is fake implementation
434 func (o *MobileGatewayOp) SetTrafficConfig(ctx context.Context, zone string, id types.ID, param *iaas.MobileGatewayTrafficControl) error {
435 _, err := o.Read(ctx, zone, id)
436 if err != nil {
437 return err
438 }
439
440 ds().Put(o.trafficConfigStoreKey(), zone, id, param)
441 return nil
442 }
443
444 // DeleteTrafficConfig is fake implementation
445 func (o *MobileGatewayOp) DeleteTrafficConfig(ctx context.Context, zone string, id types.ID) error {
446 _, err := o.Read(ctx, zone, id)
447 if err != nil {
448 return err
449 }
450
451 ds().Delete(o.trafficConfigStoreKey(), zone, id)
452 return nil
453 }
454
455 // TrafficStatus is fake implementation
456 func (o *MobileGatewayOp) TrafficStatus(ctx context.Context, zone string, id types.ID) (*iaas.MobileGatewayTrafficStatus, error) {
457 _, err := o.Read(ctx, zone, id)
458 if err != nil {
459 return nil, err
460 }
461
462 return &iaas.MobileGatewayTrafficStatus{
463 UplinkBytes: 0,
464 DownlinkBytes: 0,
465 TrafficShaping: true,
466 }, nil
467 }
468
469 // MonitorInterface is fake implementation
470 func (o *MobileGatewayOp) MonitorInterface(ctx context.Context, zone string, id types.ID, index int, condition *iaas.MonitorCondition) (*iaas.InterfaceActivity, error) {
471 _, err := o.Read(ctx, zone, id)
472 if err != nil {
473 return nil, err
474 }
475
476 now := time.Now().Truncate(time.Second)
477 m := now.Minute() % 5
478 if m != 0 {
479 now.Add(time.Duration(m) * time.Minute)
480 }
481
482 res := &iaas.InterfaceActivity{}
483 for i := 0; i < 5; i++ {
484 res.Values = append(res.Values, &iaas.MonitorInterfaceValue{
485 Time: now.Add(time.Duration(i*-5) * time.Minute),
486 Send: float64(random(1000)),
487 Receive: float64(random(1000)),
488 })
489 }
490
491 return res, nil
492 }
493
494 func (o *MobileGatewayOp) dnsStoreKey() string {
495 return o.key + "DNS"
496 }
497
498 func (o *MobileGatewayOp) simRoutesStoreKey() string {
499 return o.key + "SIMRoutes"
500 }
501
502 func (o *MobileGatewayOp) simsStoreKey() string {
503 return o.key + "SIMs"
504 }
505
506 func (o *MobileGatewayOp) trafficConfigStoreKey() string {
507 return o.key + "TrafficConfig"
508 }
509