Pyrax talk

834 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
834
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Ask who is an a) OpenStack contributor, b) OpenStack deployment/devops, or c) Just interested
  • Pyrax talk

    1. 1. Cloud APIs are great… but I want to use Python! Ed Leafe Rackspace Boston OpenStack Meetup 2012.02.13
    2. 2. Survey
    3. 3. About•Developer for 20+ years•Rackspace for 5 years•Python developer since 2000•OpenStack developer since the beginning•Swift (before OpenStack)•Nova•Keystone
    4. 4. Contact•ed.leafe@rackspace.com•ed@leafe.com•ed@openstack.org
    5. 5. APIs•Documented at: http://docs.rackspace.com/
    6. 6. Jump right in! Lets get a list of our Cloud Servers:import urllib2uri = "https://dfw.servers.api.rackspacecloud.com/" "v2/753591/servers/detail"resp = urllib2.urlopen(uri)print resp.read()
    7. 7. Oh, yeah...HTTP Error 401: Unauthorized
    8. 8. So lets handle authuri ="http://identity.api.rackspacecloud.com/v2.0/tokens"credentials ={"auth": {"passwordCredentials": {"username": "joeuser", "password": "abc123def456"}}}req = urllib2.Request(uri,data=json.dumps(credentials))req.add_header("Content-Type", "application/json")req.add_header("Accept", "application/json")try: raw_resp = urllib2.urlopen(req)except urllib2.HTTPError as e: errcode = e.getcode() if errcode == 401: # Invalid authorization print "Invalid credentials" else: print "Authentication Error: %s" % e returnresp = json.load(raw_resp)
    9. 9. Not done yet...token_info = resp.get("access").get("token")token = token_info.get("id")expires = token_info.get("expires")tenant_info = token_info.get("tenant")tenant_id = tenant_info.get("id")
    10. 10. Still not finished...access = resp.get("access")svc_catalog = access.get("serviceCatalog")# Lets see whats in thisprint svc_catalog
    11. 11. [{uendpoints: [{upublicURL: uhttps://monitoring.api.rackspacecloud.com/v1.0/753591, utenantId: u753591}], uname: ucloudMonitoring, utype: urax:monitor}, {uendpoints: [{upublicURL: uhttps://ord.loadbalancers.api.rackspacecloud.com/v1.0/753591, uregion: uORD, utenantId: u753591}, {upublicURL: uhttps://dfw.loadbalancers.api.rackspacecloud.com/v1.0/753591, uregion: uDFW, utenantId: u753591}], uname: ucloudLoadBalancers, utype: urax:load-balancer}, {uendpoints: [{upublicURL: uhttps://servers.api.rackspacecloud.com/v1.0/753591, utenantId: u753591, uversionId: u1.0, uversionInfo: uhttps://servers.api.rackspacecloud.com/v1.0, uversionList: uhttps://servers.api.rackspacecloud.com/}], uname: ucloudServers, utype: ucompute}, {uendpoints: [{upublicURL: uhttps://cdn1.clouddrive.com/v1/MossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d, uregion: uDFW, utenantId: uMossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d}, {upublicURL: uhttps://cdn2.clouddrive.com/v1/MossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d, uregion: uORD, utenantId: uMossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d}], uname: ucloudFilesCDN, utype: urax:object-cdn}, {uendpoints: [{upublicURL: uhttps://dfw.blockstorage.api.rackspacecloud.com/v1/753591, uregion: uDFW, utenantId: u753591}, {upublicURL: uhttps://ord.blockstorage.api.rackspacecloud.com/v1/753591, uregion: uORD, utenantId: u753591}], uname: ucloudBlockStorage, utype: uvolume}, {uendpoints: [{upublicURL: uhttps://dfw.databases.api.rackspacecloud.com/v1.0/753591, uregion: uDFW, utenantId: u753591}, {upublicURL: uhttps://ord.databases.api.rackspacecloud.com/v1.0/753591, uregion: uORD, utenantId: u753591}], uname: ucloudDatabases, utype: urax:database}, {uendpoints: [{upublicURL: uhttps://dfw.servers.api.rackspacecloud.com/v2/753591, uregion: uDFW, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://dfw.servers.api.rackspacecloud.com/v2, uversionList: uhttps://dfw.servers.api.rackspacecloud.com/}, {upublicURL: uhttps://ord.servers.api.rackspacecloud.com/v2/753591, uregion: uORD, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://ord.servers.api.rackspacecloud.com/v2, uversionList: uhttps://ord.servers.api.rackspacecloud.com/}], uname: ucloudServersOpenStack, utype: ucompute}, {uendpoints: [{uinternalURL: uhttps://snet-storage101.dfw1.clouddrive.com/v1/MossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d, upublicURL: uhttps://storage101.dfw1.clouddrive.com/v1/MossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d, uregion: uDFW, utenantId: uMossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d}, {uinternalURL: uhttps://snet-storage101.ord1.clouddrive.com/v1/MossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d, upublicURL: uhttps://storage101.ord1.clouddrive.com/v1/MossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d, uregion: uORD, utenantId: uMossoCloudFS_844909d3-431e-4919-8211-beca1e850a5d}], uname: ucloudFiles, utype: uobject-store}, {uendpoints: [{upublicURL: uhttps://dns.api.rackspacecloud.com/v1.0/753591, utenantId: u753591}],
    12. 12. Simple!
    13. 13. The Service Catalog•Contains all of the available services and theirendpoints.•For services that are region-specific, holds theendpoints for each region.
    14. 14. Compute Service Catalog{uendpoints: [{upublicURL: uhttps://dfw.servers.api. rackspacecloud.com/v2/753591, uregion: uDFW, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://dfw.servers.api.rackspacecloud.com/v2, uversionList: uhttps://dfw.servers.api.rackspacecloud.com/}, {upublicURL: uhttps://ord.servers.api.rackspacecloud.com/ v2/753591, uregion: uORD, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://ord.servers.api.rackspacecloud.com/v2, uversionList: uhttps://ord.servers.api.rackspacecloud.com/}], uname: ucloudServersOpenStack, utype: ucompute}
    15. 15. Compute Service Catalog{uendpoints: [{upublicURL: uhttps://dfw.servers.api. rackspacecloud.com/v2/753591, uregion: uDFW, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://dfw.servers.api.rackspacecloud.com/v2, uversionList: uhttps://dfw.servers.api.rackspacecloud.com/}, {upublicURL: uhttps://ord.servers.api.rackspacecloud.com/ v2/753591, uregion: uORD, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://ord.servers.api.rackspacecloud.com/v2, uversionList: uhttps://ord.servers.api.rackspacecloud.com/}], uname: ucloudServersOpenStack, utype: ucompute}
    16. 16. Compute Service Catalog{uendpoints: [{upublicURL: uhttps://dfw.servers.api. rackspacecloud.com/v2/753591, uregion: uDFW, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://dfw.servers.api.rackspacecloud.com/v2, uversionList: uhttps://dfw.servers.api.rackspacecloud.com/}, {upublicURL: uhttps://ord.servers.api.rackspacecloud.com/ v2/753591, uregion: uORD, utenantId: u753591, uversionId: u2, uversionInfo: uhttps://ord.servers.api.rackspacecloud.com/v2, uversionList: uhttps://ord.servers.api.rackspacecloud.com/}], uname: ucloudServersOpenStack, utype: ucompute}
    17. 17. Find URI by Regionaccess = resp["access"]svc_cat = access["serviceCatalog"]compute_svc = svc_cat["compute"]eps = compute_svc["endpoints"]reg_ep = [ep for ep in eps if ep["region"] == region][0]base_uri = reg_ep["public_url"]list_uri = "%s/servers/detail" % base_uri
    18. 18. Create the Requestimport urllib2req = urllib2.Request(list_uri)
    19. 19. Add the Auth Headersreq.add_header("X-Auth-Token", token)req.add_header("X-Auth-Project-Id", tenant_id)
    20. 20. Add the HTTP Headersreq.add_header("Accept", "application/json")req.add_header("Content-Type", "application/json")req.add_header("User-Agent", "myapp/1.1")
    21. 21. Make the Requestraw_resp = urllib2.urlopen(req)resp = json.load(raw_resp)print resp
    22. 22. {uservers: [{uOS-DCF:diskConfig: uAUTO, uOS-EXT-STS:power_state: 1, uOS-EXT-STS:task_state: None, uOS-EXT-STS:vm_state: uactive, Result: uaccessIPv4: u166.78.8.247, uaccessIPv6: u2001:4800:7810:0512:8ca7:b42c:ff04:b4ae, uaddresses: {uprivate: [{uaddr: u10.181.18.164, uversion: 4}], upublic: [{uaddr: u2001:4800:7810:0512:8ca7:b42c:ff04:b4ae, uversion: 6}, {uaddr: u166.78.8.247, uversion: 4}]}, ucreated: u2013-01-24T15:13:23Z, uflavor: {uid: u2, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/flavors/2, urel: ubookmark}]}, uhostId: ufcaa2858a7255b1bbba8cf5e3a1550f0f1bea780164a4412709e5d4d, uid: u19b394eb-17ce-4221-9989-824be1bd2236, uimage: {uid: u09a4e770-26f7-4377-8893-2b21a0b76ba8, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/images/09a4e770-26f7-4377-8893-2b21a0b76ba8, urel: ubookmark}]}, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/v2/728829/servers/19b394eb-17ce-4221-9989-824be1bd2236, urel: uself}, {uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/servers/19b394eb-17ce-4221-9989-824be1bd2236, urel: ubookmark}], umetadata: {}, uname: uNM0978FR, uprogress: 100, urax-bandwidth:bandwidth: [], ustatus: uACTIVE, utenant_id: u728829, uupdated: u2013-01-24T15:17:55Z, uuser_id: u235799}, {uOS-DCF:diskConfig: uAUTO, uOS-EXT-STS:power_state: 1, uOS-EXT-STS:task_state: None, uOS-EXT-STS:vm_state: uactive, uaccessIPv4: u198.61.217.238, uaccessIPv6: u2001:4800:780e:0510:8ca7:b42c:ff04:a78e, uaddresses: {uprivate: [{uaddr: u10.180.24.4, uversion: 4}], upublic: [{uaddr: u2001:4800:780e:0510:8ca7:b42c:ff04:a78e, uversion: 6}, {uaddr: u198.61.217.238, uversion: 4}]}, ucreated: u2012-12-03T17:23:16Z, uflavor: {uid: u2, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/flavors/2, urel: ubookmark}]}, uhostId: uec8d624af62a9cb511daba3c106d27142b3cff0eaf3aa61cda89f1fa, uid: u5e16de51-724c-4885-8849-65719bb455fd, uimage: {uid: u5cebb13a-f783-4f8c-8058-c4182c724ccd, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/images/5cebb13a-f783-4f8c-8058-c4182c724ccd, urel: ubookmark}]}, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/v2/728829/servers/5e16de51-724c-4885-8849-65719bb455fd, urel: uself}, {uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/servers/5e16de51-724c-4885-8849-65719bb455fd, urel: ubookmark}], umetadata: {}, uname: uBmwIqtGb, uprogress: 100, urax-bandwidth:bandwidth: [], ustatus: uACTIVE, utenant_id: u728829, uupdated: u2013-01-19T16:47:03Z, uuser_id: u235799}]}
    23. 23. Thats just for 2 servers!
    24. 24. Just One Server:{uOS-DCF:diskConfig: uAUTO, uOS-EXT-STS:power_state: 1, uOS-EXT-STS:task_state: None, uOS-EXT-STS:vm_state: uactive, uaccessIPv4: u166.78.8.247, uaccessIPv6: u2001:4800:7810:0512:8ca7:b42c:ff04:b4ae, uaddresses: {uprivate: [{uaddr: u10.181.18.164, uversion: 4}], upublic: [{uaddr: u2001:4800:7810:0512:8ca7:b42c:ff04:b4ae, uversion: 6}, {uaddr: u166.78.8.247, uversion: 4}]}, ucreated: u2013-01-24T15:13:23Z, uflavor: {uid: u2, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/flavors/2, urel: ubookmark}]}, uhostId: ufcaa2858a7255b1bbba8cf5e3a1550f0f1bea780164a4412709e5d4d, uid: u19b394eb-17ce-4221-9989-824be1bd2236, uimage: {uid: u09a4e770-26f7-4377-8893-2b21a0b76ba8, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/images/09a4e770-26f7-4377-8893-2b21a0b76ba8, urel: ubookmark}]}, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/v2/728829/servers/19b394eb-17ce-4221-9989-824be1bd2236, urel: uself}, {uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/servers/19b394eb-17ce-4221-9989-824be1bd2236, urel: ubookmark}], umetadata: {}, uname: uNM0978FR, uprogress: 100, urax-bandwidth:bandwidth: [], ustatus: uACTIVE, utenant_id: u728829, uupdated: u2013-01-24T15:17:55Z, uuser_id: u235799}
    25. 25. Fun, huh?
    26. 26. Just One Server:{uOS-DCF:diskConfig: uAUTO, uOS-EXT-STS:power_state: 1, uOS-EXT-STS:task_state: None, uOS-EXT-STS:vm_state: uactive, uaccessIPv4: u166.78.8.247, uaccessIPv6: u2001:4800:7810:0512:8ca7:b42c:ff04:b4ae, uaddresses: {uprivate: [{uaddr: u10.181.18.164, uversion: 4}], upublic: [{uaddr: u2001:4800:7810:0512:8ca7:b42c:ff04:b4ae, uversion: 6}, {uaddr: u166.78.8.247, uversion: 4}]}, ucreated: u2013-01-24T15:13:23Z, uflavor: {uid: u2, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/flavors/2, urel: ubookmark}]}, uhostId: ufcaa2858a7255b1bbba8cf5e3a1550f0f1bea780164a4412709e5d4d, uid: u19b394eb-17ce-4221-9989-824be1bd2236, uimage: {uid: u09a4e770-26f7-4377-8893-2b21a0b76ba8, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/images/09a4e770-26f7-4377-8893-2b21a0b76ba8, urel: ubookmark}]}, ulinks: [{uhref: uhttps://dfw.servers.api.rackspacecloud.com/v2/728829/servers/19b394eb-17ce-4221-9989-824be1bd2236, urel: uself}, {uhref: uhttps://dfw.servers.api.rackspacecloud.com/728829/servers/19b394eb-17ce-4221-9989-824be1bd2236, urel: ubookmark}], umetadata: {}, uname: uNM0978FR, uprogress: 100, urax-bandwidth:bandwidth: [], ustatus: uACTIVE, utenant_id: u728829, uupdated: u2013-01-24T15:17:55Z, uuser_id: u235799}
    27. 27. So for each request:• Retrieve authentication credentials from cache • Re-auth when no token, or when token expires• Determine endpoint for selected region from service catalog• Form URI from endpoint and API spec• Add auth header to request• Add "User-agent: xxx" header• Add "Content-Type: application/json" header• Add "Accept: application/json" header• Transmit request• Handle all errors• Retry if possible
    28. 28. ...and then•Parse results•Headers•JSON body•Extract list of resource data•Return entity (or list of entities) with appropriate info•Sometimes just a value; e.g.: cloud_dns.domain.export() => string
    29. 29. Wouldnt it be betterto work with Python objects?
    30. 30. The Resource Class•Represents an individual cloud entities.•E.g.: a server; a load balancer•Has attributes that reflect all the informationabout that entity.•Has methods for interacting with that entity.
    31. 31. The Client Class•Handles all I/O•Calls from your app to pyrax•Calls from pyrax to the API server
    32. 32. The Manager Class•Configured with base URI for service•Configured with Resource type for service•Translates method calls to full URIs•Interprets responses •Creates Resource instances as necessary
    33. 33. Architecture list()Your Client JSON CloudApp objects GET URI API URI objects list() JSON method=GET determine Resource Manager method & URI parse JSON
    34. 34. Interacting with Resources•Many calls to the client require a resourcereference; e.g.: cloud_blockstorage.create_snapshot(volume)•Resources have a reference to their manager.•If you have an instance of that resource, you cancall it directly on the resource; e.g.: volume.create_snapshot()
    35. 35. Q &A
    36. 36. Thanks!

    ×