ops_load_balancer.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  	"time"
  20  
  21  	"github.com/sacloud/iaas-api-go"
  22  	"github.com/sacloud/iaas-api-go/types"
  23  )
  24  
  25  // Find is fake implementation
  26  func (o *LoadBalancerOp) Find(ctx context.Context, zone string, conditions *iaas.FindCondition) (*iaas.LoadBalancerFindResult, error) {
  27  	results, _ := find(o.key, zone, conditions)
  28  	var values []*iaas.LoadBalancer
  29  	for _, res := range results {
  30  		dest := &iaas.LoadBalancer{}
  31  		copySameNameField(res, dest)
  32  		values = append(values, dest)
  33  	}
  34  	return &iaas.LoadBalancerFindResult{
  35  		Total:         len(results),
  36  		Count:         len(results),
  37  		From:          0,
  38  		LoadBalancers: values,
  39  	}, nil
  40  }
  41  
  42  // Create is fake implementation
  43  func (o *LoadBalancerOp) Create(ctx context.Context, zone string, param *iaas.LoadBalancerCreateRequest) (*iaas.LoadBalancer, error) {
  44  	result := &iaas.LoadBalancer{}
  45  	copySameNameField(param, result)
  46  	fill(result, fillID, fillCreatedAt)
  47  
  48  	result.Class = "loadbalancer"
  49  	result.Availability = types.Availabilities.Migrating
  50  	result.ZoneID = zoneIDs[zone]
  51  	result.SettingsHash = ""
  52  	for _, vip := range result.VirtualIPAddresses {
  53  		if vip.DelayLoop == 0 {
  54  			vip.DelayLoop = 10 // default value
  55  		}
  56  	}
  57  
  58  	putLoadBalancer(zone, result)
  59  
  60  	id := result.ID
  61  	startPowerOn(o.key, zone, func() (interface{}, error) {
  62  		return o.Read(context.Background(), zone, id)
  63  	})
  64  	return result, nil
  65  }
  66  
  67  // Read is fake implementation
  68  func (o *LoadBalancerOp) Read(ctx context.Context, zone string, id types.ID) (*iaas.LoadBalancer, error) {
  69  	value := getLoadBalancerByID(zone, id)
  70  	if value == nil {
  71  		return nil, newErrorNotFound(o.key, id)
  72  	}
  73  
  74  	dest := &iaas.LoadBalancer{}
  75  	copySameNameField(value, dest)
  76  	return dest, nil
  77  }
  78  
  79  // Update is fake implementation
  80  func (o *LoadBalancerOp) Update(ctx context.Context, zone string, id types.ID, param *iaas.LoadBalancerUpdateRequest) (*iaas.LoadBalancer, error) {
  81  	value, err := o.Read(ctx, zone, id)
  82  	if err != nil {
  83  		return nil, err
  84  	}
  85  
  86  	copySameNameField(param, value)
  87  	fill(value, fillModifiedAt)
  88  	for _, vip := range value.VirtualIPAddresses {
  89  		if vip.DelayLoop == 0 {
  90  			vip.DelayLoop = 10 // default value
  91  		}
  92  	}
  93  	putLoadBalancer(zone, value)
  94  	return value, nil
  95  }
  96  
  97  // UpdateSettings is fake implementation
  98  func (o *LoadBalancerOp) UpdateSettings(ctx context.Context, zone string, id types.ID, param *iaas.LoadBalancerUpdateSettingsRequest) (*iaas.LoadBalancer, error) {
  99  	value, err := o.Read(ctx, zone, id)
 100  	if err != nil {
 101  		return nil, err
 102  	}
 103  
 104  	copySameNameField(param, value)
 105  	fill(value, fillModifiedAt)
 106  	for _, vip := range value.VirtualIPAddresses {
 107  		if vip.DelayLoop == 0 {
 108  			vip.DelayLoop = 10 // default value
 109  		}
 110  	}
 111  	putLoadBalancer(zone, value)
 112  	return value, nil
 113  }
 114  
 115  // Delete is fake implementation
 116  func (o *LoadBalancerOp) Delete(ctx context.Context, zone string, id types.ID) error {
 117  	_, err := o.Read(ctx, zone, id)
 118  	if err != nil {
 119  		return err
 120  	}
 121  	ds().Delete(o.key, zone, id)
 122  	return nil
 123  }
 124  
 125  // Config is fake implementation
 126  func (o *LoadBalancerOp) Config(ctx context.Context, zone string, id types.ID) error {
 127  	_, err := o.Read(ctx, zone, id)
 128  	return err
 129  }
 130  
 131  // Boot is fake implementation
 132  func (o *LoadBalancerOp) Boot(ctx context.Context, zone string, id types.ID) error {
 133  	value, err := o.Read(ctx, zone, id)
 134  	if err != nil {
 135  		return err
 136  	}
 137  	if value.InstanceStatus.IsUp() {
 138  		return newErrorConflict(o.key, id, "Boot is failed")
 139  	}
 140  
 141  	startPowerOn(o.key, zone, func() (interface{}, error) {
 142  		return o.Read(context.Background(), zone, id)
 143  	})
 144  
 145  	return err
 146  }
 147  
 148  // Shutdown is fake implementation
 149  func (o *LoadBalancerOp) Shutdown(ctx context.Context, zone string, id types.ID, shutdownOption *iaas.ShutdownOption) error {
 150  	value, err := o.Read(ctx, zone, id)
 151  	if err != nil {
 152  		return err
 153  	}
 154  	if !value.InstanceStatus.IsUp() {
 155  		return newErrorConflict(o.key, id, "Shutdown is failed")
 156  	}
 157  
 158  	startPowerOff(o.key, zone, func() (interface{}, error) {
 159  		return o.Read(context.Background(), zone, id)
 160  	})
 161  
 162  	return err
 163  }
 164  
 165  // Reset is fake implementation
 166  func (o *LoadBalancerOp) Reset(ctx context.Context, zone string, id types.ID) error {
 167  	value, err := o.Read(ctx, zone, id)
 168  	if err != nil {
 169  		return err
 170  	}
 171  	if !value.InstanceStatus.IsUp() {
 172  		return newErrorConflict(o.key, id, "Reset is failed")
 173  	}
 174  
 175  	startPowerOn(o.key, zone, func() (interface{}, error) {
 176  		return o.Read(context.Background(), zone, id)
 177  	})
 178  
 179  	return nil
 180  }
 181  
 182  // MonitorInterface is fake implementation
 183  func (o *LoadBalancerOp) MonitorInterface(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.InterfaceActivity, error) {
 184  	_, err := o.Read(ctx, zone, id)
 185  	if err != nil {
 186  		return nil, err
 187  	}
 188  
 189  	now := time.Now().Truncate(time.Second)
 190  	m := now.Minute() % 5
 191  	if m != 0 {
 192  		now.Add(time.Duration(m) * time.Minute)
 193  	}
 194  
 195  	res := &iaas.InterfaceActivity{}
 196  	for i := 0; i < 5; i++ {
 197  		res.Values = append(res.Values, &iaas.MonitorInterfaceValue{
 198  			Time:    now.Add(time.Duration(i*-5) * time.Minute),
 199  			Send:    float64(random(1000)),
 200  			Receive: float64(random(1000)),
 201  		})
 202  	}
 203  
 204  	return res, nil
 205  }
 206  
 207  // Status is fake implementation
 208  func (o *LoadBalancerOp) Status(ctx context.Context, zone string, id types.ID) (*iaas.LoadBalancerStatusResult, error) {
 209  	value, err := o.Read(ctx, zone, id)
 210  	if err != nil {
 211  		return nil, err
 212  	}
 213  
 214  	var results []*iaas.LoadBalancerStatus
 215  	for _, vip := range value.VirtualIPAddresses {
 216  		status := &iaas.LoadBalancerStatus{
 217  			VirtualIPAddress: vip.VirtualIPAddress,
 218  			Port:             vip.Port,
 219  			CPS:              types.StringNumber(random(100)),
 220  		}
 221  		var servers []*iaas.LoadBalancerServerStatus
 222  		for _, server := range vip.Servers {
 223  			servers = append(servers, &iaas.LoadBalancerServerStatus{
 224  				ActiveConn: types.StringNumber(random(10)),
 225  				Status:     types.ServerInstanceStatuses.Up,
 226  				IPAddress:  server.IPAddress,
 227  				Port:       server.Port,
 228  				CPS:        types.StringNumber(random(100)),
 229  			})
 230  		}
 231  		status.Servers = servers
 232  
 233  		results = append(results, status)
 234  	}
 235  
 236  	return &iaas.LoadBalancerStatusResult{
 237  		Status: results,
 238  	}, nil
 239  }
 240  
 241  // MonitorCPU is fake implementation
 242  func (o *LoadBalancerOp) MonitorCPU(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.CPUTimeActivity, error) {
 243  	_, err := o.Read(ctx, zone, id)
 244  	if err != nil {
 245  		return nil, err
 246  	}
 247  
 248  	now := time.Now().Truncate(time.Second)
 249  	m := now.Minute() % 5
 250  	if m != 0 {
 251  		now.Add(time.Duration(m) * time.Minute)
 252  	}
 253  
 254  	res := &iaas.CPUTimeActivity{}
 255  	for i := 0; i < 5; i++ {
 256  		res.Values = append(res.Values, &iaas.MonitorCPUTimeValue{
 257  			Time:    now.Add(time.Duration(i*-5) * time.Minute),
 258  			CPUTime: float64(random(1000)),
 259  		})
 260  	}
 261  
 262  	return res, nil
 263  }
 264