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