summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/everything-you-need-to-know.rst1153
1 files changed, 1153 insertions, 0 deletions
diff --git a/src/everything-you-need-to-know.rst b/src/everything-you-need-to-know.rst
new file mode 100644
index 0000000..f478d55
--- /dev/null
+++ b/src/everything-you-need-to-know.rst
@@ -0,0 +1,1153 @@
1=========================================================
2Everything you need to know about using the OpenStack API
3=========================================================
4
5This document contains a presentation in `presentty`_ format. If you want to
6walk through it like a presentation, install `presentty` and run:
7
8.. code:: bash
9
10 presentty doc/source/user/multi-cloud-demo.rst
11
12The content is hopefully helpful even if it's not being narrated, so it's being
13included in the `shade` docs.
14
15.. _presentty: https://pypi.python.org/pypi/presentty
16
17Everything you need to know about using the OpenStack API
18=========================================================
19
20Who am I?
21=========
22
23Monty Taylor
24
25* OpenStack Infra Core
26* irc: mordred
27* twitter: @e_monty
28
29This Talk is Free Software
30==========================
31
32* http://git.inaugust.com/cgit/inaugust.com/tree/src/everything-you-need-to-know.rst
33
34What are we going to talk about?
35================================
36
37* Overview of some terminology
38* Discussion of SDKs
39* 'Simple' example
40* Step by step through in much more detail
41
42 * Auth
43 * The Catalog
44 * Service Types
45 * Version Discovery
46 * Actually doing things
47 * Microversions
48
49Expected Ranting
50================
51
52* Fixed vs. Floating IPs
53* Build your own images
54* Boot-time scripting with cloud-init
55
56Relevant Docs
57=============
58
59* https://specs.openstack.org/openstack/api-wg/
60* https://service-types.openstack.org/
61* https://developer.openstack.org/api-ref/identity/
62* https://developer.openstack.org/api-ref/compute/
63* https://docs.openstack.org/os-client-config/latest/
64* https://docs.openstack.org/keystoneauth/latest/using-sessions.html
65
66Cloud Terminology
67=================
68
69Let's define a few terms, so that we can use them with ease:
70
71* `cloud` - logically related collection of services
72* `region` - completely independent subset of a given cloud
73* `patron` - human who has an account
74* `user` - account on a cloud
75* `project` - logical collection of cloud resources
76* `domain` - collection of users and projects
77
78Cloud Terminology Relationships
79===============================
80
81* A `cloud` has one or more `regions`
82* A `patron` has one or more `users`
83* A `patron` has one or more `projects`
84* A `cloud` has one or more `domains`
85* In a `cloud` with one `domain` it is named "default"
86* Each `patron` may have their own `domain`
87* Each `user` is in one `domain`
88* Each `project` is in one `domain`
89* A `user` has one or more `roles` on one or more `projects`
90
91HTTP Sessions
92=============
93
94* HTTP interactions are authenticated via keystone
95* Authenticating returns a `token`
96* An authenticated HTTP Session is shared across a `region`
97
98Cloud Regions
99=============
100
101A `cloud region` is the basic unit of REST interaction.
102
103* A `cloud` has a `service catalog`
104* The `service catalog` is returned in the `token`
105* The `service catalog` lists `endpoint` for each `service` in each `region`
106* A `region` is completely autonomous
107
108Availability Zones
109==================
110
111* If you have exposure to AWS - OpenStack Availability Zones are not what you
112 think they are.
113* OpenStack Availability Zones are tagged groupings of hypervisor hosts,
114 storage nodes and network nodes.
115
116Users, Projects and Domains
117===========================
118
119In clouds with multiple domains, project and user names are
120only unique within a region.
121
122* Names require `domain` information for uniqueness. IDs do not.
123* Providing `domain` information when not needed is fine.
124* `project_name` requires `project_domain_name` or `project_domain_id`
125* `project_id` does not
126* `username` requires `user_domain_name` or `user_domain_id`
127* `user_id` does not
128
129Auth vs. Identity
130=================
131
132* Both provided by the ``keystone`` service
133* ``identity`` refers to CRUD operations on users, projects, etc.
134* ``auth`` refers to a user getting a token and catalog
135
136Keystone v2 vs. Keystone v3
137===========================
138
139* Two major versions of identity API
140* v2 is deprecated/legacy
141* ``project`` was called ``tenant`` in v2
142* ``domain`` did not exist in v2
143
144Confused Yet?
145=============
146
147Awesome
148
149SDKs
150====
151
152REST
153====
154
155* You can always do direct REST
156* Auth and discovery are a bit of a pain
157* Once you have those, it's all pretty easy
158
159python
160======
161
162First:
163
164* python-openstackclient ... CLI tool ``openstack``
165
166Five main libraries to be aware of:
167
168* keystoneauth
169* os-client-config
170* shade
171* python-openstacksdk
172* python-*client
173
174python-*client
175==============
176
177* Per-service client libraries
178* Avoid them. They're not written for you. They make things harder.
179
180keystoneauth
181============
182
183* wrapper around python-requests that handles auth, catalog endpoint and
184 version discovery
185* "REST" library
186
187os-client-config
188================
189
190* Library to handle client configuration
191* Can create python REST clients for you
192* Used under the covers by shade, python-openstacksdk
193 and python-openstackclient
194* Handles clouds.yaml files, environment variables and command line arguments
195
196shade
197=====
198
199* a task and end-user oriented Python library
200* abstracts deployment differences
201* designed for multi-cloud
202* simple to use
203* massive scale
204
205 * optional advanced features to handle 20k servers a day
206
207* Initial logic/design extracted from nodepool
208* Librified to re-use in Ansible
209
210python-openstacksdk
211===================
212
213* Object oriented interface to OpenStack REST APIs
214* Just got adopted by the shade team
215* Interface is going to break soon
216* shade, python-openstacksdk and os-client-config are going to merge
217* shade is safe to use - there will always be backwards compat for shade
218
219Multi-Cloud Shade Example
220==========================
221
222.. code:: python
223
224 import shade
225
226 # Initialize and turn on debug logging
227 shade.simple_logging(debug=True)
228
229 for cloud_name, region_name in [
230 ('my-vexxhost', 'ca-ymq-1'),
231 ('my-citycloud', 'Buf1'),
232 ('my-internap', 'ams01')]:
233 # Initialize cloud
234 cloud = shade.openstack_cloud(cloud=cloud_name, region_name=region_name)
235
236 # Upload an image to the cloud
237 image = cloud.get_image('Fedora 24 (Cloud Edition) [2016-09-23]')
238
239 # Find a flavor with at least 512M of RAM
240 flavor = cloud.get_flavor_by_ram(512)
241
242 # Boot a server, wait for it to boot, and then do whatever is needed
243 # to get a public ip for it.
244 cloud.create_server(
245 'my-server', image=image, flavor=flavor, wait=True, auto_ip=True)
246
247It's Not Possible To Cover Everything That Does
248===============================================
249
250Simpler Example
251===============
252
253It still may not be possible to cover it all.
254
255.. code-block:: python
256
257 import shade
258
259 # Initialize and turn on debug logging
260 shade.simple_logging(debug=True)
261
262 # Initialize cloud
263 cloud = shade.openstack_cloud(cloud='vexxhost')
264
265 # Upload an image to the cloud
266 image = cloud.get_image('Fedora 24 (Cloud Edition) [2016-09-23]')
267
268 # Find a flavor with at least 512M of RAM
269 flavor = cloud.get_flavor_by_ram(512)
270
271 # Boot a server, wait for it to boot, and then do whatever is needed
272 # to get a public ip for it.
273 cloud.create_server(
274 'my-server', image=image, flavor=flavor, wait=True, auto_ip=True)
275
276Get Some Stuff Installed
277========================
278
279.. code-block:: bash
280
281 virtualenv venv
282 source venv/bin/activate
283 pip install shade
284
285Essential pieces of Auth Information
286====================================
287
288* auth_url
289* password
290* (username + (user_domain_name or user_domain_id)) or user_id)
291* (project_name + (project_domain_name or project_domain_id)) or project_id
292
293Note: It's important to know if you have a name or id for your user and
294 project.
295
296I Lied
297======
298
299Essential pieces of Auth Information
300====================================
301
302* auth_url
303* auth API version
304* auth_type
305
306If nobody tells you an auth_type, assume ``password``
307
308If nobody tells you an auth_url, look at
309
310https://docs.openstack.org/os-client-config/latest/user/vendor-support.html
311
312Exercise - Find Auth URL for known cloud
313===========================================
314
315The cloud is Vexxhost.
316
317Answer
318======
319
320https://auth.vexxhost.net
321
322Version Discovery
323=================
324
325* Each OpenStack service has a 'Version Discovery' document at its unversioned
326 root URL. We call this the 'Unversioned Discovery Document'
327
328 * Except for swift. (pending some work with discovery caching)
329
330* Each OpenStack service ALSO has a 'Version Discovery' document at the root
331 of each Versioned URL. We call this the 'Versioned Discovery Document'
332
333* Version Discovery documents should not require Authentication
334
335 * If they do on your cloud, your cloud is broken, please file a bug
336
337Exercise #2 - Find Auth API Version from Auth URL
338=================================================
339
340::
341
342 curl -i https://auth.vexxhost.net
343
344Auth Version Discovery Response
345===============================
346
347::
348
349 {
350 "versions": {
351 "values": [
352 {
353 "status": "stable",
354 "updated": "2017-02-22T00:00:00Z",
355 "media-types": [
356 {
357 "base": "application/json",
358 "type": "application/vnd.openstack.identity-v3+json"
359 }
360 ],
361 "id": "v3.8",
362 "links": [
363 {
364 "href": "https://auth.vexxhost.net/v3/",
365 "rel": "self"
366 }
367 ]
368 },
369
370Auth Version Discovery Response Part 2
371======================================
372
373::
374 {
375 "status": "deprecated",
376 "updated": "2016-08-04T00:00:00Z",
377 "media-types": [
378 {
379 "base": "application/json",
380 "type": "application/vnd.openstack.identity-v2.0+json"
381 }
382 ],
383 "id": "v2.0",
384 "links": [
385 {
386 "href": "https://auth.vexxhost.net/v2.0/",
387 "rel": "self"
388 },
389 {
390 "href": "https://docs.openstack.org/",
391 "type": "text/html",
392 "rel": "describedby"
393 }
394 ]
395 }
396 ]
397 }
398 }
399
400Versioned Discovery Document
401============================
402
403Sometimes a cloud gives you a versioned auth_url.
404
405::
406
407 curl -i https://auth.vexxhost.net/v3
408
409Auth Version Discovery Resonse
410==============================
411
412::
413
414 {
415 "version": {
416 "status": "stable",
417 "updated": "2017-02-22T00:00:00Z",
418 "media-types": [
419 {
420 "base": "application/json",
421 "type": "application/vnd.openstack.identity-v3+json"
422 }
423 ],
424 "id": "v3.8",
425 "links": [
426 {
427 "href": "https://auth.vexxhost.net/v3/",
428 "rel": "self"
429 }
430 ]
431 }
432 }
433
434Finding a Better Version
435========================
436
437Sometimes a cloud gives you a v2 versioned auth_url.
438
439::
440
441 curl -i https://auth.vexxhost.net/v2.0
442
443**ALWAYS** prefer v3 auth if it's available.
444
445Old Auth Version Discovery Resonse
446==================================
447
448::
449
450 {
451 "version": {
452 "status": "deprecated",
453 "updated": "2016-08-04T00:00:00Z",
454 "media-types": [
455 {
456 "base": "application/json",
457 "type": "application/vnd.openstack.identity-v2.0+json"
458 }
459 ],
460 "id": "v2.0",
461 "links": [
462 {
463 "href": "https://auth.vexxhost.net/v2.0/",
464 "rel": "self"
465 },
466 {
467 "href": "https://docs.openstack.org/",
468 "type": "text/html",
469 "rel": "describedby"
470 }
471 ]
472 }
473 }
474
475Status Deprecated
476=================
477
478Strip the trailing ``v.*`` portion from the URL and try again.
479
480::
481
482 {
483 "version": {
484 "status": "deprecated",
485
486Strip the trailing ``v.*`` portion from the URL and try again.
487
488If ``v3`` is not available, complain to someone. Keystone v3 api is considered
489stable as of February 20, 2013.
490
491Isn't this fun?
492===============
493
494To Domain or Not To Domain
495==========================
496
497In ``v3``:
498
499* Project Names and User Names are only unique within a domain
500* If you don't have domain info, assume ``domain_id`` is ``default``
501
502In ``v2``:
503
504* No such thing as domains
505* Projects are called "tenant"
506
507Essential pieces of Auth Information
508====================================
509
510* auth_url - https://auth.vexxhost.net
511* auth version - ``3``
512* versioned auth endpoint - https://auth.vexxhost.net/v3
513
514* username - osdn-user-1
515* user domain id - ``default``
516* project_name - osdn-project-1
517* project domain id = ``default``
518* password - XXXXXXXX
519
520Now we can authenticate!!!
521==========================
522
523::
524
525 curl -g -i -X POST https://auth.vexxhost.net/v3/auth/tokens -H "Content-Type: application/json" -H "Accept: application/json" -d '{"auth": {"identity": {"methods": ["password"], "password": {"user": {"domain": {"id": "default"}, "name": "osdn-user-1", "password": "XXXXXXXX"}}},"scope": {"project": {"domain": {"id": "default"}, "name": "osdn-project-1"}}}}'
526
527What, you can't read that?
528==========================
529
530::
531
532 curl -g -i -X POST https://auth.vexxhost.net/v3/auth/tokens \
533 -H "Content-Type: application/json" \
534 -H "Accept: application/json" -d '{
535 "auth": {
536 "identity": {
537 "methods": ["password"],
538 "password": {
539 "user": {
540 "domain": {"id": "default"},
541 "name": "osdn-user-1",
542 "password": "XXXXXXXX"}}},
543 "scope": {
544 "project": {
545 "domain": {"id": "default"},
546 "name": "osdn-project-1"}}}}'
547
548Authentication Response
549=======================
550
551Readable version of payload: http://paste.openstack.org/raw/623947/
552
553::
554
555 HTTP/1.1 201 Created
556 Date: Tue, 17 Oct 2017 23:16:05 GMT
557 Server: Apache/2.4.6 (CentOS)
558 X-Subject-Token: gAAAAABZ5o81tyDsyJMXl6hVcVOqHgzKQ2WmpvepCSr2NWYM1D97VoaBy-i5OLT8-BbkWBZJq_aqrt03eutp2eEpORI-V4CYpYcWBDkR5jLNfq2gD-TDB9lzvRo7rHKu-PWSLIxEF7whsFJ8bVGDPMN4yc_ZwgfWcR13GxAKutU9_rzR9Gvewjg
559 Vary: X-Auth-Token
560 x-openstack-request-id: req-29d8c4e6-1924-42e9-8efa-4f154e813ee6
561 Content-Length: 11696
562 Content-Type: application/json
563
564 {"token": {"is_domain": false, "methods": ["password"], "roles": [{"id": "fd6d2130b7784b82aa6b49fd5901f70b", "name": "Member"}], "expires_at": "2017-10-18T23:16:05.000000Z", "project": {"domain": {"id": "default", "name": "Default"}, "id": "bbb1e479a9d04f34941470f37c7a0ecb", "name": "osdn-project-1"}, "catalog": [{"endpoints": [{"region_id": "ca-ymq-1", "url": "https://key-manager-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "internal", "id": "522041f846934310b928a6afab47241e"}, {"region_id": "ca-ymq-1", "url": "https://key-manager-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "admin", "id": "660a742372554b5581c1f4870d4d42cf"}, {"region_id": "ca-ymq-1", "url": "https://key-manager-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "public", "id": "c1c32be0de8441eea4306b8c22442ba3"}], "type": "key-manager", "id": "023de54c09654931856403e708b60a22", "name": "barbican"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://container-infra-ca-ymq-1.vexxhost.net/v1", "region": "ca-ymq-1", "interface": "public", "id": "289f7dcf096743fb9a17924bd598e716"}, {"region_id": "ca-ymq-1", "url": "https://container-infra-ca-ymq-1.vexxhost.net/v1", "region": "ca-ymq-1", "interface": "admin", "id": "61b6d283ef4b419a8ad23fc53dea70df"}, {"region_id": "ca-ymq-1", "url": "https://container-infra-ca-ymq-1.vexxhost.net/v1", "region": "ca-ymq-1", "interface": "internal", "id": "e1e7c79ce7834ec0aa74308326e2f96c"}], "type": "container-infra", "id": "041eac2489bb495b8a900c40b93b2065", "name": "magnum"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://orchestration-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "admin", "id": "203fd4e466b44569aa9ab8c78ef55bad"}, {"region_id": "ca-ymq-1", "url": "https://orchestration-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "internal", "id": "da3d087e0c724338ba12c9a1168ef80c"}, {"region_id": "ca-ymq-1", "url": "https://orchestration-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "public", "id": "f0a311cb5dbf4ae788670107a3433ac2"}], "type": "orchestration", "id": "0e852aec60e6412b88b066e62c2cd940", "name": "heat"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://object-storage-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "admin", "id": "4f1fafb25e58421e91a2139dc0382c53"}, {"region_id": "ca-ymq-1", "url": "https://object-storage-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "internal", "id": "5808ab12037f4ab49c37cba0ac9cd58e"}, {"region_id": "ca-ymq-1", "url": "https://object-storage-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "public", "id": "a680b7674b3b430c9f5e008f72f3dfe4"}], "type": "s3", "id": "13f4cf29c7394a7a801d8aeacca24378", "name": "swift_s3"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "http://dns.vexxhost.net/", "region": "ca-ymq-1", "interface": "internal", "id": "0bba70ede2ef4bc0a998ed73110406cb"}, {"region_id": "ca-ymq-1", "url": "http://dns.vexxhost.net/", "region": "ca-ymq-1", "interface": "public", "id": "25ee42ace1ad4707b485494baa5d4693"}, {"region_id": "ca-ymq-1", "url": "http://dns.vexxhost.net/", "region": "ca-ymq-1", "interface": "admin", "id": "cf817bfde96d4aa6807cdb4be21eca3b"}], "type": "dns", "id": "1b6455f4855e44bd85be449258340a02", "name": "designate"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://identity-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "admin", "id": "8df18f47fcdc4c348d521d4724a5b7ac"}, {"region_id": "ca-ymq-1", "url": "https://auth.vexxhost.net", "region": "ca-ymq-1", "interface": "public", "id": "c0dd9f5f8db248b093d6735b167e1af6"}, {"region_id": "ca-ymq-1", "url": "https://auth.vexxhost.net", "region": "ca-ymq-1", "interface": "internal", "id": "c8505f07c349413aa7cd61d42337af99"}], "type": "identity", "id": "1ca1ba37600a436185c317bef6d88c36", "name": "keystone"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://placement-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "internal", "id": "299df431ac7942c18e2137613d8e03d8"}, {"region_id": "ca-ymq-1", "url": "https://placement-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "public", "id": "bec896cde16646d6a3b56cff997d08cc"}, {"region_id": "ca-ymq-1", "url": "https://placement-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "admin", "id": "ce70c7029b6a45b78e008bc833187559"}], "type": "placement", "id": "37077d282f2b4961ad65f9fb87f58789", "name": "placement"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "internal", "id": "4babd2f2b8d842e4b2303468fbf5d3ac"}, {"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "admin", "id": "6b3ddcf427e04182a7aa4e24d4649581"}, {"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "public", "id": "e8e1eb90f7394f5999aec5c8f8c75c88"}], "type": "volume", "id": "40686c5446374c2b92771e67249521b3", "name": "cinder"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://image-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "internal", "id": "218d9460bd6e4eabb32b980fc580a26a"}, {"region_id": "ca-ymq-1", "url": "https://image-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "admin", "id": "21a2898a0fcf4ec783974cf75d774916"}, {"region_id": "ca-ymq-1", "url": "https://image-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "public", "id": "8842c03d2c51449ebf9ff36778cf17c1"}], "type": "image", "id": "49e5dc4cfe294aa0971e797d3bb1db20", "name": "glance"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://cloudformation-ca-ymq-1.vexxhost.net/v1", "region": "ca-ymq-1", "interface": "admin", "id": "83fbacf0d0014a27955384fb8632de4c"}, {"region_id": "ca-ymq-1", "url": "https://cloudformation-ca-ymq-1.vexxhost.net/v1", "region": "ca-ymq-1", "interface": "internal", "id": "9308a40f3a6f4dff9d20afa2dfa6b186"}, {"region_id": "ca-ymq-1", "url": "https://cloudformation-ca-ymq-1.vexxhost.net/v1", "region": "ca-ymq-1", "interface": "public", "id": "e5cb7e4e6f3440a386d397ec7e00ca44"}], "type": "cloudformation", "id": "4e77820be3494d26a0c39301082da4d7", "name": "heat-cfn"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://data-processing-ca-ymq-1.vexxhost.net/v1.1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "internal", "id": "5fdfd118a3d6460ab45c1995ca21b7f1"}, {"region_id": "ca-ymq-1", "url": "https://data-processing-ca-ymq-1.vexxhost.net/v1.1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "admin", "id": "ab9e70b4fde943e49d92c41d2f0892d9"}, {"region_id": "ca-ymq-1", "url": "https://data-processing-ca-ymq-1.vexxhost.net/v1.1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "public", "id": "cfa16dc27b82420a8cf7db5ea79aa3dd"}], "type": "data-processing", "id": "523b8e9f4bd44e51aec65c524c953c32", "name": "sahara"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://network-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "admin", "id": "37860b492dd947daa738f461b9084d2a"}, {"region_id": "ca-ymq-1", "url": "https://network-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "public", "id": "7a095734e4984cc7b8ac581aa6131f23"}, {"region_id": "ca-ymq-1", "url": "https://network-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "internal", "id": "96357df3d6694477b0ad17fef6091210"}], "type": "network", "id": "98f33898880441ddb91522bac15410b5", "name": "neutron"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v2/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "internal", "id": "01fdd8e07ca74c9daf80a8b66dcc8bf6"}, {"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v2/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "public", "id": "a25efaf48347441a8d36ce302f31d527"}, {"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v2/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "admin", "id": "ceea6017e14e4b549882b6fe359d07e0"}], "type": "volumev2", "id": "9ec8ed2478e44b368f51dd71a6f2759c", "name": "cinderv2"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://compute-ca-ymq-1.vexxhost.net/v2.1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "internal", "id": "2f582f99db974766af7548dda56c3b50"}, {"region_id": "ca-ymq-1", "url": "https://compute-ca-ymq-1.vexxhost.net/v2.1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "admin", "id": "39e28fa99b69466195aad1fbfb610323"}, {"region_id": "ca-ymq-1", "url": "https://compute-ca-ymq-1.vexxhost.net/v2.1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "public", "id": "4d38fa91197e4712a2f2d3f89fcd7dad"}], "type": "compute", "id": "a30d9b8a170144f0a7bca3ce028c9ed3", "name": "nova"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v3/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "internal", "id": "5d9aa667f2fb4c83bf14ee8ae52b541a"}, {"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v3/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "admin", "id": "96bcaf12b54d4060bc9973ded5ce4093"}, {"region_id": "ca-ymq-1", "url": "https://block-storage-ca-ymq-1.vexxhost.net/v3/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "public", "id": "ac9138596d3942babe1f9241f93a5e04"}], "type": "volumev3", "id": "a5ae83af15b146559711905c6531c721", "name": "cinderv3"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://octavia-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "internal", "id": "39830aba2eea44a3a432ea0bd219c1ab"}, {"region_id": "ca-ymq-1", "url": "https://octavia-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "public", "id": "5883ae0fb85842c5aca05ed51327ac35"}, {"region_id": "ca-ymq-1", "url": "https://octavia-ca-ymq-1.vexxhost.net", "region": "ca-ymq-1", "interface": "admin", "id": "80bd3d21df274c43ac8457aa2230598f"}], "type": "octavia", "id": "b6a1520b90a146f4a96321960e7a243a", "name": "octavia"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "http://secure.vexxhost.com/console/api", "region": "ca-ymq-1", "interface": "public", "id": "156bf3730b834d2bacf7eff6c542f394"}], "type": "dashboard", "id": "b7bb9d5476c649f483dfbcb49359c17b", "name": "cloudconsole"}, {"endpoints": [{"region_id": "ca-ymq-1", "url": "https://object-storage-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "admin", "id": "20b24181722b49a3983d17d42147a22c"}, {"region_id": "ca-ymq-1", "url": "https://object-storage-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "public", "id": "79fa33ff42ec45118ae8b36789fcb8ae"}, {"region_id": "ca-ymq-1", "url": "https://object-storage-ca-ymq-1.vexxhost.net/v1/bbb1e479a9d04f34941470f37c7a0ecb", "region": "ca-ymq-1", "interface": "internal", "id": "b073b767f10d44f895d9d14fbc3e3d6b"}], "type": "object-store", "id": "c1efec5454ec49b1b016721938401182", "name": "swift"}], "user": {"password_expires_at": null, "domain": {"id": "default", "name": "Default"}, "id": "bc2260d5b7cb40ff8270043fd7af3a08", "name": "osdn-user-1"}, "audit_ids": ["6bu2KObmSwGfO2gsIcmPNw"], "issued_at": "2017-10-17T23:16:05.000000Z"}}
565
566Authentication Response Readable Version
567========================================
568
569http://paste.openstack.org/raw/623947/
570
571Listing Images
572==============
573
574* Find 'image' Endpoint from the Catalog
575* Find image api version
576* Make API call
577
578Consuming Service Catalog
579=========================
580
581https://specs.openstack.org/openstack/api-wg/guidelines/consuming-catalog.html
582
583Docs on version discovery and cloud profile:
584
585* https://review.openstack.org/#/c/459869 Add guideline describing a cloud profile document
586* https://review.openstack.org/#/c/459710 Add guidelines on Version Discovery
587* https://review.openstack.org/#/c/459405 Add document describing consuming version discovery
588
589Find Endpoint
590=============
591
592* Most important piece of info: ``service_type`` (``type`` in catalog)
593* ``service_name`` or name carries no meaning
594
595Service Types Authority
596=======================
597
598https://service-types.openstack.org
599
600* Registry of known service types
601* Listing of historical aliases for those service types
602* https://service-types.openstack.org/service-types.json
603* Not release versoined - most current file is always accurate
604* Python library: os-service-types
605
606Find Image Endpoint
607===================
608
609::
610
611 {'endpoints': [
612 {'id': '218d9460bd6e4eabb32b980fc580a26a',
613 'interface': 'internal',
614 'region': 'ca-ymq-1',
615 'region_id': 'ca-ymq-1',
616 'url': 'https://image-ca-ymq-1.vexxhost.net'},
617 {'id': '21a2898a0fcf4ec783974cf75d774916',
618 'interface': 'admin',
619 'region': 'ca-ymq-1',
620 'region_id': 'ca-ymq-1',
621 'url': 'https://image-ca-ymq-1.vexxhost.net'},
622 {'id': '8842c03d2c51449ebf9ff36778cf17c1',
623 'interface': 'public',
624 'region': 'ca-ymq-1',
625 'region_id': 'ca-ymq-1',
626 'url': 'https://image-ca-ymq-1.vexxhost.net'}],
627 'id': '49e5dc4cfe294aa0971e797d3bb1db20',
628 'name': 'glance',
629 'type': 'image'},
630
631Endpoint Interface
632==================
633
634* public - Public/External API access - default value
635* internal - Internal network API access
636* admin - Historical - was used for keystone - not used anymore
637
638Endpoint Region Name
639====================
640
641* If there is more than one region, region_name must be specified
642* If there is only one, it can be omitted
643
644Example with more than one region:
645
646http://paste.openstack.org/raw/623900/
647
648Endpoints Found
649===============
650
651* cloud=vexxhost1,service_type=image
652
653https://image-ca-ymq-1.vexxhost.net
654
655* cloud=citycloud1,service_type=image,region_name=Sto2
656
657https://sto2.citycloud.com:9292
658
659Finding Image API Version
660=========================
661
662::
663
664 curl -i https://image-ca-ymq-1.vexxhost.net
665
666http://paste.openstack.org/raw/623901/
667
668* CURRENT - Best current version
669
670https://image-ca-ymq-1.vexxhost.net/v2/
671
672Listing Images
673==============
674
675* Send value of X-Subject-Token from auth request in X-Auth-Token
676
677::
678
679 curl -i -X GET https://image-ca-ymq-1.vexxhost.net/v2/images \
680 -H "Accept: application/json" \
681 -H "X-Auth-Token: gAAAAABZ5qpnytYif9wk-4fsqvgm3Ik81WQl_L4tdlfka7Vr4b-EG0w7QGF-JU_T4zkJsuql4XYSU_9epUnx-aE_UeKMMdaKAyecGG9om6TR3CA6yeeHbMJBTVFfdxvW-QFA76_JXoibCvXGIcKlpotK01BBl3DG5qYNxUFkSquk5cIQh-w63AY"
682
683::
684
685 HTTP/1.1 200 OK
686 Content-Length: 24153
687 Content-Type: application/json
688 X-Openstack-Request-Id: req-8a602280-1bba-46b4-9406-97addcdd9b6c
689 Date: Wed, 18 Oct 2017 01:12:43 GMT
690
691* Content: http://paste.openstack.org/raw/623902/
692* Note pagination links
693
694Getting Auth information
695========================
696
697* Download a clouds.yaml file from horizon
698* Download an legacy openrc file from horizon
699* Investigate dashboard
700* Carrier pigeon
701
702Sometimes the files are wrong and you have to apply the earlier rules.
703
704Incorrect openrc file (horizon bug)
705===================================
706
707This is downloaded from my account. Who can spot the problems?
708
709::
710
711 export OS_AUTH_URL=https://auth.vexxhost.net/v2.0
712 export OS_PROJECT_ID=bbb1e479a9d04f34941470f37c7a0ecb
713 export OS_PROJECT_NAME="osdn-project-1"
714 export OS_USER_DOMAIN_NAME="None"
715 export OS_USERNAME="osdn-user-1"
716 export OS_REGION_NAME="ca-ymq-1"
717 export OS_INTERFACE=public
718 export OS_IDENTITY_API_VERSION=3
719
720Put the info in a clouds.yaml file
721==================================
722
723clouds.yaml
724===========
725
726Information about the clouds you want to connect to is stored in a file
727called `clouds.yaml`.
728
729`clouds.yaml` can be in your homedir: `~/.config/openstack/clouds.yaml`
730or system-wide: `/etc/openstack/clouds.yaml`.
731
732Information in your homedir, if it exists, takes precedence.
733
734Full docs on `clouds.yaml` are at
735https://docs.openstack.org/developer/os-client-config/
736
737What about Mac and Windows?
738===========================
739
740`USER_CONFIG_DIR` is different on Linux, OSX and Windows.
741
742* Linux: `~/.config/openstack`
743* OSX: `~/Library/Application Support/openstack`
744* Windows: `C:\\Users\\USERNAME\\AppData\\Local\\OpenStack\\openstack`
745
746`SITE_CONFIG_DIR` is different on Linux, OSX and Windows.
747
748* Linux: `/etc/openstack`
749* OSX: `/Library/Application Support/openstack`
750* Windows: `C:\\ProgramData\\OpenStack\\openstack`
751
752Config Terminology
753==================
754
755For multi-cloud, think of two types:
756
757* `profile` - Facts about the `cloud` that are true for everyone
758* `cloud` - Information specific to a given `user`
759
760Apologies for the use of `cloud` twice.
761
762Example clouds.yaml file
763========================
764
765.. code-block:: yaml
766
767 clouds:
768 vexxhost1:
769 identity_api_version: 3
770 auth:
771 auth_url: https://auth.vexxhost.net
772 user_domain_id: default
773 project_domain_id: default
774 project_name: osdn-project-1
775 username: osdn-user-1
776 password: XXXXXXXX
777
778Vexxhost is known
779=================
780
781.. code-block:: yaml
782
783 clouds:
784 vexxhost1:
785 identity_api_version: 3
786 profile: vexxhost
787 auth:
788 user_domain_id: default
789 project_domain_id: default
790 project_name: osdn-project-1
791 username: osdn-user-1
792 password: XXXXXXXX
793
794More than one cloud
795===================
796
797Yes- I created the same user with the same password on CityCloud:
798
799.. code-block:: yaml
800
801 clouds:
802 citycloud1:
803 profile: citycloud
804 auth:
805 username: osdn-user-1
806 password: XXXXXXXX
807 project_name: osdn-project-1
808 user_domain_id: d0919bd5e8d74e49adf0e145807ffc38
809 project_domain_id: d0919bd5e8d74e49adf0e145807ffc38
810 vexxhost1:
811 profile: vexxhost
812 auth:
813 user_domain_id: default
814 project_domain_id: default
815 project_name: osdn-project-1
816 username: osdn-user-1
817 password: XXXXXXXX
818
819Quick note about SSL
820====================
821
822You can disable SSL verification::
823
824 unitedstack:
825 profile: unitedstack
826 verify: False
827
828You can set specific SSL arguments::
829
830 openstackci-infracloud-vanilla:
831 region_name: RegionOne
832 cacert: /home/nodepool/.config/openstack/infracloud_vanilla_cacert.pem
833 auth:
834 auth_url: https://controller00.vanilla.ic.openstack.org:5000
835 username: openstackci
836
837Auth per cloud, select per region
838=================================
839
840In general, the thing you need to know is:
841
842* Configure authentication per `cloud`
843* Select config to use by `cloud` and `region`
844
845Environment Variables and Simple Usage
846======================================
847
848* Environment variables starting with `OS_` go into a cloud called `envvars`
849* If you only have one cloud, you don't have to specify it
850* `OS_CLOUD` and `OS_REGION_NAME` are default values for
851 `cloud` and `region_name`
852
853Easier version of the above REST
854================================
855
856* What you should be able to do
857
858.. code-block:: python
859
860 import os_client_config
861 client = os_client_config.make_rest_client('image', cloud='vexxhost1')
862 print(client.get('/images').json())
863
864* There's a bug with make_rest_client and glance - I'll get it fixed this week.
865 Workaround:
866
867.. code-block:: python
868
869 import os_client_config
870 from keystoneauth1 import adapter
871 config = os_client_config.OpenStackConfig().get_one_cloud(cloud='vexxhost1')
872 client = adapter.Adapter(
873 config.get_session(), service_type='image', version='latest')
874 print(client.get('/images').json())
875
876Sessions and Adapters
877=====================
878
879* A Session is an Authenticated HTTP connection to a cloud
880
881.. code-block:: python
882
883 config = os_client_config.OpenStackConfig().get_one_cloud(cloud='vexxhost1')
884 session = config.get_session()
885 session.get('https://image-ca-ymq-1.vexxhost.net/v2/images')
886
887* An "Adapter" is a Session that is 'mounted' on a base endpoint
888
889.. code-block:: python
890
891 config = os_client_config.OpenStackConfig().get_one_cloud(cloud='vexxhost1')
892 client = adapter.Adapter(
893 config.get_session(), service_type='image', version='latest')
894 session.get('/images')
895
896* ``os_client_config.make_rest_client`` returns a mounted Adapter
897* Latest keystoneauth library handles version discovery properly in Adapter
898
899Creating keystoneauth session directly
900======================================
901
902.. code-block:: python
903
904 from keystoneauth1 import adapter, loading, session
905 loader = loading.get_plugin_loader('password')
906 auth = loader.load_from_options(
907 auth_url='https://auth.vexxhost.net',
908 username='osdn-user-1',
909 user_domain_id='default',
910 password='XXXXXXXX',
911 project_name='osdn-project-1',
912 project_domain_id='default')
913 # verify and ssl cert info go here too
914 session = session.Session(auth)
915 # interface, region_name also go here
916 client = adapter.Adapter(session, service_type='image', version='latest')
917 client.get('/images')
918
919Command Line
920============
921
922.. code-bock:: bash
923
924 openstack --os-cloud=vexxhost1 image list
925
926Back to shade
927=============
928
929.. code-block:: python
930
931 import shade
932 cloud = shade.openstack_cloud(cloud='vexxhost')
933 cloud.pprint(cloud.list_images())
934
935Shade Logging
936=============
937
938* `shade` uses standard python logging
939* `simple_logging` does easy defaults
940* Squelches some meaningless warnings
941
942 * `debug`
943
944 * Logs shade loggers at debug level
945
946 * `http_debug` Implies `debug`, turns on HTTP tracing
947
948.. code:: python
949
950 # Initialize and turn on debug logging
951 shade.simple_logging(debug=True)
952
953Find out what REST calls shade is making
954========================================
955
956.. code-block:: python
957
958 import shade
959 shade.simple_logging(http_debug=True)
960 cloud = shade.openstack_cloud(cloud='vexxhost1')
961 cloud.pprint(cloud.list_images())
962
963http://paste.openstack.org/raw/623906/
964
965Real tokens are not logged, only a sha of the token. Reusing the printed
966curl commands reuquires replacing the token with a real one.
967
968::
969
970 "X-Auth-Token: {SHA1}23ffd369ff0c0e7673c17bb97e6a77783d789e5e"
971
972Microversions
973=============
974
975* Per-HTTP-request behavior differences.
976* Services declare microversion support ranges in Version Discovery Document
977
978.. code-block:: bash
979
980 curl -i https://compute-ca-ymq-1.vexxhost.net
981
982Nova Compute Version Document Part One
983======================================
984
985::
986
987 HTTP/1.1 200 OK
988 Date: Wed, 18 Oct 2017 01:58:51 GMT
989 Server: Apache/2.4.6 (CentOS)
990 Content-Length: 399
991 Vary: Accept-Encoding
992 Content-Type: application/json
993
994 {
995 "versions": [
996 {
997 "status": "SUPPORTED",
998 "version": "",
999 "updated": "2011-01-21T11:33:21Z",
1000 "id": "v2.0",
1001 "links": [
1002 {
1003 "href": "https://compute-ca-ymq-1.vexxhost.net/v2/",
1004 "rel": "self"
1005 }
1006 ],
1007 "min_version": ""
1008 },
1009
1010Nova Compute Version Document Part Two
1011======================================
1012
1013Note 'version' and 'min_version'.
1014
1015::
1016
1017 {
1018 "status": "CURRENT",
1019 "version": "2.53",
1020 "updated": "2013-07-23T11:33:21Z",
1021 "id": "v2.1",
1022 "links": [
1023 {
1024 "href": "https://compute-ca-ymq-1.vexxhost.net/v2.1/",
1025 "rel": "self"
1026 }
1027 ],
1028 "min_version": "2.1"
1029 }
1030
1031Microversion Field Names
1032========================
1033
1034The min and max available microversion for the given Major API version.
1035
1036In some services they are:
1037
1038* min_version
1039* version
1040
1041In other services they are:
1042
1043* min_version
1044* max_version
1045
1046Request a Microversion
1047======================
1048
1049* Add a OpenStack-API-Version header with service-type and version::
1050
1051 OpenStack-API-Version: compute 2.13
1052
1053* Response will contain the same header specifying which version was used::
1054
1055 OpenStack-API-Version: compute 2.13
1056
1057* Older versions of Nova (pre Newton - or versions that do not support a max
1058 version of 2.27 or higher), use a different form::
1059
1060 X-OpenStack-Nova-API-Version: 2.13
1061
1062* It doesn't hurt anything to send both - which is what keystoneauth does
1063 under the covers.
1064
1065Documentation on Nova Microversion Changes
1066==========================================
1067
1068https://docs.openstack.org/nova/latest/reference/api-microversion-history.html
1069
1070Simple Microversion Example with Default
1071========================================
1072
1073Microversion 2.36 removed some calls. Before 2.36 nova had a ``/images`` API
1074that would proxy to glance. It is removed in 2.36 and later.
1075
1076Making a GET call defaults to the minimum (2.1 in this case)
1077
1078.. code-bock:: python
1079
1080 import os_client_config
1081
1082 client = os_client_config.make_rest_client('compute', cloud='vexxhost')
1083 client.get('/images')
1084
1085::
1086
1087 curl -g -i -X GET https://compute-ca-ymq-1.vexxhost.net/v2.1/db92b20496ae4fbda850a689ea9d563f/images -H "X-Auth-Token: {SHA1}23ffd369ff0c0e7673c17bb97e6a77783d789e5e" -H "User-Agent: os-client-config/1.28.1 keystoneauth1/3.2.1 python-requests/2.18.3 CPython/3.5.2"
1088 [200] Date: Wed, 18 Oct 2017 02:10:49 GMT Server: Apache/2.4.6 (CentOS) OpenStack-API-Version: compute 2.1 X-OpenStack-Nova-API-Version: 2.1 Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version,Accept-Encoding x-openstack-request-id: req-3e6bc318-dfd6-493b-9675-8bb1f9285cac x-compute-request-id: req-3e6bc318-dfd6-493b-9675-8bb1f9285cac Content-Encoding: gzip Content-Length: 2411 Content-Type: application/json
1089
1090Simple Microversion Example with Microversion
1091=============================================
1092
1093Sending microversion 2.36 for the same call tells Nova to use the 2.36
1094behavior, which results in a 404.
1095
1096.. code-bock:: python
1097
1098 import os_client_config
1099
1100 client = os_client_config.make_rest_client('compute', cloud='vexxhost')
1101 client.get('/images', microversion='2.36')
1102
1103::
1104
1105 curl -g -i -X GET https://compute-ca-ymq-1.vexxhost.net/v2.1/db92b20496ae4fbda850a689ea9d563f/images -H "User-Agent: os-client-config/1.28.1 keystoneauth1/3.2.1 python-requests/2.18.3 CPython/3.5.2" -H "X-Auth-Token: {SHA1}23ffd369ff0c0e7673c17bb97e6a77783d789e5e" -H "OpenStack-API-Version: compute 2.36" -H "X-OpenStack-Nova-API-Version: 2.36"
1106 [404] Date: Wed, 18 Oct 2017 02:11:00 GMT Server: Apache/2.4.6 (CentOS) OpenStack-API-Version: compute 2.36 X-OpenStack-Nova-API-Version: 2.36 Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version x-openstack-request-id: req-d733583e-d2c3-4ca4-bdfb-5e658e194028 x-compute-request-id: req-d733583e-d2c3-4ca4-bdfb-5e658e194028 Content-Length: 78 Content-Type: application/json; charset=UTF-8
1107 {"itemNotFound": {"message": "The resource could not be found.", "code": 404}}
1108
1109
1110Create Server Group
1111===================
1112
1113The server group doesn't matter - this is just to have an object to show.
1114
1115.. code-bock:: python
1116
1117 import os_client_config
1118
1119 client = os_client_config.make_rest_client('compute', cloud='vexxhost')
1120 client.post(
1121 '/os-server-groups',
1122 json=dict(server_group=dict(name='test', policies=['anti-affinity'])))
1123
1124Example of No Microversion Content Behavior
1125===========================================
1126
1127No microversion specified.
1128
1129.. code-bock:: python
1130
1131 client.get('/os-server-groups')
1132
1133::
1134
1135 curl -g -i -X GET https://compute-ca-ymq-1.vexxhost.net/v2.1/bbb1e479a9d04f34941470f37c7a0ecb/os-server-groups -H "X-Auth-Token: {SHA1}fe541768b55bbe23f79f97595b137fed3326166a" -H "User-Agent: os-client-config/1.28.1 keystoneauth1/3.2.1 python-requests/2.18.3 CPython/3.5.2"
1136 [200] Date: Wed, 18 Oct 2017 02:18:30 GMT Server: Apache/2.4.6 (CentOS) OpenStack-API-Version: compute 2.1 X-OpenStack-Nova-API-Version: 2.1 Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version,Accept-Encoding x-openstack-request-id: req-85e061c0-d474-497c-bd17-96b629086169 x-compute-request-id: req-85e061c0-d474-497c-bd17-96b629086169 Content-Encoding: gzip Content-Length: 137 Content-Type: application/json
1137 {"server_groups": [{"members": [], "metadata": {}, "id": "f88c7aef-b34a-4b0e-b0c7-9076eab88de2", "policies": ["anti-affinity"], "name": "test"}]}
1138
1139Example of Microversion Content Behavior
1140========================================
1141
1142Request microversion 2.13, which adds user_id and project_id.
1143
1144.. code-bock:: python
1145
1146 client.get('/os-server-groups', microversion='2.13').json()
1147
1148::
1149
1150 curl -g -i -X GET https://compute-ca-ymq-1.vexxhost.net/v2.1/bbb1e479a9d04f34941470f37c7a0ecb/os-server-groups -H "User-Agent: os-client-config/1.28.1 keystoneauth1/3.2.1 python-requests/2.18.3 CPython/3.5.2" -H "X-Auth-Token: {SHA1}fe541768b55bbe23f79f97595b137fed3326166a" -H "OpenStack-API-Version: compute 2.13" -H "X-OpenStack-Nova-API-Version: 2.13"
1151 [200] Date: Wed, 18 Oct 2017 02:20:13 GMT Server: Apache/2.4.6 (CentOS) OpenStack-API-Version: compute 2.13 X-OpenStack-Nova-API-Version: 2.13 Vary: OpenStack-API-Version,X-OpenStack-Nova-API-Version,Accept-Encoding x-openstack-request-id: req-6c71b008-185a-46c1-8762-5c2718be1741 x-compute-request-id: req-6c71b008-185a-46c1-8762-5c2718be1741 Content-Encoding: gzip Content-Length: 195 Content-Type: application/json
1152 {"server_groups": [{"user_id": "bc2260d5b7cb40ff8270043fd7af3a08", "policies": ["anti-affinity"], "name": "test", "members": [], "project_id": "bbb1e479a9d04f34941470f37c7a0ecb", "id": "f88c7aef-b34a-4b0e-b0c7-9076eab88de2", "metadata": {}}]}
1153