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