yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/routetables.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 huawei 16 17 import ( 18 "fmt" 19 20 "yunion.io/x/jsonutils" 21 "yunion.io/x/pkg/errors" 22 23 api "yunion.io/x/cloudmux/pkg/apis/compute" 24 "yunion.io/x/cloudmux/pkg/cloudprovider" 25 "yunion.io/x/cloudmux/pkg/multicloud" 26 ) 27 28 var hoptypes = map[string]string{ 29 api.NEXT_HOP_TYPE_VPCPEERING: "peering", 30 api.NEXT_HOP_TYPE_INSTANCE: "ecs", 31 api.NEXT_HOP_TYPE_NAT: "nat", 32 api.NEXT_HOP_TYPE_HAVIP: "vip", 33 api.NEXT_HOP_TYPE_NETWORK: "eni", 34 api.NEXT_HOP_TYPE_INTERVPCNETWORK: "cc", 35 } 36 37 type SRoute struct { 38 multicloud.SResourceBase 39 HuaweiTags 40 41 Type string `json:"type"` 42 Destination string `json:"destination"` 43 Nexthop string `json:"nexthop"` 44 Description string `json:"description,omitempty"` 45 } 46 47 func (self *SRoute) GetCidr() string { 48 return self.Destination 49 } 50 51 func (self *SRoute) GetGlobalId() string { 52 return self.GetId() 53 } 54 55 func (self *SRoute) GetId() string { 56 return fmt.Sprintf("%s:%s:%s", self.Type, self.Nexthop, self.Destination) 57 } 58 59 func (self *SRoute) GetName() string { 60 return "" 61 } 62 63 func (route *SRoute) GetStatus() string { 64 return api.ROUTE_ENTRY_STATUS_AVAILIABLE 65 } 66 67 func (route *SRoute) GetType() string { 68 if route.Type != "local" { 69 return api.ROUTE_ENTRY_TYPE_CUSTOM 70 } 71 return api.ROUTE_ENTRY_TYPE_SYSTEM 72 } 73 74 func (self *SRoute) GetNextHopType() string { 75 for k, v := range hoptypes { 76 if v == self.Type { 77 return k 78 } 79 } 80 return self.Type 81 } 82 83 type Subnet struct { 84 Id string `json:"id"` 85 } 86 87 type SRouteTable struct { 88 multicloud.SResourceBase 89 HuaweiTags 90 vpc *SVpc 91 92 Id string `json:"id"` 93 Name string `json:"name"` 94 Routes []SRoute `json:"routes"` 95 Subnets []Subnet `json:"subnets"` 96 VpcId string `json:"vpc_id"` 97 Default bool `json:"default"` 98 TenantId string `json:"tenant_id"` 99 } 100 101 func (self *SRouteTable) GetDescription() string { 102 return "" 103 } 104 105 func (self *SRouteTable) GetGlobalId() string { 106 return self.Id 107 } 108 109 func (self *SRouteTable) GetId() string { 110 return self.Id 111 } 112 113 func (self *SRouteTable) GetName() string { 114 return self.Name 115 } 116 117 func (self *SRouteTable) GetRegionId() string { 118 return self.vpc.region.GetId() 119 } 120 121 func (self *SRouteTable) GetVpcId() string { 122 return self.VpcId 123 } 124 125 func (self *SRouteTable) GetType() cloudprovider.RouteTableType { 126 return cloudprovider.RouteTableTypeSystem 127 } 128 129 func (self *SRouteTable) GetStatus() string { 130 return api.ROUTE_TABLE_AVAILABLE 131 } 132 133 func (self *SRouteTable) Refresh() error { 134 rtb, err := self.vpc.region.GetRouteTable(self.Id) 135 if err != nil { 136 return err 137 } 138 return jsonutils.Update(self, rtb) 139 } 140 141 func (self *SRouteTable) GetIRoutes() ([]cloudprovider.ICloudRoute, error) { 142 if len(self.Routes) == 0 { 143 err := self.Refresh() 144 if err != nil { 145 return nil, err 146 } 147 } 148 ret := []cloudprovider.ICloudRoute{} 149 for i := range self.Routes { 150 ret = append(ret, &self.Routes[i]) 151 } 152 return ret, nil 153 } 154 155 func (self *SRoute) GetNextHop() string { 156 return self.Nexthop 157 } 158 159 func (self *SRegion) GetRouteTables(vpcId string) ([]SRouteTable, error) { 160 params := map[string]string{} 161 if len(vpcId) > 0 { 162 params["vpc_id"] = vpcId 163 } 164 rtbs := make([]SRouteTable, 0) 165 err := doListAllWithMarker(self.ecsClient.RouteTables.List, params, &rtbs) 166 return rtbs, err 167 } 168 169 func (self *SRegion) GetRouteTable(id string) (*SRouteTable, error) { 170 resp, err := self.ecsClient.RouteTables.Get(id, nil) 171 if err != nil { 172 return nil, err 173 } 174 tb := &SRouteTable{} 175 return tb, resp.Unmarshal(tb) 176 } 177 178 func (self *SRouteTable) CreateRoute(route cloudprovider.RouteSet) error { 179 routeType, ok := hoptypes[route.NextHopType] 180 if !ok { 181 return errors.Wrapf(cloudprovider.ErrNotSupported, route.NextHopType) 182 } 183 params := map[string]interface{}{ 184 "routes": map[string]interface{}{ 185 "add": []map[string]interface{}{ 186 { 187 "type": routeType, 188 "destination": route.Destination, 189 "nexthop": route.NextHop, 190 }, 191 }, 192 }, 193 } 194 _, err := self.vpc.region.ecsClient.VpcRoutes.Update(self.Id, jsonutils.Marshal(params)) 195 return err 196 } 197 198 func (self *SRouteTable) RemoveRoute(route cloudprovider.RouteSet) error { 199 routeType, ok := hoptypes[route.NextHopType] 200 if !ok { 201 return errors.Wrapf(cloudprovider.ErrNotSupported, route.NextHopType) 202 } 203 params := map[string]interface{}{ 204 "routes": map[string]interface{}{ 205 "mod": []map[string]interface{}{ 206 { 207 "type": routeType, 208 "destination": route.Destination, 209 "nexthop": route.NextHop, 210 }, 211 }, 212 }, 213 } 214 _, err := self.vpc.region.ecsClient.VpcRoutes.Update(self.Id, jsonutils.Marshal(params)) 215 return err 216 } 217 218 func (self *SRouteTable) UpdateRoute(route cloudprovider.RouteSet) error { 219 err := self.RemoveRoute(route) 220 if err != nil { 221 return errors.Wrap(err, "self.RemoveRoute(route)") 222 } 223 err = self.CreateRoute(route) 224 if err != nil { 225 return errors.Wrap(err, "self.CreateRoute(route)") 226 } 227 return nil 228 } 229 230 func (self *SRouteTable) GetAssociations() []cloudprovider.RouteTableAssociation { 231 return []cloudprovider.RouteTableAssociation{} 232 }