github.com/sacloud/libsacloud/v2@v2.32.3/helper/service/vpcrouter/update_standard_request.go (about) 1 // Copyright 2016-2022 The Libsacloud 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 vpcrouter 16 17 import ( 18 "context" 19 "fmt" 20 21 "github.com/sacloud/libsacloud/v2/helper/service" 22 "github.com/sacloud/libsacloud/v2/helper/validate" 23 "github.com/sacloud/libsacloud/v2/sacloud" 24 "github.com/sacloud/libsacloud/v2/sacloud/types" 25 ) 26 27 type UpdateStandardRequest struct { 28 Zone string `request:"-" validate:"required"` 29 ID types.ID `request:"-" validate:"required"` 30 31 Name *string `request:",omitempty" validate:"omitempty,min=1"` 32 Description *string `request:",omitempty" validate:"omitempty,min=1,max=512"` 33 Tags *types.Tags `request:",omitempty"` 34 IconID *types.ID `request:",omitempty"` 35 36 AdditionalNICSettings *[]*AdditionalStandardNICSettingUpdate `request:"-"` // Indexが同じものを手動でマージする 37 RouterSetting *RouterSettingUpdate `request:",omitempty,recursive"` 38 NoWait bool 39 40 SettingsHash string 41 } 42 43 type AdditionalStandardNICSettingUpdate struct { 44 SwitchID *types.ID `request:",omitempty"` 45 IPAddress *string `request:",omitempty"` 46 NetworkMaskLen *int `request:",omitempty"` 47 Index int `request:",omitempty"` 48 } 49 50 func (req *UpdateStandardRequest) Validate() error { 51 return validate.Struct(req) 52 } 53 54 func (req *UpdateStandardRequest) ApplyRequest(ctx context.Context, caller sacloud.APICaller) (*ApplyRequest, error) { 55 current, err := sacloud.NewVPCRouterOp(caller).Read(ctx, req.Zone, req.ID) 56 if err != nil { 57 return nil, err 58 } 59 60 if current.PlanID != types.VPCRouterPlans.Standard { 61 return nil, fmt.Errorf("target is not a standard plan: Zone=%s ID=%s", req.Zone, req.ID) 62 } 63 if current.Availability != types.Availabilities.Available { 64 return nil, fmt.Errorf("target has invalid Availability: Zone=%s ID=%s Availability=%v", req.Zone, req.ID.String(), current.Availability) 65 } 66 67 var additionalNICs []AdditionalNICSettingHolder 68 for _, nic := range current.Interfaces { 69 if nic.Index == 0 { 70 continue 71 } 72 var setting *sacloud.VPCRouterInterfaceSetting 73 for _, s := range current.Settings.Interfaces { 74 if s.Index == nic.Index { 75 setting = s 76 break 77 } 78 } 79 if setting == nil { 80 continue 81 } 82 83 ip := "" 84 if len(setting.IPAddress) > 0 { 85 ip = setting.IPAddress[0] 86 } 87 additionalNICs = append(additionalNICs, &AdditionalStandardNICSetting{ 88 SwitchID: nic.SwitchID, 89 IPAddress: ip, 90 NetworkMaskLen: setting.NetworkMaskLen, 91 Index: setting.Index, 92 }) 93 } 94 95 applyRequest := &ApplyRequest{ 96 Zone: req.Zone, 97 ID: req.ID, 98 Name: current.Name, 99 Description: current.Description, 100 Tags: current.Tags, 101 IconID: current.IconID, 102 PlanID: current.PlanID, 103 NICSetting: &StandardNICSetting{}, 104 AdditionalNICSettings: additionalNICs, 105 RouterSetting: &RouterSetting{ 106 VRID: current.Settings.VRID, 107 InternetConnectionEnabled: current.Settings.InternetConnectionEnabled, 108 StaticNAT: current.Settings.StaticNAT, 109 PortForwarding: current.Settings.PortForwarding, 110 Firewall: current.Settings.Firewall, 111 DHCPServer: current.Settings.DHCPServer, 112 DHCPStaticMapping: current.Settings.DHCPStaticMapping, 113 DNSForwarding: current.Settings.DNSForwarding, 114 PPTPServer: current.Settings.PPTPServer, 115 L2TPIPsecServer: current.Settings.L2TPIPsecServer, 116 RemoteAccessUsers: current.Settings.RemoteAccessUsers, 117 SiteToSiteIPsecVPN: current.Settings.SiteToSiteIPsecVPN, 118 StaticRoute: current.Settings.StaticRoute, 119 SyslogHost: current.Settings.SyslogHost, 120 }, 121 NoWait: false, 122 } 123 124 if err := service.RequestConvertTo(req, applyRequest); err != nil { 125 return nil, err 126 } 127 128 // NOTE: AdditionalNICSettingsは配列のインデックスではなく 129 // 要素中のIndexフィールドを元にマージする必要があるためここで個別実装する 130 if err := req.mergeAdditionalNICSettings(applyRequest); err != nil { 131 return nil, err 132 } 133 134 return applyRequest, nil 135 } 136 137 func (req *UpdateStandardRequest) mergeAdditionalNICSettings(applyRequest *ApplyRequest) error { 138 if req.AdditionalNICSettings != nil { 139 var newAdditionalNICs []AdditionalNICSettingHolder 140 for _, reqNIC := range *req.AdditionalNICSettings { 141 var nic AdditionalNICSettingHolder 142 for _, n := range applyRequest.AdditionalNICSettings { 143 if reqNIC.Index == n.interfaceSetting().Index { 144 nic = n 145 break 146 } 147 } 148 if nic == nil { 149 nic = &AdditionalStandardNICSetting{} 150 } 151 if err := service.RequestConvertTo(reqNIC, nic); err != nil { 152 return err 153 } 154 newAdditionalNICs = append(newAdditionalNICs, nic) 155 } 156 applyRequest.AdditionalNICSettings = newAdditionalNICs 157 } 158 return nil 159 }