datacentred 0.1.1pre → 1.1.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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +11 -0
  3. data/.coveralls.yml +1 -0
  4. data/.gitignore +9 -0
  5. data/.rubocop.yml +2 -0
  6. data/.yardopts +1 -0
  7. data/CODE_OF_CONDUCT.md +46 -0
  8. data/Gemfile.lock +39 -2
  9. data/LICENSE +21 -0
  10. data/README.md +160 -2
  11. data/circle.yml +0 -2
  12. data/datacentred.gemspec +17 -14
  13. data/docs/Datacentred.html +537 -0
  14. data/docs/Datacentred/Errors.html +260 -0
  15. data/docs/Datacentred/Errors/Error.html +139 -0
  16. data/docs/Datacentred/Errors/NotFound.html +145 -0
  17. data/docs/Datacentred/Errors/Unauthorized.html +149 -0
  18. data/docs/Datacentred/Errors/UnprocessableEntity.html +145 -0
  19. data/docs/Datacentred/Model.html +128 -0
  20. data/docs/Datacentred/Model/Base.html +255 -0
  21. data/docs/Datacentred/Model/Project.html +1729 -0
  22. data/docs/Datacentred/Model/Role.html +1830 -0
  23. data/docs/Datacentred/Model/Usage.html +510 -0
  24. data/docs/Datacentred/Model/User.html +832 -0
  25. data/docs/Datacentred/Model/Version.html +451 -0
  26. data/docs/Datacentred/Project.html +142 -0
  27. data/docs/Datacentred/Request.html +128 -0
  28. data/docs/Datacentred/Request/Base.html +675 -0
  29. data/docs/Datacentred/Request/Projects.html +1286 -0
  30. data/docs/Datacentred/Request/Roles.html +1286 -0
  31. data/docs/Datacentred/Request/Usage.html +315 -0
  32. data/docs/Datacentred/Request/Users.html +841 -0
  33. data/docs/Datacentred/Request/Versions.html +258 -0
  34. data/docs/Datacentred/Response.html +410 -0
  35. data/docs/Datacentred/Role.html +142 -0
  36. data/docs/Datacentred/Usage.html +142 -0
  37. data/docs/Datacentred/User.html +142 -0
  38. data/docs/Datacentred/Version.html +142 -0
  39. data/docs/_index.html +349 -0
  40. data/docs/class_list.html +51 -0
  41. data/docs/css/common.css +1 -0
  42. data/docs/css/full_list.css +58 -0
  43. data/docs/css/style.css +492 -0
  44. data/docs/file.README.html +231 -0
  45. data/docs/file_list.html +56 -0
  46. data/docs/frames.html +17 -0
  47. data/docs/index.html +231 -0
  48. data/docs/js/app.js +248 -0
  49. data/docs/js/full_list.js +216 -0
  50. data/docs/js/jquery.js +4 -0
  51. data/docs/method_list.html +643 -0
  52. data/docs/top-level-namespace.html +110 -0
  53. data/lib/datacentred.rb +65 -12
  54. data/lib/datacentred/error.rb +37 -15
  55. data/lib/datacentred/model/base.rb +21 -0
  56. data/lib/datacentred/model/project.rb +90 -31
  57. data/lib/datacentred/model/role.rb +89 -31
  58. data/lib/datacentred/model/usage.rb +16 -9
  59. data/lib/datacentred/model/user.rb +54 -22
  60. data/lib/datacentred/model/version.rb +17 -8
  61. data/lib/datacentred/request/base.rb +68 -31
  62. data/lib/datacentred/request/projects.rb +92 -24
  63. data/lib/datacentred/request/roles.rb +92 -24
  64. data/lib/datacentred/request/usage.rb +10 -1
  65. data/lib/datacentred/request/users.rb +58 -15
  66. data/lib/datacentred/request/versions.rb +13 -1
  67. data/lib/datacentred/response.rb +6 -2
  68. data/test/integration/authorization_test.rb +30 -0
  69. data/test/integration/projects_test.rb +11 -11
  70. data/test/integration/roles_test.rb +17 -17
  71. data/test/integration/usage_test.rb +8 -8
  72. data/test/integration/users_test.rb +23 -19
  73. data/test/integration/versions_test.rb +1 -2
  74. data/test/test_helper.rb +8 -5
  75. data/test/vcr_cassettes/not_authorized.yml +57 -0
  76. data/test/vcr_cassettes/unexpected_error.yml +56 -0
  77. metadata +115 -9
@@ -1,14 +1,21 @@
1
1
  module Datacentred
2
2
  module Model
