scalingo 3.0.0.beta.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 (222) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rubocop.yml +16 -0
  4. data/.travis.yml +24 -0
  5. data/CHANGELOG.md +29 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +110 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +147 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +12 -0
  12. data/bin/setup +8 -0
  13. data/lib/scalingo.rb +2 -0
  14. data/lib/scalingo/api/client.rb +79 -0
  15. data/lib/scalingo/api/endpoint.rb +23 -0
  16. data/lib/scalingo/api/response.rb +71 -0
  17. data/lib/scalingo/auth.rb +21 -0
  18. data/lib/scalingo/auth/keys.rb +56 -0
  19. data/lib/scalingo/auth/scm_integrations.rb +57 -0
  20. data/lib/scalingo/auth/tokens.rb +78 -0
  21. data/lib/scalingo/auth/two_factor_auth.rb +61 -0
  22. data/lib/scalingo/auth/user.rb +31 -0
  23. data/lib/scalingo/bearer_token.rb +20 -0
  24. data/lib/scalingo/client.rb +105 -0
  25. data/lib/scalingo/config.rb +38 -0
  26. data/lib/scalingo/error/expired_token.rb +6 -0
  27. data/lib/scalingo/error/unauthenticated.rb +6 -0
  28. data/lib/scalingo/errors.rb +2 -0
  29. data/lib/scalingo/regional.rb +35 -0
  30. data/lib/scalingo/regional/addons.rb +109 -0
  31. data/lib/scalingo/regional/apps.rb +109 -0
  32. data/lib/scalingo/regional/collaborators.rb +57 -0
  33. data/lib/scalingo/regional/containers.rb +57 -0
  34. data/lib/scalingo/regional/deployments.rb +44 -0
  35. data/lib/scalingo/regional/domains.rb +70 -0
  36. data/lib/scalingo/regional/environment.rb +83 -0
  37. data/lib/scalingo/regional/events.rb +55 -0
  38. data/lib/scalingo/regional/logs.rb +38 -0
  39. data/lib/scalingo/regional/metrics.rb +41 -0
  40. data/lib/scalingo/regional/notifiers.rb +96 -0
  41. data/lib/scalingo/regional/operations.rb +18 -0
  42. data/lib/scalingo/regional/scm_repo_links.rb +109 -0
  43. data/lib/scalingo/version.rb +3 -0
  44. data/samples/auth/keys/_meta.json +13 -0
  45. data/samples/auth/keys/all-200.json +62 -0
  46. data/samples/auth/keys/create-201.json +67 -0
  47. data/samples/auth/keys/create-422.json +34 -0
  48. data/samples/auth/keys/destroy-204.json +19 -0
  49. data/samples/auth/keys/destroy-404.json +19 -0
  50. data/samples/auth/keys/show-200.json +60 -0
  51. data/samples/auth/keys/show-404.json +19 -0
  52. data/samples/auth/scm_integrations/_meta.json +14 -0
  53. data/samples/auth/scm_integrations/all-200.json +41 -0
  54. data/samples/auth/scm_integrations/create-201.json +41 -0
  55. data/samples/auth/scm_integrations/create-422.json +36 -0
  56. data/samples/auth/scm_integrations/destroy-204.json +15 -0
  57. data/samples/auth/scm_integrations/destroy-404.json +23 -0
  58. data/samples/auth/scm_integrations/show-200.json +34 -0
  59. data/samples/auth/scm_integrations/show-404.json +23 -0
  60. data/samples/auth/tokens/_meta.json +13 -0
  61. data/samples/auth/tokens/all-200.json +32 -0
  62. data/samples/auth/tokens/create-201.json +37 -0
  63. data/samples/auth/tokens/destroy-204.json +19 -0
  64. data/samples/auth/tokens/destroy-404.json +19 -0
  65. data/samples/auth/tokens/exchange-200.json +25 -0
  66. data/samples/auth/tokens/exchange-401.json +24 -0
  67. data/samples/auth/tokens/renew-200.json +32 -0
  68. data/samples/auth/tokens/renew-404.json +20 -0
  69. data/samples/auth/two_factor_auth/_meta.json +10 -0
  70. data/samples/auth/two_factor_auth/disable-not-initiated.json +23 -0
  71. data/samples/auth/two_factor_auth/disable-success.json +29 -0
  72. data/samples/auth/two_factor_auth/initiate-already-enabled.json +29 -0
  73. data/samples/auth/two_factor_auth/initiate-success.json +36 -0
  74. data/samples/auth/two_factor_auth/initiate-wrong-provider.json +29 -0
  75. data/samples/auth/two_factor_auth/status.json +29 -0
  76. data/samples/auth/two_factor_auth/validate-not-initiated.json +29 -0
  77. data/samples/auth/two_factor_auth/validate-success.json +49 -0
  78. data/samples/auth/two_factor_auth/validate-wrong.json +29 -0
  79. data/samples/auth/user/_meta.json +10 -0
  80. data/samples/auth/user/self.json +54 -0
  81. data/samples/auth/user/update-200.json +59 -0
  82. data/samples/auth/user/update-422.json +33 -0
  83. data/samples/regional/addons/_meta.json +22 -0
  84. data/samples/regional/addons/categories-guest.json +36 -0
  85. data/samples/regional/addons/categories-logged.json +37 -0
  86. data/samples/regional/addons/destroy-204.json +19 -0
  87. data/samples/regional/addons/destroy-404.json +24 -0
  88. data/samples/regional/addons/find-200.json +48 -0
  89. data/samples/regional/addons/find-404.json +24 -0
  90. data/samples/regional/addons/for-200.json +50 -0
  91. data/samples/regional/addons/providers-guest.json +588 -0
  92. data/samples/regional/addons/providers-logged.json +705 -0
  93. data/samples/regional/addons/provision-201.json +58 -0
  94. data/samples/regional/addons/provision-400.json +29 -0
  95. data/samples/regional/addons/sso-200.json +49 -0
  96. data/samples/regional/addons/sso-404.json +24 -0
  97. data/samples/regional/addons/update-200.json +58 -0
  98. data/samples/regional/addons/update-404.json +30 -0
  99. data/samples/regional/apps/_meta.json +52 -0
  100. data/samples/regional/apps/all.json +99 -0
  101. data/samples/regional/apps/create-201.json +66 -0
  102. data/samples/regional/apps/create-422.json +34 -0
  103. data/samples/regional/apps/destroy-204.json +19 -0
  104. data/samples/regional/apps/destroy-404.json +24 -0
  105. data/samples/regional/apps/destroy-422.json +27 -0
  106. data/samples/regional/apps/find-200.json +60 -0
  107. data/samples/regional/apps/find-404.json +24 -0
  108. data/samples/regional/apps/logs_url.json +62 -0
  109. data/samples/regional/apps/rename-200.json +65 -0
  110. data/samples/regional/apps/rename-404.json +29 -0
  111. data/samples/regional/apps/rename-422.json +33 -0
  112. data/samples/regional/apps/transfer-200.json +65 -0
  113. data/samples/regional/apps/transfer-404.json +27 -0
  114. data/samples/regional/apps/transfer-422.json +34 -0
  115. data/samples/regional/apps/update-200.json +66 -0
  116. data/samples/regional/apps/update-stack-404.json +30 -0
  117. data/samples/regional/collaborators/_meta.json +17 -0
  118. data/samples/regional/collaborators/accept-200.json +60 -0
  119. data/samples/regional/collaborators/accept-400.json +24 -0
  120. data/samples/regional/collaborators/accept-404.json +24 -0
  121. data/samples/regional/collaborators/destroy-204.json +19 -0
  122. data/samples/regional/collaborators/destroy-404.json +24 -0
  123. data/samples/regional/collaborators/for-200.json +34 -0
  124. data/samples/regional/collaborators/invite-201.json +37 -0
  125. data/samples/regional/collaborators/invite-422.json +34 -0
  126. data/samples/regional/containers/_meta.json +25 -0
  127. data/samples/regional/containers/for-200.json +39 -0
  128. data/samples/regional/containers/restart-202.json +28 -0
  129. data/samples/regional/containers/restart-422.json +33 -0
  130. data/samples/regional/containers/scale-202.json +48 -0
  131. data/samples/regional/containers/scale-422.json +36 -0
  132. data/samples/regional/containers/sizes-guest.json +115 -0
  133. data/samples/regional/containers/sizes-logged.json +116 -0
  134. data/samples/regional/deployments/_meta.json +8 -0
  135. data/samples/regional/deployments/find-200.json +45 -0
  136. data/samples/regional/deployments/find-404.json +24 -0
  137. data/samples/regional/deployments/for-with-paging.json +35 -0
  138. data/samples/regional/deployments/for-without-pages.json +56 -0
  139. data/samples/regional/deployments/logs-200.json +22 -0
  140. data/samples/regional/deployments/logs-404.json +24 -0
  141. data/samples/regional/domains/_meta.json +21 -0
  142. data/samples/regional/domains/create-201.json +44 -0
  143. data/samples/regional/domains/create-422.json +33 -0
  144. data/samples/regional/domains/destroy-204.json +19 -0
  145. data/samples/regional/domains/destroy-404.json +24 -0
  146. data/samples/regional/domains/find-200.json +38 -0
  147. data/samples/regional/domains/find-404.json +24 -0
  148. data/samples/regional/domains/for-200.json +40 -0
  149. data/samples/regional/domains/update-200.json +44 -0
  150. data/samples/regional/domains/update-404.json +30 -0
  151. data/samples/regional/domains/update-422.json +33 -0
  152. data/samples/regional/environment/_meta.json +43 -0
  153. data/samples/regional/environment/bulk-destroy-204.json +19 -0
  154. data/samples/regional/environment/bulk-update-200.json +70 -0
  155. data/samples/regional/environment/create-201.json +36 -0
  156. data/samples/regional/environment/create-422.json +37 -0
  157. data/samples/regional/environment/destroy-204.json +19 -0
  158. data/samples/regional/environment/destroy-404.json +24 -0
  159. data/samples/regional/environment/for-200.json +31 -0
  160. data/samples/regional/environment/update-200.json +35 -0
  161. data/samples/regional/environment/update-404.json +30 -0
  162. data/samples/regional/events/_meta.json +3 -0
  163. data/samples/regional/events/all-200.json +619 -0
  164. data/samples/regional/events/categories-guest.json +66 -0
  165. data/samples/regional/events/categories-logged.json +67 -0
  166. data/samples/regional/events/for-200.json +404 -0
  167. data/samples/regional/events/types-guest.json +288 -0
  168. data/samples/regional/events/types-logged.json +289 -0
  169. data/samples/regional/logs/_meta.json +11 -0
  170. data/samples/regional/logs/archives-200.json +28 -0
  171. data/samples/regional/logs/get-guest-200.json +18 -0
  172. data/samples/regional/logs/get-logged-200.json +19 -0
  173. data/samples/regional/logs/get-with-limit-200.json +18 -0
  174. data/samples/regional/metrics/_meta.json +15 -0
  175. data/samples/regional/metrics/for-invalid-400.json +23 -0
  176. data/samples/regional/metrics/for-valid-cpu-200.json +747 -0
  177. data/samples/regional/metrics/for-valid-router-404.json +23 -0
  178. data/samples/regional/metrics/types-guest.json +66 -0
  179. data/samples/regional/metrics/types-logged.json +67 -0
  180. data/samples/regional/notifiers/_meta.json +23 -0
  181. data/samples/regional/notifiers/create-201.json +55 -0
  182. data/samples/regional/notifiers/create-404.json +30 -0
  183. data/samples/regional/notifiers/create-422.json +36 -0
  184. data/samples/regional/notifiers/destroy-204.json +19 -0
  185. data/samples/regional/notifiers/destroy-404.json +24 -0
  186. data/samples/regional/notifiers/find-200.json +47 -0
  187. data/samples/regional/notifiers/find-404.json +24 -0
  188. data/samples/regional/notifiers/for-200.json +49 -0
  189. data/samples/regional/notifiers/platforms-guest.json +184 -0
  190. data/samples/regional/notifiers/platforms-logged.json +185 -0
  191. data/samples/regional/notifiers/test-200.json +22 -0
  192. data/samples/regional/notifiers/test-404.json +25 -0
  193. data/samples/regional/notifiers/update-200.json +53 -0
  194. data/samples/regional/operations/_meta.json +5 -0
  195. data/samples/regional/operations/find-200.json +31 -0
  196. data/samples/regional/operations/find-404.json +24 -0
  197. data/samples/regional/scm_repo_links/_meta.json +22 -0
  198. data/samples/regional/scm_repo_links/create-201.json +54 -0
  199. data/samples/regional/scm_repo_links/destroy-204.json +15 -0
  200. data/samples/regional/scm_repo_links/manual-deploy-200.json +32 -0
  201. data/samples/regional/scm_repo_links/show-200.json +43 -0
  202. data/samples/regional/scm_repo_links/update-200.json +50 -0
  203. data/scalingo.gemspec +51 -0
  204. data/spec/scalingo/auth/keys_spec.rb +58 -0
  205. data/spec/scalingo/auth/scm_integrations_spec.rb +58 -0
  206. data/spec/scalingo/auth/tokens_spec.rb +74 -0
  207. data/spec/scalingo/auth/two_factor_auth_spec.rb +69 -0
  208. data/spec/scalingo/auth/user_spec.rb +25 -0
  209. data/spec/scalingo/regional/addons_spec.rb +133 -0
  210. data/spec/scalingo/regional/apps_spec.rb +137 -0
  211. data/spec/scalingo/regional/collaborators_spec.rb +69 -0
  212. data/spec/scalingo/regional/containers_spec.rb +67 -0
  213. data/spec/scalingo/regional/deployments_spec.rb +45 -0
  214. data/spec/scalingo/regional/domains_spec.rb +84 -0
  215. data/spec/scalingo/regional/environment_spec.rb +77 -0
  216. data/spec/scalingo/regional/events_spec.rb +65 -0
  217. data/spec/scalingo/regional/logs_spec.rb +39 -0
  218. data/spec/scalingo/regional/metrics_spec.rb +46 -0
  219. data/spec/scalingo/regional/notifiers_spec.rb +113 -0
  220. data/spec/scalingo/regional/operations_spec.rb +19 -0
  221. data/spec/scalingo/regional/scm_repo_links_spec.rb +48 -0
  222. metadata +488 -0
