154 lines
5.5 KiB
JavaScript
154 lines
5.5 KiB
JavaScript
/*
|
|
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc overview
|
|
* @name horizon.dashboard.project.workflow.keypair.create-keypair-service
|
|
*
|
|
* @description
|
|
* Service to handle creating keypairs and downloading their private keys.
|
|
* Please note, the implementation has quirks due to what features are
|
|
* available in which browsers. As a result, the implementation involves
|
|
* using iframes to specify downloads. Since the API does not allow the
|
|
* full retrieval of the key pair after creation, and the URL retrieved in
|
|
* an iframe must be a GET method, and the fact that we shouldn't pass
|
|
* data as part of the URL (because it is potentially logged and contains
|
|
* private key data), we have to make the actual API call when performing
|
|
* the GET. This also means that if the user misses the download for some
|
|
* reason, we need to provide the ability to regenerate the key pair,
|
|
* although that is not a feature of this service.
|
|
*/
|
|
|
|
angular
|
|
.module('horizon.app.core.openstack-service-api')
|
|
.factory('horizon.app.core.openstack-service-api.keypair-download-service',
|
|
keypairDownloadService);
|
|
|
|
keypairDownloadService.$inject = [
|
|
'$document',
|
|
'horizon.app.core.openstack-service-api.nova',
|
|
'$q',
|
|
'$timeout'
|
|
];
|
|
|
|
function keypairDownloadService($document, novaAPI, $q, $timeout) {
|
|
|
|
var service = {
|
|
createAndDownloadKeypair: createAndDownloadKeypair
|
|
};
|
|
|
|
return service;
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name createAndDownloadKeypair
|
|
*
|
|
* @description
|
|
* This function performs the actions necessary to begin a download
|
|
* of a newly created key pair. The given name will be used as the
|
|
* logical name of the key pair and will be used to make a file-system-
|
|
* friendly filename.
|
|
* In this implementation, for browser compatibility reasons, the
|
|
* download is achieved by creating an iframe with the given path for
|
|
* the create API call given, so the results are streamed directly to the
|
|
* client. This is not ideal but is due to lack of support in IE for
|
|
* features like the data: protocol. The iframes require that an element
|
|
* with the class of 'download-iframes' is present.
|
|
*
|
|
* @param {string} name The desired name for the key pair
|
|
* @returns {promise} A promise resolving if true, rejecting with error
|
|
*/
|
|
function createAndDownloadKeypair(name) {
|
|
addDOMResource(name);
|
|
return verifyCreatedPromise(name);
|
|
}
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name addDOMResource
|
|
*
|
|
* @description
|
|
* This adds an iframe to the body of the current document, using
|
|
* the appropriate URL for the API to create/download the new key pair.
|
|
*
|
|
* @param {string} keypairName The desired name for the key pair
|
|
* @returns {undefined} Returns nothing
|
|
*/
|
|
function addDOMResource(keypairName) {
|
|
var url = novaAPI.getCreateKeypairUrl(keypairName);
|
|
var iframe = angular.element("<iframe></iframe>");
|
|
iframe.attr('id', keypairName);
|
|
iframe.attr('src', url);
|
|
iframe.attr('style', 'display: none;');
|
|
if ($document.find('.download-iframes').size() === 0) {
|
|
var iframeContainer = angular.element('<div class="download-iframes"></div>');
|
|
$document.find('body').append(iframeContainer);
|
|
}
|
|
$document.find('.download-iframes').append(iframe);
|
|
}
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name verifyCreatedPromise
|
|
*
|
|
* @description
|
|
* This function returns a promise that tries ten times to see if a
|
|
* key pair of the given name exists in the key pair listing. These
|
|
* tries are one second apart. Once it has been found, the promise
|
|
* is resolved with the key pair data. If it is not found within the
|
|
* period, the promise is rejected.
|
|
*
|
|
* @param {string} name The name for the key pair
|
|
* @returns {promise} A promise resolving if true, rejecting with error
|
|
*/
|
|
function verifyCreatedPromise(name) {
|
|
return $q(function doesKeypairExistPromise(resolve, reject) {
|
|
|
|
doesKeypairExist(10);
|
|
|
|
function doesKeypairExist(timesToCheck) {
|
|
$timeout(function doesKeypairExistTimeout() {
|
|
novaAPI.getKeypairs().then(function isKeypairInResponse(response) {
|
|
|
|
var foundKeypairs = response.data.items.filter(function sameName(item) {
|
|
return item.keypair.name === name;
|
|
});
|
|
|
|
if (foundKeypairs.length === 1) {
|
|
resolve(foundKeypairs[0].keypair);
|
|
angular.element('.download-iframes #' + name).remove();
|
|
} else if (timesToCheck > 1) {
|
|
doesKeypairExist(timesToCheck - 1);
|
|
} else {
|
|
reject();
|
|
angular.element('.download-iframes #' + name).remove();
|
|
}
|
|
|
|
});
|
|
},
|
|
1000);
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
})();
|