3
- class Usage < OpenStruct
4
- def initialize(params)
5
- params.delete("links")
6
- # params["last_updated_at"] = Time.parse params["last_updated_at"]
7
- super(params)
8
- end
9
-
10
- def self.show(year, month)
11
- Request::Usage.show(year, month)["projects"].map{ |project| new(project) }
3
+ # Usage data for a given month/year.
4
+ #
5
+ # Data is updated every few hours for the current month.
6
+ #
7
+ # @attr [Time] last_updated_at
8
+ # @attr [[Hash]] projects
9
+ class Usage < Base
10
+ # Retrieve account usage data for a given year/month.
11
+ #
12
+ # @param [Integer] year The year.
13
+ # @param [Integer] month The month.
14
+ # @raise [Errors::NotFound] Raised if no usage data found for given year/month pair.
15
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
16
+ # @return [Usage] Usage for given year/month pair.
17
+ def self.find(year, month)
18
+ new Request::Usage.show year, month
12
19
  end
13
20
  end
14
21
  end
@@ -1,31 +1,63 @@
1
1
  module Datacentred
2
2
  module Model
3
- class User < OpenStruct
4
- def initialize(params)
5
- params.delete("links")
6
- params["created_at"] = Time.parse params["created_at"]
7
- params["updated_at"] = Time.parse params["updated_at"]
8
- super(params)
9
- end
10
-
11
- def self.all
12
- Request::Users.list.map { |user| new(user) }
13
- end
3
+ # A user on your DataCentred account.
4
+ #
5
+ # Users are team members with the ability to log into your DataCentred account.
6
+ #
7
+ # All users created in your DataCented account are backed by a corresponding user in OpenStack's identity service (Keystone).
8
+ class User < Base
9
+ class << self
10
+ # Create a new user.
11
+ #
12
+ # @param [Hash] params User attributes.
13
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the supplied attributes.
14
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
15
+ # @return [User] New user.
16
+ def create(params)
17
+ new Request::Users.create params
18
+ end
14
19
 
15
- def self.find(id)
16
- new Request::Users.show(id)
17
- end
20
+ # List all available users.
21
+ #
22
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
23
+ # @return [[User]] A collection of all users on this account.
24
+ def all
25
+ Request::Users.list.map {|user| new user }
26
+ end
18
27
 
19
- def self.create(params)
20
- new Request::Users.create(params)
21
- end
28
+ # Find a user by unique ID.
29
+ #
30
+ # @param [String] id The unique identifier for this user.
31
+ # @raise [Errors::NotFound] Raised if the user couldn't be found.
32
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
33
+ # @return [User] The user, if it exists.
34
+ def find(id)
35
+ new Request::Users.show id
36
+ end
22
37
 
23
- def self.update(id, params)
24
- new Request::Users.update(id, params)
25
- end
38
+ # Update a user by unique ID.
39
+ #
40
+ # @param [String] id The unique identifier for this user.
41
+ # @param [Hash] params User attributes.
42
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the supplied attributes.
43
+ # @raise [Errors::NotFound] Raised if the user couldn't be found.
44
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
45
+ # @return [User] The updated user.
46
+ def update(id, params)
47
+ new Request::Users.update id, params
48
+ end
26
49
 
27
- def self.delete(id)
28
- Request::Users.destroy(id)
50
+ # Permanently remove the specified user.
51
+ #
52
+ # @param [String] id The unique identifier for this user.
53
+ # @raise [Errors::NotFound] Raised if the user couldn't be found.
54
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the specified user.
55
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
56
+ # @return [Boolean] Confirms the user was destroyed.
57
+ def destroy(id)
58
+ Request::Users.destroy id
59
+ true
60
+ end
29
61
  end
30
62
  end
31
63
  end
@@ -1,13 +1,22 @@
1
1
  module Datacentred
2
2
  module Model
3
- class Version < OpenStruct
4
- def initialize(params)
5
- params.delete("links")
6
- super(params)
7
- end
8
-
9
- def self.show
10
- Request::Versions.list.map { |version| new(version) }
3
+ # An API version currently available for use.
4
+ #
5
+ # This method does not require authentication.
6
+ #
7
+ # An API version may be:
8
+ # * *CURRENT* - The latest supported version.
9
+ # * *SUPPORTED* - A supported older version.
10
+ # * *DEPRECATED* - Currently supported but soon to be retired.
11
+ #
12
+ # @attr [Integer] id
13
+ # @attr [String] status
14
+ class Version < Base
15
+ # List all available API versions
16
+ #
17
+ # @return [[Version]] Currently available versions of the API.
18
+ def self.all
19
+ Request::Versions.list.map {|version| new version }
11
20
  end