@@ -0,0 +1,23 @@
1
+ require "forwardable"
2
+ require "scalingo/api/response"
3
+
4
+ module Scalingo
5
+ module API
6
+ class Endpoint
7
+ extend Forwardable
8
+ attr_reader :client
9
+
10
+ def initialize(client)
11
+ @client = client
12
+ end
13
+
14
+ def_delegator :client, :connection
15
+
16
+ private
17
+
18
+ def unpack(*args)
19
+ Response.unpack(*args)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,71 @@
1
+ module Scalingo
2
+ module API
3
+ class Response
4
+ def self.transform_object(object, resource_class: nil)
5
+ resource_class&.new(object) || object
6
+ end
7
+
8
+ def self.transform_body(body, resource_class: nil)
9
+ case body
10
+ when Hash
11
+ transform_object(body, resource_class: resource_class)
12
+ when Array
13
+ body.map { |item| transform_object(item, resource_class: resource_class) }
14
+ else
15
+ body
16
+ end
17
+ end
18
+
19
+ def self.transform_meta(body)
20
+ if body.present? && body.respond_to?(:key) && body.key?(:meta)
21
+ body[:meta]
22
+ end
23
+ end
24
+
25
+ def self.unpack(response, key: nil, resource_class: nil)
26
+ data = if response.body.respond_to?(:key?) && key.present?
27
+ response.body[key]
28
+ else
29
+ response.body
30
+ end
31
+
32
+ parsed = transform_body(data, resource_class: resource_class)
33
+ meta = transform_meta(response.body)
34
+
35
+ new(
36
+ status: response.status,
37
+ headers: response.headers,
38
+ data: parsed,
39
+ meta: meta,
40
+ full_body: response.body,
41
+ )
42
+ end
43
+
44
+ attr_reader :status, :headers, :data, :full_body, :meta
45
+
46
+ def initialize(status:, headers:, data:, full_body:, meta: nil)
47
+ @status = status
48
+ @headers = headers
49
+ @data = data
50
+ @full_body = full_body
51
+ @meta = meta
52
+ end
53
+
54
+ def successful?
55
+ status >= 200 && status < 300
56
+ end
57
+
58
+ def paginated?
59
+ meta&.dig(:pagination).present?
60
+ end
61
+
62
+ def operation
63
+ headers[:location]
64
+ end
65
+
66
+ def operation?
67
+ operation.present
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,21 @@
1
+ require "scalingo/api/client"
2
+
3
+ module Scalingo
4
+ class Auth < API::Client
5
+ require "scalingo/auth/keys"
6
+ require "scalingo/auth/scm_integrations"
7
+ require "scalingo/auth/tokens"
8
+ require "scalingo/auth/two_factor_auth"
9
+ require "scalingo/auth/user"
10
+
11
+ register_handlers!(
12
+ keys: Keys,
13
+ scm_integrations: ScmIntegrations,
14
+ tokens: Tokens,
15
+ two_factor_auth: TwoFactorAuth,
16
+ user: User,
17
+ )
18
+
19
+ alias_method :tfa, :two_factor_auth
20
+ end
21
+ end
@@ -0,0 +1,56 @@
1
+ require "scalingo/api/endpoint"
2
+
3
+ module Scalingo
4
+ class Auth::Keys < API::Endpoint
5
+ def all(headers = nil, &block)
6
+ data = nil
7
+
8
+ response = connection.get(
9
+ "keys",
10
+ data,
11
+ headers,
12
+ &block
13
+ )
14
+
15
+ unpack(response, key: :keys)
16
+ end
17
+
18
+ def show(id, headers = nil, &block)
19
+ data = nil
20
+
21
+ response = connection.get(
22
+ "keys/#{id}",
23
+ data,
24
+ headers,
25
+ &block
26
+ )
27
+
28
+ unpack(response, key: :key)
29
+ end
30
+
31
+ def create(payload, headers = nil, &block)
32
+ data = {key: payload}
33
+
34
+ response = connection.post(
35
+ "keys",
36
+ data,
37
+ headers,
38
+ &block
39
+ )
40
+
41
+ unpack(response, key: :key)
42
+ end
43
+
44
+ def destroy(id, headers = nil, &block)
45
+ data = nil
46
+ response = connection.delete(
47
+ "keys/#{id}",
48
+ data,
49
+ headers,
50
+ &block
51
+ )
52
+
53
+ unpack(response)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,57 @@
1
+ require "scalingo/api/endpoint"
2
+
3
+ module Scalingo
4
+ class Auth::ScmIntegrations < API::Endpoint
5
+ def all(headers = nil, &block)
6
+ data = nil
7
+
8
+ response = connection.get(
9
+ "scm_integrations",
10
+ data,
11
+ headers,
12
+ &block
13
+ )
14
+
15
+ unpack(response, key: :scm_integrations)
16
+ end
17
+
18
+ def show(id, headers = nil, &block)
19
+ data = nil
20
+
21
+ response = connection.get(
22
+ "scm_integrations/#{id}",
23
+ data,
24
+ headers,
25
+ &block
26
+ )
27
+
28
+ unpack(response, key: :scm_integration)
29
+ end
30
+
31
+ def create(payload, headers = nil, &block)
32
+ data = {scm_integration: payload}
33
+
34
+ response = connection.post(
35
+ "scm_integrations",
36
+ data,
37
+ headers,
38
+ &block
39
+ )
40
+
41
+ unpack(response, key: :scm_integration)
42
+ end
43
+
44
+ def destroy(id, headers = nil, &block)
45
+ data = nil
46
+
47
+ response = connection.delete(
48
+ "scm_integrations/#{id}",
49
+ data,
50
+ headers,
51
+ &block
52
+ )
53
+
54
+ unpack(response)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,78 @@
1
+ require "scalingo/api/endpoint"
2
+
3
+ module Scalingo
4
+ class Auth::Tokens < API::Endpoint
5
+ def exchange(token, headers = nil, &block)
6
+ data = nil
7
+
8
+ authorization = Faraday::Request::BasicAuthentication.header("", token)
9
+
10
+ request_headers = {
11
+ Faraday::Request::Authorization::KEY => authorization
12
+ }
13
+
14
+ request_headers.update(headers) if headers
15
+
16
+ response = client.unauthenticated_connection.post(
17
+ "tokens/exchange",
18
+ data,
19
+ request_headers,
20
+ &block
21
+ )
22
+
23
+ unpack(response)
24
+ end
25
+
26
+ def all(headers = nil, &block)
27
+ data = nil
28
+
29
+ response = connection.get(
30
+ "tokens",
31
+ data,
32
+ headers,
33
+ &block
34
+ )
35
+
36
+ unpack(response, key: :tokens)
37
+ end
38
+
39
+ def create(payload, headers = nil, &block)
40
+ data = {token: payload}
41
+
42
+ response = connection.post(
43
+ "tokens",
44
+ data,
45
+ headers,
46
+ &block
47
+ )
48
+
49
+ unpack(response, key: :token)
50
+ end
51
+
52
+ def renew(id, headers = nil, &block)
53
+ data = nil
54
+
55
+ response = connection.patch(
56
+ "tokens/#{id}/renew",
57
+ data,
58
+ headers,
59
+ &block
60
+ )
61
+
62
+ unpack(response, key: :token)
63
+ end
64
+
65
+ def destroy(id, headers = nil, &block)
66
+ data = nil
67
+
68
+ response = connection.delete(
69
+ "tokens/#{id}",
70
+ data,
71
+ headers,
72
+ &block
73
+ )
74
+
75
+ unpack(response)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,61 @@
1
+ require "scalingo/api/endpoint"
2
+
3
+ module Scalingo
4
+ class Auth::TwoFactorAuth < API::Endpoint
5
+ TOTP_PROVIDER = "totp"
6
+ DEFAULT_PROVIDER = TOTP_PROVIDER
7
+ SUPPORTED_PROVIDERS = [TOTP_PROVIDER]
8
+
9
+ def status(headers = nil, &block)
10
+ data = nil
11
+
12
+ response = connection.get(
13
+ "client/tfa",
14
+ data,
15
+ headers,
16
+ &block
17
+ )
18
+
19
+ unpack(response, key: :tfa)
20
+ end
21
+
22
+ def initiate(provider = DEFAULT_PROVIDER, headers = nil, &block)
23
+ data = {tfa: {provider: provider}}
24
+
25
+ response = connection.post(
26
+ "client/tfa",
27
+ data,
28
+ headers,
29
+ &block
30
+ )
31
+
32
+ unpack(response, key: :tfa)
33
+ end
34
+
35
+ def validate(attempt, headers = nil, &block)
36
+ data = {tfa: {attempt: attempt}}
37
+
38
+ response = connection.post(
39
+ "client/tfa/validate",
40
+ data,
41
+ headers,
42
+ &block
43
+ )
44
+
45
+ unpack(response, key: :tfa)
46
+ end
47
+
48
+ def disable(headers = nil, &block)
49
+ data = nil
50
+
51
+ response = connection.delete(
52
+ "client/tfa",
53
+ data,
54
+ headers,
55
+ &block
56
+ )
57
+
58
+ unpack(response, key: :tfa)
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,31 @@
1
+ require "scalingo/api/endpoint"
2
+
3
+ module Scalingo
4
+ class Auth::User < API::Endpoint
5
+ def self(headers = nil, &block)
6
+ data = nil
7
+
8
+ response = connection.get(
9
+ "users/self",
10
+ data,
11
+ headers,
12
+ &block
13
+ )
14
+
15
+ unpack(response, key: :user)
16
+ end
17
+
18
+ def update(payload, headers = nil, &block)
19
+ data = {user: payload}
20
+
21
+ response = connection.put(
22
+ "users/account",
23
+ data,
24
+ headers,
25
+ &block
26
+ )
27
+
28
+ unpack(response, key: :user)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ module Scalingo
2
+ class BearerToken
3
+ attr_reader :expires_in
4
+
5
+ def initialize(value, expires_in: nil)
6
+ @value = value
7
+ @expires_in = expires_in if expires_in
8
+ end
9
+
10
+ def expired?
11
+ expires_in && expires_in <= Time.now
12
+ end
13
+
14
+ def value
15
+ raise Error::ExpiredToken if expired? && Scalingo.config.raise_on_expired_token
16
+
17
+ @value
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,105 @@
1
+ require "forwardable"
2
+ require "faraday"
3
+ require "faraday_middleware"
4
+ require "scalingo/bearer_token"
5
+ require "scalingo/errors"
6
+ require "scalingo/auth"
7
+ require "scalingo/regional"
8
+
9
+ module Scalingo
10
+ class Client
11
+ extend Forwardable
12
+
13
+ ## Authentication helpers / Token management
14
+ attr_reader :token
15
+
16
+ def token=(input)
17
+ @token = input.is_a?(BearerToken) ? input : BearerToken.new(input.to_s)
18
+ end
19
+
20
+ def authenticated?
21
+ token.present? && !token.expired?
22
+ end
23
+
24
+ def authenticate_with(access_token: nil, bearer_token: nil, expires_in: nil)
25
+ if !access_token && !bearer_token
26
+ raise ArgumentError, "You must supply one of `access_token` or `bearer_token`"
27
+ end
28
+
29
+ if access_token && bearer_token
30
+ raise ArgumentError, "You cannot supply both `access_token` and `bearer_token`"
31
+ end
32
+
33
+ if expires_in && !bearer_token
34
+ raise ArgumentError, "`expires_in` can only be used with `bearer_token`. `access_token` have a 1 hour expiration."
35
+ end
36
+
37
+ if access_token
38
+ expiration = Time.now + Scalingo.config.exchanged_token_validity
39
+ response = auth.tokens.exchange(access_token)
40
+
41
+ if response.successful?
42
+ self.token = BearerToken.new(
43
+ response.data[:token],
44
+ expires_in: expiration,
45
+ )
46
+ end
47
+
48
+ return response.successful?
49
+ end
50
+
51
+ if bearer_token
52
+ self.token = expires_in ? BearerToken.new(bearer_token.to_s, expires_in: expires_in) : bearer_token
53
+ end
54
+ end
55
+
56
+ ## API clients
57
+ def auth
58
+ @auth ||= Auth.new(self, Scalingo.config.urls.auth)
59
+ end
60
+
61
+ def region
62
+ public_send(Scalingo.config.default_region)
63
+ end
64
+
65
+ Scalingo.config.regions.each do |region|
66
+ if Scalingo.config.urls[region].blank?
67
+ raise ArgumentError, "Scalingo: no url configured for region #{region}"
68
+ end
69
+
70
+ define_method(region) do
71
+ region_client = instance_variable_get :"@#{region}"
72
+
73
+ unless region_client
74
+ region_client = Regional.new(self, Scalingo.config.urls[region])
75
+
76
+ instance_variable_set :"@#{region}", region_client
77
+ end
78
+
79
+ region_client
80
+ end
81
+ end
82
+
83
+ ## Delegations
84
+ def_delegator :auth, :keys
85
+ def_delegator :auth, :scm_integrations
86
+ def_delegator :auth, :tokens
87
+ def_delegator :auth, :two_factor_auth
88
+ def_delegator :auth, :tfa
89
+ def_delegator :auth, :user
90
+
91
+ def_delegator :region, :addons
92
+ def_delegator :region, :apps
93
+ def_delegator :region, :collaborators
94
+ def_delegator :region, :containers
95
+ def_delegator :region, :deployments
96
+ def_delegator :region, :domains
97
+ def_delegator :region, :environment
98
+ def_delegator :region, :events
99
+ def_delegator :region, :logs
100
+ def_delegator :region, :metrics
101
+ def_delegator :region, :notifiers
102
+ def_delegator :region, :operations
103
+ def_delegator :region, :scm_repo_links
104
+ end
105
+ end