github.com/sacloud/libsacloud/v2@v2.32.3/helper/service/vpcrouter/update_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 UpdateRequest 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 NICSetting *PremiumNICSettingUpdate `request:",omitempty,recursive"` 37 AdditionalNICSettings *[]*AdditionalPremiumNICSettingUpdate `request:"-"` // Indexが同じものを手動でマージする 38 RouterSetting *RouterSettingUpdate `request:",omitempty,recursive"` 39 NoWait bool 40 41 SettingsHash string 42 } 43 44 type PremiumNICSettingUpdate struct { 45 IPAddresses *[]string `request:",omitempty"` 46 VirtualIPAddress *string `request:",omitempty"` 47 IPAliases *[]string `request:",omitempty"` 48 } 49 50 type AdditionalPremiumNICSettingUpdate struct { 51 SwitchID *types.ID `request:",omitempty"` 52 IPAddresses *[]string `request:",omitempty"` 53 VirtualIPAddress *string `request:",omitempty"` 54 NetworkMaskLen *int `request:",omitempty"` 55 Index int 56 } 57 58 type RouterSettingUpdate struct { 59 InternetConnectionEnabled *bool `request:",omitempty"` 60 StaticNAT *[]*sacloud.VPCRouterStaticNAT `request:",omitempty,recursive"` 61 PortForwarding *[]*sacloud.VPCRouterPortForwarding `request:",omitempty,recursive"` 62 Firewall *[]*sacloud.VPCRouterFirewall `request:",omitempty,recursive"` 63 DHCPServer *[]*sacloud.VPCRouterDHCPServer `request:",omitempty,recursive"` 64 DHCPStaticMapping *[]*sacloud.VPCRouterDHCPStaticMapping `request:",omitempty,recursive"` 65 PPTPServer *sacloud.VPCRouterPPTPServer `request:",omitempty,recursive"` 66 L2TPIPsecServer *sacloud.VPCRouterL2TPIPsecServer `request:",omitempty,recursive"` 67 WireGuard *sacloud.VPCRouterWireGuard `request:",omitempty,recursive"` 68 RemoteAccessUsers *[]*sacloud.VPCRouterRemoteAccessUser `request:",omitempty,recursive"` 69 SiteToSiteIPsecVPN *[]*sacloud.VPCRouterSiteToSiteIPsecVPN `request:",omitempty,recursive"` 70 StaticRoute *[]*sacloud.VPCRouterStaticRoute `request:",omitempty,recursive"` 71 SyslogHost *string `request:",omitempty"` 72 } 73 74 func (req *UpdateRequest) Validate() error { 75 return validate.Struct(req) 76 } 77 78 func (req *UpdateRequest) ApplyRequest(ctx context.Context, caller sacloud.APICaller) (*ApplyRequest, error) { 79 current, err := sacloud.NewVPCRouterOp(caller).Read(ctx, req.Zone, req.ID) 80 if err != nil { 81 return nil, err 82 } 83 84 if current.PlanID == types.VPCRouterPlans.Standard { 85 return nil, fmt.Errorf("target is not a premium or higher plan: Zone=%s ID=%s", req.Zone, req.ID) 86 } 87 if current.Availability != types.Availabilities.Available { 88 return nil, fmt.Errorf("target has invalid Availability: Zone=%s ID=%s Availability=%v", req.Zone, req.ID.String(), current.Availability) 89 } 90 91 var additionalNICs []AdditionalNICSettingHolder 92 for _, nic := range current.Interfaces { 93 if nic.Index == 0 { 94 continue 95 } 96 var setting *sacloud.VPCRouterInterfaceSetting 97 for _, s := range current.Settings.Interfaces { 98 if s.Index == nic.Index { 99 setting = s 100 break 101 } 102 } 103 if setting == nil { 104 continue 105 } 106 107 additionalNICs = append(additionalNICs, &AdditionalPremiumNICSetting{ 108 SwitchID: nic.SwitchID, 109 IPAddresses: setting.IPAddress, 110 VirtualIPAddress: setting.VirtualIPAddress, 111 NetworkMaskLen: setting.NetworkMaskLen, 112 Index: setting.Index, 113 }) 114 } 115 116 var nicSetting *PremiumNICSetting 117 for _, s := range current.Settings.Interfaces { 118 if s.Index == 0 { 119 nicSetting = &PremiumNICSetting{ 120 SwitchID: current.Interfaces[0].SwitchID, 121 IPAddresses: s.IPAddress, 122 VirtualIPAddress: s.VirtualIPAddress, 123 IPAliases: s.IPAliases, 124 } 125 break 126 } 127 } 128 129 applyRequest := &ApplyRequest{ 130 Zone: req.Zone, 131 ID: req.ID, 132 Name: current.Name, 133 Description: current.Description, 134 Tags: current.Tags, 135 IconID: current.IconID, 136 PlanID: current.PlanID, 137 NICSetting: nicSetting, 138 AdditionalNICSettings: additionalNICs, 139 RouterSetting: &RouterSetting{ 140 VRID: current.Settings.VRID, 141 InternetConnectionEnabled: current.Settings.InternetConnectionEnabled, 142 StaticNAT: current.Settings.StaticNAT, 143 PortForwarding: current.Settings.PortForwarding, 144 Firewall: current.Settings.Firewall, 145 DHCPServer: current.Settings.DHCPServer, 146 DHCPStaticMapping: current.Settings.DHCPStaticMapping, 147 DNSForwarding: current.Settings.DNSForwarding, 148 PPTPServer: current.Settings.PPTPServer, 149 L2TPIPsecServer: current.Settings.L2TPIPsecServer, 150 RemoteAccessUsers: current.Settings.RemoteAccessUsers, 151 SiteToSiteIPsecVPN: current.Settings.SiteToSiteIPsecVPN, 152 StaticRoute: current.Settings.StaticRoute, 153 SyslogHost: current.Settings.SyslogHost, 154 }, 155 NoWait: false, 156 } 157 158 if err := service.RequestConvertTo(req, applyRequest); err != nil { 159 return nil, err 160 } 161 162 // NOTE: AdditionalNICSettingsは配列のインデックスではなく 163 // 要素中のIndexフィールドを元にマージする必要があるためここで個別実装する 164 if err := req.mergeAdditionalNICSettings(applyRequest); err != nil { 165 return nil, err 166 } 167 168 return applyRequest, nil 169 } 170 171 func (req *UpdateRequest) mergeAdditionalNICSettings(applyRequest *ApplyRequest) error { 172 if req.AdditionalNICSettings != nil { 173 var newAdditionalNICs []AdditionalNICSettingHolder 174 for _, reqNIC := range *req.AdditionalNICSettings { 175 var nic AdditionalNICSettingHolder 176 for _, n := range applyRequest.AdditionalNICSettings { 177 if reqNIC.Index == n.interfaceSetting().Index { 178 nic = n 179 break 180 } 181 } 182 if nic == nil { 183 nic = &AdditionalPremiumNICSetting{} 184 } 185 if err := service.RequestConvertTo(reqNIC, nic); err != nil { 186 return err 187 } 188 newAdditionalNICs = append(newAdditionalNICs, nic) 189 } 190 applyRequest.AdditionalNICSettings = newAdditionalNICs 191 } 192 return nil 193 }