github.com/sacloud/iaas-api-go@v1.12.0/fake/ops_vpc_router.go (about) 1 // Copyright 2022-2023 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 "net" 21 "time" 22 23 "github.com/sacloud/iaas-api-go" 24 "github.com/sacloud/iaas-api-go/types" 25 ) 26 27 // Find is fake implementation 28 func (o *VPCRouterOp) Find(ctx context.Context, zone string, conditions *iaas.FindCondition) (*iaas.VPCRouterFindResult, error) { 29 results, _ := find(o.key, zone, conditions) 30 var values []*iaas.VPCRouter 31 for _, res := range results { 32 dest := &iaas.VPCRouter{} 33 copySameNameField(res, dest) 34 values = append(values, dest) 35 } 36 return &iaas.VPCRouterFindResult{ 37 Total: len(results), 38 Count: len(results), 39 From: 0, 40 VPCRouters: values, 41 }, nil 42 } 43 44 // Create is fake implementation 45 func (o *VPCRouterOp) Create(ctx context.Context, zone string, param *iaas.VPCRouterCreateRequest) (*iaas.VPCRouter, error) { 46 result := &iaas.VPCRouter{} 47 copySameNameField(param, result) 48 fill(result, fillID, fillCreatedAt) 49 50 result.Class = "vpcrouter" 51 result.Availability = types.Availabilities.Migrating 52 result.ZoneID = zoneIDs[zone] 53 result.SettingsHash = "" 54 if result.Version == 0 { 55 result.Version = 2 56 } 57 58 ifOp := NewInterfaceOp() 59 swOp := NewSwitchOp() 60 61 ifCreateParam := &iaas.InterfaceCreateRequest{} 62 if param.Switch.Scope == types.Scopes.Shared { 63 ifCreateParam.ServerID = result.ID 64 } else { 65 _, err := swOp.Read(ctx, zone, param.Switch.ID) 66 if err != nil { 67 return nil, newErrorConflict(o.key, types.ID(0), err.Error()) 68 } 69 } 70 71 iface, err := ifOp.Create(ctx, zone, ifCreateParam) 72 if err != nil { 73 return nil, newErrorConflict(o.key, types.ID(0), err.Error()) 74 } 75 76 if param.Switch.Scope == types.Scopes.Shared { 77 if err := ifOp.ConnectToSharedSegment(ctx, zone, iface.ID); err != nil { 78 return nil, newErrorConflict(o.key, types.ID(0), err.Error()) 79 } 80 } else { 81 if err := ifOp.ConnectToSwitch(ctx, zone, iface.ID, param.Switch.ID); err != nil { 82 return nil, newErrorConflict(o.key, types.ID(0), err.Error()) 83 } 84 } 85 86 iface, err = ifOp.Read(ctx, zone, iface.ID) 87 if err != nil { 88 return nil, newErrorConflict(o.key, types.ID(0), err.Error()) 89 } 90 91 vpcRouterInterface := &iaas.VPCRouterInterface{} 92 copySameNameField(iface, vpcRouterInterface) 93 if param.Switch.Scope == types.Scopes.Shared { 94 sharedIP := pool().nextSharedIP() 95 vpcRouterInterface.IPAddress = sharedIP.String() 96 vpcRouterInterface.SubnetNetworkMaskLen = sharedSegmentSwitch.NetworkMaskLen 97 98 ipv4Mask := net.CIDRMask(pool().SharedNetMaskLen, 32) 99 vpcRouterInterface.SubnetNetworkAddress = sharedIP.Mask(ipv4Mask).String() 100 vpcRouterInterface.SubnetDefaultRoute = pool().SharedDefaultGateway.String() 101 } 102 result.Interfaces = append(result.Interfaces, vpcRouterInterface) 103 104 putVPCRouter(zone, result) 105 106 id := result.ID 107 startMigration(o.key, zone, func() (interface{}, error) { 108 return o.Read(context.Background(), zone, id) 109 }) 110 return result, nil 111 } 112 113 // Read is fake implementation 114 func (o *VPCRouterOp) Read(ctx context.Context, zone string, id types.ID) (*iaas.VPCRouter, error) { 115 value := getVPCRouterByID(zone, id) 116 if value == nil { 117 return nil, newErrorNotFound(o.key, id) 118 } 119 dest := &iaas.VPCRouter{} 120 copySameNameField(value, dest) 121 return dest, nil 122 } 123 124 // Update is fake implementation 125 func (o *VPCRouterOp) Update(ctx context.Context, zone string, id types.ID, param *iaas.VPCRouterUpdateRequest) (*iaas.VPCRouter, error) { 126 value, err := o.Read(ctx, zone, id) 127 if err != nil { 128 return nil, err 129 } 130 copySameNameField(param, value) 131 fill(value, fillModifiedAt) 132 133 putVPCRouter(zone, value) 134 return value, nil 135 } 136 137 // UpdateSettings is fake implementation 138 func (o *VPCRouterOp) UpdateSettings(ctx context.Context, zone string, id types.ID, param *iaas.VPCRouterUpdateSettingsRequest) (*iaas.VPCRouter, error) { 139 value, err := o.Read(ctx, zone, id) 140 if err != nil { 141 return nil, err 142 } 143 copySameNameField(param, value) 144 fill(value, fillModifiedAt) 145 146 putVPCRouter(zone, value) 147 return value, nil 148 } 149 150 // Delete is fake implementation 151 func (o *VPCRouterOp) Delete(ctx context.Context, zone string, id types.ID) error { 152 _, err := o.Read(ctx, zone, id) 153 if err != nil { 154 return err 155 } 156 ds().Delete(o.key, zone, id) 157 return nil 158 } 159 160 // Config is fake implementation 161 func (o *VPCRouterOp) Config(ctx context.Context, zone string, id types.ID) error { 162 return nil 163 } 164 165 // Boot is fake implementation 166 func (o *VPCRouterOp) Boot(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, "Boot is failed") 173 } 174 175 startPowerOn(o.key, zone, func() (interface{}, error) { 176 return o.Read(context.Background(), zone, id) 177 }) 178 179 return err 180 } 181 182 // Shutdown is fake implementation 183 func (o *VPCRouterOp) Shutdown(ctx context.Context, zone string, id types.ID, shutdownOption *iaas.ShutdownOption) error { 184 value, err := o.Read(ctx, zone, id) 185 if err != nil { 186 return err 187 } 188 if !value.InstanceStatus.IsUp() { 189 return newErrorConflict(o.key, id, "Shutdown is failed") 190 } 191 192 startPowerOff(o.key, zone, func() (interface{}, error) { 193 return o.Read(context.Background(), zone, id) 194 }) 195 196 return err 197 } 198 199 // Reset is fake implementation 200 func (o *VPCRouterOp) Reset(ctx context.Context, zone string, id types.ID) error { 201 value, err := o.Read(ctx, zone, id) 202 if err != nil { 203 return err 204 } 205 if !value.InstanceStatus.IsUp() { 206 return newErrorConflict(o.key, id, "Reset is failed") 207 } 208 209 startPowerOn(o.key, zone, func() (interface{}, error) { 210 return o.Read(context.Background(), zone, id) 211 }) 212 213 return nil 214 } 215 216 // ConnectToSwitch is fake implementation 217 func (o *VPCRouterOp) ConnectToSwitch(ctx context.Context, zone string, id types.ID, nicIndex int, switchID types.ID) error { 218 value, err := o.Read(ctx, zone, id) 219 if err != nil { 220 return err 221 } 222 223 for _, nic := range value.Interfaces { 224 if nic.Index == nicIndex { 225 return newErrorBadRequest(o.key, id, fmt.Sprintf("nic[%d] already connected to switch", nicIndex)) 226 } 227 } 228 229 // find switch 230 swOp := NewSwitchOp() 231 _, err = swOp.Read(ctx, zone, switchID) 232 if err != nil { 233 return fmt.Errorf("ConnectToSwitch is failed: %s", err) 234 } 235 236 // create interface 237 ifOp := NewInterfaceOp() 238 iface, err := ifOp.Create(ctx, zone, &iaas.InterfaceCreateRequest{ServerID: id}) 239 if err != nil { 240 return newErrorConflict(o.key, types.ID(0), err.Error()) 241 } 242 243 if err := ifOp.ConnectToSwitch(ctx, zone, iface.ID, switchID); err != nil { 244 return newErrorConflict(o.key, types.ID(0), err.Error()) 245 } 246 247 iface, err = ifOp.Read(ctx, zone, iface.ID) 248 if err != nil { 249 return newErrorConflict(o.key, types.ID(0), err.Error()) 250 } 251 252 vpcRouterInterface := &iaas.VPCRouterInterface{} 253 copySameNameField(iface, vpcRouterInterface) 254 vpcRouterInterface.Index = nicIndex 255 value.Interfaces = append(value.Interfaces, vpcRouterInterface) 256 257 putVPCRouter(zone, value) 258 return nil 259 } 260 261 // DisconnectFromSwitch is fake implementation 262 func (o *VPCRouterOp) DisconnectFromSwitch(ctx context.Context, zone string, id types.ID, nicIndex int) error { 263 value, err := o.Read(ctx, zone, id) 264 if err != nil { 265 return err 266 } 267 268 var exists bool 269 var nicID types.ID 270 var interfaces []*iaas.VPCRouterInterface 271 272 for _, nic := range value.Interfaces { 273 if nic.Index == nicIndex { 274 exists = true 275 nicID = nic.ID 276 } else { 277 interfaces = append(interfaces, nic) 278 } 279 } 280 if !exists { 281 return newErrorBadRequest(o.key, id, fmt.Sprintf("nic[%d] is not exists", nicIndex)) 282 } 283 284 ifOp := NewInterfaceOp() 285 if err := ifOp.DisconnectFromSwitch(ctx, zone, nicID); err != nil { 286 return newErrorConflict(o.key, types.ID(0), err.Error()) 287 } 288 289 value.Interfaces = interfaces 290 putVPCRouter(zone, value) 291 return nil 292 } 293 294 // MonitorInterface is fake implementation 295 func (o *VPCRouterOp) MonitorInterface(ctx context.Context, zone string, id types.ID, index int, condition *iaas.MonitorCondition) (*iaas.InterfaceActivity, error) { 296 _, err := o.Read(ctx, zone, id) 297 if err != nil { 298 return nil, err 299 } 300 301 now := time.Now().Truncate(time.Second) 302 m := now.Minute() % 5 303 if m != 0 { 304 now.Add(time.Duration(m) * time.Minute) 305 } 306 307 res := &iaas.InterfaceActivity{} 308 for i := 0; i < 5; i++ { 309 res.Values = append(res.Values, &iaas.MonitorInterfaceValue{ 310 Time: now.Add(time.Duration(i*-5) * time.Minute), 311 Send: float64(random(1000)), 312 Receive: float64(random(1000)), 313 }) 314 } 315 316 return res, nil 317 } 318 319 // Status is fake implementation 320 func (o *VPCRouterOp) Status(ctx context.Context, zone string, id types.ID) (*iaas.VPCRouterStatus, error) { 321 v, err := o.Read(ctx, zone, id) 322 if err != nil { 323 return nil, err 324 } 325 326 if v.InstanceStatus.IsUp() && v.Settings.WireGuardEnabled.Bool() { 327 return &iaas.VPCRouterStatus{ 328 WireGuard: &iaas.WireGuardStatus{ 329 PublicKey: "fake-public-key", 330 }, 331 SessionAnalysis: &iaas.VPCRouterSessionAnalysis{ 332 SourceAndDestination: []*iaas.VPCRouterStatisticsValue{ 333 {Name: "UDP src:127.0.0.1 dst:127.0.0.1:53", Count: 1}, 334 }, 335 DestinationAddress: []*iaas.VPCRouterStatisticsValue{ 336 {Name: "127.0.0.1", Count: 1}, 337 }, 338 DestinationPort: []*iaas.VPCRouterStatisticsValue{ 339 {Name: "UDP:53", Count: 1}, 340 }, 341 SourceAddress: []*iaas.VPCRouterStatisticsValue{ 342 {Name: "127.0.0.1", Count: 1}, 343 }, 344 }, 345 }, nil 346 } 347 return &iaas.VPCRouterStatus{}, nil 348 } 349 350 // MonitorCPU is fake implementation 351 func (o *VPCRouterOp) MonitorCPU(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.CPUTimeActivity, error) { 352 _, err := o.Read(ctx, zone, id) 353 if err != nil { 354 return nil, err 355 } 356 357 now := time.Now().Truncate(time.Second) 358 m := now.Minute() % 5 359 if m != 0 { 360 now.Add(time.Duration(m) * time.Minute) 361 } 362 363 res := &iaas.CPUTimeActivity{} 364 for i := 0; i < 5; i++ { 365 res.Values = append(res.Values, &iaas.MonitorCPUTimeValue{ 366 Time: now.Add(time.Duration(i*-5) * time.Minute), 367 CPUTime: float64(random(1000)), 368 }) 369 } 370 371 return res, nil 372 } 373 374 // Logs is fake implementation 375 func (o *VPCRouterOp) Logs(ctx context.Context, zone string, id types.ID) (*iaas.VPCRouterLog, error) { 376 return &iaas.VPCRouterLog{Log: "fake"}, nil 377 } 378 379 func (o *VPCRouterOp) Ping(ctx context.Context, zone string, id types.ID, destination string) (*iaas.VPCRouterPingResults, error) { 380 return &iaas.VPCRouterPingResults{Result: []string{"fake"}}, nil 381 }