yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/qcloud/vpc_peering_connection.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 qcloud 16 17 import ( 18 "fmt" 19 "strings" 20 "time" 21 22 "yunion.io/x/jsonutils" 23 "yunion.io/x/pkg/errors" 24 25 api "yunion.io/x/cloudmux/pkg/apis/compute" 26 "yunion.io/x/cloudmux/pkg/cloudprovider" 27 "yunion.io/x/cloudmux/pkg/multicloud" 28 ) 29 30 type SVpcPC struct { 31 multicloud.SResourceBase 32 QcloudTags 33 vpc *SVpc 34 VpcID string `json:"vpcId"` 35 UnVpcID string `json:"unVpcId"` 36 PeerVpcID string `json:"peerVpcId"` 37 UnPeerVpcID string `json:"unPeerVpcId"` 38 AppID string `json:"appId"` 39 PeeringConnectionID string `json:"peeringConnectionId"` 40 PeeringConnectionName string `json:"peeringConnectionName"` 41 State int `json:"state"` 42 CreateTime string `json:"createTime"` 43 Uin string `json:"uin"` 44 PeerUin string `json:"peerUin"` 45 Region string `json:"region"` 46 PeerRegion string `json:"peerRegion"` 47 } 48 49 func (region *SRegion) DescribeVpcPeeringConnections(vpcId string, peeringConnectionId string, offset int, limit int) ([]SVpcPC, int, error) { 50 if limit > 50 || limit <= 0 { 51 limit = 50 52 } 53 params := make(map[string]string) 54 params["offset"] = fmt.Sprintf("%d", offset) 55 params["limit"] = fmt.Sprintf("%d", limit) 56 if len(vpcId) > 0 { 57 params["vpcId"] = vpcId 58 } 59 if len(peeringConnectionId) > 0 { 60 params["peeringConnectionId"] = peeringConnectionId 61 } 62 body, err := region.vpc2017Request("DescribeVpcPeeringConnections", params) 63 if err != nil { 64 return nil, 0, errors.Wrapf(err, `region.vpcRequest("DescribeVpcPeeringConnections", %s)`, jsonutils.Marshal(params).String()) 65 } 66 67 total, _ := body.Float("totalCount") 68 if total <= 0 { 69 return nil, int(total), nil 70 } 71 72 vpcPCs := make([]SVpcPC, 0) 73 err = body.Unmarshal(&vpcPCs, "data") 74 if err != nil { 75 return nil, 0, errors.Wrapf(err, "body.Unmarshal(&vpcPCs,%s)", body.String()) 76 } 77 return vpcPCs, int(total), nil 78 } 79 80 func (region *SRegion) GetAllVpcPeeringConnections(vpcId string) ([]SVpcPC, error) { 81 result := []SVpcPC{} 82 for { 83 vpcPCS, total, err := region.DescribeVpcPeeringConnections(vpcId, "", len(result), 50) 84 if err != nil { 85 return nil, errors.Wrapf(err, `client.DescribeVpcPeeringConnections(%s,"",%d,50)`, vpcId, len(result)) 86 } 87 result = append(result, vpcPCS...) 88 if total <= len(result) { 89 break 90 } 91 } 92 return result, nil 93 } 94 95 func (region *SRegion) GetVpcPeeringConnectionbyId(vpcPCId string) (*SVpcPC, error) { 96 vpcPCs, _, err := region.DescribeVpcPeeringConnections("", vpcPCId, 0, 50) 97 if err != nil { 98 return nil, errors.Wrapf(err, `client.DescribeVpcPeeringConnections("", %s, 0, 50)`, vpcPCId) 99 } 100 if len(vpcPCs) < 1 { 101 return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetVpcPeeringConnectionbyId(%s)", vpcPCId) 102 } 103 if len(vpcPCs) > 1 { 104 return nil, errors.Wrapf(cloudprovider.ErrDuplicateId, "GetVpcPeeringConnectionbyId(%s)", vpcPCId) 105 } 106 return &vpcPCs[0], nil 107 } 108 109 func (region *SRegion) CreateVpcPeeringConnection(vpcId string, opts *cloudprovider.VpcPeeringConnectionCreateOptions) (string, error) { 110 params := make(map[string]string) 111 params["vpcId"] = vpcId 112 params["peerVpcId"] = opts.PeerVpcId 113 params["peerUin"] = opts.PeerAccountId 114 params["peeringConnectionName"] = opts.Name 115 body, err := region.vpc2017Request("CreateVpcPeeringConnection", params) 116 if err != nil { 117 return "", errors.Wrapf(err, `client.vpc2017Request("CreateVpcPeeringConnection", %s)`, jsonutils.Marshal(params).String()) 118 } 119 peeringId, err := body.GetString("peeringConnectionId") 120 if err != nil { 121 return "", errors.Wrapf(err, `%s body.GetString("peeringConnectionId")`, body.String()) 122 } 123 return peeringId, nil 124 } 125 126 func (region *SRegion) AcceptVpcPeeringConnection(peeringId string) error { 127 params := make(map[string]string) 128 params["peeringConnectionId"] = peeringId 129 _, err := region.vpc2017Request("AcceptVpcPeeringConnection", params) 130 if err != nil { 131 return errors.Wrapf(err, `client.vpc2017Request("AcceptVpcPeeringConnection",%s)`, jsonutils.Marshal(params).String()) 132 } 133 return nil 134 } 135 136 func (region *SRegion) DeleteVpcPeeringConnection(peeringId string) error { 137 params := make(map[string]string) 138 params["peeringConnectionId"] = peeringId 139 _, err := region.vpc2017Request("DeleteVpcPeeringConnection", params) 140 if err != nil { 141 return errors.Wrapf(err, `client.vpc2017Request("DeleteVpcPeeringConnection",%s)`, jsonutils.Marshal(params).String()) 142 } 143 return nil 144 } 145 146 func (region *SRegion) CreateVpcPeeringConnectionEx(vpcId string, opts *cloudprovider.VpcPeeringConnectionCreateOptions) (int64, error) { 147 params := make(map[string]string) 148 params["vpcId"] = vpcId 149 params["peerVpcId"] = opts.PeerVpcId 150 params["peerUin"] = opts.PeerAccountId 151 params["peeringConnectionName"] = opts.Name 152 params["peerRegion"] = opts.PeerRegionId 153 params["bandwidth"] = fmt.Sprintf("%d", opts.Bandwidth) 154 body, err := region.vpc2017Request("CreateVpcPeeringConnectionEx", params) 155 if err != nil { 156 return 0, errors.Wrapf(err, `client.vpc2017Request("CreateVpcPeeringConnectionEx", %s)`, jsonutils.Marshal(params).String()) 157 } 158 taskId, err := body.Int("taskId") 159 if err != nil { 160 return 0, errors.Wrapf(err, `%s body.Int("taskId")`, body.String()) 161 } 162 return taskId, nil 163 } 164 165 func (region *SRegion) DescribeVpcTaskResult(taskId string) (int, error) { 166 params := make(map[string]string) 167 params["taskId"] = taskId 168 body, err := region.vpc2017Request("DescribeVpcTaskResult", params) 169 if err != nil { 170 return 0, errors.Wrapf(err, `client.vpc2017Request("DescribeVpcTaskResult",%s)`, taskId) 171 } 172 status, err := body.Float("data", "status") 173 if err != nil { 174 return 0, errors.Wrapf(err, `%s body.Int("data.status")`, body.String()) 175 } 176 return int(status), nil 177 } 178 179 func (region *SRegion) AcceptVpcPeeringConnectionEx(peeringId string) (int64, error) { 180 params := make(map[string]string) 181 params["peeringConnectionId"] = peeringId 182 body, err := region.vpc2017Request("AcceptVpcPeeringConnectionEx", params) 183 if err != nil { 184 return 0, errors.Wrapf(err, `client.vpc2017Request("AcceptVpcPeeringConnectionEx", %s)`, jsonutils.Marshal(params).String()) 185 } 186 taskId, err := body.Int("taskId") 187 if err != nil { 188 return 0, errors.Wrapf(err, `%s body.Int("taskId")`, body.String()) 189 } 190 return taskId, nil 191 } 192 193 func (region *SRegion) DeleteVpcPeeringConnectionEx(peeringId string) (int64, error) { 194 params := make(map[string]string) 195 params["peeringConnectionId"] = peeringId 196 body, err := region.vpc2017Request("DeleteVpcPeeringConnectionEx", params) 197 if err != nil { 198 return 0, errors.Wrapf(err, `client.vpc2017Request("DeleteVpcPeeringConnectionEx",%s)`, jsonutils.Marshal(params).String()) 199 } 200 taskId, err := body.Int("taskId") 201 if err != nil { 202 return 0, errors.Wrapf(err, `%s body.Int("taskId")`, body.String()) 203 } 204 return taskId, nil 205 } 206 207 func (self *SVpcPC) GetId() string { 208 return self.PeeringConnectionID 209 } 210 211 func (self *SVpcPC) GetName() string { 212 return self.PeeringConnectionName 213 } 214 215 func (self *SVpcPC) GetGlobalId() string { 216 return self.GetId() 217 } 218 219 func (self *SVpcPC) GetStatus() string { 220 switch self.State { 221 case 1: 222 return api.VPC_PEERING_CONNECTION_STATUS_ACTIVE 223 case 0: 224 return api.VPC_PEERING_CONNECTION_STATUS_PENDING_ACCEPT 225 default: 226 return api.VPC_PEERING_CONNECTION_STATUS_UNKNOWN 227 } 228 } 229 230 func (self *SVpcPC) Refresh() error { 231 svpcPC, err := self.vpc.region.GetVpcPeeringConnectionbyId(self.GetId()) 232 if err != nil { 233 return errors.Wrapf(err, "self.vpc.region.GetVpcPeeringConnectionbyId(%s)", self.GetId()) 234 } 235 return jsonutils.Update(self, svpcPC) 236 } 237 238 func (self *SVpcPC) GetPeerVpcId() string { 239 return self.UnPeerVpcID 240 } 241 242 func (self *SVpcPC) GetPeerAccountId() string { 243 if strings.Contains(self.PeerUin, ".") { 244 return strings.Split(self.PeerUin, ".")[0] 245 } 246 return self.PeerUin 247 } 248 249 func (self *SVpcPC) GetEnabled() bool { 250 return true 251 } 252 253 func (self *SVpcPC) Delete() error { 254 if !self.IsCrossRegion() { 255 return self.vpc.region.DeleteVpcPeeringConnection(self.GetId()) 256 } 257 taskId, err := self.vpc.region.DeleteVpcPeeringConnectionEx(self.GetId()) 258 if err != nil { 259 return errors.Wrapf(err, "self.vpc.region.DeleteVpcPeeringConnection(%s)", self.GetId()) 260 } 261 //err = self.vpc.region.WaitVpcTask(fmt.Sprintf("%d", taskId), time.Second*5, time.Minute*10) 262 err = cloudprovider.Wait(time.Second*5, time.Minute*6, func() (bool, error) { 263 status, err := self.vpc.region.DescribeVpcTaskResult(fmt.Sprintf("%d", taskId)) 264 if err != nil { 265 return false, errors.Wrap(err, "self.vpc.region.DescribeVpcTaskResult") 266 } 267 //任务的当前状态。0:成功,1:失败,2:进行中。 268 if status == 1 { 269 return false, errors.Wrap(fmt.Errorf("taskfailed,taskId=%d", taskId), "client.DescribeVpcTaskResult(taskId)") 270 } 271 if status == 0 { 272 return true, nil 273 } 274 return false, nil 275 }) 276 if err != nil { 277 return errors.Wrapf(err, "self.region.WaitTask(%d)", taskId) 278 } 279 return nil 280 } 281 282 func (self *SVpcPC) IsCrossRegion() bool { 283 if len(self.Region) == 0 { 284 return false 285 } 286 return self.Region != self.PeerRegion 287 }