github.com/sacloud/iaas-api-go@v1.12.0/fake/ops_interface.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 "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 *InterfaceOp) Find(ctx context.Context, zone string, conditions *iaas.FindCondition) (*iaas.InterfaceFindResult, error) { 28 results, _ := find(o.key, zone, conditions) 29 var values []*iaas.Interface 30 for _, res := range results { 31 dest := &iaas.Interface{} 32 copySameNameField(res, dest) 33 values = append(values, dest) 34 } 35 return &iaas.InterfaceFindResult{ 36 Total: len(results), 37 Count: len(results), 38 From: 0, 39 Interfaces: values, 40 }, nil 41 } 42 43 // Create is fake implementation 44 func (o *InterfaceOp) Create(ctx context.Context, zone string, param *iaas.InterfaceCreateRequest) (*iaas.Interface, error) { 45 result := &iaas.Interface{} 46 copySameNameField(param, result) 47 fill(result, fillID, fillCreatedAt) 48 49 result.MACAddress = pool().nextMACAddress().String() 50 51 // connect to server 52 if param != nil && !param.ServerID.IsEmpty() { 53 serverOp := NewServerOp() 54 server, err := serverOp.Read(ctx, zone, param.ServerID) 55 if err == nil { 56 ifaceView := &iaas.InterfaceView{} 57 copySameNameField(result, ifaceView) 58 server.Interfaces = append(server.Interfaces, ifaceView) 59 putServer(zone, server) 60 } 61 } 62 63 putInterface(zone, result) 64 return result, nil 65 } 66 67 // Read is fake implementation 68 func (o *InterfaceOp) Read(ctx context.Context, zone string, id types.ID) (*iaas.Interface, error) { 69 value := getInterfaceByID(zone, id) 70 if value == nil { 71 return nil, newErrorNotFound(o.key, id) 72 } 73 74 dest := &iaas.Interface{} 75 copySameNameField(value, dest) 76 return dest, nil 77 } 78 79 // Update is fake implementation 80 func (o *InterfaceOp) Update(ctx context.Context, zone string, id types.ID, param *iaas.InterfaceUpdateRequest) (*iaas.Interface, 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 89 serverOp := NewServerOp() 90 searched, err := serverOp.Find(ctx, zone, nil) 91 if err == nil { 92 for _, server := range searched.Servers { 93 for _, iface := range server.Interfaces { 94 if iface.ID == id { 95 iface.UserIPAddress = param.UserIPAddress 96 putServer(zone, server) 97 } 98 } 99 } 100 } 101 102 putInterface(zone, value) 103 return value, nil 104 } 105 106 // Delete is fake implementation 107 func (o *InterfaceOp) Delete(ctx context.Context, zone string, id types.ID) error { 108 value, err := o.Read(ctx, zone, id) 109 if err != nil { 110 return err 111 } 112 ds().Delete(o.key, zone, id) 113 114 if !value.ServerID.IsEmpty() { 115 server, err := NewServerOp().Read(ctx, zone, value.ServerID) 116 if err == nil { 117 var deleted []*iaas.InterfaceView 118 for _, iface := range server.Interfaces { 119 if iface.ID != id { 120 deleted = append(deleted, iface) 121 } 122 } 123 server.Interfaces = deleted 124 putServer(zone, server) 125 } 126 } 127 128 return nil 129 } 130 131 // Monitor is fake implementation 132 func (o *InterfaceOp) Monitor(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.InterfaceActivity, error) { 133 _, err := o.Read(ctx, zone, id) 134 if err != nil { 135 return nil, err 136 } 137 138 now := time.Now().Truncate(time.Second) 139 m := now.Minute() % 5 140 if m != 0 { 141 now.Add(time.Duration(m) * time.Minute) 142 } 143 144 res := &iaas.InterfaceActivity{} 145 for i := 0; i < 5; i++ { 146 res.Values = append(res.Values, &iaas.MonitorInterfaceValue{ 147 Time: now.Add(time.Duration(i*-5) * time.Minute), 148 Send: float64(random(1000)), 149 Receive: float64(random(1000)), 150 }) 151 } 152 153 return res, nil 154 } 155 156 // ConnectToSharedSegment is fake implementation 157 func (o *InterfaceOp) ConnectToSharedSegment(ctx context.Context, zone string, id types.ID) error { 158 value, err := o.Read(ctx, zone, id) 159 if err != nil { 160 return err 161 } 162 163 if !value.SwitchID.IsEmpty() { 164 return newErrorConflict(o.key, id, 165 fmt.Sprintf("Interface[%d] is already connected to switch[%d]", value.ID, value.SwitchID)) 166 } 167 168 value.SwitchID = sharedSegmentSwitch.ID 169 putInterface(zone, value) 170 171 if !value.ServerID.IsEmpty() { 172 server, err := NewServerOp().Read(ctx, zone, value.ServerID) 173 if err == nil { 174 for _, iface := range server.Interfaces { 175 if iface.ID == id { 176 iface.SwitchScope = types.Scopes.Shared 177 iface.SwitchID = sharedSegmentSwitch.ID 178 iface.SwitchName = sharedSegmentSwitch.Name 179 } 180 } 181 putServer(zone, server) 182 } 183 } 184 185 return nil 186 } 187 188 // ConnectToSwitch is fake implementation 189 func (o *InterfaceOp) ConnectToSwitch(ctx context.Context, zone string, id types.ID, switchID types.ID) error { 190 value, err := o.Read(ctx, zone, id) 191 if err != nil { 192 return err 193 } 194 if !value.SwitchID.IsEmpty() { 195 return newErrorConflict(o.key, id, 196 fmt.Sprintf("Interface[%d] is already connected to switch[%d]", value.ID, switchID)) 197 } 198 199 sw, err := NewSwitchOp().Read(ctx, zone, switchID) 200 if err != nil { 201 return err 202 } 203 sw.ServerCount++ 204 putSwitch(zone, sw) 205 206 value.SwitchID = switchID 207 putInterface(zone, value) 208 209 if !value.ServerID.IsEmpty() { 210 server, err := NewServerOp().Read(ctx, zone, value.ServerID) 211 if err == nil { 212 for _, iface := range server.Interfaces { 213 if iface.ID == id { 214 iface.SwitchScope = types.Scopes.User 215 iface.SwitchID = sw.ID 216 iface.SwitchName = sw.Name 217 } 218 } 219 putServer(zone, server) 220 } 221 } 222 223 return nil 224 } 225 226 // DisconnectFromSwitch is fake implementation 227 func (o *InterfaceOp) DisconnectFromSwitch(ctx context.Context, zone string, id types.ID) error { 228 value, err := o.Read(ctx, zone, id) 229 if err != nil { 230 return err 231 } 232 if value.SwitchID.IsEmpty() { 233 return newErrorConflict(o.key, id, 234 fmt.Sprintf("Interface[%d] is already disconnected", value.ID)) 235 } 236 237 value.SwitchID = types.ID(0) 238 putInterface(zone, value) 239 240 if !value.ServerID.IsEmpty() { 241 server, err := NewServerOp().Read(ctx, zone, value.ServerID) 242 if err == nil { 243 for _, iface := range server.Interfaces { 244 if iface.ID == id { 245 iface.SwitchScope = types.EScope("") 246 iface.SwitchID = types.ID(0) 247 iface.SwitchName = "" 248 } 249 } 250 putServer(zone, server) 251 } 252 } 253 return nil 254 } 255 256 // ConnectToPacketFilter is fake implementation 257 func (o *InterfaceOp) ConnectToPacketFilter(ctx context.Context, zone string, id types.ID, packetFilterID types.ID) error { 258 value, err := o.Read(ctx, zone, id) 259 if err != nil { 260 return err 261 } 262 if !value.PacketFilterID.IsEmpty() { 263 return newErrorConflict(o.key, id, 264 fmt.Sprintf("Interface[%d] is already connected to packetfilter[%s]", value.ID, value.PacketFilterID)) 265 } 266 267 value.PacketFilterID = packetFilterID 268 putInterface(zone, value) 269 270 // server配下のInterfaceの修正 271 searched, err := NewServerOp().Find(ctx, zone, nil) 272 if err != nil { 273 return err 274 } 275 for _, server := range searched.Servers { 276 upd := false 277 for _, nic := range server.Interfaces { 278 if nic.ID == id { 279 nic.PacketFilterID = packetFilterID 280 upd = true 281 } 282 } 283 if upd { 284 putServer(zone, server) 285 } 286 } 287 288 return nil 289 } 290 291 // DisconnectFromPacketFilter is fake implementation 292 func (o *InterfaceOp) DisconnectFromPacketFilter(ctx context.Context, zone string, id types.ID) error { 293 value, err := o.Read(ctx, zone, id) 294 if err != nil { 295 return err 296 } 297 if value.PacketFilterID.IsEmpty() { 298 return newErrorConflict(o.key, id, 299 fmt.Sprintf("Interface[%d] is already disconnected", value.ID)) 300 } 301 302 value.PacketFilterID = types.ID(0) 303 putInterface(zone, value) 304 305 // server配下のInterfaceの修正 306 searched, err := NewServerOp().Find(ctx, zone, nil) 307 if err != nil { 308 return err 309 } 310 for _, server := range searched.Servers { 311 upd := false 312 for _, nic := range server.Interfaces { 313 if nic.ID == id { 314 nic.PacketFilterID = types.ID(0) 315 upd = true 316 } 317 } 318 if upd { 319 putServer(zone, server) 320 } 321 } 322 return nil 323 }