yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/hcs/natgateway.go (about) 1 // Copyright 2019 Yunion 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 hcs 16 17 import ( 18 "net/url" 19 "strings" 20 "time" 21 22 "yunion.io/x/jsonutils" 23 "yunion.io/x/pkg/errors" 24 25 billing_api "yunion.io/x/cloudmux/pkg/apis/billing" 26 api "yunion.io/x/cloudmux/pkg/apis/compute" 27 "yunion.io/x/cloudmux/pkg/cloudprovider" 28 "yunion.io/x/cloudmux/pkg/multicloud" 29 ) 30 31 type SNatGateway struct { 32 multicloud.SNatGatewayBase 33 HcsTags 34 region *SRegion 35 36 Id string 37 Name string 38 Description string 39 Spec string 40 Status string 41 InternalNetworkId string 42 CreatedTime string `json:"created_at"` 43 } 44 45 func (gateway *SNatGateway) GetId() string { 46 return gateway.Id 47 } 48 49 func (gateway *SNatGateway) GetName() string { 50 return gateway.Name 51 } 52 53 func (gateway *SNatGateway) GetGlobalId() string { 54 return gateway.GetId() 55 } 56 57 func (gateway *SNatGateway) GetStatus() string { 58 return NatResouceStatusTransfer(gateway.Status) 59 } 60 61 func (self *SNatGateway) Delete() error { 62 return self.region.DeleteNatGateway(self.Id) 63 } 64 65 func (self *SNatGateway) Refresh() error { 66 nat, err := self.region.GetNatGateway(self.Id) 67 if err != nil { 68 return errors.Wrapf(err, "GetNatGateway(%s)", self.Id) 69 } 70 return jsonutils.Update(self, nat) 71 } 72 73 func (self *SNatGateway) GetINetworkId() string { 74 return self.InternalNetworkId 75 } 76 77 func (gateway *SNatGateway) GetNatSpec() string { 78 switch gateway.Spec { 79 case "1": 80 return api.NAT_SPEC_SMALL 81 case "2": 82 return api.NAT_SPEC_MIDDLE 83 case "3": 84 return api.NAT_SPEC_LARGE 85 case "4": 86 return api.NAT_SPEC_XLARGE 87 } 88 return gateway.Spec 89 } 90 91 func (gateway *SNatGateway) GetDescription() string { 92 return gateway.Description 93 } 94 95 func (gateway *SNatGateway) GetBillingType() string { 96 return billing_api.BILLING_TYPE_POSTPAID 97 } 98 99 func (gateway *SNatGateway) GetCreatedAt() time.Time { 100 t, _ := time.Parse("2006-01-02 15:04:05.000000", gateway.CreatedTime) 101 return t 102 } 103 104 func (gateway *SNatGateway) GetExpiredAt() time.Time { 105 return time.Time{} 106 } 107 108 func (gateway *SNatGateway) GetIEips() ([]cloudprovider.ICloudEIP, error) { 109 IEips, err := gateway.region.GetIEips() 110 if err != nil { 111 return nil, errors.Wrapf(err, `get all Eips of region %q error`, gateway.region.GetId()) 112 } 113 dNatTables, err := gateway.GetINatDTable() 114 if err != nil { 115 return nil, errors.Wrapf(err, `get all DNatTable of gateway %q error`, gateway.GetId()) 116 } 117 sNatTables, err := gateway.GetINatSTable() 118 if err != nil { 119 return nil, errors.Wrapf(err, `get all SNatTable of gateway %q error`, gateway.GetId()) 120 } 121 122 // Get natIPSet of nat rules 123 natIPSet := make(map[string]struct{}) 124 for _, snat := range sNatTables { 125 natIPSet[snat.GetIP()] = struct{}{} 126 } 127 for _, dnat := range dNatTables { 128 natIPSet[dnat.GetExternalIp()] = struct{}{} 129 } 130 131 // Add Eip whose GetIpAddr() in natIPSet to ret 132 ret := make([]cloudprovider.ICloudEIP, 0, 2) 133 for i := range IEips { 134 if _, ok := natIPSet[IEips[i].GetIpAddr()]; ok { 135 ret = append(ret, IEips[i]) 136 } 137 } 138 return ret, nil 139 } 140 141 func (gateway *SNatGateway) GetINatDTable() ([]cloudprovider.ICloudNatDEntry, error) { 142 dNatTable, err := gateway.getNatDTable() 143 if err != nil { 144 return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId()) 145 } 146 ret := make([]cloudprovider.ICloudNatDEntry, len(dNatTable)) 147 for i := range dNatTable { 148 ret[i] = &dNatTable[i] 149 } 150 return ret, nil 151 } 152 153 func (gateway *SNatGateway) GetINatSTable() ([]cloudprovider.ICloudNatSEntry, error) { 154 sNatTable, err := gateway.getNatSTable() 155 if err != nil { 156 return nil, errors.Wrapf(err, `get dnat table of nat gateway %q`, gateway.GetId()) 157 } 158 ret := make([]cloudprovider.ICloudNatSEntry, len(sNatTable)) 159 for i := range sNatTable { 160 ret[i] = &sNatTable[i] 161 } 162 return ret, nil 163 } 164 165 func (gateway *SNatGateway) CreateINatDEntry(rule cloudprovider.SNatDRule) (cloudprovider.ICloudNatDEntry, error) { 166 dnat, err := gateway.region.CreateNatDEntry(rule, gateway.GetId()) 167 if err != nil { 168 return nil, err 169 } 170 dnat.gateway = gateway 171 return dnat, nil 172 } 173 174 func (gateway *SNatGateway) CreateINatSEntry(rule cloudprovider.SNatSRule) (cloudprovider.ICloudNatSEntry, error) { 175 snat, err := gateway.region.CreateNatSEntry(rule, gateway.GetId()) 176 if err != nil { 177 return nil, err 178 } 179 snat.gateway = gateway 180 return snat, nil 181 } 182 183 func (gateway *SNatGateway) GetINatDEntryByID(id string) (cloudprovider.ICloudNatDEntry, error) { 184 dnat, err := gateway.region.GetNatDEntry(id) 185 if err != nil { 186 return nil, err 187 } 188 dnat.gateway = gateway 189 return dnat, nil 190 } 191 192 func (gateway *SNatGateway) GetINatSEntryByID(id string) (cloudprovider.ICloudNatSEntry, error) { 193 snat, err := gateway.region.GetNatSEntry(id) 194 if err != nil { 195 return nil, err 196 } 197 snat.gateway = gateway 198 return snat, nil 199 } 200 201 func (self *SRegion) GetNatGateways(vpcId string) ([]SNatGateway, error) { 202 query := url.Values{} 203 if len(vpcId) > 0 { 204 query.Set("router_id", vpcId) 205 } 206 ret := []SNatGateway{} 207 return ret, self.list("nat", "v2.0", "nat_gateways", query, &ret) 208 } 209 210 func NatResouceStatusTransfer(status string) string { 211 // In Huawei Cloud, there are isx resource status of Nat, "ACTIVE", "PENDING_CREATE", 212 // "PENDING_UPDATE", "PENDING_DELETE", "EIP_FREEZED", "INACTIVE". 213 switch status { 214 case "ACTIVE": 215 return api.NAT_STAUTS_AVAILABLE 216 case "PENDING_CREATE": 217 return api.NAT_STATUS_ALLOCATE 218 case "PENDING_UPDATE", "PENDING_DELETE": 219 return api.NAT_STATUS_DEPLOYING 220 default: 221 return api.NAT_STATUS_UNKNOWN 222 } 223 } 224 225 func (self *SRegion) GetNatGateway(id string) (*SNatGateway, error) { 226 ret := &SNatGateway{region: self} 227 return ret, self.get("nat", "v2.0", "nat_gateways/"+id, ret) 228 } 229 230 func (self *SVpc) CreateINatGateway(opts *cloudprovider.NatGatewayCreateOptions) (cloudprovider.ICloudNatGateway, error) { 231 nat, err := self.region.CreateNatGateway(opts) 232 if err != nil { 233 return nil, errors.Wrapf(err, "CreateNatGateway") 234 } 235 return nat, nil 236 } 237 238 func (self *SRegion) CreateNatGateway(opts *cloudprovider.NatGatewayCreateOptions) (*SNatGateway, error) { 239 spec := "" 240 switch strings.ToLower(opts.NatSpec) { 241 case api.NAT_SPEC_SMALL: 242 spec = "1" 243 case api.NAT_SPEC_MIDDLE: 244 spec = "2" 245 case api.NAT_SPEC_LARGE: 246 spec = "3" 247 case api.NAT_SPEC_XLARGE: 248 spec = "4" 249 } 250 params := map[string]interface{}{ 251 "nat_gateway": map[string]interface{}{ 252 "name": opts.Name, 253 "description": opts.Desc, 254 "router_id": opts.VpcId, 255 "internal_network_id": opts.NetworkId, 256 "spec": spec, 257 }, 258 } 259 ret := SNatGateway{region: self} 260 return &ret, self.create("nat", "v2.0", "nat_gateways", params, &ret) 261 } 262 263 func (self *SRegion) DeleteNatGateway(id string) error { 264 return self.delete("nat", "v2.0", "nat_gateways/"+id) 265 }