12
21
  end
13
22
  end
@@ -1,46 +1,83 @@
1
1
  module Datacentred
2
2
  module Request
3
- API_BASE_URL = 'https://my.datacentred.io'
4
-
3
+ # Base class for all API requests.
4
+ #
5
+ # Uses the Faraday library for HTTP interactions.
5
6
  class Base
7
+ class << self
8
+ # Access a resource via HTTP GET.
9
+ #
10
+ # @param [String] path Desired server path.
11
+ # @raise [Errors::Error] Raised if the server returns a non 2xx error code.
12
+ # @return [Object] Parsed server response body.
13
+ def get(path)
14
+ action :get, path
15
+ end
6
16
 
7
- def self.get(url, payload=nil)
8
- response = Datacentred::Response.new(conn.get(url, payload))
9
- response.body
10
- end
17
+ # Access a resource via HTTP POST.
18
+ #
19
+ # @param [String] path Desired server path.
20
+ # @param [Object] payload JSON serializable object.
21
+ # @raise [Errors::Error] Raised if the server returns a non 2xx error code.
22
+ # @return [Object] Parsed server response body.
23
+ def post(path, payload=nil)
24
+ action :post, path, payload
25
+ end
11
26
 
12
- def self.post(url, payload=nil)
13
- response = Datacentred::Response.new(conn.post(url, payload))
14
- response.body
15
- end
27
+ # Access a resource via HTTP PUT.
28
+ #
29
+ # @param [String] path Desired server path.
30
+ # @param [Object] payload JSON serializable object.
31
+ # @raise [Errors::Error] Raised if the server returns a non 2xx error code.
32
+ # @return [Object] Parsed server response body.
33
+ def put(path, payload=nil)
34
+ action :put, path, payload
35
+ end
16
36
 
17
- def self.put(url, payload=nil)
18
- response = Datacentred::Response.new(conn.put(url, payload))
19
- response.body
20
- end
37
+ # Access a resource via HTTP DELETE.
38
+ #
39
+ # @param [String] path Desired server path.
40
+ # @raise [Errors::Error] Raised if the server returns a non 2xx error code.
41
+ # @return [nil] Returns nil on success.
42
+ def delete(path)
43
+ action :delete, path
44
+ end
21
45
 
22
- def self.delete(url, payload=nil)
23
- response = Datacentred::Response.new(conn.delete(url, payload))
24
- response.body
25
- end
46
+ private
26
47
 
27
- private
48
+ def action(verb, path, payload=nil)
49
+ params = [path, payload&.to_json].compact
50
+ response = Datacentred::Response.new connection.send verb, *params
51
+ response.body
52
+ end
28
53
 
29
- def self.conn
30
- Faraday.new(:url => API_BASE_URL) do |faraday|
31
- faraday.path_prefix = "/api/"
32
- faraday.request :url_encoded
33
- faraday.headers['Accept'] = "application/vnd.datacentred.api+json; version=1"
34
- faraday.headers['Authorization'] = "Token token=#{credentials}"
35
- faraday.headers['Content-Type'] = 'application/json'
36
- faraday.adapter Faraday.default_adapter
54
+ def connection
55
+ Faraday.new(url: base_url) do |faraday|
56
+ faraday.request :url_encoded
57
+ faraday.adapter Faraday.default_adapter
58
+ faraday.headers['Accept'] = "#{accept_type}; version=#{api_version}"
59
+ faraday.headers['Authorization'] = "Token token=#{credentials}"
60
+ faraday.headers['Content-Type'] = "application/json"
61
+ faraday.path_prefix = "/api/"
62
+ end
37
63
  end
38
- end
39
64
 
40
- def self.credentials
41
- "#{Datacentred.access_key}:#{Datacentred.secret_key}"
42
- end
65
+ def accept_type
66
+ "application/vnd.datacentred.api+json"
67
+ end
68
+
69
+ def api_version
70
+ "1".freeze
71
+ end
43
72
 
73
+ def base_url
74
+ "https://my.datacentred.io"
75
+ end
76
+
77
+ def credentials
78
+ [Datacentred.access_key, Datacentred.secret_key].join ":"
79
+ end
80
+ end
44
81
  end
45
82
  end
46
83
  end
@@ -1,37 +1,105 @@
1
1
  module Datacentred
2
2
  module Request
3
+ # RESTful API requests for the projects endpoints.
3
4
  class Projects < Base
