routetable.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. // Copyright 2023 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. package volcengine
  15. import (
  16. "fmt"
  17. "strings"
  18. "time"
  19. api "yunion.io/x/cloudmux/pkg/apis/compute"
  20. "yunion.io/x/cloudmux/pkg/cloudprovider"
  21. "yunion.io/x/cloudmux/pkg/multicloud"
  22. "yunion.io/x/pkg/errors"
  23. )
  24. type SRouteEntry struct {
  25. multicloud.SResourceBase
  26. VolcEngineTags
  27. routeTable *SRouteTable
  28. Description string
  29. DestinationCidrBlock string
  30. RouteEntryId string
  31. RouteEntryName string
  32. RouteTableId string
  33. Status string
  34. Type string
  35. VpcId string
  36. NextHopId string
  37. NextHopName string
  38. NextHopType string
  39. }
  40. type SRouteEntrys []*SRouteEntry
  41. type SubnetIds []string
  42. type SRouteTable struct {
  43. multicloud.SResourceBase
  44. VolcEngineTags
  45. region *SRegion
  46. vpc *SVpc
  47. routes []cloudprovider.ICloudRoute
  48. Description string
  49. RouteTableId string
  50. RouteTableName string
  51. RouteTableType string
  52. VpcId string
  53. VpcName string
  54. CreationTime time.Time
  55. UpdateTime time.Time
  56. AccountId string
  57. ProjectName string
  58. SubnetIds SubnetIds
  59. RouteEntrys SRouteEntrys
  60. }
  61. func (route *SRouteEntry) GetId() string {
  62. return fmt.Sprintf("%s-%s-%s", route.RouteTableId, route.DestinationCidrBlock, route.NextHopType)
  63. }
  64. func (route *SRouteEntry) GetName() string {
  65. return route.RouteEntryName
  66. }
  67. func (route *SRouteEntry) GetGlobalId() string {
  68. return route.GetId()
  69. }
  70. func (route *SRouteEntry) GetStatus() string {
  71. return api.ROUTE_ENTRY_STATUS_AVAILIABLE
  72. }
  73. func (route *SRouteEntry) Refresh() error {
  74. return nil
  75. }
  76. func (route *SRouteEntry) GetType() string {
  77. return route.Type
  78. }
  79. func (route *SRouteEntry) GetCidr() string {
  80. return route.DestinationCidrBlock
  81. }
  82. func (route *SRouteEntry) GetNextHopType() string {
  83. switch route.NextHopType {
  84. case "Instance":
  85. return api.NEXT_HOP_TYPE_INSTANCE
  86. case "HaVip":
  87. return api.NEXT_HOP_TYPE_HAVIP
  88. case "VpnGW":
  89. return api.NEXT_HOP_TYPE_VPN
  90. case "NatGW":
  91. return api.NEXT_HOP_TYPE_NAT
  92. case "NetworkInterface":
  93. return api.NEXT_HOP_TYPE_NETWORK
  94. case "IPv6GW":
  95. return api.NEXT_HOP_TYPE_IPV6
  96. case "TransitRouter":
  97. return api.NEXT_HOP_TYPE_ROUTER
  98. default:
  99. return ""
  100. }
  101. }
  102. func (route *SRouteEntry) GetNextHop() string {
  103. return route.NextHopId
  104. }
  105. func (table *SRouteTable) GetDescription() string {
  106. return table.Description
  107. }
  108. func (table *SRouteTable) GetId() string {
  109. return table.RouteTableId
  110. }
  111. func (table *SRouteTable) GetGlobalId() string {
  112. return table.RouteTableId
  113. }
  114. func (table *SRouteTable) GetName() string {
  115. return table.RouteTableName
  116. }
  117. func (table *SRouteTable) GetRegionId() string {
  118. return table.region.RegionId
  119. }
  120. func (table *SRouteTable) GetType() cloudprovider.RouteTableType {
  121. switch table.RouteTableType {
  122. case "System":
  123. return cloudprovider.RouteTableTypeSystem
  124. case "Custom":
  125. return cloudprovider.RouteTableTypeCustom
  126. default:
  127. return cloudprovider.RouteTableTypeSystem
  128. }
  129. }
  130. func (table *SRouteTable) GetVpcId() string {
  131. return table.VpcId
  132. }
  133. func (table *SRouteTable) GetStatus() string {
  134. return api.ROUTE_TABLE_AVAILABLE
  135. }
  136. func (table *SRouteTable) Refresh() error {
  137. return nil
  138. }
  139. func (routeTable *SRouteTable) IsSystem() bool {
  140. return strings.ToLower(routeTable.RouteTableType) == "system"
  141. }
  142. func (table *SRouteTable) RemoteGetRoutes(pageNumber int, pageSize int) ([]*SRouteEntry, int, error) {
  143. if pageSize > 100 || pageSize <= 0 {
  144. pageSize = 100
  145. }
  146. params := make(map[string]string)
  147. params["RouteTableId"] = table.RouteTableId
  148. params["PageSize"] = fmt.Sprintf("%d", pageSize)
  149. params["PageNumber"] = fmt.Sprintf("%d", pageNumber)
  150. body, err := table.region.vpcRequest("DescribeRouteEntryList", params)
  151. if err != nil {
  152. return nil, 0, errors.Wrapf(err, "RemoteGetRoutes fail")
  153. }
  154. entries := SRouteEntrys{}
  155. err = body.Unmarshal(&entries, "RouteEntries")
  156. if err != nil {
  157. return nil, 0, errors.Wrapf(err, "Unmarshal routeEntrys fail")
  158. }
  159. total, _ := body.Int("TotalCount")
  160. return entries, int(total), nil
  161. }
  162. func (table *SRouteTable) fetchRoutes() error {
  163. routes := []*SRouteEntry{}
  164. pageNumber := 1
  165. for {
  166. parts, total, err := table.RemoteGetRoutes(pageNumber, 50)
  167. if err != nil {
  168. return err
  169. }
  170. routes = append(routes, parts...)
  171. if len(routes) >= total {
  172. break
  173. }
  174. pageNumber += 1
  175. }
  176. table.routes = make([]cloudprovider.ICloudRoute, len(routes))
  177. for i := 0; i < len(routes); i++ {
  178. routes[i].routeTable = table
  179. table.routes[i] = routes[i]
  180. }
  181. return nil
  182. }
  183. func (table *SRouteTable) GetIRoutes() ([]cloudprovider.ICloudRoute, error) {
  184. if table.routes == nil {
  185. err := table.fetchRoutes()
  186. if err != nil {
  187. return nil, err
  188. }
  189. }
  190. return table.routes, nil
  191. }
  192. func (table *SRouteTable) GetAssociations() []cloudprovider.RouteTableAssociation {
  193. result := []cloudprovider.RouteTableAssociation{}
  194. for i := range table.SubnetIds {
  195. association := cloudprovider.RouteTableAssociation{
  196. AssociationId: table.RouteTableId + ":" + table.SubnetIds[i],
  197. AssociationType: cloudprovider.RouteTableAssociaToSubnet,
  198. AssociatedResourceId: table.SubnetIds[i],
  199. }
  200. result = append(result, association)
  201. }
  202. return result
  203. }
  204. func (table *SRouteTable) CreateRoute(route cloudprovider.RouteSet) error {
  205. return cloudprovider.ErrNotSupported
  206. }
  207. func (table *SRouteTable) UpdateRoute(route cloudprovider.RouteSet) error {
  208. return cloudprovider.ErrNotSupported
  209. }
  210. func (table *SRouteTable) RemoveRoute(route cloudprovider.RouteSet) error {
  211. return cloudprovider.ErrNotSupported
  212. }
  213. func (vpc *SVpc) RemoteGetRouteTableList(pageNumber int, pageSize int) ([]*SRouteTable, int, error) {
  214. if pageSize > 100 || pageSize <= 0 {
  215. pageSize = 100
  216. }
  217. params := make(map[string]string)
  218. params["VpcId"] = vpc.VpcId
  219. params["PageSize"] = fmt.Sprintf("%d", pageSize)
  220. params["PageNumber"] = fmt.Sprintf("%d", pageNumber)
  221. body, err := vpc.region.vpcRequest("DescribeRouteTableList", params)
  222. if err != nil {
  223. return nil, 0, errors.Wrapf(err, "RemoteGetRouteTableList fail")
  224. }
  225. routeTables := make([]*SRouteTable, 0)
  226. err = body.Unmarshal(&routeTables, "RouterTableList")
  227. if err != nil {
  228. return nil, 0, errors.Wrapf(err, "Unmarshal routeTables fail")
  229. }
  230. for _, routeTable := range routeTables {
  231. routeTable.region = vpc.region
  232. }
  233. total, _ := body.Int("TotalCount")
  234. return routeTables, int(total), nil
  235. }
  236. func (region *SRegion) AssociateRouteTable(rtableId string, SubnetId string) error {
  237. params := make(map[string]string)
  238. params["RouteTableId"] = rtableId
  239. params["SubnetId"] = SubnetId
  240. _, err := region.vpcRequest("AssociateRouteTable", params)
  241. return err
  242. }
  243. func (region *SRegion) UnassociateRouteTable(rtableId string, SubnetId string) error {
  244. params := make(map[string]string)
  245. params["RouteTableId"] = rtableId
  246. params["SubnetId"] = SubnetId
  247. _, err := region.vpcRequest("UnassociateRouteTable", params)
  248. return err
  249. }