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  }