/acceptance/openstack/networking/v2/networking.go

https://github.com/gophercloud/gophercloud · Go · 568 lines · 406 code · 118 blank · 44 comment · 68 complexity · cb08e8ce7001a908ba9187303ce8b418 MD5 · raw file

  1. package v2
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/gophercloud/gophercloud"
  6. "github.com/gophercloud/gophercloud/acceptance/tools"
  7. "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/extradhcpopts"
  8. "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/portsecurity"
  9. "github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
  10. "github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
  11. "github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
  12. th "github.com/gophercloud/gophercloud/testhelper"
  13. )
  14. // PortWithExtraDHCPOpts represents a port with extra DHCP options configuration.
  15. type PortWithExtraDHCPOpts struct {
  16. ports.Port
  17. extradhcpopts.ExtraDHCPOptsExt
  18. }
  19. // CreateNetwork will create basic network. An error will be returned if the
  20. // network could not be created.
  21. func CreateNetwork(t *testing.T, client *gophercloud.ServiceClient) (*networks.Network, error) {
  22. networkName := tools.RandomString("TESTACC-", 8)
  23. networkDescription := tools.RandomString("TESTACC-DESC-", 8)
  24. createOpts := networks.CreateOpts{
  25. Name: networkName,
  26. Description: networkDescription,
  27. AdminStateUp: gophercloud.Enabled,
  28. }
  29. t.Logf("Attempting to create network: %s", networkName)
  30. network, err := networks.Create(client, createOpts).Extract()
  31. if err != nil {
  32. return network, err
  33. }
  34. t.Logf("Successfully created network.")
  35. th.AssertEquals(t, network.Name, networkName)
  36. th.AssertEquals(t, network.Description, networkDescription)
  37. return network, nil
  38. }
  39. // CreateNetworkWithoutPortSecurity will create a network without port security.
  40. // An error will be returned if the network could not be created.
  41. func CreateNetworkWithoutPortSecurity(t *testing.T, client *gophercloud.ServiceClient) (*networks.Network, error) {
  42. networkName := tools.RandomString("TESTACC-", 8)
  43. networkCreateOpts := networks.CreateOpts{
  44. Name: networkName,
  45. AdminStateUp: gophercloud.Enabled,
  46. }
  47. iFalse := false
  48. createOpts := portsecurity.NetworkCreateOptsExt{
  49. CreateOptsBuilder: networkCreateOpts,
  50. PortSecurityEnabled: &iFalse,
  51. }
  52. t.Logf("Attempting to create network: %s", networkName)
  53. network, err := networks.Create(client, createOpts).Extract()
  54. if err != nil {
  55. return network, err
  56. }
  57. t.Logf("Successfully created network.")
  58. th.AssertEquals(t, network.Name, networkName)
  59. return network, nil
  60. }
  61. // CreatePort will create a port on the specified subnet. An error will be
  62. // returned if the port could not be created.
  63. func CreatePort(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) {
  64. portName := tools.RandomString("TESTACC-", 8)
  65. portDescription := tools.RandomString("TESTACC-DESC-", 8)
  66. t.Logf("Attempting to create port: %s", portName)
  67. createOpts := ports.CreateOpts{
  68. NetworkID: networkID,
  69. Name: portName,
  70. Description: portDescription,
  71. AdminStateUp: gophercloud.Enabled,
  72. FixedIPs: []ports.IP{ports.IP{SubnetID: subnetID}},
  73. }
  74. port, err := ports.Create(client, createOpts).Extract()
  75. if err != nil {
  76. return port, err
  77. }
  78. if err := WaitForPortToCreate(client, port.ID); err != nil {
  79. return port, err
  80. }
  81. newPort, err := ports.Get(client, port.ID).Extract()
  82. if err != nil {
  83. return newPort, err
  84. }
  85. t.Logf("Successfully created port: %s", portName)
  86. th.AssertEquals(t, port.Name, portName)
  87. th.AssertEquals(t, port.Description, portDescription)
  88. return newPort, nil
  89. }
  90. // CreatePortWithNoSecurityGroup will create a port with no security group
  91. // attached. An error will be returned if the port could not be created.
  92. func CreatePortWithNoSecurityGroup(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) {
  93. portName := tools.RandomString("TESTACC-", 8)
  94. iFalse := false
  95. t.Logf("Attempting to create port: %s", portName)
  96. createOpts := ports.CreateOpts{
  97. NetworkID: networkID,
  98. Name: portName,
  99. AdminStateUp: &iFalse,
  100. FixedIPs: []ports.IP{ports.IP{SubnetID: subnetID}},
  101. SecurityGroups: &[]string{},
  102. }
  103. port, err := ports.Create(client, createOpts).Extract()
  104. if err != nil {
  105. return port, err
  106. }
  107. if err := WaitForPortToCreate(client, port.ID); err != nil {
  108. return port, err
  109. }
  110. newPort, err := ports.Get(client, port.ID).Extract()
  111. if err != nil {
  112. return newPort, err
  113. }
  114. t.Logf("Successfully created port: %s", portName)
  115. th.AssertEquals(t, port.Name, portName)
  116. return newPort, nil
  117. }
  118. // CreatePortWithoutPortSecurity will create a port without port security on the
  119. // specified subnet. An error will be returned if the port could not be created.
  120. func CreatePortWithoutPortSecurity(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) {
  121. portName := tools.RandomString("TESTACC-", 8)
  122. t.Logf("Attempting to create port: %s", portName)
  123. portCreateOpts := ports.CreateOpts{
  124. NetworkID: networkID,
  125. Name: portName,
  126. AdminStateUp: gophercloud.Enabled,
  127. FixedIPs: []ports.IP{ports.IP{SubnetID: subnetID}},
  128. }
  129. iFalse := false
  130. createOpts := portsecurity.PortCreateOptsExt{
  131. CreateOptsBuilder: portCreateOpts,
  132. PortSecurityEnabled: &iFalse,
  133. }
  134. port, err := ports.Create(client, createOpts).Extract()
  135. if err != nil {
  136. return port, err
  137. }
  138. if err := WaitForPortToCreate(client, port.ID); err != nil {
  139. return port, err
  140. }
  141. newPort, err := ports.Get(client, port.ID).Extract()
  142. if err != nil {
  143. return newPort, err
  144. }
  145. t.Logf("Successfully created port: %s", portName)
  146. th.AssertEquals(t, port.Name, portName)
  147. return newPort, nil
  148. }
  149. // CreatePortWithExtraDHCPOpts will create a port with DHCP options on the
  150. // specified subnet. An error will be returned if the port could not be created.
  151. func CreatePortWithExtraDHCPOpts(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*PortWithExtraDHCPOpts, error) {
  152. portName := tools.RandomString("TESTACC-", 8)
  153. t.Logf("Attempting to create port: %s", portName)
  154. portCreateOpts := ports.CreateOpts{
  155. NetworkID: networkID,
  156. Name: portName,
  157. AdminStateUp: gophercloud.Enabled,
  158. FixedIPs: []ports.IP{ports.IP{SubnetID: subnetID}},
  159. }
  160. createOpts := extradhcpopts.CreateOptsExt{
  161. CreateOptsBuilder: portCreateOpts,
  162. ExtraDHCPOpts: []extradhcpopts.CreateExtraDHCPOpt{
  163. {
  164. OptName: "test_option_1",
  165. OptValue: "test_value_1",
  166. },
  167. },
  168. }
  169. port := &PortWithExtraDHCPOpts{}
  170. err := ports.Create(client, createOpts).ExtractInto(port)
  171. if err != nil {
  172. return nil, err
  173. }
  174. if err := WaitForPortToCreate(client, port.ID); err != nil {
  175. return nil, err
  176. }
  177. err = ports.Get(client, port.ID).ExtractInto(port)
  178. if err != nil {
  179. return port, err
  180. }
  181. t.Logf("Successfully created port: %s", portName)
  182. return port, nil
  183. }
  184. // CreatePortWithMultipleFixedIPs will create a port with two FixedIPs on the
  185. // specified subnet. An error will be returned if the port could not be created.
  186. func CreatePortWithMultipleFixedIPs(t *testing.T, client *gophercloud.ServiceClient, networkID, subnetID string) (*ports.Port, error) {
  187. portName := tools.RandomString("TESTACC-", 8)
  188. portDescription := tools.RandomString("TESTACC-DESC-", 8)
  189. t.Logf("Attempting to create port with two fixed IPs: %s", portName)
  190. createOpts := ports.CreateOpts{
  191. NetworkID: networkID,
  192. Name: portName,
  193. Description: portDescription,
  194. AdminStateUp: gophercloud.Enabled,
  195. FixedIPs: []ports.IP{ports.IP{SubnetID: subnetID}, ports.IP{SubnetID: subnetID}},
  196. }
  197. port, err := ports.Create(client, createOpts).Extract()
  198. if err != nil {
  199. return port, err
  200. }
  201. if err := WaitForPortToCreate(client, port.ID); err != nil {
  202. return port, err
  203. }
  204. newPort, err := ports.Get(client, port.ID).Extract()
  205. if err != nil {
  206. return newPort, err
  207. }
  208. t.Logf("Successfully created port: %s", portName)
  209. th.AssertEquals(t, port.Name, portName)
  210. th.AssertEquals(t, port.Description, portDescription)
  211. if len(port.FixedIPs) != 2 {
  212. t.Fatalf("Failed to create a port with two fixed IPs: %s", portName)
  213. }
  214. return newPort, nil
  215. }
  216. // CreateSubnet will create a subnet on the specified Network ID. An error
  217. // will be returned if the subnet could not be created.
  218. func CreateSubnet(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) {
  219. subnetName := tools.RandomString("TESTACC-", 8)
  220. subnetDescription := tools.RandomString("TESTACC-DESC-", 8)
  221. subnetOctet := tools.RandomInt(1, 250)
  222. subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet)
  223. subnetGateway := fmt.Sprintf("192.168.%d.1", subnetOctet)
  224. createOpts := subnets.CreateOpts{
  225. NetworkID: networkID,
  226. CIDR: subnetCIDR,
  227. IPVersion: 4,
  228. Name: subnetName,
  229. Description: subnetDescription,
  230. EnableDHCP: gophercloud.Disabled,
  231. GatewayIP: &subnetGateway,
  232. }
  233. t.Logf("Attempting to create subnet: %s", subnetName)
  234. subnet, err := subnets.Create(client, createOpts).Extract()
  235. if err != nil {
  236. return subnet, err
  237. }
  238. t.Logf("Successfully created subnet.")
  239. th.AssertEquals(t, subnet.Name, subnetName)
  240. th.AssertEquals(t, subnet.Description, subnetDescription)
  241. th.AssertEquals(t, subnet.GatewayIP, subnetGateway)
  242. th.AssertEquals(t, subnet.CIDR, subnetCIDR)
  243. return subnet, nil
  244. }
  245. // CreateSubnetWithDefaultGateway will create a subnet on the specified Network
  246. // ID and have Neutron set the gateway by default An error will be returned if
  247. // the subnet could not be created.
  248. func CreateSubnetWithDefaultGateway(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) {
  249. subnetName := tools.RandomString("TESTACC-", 8)
  250. subnetOctet := tools.RandomInt(1, 250)
  251. subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet)
  252. defaultGateway := fmt.Sprintf("192.168.%d.1", subnetOctet)
  253. createOpts := subnets.CreateOpts{
  254. NetworkID: networkID,
  255. CIDR: subnetCIDR,
  256. IPVersion: 4,
  257. Name: subnetName,
  258. EnableDHCP: gophercloud.Disabled,
  259. }
  260. t.Logf("Attempting to create subnet: %s", subnetName)
  261. subnet, err := subnets.Create(client, createOpts).Extract()
  262. if err != nil {
  263. return subnet, err
  264. }
  265. t.Logf("Successfully created subnet.")
  266. th.AssertEquals(t, subnet.Name, subnetName)
  267. th.AssertEquals(t, subnet.GatewayIP, defaultGateway)
  268. th.AssertEquals(t, subnet.CIDR, subnetCIDR)
  269. return subnet, nil
  270. }
  271. // CreateSubnetWithNoGateway will create a subnet with no gateway on the
  272. // specified Network ID. An error will be returned if the subnet could not be
  273. // created.
  274. func CreateSubnetWithNoGateway(t *testing.T, client *gophercloud.ServiceClient, networkID string) (*subnets.Subnet, error) {
  275. var noGateway = ""
  276. subnetName := tools.RandomString("TESTACC-", 8)
  277. subnetOctet := tools.RandomInt(1, 250)
  278. subnetCIDR := fmt.Sprintf("192.168.%d.0/24", subnetOctet)
  279. dhcpStart := fmt.Sprintf("192.168.%d.10", subnetOctet)
  280. dhcpEnd := fmt.Sprintf("192.168.%d.200", subnetOctet)
  281. createOpts := subnets.CreateOpts{
  282. NetworkID: networkID,
  283. CIDR: subnetCIDR,
  284. IPVersion: 4,
  285. Name: subnetName,
  286. EnableDHCP: gophercloud.Disabled,
  287. GatewayIP: &noGateway,
  288. AllocationPools: []subnets.AllocationPool{
  289. {
  290. Start: dhcpStart,
  291. End: dhcpEnd,
  292. },
  293. },
  294. }
  295. t.Logf("Attempting to create subnet: %s", subnetName)
  296. subnet, err := subnets.Create(client, createOpts).Extract()
  297. if err != nil {
  298. return subnet, err
  299. }
  300. t.Logf("Successfully created subnet.")
  301. th.AssertEquals(t, subnet.Name, subnetName)
  302. th.AssertEquals(t, subnet.GatewayIP, "")
  303. th.AssertEquals(t, subnet.CIDR, subnetCIDR)
  304. return subnet, nil
  305. }
  306. // CreateSubnetWithSubnetPool will create a subnet associated with the provided subnetpool on the specified Network ID.
  307. // An error will be returned if the subnet or the subnetpool could not be created.
  308. func CreateSubnetWithSubnetPool(t *testing.T, client *gophercloud.ServiceClient, networkID string, subnetPoolID string) (*subnets.Subnet, error) {
  309. subnetName := tools.RandomString("TESTACC-", 8)
  310. subnetOctet := tools.RandomInt(1, 250)
  311. subnetCIDR := fmt.Sprintf("10.%d.0.0/24", subnetOctet)
  312. createOpts := subnets.CreateOpts{
  313. NetworkID: networkID,
  314. CIDR: subnetCIDR,
  315. IPVersion: 4,
  316. Name: subnetName,
  317. EnableDHCP: gophercloud.Disabled,
  318. SubnetPoolID: subnetPoolID,
  319. }
  320. t.Logf("Attempting to create subnet: %s", subnetName)
  321. subnet, err := subnets.Create(client, createOpts).Extract()
  322. if err != nil {
  323. return subnet, err
  324. }
  325. t.Logf("Successfully created subnet.")
  326. th.AssertEquals(t, subnet.Name, subnetName)
  327. th.AssertEquals(t, subnet.CIDR, subnetCIDR)
  328. return subnet, nil
  329. }
  330. // CreateSubnetWithSubnetPoolNoCIDR will create a subnet associated with the
  331. // provided subnetpool on the specified Network ID.
  332. // An error will be returned if the subnet or the subnetpool could not be created.
  333. func CreateSubnetWithSubnetPoolNoCIDR(t *testing.T, client *gophercloud.ServiceClient, networkID string, subnetPoolID string) (*subnets.Subnet, error) {
  334. subnetName := tools.RandomString("TESTACC-", 8)
  335. createOpts := subnets.CreateOpts{
  336. NetworkID: networkID,
  337. IPVersion: 4,
  338. Name: subnetName,
  339. EnableDHCP: gophercloud.Disabled,
  340. SubnetPoolID: subnetPoolID,
  341. }
  342. t.Logf("Attempting to create subnet: %s", subnetName)
  343. subnet, err := subnets.Create(client, createOpts).Extract()
  344. if err != nil {
  345. return subnet, err
  346. }
  347. t.Logf("Successfully created subnet.")
  348. th.AssertEquals(t, subnet.Name, subnetName)
  349. return subnet, nil
  350. }
  351. // CreateSubnetWithSubnetPoolPrefixlen will create a subnet associated with the
  352. // provided subnetpool on the specified Network ID and with overwritten
  353. // prefixlen instead of the default subnetpool prefixlen.
  354. // An error will be returned if the subnet or the subnetpool could not be created.
  355. func CreateSubnetWithSubnetPoolPrefixlen(t *testing.T, client *gophercloud.ServiceClient, networkID string, subnetPoolID string) (*subnets.Subnet, error) {
  356. subnetName := tools.RandomString("TESTACC-", 8)
  357. createOpts := subnets.CreateOpts{
  358. NetworkID: networkID,
  359. IPVersion: 4,
  360. Name: subnetName,
  361. EnableDHCP: gophercloud.Disabled,
  362. SubnetPoolID: subnetPoolID,
  363. Prefixlen: 12,
  364. }
  365. t.Logf("Attempting to create subnet: %s", subnetName)
  366. subnet, err := subnets.Create(client, createOpts).Extract()
  367. if err != nil {
  368. return subnet, err
  369. }
  370. t.Logf("Successfully created subnet.")
  371. th.AssertEquals(t, subnet.Name, subnetName)
  372. return subnet, nil
  373. }
  374. // DeleteNetwork will delete a network with a specified ID. A fatal error will
  375. // occur if the delete was not successful. This works best when used as a
  376. // deferred function.
  377. func DeleteNetwork(t *testing.T, client *gophercloud.ServiceClient, networkID string) {
  378. t.Logf("Attempting to delete network: %s", networkID)
  379. err := networks.Delete(client, networkID).ExtractErr()
  380. if err != nil {
  381. t.Fatalf("Unable to delete network %s: %v", networkID, err)
  382. }
  383. t.Logf("Deleted network: %s", networkID)
  384. }
  385. // DeletePort will delete a port with a specified ID. A fatal error will
  386. // occur if the delete was not successful. This works best when used as a
  387. // deferred function.
  388. func DeletePort(t *testing.T, client *gophercloud.ServiceClient, portID string) {
  389. t.Logf("Attempting to delete port: %s", portID)
  390. err := ports.Delete(client, portID).ExtractErr()
  391. if err != nil {
  392. t.Fatalf("Unable to delete port %s: %v", portID, err)
  393. }
  394. t.Logf("Deleted port: %s", portID)
  395. }
  396. // DeleteSubnet will delete a subnet with a specified ID. A fatal error will
  397. // occur if the delete was not successful. This works best when used as a
  398. // deferred function.
  399. func DeleteSubnet(t *testing.T, client *gophercloud.ServiceClient, subnetID string) {
  400. t.Logf("Attempting to delete subnet: %s", subnetID)
  401. err := subnets.Delete(client, subnetID).ExtractErr()
  402. if err != nil {
  403. t.Fatalf("Unable to delete subnet %s: %v", subnetID, err)
  404. }
  405. t.Logf("Deleted subnet: %s", subnetID)
  406. }
  407. func WaitForPortToCreate(client *gophercloud.ServiceClient, portID string) error {
  408. return tools.WaitFor(func() (bool, error) {
  409. p, err := ports.Get(client, portID).Extract()
  410. if err != nil {
  411. return false, err
  412. }
  413. if p.Status == "ACTIVE" || p.Status == "DOWN" {
  414. return true, nil
  415. }
  416. return false, nil
  417. })
  418. }
  419. // This is duplicated from https://github.com/gophercloud/utils
  420. // so that Gophercloud "core" doesn't have a dependency on the
  421. // complementary utils repository.
  422. func IDFromName(client *gophercloud.ServiceClient, name string) (string, error) {
  423. count := 0
  424. id := ""
  425. listOpts := networks.ListOpts{
  426. Name: name,
  427. }
  428. pages, err := networks.List(client, listOpts).AllPages()
  429. if err != nil {
  430. return "", err
  431. }
  432. all, err := networks.ExtractNetworks(pages)
  433. if err != nil {
  434. return "", err
  435. }
  436. for _, s := range all {
  437. if s.Name == name {
  438. count++
  439. id = s.ID
  440. }
  441. }
  442. switch count {
  443. case 0:
  444. return "", gophercloud.ErrResourceNotFound{Name: name, ResourceType: "network"}
  445. case 1:
  446. return id, nil
  447. default:
  448. return "", gophercloud.ErrMultipleResourcesFound{Name: name, Count: count, ResourceType: "network"}
  449. }
  450. }