Class: Ovh::Client
- Inherits:
-
Object
- Object
- Ovh::Client
- Defined in:
- lib/ovh-client/client.rb,
lib/ovh-client/client/clock.rb,
lib/ovh-client/client/signature.rb
Overview
Signing wrapper over the generated Api transport gem. It builds an Ovh::Api::Client and wires request signing (and optional retries) onto its middleware seam, then exposes the generated surface through #api.
Defined Under Namespace
Constant Summary collapse
- ENDPOINTS =
OVH API endpoints per datacenter. Combined with the api_version to form base_url.
{ eu: 'https://eu.api.ovh.com', ca: 'https://ca.api.ovh.com', us: 'https://api.us.ovhcloud.com' }.freeze
- RETRY_STATUSES =
HTTP statuses worth retrying: OVH rate limiting and transient gateway/server errors. Retries apply to idempotent verbs only (never POST/PATCH).
[429, 500, 502, 503, 504].freeze
- RETRY_METHODS =
%i[get head delete put].freeze
- REDACTED =
'[REDACTED]'- SENSITIVE_HEADERS =
Credential headers to scrub from any downstream logger. ovh-api's built-in logger runs before signing so it never sees these; these filters are for a caller-supplied logger placed after the signature middleware.
%w[X-Ovh-Application X-Ovh-Consumer X-Ovh-Signature].freeze
Instance Attribute Summary collapse
-
#api ⇒ Ovh::Api::Client
readonly
The generated transport client.
Class Method Summary collapse
-
.log_filters ⇒ Array<(Regexp, String)>
Regex/replacement pairs that scrub the OVH credential headers from a Faraday logger's output.
-
.request_consumer_key(application_key:, access_rules:, endpoint: :eu, api_version: '1.0', redirection: nil) ⇒ Object
Start the OVH credential flow: request a consumer key scoped to the given access rules.
Instance Method Summary collapse
-
#current_credential ⇒ Object
Fetch the credential currently in use (scope, status, expiration).
-
#initialize(application_key:, application_secret:, consumer_key:, endpoint: :eu, api_version: '1.0', time_delta: 0, auto_sync_time: false, retries: 0, **options) ⇒ Client
constructor
rubocop:disable Metrics/MethodLength, Metrics/ParameterLists.
-
#synchronize_time! ⇒ Integer
Measure the offset between OVH's clock and the local one and remember it for every subsequent signed request.
Constructor Details
#initialize(application_key:, application_secret:, consumer_key:, endpoint: :eu, api_version: '1.0', time_delta: 0, auto_sync_time: false, retries: 0, **options) ⇒ Client
rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ovh-client/client.rb', line 68 def initialize(application_key:, application_secret:, consumer_key:, endpoint: :eu, api_version: '1.0', time_delta: 0, auto_sync_time: false, retries: 0, **) @retries = retries base_url = "#{resolve_endpoint(endpoint)}/#{api_version}" # method(:synchronize_time!) is bound now but only invoked on the first signed # request, by which point @api is set. @clock = Clock.new(delta: time_delta, syncer: (auto_sync_time ? method(:synchronize_time!) : nil)) @api = Ovh::Api::Client.new(base_url: base_url, **) do |config| # Retry is registered before Signature so it wraps it: each retry attempt # re-enters Signature and re-signs with a fresh timestamp. config.use(Faraday::Retry::Middleware, ) if retries.positive? config.use(Signature, application_key: application_key, application_secret: application_secret, consumer_key: consumer_key, clock: @clock) end end |
Instance Attribute Details
#api ⇒ Ovh::Api::Client (readonly)
Returns the generated transport client.
33 34 35 |
# File 'lib/ovh-client/client.rb', line 33 def api @api end |
Class Method Details
.log_filters ⇒ Array<(Regexp, String)>
Regex/replacement pairs that scrub the OVH credential headers from a Faraday logger's output. Use when wiring your own logger downstream of signing.
38 39 40 41 42 |
# File 'lib/ovh-client/client.rb', line 38 def self.log_filters SENSITIVE_HEADERS.map do |header| [/(#{Regexp.escape(header)}:\s*)[^\r\n]+/i, "\\1#{REDACTED}"] end end |
.request_consumer_key(application_key:, access_rules:, endpoint: :eu, api_version: '1.0', redirection: nil) ⇒ Object
Start the OVH credential flow: request a consumer key scoped to the given access rules. Runs before a consumer key exists; needs only the application key (the call is unsigned, so application_secret is irrelevant here). The response carries a consumerKey and a validationUrl the end user must visit.
59 60 61 62 63 64 65 |
# File 'lib/ovh-client/client.rb', line 59 def self.request_consumer_key(application_key:, access_rules:, endpoint: :eu, api_version: '1.0', redirection: nil) client = new(application_key: application_key, application_secret: nil, consumer_key: nil, endpoint: endpoint, api_version: api_version) body = { 'accessRules' => access_rules } body['redirection'] = redirection if redirection client.api.connection.call(:POST, '/auth/credential', body: body).data end |
Instance Method Details
#current_credential ⇒ Object
Fetch the credential currently in use (scope, status, expiration).
103 104 105 |
# File 'lib/ovh-client/client.rb', line 103 def current_credential @api.connection.call(:GET, '/auth/currentCredential').data end |
#synchronize_time! ⇒ Integer
Measure the offset between OVH's clock and the local one and remember it for every subsequent signed request. The call is unsigned (the /auth/time endpoint is public and skip-listed by Signature).
94 95 96 97 98 99 |
# File 'lib/ovh-client/client.rb', line 94 def synchronize_time! server = @api.connection.call(:GET, '/auth/time').data delta = server.to_i - Time.now.to_i @clock.synchronize!(delta) delta end |