github.com/sacloud/iaas-api-go@v1.12.0/helper/plans/change_plan.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 plans
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"strings"
    21  
    22  	"github.com/sacloud/iaas-api-go"
    23  	"github.com/sacloud/iaas-api-go/types"
    24  )
    25  
    26  var (
    27  	PreviousIDTagName = "@previous-id"
    28  	maxTags           = 10 // タグ上限数
    29  )
    30  
    31  // ChangeServerPlan 現在のIDをタグとして保持しつつプランを変更する
    32  //
    33  // もしすでにタグが上限(10)まで付与されている場合はプラン変更だけ行う
    34  func ChangeServerPlan(
    35  	ctx context.Context,
    36  	caller iaas.APICaller,
    37  	zone string,
    38  	id types.ID,
    39  	planRequest *iaas.ServerChangePlanRequest,
    40  ) (*iaas.Server, error) {
    41  	serverOp := iaas.NewServerOp(caller)
    42  	server, err := serverOp.Read(ctx, zone, id)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  
    47  	if len(server.Tags) < maxTags {
    48  		server.Tags = AppendPreviousIDTagIfAbsent(server.Tags, server.ID)
    49  
    50  		updated, err := serverOp.Update(ctx, zone, server.ID, &iaas.ServerUpdateRequest{
    51  			Name:            server.Name,
    52  			Description:     server.Description,
    53  			Tags:            server.Tags,
    54  			IconID:          server.IconID,
    55  			PrivateHostID:   server.PrivateHostID,
    56  			InterfaceDriver: server.InterfaceDriver,
    57  		})
    58  		if err != nil {
    59  			return nil, err
    60  		}
    61  		server = updated
    62  	}
    63  
    64  	return serverOp.ChangePlan(ctx, zone, server.ID, planRequest)
    65  }
    66  
    67  // ChangeRouterPlan 現在のIDをタグとして保持しつつプランを変更する
    68  //
    69  // もしすでにタグが上限(10)まで付与されている場合はプラン変更だけ行う
    70  func ChangeRouterPlan(
    71  	ctx context.Context,
    72  	caller iaas.APICaller,
    73  	zone string,
    74  	id types.ID,
    75  	bandWidth int,
    76  ) (*iaas.Internet, error) {
    77  	internetOp := iaas.NewInternetOp(caller)
    78  	router, err := internetOp.Read(ctx, zone, id)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	if len(router.Tags) < maxTags {
    84  		router.Tags = AppendPreviousIDTagIfAbsent(router.Tags, router.ID)
    85  
    86  		updated, err := internetOp.Update(ctx, zone, router.ID, &iaas.InternetUpdateRequest{
    87  			Name:        router.Name,
    88  			Description: router.Description,
    89  			Tags:        router.Tags,
    90  			IconID:      router.IconID,
    91  		})
    92  		if err != nil {
    93  			return nil, err
    94  		}
    95  		router = updated
    96  	}
    97  
    98  	return internetOp.UpdateBandWidth(ctx, zone, router.ID, &iaas.InternetUpdateBandWidthRequest{
    99  		BandWidthMbps: bandWidth,
   100  	})
   101  }
   102  
   103  // ChangeProxyLBPlan 現在のIDをタグとして保持しつつプランを変更する
   104  //
   105  // もしすでにタグが上限(10)まで付与されている場合はプラン変更だけ行う
   106  func ChangeProxyLBPlan(
   107  	ctx context.Context,
   108  	caller iaas.APICaller,
   109  	id types.ID,
   110  	cps int,
   111  ) (*iaas.ProxyLB, error) {
   112  	elbOp := iaas.NewProxyLBOp(caller)
   113  	elb, err := elbOp.Read(ctx, id)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	if len(elb.Tags) < maxTags {
   119  		elb.Tags = AppendPreviousIDTagIfAbsent(elb.Tags, elb.ID)
   120  
   121  		updated, err := elbOp.Update(ctx, elb.ID, &iaas.ProxyLBUpdateRequest{
   122  			HealthCheck:   elb.HealthCheck,
   123  			SorryServer:   elb.SorryServer,
   124  			BindPorts:     elb.BindPorts,
   125  			Servers:       elb.Servers,
   126  			Rules:         elb.Rules,
   127  			LetsEncrypt:   elb.LetsEncrypt,
   128  			StickySession: elb.StickySession,
   129  			Timeout:       elb.Timeout,
   130  			Gzip:          elb.Gzip,
   131  			ProxyProtocol: elb.ProxyProtocol,
   132  			Syslog:        elb.Syslog,
   133  			SettingsHash:  elb.SettingsHash,
   134  			Name:          elb.Name,
   135  			Description:   elb.Description,
   136  			Tags:          elb.Tags,
   137  			IconID:        elb.IconID,
   138  		})
   139  		if err != nil {
   140  			return nil, err
   141  		}
   142  		elb = updated
   143  	}
   144  
   145  	return elbOp.ChangePlan(ctx, elb.ID, &iaas.ProxyLBChangePlanRequest{
   146  		ServiceClass: types.ProxyLBServiceClass(types.EProxyLBPlan(cps), elb.Region),
   147  	})
   148  }
   149  
   150  func AppendPreviousIDTagIfAbsent(tags types.Tags, currentID types.ID) types.Tags {
   151  	if len(tags) > maxTags {
   152  		return tags
   153  	}
   154  	// すでに付けられたPreviousIDタグを消す
   155  	updated := types.Tags{}
   156  	for _, t := range tags {
   157  		if !strings.HasPrefix(t, PreviousIDTagName) {
   158  			updated = append(updated, t)
   159  		}
   160  	}
   161  	updated = append(updated, fmt.Sprintf("%s=%s", PreviousIDTagName, currentID))
   162  	updated.Sort()
   163  	return updated
   164  }