UNPKG

openstack-swift-client-region

Version:
109 lines (94 loc) 2.87 kB
"use strict"; const EventEmitter = require('events'); const requestp = require('request-promise'); class KeystoneV3Authenticator extends EventEmitter { constructor(credentials) { super(); this.credentials = credentials; this.currentToken = null; } tryFindEndpointUrl(catalog, service, iface) { const catalogEntry = catalog.find(x => x.name === service); if (!catalogEntry) { return null; } let endpoint = null let region = this.credentials.regionName if (!!region) { endpoint = catalogEntry.endpoints.find(x => x.interface === iface && x.region === region); } else { endpoint = catalogEntry.endpoints.find(x => x.interface === iface); } if (!endpoint) { return null; } return endpoint.url; } async getToken() { const credentials = this.credentials; const model = { auth: { identity: { methods: [ 'password' ], password: { user: { name: credentials.username, password: credentials.password, domain: { id: credentials.domainId } } } }, scope: { project: { id: credentials.projectId, domain: { id: credentials.domainId } } } } }; const response = await requestp({ method: 'POST', uri: credentials.endpointUrl + '/auth/tokens', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, json: model, resolveWithFullResponse: true }); const catalog = response.body.token.catalog; // console.log('catalog', catalog) const swiftUrl = this.tryFindEndpointUrl(catalog, 'swift', 'public') || this.tryFindEndpointUrl(catalog, 'radosgw-swift', 'public'); // many OpenStack clouds use ceph radosgw to provide swift console.log('swiftUrl', swiftUrl) if (!swiftUrl) { throw new Error('could not find swift or radosgw-swift service in catalog'); } return { token: response.headers['x-subject-token'], expires: new Date(response.body.expires_at), // expires_at is an ISO 8601 Date: swiftUrl: swiftUrl } }; async authenticate() { if (!this.currentToken) { this.currentToken = await this.getToken(); } const tokenPreRefreshInterval = 10000; // renew tokens 10s before they expire const requestedTokenExpiry = new Date(Date.now() + tokenPreRefreshInterval) if (requestedTokenExpiry > this.currentToken.expires_at) { this.currentToken = await this.getToken(); } const validToken = this.currentToken; return { url: validToken.swiftUrl, token: validToken.token }; } } module.exports = KeystoneV3Authenticator;