vpc.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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. package openstack
  15. import (
  16. "fmt"
  17. "net/url"
  18. "time"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/pkg/errors"
  21. api "yunion.io/x/cloudmux/pkg/apis/compute"
  22. "yunion.io/x/cloudmux/pkg/cloudprovider"
  23. "yunion.io/x/cloudmux/pkg/multicloud"
  24. )
  25. const (
  26. VPC_STATUS_ACTIVE = "ACTIVE"
  27. VPC_STATUS_DOWN = "DOWN"
  28. VPC_STATUS_BUILD = "BUILD"
  29. VPC_STATUS_ERROR = "ERROR"
  30. )
  31. type SVpc struct {
  32. multicloud.SVpc
  33. OpenStackTags
  34. region *SRegion
  35. AdminStateUp bool
  36. AvailabilityZoneHints []string
  37. AvailabilityZones []string
  38. CreatedAt time.Time
  39. DnsDomain string
  40. Id string
  41. Ipv4AddressScope string
  42. Ipv6AddressScope string
  43. L2Adjacency bool
  44. Mtu int
  45. Name string
  46. PortSecurityEnabled bool
  47. ProjectID string
  48. QosPolicyID string
  49. RevisionNumber int
  50. External bool `json:"router:external"`
  51. Shared bool
  52. Status string
  53. Subnets []string
  54. TenantID string
  55. UpdatedAt time.Time
  56. VlanTransparent bool
  57. Fescription string
  58. IsDefault bool
  59. NetworkType string `json:"provider:network_type"` // flat, vlan, vxlan, or gre ...
  60. PhysicalNetwork string `json:"provider:physical_network"`
  61. SegmentationId string `json:"provider:segmentation_id"`
  62. }
  63. func (vpc *SVpc) GetId() string {
  64. return vpc.Id
  65. }
  66. func (vpc *SVpc) GetName() string {
  67. if len(vpc.Name) > 0 {
  68. return vpc.Name
  69. }
  70. return vpc.Id
  71. }
  72. func (vpc *SVpc) GetGlobalId() string {
  73. return vpc.Id
  74. }
  75. func (vpc *SVpc) IsEmulated() bool {
  76. return false
  77. }
  78. func (vpc *SVpc) GetIsDefault() bool {
  79. return vpc.IsDefault
  80. }
  81. func (vpc *SVpc) GetCidrBlock() string {
  82. return ""
  83. }
  84. func (vpc *SVpc) GetStatus() string {
  85. switch vpc.Status {
  86. case VPC_STATUS_ACTIVE:
  87. return api.VPC_STATUS_AVAILABLE
  88. case VPC_STATUS_BUILD, VPC_STATUS_DOWN:
  89. return api.VPC_STATUS_PENDING
  90. case VPC_STATUS_ERROR:
  91. return api.VPC_STATUS_FAILED
  92. default:
  93. return api.VPC_STATUS_UNKNOWN
  94. }
  95. }
  96. func (vpc *SVpc) Delete() error {
  97. return vpc.region.DeleteVpc(vpc.Id)
  98. }
  99. func (region *SRegion) DeleteVpc(vpcId string) error {
  100. resource := fmt.Sprintf("/v2.0/networks/%s", vpcId)
  101. _, err := region.vpcDelete(resource)
  102. return err
  103. }
  104. func (vpc *SVpc) GetISecurityGroups() ([]cloudprovider.ICloudSecurityGroup, error) {
  105. return []cloudprovider.ICloudSecurityGroup{}, nil
  106. }
  107. func (vpc *SVpc) GetIRouteTables() ([]cloudprovider.ICloudRouteTable, error) {
  108. if vpc.PhysicalNetwork == "public" {
  109. return []cloudprovider.ICloudRouteTable{}, nil
  110. }
  111. err := vpc.region.fetchrouters()
  112. if err != nil {
  113. return nil, errors.Wrap(err, "vpc.region.fetchrouters()")
  114. }
  115. routeTables := []SRouteTable{}
  116. for index, router := range vpc.region.routers {
  117. if len(router.Routes) < 1 {
  118. continue
  119. }
  120. for _, port := range router.ports {
  121. if port.NetworkID == vpc.GetId() {
  122. routeTable := SRouteTable{}
  123. routeTable.entries = router.Routes
  124. routeTable.router = &vpc.region.routers[index]
  125. routeTable.vpc = vpc
  126. routeTables = append(routeTables, routeTable)
  127. break
  128. }
  129. }
  130. }
  131. ret := []cloudprovider.ICloudRouteTable{}
  132. for i := range routeTables {
  133. ret = append(ret, &routeTables[i])
  134. }
  135. return ret, nil
  136. }
  137. func (self *SVpc) GetIRouteTableById(routeTableId string) (cloudprovider.ICloudRouteTable, error) {
  138. return nil, cloudprovider.ErrNotSupported
  139. }
  140. func (vpc *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) {
  141. iwires, err := vpc.GetIWires()
  142. if err != nil {
  143. return nil, errors.Wrap(err, "GetIWires")
  144. }
  145. for i := range iwires {
  146. if iwires[i].GetGlobalId() == wireId {
  147. return iwires[i], nil
  148. }
  149. }
  150. return nil, cloudprovider.ErrNotFound
  151. }
  152. func (vpc *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) {
  153. return []cloudprovider.ICloudWire{&SWire{vpc: vpc}}, nil
  154. }
  155. func (vpc *SVpc) GetRegion() cloudprovider.ICloudRegion {
  156. return vpc.region
  157. }
  158. func (region *SRegion) GetVpc(vpcId string) (*SVpc, error) {
  159. vpc := &SVpc{region: region}
  160. resource := fmt.Sprintf("/v2.0/networks/%s", vpcId)
  161. resp, err := region.vpcGet(resource)
  162. if err != nil {
  163. return nil, errors.Wrapf(err, "vpcGet(%s)", resource)
  164. }
  165. err = resp.Unmarshal(vpc, "network")
  166. if err != nil {
  167. return nil, errors.Wrap(err, "resp.Unmarshal")
  168. }
  169. return vpc, nil
  170. }
  171. func (region *SRegion) GetVpcs(projectId string) ([]SVpc, error) {
  172. vpcs := []SVpc{}
  173. resource := "/v2.0/networks"
  174. query := url.Values{}
  175. if len(projectId) > 0 {
  176. query.Set("tenant_id", projectId)
  177. }
  178. for {
  179. resp, err := region.vpcList(resource, query)
  180. if err != nil {
  181. return nil, errors.Wrapf(err, "vpcList.%s", resource)
  182. }
  183. part := struct {
  184. Networks []SVpc
  185. NetworksLinks SNextLinks
  186. }{}
  187. err = resp.Unmarshal(&part)
  188. if err != nil {
  189. return nil, errors.Wrap(err, "resp.Unmarshal")
  190. }
  191. vpcs = append(vpcs, part.Networks...)
  192. marker := part.NetworksLinks.GetNextMark()
  193. if len(marker) == 0 {
  194. break
  195. }
  196. query.Set("marker", marker)
  197. }
  198. return vpcs, nil
  199. }
  200. func (vpc *SVpc) Refresh() error {
  201. _vpc, err := vpc.region.GetVpc(vpc.Id)
  202. if err != nil {
  203. return errors.Wrapf(err, "GetVpc(%s)", vpc.Id)
  204. }
  205. return jsonutils.Update(vpc, _vpc)
  206. }
  207. func (region *SRegion) CreateVpc(name, desc string) (*SVpc, error) {
  208. params := map[string]map[string]string{
  209. "network": {
  210. "name": name,
  211. "description": desc,
  212. },
  213. }
  214. resource := "/v2.0/networks"
  215. resp, err := region.vpcPost(resource, params)
  216. if err != nil {
  217. return nil, errors.Wrap(err, "vpcPost")
  218. }
  219. vpc := &SVpc{region: region}
  220. err = resp.Unmarshal(vpc, "network")
  221. if err != nil {
  222. return nil, errors.Wrap(err, "resp.Unmarshal")
  223. }
  224. return vpc, nil
  225. }