xnode-keystone 0.2.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +11 -0
- data/README.md +54 -9
- data/lib/xnode/keystone.rb +113 -53
- data/lib/xnode/keystone/http.rb +1 -46
- data/lib/xnode/keystone/utils.rb +25 -1
- data/lib/xnode/keystone/version.rb +1 -1
- data/xnode-keystone.gemspec +2 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b398540f03b56c036f706e2674154f35de43746b
|
4
|
+
data.tar.gz: a168bbeb4a24112e145f515284034329660a5250
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0864c1ec3472ddd68f0c1fada42557e0215431b62b85e7c0e7f55faffc90830405e5ea40ecae5f2d2c9959c9b66c93de262ac817fe38405e7148f994b87e8c9b
|
7
|
+
data.tar.gz: 21cbdfc5daa6227941adcbffddae47bf06fd45b142b6ad35296c2e586a28f31c650ce04435ab09cacf8b8d387af11d992f9d253e3ad1aeae181f8104c087aab7
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# Xnode::Keystone
|
2
2
|
|
3
|
-

|
4
|
-
[](
|
3
|
+
[](https://travis-ci.org/xnoder/xnode-keystone)
|
4
|
+
[](https://rubygems.org/gems/xnode-keystone)
|
5
5
|
|
6
6
|
`xnode-keystone` provides methods that allow you to interact with the Keystone Identity service provided by an OpenStack
|
7
|
-
cloud. It covers your authentication,
|
8
|
-
|
7
|
+
cloud. It covers your authentication, as well as retrieving other OpenStack API endpoints exposed by your cloud
|
8
|
+
administrators.
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -25,22 +25,35 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
-
Basic usage is as follows. You need to have an openrc file somewhere that looks something like this:
|
28
|
+
Basic usage is as follows. You need to have an `openrc` file somewhere that looks something like this:
|
29
29
|
|
30
30
|
```
|
31
31
|
export OS_USERNAME=demo
|
32
32
|
export OS_PASSWORD=supas33krit
|
33
33
|
export OS_TENANT_NAME=Demo
|
34
34
|
export OS_AUTH_URL=https://controller:5000/v2.0
|
35
|
+
export OS_AUTH_URL=https://controller:5000/v3
|
35
36
|
```
|
36
37
|
|
37
38
|
Source it with `. openrc.sh` to load the environment variables. `xnode-keystone` needs these to find your creds.
|
38
39
|
|
40
|
+
There are modules for both `v2.0` and `v3` of the Keystone Identity service. These are called as follows:
|
41
|
+
|
42
|
+
For `v2.0`:
|
43
|
+
|
44
|
+
`Xnode::Keystone::V2::Authenticate.new`
|
45
|
+
|
46
|
+
and for `v3`:
|
47
|
+
|
48
|
+
`Xnode::Keystone::V3::Authenticate.new`
|
49
|
+
|
50
|
+
Below is an example that is for `V2`:
|
51
|
+
|
39
52
|
```ruby
|
40
|
-
require 'xnode
|
53
|
+
require 'xnode/keystone'
|
41
54
|
|
42
55
|
# Initialise a new instance of the base class
|
43
|
-
auth = Xnode::Keystone::Authenticate.new
|
56
|
+
auth = Xnode::Keystone::V2::Authenticate.new
|
44
57
|
|
45
58
|
# Send an authentication request, and get a JSON response back that's been decoded bash into a Hash
|
46
59
|
request = auth.request
|
@@ -57,11 +70,43 @@ keystone = endpoints['identity']['public']
|
|
57
70
|
tenants = auth.tenants(keystone, token)
|
58
71
|
```
|
59
72
|
|
73
|
+
And finally, an example for `V3`:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
require 'xnode/keystone'
|
77
|
+
|
78
|
+
# Initialise a new instance of the base class
|
79
|
+
auth = Xnode::Keystone::V3::Authenticate.new
|
80
|
+
|
81
|
+
# Send an authentication request, and get a JSON response back that's been decoded bash into a Hash
|
82
|
+
request = auth.request
|
83
|
+
|
84
|
+
# To extract a token from the request...
|
85
|
+
token = auth.get_token
|
86
|
+
|
87
|
+
# And to get the public compute API endpoint back...
|
88
|
+
endpoints = auth.catalog(request)
|
89
|
+
compute = endpoints['compute']['public']
|
90
|
+
|
91
|
+
# If you want a list of tenants...
|
92
|
+
keystone = endpoints['identity']['public']
|
93
|
+
tenants = auth.tenants(keystone, token)
|
94
|
+
```
|
95
|
+
|
96
|
+
Both are almost syntactically identical, but require some tweaks internally to manipulate the way that the data needed
|
97
|
+
is returned to the user. The *major* difference is in the `get_token` method. In `V2`, you need to pass in the response
|
98
|
+
body, as the token is contained within the `JSON` response returned by the API. In `V3`, you just need to call the
|
99
|
+
method without any parameters, as the token is actually returned as a header in the form of `X-Subject-Token`, which
|
100
|
+
I just write to an instance variable, which is accessed by `get_token` when called.
|
101
|
+
|
60
102
|
## Development
|
61
103
|
|
62
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
|
104
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
|
105
|
+
also run `bin/console` for an interactive prompt that will allow you to experiment.
|
63
106
|
|
64
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
107
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
108
|
+
version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
|
109
|
+
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
65
110
|
|
66
111
|
## Contributing
|
67
112
|
|
data/lib/xnode/keystone.rb
CHANGED
@@ -8,73 +8,133 @@
|
|
8
8
|
# License:: Distributed under the MIT license.
|
9
9
|
|
10
10
|
require "xnode/keystone/version"
|
11
|
-
require "xnode/keystone/http"
|
12
11
|
require "xnode/keystone/utils"
|
13
12
|
|
14
13
|
require 'json'
|
14
|
+
require 'rest-client'
|
15
15
|
|
16
16
|
module Xnode
|
17
17
|
module Keystone
|
18
18
|
|
19
|
-
#
|
20
|
-
|
21
|
-
#
|
22
|
-
# ==== Example
|
23
|
-
#
|
24
|
-
# => auth = Xnode::Keystone::Authenticate.new
|
25
|
-
# => request = auth.request
|
26
|
-
# => token = auth.get_token(request)
|
27
|
-
# => catalog = auth.catalog(request)
|
28
|
-
# => keystone_endpoint = catalog['identity']['public']
|
29
|
-
# => tenants = auth.tenants(keystone_endpoint, token)
|
30
|
-
class Authenticate
|
31
|
-
|
32
|
-
# Set accessors for credentials
|
33
|
-
attr_accessor :username, :password, :tenant, :baseurl, :url
|
34
|
-
|
35
|
-
# Authenticates against the OpenStack Identity API endpoint on 5000/tcp or 35357/tcp via HTTP/S.
|
36
|
-
# Uses environment variables to set your authentication credentials.
|
37
|
-
def initialize
|
38
|
-
@username = ENV['OS_USERNAME']
|
39
|
-
@password = ENV['OS_PASSWORD']
|
40
|
-
@tenant = ENV['OS_TENANT_NAME']
|
41
|
-
@baseurl = ENV['OS_AUTH_URL']
|
42
|
-
end
|
19
|
+
# Provide support for v2.0 of the Keystone Identity Service
|
20
|
+
module V2
|
43
21
|
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
22
|
+
# This class sets up an authenticated session with the OpenStack API's via Keystone, and exposes methods for
|
23
|
+
# interacting the Identity service.
|
24
|
+
#
|
25
|
+
# ==== Example
|
26
|
+
#
|
27
|
+
# => auth = Xnode::Keystone::V2::Authenticate.new
|
28
|
+
# => request = auth.request
|
29
|
+
# => token = auth.get_token(request)
|
30
|
+
# => catalog = auth.catalog(request)
|
31
|
+
# => keystone_endpoint = catalog['identity']['public']
|
32
|
+
# => tenants = auth.tenants(keystone_endpoint, token)
|
33
|
+
class Authenticate
|
52
34
|
|
53
|
-
|
54
|
-
|
55
|
-
data['access']['token']['id']
|
56
|
-
end
|
35
|
+
# Set accessors for credentials
|
36
|
+
attr_accessor :username, :password, :tenant, :baseurl, :url
|
57
37
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
38
|
+
# Authenticates against the OpenStack Identity API endpoint on 5000/tcp or 35357/tcp via HTTP/S.
|
39
|
+
# Uses environment variables to set your authentication credentials.
|
40
|
+
def initialize
|
41
|
+
@username = ENV['OS_USERNAME']
|
42
|
+
@password = ENV['OS_PASSWORD']
|
43
|
+
@tenant = ENV['OS_TENANT_NAME']
|
44
|
+
@baseurl = ENV['OS_AUTH_URL']
|
45
|
+
end
|
46
|
+
|
47
|
+
# Uses a private post method (keystone/http.rb) to send an HTTP POST request to OpenStack. The JSON response is
|
48
|
+
# automatically decoded into a Ruby Hash for later manipulation. The response body remains untouched otherwise,
|
49
|
+
# so everything you'd expect to find in the response is within the Hash.
|
50
|
+
def request
|
51
|
+
url = "#{@baseurl}/tokens"
|
52
|
+
data = Xnode::Keystone.auth_data(@tenant, @username, @password).to_json
|
53
|
+
request = RestClient.post "#{url}", data, :content_type => :json, :accept => :json
|
54
|
+
response = JSON.parse(request)
|
68
55
|
end
|
69
|
-
return mapendpoints
|
70
|
-
end
|
71
56
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
57
|
+
# Extracts the authentication token from the response, returning it as a String.
|
58
|
+
def get_token(data)
|
59
|
+
data['access']['token']['id']
|
60
|
+
end
|
61
|
+
|
62
|
+
# Parses the serviceCatalog returned within the response, and writes it into a modified Hash that makes it
|
63
|
+
# easy to extract public, internal or admin URI's by service type.
|
64
|
+
def catalog(data)
|
65
|
+
mapendpoints = Hash.new
|
66
|
+
data['access']['serviceCatalog'].each do |key, value|
|
67
|
+
mapendpoints[key['type']] = {
|
68
|
+
'public' => key['endpoints'][0]['publicURL'],
|
69
|
+
'internal' => key['endpoints'][0]['internalURL'],
|
70
|
+
'admin' => key['endpoints'][0]['adminURL']
|
71
|
+
}
|
72
|
+
end
|
73
|
+
return mapendpoints
|
74
|
+
end
|
76
75
|
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Provide support for v3 of the Keystone Identity Service
|
79
|
+
module V3
|
80
|
+
|
81
|
+
# This class sets up an authenticated session with the OpenStack API's via Keystone, and exposes methods for
|
82
|
+
# interacting the Identity service.
|
83
|
+
#
|
84
|
+
# ==== Example
|
85
|
+
#
|
86
|
+
# => auth = Xnode::Keystone::V3::Authenticate.new
|
87
|
+
# => request = auth.request
|
88
|
+
# => token = auth.get_token(request)
|
89
|
+
# => catalog = auth.catalog(request)
|
90
|
+
# => keystone_endpoint = catalog['identity']['public']
|
91
|
+
# => tenants = auth.tenants(keystone_endpoint, token)
|
92
|
+
class Authenticate
|
77
93
|
|
94
|
+
# Set accessors for credentials
|
95
|
+
attr_accessor :username, :password, :tenant, :baseurl, :token
|
96
|
+
|
97
|
+
# Authenticates against the OpenStack Identity API endpoint on 5000/tcp or 35357/tcp via HTTP/S.
|
98
|
+
# Uses environment variables to set your authentication credentials.
|
99
|
+
def initialize
|
100
|
+
@username = ENV['OS_USERNAME']
|
101
|
+
@password = ENV['OS_PASSWORD']
|
102
|
+
@tenant = ENV['OS_TENANT_NAME']
|
103
|
+
@baseurl = ENV['OS_AUTH_URL_V3']
|
104
|
+
end
|
105
|
+
|
106
|
+
# Uses a private post method (keystone/http.rb) to send an HTTP POST request to OpenStack. The JSON response is
|
107
|
+
# automatically decoded into a Ruby Hash for later manipulation. The response body remains untouched otherwise,
|
108
|
+
# so everything you'd expect to find in the response is within the Hash.
|
109
|
+
def request
|
110
|
+
url = "#{@baseurl}/auth/tokens"
|
111
|
+
data = Xnode::Keystone.auth_data_v3(@username, @password).to_json
|
112
|
+
# TODO: fix this so that the generic :post method can be used.
|
113
|
+
response = RestClient.post "#{url}", data, :content_type => :json, :accept => :json
|
114
|
+
@token = response.headers[:x_subject_token]
|
115
|
+
|
116
|
+
return JSON.parse(response.body)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Extracts the authentication token from the response, returning it as a String.
|
120
|
+
def get_token
|
121
|
+
@token
|
122
|
+
end
|
123
|
+
|
124
|
+
# Parses the serviceCatalog returned within the response, and writes it into a modified Hash that makes it
|
125
|
+
# easy to extract public, internal or admin URI's by service type.
|
126
|
+
def catalog(data)
|
127
|
+
mapendpoints = Hash.new
|
128
|
+
data['token']['catalog'].each do |key, value|
|
129
|
+
mapendpoints[key['type']] = Hash.new
|
130
|
+
key['endpoints'].each do |k, v|
|
131
|
+
mapendpoints[key['type']][k['interface']] = "#{k['url']}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
return mapendpoints
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
78
138
|
end
|
79
139
|
end
|
80
140
|
end
|
data/lib/xnode/keystone/http.rb
CHANGED
@@ -1,46 +1 @@
|
|
1
|
-
#
|
2
|
-
# other library calls, but allows the author to switch out and modify the requests without breaking the API, as
|
3
|
-
# the request responses are dictated by the OpenStack platform, allowing some scope in modifying the request/response
|
4
|
-
# features for speed or error handling proficiency.
|
5
|
-
|
6
|
-
require 'rest-client'
|
7
|
-
|
8
|
-
module Xnode
|
9
|
-
module Keystone
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
# Send an HTTP GET request to an OpenStack API endpoint.
|
14
|
-
def get(url, token)
|
15
|
-
request = RestClient::Request.execute(
|
16
|
-
method: :get,
|
17
|
-
url: "#{url}",
|
18
|
-
headers: {'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'})
|
19
|
-
response = JSON.parse(request.body)
|
20
|
-
end
|
21
|
-
module_function :get
|
22
|
-
|
23
|
-
# Send an HTTP POST request to an OpenStack API endpoint.
|
24
|
-
def post(url, data)
|
25
|
-
request = RestClient.post "#{url}", data, :content_type => :json, :accept => :json
|
26
|
-
response = JSON.parse(request.body)
|
27
|
-
end
|
28
|
-
module_function :post
|
29
|
-
|
30
|
-
# Send an HTTP DELETE request to an OpenStack API endpoint.
|
31
|
-
def delete
|
32
|
-
end
|
33
|
-
module_function :delete
|
34
|
-
|
35
|
-
# Send an HTTP PATCH request to an OpenStack API endpoint.
|
36
|
-
def patch
|
37
|
-
end
|
38
|
-
module_function :patch
|
39
|
-
|
40
|
-
# Send an HTTP PUT request to an OpenStack API endpoint.
|
41
|
-
def put
|
42
|
-
end
|
43
|
-
module_function :put
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
1
|
+
# STUB
|
data/lib/xnode/keystone/utils.rb
CHANGED
@@ -8,7 +8,7 @@ module Xnode
|
|
8
8
|
|
9
9
|
# Set up a Keystone JSON request body for authentication purposes.
|
10
10
|
def auth_data(tenant, username, password)
|
11
|
-
|
11
|
+
payload = {
|
12
12
|
:auth => {
|
13
13
|
:tenantName => tenant,
|
14
14
|
:passwordCredentials => {
|
@@ -20,5 +20,29 @@ module Xnode
|
|
20
20
|
end
|
21
21
|
module_function :auth_data
|
22
22
|
|
23
|
+
# Set up a Keystone V3 JSON request body for authentication purposes.
|
24
|
+
def auth_data_v3(username, password)
|
25
|
+
payload = {
|
26
|
+
:auth => {
|
27
|
+
:identity => {
|
28
|
+
:methods =>
|
29
|
+
[
|
30
|
+
:password
|
31
|
+
],
|
32
|
+
:password => {
|
33
|
+
:user => {
|
34
|
+
:domain => {
|
35
|
+
:id => :default
|
36
|
+
},
|
37
|
+
:name => username,
|
38
|
+
:password => password
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
module_function :auth_data_v3
|
46
|
+
|
23
47
|
end
|
24
48
|
end
|
data/xnode-keystone.gemspec
CHANGED
@@ -14,6 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = "https://github.com/xnoder/xnode-keystone"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
|
+
spec.required_ruby_version = '~> 1.9.3-p551'
|
18
|
+
|
17
19
|
spec.add_runtime_dependency 'rest-client', "~> 1.8", ">= 1.8.0"
|
18
20
|
|
19
21
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xnode-keystone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Stevens
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -130,9 +130,9 @@ require_paths:
|
|
130
130
|
- lib
|
131
131
|
required_ruby_version: !ruby/object:Gem::Requirement
|
132
132
|
requirements:
|
133
|
-
- - "
|
133
|
+
- - "~>"
|
134
134
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
135
|
+
version: 1.9.3.pre.p551
|
136
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
137
|
requirements:
|
138
138
|
- - ">="
|