clients.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. // Package clients contains functions for creating OpenStack service clients
  2. // for use in acceptance tests. It also manages the required environment
  3. // variables to run the tests.
  4. package clients
  5. import (
  6. "fmt"
  7. "net/http"
  8. "os"
  9. "strings"
  10. "devel.mephi.ru/iacherepanov/openstack-gophercloud"
  11. "devel.mephi.ru/iacherepanov/openstack-gophercloud/openstack"
  12. "devel.mephi.ru/iacherepanov/openstack-gophercloud/openstack/blockstorage/noauth"
  13. )
  14. // AcceptanceTestChoices contains image and flavor selections for use by the acceptance tests.
  15. type AcceptanceTestChoices struct {
  16. // ImageID contains the ID of a valid image.
  17. ImageID string
  18. // FlavorID contains the ID of a valid flavor.
  19. FlavorID string
  20. // FlavorIDResize contains the ID of a different flavor available on the same OpenStack installation, that is distinct
  21. // from FlavorID.
  22. FlavorIDResize string
  23. // FloatingIPPool contains the name of the pool from where to obtain floating IPs.
  24. FloatingIPPoolName string
  25. // NetworkName is the name of a network to launch the instance on.
  26. NetworkName string
  27. // ExternalNetworkID is the network ID of the external network.
  28. ExternalNetworkID string
  29. // ShareNetworkID is the Manila Share network ID
  30. ShareNetworkID string
  31. // DBDatastoreType is the datastore type for DB tests.
  32. DBDatastoreType string
  33. // DBDatastoreTypeID is the datastore type version for DB tests.
  34. DBDatastoreVersion string
  35. }
  36. // AcceptanceTestChoicesFromEnv populates a ComputeChoices struct from environment variables.
  37. // If any required state is missing, an `error` will be returned that enumerates the missing properties.
  38. func AcceptanceTestChoicesFromEnv() (*AcceptanceTestChoices, error) {
  39. imageID := os.Getenv("OS_IMAGE_ID")
  40. flavorID := os.Getenv("OS_FLAVOR_ID")
  41. flavorIDResize := os.Getenv("OS_FLAVOR_ID_RESIZE")
  42. networkName := os.Getenv("OS_NETWORK_NAME")
  43. floatingIPPoolName := os.Getenv("OS_POOL_NAME")
  44. externalNetworkID := os.Getenv("OS_EXTGW_ID")
  45. shareNetworkID := os.Getenv("OS_SHARE_NETWORK_ID")
  46. dbDatastoreType := os.Getenv("OS_DB_DATASTORE_TYPE")
  47. dbDatastoreVersion := os.Getenv("OS_DB_DATASTORE_VERSION")
  48. missing := make([]string, 0, 3)
  49. if imageID == "" {
  50. missing = append(missing, "OS_IMAGE_ID")
  51. }
  52. if flavorID == "" {
  53. missing = append(missing, "OS_FLAVOR_ID")
  54. }
  55. if flavorIDResize == "" {
  56. missing = append(missing, "OS_FLAVOR_ID_RESIZE")
  57. }
  58. if floatingIPPoolName == "" {
  59. missing = append(missing, "OS_POOL_NAME")
  60. }
  61. if externalNetworkID == "" {
  62. missing = append(missing, "OS_EXTGW_ID")
  63. }
  64. if networkName == "" {
  65. networkName = "private"
  66. }
  67. if shareNetworkID == "" {
  68. missing = append(missing, "OS_SHARE_NETWORK_ID")
  69. }
  70. notDistinct := ""
  71. if flavorID == flavorIDResize {
  72. notDistinct = "OS_FLAVOR_ID and OS_FLAVOR_ID_RESIZE must be distinct."
  73. }
  74. if len(missing) > 0 || notDistinct != "" {
  75. text := "You're missing some important setup:\n"
  76. if len(missing) > 0 {
  77. text += " * These environment variables must be provided: " + strings.Join(missing, ", ") + "\n"
  78. }
  79. if notDistinct != "" {
  80. text += " * " + notDistinct + "\n"
  81. }
  82. return nil, fmt.Errorf(text)
  83. }
  84. return &AcceptanceTestChoices{
  85. ImageID: imageID,
  86. FlavorID: flavorID,
  87. FlavorIDResize: flavorIDResize,
  88. FloatingIPPoolName: floatingIPPoolName,
  89. NetworkName: networkName,
  90. ExternalNetworkID: externalNetworkID,
  91. ShareNetworkID: shareNetworkID,
  92. DBDatastoreType: dbDatastoreType,
  93. DBDatastoreVersion: dbDatastoreVersion,
  94. }, nil
  95. }
  96. // NewBlockStorageV1Client returns a *ServiceClient for making calls
  97. // to the OpenStack Block Storage v1 API. An error will be returned
  98. // if authentication or client creation was not possible.
  99. func NewBlockStorageV1Client() (*gophercloud.ServiceClient, error) {
  100. ao, err := openstack.AuthOptionsFromEnv()
  101. if err != nil {
  102. return nil, err
  103. }
  104. client, err := openstack.AuthenticatedClient(ao)
  105. if err != nil {
  106. return nil, err
  107. }
  108. client = configureDebug(client)
  109. return openstack.NewBlockStorageV1(client, gophercloud.EndpointOpts{
  110. Region: os.Getenv("OS_REGION_NAME"),
  111. })
  112. }
  113. // NewBlockStorageV2Client returns a *ServiceClient for making calls
  114. // to the OpenStack Block Storage v2 API. An error will be returned
  115. // if authentication or client creation was not possible.
  116. func NewBlockStorageV2Client() (*gophercloud.ServiceClient, error) {
  117. ao, err := openstack.AuthOptionsFromEnv()
  118. if err != nil {
  119. return nil, err
  120. }
  121. client, err := openstack.AuthenticatedClient(ao)
  122. if err != nil {
  123. return nil, err
  124. }
  125. client = configureDebug(client)
  126. return openstack.NewBlockStorageV2(client, gophercloud.EndpointOpts{
  127. Region: os.Getenv("OS_REGION_NAME"),
  128. })
  129. }
  130. // NewBlockStorageV3Client returns a *ServiceClient for making calls
  131. // to the OpenStack Block Storage v3 API. An error will be returned
  132. // if authentication or client creation was not possible.
  133. func NewBlockStorageV3Client() (*gophercloud.ServiceClient, error) {
  134. ao, err := openstack.AuthOptionsFromEnv()
  135. if err != nil {
  136. return nil, err
  137. }
  138. client, err := openstack.AuthenticatedClient(ao)
  139. if err != nil {
  140. return nil, err
  141. }
  142. client = configureDebug(client)
  143. return openstack.NewBlockStorageV3(client, gophercloud.EndpointOpts{
  144. Region: os.Getenv("OS_REGION_NAME"),
  145. })
  146. }
  147. // NewBlockStorageV2NoAuthClient returns a noauth *ServiceClient for
  148. // making calls to the OpenStack Block Storage v2 API. An error will be
  149. // returned if client creation was not possible.
  150. func NewBlockStorageV2NoAuthClient() (*gophercloud.ServiceClient, error) {
  151. client, err := noauth.NewClient(gophercloud.AuthOptions{
  152. Username: os.Getenv("OS_USERNAME"),
  153. TenantName: os.Getenv("OS_TENANT_NAME"),
  154. })
  155. if err != nil {
  156. return nil, err
  157. }
  158. client = configureDebug(client)
  159. return noauth.NewBlockStorageNoAuth(client, noauth.EndpointOpts{
  160. CinderEndpoint: os.Getenv("CINDER_ENDPOINT"),
  161. })
  162. }
  163. // NewBlockStorageV3NoAuthClient returns a noauth *ServiceClient for
  164. // making calls to the OpenStack Block Storage v2 API. An error will be
  165. // returned if client creation was not possible.
  166. func NewBlockStorageV3NoAuthClient() (*gophercloud.ServiceClient, error) {
  167. client, err := noauth.NewClient(gophercloud.AuthOptions{
  168. Username: os.Getenv("OS_USERNAME"),
  169. TenantName: os.Getenv("OS_TENANT_NAME"),
  170. })
  171. if err != nil {
  172. return nil, err
  173. }
  174. client = configureDebug(client)
  175. return noauth.NewBlockStorageNoAuth(client, noauth.EndpointOpts{
  176. CinderEndpoint: os.Getenv("CINDER_ENDPOINT"),
  177. })
  178. }
  179. // NewComputeV2Client returns a *ServiceClient for making calls
  180. // to the OpenStack Compute v2 API. An error will be returned
  181. // if authentication or client creation was not possible.
  182. func NewComputeV2Client() (*gophercloud.ServiceClient, error) {
  183. ao, err := openstack.AuthOptionsFromEnv()
  184. if err != nil {
  185. return nil, err
  186. }
  187. client, err := openstack.AuthenticatedClient(ao)
  188. if err != nil {
  189. return nil, err
  190. }
  191. client = configureDebug(client)
  192. return openstack.NewComputeV2(client, gophercloud.EndpointOpts{
  193. Region: os.Getenv("OS_REGION_NAME"),
  194. })
  195. }
  196. // NewDBV1Client returns a *ServiceClient for making calls
  197. // to the OpenStack Database v1 API. An error will be returned
  198. // if authentication or client creation was not possible.
  199. func NewDBV1Client() (*gophercloud.ServiceClient, error) {
  200. ao, err := openstack.AuthOptionsFromEnv()
  201. if err != nil {
  202. return nil, err
  203. }
  204. client, err := openstack.AuthenticatedClient(ao)
  205. if err != nil {
  206. return nil, err
  207. }
  208. client = configureDebug(client)
  209. return openstack.NewDBV1(client, gophercloud.EndpointOpts{
  210. Region: os.Getenv("OS_REGION_NAME"),
  211. })
  212. }
  213. // NewDNSV2Client returns a *ServiceClient for making calls
  214. // to the OpenStack Compute v2 API. An error will be returned
  215. // if authentication or client creation was not possible.
  216. func NewDNSV2Client() (*gophercloud.ServiceClient, error) {
  217. ao, err := openstack.AuthOptionsFromEnv()
  218. if err != nil {
  219. return nil, err
  220. }
  221. client, err := openstack.AuthenticatedClient(ao)
  222. if err != nil {
  223. return nil, err
  224. }
  225. client = configureDebug(client)
  226. return openstack.NewDNSV2(client, gophercloud.EndpointOpts{
  227. Region: os.Getenv("OS_REGION_NAME"),
  228. })
  229. }
  230. // NewIdentityV2Client returns a *ServiceClient for making calls
  231. // to the OpenStack Identity v2 API. An error will be returned
  232. // if authentication or client creation was not possible.
  233. func NewIdentityV2Client() (*gophercloud.ServiceClient, error) {
  234. ao, err := openstack.AuthOptionsFromEnv()
  235. if err != nil {
  236. return nil, err
  237. }
  238. client, err := openstack.AuthenticatedClient(ao)
  239. if err != nil {
  240. return nil, err
  241. }
  242. client = configureDebug(client)
  243. return openstack.NewIdentityV2(client, gophercloud.EndpointOpts{
  244. Region: os.Getenv("OS_REGION_NAME"),
  245. })
  246. }
  247. // NewIdentityV2AdminClient returns a *ServiceClient for making calls
  248. // to the Admin Endpoint of the OpenStack Identity v2 API. An error
  249. // will be returned if authentication or client creation was not possible.
  250. func NewIdentityV2AdminClient() (*gophercloud.ServiceClient, error) {
  251. ao, err := openstack.AuthOptionsFromEnv()
  252. if err != nil {
  253. return nil, err
  254. }
  255. client, err := openstack.AuthenticatedClient(ao)
  256. if err != nil {
  257. return nil, err
  258. }
  259. client = configureDebug(client)
  260. return openstack.NewIdentityV2(client, gophercloud.EndpointOpts{
  261. Region: os.Getenv("OS_REGION_NAME"),
  262. Availability: gophercloud.AvailabilityAdmin,
  263. })
  264. }
  265. // NewIdentityV2UnauthenticatedClient returns an unauthenticated *ServiceClient
  266. // for the OpenStack Identity v2 API. An error will be returned if
  267. // authentication or client creation was not possible.
  268. func NewIdentityV2UnauthenticatedClient() (*gophercloud.ServiceClient, error) {
  269. ao, err := openstack.AuthOptionsFromEnv()
  270. if err != nil {
  271. return nil, err
  272. }
  273. client, err := openstack.NewClient(ao.IdentityEndpoint)
  274. if err != nil {
  275. return nil, err
  276. }
  277. client = configureDebug(client)
  278. return openstack.NewIdentityV2(client, gophercloud.EndpointOpts{})
  279. }
  280. // NewIdentityV3Client returns a *ServiceClient for making calls
  281. // to the OpenStack Identity v3 API. An error will be returned
  282. // if authentication or client creation was not possible.
  283. func NewIdentityV3Client() (*gophercloud.ServiceClient, error) {
  284. ao, err := openstack.AuthOptionsFromEnv()
  285. if err != nil {
  286. return nil, err
  287. }
  288. client, err := openstack.AuthenticatedClient(ao)
  289. if err != nil {
  290. return nil, err
  291. }
  292. client = configureDebug(client)
  293. return openstack.NewIdentityV3(client, gophercloud.EndpointOpts{
  294. Region: os.Getenv("OS_REGION_NAME"),
  295. })
  296. }
  297. // NewIdentityV3UnauthenticatedClient returns an unauthenticated *ServiceClient
  298. // for the OpenStack Identity v3 API. An error will be returned if
  299. // authentication or client creation was not possible.
  300. func NewIdentityV3UnauthenticatedClient() (*gophercloud.ServiceClient, error) {
  301. ao, err := openstack.AuthOptionsFromEnv()
  302. if err != nil {
  303. return nil, err
  304. }
  305. client, err := openstack.NewClient(ao.IdentityEndpoint)
  306. if err != nil {
  307. return nil, err
  308. }
  309. client = configureDebug(client)
  310. return openstack.NewIdentityV3(client, gophercloud.EndpointOpts{})
  311. }
  312. // NewImageServiceV2Client returns a *ServiceClient for making calls to the
  313. // OpenStack Image v2 API. An error will be returned if authentication or
  314. // client creation was not possible.
  315. func NewImageServiceV2Client() (*gophercloud.ServiceClient, error) {
  316. ao, err := openstack.AuthOptionsFromEnv()
  317. if err != nil {
  318. return nil, err
  319. }
  320. client, err := openstack.AuthenticatedClient(ao)
  321. if err != nil {
  322. return nil, err
  323. }
  324. client = configureDebug(client)
  325. return openstack.NewImageServiceV2(client, gophercloud.EndpointOpts{
  326. Region: os.Getenv("OS_REGION_NAME"),
  327. })
  328. }
  329. // NewNetworkV2Client returns a *ServiceClient for making calls to the
  330. // OpenStack Networking v2 API. An error will be returned if authentication
  331. // or client creation was not possible.
  332. func NewNetworkV2Client() (*gophercloud.ServiceClient, error) {
  333. ao, err := openstack.AuthOptionsFromEnv()
  334. if err != nil {
  335. return nil, err
  336. }
  337. client, err := openstack.AuthenticatedClient(ao)
  338. if err != nil {
  339. return nil, err
  340. }
  341. client = configureDebug(client)
  342. return openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
  343. Region: os.Getenv("OS_REGION_NAME"),
  344. })
  345. }
  346. // NewObjectStorageV1Client returns a *ServiceClient for making calls to the
  347. // OpenStack Object Storage v1 API. An error will be returned if authentication
  348. // or client creation was not possible.
  349. func NewObjectStorageV1Client() (*gophercloud.ServiceClient, error) {
  350. ao, err := openstack.AuthOptionsFromEnv()
  351. if err != nil {
  352. return nil, err
  353. }
  354. client, err := openstack.AuthenticatedClient(ao)
  355. if err != nil {
  356. return nil, err
  357. }
  358. client = configureDebug(client)
  359. return openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{
  360. Region: os.Getenv("OS_REGION_NAME"),
  361. })
  362. }
  363. // NewSharedFileSystemV2Client returns a *ServiceClient for making calls
  364. // to the OpenStack Shared File System v2 API. An error will be returned
  365. // if authentication or client creation was not possible.
  366. func NewSharedFileSystemV2Client() (*gophercloud.ServiceClient, error) {
  367. ao, err := openstack.AuthOptionsFromEnv()
  368. if err != nil {
  369. return nil, err
  370. }
  371. client, err := openstack.AuthenticatedClient(ao)
  372. if err != nil {
  373. return nil, err
  374. }
  375. client = configureDebug(client)
  376. return openstack.NewSharedFileSystemV2(client, gophercloud.EndpointOpts{
  377. Region: os.Getenv("OS_REGION_NAME"),
  378. })
  379. }
  380. // NewLoadBalancerV2Client returns a *ServiceClient for making calls to the
  381. // OpenStack Octavia v2 API. An error will be returned if authentication
  382. // or client creation was not possible.
  383. func NewLoadBalancerV2Client() (*gophercloud.ServiceClient, error) {
  384. ao, err := openstack.AuthOptionsFromEnv()
  385. if err != nil {
  386. return nil, err
  387. }
  388. client, err := openstack.AuthenticatedClient(ao)
  389. if err != nil {
  390. return nil, err
  391. }
  392. client = configureDebug(client)
  393. return openstack.NewLoadBalancerV2(client, gophercloud.EndpointOpts{
  394. Region: os.Getenv("OS_REGION_NAME"),
  395. })
  396. }
  397. // NewClusteringV1Client returns a *ServiceClient for making calls
  398. // to the OpenStack Clustering v1 API. An error will be returned
  399. // if authentication or client creation was not possible.
  400. func NewClusteringV1Client() (*gophercloud.ServiceClient, error) {
  401. ao, err := openstack.AuthOptionsFromEnv()
  402. if err != nil {
  403. return nil, err
  404. }
  405. client, err := openstack.AuthenticatedClient(ao)
  406. if err != nil {
  407. return nil, err
  408. }
  409. return openstack.NewClusteringV1(client, gophercloud.EndpointOpts{
  410. Region: os.Getenv("OS_REGION_NAME"),
  411. })
  412. }
  413. // NewMessagingV2Client returns a *ServiceClient for making calls
  414. // to the OpenStack Messaging (Zaqar) v2 API. An error will be returned
  415. // if authentication or client creation was not possible.
  416. func NewMessagingV2Client(clientID string) (*gophercloud.ServiceClient, error) {
  417. ao, err := openstack.AuthOptionsFromEnv()
  418. if err != nil {
  419. return nil, err
  420. }
  421. client, err := openstack.AuthenticatedClient(ao)
  422. if err != nil {
  423. return nil, err
  424. }
  425. client = configureDebug(client)
  426. return openstack.NewMessagingV2(client, clientID, gophercloud.EndpointOpts{
  427. Region: os.Getenv("OS_REGION_NAME"),
  428. })
  429. }
  430. // NewContainerV1Client returns a *ServiceClient for making calls
  431. // to the OpenStack Container V1 API. An error will be returned
  432. // if authentication or client creation was not possible.
  433. func NewContainerV1Client() (*gophercloud.ServiceClient, error) {
  434. ao, err := openstack.AuthOptionsFromEnv()
  435. if err != nil {
  436. return nil, err
  437. }
  438. client, err := openstack.AuthenticatedClient(ao)
  439. if err != nil {
  440. return nil, err
  441. }
  442. return openstack.NewContainerV1(client, gophercloud.EndpointOpts{
  443. Region: os.Getenv("OS_REGION_NAME"),
  444. })
  445. }
  446. // configureDebug will configure the provider client to print the API
  447. // requests and responses if OS_DEBUG is enabled.
  448. func configureDebug(client *gophercloud.ProviderClient) *gophercloud.ProviderClient {
  449. if os.Getenv("OS_DEBUG") != "" {
  450. client.HTTPClient = http.Client{
  451. Transport: &LogRoundTripper{
  452. Rt: &http.Transport{},
  453. },
  454. }
  455. }
  456. return client
  457. }