5
+ class << self
6
+ # Create a new project.
7
+ #
8
+ # POST /api/projects
9
+ #
10
+ # @param [Hash] params Project attributes.
11
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the supplied attributes.
12
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
13
+ # @return [Hash] New project.
14
+ def create(params)
15
+ post('projects', 'project' => params)['project']
16
+ end
4
17
 
5
- def self.create(payload={})
6
- post('projects', payload.to_json)['project']
7
- end
8
-
9
- def self.list
10
- get('projects')['projects']
11
- end
18
+ # List all available projects.
19
+ #
20
+ # GET /api/projects
21
+ #
22
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
23
+ # @return [[Hash]] A collection of all projects on this account.
24
+ def list
25
+ get('projects')['projects']
26
+ end
12
27
 
13
- def self.show(id)
14
- get("projects/#{id}")['project']
15
- end
28
+ # Find a project by unique ID.
29
+ #
30
+ # GET /api/projects/ead738d9f894bed9
31
+ #
32
+ # @param [String] id The unique identifier for this project.
33
+ # @raise [Errors::NotFound] Raised if the project couldn't be found.
34
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
35
+ # @return [Hash] The project, if it exists.
36
+ def show(id)
37
+ get("projects/#{id}")['project']
38
+ end
16
39
 
17
- def self.update(id, payload={})
18
- put("projects/#{id}", payload.to_json)['project']
19
- end
40
+ # Update a project by unique ID.
41
+ #
42
+ # PUT /api/projects/ead738d9f894bed9
43
+ #
44
+ # @param [String] id The unique identifier for this project.
45
+ # @param [Hash] params Project attributes.
46
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the supplied attributes.
47
+ # @raise [Errors::NotFound] Raised if the project could not be found.
48
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
49
+ # @return [Hash] The updated project.
50
+ def update(id, params)
51
+ put("projects/#{id}", 'project' => params)['project']
52
+ end
20
53
 
21
- def self.destroy(id)
22
- delete("projects/#{id}")
23
- end
54
+ # Permanently remove the specified project.
55
+ #
56
+ # DELETE /api/projects/ead738d9f894bed9
57
+ #
58
+ # @param [String] id The unique identifier for this project.
59
+ # @raise [Errors::NotFound] Raised if the project couldn't be found.
60
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the specified project.
61
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
62
+ # @return [nil] Confirms the user was destroyed.
63
+ def destroy(id)
64
+ delete("projects/#{id}")
65
+ end
24
66
 
25
- def self.list_users(id)
26
- get("projects/#{id}/users")['users']
27
- end
67
+ # List all users assigned to this project.
68
+ #
69
+ # GET /api/projects/ead738d9f894bed9/users
70
+ #
71
+ # @param [String] id The unique identifier for this project.
72
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
73
+ # @return [[Hash]] A collection of the project's users.
74
+ def list_users(id)
75
+ get("projects/#{id}/users")['users']
76
+ end
28
77
 
29
- def self.add_user(project_id, user_id)
30
- put("projects/#{project_id}/users/#{user_id}")
31
- end
78
+ # Add a new user to this project, giving them access to it via OpenStack.
79
+ #
80
+ # PUT /api/projects/ead738d9f894bed9/users/82fa8de8f09102cc
81
+ #
82
+ # @param [String] project_id The unique identifier for this project.
83
+ # @param [String] user_id The unique identifier for this user.
84
+ # @raise [Errors::NotFound] Raised if the project or user couldn't be found.
85
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
86
+ # @return [nil] Confirms the user was added (or is already present).
87
+ def add_user(project_id, user_id)
88
+ put("projects/#{project_id}/users/#{user_id}")
89
+ end
32
90
 
33
- def self.remove_user(project_id, user_id)
34
- delete("projects/#{project_id}/users/#{user_id}")
91
+ # Remove user from this project, revoking their access to it on OpenStack.
92
+ #
93
+ # DELETE /api/projects/ead738d9f894bed9/users/82fa8de8f09102cc
94
+ #
95
+ # @param [String] project_id The unique identifier for this project.
96
+ # @param [String] user_id The unique identifier for this user.
97
+ # @raise [Errors::NotFound] Raised if project or user couldn't be found.
98
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
99
+ # @return [nil] Confirms that user was removed (or is already absent).
100
+ def remove_user(project_id, user_id)
101
+ delete("projects/#{project_id}/users/#{user_id}")
102
+ end
35
103
  end
36
104
  end
37
105
  end
@@ -1,37 +1,105 @@
1
1
  module Datacentred
2
2
  module Request
3
+ # RESTful API requests for the roles endpoints.
3
4
  class Roles < Base
