github.com/sacloud/iaas-api-go@v1.12.0/fake/ops_internet.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  	"net"
    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 *InternetOp) Find(ctx context.Context, zone string, conditions *iaas.FindCondition) (*iaas.InternetFindResult, error) {
    28  	results, _ := find(o.key, zone, conditions)
    29  	var values []*iaas.Internet
    30  	for _, res := range results {
    31  		dest := &iaas.Internet{}
    32  		copySameNameField(res, dest)
    33  		values = append(values, dest)
    34  	}
    35  	return &iaas.InternetFindResult{
    36  		Total:    len(results),
    37  		Count:    len(results),
    38  		From:     0,
    39  		Internet: values,
    40  	}, nil
    41  }
    42  
    43  // Create is fake implementation
    44  func (o *InternetOp) Create(ctx context.Context, zone string, param *iaas.InternetCreateRequest) (*iaas.Internet, error) {
    45  	if param.NetworkMaskLen == 0 {
    46  		param.NetworkMaskLen = 28
    47  	}
    48  	if param.BandWidthMbps == 0 {
    49  		param.BandWidthMbps = 100
    50  	}
    51  
    52  	result := &iaas.Internet{}
    53  	copySameNameField(param, result)
    54  	fill(result, fillID, fillCreatedAt)
    55  
    56  	// assign global address
    57  	subnet := pool().nextSubnet(result.NetworkMaskLen)
    58  
    59  	// create switch
    60  	swOp := NewSwitchOp()
    61  	sw, err := swOp.Create(ctx, zone, &iaas.SwitchCreateRequest{
    62  		Name:           result.Name,
    63  		NetworkMaskLen: subnet.networkMaskLen,
    64  		DefaultRoute:   subnet.defaultRoute,
    65  	})
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	sSubnet := &iaas.SwitchSubnet{
    71  		ID:                   pool().generateID(),
    72  		DefaultRoute:         subnet.defaultRoute,
    73  		NetworkAddress:       subnet.networkAddress,
    74  		NetworkMaskLen:       subnet.networkMaskLen,
    75  		Internet:             result,
    76  		AssignedIPAddressMax: subnet.addresses[len(subnet.addresses)-1],
    77  		AssignedIPAddressMin: subnet.addresses[0],
    78  	}
    79  	sw.Subnets = append(sw.Subnets, sSubnet)
    80  
    81  	// for Internet.Switch
    82  	switchInfo := &iaas.SwitchInfo{}
    83  	copySameNameField(sw, switchInfo)
    84  
    85  	iSubnet := &iaas.InternetSubnet{
    86  		ID:             sSubnet.ID,
    87  		DefaultRoute:   sSubnet.DefaultRoute,
    88  		NetworkAddress: sSubnet.NetworkAddress,
    89  		NetworkMaskLen: sSubnet.NetworkMaskLen,
    90  	}
    91  	switchInfo.Subnets = []*iaas.InternetSubnet{iSubnet}
    92  	result.Switch = switchInfo
    93  
    94  	// for raw subnet
    95  	rSubnet := &iaas.Subnet{}
    96  	copySameNameField(sSubnet, rSubnet)
    97  	for _, ip := range subnet.addresses {
    98  		rSubnet.IPAddresses = append(rSubnet.IPAddresses, &iaas.SubnetIPAddress{IPAddress: ip})
    99  	}
   100  	rSubnet.SwitchID = sw.ID
   101  	rSubnet.InternetID = result.ID
   102  
   103  	putSwitch(zone, sw)
   104  	putInternet(zone, result)
   105  	putSubnet(zone, rSubnet)
   106  	return result, nil
   107  }
   108  
   109  // Read is fake implementation
   110  func (o *InternetOp) Read(ctx context.Context, zone string, id types.ID) (*iaas.Internet, error) {
   111  	value := getInternetByID(zone, id)
   112  	if value == nil {
   113  		return nil, newErrorNotFound(o.key, id)
   114  	}
   115  	dest := &iaas.Internet{}
   116  	copySameNameField(value, dest)
   117  	return dest, nil
   118  }
   119  
   120  // Update is fake implementation
   121  func (o *InternetOp) Update(ctx context.Context, zone string, id types.ID, param *iaas.InternetUpdateRequest) (*iaas.Internet, error) {
   122  	value, err := o.Read(ctx, zone, id)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	copySameNameField(param, value)
   127  
   128  	putInternet(zone, value)
   129  	return value, nil
   130  }
   131  
   132  // Delete is fake implementation
   133  func (o *InternetOp) Delete(ctx context.Context, zone string, id types.ID) error {
   134  	value, err := o.Read(ctx, zone, id)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	// check subnets/ipv6nets
   140  	if len(value.Switch.Subnets) > 1 {
   141  		return newErrorBadRequest(ResourceInternet, value.ID, "Internet resource still have Subnets")
   142  	}
   143  	if len(value.Switch.IPv6Nets) > 1 {
   144  		return newErrorBadRequest(ResourceInternet, value.ID, "Internet resource still have Subnets")
   145  	}
   146  
   147  	swOp := NewSwitchOp()
   148  	if err := swOp.Delete(ctx, zone, value.Switch.ID); err != nil {
   149  		return err
   150  	}
   151  
   152  	ds().Delete(o.key, zone, id)
   153  	return nil
   154  }
   155  
   156  // UpdateBandWidth is fake implementation
   157  func (o *InternetOp) UpdateBandWidth(ctx context.Context, zone string, id types.ID, param *iaas.InternetUpdateBandWidthRequest) (*iaas.Internet, error) {
   158  	value, err := o.Read(ctx, zone, id)
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	value.BandWidthMbps = param.BandWidthMbps
   164  	putInternet(zone, value)
   165  	return value, nil
   166  }
   167  
   168  // AddSubnet is fake implementation
   169  func (o *InternetOp) AddSubnet(ctx context.Context, zone string, id types.ID, param *iaas.InternetAddSubnetRequest) (*iaas.InternetSubnetOperationResult, error) {
   170  	value, err := o.Read(ctx, zone, id)
   171  	if err != nil {
   172  		return nil, err
   173  	}
   174  
   175  	// assign global address
   176  	subnet := pool().nextSubnetFull(param.NetworkMaskLen, param.NextHop)
   177  
   178  	// create switch
   179  	swOp := NewSwitchOp()
   180  	sw, err := swOp.Read(ctx, zone, value.Switch.ID)
   181  	if err != nil {
   182  		return nil, err
   183  	}
   184  
   185  	sSubnet := &iaas.SwitchSubnet{
   186  		ID:                   pool().generateID(),
   187  		NetworkAddress:       subnet.networkAddress,
   188  		NetworkMaskLen:       subnet.networkMaskLen,
   189  		NextHop:              param.NextHop,
   190  		StaticRoute:          param.NextHop,
   191  		Internet:             value,
   192  		AssignedIPAddressMax: subnet.addresses[len(subnet.addresses)-1],
   193  		AssignedIPAddressMin: subnet.addresses[0],
   194  	}
   195  	sw.Subnets = append(sw.Subnets, sSubnet)
   196  
   197  	// for Internet.Switch
   198  	iSubnet := &iaas.InternetSubnet{
   199  		ID:             sSubnet.ID,
   200  		DefaultRoute:   sSubnet.DefaultRoute,
   201  		NetworkAddress: sSubnet.NetworkAddress,
   202  		NetworkMaskLen: sSubnet.NetworkMaskLen,
   203  		NextHop:        param.NextHop,
   204  		StaticRoute:    param.NextHop,
   205  	}
   206  	value.Switch.Subnets = append(value.Switch.Subnets, iSubnet)
   207  
   208  	// for raw subnet
   209  	rSubnet := &iaas.Subnet{}
   210  	copySameNameField(sSubnet, rSubnet)
   211  	for _, ip := range subnet.addresses {
   212  		rSubnet.IPAddresses = append(rSubnet.IPAddresses, &iaas.SubnetIPAddress{IPAddress: ip})
   213  	}
   214  	rSubnet.SwitchID = sw.ID
   215  	rSubnet.InternetID = value.ID
   216  
   217  	putSwitch(zone, sw)
   218  	putInternet(zone, value)
   219  	putSubnet(zone, rSubnet)
   220  
   221  	return &iaas.InternetSubnetOperationResult{
   222  		ID:             sSubnet.ID,
   223  		NextHop:        param.NextHop,
   224  		StaticRoute:    param.NextHop,
   225  		NetworkMaskLen: sSubnet.NetworkMaskLen,
   226  		NetworkAddress: sSubnet.NetworkAddress,
   227  		IPAddresses:    subnet.addresses,
   228  	}, nil
   229  }
   230  
   231  // UpdateSubnet is fake implementation
   232  func (o *InternetOp) UpdateSubnet(ctx context.Context, zone string, id types.ID, subnetID types.ID, param *iaas.InternetUpdateSubnetRequest) (*iaas.InternetSubnetOperationResult, error) {
   233  	value, err := o.Read(ctx, zone, id)
   234  	if err != nil {
   235  		return nil, err
   236  	}
   237  	// create switch
   238  	swOp := NewSwitchOp()
   239  	sw, err := swOp.Read(ctx, zone, value.Switch.ID)
   240  	if err != nil {
   241  		return nil, err
   242  	}
   243  
   244  	rSubnet, err := NewSubnetOp().Read(ctx, zone, subnetID)
   245  	if err != nil {
   246  		return nil, err
   247  	}
   248  
   249  	rSubnet.NextHop = param.NextHop
   250  
   251  	var nwMaskLen int
   252  	var nwAddress, minAddr, maxAddr string
   253  	var addresses []string
   254  
   255  	for _, subnet := range sw.Subnets {
   256  		if subnet.ID == subnetID {
   257  			subnet.NextHop = param.NextHop
   258  			subnet.StaticRoute = param.NextHop
   259  
   260  			minAddr = subnet.AssignedIPAddressMin
   261  			maxAddr = subnet.AssignedIPAddressMax
   262  			nwMaskLen = subnet.NetworkMaskLen
   263  			nwAddress = subnet.NetworkAddress
   264  		}
   265  	}
   266  
   267  	for _, subnet := range value.Switch.Subnets {
   268  		if subnet.ID == subnetID {
   269  			subnet.NextHop = param.NextHop
   270  			subnet.StaticRoute = param.NextHop
   271  		}
   272  	}
   273  
   274  	baseIP := net.ParseIP(minAddr).To4()
   275  	min := baseIP[3]
   276  	max := net.ParseIP(maxAddr).To4()[3]
   277  
   278  	var i byte
   279  	for (min + i) <= max { // 境界含む
   280  		ip := net.IPv4(baseIP[0], baseIP[1], baseIP[2], baseIP[3]+i)
   281  		addresses = append(addresses, ip.String())
   282  		i++
   283  	}
   284  
   285  	putSubnet(zone, rSubnet)
   286  	putSwitch(zone, sw)
   287  	putInternet(zone, value)
   288  	return &iaas.InternetSubnetOperationResult{
   289  		ID:             subnetID,
   290  		NextHop:        param.NextHop,
   291  		StaticRoute:    param.NextHop,
   292  		NetworkMaskLen: nwMaskLen,
   293  		NetworkAddress: nwAddress,
   294  		IPAddresses:    addresses,
   295  	}, nil
   296  }
   297  
   298  // DeleteSubnet is fake implementation
   299  func (o *InternetOp) DeleteSubnet(ctx context.Context, zone string, id types.ID, subnetID types.ID) error {
   300  	value, err := o.Read(ctx, zone, id)
   301  	if err != nil {
   302  		return err
   303  	}
   304  
   305  	// create switch
   306  	swOp := NewSwitchOp()
   307  	sw, err := swOp.Read(ctx, zone, value.Switch.ID)
   308  	if err != nil {
   309  		return err
   310  	}
   311  
   312  	var sSubnets []*iaas.SwitchSubnet
   313  	for _, subnet := range sw.Subnets {
   314  		if subnet.ID != subnetID {
   315  			sSubnets = append(sSubnets, subnet)
   316  		}
   317  	}
   318  	sw.Subnets = sSubnets
   319  
   320  	var iSubnets []*iaas.InternetSubnet
   321  	for _, subnet := range value.Switch.Subnets {
   322  		if subnet.ID != subnetID {
   323  			iSubnets = append(iSubnets, subnet)
   324  		}
   325  	}
   326  	value.Switch.Subnets = iSubnets
   327  
   328  	ds().Delete(ResourceSubnet, zone, subnetID)
   329  	putSwitch(zone, sw)
   330  	putInternet(zone, value)
   331  	return nil
   332  }
   333  
   334  // Monitor is fake implementation
   335  func (o *InternetOp) Monitor(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.RouterActivity, error) {
   336  	_, err := o.Read(ctx, zone, id)
   337  	if err != nil {
   338  		return nil, err
   339  	}
   340  
   341  	now := time.Now().Truncate(time.Second)
   342  	m := now.Minute() % 5
   343  	if m != 0 {
   344  		now.Add(time.Duration(m) * time.Minute)
   345  	}
   346  
   347  	res := &iaas.RouterActivity{}
   348  	for i := 0; i < 5; i++ {
   349  		res.Values = append(res.Values, &iaas.MonitorRouterValue{
   350  			Time: now.Add(time.Duration(i*-5) * time.Minute),
   351  			In:   float64(random(1000)),
   352  			Out:  float64(random(1000)),
   353  		})
   354  	}
   355  
   356  	return res, nil
   357  }
   358  
   359  // MonitorRouter is fake implementation
   360  func (o *InternetOp) MonitorRouter(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.RouterActivity, error) {
   361  	return o.Monitor(ctx, zone, id, condition)
   362  }
   363  
   364  // EnableIPv6 is fake implementation
   365  func (o *InternetOp) EnableIPv6(ctx context.Context, zone string, id types.ID) (*iaas.IPv6NetInfo, error) {
   366  	value, err := o.Read(ctx, zone, id)
   367  	if err != nil {
   368  		return nil, err
   369  	}
   370  
   371  	ipv6net := &iaas.IPv6Net{
   372  		ID:            pool().generateID(),
   373  		IPv6Prefix:    "2001:db8:11aa:22bb::/64",
   374  		IPv6PrefixLen: 64,
   375  	}
   376  	putIPv6Net(zone, ipv6net)
   377  
   378  	ipv6netInfo := &iaas.IPv6NetInfo{}
   379  	copySameNameField(ipv6net, ipv6netInfo)
   380  
   381  	value.Switch.IPv6Nets = []*iaas.IPv6NetInfo{ipv6netInfo}
   382  	putInternet(zone, value)
   383  	return ipv6netInfo, nil
   384  }
   385  
   386  // DisableIPv6 is fake implementation
   387  func (o *InternetOp) DisableIPv6(ctx context.Context, zone string, id types.ID, ipv6netID types.ID) error {
   388  	value, err := o.Read(ctx, zone, id)
   389  	if err != nil {
   390  		return err
   391  	}
   392  
   393  	if len(value.Switch.IPv6Nets) == 0 {
   394  		return nil
   395  	}
   396  
   397  	ds().Delete(ResourceIPv6Net, zone, value.Switch.IPv6Nets[0].ID)
   398  	value.Switch.IPv6Nets = []*iaas.IPv6NetInfo{}
   399  	putInternet(zone, value)
   400  	return nil
   401  }