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