5
+ class << self
6
+ # Create a new role.
7
+ #
8
+ # POST /api/roles
9
+ #
10
+ # @param [Hash] params Role attributes.
11
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the supplied attributes.
12
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
13
+ # @return [Hash] New role.
14
+ def create(params)
15
+ post('roles', 'role' => params)['role']
16
+ end
4
17
 
5
- def self.create(payload={})
6
- post('roles', payload.to_json)['role']
7
- end
8
-
9
- def self.list
10
- get('roles')['roles']
11
- end
18
+ # List all available roles.
19
+ #
20
+ # GET /api/roles
21
+ #
22
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
23
+ # @return [[Hash]] A collection of all roles on this account.
24
+ def list
25
+ get('roles')['roles']
26
+ end
12
27
 
13
- def self.show(id)
14
- get("roles/#{id}")['role']
15
- end
28
+ # Find a role by unique ID.
29
+ #
30
+ # GET /api/roles/ea894bed9d738d9f
31
+ #
32
+ # @param [String] id The unique identifier for this role.
33
+ # @raise [Errors::NotFound] Raised if the role couldn't be found.
34
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
35
+ # @return [Hash] The role, if it exists.
36
+ def show(id)
37
+ get("roles/#{id}")['role']
38
+ end
16
39
 
17
- def self.update(id, payload={})
18
- put("roles/#{id}", payload.to_json)['role']
19
- end
40
+ # Update a role by unique ID.
41
+ #
42
+ # PUT /api/roles/ea894bed9d738d9f
43
+ #
44
+ # @param [String] id The unique identifier for this role.
45
+ # @param [Hash] params Role attributes.
46
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the supplied attributes.
47
+ # @raise [Errors::NotFound] Raised if the role doesn't exist.
48
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
49
+ # @return [Hash] The updated role.
50
+ def update(id, params)
51
+ put("roles/#{id}", 'role' => params)['role']
52
+ end
20
53
 
21
- def self.destroy(id)
22
- delete("roles/#{id}")
23
- end
54
+ # Permanently remove the specified role.
55
+ #
56
+ # DELETE /api/roles/ea894bed9d738d9f
57
+ #
58
+ # @param [String] id The unique identifier for this role.
59
+ # @raise [Errors::NotFound] Raised if the role couldn't be found.
60
+ # @raise [Errors::UnprocessableEntity] Raised if validations fail for the specifed role.
61
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
62
+ # @return [nil] Confirms the role was destroyed.
63
+ def destroy(id)
64
+ delete("roles/#{id}")
65
+ end
24
66
 
25
- def self.list_users(role_id)
26
- get("roles/#{role_id}/users")['users']
27
- end
67
+ # List all users assigned to this role.
68
+ #
69
+ # GET /api/roles/ea894bed9d738d9f/users
70
+ #
71
+ # @param [String] role_id The unique identifier for this role.
72
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
73
+ # @return [[Hash]] A collection of the role's users.
74
+ def list_users(role_id)
75
+ get("roles/#{role_id}/users")['users']
76
+ end
28
77
 
29
- def self.add_user(role_id, user_id)
30
- put("roles/#{role_id}/users/#{user_id}")
31
- end
78
+ # Add new user to this role, giving them the associated permissions.
79
+ #
80
+ # PUT /api/roles/ea894bed9d738d9f/users/82fa8de8f09102cc
81
+ #
82
+ # @param [String] role_id The unique identifier for this role.
83
+ # @param [String] user_id The unique identifier for this user.
84
+ # @raise [Errors::NotFound] Raised if the role or user couldn't be found.
85
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
86
+ # @return [nil] Confirms that user was added (or is already present).
87
+ def add_user(role_id, user_id)
88
+ put("roles/#{role_id}/users/#{user_id}")
89
+ end
32
90
 
33
- def self.remove_user(role_id, user_id)
34
- delete("roles/#{role_id}/users/#{user_id}")
91
+ # Remove user from this role, revoking the associated permissions.
92
+ #
93
+ # DELETE /api/roles/ea894bed9d738d9f/users/82fa8de8f09102cc
94
+ #
95
+ # @param [String] role_id The unique identifier for this role.
96
+ # @param [String] user_id The unique identifier for this user.
97
+ # @raise [Errors::NotFound] Raised if the role or user coundn't be found.
98
+ # @raise [Errors::Unauthorized] Raised if credentials aren't valid.
99
+ # @return [nil] Confirms that user was removed (or is already absent).
100
+ def remove_user(role_id, user_id)
101
+ delete("roles/#{role_id}/users/#{user_id}")
102
+ end
35
103
  end
36
104
  end
37
105
  end